|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
! }- |/ k7 [8 [8 p' z+ a! J* |& {1 ] H$ d! f4 U7 R
4 f: C% g* l) f///////////////////////////////////////////, e) g2 I: [. W- I+ u
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.# O! L3 z8 \% L3 ?- ?
8 G7 I) }) {* E$ H" A n( O; m
- K- W3 _ j/ B+ B; S( C#pragma once" q! @2 d& ~$ L: e7 w6 f6 m4 s
#include <exception>; s4 w, P3 Z. S* w% w
: A8 M( F6 a- d- @2 S
" ?4 f1 i/ y2 m- Y( J+ {3 ?2 h enum TRISTATE{' D7 V# S, h( P2 N, d6 N7 k5 _
TRIS_FALSE," B9 ^: g6 E4 g) e/ P! n: t
TRIS_UNKNOWN," p) f' L3 W9 b6 y6 Q2 v) W! \
TRIS_TRUE" t% U4 B; G7 L7 N, Q
};8 J$ _$ C, v/ V1 z4 k
' u5 | k( ~, h& d, e8 F" i+ T& U+ I# m
enum UPNP_IMPLEMENTATION{0 m6 a8 ]( i9 G* ^8 n
UPNP_IMPL_WINDOWSERVICE = 0,1 L. e! g+ \6 Z* Y
UPNP_IMPL_MINIUPNPLIB,
* P" I; b* Z- b1 J e UPNP_IMPL_NONE /*last*/2 \0 j) i1 @3 L1 l
};
$ P* \+ _! j4 @6 M& ]- v/ v0 `# d) {0 A
$ ?# U8 Y( ^! ]$ ~( T6 ?
; O! R$ ?- F: R/ N+ n3 A( v a. E& O/ T" Z& D7 e. o3 t$ u
class CUPnPImpl5 F9 m. F* U- w9 |- l$ z! _
{* z& J& e6 s0 m" o" C |3 T6 Y
public:
2 N! ~0 h5 \/ k3 `4 Y* g CUPnPImpl();6 z8 T6 n5 x5 Q- X# A v
virtual ~CUPnPImpl();" |; x6 R: f/ a4 @; p% q; w% D
struct UPnPError : std::exception {};
2 M5 b6 u$ Y) ~- s, R enum {
# a( P- y) R# A/ @. @: ~: k4 q; T7 U. l UPNP_OK,8 N j; r/ u" b
UPNP_FAILED,! Y2 U8 J4 ]: N
UPNP_TIMEOUT% C0 a9 m, ?: b& v( w5 U! E3 B
};
0 a/ l( k/ y! C( y
$ A# n! J1 s) [% E; W9 v
1 ^( I" B, \% ], l# g+ N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
5 S2 h. W4 X6 C' S' Y$ x virtual bool CheckAndRefresh() = 0;
& p0 F1 n1 K1 n/ d- r$ E5 f virtual void StopAsyncFind() = 0;
- c! t/ _: A' J/ }# s/ c& r- ]+ l virtual void DeletePorts() = 0;0 Z3 H0 y' O9 R. K1 h
virtual bool IsReady() = 0;, @9 I3 n9 O+ R5 p' t$ |( d( i
virtual int GetImplementationID() = 0;
2 a# y6 ^6 y; h" k
# m. f) K U f! c! E! j void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping8 I" |: b. q; V0 u" }- H4 c
* L; y8 E+ ]4 B. w( m" ]
! k" N, V" C7 A/ _0 M0 A void SetMessageOnResult(HWND hWindow, UINT nMessageID);
: C; @& ^ o# o$ _/ p TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }- b8 l8 M7 T5 M8 T& O. E7 ^4 T
uint16 GetUsedTCPPort() { return m_nTCPPort; }0 r, T% M7 Q. b L
uint16 GetUsedUDPPort() { return m_nUDPPort; } ! w- p' ~& M' X8 F
: g, @+ j" k9 y& T
$ W# a6 u3 [3 \) R
// Implementation3 T0 @ T+ X! r! V& Y$ g
protected:
" N) L( P7 A. b4 b+ G volatile TRISTATE m_bUPnPPortsForwarded;
* c. Q8 F3 m+ [! M* ]6 u, e void SendResultMessage();
& U: \& ?( E7 d uint16 m_nUDPPort;# ], E4 ~2 d$ }" n' I! L. J/ G8 _& c: r
uint16 m_nTCPPort;
7 S7 F0 ^( X) p. Q$ R$ f uint16 m_nTCPWebPort;$ y9 k/ f2 S: h
bool m_bCheckAndRefresh;, }$ L# D7 I4 E8 h. k/ `! A, J
7 G: }1 I* Z$ {) M; l9 y; t4 y3 q
5 z: Z" u, X' F& |1 u
private:
" D5 n1 F! [0 w$ i6 y" O HWND m_hResultMessageWindow;
2 ]+ J/ ^% s( p5 A UINT m_nResultMessageID;% X3 E9 ~9 ]* W" v! r# u( ]
3 j2 D2 B$ M" x+ q' R9 j) r$ a; @" E: ?& t, `9 Y) y
};1 _: G* ~; Q+ h( b' }8 Y' }
- m( b) ?4 O! v" w* S' n8 `' d( Q1 {9 j0 W: A7 e4 `
// Dummy Implementation to be used when no other implementation is available4 Q3 F) Y8 ?: [4 x- f- L( J
class CUPnPImplNone: public CUPnPImpl
7 o9 b: X7 W* {: b3 A* ?7 k: t{8 t4 I8 ^1 @2 T" p, m5 k
public:2 |+ `" x0 ^) r" K
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }0 U T: C3 [& W, D) h$ _# K
virtual bool CheckAndRefresh() { return false; }% [9 G8 Z& Z; }; j# h& u. }
virtual void StopAsyncFind() { }: r7 w4 c& h6 F4 O0 _+ p4 ~9 H4 F
virtual void DeletePorts() { }0 `3 X5 H. R1 f, S9 m# Y! W
virtual bool IsReady() { return false; }8 t2 b+ m4 u4 |, o, p( O( a8 i3 v# s
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }3 o* }# u/ {* L. b4 G5 r9 @
};1 y# |) A+ r. I/ M* {1 D
# O2 ?3 I0 o" v! F& w) Y
, [( w3 q" X0 C- }% S6 D" ~
/////////////////////////////////////# A; _+ s/ W/ Q
//下面是使用windows操作系统自带的UPNP功能的子类& Z. F6 R' y5 K
1 R! x3 a& j f# z% ]2 Q) [/ w) L0 _+ R6 H& r: g, j- W
#pragma once
3 ^" e: }; Q( B: j5 p, z9 M#pragma warning( disable: 4355 )
7 f' j p1 E5 A: k# x: g3 J
. _2 {5 T+ t9 }7 f9 B+ v8 ]6 u; K, y7 I9 B, s, T
#include "UPnPImpl.h"( D6 n* G- y5 U+ |
#include <upnp.h>- q/ [! t( j5 a+ y& M `+ L" X
#include <iphlpapi.h>
# @4 x' `5 `7 m2 X, f( ]9 _# K#include <comdef.h>
/ e) o/ m: Y) r#include <winsvc.h>) L) E( K# x M, W
3 @. j! K+ c, q3 ^2 K& |# S1 k5 v; u9 r+ A$ W( s' Y$ p. E b
#include <vector>: L$ I% s1 ?. Z9 j' ^- L. S
#include <exception>
; R, G; M6 Q- ]/ h7 \+ y& @2 @#include <functional>
3 a. S3 d3 B( _1 x2 h. k0 Q7 i3 b1 t6 Z) e* l" Y% |
2 t: z$ d4 B& @: V8 @$ }5 l
. s0 q+ X4 W; M' A
" G7 k8 y2 f, W) Rtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 q9 L& e$ x& q# x* W5 itypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;! s _+ ~0 _, R: ]5 D/ b3 [
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
6 B, a& s3 O' n1 |typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;1 E) l" ~1 K. \- F5 R8 T% \3 C
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 p! v! p4 j& h: ~0 L% @2 `
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
# \7 W' Y( [' g9 U# n. z' btypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;9 u: Y: H' U% z; A. M6 }
7 S/ _' F N1 r" K
; H! @4 N! ?8 {) d( Y4 N6 c: Ptypedef DWORD (WINAPI* TGetBestInterface) (
' W+ x" x/ _& [ IPAddr dwDestAddr,/ ?/ C, ^% O. ]- r) b
PDWORD pdwBestIfIndex- A0 r1 Q5 g' X* E
);
: s: k' `% X2 V( X! @. Y2 x, _" l/ C5 L2 B
- Q% {0 H; v$ ^5 S, wtypedef DWORD (WINAPI* TGetIpAddrTable) (
; K& _7 A5 S% Q* @ PMIB_IPADDRTABLE pIpAddrTable,
3 o+ Z% A {9 |6 t PULONG pdwSize,8 \3 s* [+ @* S+ ~2 O/ l4 r0 ?
BOOL bOrder
Y, ?3 E/ Q* J& A3 s);" c" N6 n4 S# G; f9 v
4 j: w: j" V' \- }. R5 y! e4 d2 J8 O, @& Y
typedef DWORD (WINAPI* TGetIfEntry) (
- ~) f6 u, w! r6 a+ a PMIB_IFROW pIfRow- U9 {# i% t" }5 v6 [
);4 [$ b' ~% B& L% l- A( C
6 D! x& B# A# k" E: x3 I
# b6 N" L. h+ Q$ B7 UCString translateUPnPResult(HRESULT hr);
( i4 ~4 U8 O& h& QHRESULT UPnPMessage(HRESULT hr);4 D" `5 X s: l( a
; Q7 W9 [9 X% s! T$ A1 V+ N
4 z" Z( K7 F3 {6 {. n4 m1 Z; Iclass CUPnPImplWinServ: public CUPnPImpl
$ K+ t3 v5 T/ R{
* m( o0 T! I u6 P6 c& Q friend class CDeviceFinderCallback;$ x# S3 T; E9 f# u4 E
friend class CServiceCallback;
. Z& b& C5 R. D& A' p9 V* }// Construction
1 y$ z% O; ?3 v4 E2 p: G4 ?+ lpublic:8 p# k- N6 t# ^2 P% e+ W
virtual ~CUPnPImplWinServ();% B0 B! J# O+ ~1 s# Y: v# V& S% h2 Q F
CUPnPImplWinServ();6 E9 n: j2 l# i9 X
- e: ?. t1 P) x' l$ z. s
. d" M! k, u* h( e6 H% } virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. C. [" G9 a4 C6 l& r( d virtual void StopAsyncFind();
8 T8 f7 h7 J1 A virtual void DeletePorts();! Y2 p: C3 Q7 p% `( E" _2 [
virtual bool IsReady();
: @, U: e( u, g6 P C$ c virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }7 P$ Q2 r$ x! D# u9 P# u
% h" v3 p+ o8 r _
3 z( u- q4 O+ w7 t8 L9 g' |+ i8 w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
7 v2 O0 ]2 U. m7 ~' j" j3 c // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later2 z! _9 D& n7 R! k# H S
virtual bool CheckAndRefresh() { return false; };% x$ [9 R. ?1 A
) B/ b: S0 G: c& q7 o7 ^* a* V4 T# d# O
protected:: y: e& O- A' c, z; y! s
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( s+ k, r" G2 z$ I void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);2 T/ o& s+ G- J! t& o4 u
void RemoveDevice(CComBSTR bsUDN);
2 I/ d, o5 D' V+ G5 l c4 Z bool OnSearchComplete();
9 U4 Z$ j1 a2 l void Init();
, v3 ~, u, W& j$ N% ]
) c' i2 H7 G4 d( b1 L9 B, |% K N" V6 i* q u% |. z' D0 E
inline bool IsAsyncFindRunning() " I, O E; z# y( x! y* X# i
{/ p1 f1 H2 G3 _6 N; g7 u
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )2 v7 J Y* Y5 V; |
{
8 ^( X1 q& Y9 w0 K3 U7 K& ] m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );3 ?% }4 O, y; @( N8 ^/ ?5 }3 h
m_bAsyncFindRunning = false;' A2 t4 L, \! k5 j3 y
}+ W z- j: X* U( h8 X% k7 @
MSG msg;
# a1 h! A2 h6 D r while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )0 e3 ^ J: R! i4 Z8 d$ ?0 E
{8 h9 [" i( Q- J
TranslateMessage( &msg );5 Z% z/ L6 ?5 U( z. E* ~
DispatchMessage( &msg );/ e0 z! n. Q+ D3 F/ a- V
}4 m9 l! L( p3 S0 A' Y( G
return m_bAsyncFindRunning;* g: N2 h2 \6 A. i! [- J- V* O
}
0 N: X7 ]; t n1 p$ i( G
$ s7 `0 b- [0 x! _. j
+ J! s( m6 l+ i+ k# q8 A8 z$ n6 x TRISTATE m_bUPnPDeviceConnected;7 E$ p' v6 u$ Y5 ^$ Y& E0 x* [5 C
9 q0 P2 C a8 S" k) Y- j
) \. S1 g6 E8 i- a& I) @+ v5 w4 k
// Implementation+ o5 v% _' H& T
// API functions& h! W" [; D2 z. l& m
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 B; S+ M: P0 M8 S( j9 ? SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
9 L6 }5 c" [4 \0 D BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
, K9 w/ e$ u/ w( o+ r BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
2 p2 o2 g. K7 A0 }8 g6 u3 Y8 ? BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
1 ]5 _% Y. t' m, J BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);4 m7 Z: O7 x1 P+ a7 o+ H. R
' j, U3 e& v& u' Q1 S9 E0 ~
7 d. j* {5 [) [ TGetBestInterface m_pfGetBestInterface;6 ~. l1 k m; `+ b
TGetIpAddrTable m_pfGetIpAddrTable;$ G/ r& z& n+ M1 r
TGetIfEntry m_pfGetIfEntry;# d8 a; i3 X9 A0 J. L% ~
- ?9 l8 r! |. H% c3 x
7 J/ W5 S& I. L" b2 W7 C
static FinderPointer CreateFinderInstance();
d. d, L6 _% |2 w struct FindDevice : std::unary_function< DevicePointer, bool >+ n0 G; X% a* v5 r$ [5 P/ J; A
{
8 g" k! K7 D$ N4 _. M- H4 S, k FindDevice(const CComBSTR& udn) : m_udn( udn ) {}8 q' m: f! G" j7 @5 d7 w( E8 _
result_type operator()(argument_type device) const
/ A9 }! K3 y/ a* s; W- I0 h3 u( ] {
: z( R$ ]' r2 `1 V9 D CComBSTR deviceName;* J3 J$ g& i% j) _
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( o/ G/ d" Z& i( `4 [* c% [; [5 S8 x [0 W: q
) U5 n4 _: d3 H- G9 G
if ( FAILED( hr ) )/ E& x9 y; u- ]1 y$ b/ d
return UPnPMessage( hr ), false;
# ]3 u) U( X( K
, G0 C' u: ~6 E
( R: I6 Y2 o, u; d return wcscmp( deviceName.m_str, m_udn ) == 0;! _9 Y7 z6 u/ f, [( ]
}0 o! B5 \+ j- L% V
CComBSTR m_udn;% t4 J; h ]! k
};
4 @4 G- I& { Q3 O , {/ c# e w1 N, C* ]4 |' l' ] e
void ProcessAsyncFind(CComBSTR bsSearchType);4 I& N* z) _ l8 X
HRESULT GetDeviceServices(DevicePointer pDevice);
7 N- p8 P3 y$ W' n v void StartPortMapping();
8 x: M; _2 Z0 |+ v+ j HRESULT MapPort(const ServicePointer& service);
I$ |, @( H6 g void DeleteExistingPortMappings(ServicePointer pService);
7 M" Z( D$ E. x9 G. |/ o3 L void CreatePortMappings(ServicePointer pService);/ ], k/ k0 H; r( ~$ e
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);- u1 E% s8 A# E0 I
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: b3 N* D6 r4 S# @9 F& g# k- e LPCTSTR pszInArgString, CString& strResult);$ D) b+ |3 H5 A
void StopUPnPService();4 c; {3 M2 }0 i/ D! @
$ ^, s2 B% t: Y3 p. I: N7 {* g2 N! K6 q# z3 Y* P9 m
// Utility functions
8 N1 b4 l. r% V HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
- h! t- j8 p2 V8 Q% X* j( C3 ? INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);0 ~- T' E. q% x" h0 y
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);5 c) b3 }$ j" @1 u9 e! ~; M) n8 q
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);) P- C4 |7 p7 o# e6 B6 l
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);' z' A8 H2 O' s
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- x, v! p1 R5 }. z CString GetLocalRoutableIP(ServicePointer pService);
# h; u. O9 w: C3 \4 k# @& W6 G# f8 b+ E
1 i, c* o1 |0 Y1 a! f// Private members
8 E" x1 Q8 d: ^- i( C- i3 Jprivate:
7 }9 D3 |$ j, _ E+ ^+ p& x DWORD m_tLastEvent; // When the last event was received?3 n8 A" J: k1 |9 K0 D2 C3 a8 P* d
std::vector< DevicePointer > m_pDevices;1 j% I1 f N( z, P
std::vector< ServicePointer > m_pServices;9 o# x% e% n: C* n
FinderPointer m_pDeviceFinder;
7 Z, R7 T( j; q$ _& v0 m. x. ~ DeviceFinderCallback m_pDeviceFinderCallback;
" T# z+ F6 S0 x v; m7 R9 c8 [ ServiceCallback m_pServiceCallback;
8 Y' b& ?2 } S: A; p4 o: T/ M
0 g$ B5 N" m6 a& m# H y5 F& a w7 o7 p0 o* I+ \
LONG m_nAsyncFindHandle;
/ n% s1 V" g4 V# |0 | bool m_bCOM;
5 P! J3 \3 y1 v% @' f; L6 a$ B bool m_bPortIsFree;
6 ~' u2 |- k$ V% G! {. E; i3 i1 ? CString m_sLocalIP;
6 U0 B+ \4 \$ v/ P3 u* P CString m_sExternalIP;4 \* Y* s5 Y. u/ e& C
bool m_bADSL; // Is the device ADSL?
% l! E8 k8 e* W( v" a* U bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
3 H% D: t9 M d% r$ Q5 ^+ G bool m_bInited;. m0 l2 e& b! i' N2 B ^9 Q
bool m_bAsyncFindRunning;7 H$ l' _! H1 g" Z$ v8 g
HMODULE m_hADVAPI32_DLL;. m% g; o0 T* }+ T9 ^* s
HMODULE m_hIPHLPAPI_DLL;& M& l* ]6 Q9 U \5 G
bool m_bSecondTry;
, l1 X! ?: q6 Q3 X! S" s bool m_bServiceStartedByEmule;
" r q' X# U# c$ T' x bool m_bDisableWANIPSetup;% B! ?- i/ h5 g1 o
bool m_bDisableWANPPPSetup; [; \& M" o# }
2 q6 L L4 H& ]; ?' S% S% i! p: ?; N+ i; o
};( L& l8 b4 [$ r+ l( I- V/ N
7 ^- z8 K9 k3 C/ ~3 b0 l. n p5 R
1 I+ R0 v7 C: M% S3 t// DeviceFinder Callback
- v6 k9 Q0 Y) i# D2 d1 D, [6 |- Rclass CDeviceFinderCallback) H- V2 v( l- V1 b3 P3 E
: public IUPnPDeviceFinderCallback B7 E2 e! Q6 n: U
{
6 [" M( i3 `/ B1 xpublic:& h s+ M6 T4 o3 e4 { V \) z
CDeviceFinderCallback(CUPnPImplWinServ& instance)2 C" G) [, W2 o
: m_instance( instance )5 V" [, v& P# x# z; P! @4 L
{ m_lRefCount = 0; }
4 {( B& u. n. k/ n6 W" M* {6 N, {8 g6 t* N
+ r" N+ ]7 o( \& @' K( N STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 H4 C3 B& R0 Z# [
STDMETHODIMP_(ULONG) AddRef();
$ } N* P3 F( O. q+ w+ l# p STDMETHODIMP_(ULONG) Release();
4 z# m& b/ [4 G2 G6 l6 v3 o# p
% x+ Y. @- C$ y& g: N( j4 Q4 i( W5 A
// implementation2 O6 c8 O3 G9 _, O* r
private:
/ q. q, w- J, k; W9 o HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& k p# Y$ B1 {+ @
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);* Q0 X P8 d) c
HRESULT __stdcall SearchComplete(LONG nFindData);; x/ A& ]) B$ {# U, `4 V3 y
. ]" q% H. N6 ?2 t7 D
% o1 a R0 m5 fprivate:
a9 b0 Y' K5 Z5 @ CUPnPImplWinServ& m_instance;
$ C/ M1 Y0 Y7 q& Y% G9 I LONG m_lRefCount;
$ E6 V( B; m# N( o: O};
( m2 h2 Y5 K g5 X ~/ E: x$ O. v* C# ~
) ?) c) q% x7 M2 L& ^// Service Callback , @3 |/ w, m4 @$ m2 N' a
class CServiceCallback
+ z/ o' a7 P4 s4 ~ : public IUPnPServiceCallback
& ^: ]2 F" v& H2 o( W: O# e! C, [{
( {2 t; e" R, k) j" Bpublic:7 B" X0 r3 z6 e$ a9 g6 a7 s1 b% C
CServiceCallback(CUPnPImplWinServ& instance)3 _! S G5 v. F" T C
: m_instance( instance )( [* ~# n5 D# R7 W4 U; d
{ m_lRefCount = 0; }- M! s5 |* i% I- C8 p: C
$ _/ t6 [4 A; r2 i! q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);6 k! V0 a8 R1 g* Y% m5 G
STDMETHODIMP_(ULONG) AddRef();* w9 t) g3 T7 ^: A8 Q$ K8 L
STDMETHODIMP_(ULONG) Release();4 l- b4 x2 k* S6 S7 m$ G4 d
. a2 E' y0 c0 P% E6 D1 K/ m. ^. y' ^. A& V/ y3 g
// implementation
Q7 e6 c9 _0 o8 N7 M Wprivate:
- ]# P5 _: [. A1 N/ @ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
% r" y. \# _6 {# @) j HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);; V. f3 U: K9 t+ T5 q
! ?2 _! I) S3 k1 J2 j) |
9 F7 j, e5 n% b8 K9 [1 r, g8 R6 Rprivate:: h# Z: _2 M: o! q K4 G, a
CUPnPImplWinServ& m_instance;
1 M- w2 W$ z% t. ]8 o LONG m_lRefCount;
: P, B0 @6 k$ P& M' a% f* B L};
' P, P; t9 O0 Q9 f
4 q; h/ n" M5 X A; a, [8 `$ o1 G3 u# G" S
/////////////////////////////////////////////////# i# j: ~/ D2 c% J/ M
! N6 u. V. v* `; P _ ` y7 R& Q
使用时只需要使用抽象类的接口。6 y, [! d# t1 H/ E1 C# p$ n m
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. @5 o+ H2 u8 v7 e4 Z
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
1 W) W, i/ R& Y3 V, R8 R) {, j* s) MCUPnPImpl::StopAsyncFind停止设备查找.) \8 B) W' k0 X2 u& t' R" y a; v
CUPnPImpl::DeletePorts删除端口映射. |
|