|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
5 n) D6 c" J, R8 _8 z7 ~; B# H) u
: j6 i6 H+ m4 s8 D; n `% S
///////////////////////////////////////////
5 P( ~7 C6 X( j! C. b" T2 u9 }//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% Q1 T( B% o! H: t4 Z
4 G! d9 j8 h0 c8 S( I* B
7 q( @% x5 E1 E1 Y F( X#pragma once1 `5 n3 j# l& `& q
#include <exception>
3 @4 g# _) Y# O3 N6 F
% z/ Q6 m5 N+ s. l: ]7 E& p( t/ a% G+ R6 q1 z5 ]
enum TRISTATE{
# x$ G8 n2 G+ T3 | TRIS_FALSE,
- `9 {& }& ^! o& n6 L TRIS_UNKNOWN,
; M+ E3 g& G* ]* a7 j% s TRIS_TRUE" J" ?! o0 l1 w. K
};" \, N4 @: N0 w' U7 @; A
* l- Y9 W6 J- p
Q$ h+ h" r& o* h% U. w* Denum UPNP_IMPLEMENTATION{1 ~0 |: `+ b. ]. s
UPNP_IMPL_WINDOWSERVICE = 0,/ x9 [& ]# A0 V4 c* |
UPNP_IMPL_MINIUPNPLIB,* f" n# e8 ^1 ~) f$ v
UPNP_IMPL_NONE /*last*/7 d% T3 M0 k0 d+ G/ q: Y. Y/ {
};
9 S6 }" Z* D( ?! d
* i6 x% Y, @+ |4 r, r7 k/ ^+ ]7 p9 b' j$ x6 p* t/ x8 Y
- K& X; j4 O8 Z. F W9 F4 ~) Q( N- G4 p; v
class CUPnPImpl/ W d+ q! v; X
{0 g4 Y. s& s1 U! u; B6 v8 U
public:
8 {1 i$ J& n/ |7 t CUPnPImpl();
! A% J, w7 D, w& @( C6 K2 {5 A, Z( W" s virtual ~CUPnPImpl();
+ }" d) y5 l2 `/ l' \& ?, x struct UPnPError : std::exception {};
: G7 O0 g' ~) X8 C1 x5 H+ ^. O enum {
$ p) @3 l$ e" G7 u& a UPNP_OK,. ?$ Y' u1 a% E$ p
UPNP_FAILED,
/ J; K1 {6 M, } UPNP_TIMEOUT
5 v7 N i7 Y' ]8 I7 E! U };
0 o( Q+ y5 u) g9 M9 F& Z: ` k0 w9 \) S9 m; P# W
! u& x$ q. a2 ?* n% } virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;9 f- a4 N1 J+ o0 x4 [
virtual bool CheckAndRefresh() = 0;1 j5 X8 j7 |; \
virtual void StopAsyncFind() = 0;7 U- I# b+ n" ^" \& |6 p
virtual void DeletePorts() = 0;
( ^4 H3 q2 @2 q virtual bool IsReady() = 0;
( Z* H: L$ L5 f7 I* B virtual int GetImplementationID() = 0;
/ V( k( O/ \$ a ) o! r# n" C- t: @* A. f' z6 a
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping0 o8 [$ L0 E, g `' g" ]1 k: ~2 F8 l9 ~
, {/ z2 K9 W1 y3 R/ `9 V
# C* t6 h& v% {( I; l% Q; M! q* I) n void SetMessageOnResult(HWND hWindow, UINT nMessageID);
! q/ L% _8 {5 Q& Y; J TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ k4 l6 {' m3 a! o' y C1 u) b4 d/ n: A
uint16 GetUsedTCPPort() { return m_nTCPPort; }- a0 X6 N V0 G# X% T( I4 b0 Y
uint16 GetUsedUDPPort() { return m_nUDPPort; }
; l/ U3 j) A" h! i
2 G. j0 i7 L5 T; a, o. N" c
6 ?. l1 @* T- z. f. _0 Y// Implementation
( u2 j$ E2 m* m1 V5 aprotected:2 v* o: Y( w1 M' O* u$ n
volatile TRISTATE m_bUPnPPortsForwarded;. q# o4 J4 O) a8 L7 m# {7 h
void SendResultMessage(); I3 X4 i8 ~1 m2 r# q) H
uint16 m_nUDPPort;
) e3 e. O( `& ~" ]4 Q uint16 m_nTCPPort;
+ p9 T; d; X3 B uint16 m_nTCPWebPort;
0 Z8 a i0 e$ { bool m_bCheckAndRefresh;8 E* B! K" L+ V! M% I/ C0 o
8 W6 ?) H( h2 F: k4 a" N9 Z" y9 B. F) k' j7 Y G1 p& p& I" x
private:1 {+ E, k+ u5 y5 w5 j& X
HWND m_hResultMessageWindow;( Y' t6 `: r% G" \3 @! N: l
UINT m_nResultMessageID;( \& E. \- A" A4 e t
2 m+ C9 ^* a6 G2 ~' h
+ e$ W0 D0 V$ v2 p, `
};
% O7 q/ {" h- a* e7 [
9 V: Z$ `+ I) x# P5 L9 k
; U& ^5 d9 k5 [/ f// Dummy Implementation to be used when no other implementation is available, P( F" Y) L" Q2 Q. U% ^3 q% g
class CUPnPImplNone: public CUPnPImpl
+ ^9 w) b3 q: m" O! X: {{
0 w" N r( B. m5 y" y4 Q- V+ [public:
- h) b& c3 k9 g5 E( f Q+ I virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }6 E3 U2 W9 v7 H, ]3 ^, g# y! O% V
virtual bool CheckAndRefresh() { return false; }
1 K" I6 X0 c! S- E/ u virtual void StopAsyncFind() { }5 l5 E% h6 Z. L2 k; k
virtual void DeletePorts() { }
+ W% A. p# ~1 h" Z/ {& L8 E/ V virtual bool IsReady() { return false; }/ q! f( y4 t# @( \% V1 n- l
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }. r. g% ~3 v1 Q1 R
};
' ^; P- Y; x! L8 X& e/ m- e( P
6 ` I" j7 v+ X1 ^, M. b B$ n, @! S: g8 R& @
/////////////////////////////////////; M2 I/ |8 E) G7 y- F
//下面是使用windows操作系统自带的UPNP功能的子类
+ j T" [+ |- m0 C8 ~
' c2 I( a. g n5 f9 H! P$ {- F1 v8 E% L5 E; L
#pragma once
5 U) n; G5 X. ~, _, O# \#pragma warning( disable: 4355 )# {1 g4 `+ F! U
& e) C1 e) A. D6 ~' [7 b2 ~% J
8 `3 G9 N6 i% k! f. s
#include "UPnPImpl.h"
) q5 }6 T+ ^3 w1 |* g( Y( `#include <upnp.h>% D: w( X9 l. U O7 B" g; ^
#include <iphlpapi.h>
1 c1 \1 Z# {: c2 H: _" n; m$ i#include <comdef.h>
$ e1 C! [5 v+ O" \& N7 A! A( V: @#include <winsvc.h>5 y5 R( v! G/ S
* Y& n& ]& i2 X/ p$ _* z9 H* g
2 c) `0 y/ `: V( e8 j#include <vector>
& G/ ~+ g9 h) T! w: @( A0 T#include <exception>7 t0 }* ]' J8 D( A) p
#include <functional>. k2 q" m/ |4 u/ B0 Q
/ T3 [) D7 F7 _2 v. v4 a% F
9 `5 I6 S7 j% ~: w( d5 ?" {; b
7 |# S4 k' Q9 H+ e; k& Y3 R' F9 F- j; o) J: L$ t" [
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;' L, j# U8 D, U1 v
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 C$ M- w/ M" l7 a2 R+ V5 N1 E( n
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
% v* d2 ^! A9 j. W8 f: vtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
6 L9 v' e0 @' K( Ktypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" Z" a# b. k1 x; }# }% Y% e2 Rtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
4 C* h7 C* d9 v; @2 X( utypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 X! S" @" x/ l+ n
" v0 g0 c) l* d; G
3 G- D) Y5 s z* M. q8 \" Y! ftypedef DWORD (WINAPI* TGetBestInterface) (
) `, i+ N. A L$ V$ E3 d IPAddr dwDestAddr,
3 x% E2 c" |+ ^9 _0 \1 I PDWORD pdwBestIfIndex
% t- N4 z6 m8 c$ D* n$ a) p* \);, V7 i9 u: f7 ~- m
/ r: W2 i7 }( `0 K* i* e( ], ~1 i
# L( y2 _, w+ @' v. _6 t& C1 M& C
typedef DWORD (WINAPI* TGetIpAddrTable) (' H2 n+ i- Q' B* T: z/ ]
PMIB_IPADDRTABLE pIpAddrTable,
4 K6 p- N9 E7 R/ W PULONG pdwSize,# j4 C5 J4 z7 ^1 H* Q
BOOL bOrder; S+ \/ s0 U- T( B E6 B
);
; u! |1 r) q/ M3 l7 E1 O: _) t4 j
5 G- m1 @# H- R1 K6 U
* ?# S0 R$ ?& E( h h7 T0 e7 @3 Dtypedef DWORD (WINAPI* TGetIfEntry) (
- S2 v! i& ]3 A4 B w7 J PMIB_IFROW pIfRow; b( S2 v* K+ N* k3 Y9 G
);/ c# r9 `2 n) B( y* W" F
, g; @+ c0 ?+ P3 d% s
& B" F0 t/ ]6 ?- r4 E( M3 Y
CString translateUPnPResult(HRESULT hr);& j0 L( m3 i& @2 x" f0 i, E) \
HRESULT UPnPMessage(HRESULT hr);
( H1 K4 P- J, U5 o8 F5 N; b3 d& G& a
9 t; j- f' d' W6 q
class CUPnPImplWinServ: public CUPnPImpl
6 W8 q; ^* i+ A: s{; e ~7 U! p0 v! z0 o8 f6 j
friend class CDeviceFinderCallback;2 B: K8 Z0 S* p! ~" o
friend class CServiceCallback;
+ K3 N1 w- P# B// Construction
% u# B& [8 A0 `1 A6 J% }4 J3 D8 b( Epublic:6 b- k; A" J9 P6 h" O; u a" F, z9 b
virtual ~CUPnPImplWinServ(); D2 U6 j* H4 M; _6 M
CUPnPImplWinServ();( g/ r! B$ ?7 Z1 b$ X, F5 \
" v/ o- E l8 ^8 F5 h6 r" v& _5 `( ]. }, R! k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
1 E7 }1 b& I' X# [ virtual void StopAsyncFind();
' {/ e$ W1 W7 p; C& l ~+ ? virtual void DeletePorts();3 Q0 N* c5 E ]+ r8 M5 e
virtual bool IsReady();/ c/ L- w6 O* l9 }" C" V" y1 {
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, `! l: K" f+ S0 D. q1 ]) T' X4 L F3 c# }5 v# k
( [6 g8 u" e& G // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
& x* x, z$ i3 e' C7 {, i // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
3 `+ Y2 x% {2 M/ x9 j% d6 _ virtual bool CheckAndRefresh() { return false; };
2 d: Q0 C1 f1 e9 h& L$ m1 _; r5 G2 h4 j$ F
5 P# F, I+ z& p! o+ r4 D- I
protected:
$ U# N2 i5 K5 d( s# U void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 X0 T, z L" t( K& b void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
( W, R$ k& e. s( i: V/ `4 d% Y6 A0 ]) ` void RemoveDevice(CComBSTR bsUDN);0 X' d" C9 k- f5 T7 {6 d& D
bool OnSearchComplete();- V. _3 g. L. ~' z7 ~: r" B/ b- P* `
void Init();1 p8 P% h0 Q: v4 E
! s: N1 o+ w& J! k" ?
& s% o) I0 k) X& b: }5 j9 m" N* N! f
inline bool IsAsyncFindRunning() ' B) m( \1 w0 l P5 d8 G; S
{
/ T0 d8 C, B5 L. z+ I if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
! ] |& _1 S) [6 Y8 k% c {
- z8 z8 h$ ?2 t" A m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
+ |: T& x) R1 Z l' I; D m_bAsyncFindRunning = false;$ D* {/ W$ o( h0 }- Q* k
}
- d& D3 c. s' J* k MSG msg;+ M' D* |% f3 E( F2 W
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6 D2 |; ?# _: n1 G. M5 c4 n% B {
7 O! d1 s6 Y t1 C4 ]3 Z TranslateMessage( &msg );& y4 Y" A8 M. [, u9 U# @1 l& [3 \
DispatchMessage( &msg ); F: B0 t. \: P! E+ O/ H) N" j
}
3 F) M2 _% d( ?3 h4 u! j return m_bAsyncFindRunning;
5 ]: D" \4 A1 d) E+ m- N0 G }: A9 ^- X/ W* I
4 n8 z8 A" [. ^' E& ]- ~) G; h
$ ~5 \/ o: O5 R& Q' H' J" ^ TRISTATE m_bUPnPDeviceConnected;
3 |9 `+ x+ o9 C8 @& t" @/ x& E/ m6 D) r6 d* T6 `
# a0 B& [4 f+ {4 X* A4 u// Implementation
$ C' ~! r4 U( A; ?4 g // API functions
5 u6 Y8 q6 C- ~: s. d SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
" H- z2 c3 x9 E7 u( S4 ~) @ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
& P2 [# z' Z5 J BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
9 M5 T9 D! H9 l8 L8 Y6 u( Z BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
0 F1 b- q$ P( k( m1 } BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 E- v# t) N+ }2 X/ ^4 j$ P
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ n- X; {8 t. ]; P+ ?
0 O2 M4 k, e# f: O
) E- `% q- f8 }: p5 g' `4 }6 I TGetBestInterface m_pfGetBestInterface;# x1 R6 u3 S, L2 T j; r# S
TGetIpAddrTable m_pfGetIpAddrTable;
* [0 w4 e* a2 H! e TGetIfEntry m_pfGetIfEntry;
2 M; g. g+ z8 q5 [' T0 z) B- p; {' R* E; Y( p0 ^
7 E$ |7 G# t; `( T: s static FinderPointer CreateFinderInstance();5 K* k9 H) a$ {2 D
struct FindDevice : std::unary_function< DevicePointer, bool >
( u6 |5 b- a$ s) F) S {
& s$ S) Q; q& }" V' y8 ? FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 `; h3 w/ f( |; i' C% @
result_type operator()(argument_type device) const
& D: p; e8 s! S+ D {' r0 `. l0 Z2 ~: c: b# `
CComBSTR deviceName;
* ^. F6 d( q. ^- [ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
) ~6 ]: B1 ~6 U5 B" n$ h( R! r& g/ `; O; p; z+ `; E
& l5 \$ F1 f' b' _1 Y5 J
if ( FAILED( hr ) )$ R! W* y b6 }: n
return UPnPMessage( hr ), false;9 g8 I9 K D2 v* d: C
8 l1 N& p" M8 i' O% Z) n( C
( I1 ^- Y' s! u5 k return wcscmp( deviceName.m_str, m_udn ) == 0;/ T) |$ N/ a& n
}
$ H% T- A1 e: T6 m: K CComBSTR m_udn;# B9 N+ h5 i* E) w
};$ D& F) h! D: t
' k" p. h0 a9 `6 v6 v& { void ProcessAsyncFind(CComBSTR bsSearchType);
) ]5 _4 ]. o5 f) ]( } HRESULT GetDeviceServices(DevicePointer pDevice);
- L, {' x7 p8 D# e" c* t void StartPortMapping();
5 V/ z0 ]+ e, D; L+ [! X HRESULT MapPort(const ServicePointer& service);- A. e2 j2 Y7 V( B6 O d
void DeleteExistingPortMappings(ServicePointer pService);
' D% D/ k' j2 g: i. e5 z void CreatePortMappings(ServicePointer pService);+ E& h { I. a; ]8 i7 T
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
% Y# I5 c1 R6 ?2 I( h7 d: G HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* y4 I, B) k0 y& ^7 n$ I LPCTSTR pszInArgString, CString& strResult);
1 ~6 q4 ^+ Y7 y1 I% |3 v4 M/ V3 w void StopUPnPService();
9 y$ Z( }0 f( ^: ?1 z' R4 L
% L4 S1 R( K6 e4 s3 z5 k$ C& D# @9 f* Y0 d- |# Y
// Utility functions
7 y4 M9 P8 ^5 r HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);& k0 C- ~: \& t& a3 K9 c# k
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
# G: \3 s# W' O& g+ C! c$ } INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
9 y+ a% M" X1 b- D {0 V+ Q6 M void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);/ E: R- K8 {0 W0 @3 a1 {
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
& i1 I1 p( F1 u" D; p HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
' [1 {3 z6 D$ b6 {4 b2 e5 U1 D1 X CString GetLocalRoutableIP(ServicePointer pService);
; q4 {+ Z1 q n [4 k s# g0 W+ g) j& k; L9 U$ z) Z4 e& {
; ~$ e" I# S3 ~# W+ }// Private members7 A- Z* e2 q$ I t: f
private: e& E9 ~* }) j* s# y2 Y6 ?
DWORD m_tLastEvent; // When the last event was received?
5 Y5 Q4 `" k" M( \ std::vector< DevicePointer > m_pDevices;
* j" Y" y+ s: b std::vector< ServicePointer > m_pServices;0 M5 M8 ] B# n- @! c
FinderPointer m_pDeviceFinder; K* e, \, F# Q( o# c& Z( y
DeviceFinderCallback m_pDeviceFinderCallback;' h4 s" P; l& E& d
ServiceCallback m_pServiceCallback;. A' }9 h( x5 w" l
3 L- L* ?% h6 g/ }
1 J( A% m) O" }) o3 Q, _ LONG m_nAsyncFindHandle;
2 Y4 i3 x$ e7 Z) f' X bool m_bCOM;+ M4 k2 h/ e w+ X' e/ w% f& D; c
bool m_bPortIsFree;
k) }0 N3 U; J' _4 [9 N9 v CString m_sLocalIP;$ h, l* ^. s6 b
CString m_sExternalIP;2 C, e6 w* Q8 I# K4 F( C
bool m_bADSL; // Is the device ADSL?" | k: p w; G' P: f4 m
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
4 [! [9 n* n4 Y$ l$ X4 _ bool m_bInited;
' q5 N- E; W; X" v( L5 [ bool m_bAsyncFindRunning;
- |9 @; S. y3 I& _6 }& E HMODULE m_hADVAPI32_DLL;3 h, d+ e9 O @, R: b+ k2 I
HMODULE m_hIPHLPAPI_DLL;
. a" g$ F6 U% B% t bool m_bSecondTry;" i. E4 J4 k `- e1 L
bool m_bServiceStartedByEmule;
5 u. r' y# w5 E, Z9 H bool m_bDisableWANIPSetup;
% i+ ]: U. k/ V bool m_bDisableWANPPPSetup;
/ C; f! B c* E" n7 ?" j" o& Q0 ]5 l1 I- U" a: u
. W3 u8 A0 o6 `* E3 l};
- o% M# e& J4 c4 m! r* x/ h8 y0 X' ? K( p
8 z+ H: J4 W/ K( w
// DeviceFinder Callback
# F! q' C% l4 `2 \ xclass CDeviceFinderCallback
: L# I0 d: A5 L; \ : public IUPnPDeviceFinderCallback
, e' v! y3 l; P3 g3 b9 G{
, K _5 x% {# e5 h# S9 ]/ Fpublic:6 [6 K2 ?- o- d1 x3 S' W- h
CDeviceFinderCallback(CUPnPImplWinServ& instance); w: \8 Q4 j- n) r& \# S
: m_instance( instance )
' c& N/ w& @ K' K { m_lRefCount = 0; }
$ G8 I( Q4 x0 Q9 } I3 r$ N0 k# f9 ?* g# k- O5 I9 d9 d
6 N% B9 ~' [9 s" N8 C& x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
7 m l; d7 M: G) Z STDMETHODIMP_(ULONG) AddRef();
) W: y- e) q7 U5 m+ R STDMETHODIMP_(ULONG) Release();
8 s5 l, J8 W8 N# A- Y
. d. E! ^+ e% L+ s
P- v0 L: |5 M! e// implementation$ I9 n% ^! B/ E6 m! g! A
private:
" H; i: e/ ~: [4 t+ X R HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( U! {9 H2 Y; {2 y: C9 D
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);7 {( E5 C7 ~ {7 ]6 t& |
HRESULT __stdcall SearchComplete(LONG nFindData);
: V$ w+ s- X, ~3 X! ?) H8 Q" k, \2 C5 ]0 f8 T0 Z6 Y' @% B
x" B+ o& V, L1 Uprivate:' b: @5 ?& O, l8 {; c3 k
CUPnPImplWinServ& m_instance;
0 E( _& ~* E {: T* L. C. u LONG m_lRefCount;
2 s4 g! X5 U9 B0 z5 R};
3 N( q8 U0 v W; n$ ~: ~' s" S$ A* {6 L
# `% u0 [6 r" g( ~$ e6 J
// Service Callback
I5 @: s# x) D, |+ B) r2 h- Uclass CServiceCallback
' b" d) B& g8 h9 S3 e9 L9 C6 q : public IUPnPServiceCallback
: J; l0 J( P: R; R* ?{
8 ^3 P8 \7 [# Y, I" S5 ppublic:
" Z7 U8 a2 k! p6 U- c0 w CServiceCallback(CUPnPImplWinServ& instance)2 [- N, O2 C' ?8 ^1 p$ q! o3 P
: m_instance( instance )8 d, F2 z7 v) `" a
{ m_lRefCount = 0; }3 b3 W$ M9 m& b$ M% N# w
' l( }& E, M( }( | STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 q6 v7 f: T2 B STDMETHODIMP_(ULONG) AddRef();0 k V/ n, B; A8 W, I7 y
STDMETHODIMP_(ULONG) Release();
( m, p% \8 P7 G' d
" C5 X! [1 E- A' b! t" Y T8 v) w' J {2 R. B G% s( G% b
// implementation
/ x+ |: P; r0 Z4 `4 L" s5 u& kprivate:
+ S+ D/ _$ {4 p' f! ]. |0 X% v HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);) Q) C: Y4 t, e7 s9 u8 y3 [: t
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);3 d. Z7 E8 B% A: F
- O# E v* M/ R7 t) @. _9 y( b- ^
# l* o6 q/ ?& K0 f
private:
* k0 y6 i/ M( j# P3 ~* J( `" y CUPnPImplWinServ& m_instance;
: {- @! O$ r3 k+ J LONG m_lRefCount;% g5 ~3 U& w1 x6 W# I1 N+ Z
};
6 {" [2 O. H! c7 }0 o: X
% O1 O% E) z& R: a, g6 H7 {9 C
8 @5 x! _4 V! Y3 _/////////////////////////////////////////////////9 `; b7 ~& T9 }; o/ l$ ?" D& D0 n/ \
; u2 X9 ?3 V' j2 U
# F1 \( D& \2 d" x) l
使用时只需要使用抽象类的接口。
, w, ]9 P2 T& m' Q9 S1 RCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; d9 d9 D+ |: ?% s# \" m8 b
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口./ h( I3 k6 f5 ~* P# w
CUPnPImpl::StopAsyncFind停止设备查找.& u8 j& W4 U3 l' ~+ ~* B% y# A
CUPnPImpl::DeletePorts删除端口映射. |
|