|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
7 M$ E' o/ _$ j/ c( c
. a8 F% Y% K( w* U2 u! l4 u& X" O% a
///////////////////////////////////////////' ?0 |; Q( O6 A2 g
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 O0 J! U8 I4 r' z* u8 b8 z4 ?
C7 }+ h$ o' D+ \: O2 V% ~8 x3 k$ Y3 [$ \: u
#pragma once- {" H% l, H9 w2 a* W0 X
#include <exception>
* I: q: n% Z a( k
* t. |% P5 x& |0 Q) F4 t0 f' l; W2 F
( j: x+ y% k, i: g1 I. D enum TRISTATE{6 f) H7 Z' s! G. |9 O
TRIS_FALSE,8 `5 C! a1 c1 m) [8 K: O9 `) d
TRIS_UNKNOWN,7 a- h7 y: E# q* g) { ?
TRIS_TRUE1 ~. P0 V4 q: S$ G
};5 e' c- S) r, I* y+ ^& {
' c0 X8 C1 D. j* e c9 W4 i
4 B* J" g" v0 |$ Z$ T% E! s5 ^
enum UPNP_IMPLEMENTATION{
7 s% u' I: {/ F3 B! d6 W& [ UPNP_IMPL_WINDOWSERVICE = 0,' N7 e* U- k) g( |8 I7 v! V
UPNP_IMPL_MINIUPNPLIB, \% |& M7 {; H& ^5 d1 a
UPNP_IMPL_NONE /*last*/
( ^1 [0 F( } I; F, e# Y};9 b1 F$ u/ I6 @' b5 G7 A# Q
4 M+ ~8 Z6 W& n: R
/ q0 O0 u. O3 @" D
5 \; U! j7 y3 u. a8 H
( b. [2 O% H* e8 P X6 dclass CUPnPImpl& x& {. g& o! X+ p' u: X- r7 f2 X
{
' i" e, M4 Z6 i6 J H) b$ Apublic:: U! s) c0 f# \% K- o% c
CUPnPImpl();
" }; b7 Q: d* C7 ~& b virtual ~CUPnPImpl();( n# r8 R/ e0 X- H2 x: u
struct UPnPError : std::exception {};7 Z0 } F+ t9 f) y+ Y7 ~( x# y
enum {6 O- l, Q+ c3 I' }: D& M3 ?% i# W
UPNP_OK,
; {: l6 R! l- a7 [ UPNP_FAILED,8 n- f: I9 d0 [8 C# J
UPNP_TIMEOUT9 z, e4 C2 \1 q, ~
};
# a9 B m" A3 o8 K8 F- h8 S
v- e% |- [+ R0 Y2 i) M
! M6 O2 T) j2 N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;; p( V; D# s, x# X4 L* H* k8 m2 }
virtual bool CheckAndRefresh() = 0;* t8 M5 x. n$ s- O9 G8 N- I' e
virtual void StopAsyncFind() = 0;
/ V4 l8 Y$ q3 t& K3 q virtual void DeletePorts() = 0;: b. a0 i0 v, l d2 I+ V+ p' k
virtual bool IsReady() = 0;! ?. }# e4 c: Z1 x- ~+ H0 p: r, Q
virtual int GetImplementationID() = 0;
' Z& X- C4 f% w, C
* M0 l1 m8 c5 y1 s, ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping7 C( f# T1 W8 R+ Y2 Z
a Y0 `" h# N2 Y( [
# d5 m. |: @. p& H5 F
void SetMessageOnResult(HWND hWindow, UINT nMessageID);/ S9 P# Y2 t) \
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 `$ j/ W* N, }( ]" R4 [4 W
uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ a: T+ |% H: Y) S5 p, o5 X uint16 GetUsedUDPPort() { return m_nUDPPort; }
! X8 ^6 [3 [7 C/ J- k3 d5 D) `+ O# P7 n5 y2 V* [# E
7 ?8 a( q- k' N0 j7 M$ x
// Implementation
" R+ q+ g( S0 k% W$ Hprotected:3 y( D- R/ G3 q8 r& s5 i
volatile TRISTATE m_bUPnPPortsForwarded;/ T# y# U& s; U8 I) {7 y
void SendResultMessage();
4 b9 _& |3 s) A' Z% ]( f uint16 m_nUDPPort;
) q. D7 ~, Z) J: t uint16 m_nTCPPort;8 ^+ B% c3 Y r% @" Q) V
uint16 m_nTCPWebPort;
' |- q0 l2 V" x2 M bool m_bCheckAndRefresh;' ]1 Y9 o5 e, |8 Y% ?) W
5 O2 z' B9 ^% s, t* f
G8 c; i# G! W8 F& A7 e
private:# R v, i8 y5 a1 g
HWND m_hResultMessageWindow;
4 E, y0 [- L. U3 N+ e& I UINT m_nResultMessageID;- I/ m, c+ v* a2 P0 Z9 X4 f9 C/ r
+ M* P; d' P7 L' f ^: A6 I
4 I- F* F3 v' V: z};
& o+ ~3 @9 @$ W* a Q" j# b7 d
9 r& o' Q U$ G8 C1 o' W# j" U1 u* ~ y! }- R
// Dummy Implementation to be used when no other implementation is available1 O8 ?$ m; C" L. w# p$ |
class CUPnPImplNone: public CUPnPImpl% }# L7 g) x, @
{
. R6 ]8 X) R; C2 \% |/ Cpublic:
' c# V2 r+ D4 l: y* H& i. y8 v virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ c: }' X/ P$ U! I' D+ c& Z virtual bool CheckAndRefresh() { return false; }
2 X; A, y: D+ G& T; t( _" ]2 k virtual void StopAsyncFind() { }" o3 ~1 j3 L8 i, O1 d- W- e8 u
virtual void DeletePorts() { }
3 H/ n# y$ D4 ]- \: w& I7 A0 x virtual bool IsReady() { return false; }7 I$ ]* m; G x& y0 n' w
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
+ R7 n& z3 e; Q& Q" X; t};
' `! R% z: X# P0 u, f' t* _/ \/ ~; f
6 _& X! `9 J+ e7 h, V- K/////////////////////////////////////
$ i7 h3 Y: d6 f//下面是使用windows操作系统自带的UPNP功能的子类
% r( m M; f- ]9 o9 r2 C" B' T' J' M f! g
. |: B& ?. J- P' _0 d8 j#pragma once* S" \) Z' M; n- o
#pragma warning( disable: 4355 )8 Q2 C5 L# t0 S) ^& J
; u8 P! ?; }/ o2 ~$ w# t( Z
H- _$ X; j* V3 j* i4 V#include "UPnPImpl.h"
1 \* \$ ~/ }$ m1 a _7 A0 E#include <upnp.h>
0 G* w/ a) \( i* ?# _#include <iphlpapi.h>2 O3 \/ b" M5 C! u) @7 A% `" e
#include <comdef.h>! D/ U4 V# }: I5 W. y' G
#include <winsvc.h>
; H+ H+ N" ~, y2 U; T) i
" G' O' q5 m5 A$ k' ~6 T( U! Q+ z M9 N
#include <vector>, ~# O6 z, h7 Z
#include <exception>
4 W4 I: n8 r7 t: `( |5 d#include <functional>) v. O: t8 `$ U) H& D" O
0 u. H. }) {4 T. _% i: }+ A% [+ c( x+ H3 A* k
/ G$ d; Y& j; y+ a
! T8 V7 G) a& k/ ]9 D3 ^" B4 ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
# j" q5 U5 M- B0 N) ]typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
3 H$ `. `4 k% l+ C( _typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 Y' o/ {7 g+ V9 u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
3 }* w+ x5 \2 f6 H) qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 l4 H+ k1 {5 D; I
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;0 _, a8 V0 S" M1 {1 U6 u
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 \; ?; F* a: r. }) P
$ M# z. z8 `! N3 T$ h1 T; ]* m! L) q+ `
+ Z: N6 I+ U( l9 l2 S
typedef DWORD (WINAPI* TGetBestInterface) (
+ Z2 i( H4 H- Y" r IPAddr dwDestAddr,
: R1 |; ?$ i! X) c4 q8 W PDWORD pdwBestIfIndex
2 }- t2 @: g* J- O. }: Q G. p6 Y4 p);
/ `- \, Z4 U& E
! z8 I2 y* \, C3 l! ]% [/ a+ [( L) w( [& O
typedef DWORD (WINAPI* TGetIpAddrTable) (" x/ w7 k5 W9 {' @0 A( V; Y
PMIB_IPADDRTABLE pIpAddrTable,
7 a, t$ h: O4 F& h$ b( s PULONG pdwSize,) j1 m* Y, E1 A F4 z8 s. l
BOOL bOrder
1 }5 l& E- ]$ Q);7 Z2 E, P+ x# |2 L
O M+ J' b3 Y+ w4 Z2 k& M. S, G2 _4 X- w7 L
typedef DWORD (WINAPI* TGetIfEntry) (3 W7 y" y1 q: M0 W* ~9 b
PMIB_IFROW pIfRow
, X# s7 j' l2 i( O, w* O);) N* g% }; u# j1 E3 x
# v- ^) ^1 A) h% t4 d3 |# w/ B
7 j* q, \" b, b% K4 X8 sCString translateUPnPResult(HRESULT hr);
" `, @! W. ?7 ~5 `( m4 qHRESULT UPnPMessage(HRESULT hr);
% l" O/ P8 J Z: d
5 B& @! X* H$ T- F
; L' ]5 a/ K) u% r6 B% Eclass CUPnPImplWinServ: public CUPnPImpl
6 E1 B# x& [5 a8 ]4 s: J{
6 Q3 ~+ e4 ^7 J& r3 Y, E, W3 i. a friend class CDeviceFinderCallback;
) _/ N" S; w% E9 c2 }3 G) C, M friend class CServiceCallback;
# O4 \1 W, B" g6 P// Construction
x) U$ E' e& T% M/ Kpublic:- C4 m7 k6 X$ `* e
virtual ~CUPnPImplWinServ();) ?) J3 u% @+ l" z
CUPnPImplWinServ();! b8 m! A3 ^' X4 b9 P4 I' t
: C. x( _! u6 d, ?2 D0 n2 y
! b5 p# f9 |5 r1 n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }* N% c) ~9 f4 J4 k( e
virtual void StopAsyncFind();
% \3 e# S& r$ t$ r) e* A/ ?# v8 ~2 y" E virtual void DeletePorts();
3 v! N! w4 @$ K5 f+ ]* T, G& a virtual bool IsReady();
2 q* |9 ?9 e, f# R6 X- }: N virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
" Z; m b/ G0 O, g9 S) A! a4 ]. t* v/ |% w. \
2 e4 p+ x# ]7 F3 y // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 o- Z" u) k j- E o/ U. ?$ s // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 E. L" i5 j* I# i& b
virtual bool CheckAndRefresh() { return false; };" `$ }- `9 V* D) O: d+ b* O
, q: d# d% j2 l
]5 y, z ~) ]( K# k; d# D% e+ Vprotected:( n3 b2 {% F" {3 f" K! S6 k
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
0 k+ m/ _# k5 w void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
3 h3 y& F% F; L; B void RemoveDevice(CComBSTR bsUDN);* Y) p& L* D* W: S7 \+ u0 X4 t
bool OnSearchComplete();8 n( d {8 f- ^, w! p( l* {
void Init();
0 L0 j" I0 {5 v8 `2 W' o2 _3 h" C! x" I! z* |
" X: `- S& H. C7 m6 V) \1 _8 V inline bool IsAsyncFindRunning() ' M. o7 S; b( x& T/ u8 N" s
{% j+ b' u# ~( z. N" Q7 y
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
; \0 t7 d! r% e( ]: z {* z# g1 K) a! i/ C9 ]% k' L
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- t0 y, V4 e( g; P
m_bAsyncFindRunning = false;7 p0 y+ K1 \# U# T5 K( P
}
$ T( t$ Z3 {/ \; N: ? MSG msg;
! h) c8 _0 ~1 c, Z* I; U while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ B$ o0 i, i1 g; O* Y
{/ c! @ i5 J) [! z
TranslateMessage( &msg );$ S3 `$ n, a" t2 b
DispatchMessage( &msg );: V$ n" p2 S$ x5 p: c# B
}
Y; k$ |& ^4 ? d return m_bAsyncFindRunning;, z- }# _& ^* P* e. @" z
}
, B( b# u* u0 d$ n* j' @5 i' E2 s
# a& [! ^$ H2 b# Q) {: V TRISTATE m_bUPnPDeviceConnected;
( w) m! G* l! E' c6 G A+ b2 O) \4 y! e& a) i
+ F, Z% |; Q" ^) y& V" N
// Implementation m2 n; M: ?# ~& r
// API functions3 \* _9 L7 d( i. K
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
' z2 M7 X4 N! i9 @- P6 B SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);0 g+ ]$ w! ^3 V
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 H2 K; {' h& Y3 k+ H8 ?. b% A+ I BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
$ t# `5 s$ _8 j7 [2 D9 r% p! I BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% L1 w5 y6 ^1 a$ e# s
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);% l8 F: R- K' }: Z
6 ]# _3 ^4 W) u# P0 X
' f8 ^" l q. e" u
TGetBestInterface m_pfGetBestInterface;
, y0 r' s7 t6 N/ O TGetIpAddrTable m_pfGetIpAddrTable;. G2 h/ {! {! e# j' f
TGetIfEntry m_pfGetIfEntry;
" I8 C9 Z) [' D0 `
. |) ?: `% l" u( q9 m# B8 Q; I5 Z2 L9 U' ^6 B" r
static FinderPointer CreateFinderInstance();7 Z# ^8 ~5 [. B. p; ^
struct FindDevice : std::unary_function< DevicePointer, bool >
( b: L- _( Z! t- l$ P, S {8 y. C6 V u! e) H( {. D" n
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
S0 N: [. k' r1 G result_type operator()(argument_type device) const m" T7 \! Q7 @: W9 M
{
3 d4 P" c7 U# K4 |: F" K CComBSTR deviceName;0 L) u2 d9 ?1 s! }- W6 i
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
. N, T# ]$ s1 m# q6 w5 m& M. _2 j# u4 L
$ @: D. W& D. R9 _1 Y
if ( FAILED( hr ) )2 D' W- ^+ o9 }8 A
return UPnPMessage( hr ), false;
# ^3 b1 z0 D( [: K: T4 H" m- _' D0 T; T X f
& p! p2 F$ m! G0 T9 [+ @
return wcscmp( deviceName.m_str, m_udn ) == 0;
# Y$ G; m" Q' M* y }
% [) {& S$ P- [' z7 U5 h1 y( L CComBSTR m_udn;
5 S) o+ g; U. ~9 K% Y };9 `+ L0 }7 {: R% R
+ I5 l# b2 z: Z* Q! F5 o' @ void ProcessAsyncFind(CComBSTR bsSearchType);
5 B$ [# |5 x! X HRESULT GetDeviceServices(DevicePointer pDevice);3 J$ l2 r# [% s' ]% g5 v6 q$ |
void StartPortMapping();0 b6 a% {# S1 d% V4 g
HRESULT MapPort(const ServicePointer& service);
/ o K3 s' _( r! ?4 g void DeleteExistingPortMappings(ServicePointer pService);+ d3 c: A+ \7 y
void CreatePortMappings(ServicePointer pService);
- P5 ]+ B8 P+ b1 k0 F4 A# d HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);1 [! @1 |8 p& E/ `
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, - C$ v2 N9 v6 i; `7 n1 M
LPCTSTR pszInArgString, CString& strResult);) G# C3 F+ G8 P* a# `
void StopUPnPService();$ M/ F' v% ?# n. {) i1 b7 p
7 w/ k$ g' C" [' k9 q/ N
. b; |: q {# c8 b, V
// Utility functions
) G+ U. e) m4 _1 Z. Z8 ] d' e HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
( Q1 D* Q2 b0 X9 S INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
% {$ A& V3 r' l1 s INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
) t: K+ z( ?+ [* F void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);( _# n |+ C& g% G, F
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; P& _9 j @3 f: J! I4 R3 T
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);- ^3 _% V8 V% D# q0 Y* m; M+ f( r
CString GetLocalRoutableIP(ServicePointer pService);
. J3 q5 {# z/ l1 E5 i# N* c+ R) t4 }8 M& w
3 @; z# r" ^9 m" a, _) A// Private members* F, }* G/ s. ?0 A% |9 u
private:
7 d7 P6 i6 ?6 O4 g# ~& t DWORD m_tLastEvent; // When the last event was received?
9 H8 z7 d \7 J: N, H# U8 F6 i) S std::vector< DevicePointer > m_pDevices;- V" m) s- @) O* o
std::vector< ServicePointer > m_pServices;
) c8 x* g6 O8 b! l. x FinderPointer m_pDeviceFinder;
! \1 W/ u; w% N; f: @ DeviceFinderCallback m_pDeviceFinderCallback;) p; i& b% r' e3 j. o9 V
ServiceCallback m_pServiceCallback;) Q+ E, \+ C6 q3 ? H
' |- N6 ?# H) r/ C1 i
$ t8 I5 f- F0 G8 B' O+ n
LONG m_nAsyncFindHandle; `. Q2 ?7 h8 H8 m; P; a& G
bool m_bCOM;
+ Z" U8 y- k; s( i2 f2 j" j bool m_bPortIsFree;0 n" i; ?% n; b* o+ \& H
CString m_sLocalIP;
D) n- k2 `% h2 k0 ^5 T2 q, T CString m_sExternalIP;: k) t4 U* i) [; q7 S
bool m_bADSL; // Is the device ADSL?5 \/ E4 R: \4 X2 ?0 q+ Z
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?; V% v# g F# ^, {% k8 h' q
bool m_bInited;& g* a6 a* `$ T# a
bool m_bAsyncFindRunning;
; N4 H) v9 w- G' p HMODULE m_hADVAPI32_DLL;
) v2 P5 m3 v: C! ?+ y6 e HMODULE m_hIPHLPAPI_DLL;* Y# \8 c% |8 Q( Y1 H% j
bool m_bSecondTry;
, `$ F) g/ Z+ u bool m_bServiceStartedByEmule;1 o6 m5 M$ l* z/ J; \9 j
bool m_bDisableWANIPSetup;
- J# I# F# `; f) A" d bool m_bDisableWANPPPSetup;5 q) V0 W) j+ u. ^) N1 q
$ `' }3 W& R0 C/ x l' t E
& J& W0 B0 ~' f$ J. ]0 `+ {};
& T: u0 U6 C# G; m! s$ M) I2 U5 {. X5 N- p$ ~1 {
, d, ^1 ^4 W7 t) \4 M; ~7 {* d
// DeviceFinder Callback8 O: x9 G% ]9 b4 Y% ]5 D. K a
class CDeviceFinderCallback. |5 R/ h3 @8 t7 `" z. l4 O( D
: public IUPnPDeviceFinderCallback
: q( I6 o; s* G \% d$ s{8 V5 u5 t0 o5 S1 d( W" A) @
public:% D6 D8 M! K, b" g
CDeviceFinderCallback(CUPnPImplWinServ& instance)
1 @$ _. X7 p2 [ : m_instance( instance )8 ]. l ` F( }5 w4 c7 x
{ m_lRefCount = 0; }
+ l# c! k1 Z/ u" |7 K! M. T2 o( {' g# y+ ^ Z3 q& n: B
, N8 e z# W( {. P STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 e6 E; h( }# F% |% t2 }0 t STDMETHODIMP_(ULONG) AddRef();
0 u1 F7 r. x2 I/ [& z STDMETHODIMP_(ULONG) Release();3 a. O- P/ E- w5 o; U0 L+ T$ l
" X4 n8 T$ @, P4 N( b8 w- }
$ |2 e5 x9 i- \; Q% \, }" k0 I// implementation; p" H( @ M7 T$ ?7 u2 G* p
private:
% f, E0 U8 Q) L+ M. x HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);. Y; Q! D! b8 B
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
9 }) m& ]" }- P3 P HRESULT __stdcall SearchComplete(LONG nFindData);
. D, v1 [. ~8 ~6 t: J- `- n* G# v) l d! S+ ^8 T3 q6 | G2 M
, j, e4 o: o' u) a1 [- w
private:5 c: W Q, }$ y7 A
CUPnPImplWinServ& m_instance;
9 T8 _1 L/ C: R9 l+ T& |" V' P9 I LONG m_lRefCount;
. L0 Z! l! g5 B7 g2 b4 y};; F9 g/ t' ?2 v* j
. w4 f: N; q4 Z( |8 K/ t+ N! F; o' w4 u$ W) o- X+ p
// Service Callback . Z/ ^4 ^- f" r
class CServiceCallback
$ N# ]4 q) p# b4 E : public IUPnPServiceCallback
: z( C$ h3 y2 @3 ?# c J: ^{
% p1 T: E. d) c6 I4 r# d5 Gpublic:, u9 V& O5 U( p3 {. L
CServiceCallback(CUPnPImplWinServ& instance)
" `. P* {; i6 d : m_instance( instance )
) {) f' P6 d9 s6 o { m_lRefCount = 0; }* U+ z- W: r- ^( i
; c d' i, s1 ?# V+ S3 r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ U2 U/ o3 b5 V: E
STDMETHODIMP_(ULONG) AddRef();# E9 Y4 \' B8 L L- @; d8 g
STDMETHODIMP_(ULONG) Release();
2 I, Q! S/ @, l
0 B9 S& G4 j4 R3 C9 j
7 J- D: o4 N+ N. \/ m* G// implementation
, |$ ~& ]- j6 c) b0 vprivate:* t. V; a+ x0 _
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
* d; E$ L ]% ^' q HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
9 f$ Y# j* p& k: N5 S7 K$ c8 A+ I( x
) h) s- @% _, K; D+ |4 I3 Q" z7 k ]& Y, q' j$ r0 f
private: a0 {6 _1 l7 c }( w' t+ _& r- w) l
CUPnPImplWinServ& m_instance;
" \" R/ H! X! ]* w, F$ Z LONG m_lRefCount;
1 j6 z) p3 ]. `: T! Z8 U6 J @};% u9 w% C# }1 _& v
, j6 v) X: l! F+ r$ l
! }' H9 e6 X/ [" F/////////////////////////////////////////////////8 {/ \9 X7 A* o% z7 @
3 C: |+ Z( W& g1 _* e
- i1 W7 k. j$ ~9 X& o使用时只需要使用抽象类的接口。- q) A2 Z0 Q- ^( Q$ w3 p' V l
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
2 u' G Z6 y3 A0 k$ o- ? Z# }3 @CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口." e! `& T. L* C* l
CUPnPImpl::StopAsyncFind停止设备查找.7 h' j j9 s! a! Z: x' C3 N
CUPnPImpl::DeletePorts删除端口映射. |
|