|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 D" K# T+ F8 n0 ]5 @
$ ~$ l% a$ U% ]+ ^
! ~9 }2 j. A: x6 X' O
///////////////////////////////////////////2 X2 S& t3 s K2 [, f" s
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
7 u6 f; T0 ~* f& W0 z- J* l( w K+ S# L/ _, ]
: R& v% D& M: H% L" q l#pragma once
7 E1 G9 D$ e" H5 A! |#include <exception>0 j J' r1 @+ i( G: `# u3 l
+ Z1 K; { k& { @8 {+ |* z
7 k0 H# v1 M. K4 \$ a6 [
enum TRISTATE{
* s" u* K4 r9 `3 P: T TRIS_FALSE,6 h% h* o2 c, @: R, O0 k3 n6 {5 c
TRIS_UNKNOWN,
5 m( n/ C V0 i! p% P Z5 P TRIS_TRUE
/ r* \$ U5 ^8 m+ Q, j$ t};7 P, g! o, ^5 t2 A- o9 {/ L# W# `. G
% X! q/ x X; S8 ~( o/ {2 }, j9 N
- ]$ V' V0 ?$ M1 a# B0 oenum UPNP_IMPLEMENTATION{
/ w6 X$ d0 F I- i0 t UPNP_IMPL_WINDOWSERVICE = 0,4 v+ j' a; h2 R5 g5 _
UPNP_IMPL_MINIUPNPLIB,
3 m. X' b6 W, v! } UPNP_IMPL_NONE /*last*// E. L6 l' E/ ~5 I/ ~
};
3 D& f4 V8 W! ?* ^* @
; T, i/ {; z6 q/ [! h8 r* k' f$ d) a& w( h1 W- o
$ A0 b. P" v! ? U5 q1 ~' x' m4 C6 y1 m4 D$ F6 H
class CUPnPImpl
5 F) C1 T8 D4 t+ y3 x5 U; M+ R{
# K2 D/ I1 q: R1 Fpublic:6 v% V1 ^. l8 e# n6 ~
CUPnPImpl();' d' R( I }+ o; |( M- l
virtual ~CUPnPImpl();8 d' ^0 T/ r, _' w
struct UPnPError : std::exception {};
5 b; ^/ C& v1 q: F4 S$ e1 p* I enum {( w$ k2 r4 B: S7 `; K/ O7 L; r* o
UPNP_OK,+ k9 u; } q+ L" V4 ?6 `, a* q* @8 ^
UPNP_FAILED," w+ R' p' |& r5 T
UPNP_TIMEOUT
$ ?7 r- W8 t6 v; k };0 X5 r4 x; a+ h/ b% m
1 l [+ q- ~/ F9 X7 X i I
9 W/ P8 Z/ n5 M! N3 |
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
+ X' x! h9 E9 F9 V9 {6 D/ F3 {0 f virtual bool CheckAndRefresh() = 0;: u+ l1 S, I# O: V
virtual void StopAsyncFind() = 0;
4 x% P$ ?2 H& {# X# l' a) v1 ? virtual void DeletePorts() = 0;2 P w5 T% X8 H* b: ]$ a/ I/ U
virtual bool IsReady() = 0;
+ f+ |, |0 {6 p; s8 M7 r virtual int GetImplementationID() = 0;9 r5 ?1 |2 B; U
% h& i6 b6 \. d' D: M, X void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping7 _6 V* t a& @6 n. O" | s
# Z5 u) v- a/ P8 }) s1 ]6 w0 `
5 U2 i3 S+ Z* P4 e% a i4 u9 X
void SetMessageOnResult(HWND hWindow, UINT nMessageID);+ [8 \( `7 w9 O
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
9 u. [* _1 u! s; z, V% [2 r uint16 GetUsedTCPPort() { return m_nTCPPort; }+ D( ]$ d7 l7 q
uint16 GetUsedUDPPort() { return m_nUDPPort; }
" j$ p. y; i( p, A' N& k2 i# m; G2 S) |+ ^1 q
+ j+ w ]" U3 h* o% B$ v' @
// Implementation3 `! Q7 H4 p. \2 E
protected:! s; z8 o k+ ?5 Y' g) U) H
volatile TRISTATE m_bUPnPPortsForwarded;+ L3 z- m' H1 u- F2 E/ O5 K
void SendResultMessage();
6 r& y, m; @ T2 \7 H uint16 m_nUDPPort;
0 p$ t. j. Z: \ uint16 m_nTCPPort;
! P X( K3 g5 r' @7 v uint16 m_nTCPWebPort;: K! S0 U' ^8 e1 S
bool m_bCheckAndRefresh;
3 A& [2 G5 d$ S# g2 W
' m* X, x7 ?4 ~. P+ K; e: W; F
# `' y" n1 L7 R$ `3 W- @& W& ?private:5 I8 q% \; o/ n0 w7 |/ v- a+ n: H
HWND m_hResultMessageWindow;
4 |( W6 c% f% B/ _' Q q# h. K UINT m_nResultMessageID;
5 G o, s( u" O) {) H" M! G% x# e$ X6 c! o0 V5 K Y; @; o9 e# R- E
g( j* a2 O# I};
0 {+ b3 I9 Y; J) y, A* Z5 v4 N% y" I [% ^4 Y/ N
# F+ s2 E u- ]( A* b
// Dummy Implementation to be used when no other implementation is available7 w5 c. ], h- T. x
class CUPnPImplNone: public CUPnPImpl5 H& p7 L: z0 Z9 |; h4 y# _
{" q& L+ f) `% W* b
public:9 j, U, D! O7 _/ Q) ~- n
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
; A* Q+ w* j- O5 u6 L virtual bool CheckAndRefresh() { return false; }
) g' A# |% a, e virtual void StopAsyncFind() { }4 R( r v2 Q T' P9 E) v
virtual void DeletePorts() { }
1 k9 Z) D7 }! r virtual bool IsReady() { return false; }
" F9 {1 O5 h' o* S) I* u virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% ?; s( d; Y2 Y% ~# S- F
};% c+ O Z* e7 Q4 M7 j; J
# u' z b) c' G/ a4 a) O/ d
% n5 z( x; y9 q/////////////////////////////////////9 H, I# B. k- t( r
//下面是使用windows操作系统自带的UPNP功能的子类0 P i6 \! r" { L3 G3 n
/ X, F8 S3 d, L: @$ O) X
7 p* C1 \& }3 ~% ^) J2 W% Q+ c# B
#pragma once
+ {/ b8 [6 J6 f1 p#pragma warning( disable: 4355 )2 p& l$ ]( Y. I0 G" P$ v/ n' J
9 g0 U3 V' l, ?$ s; a4 E
+ ~/ D) l$ ~, c; H9 [2 D1 _#include "UPnPImpl.h"% a6 ~. h% K$ [2 r/ _; @& n
#include <upnp.h>
5 W3 S3 H* z) m1 `#include <iphlpapi.h>
/ E4 i1 P- y. E$ m( u( v#include <comdef.h>+ U5 B5 B% \& k7 C
#include <winsvc.h>% x; ^0 C# ~3 h' T6 D' X
- Q; Z. S8 o" U) w7 T% P& i9 k* [. P" I
#include <vector>" G& E& r9 b1 K$ { i
#include <exception>/ [5 y$ g4 x- _ k# q4 F$ d5 S
#include <functional>, M O9 ]1 Q4 d& d" G5 ~5 |: s
$ W: v* l, p0 Q/ ^; r1 D9 F; E
1 W" I" r4 v1 ?9 O7 ~. J7 R/ k; ~1 T! @$ S' p s9 T
4 T; Y$ P7 K# G
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
* `6 n" z; `2 w5 Ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
4 F8 e1 f: ?' F1 Z( ]: Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;, t5 [7 O; ~4 o$ `3 [0 R9 h7 C
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
5 s4 t$ m" I. J" ]( O6 k9 Ltypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 y( m' w* x3 c8 F! G' j0 ptypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;3 z; T9 U: S( D+ G
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ f$ T4 C6 j, R9 ~
8 P/ L" Z4 f; [3 h3 S* T5 y
8 f& _8 _* ]; i/ S; N* I
typedef DWORD (WINAPI* TGetBestInterface) (
' f1 B) P( k X IPAddr dwDestAddr,) K# `" F. ^! f- c# m
PDWORD pdwBestIfIndex
/ {2 ^5 J& N! b: ~8 E* f$ ^);8 ^, @; n* Y% D( {, A. N
6 z3 w2 g( x z3 q- |5 U, _( C7 d8 ^" m) m& O
typedef DWORD (WINAPI* TGetIpAddrTable) (6 C/ l ]6 s, Y0 Y# o( @$ p& ~
PMIB_IPADDRTABLE pIpAddrTable,) c& e# [; K6 ^4 u! q5 I8 o
PULONG pdwSize,* m# j4 u+ a8 e# h* G# C r, X! ~
BOOL bOrder3 d) `2 n9 l: X- j* U1 O* V
);
0 l* o5 X9 D8 I. B4 j( q+ w
1 V( @- V5 T' p
. t6 R1 |1 y' M+ ]" h# r8 Ttypedef DWORD (WINAPI* TGetIfEntry) (, Y! B' E- c Z* a) [* r( j5 Z
PMIB_IFROW pIfRow
! W9 N% k5 W! x+ x0 J. M);7 N1 c8 @6 I( f0 p0 ~% G
9 S9 P1 W+ e( m7 i* p; K1 E$ }
) G% K7 n* [5 J( G; w9 sCString translateUPnPResult(HRESULT hr);7 ~- q5 h9 d6 p- j* M
HRESULT UPnPMessage(HRESULT hr);
' ^5 i: E. ~" S$ Y/ N$ ?( j, Z8 M; n' O5 K; a
, a9 I: I2 j5 sclass CUPnPImplWinServ: public CUPnPImpl, b3 W* M' \% }5 F
{3 I4 a& `1 A4 b1 @0 r/ j
friend class CDeviceFinderCallback;: h/ V# o; ~, Q
friend class CServiceCallback;% G+ F6 Z' E; ^ M2 y* Y
// Construction
- l4 e- J0 K; A. W. r5 \7 w2 m8 \public:; u% d1 y* \! G' H* f9 _+ f
virtual ~CUPnPImplWinServ();
5 ]( e9 ?- S4 i- W$ [8 l+ x! x CUPnPImplWinServ();
' a! w6 E7 C9 i$ j1 I5 H0 I, E
" f- b* H% @# ? h0 \% A' k# ^4 ]& r7 L" E1 R$ ~
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
( t8 y5 X# u. g5 Y: c m8 H. ~8 `. l virtual void StopAsyncFind();1 f5 `. I" y- z0 _9 E s* W
virtual void DeletePorts();
1 @ O# [4 _7 | virtual bool IsReady();
; F1 W/ U8 R1 ] virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; } H( i$ O' Y8 J) \8 D5 u& X n
* R* {; @+ v# [% v8 C& a" T
+ `4 c# Z9 `1 X- c; m" g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)3 o& y s0 J* w
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
0 F3 O: J0 [9 {( @( P0 `$ A virtual bool CheckAndRefresh() { return false; };
* T: d w. d4 C& ?
* ]' B1 T$ z/ l/ Y T/ T+ `, @* ?+ ]6 C6 n) F- _" Q2 P4 t
protected:9 L, y. `$ N1 c9 s6 h- H
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& p7 ]6 }4 A3 b& ?8 w2 g! J5 @ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
( A5 y/ K- R% [3 Z6 a1 f9 A void RemoveDevice(CComBSTR bsUDN);
, w' f4 r$ S+ n8 |8 @+ [& c/ a! k0 h bool OnSearchComplete();
) C; x& c( i: q+ P. Q void Init();# M0 Y1 R, b/ d3 A, E1 a" y
8 \- p5 f0 d& N E- d+ N$ m* X; M
& T8 U5 P+ b" u2 u& k5 U inline bool IsAsyncFindRunning()
8 r! C; P7 n: V9 p$ Z* g {$ ^. Y( l/ d& \8 F6 G1 i
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )" R7 k" _5 E6 w; V, t0 H
{
; ?! S/ M: f/ t& r m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );" d q- ^5 E9 p g6 O& Y
m_bAsyncFindRunning = false;8 O5 X, d) X; F2 G" q
}
7 R) M* l# \0 F1 n) p/ ^ MSG msg;
8 y+ y% n5 \& G+ @! S; X0 g. v( r( C while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
3 U1 d! o' ^: M0 c$ q {! n! E6 ^, {; y
TranslateMessage( &msg );
1 h; f* g6 C6 a$ e& y' y DispatchMessage( &msg );
' D3 x y" Q1 a" X T }) m9 f) I# `4 q& L2 u
return m_bAsyncFindRunning;
) O" ^0 k9 s6 S' l" T }
4 V4 h7 x, w, C2 F1 B/ B& }0 ]% @& y' v4 q
$ L0 e8 N& y, U
TRISTATE m_bUPnPDeviceConnected;
7 Q( T0 l/ y8 S) x
0 A, y8 Q3 `% m9 T: y* i
/ Q( q* R0 x) u9 d4 ^, |+ N7 k) ?7 `5 N// Implementation. ?% C/ e) L5 ^& i! H3 _
// API functions
! D/ i6 U: o/ Y: ]' ^ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD); K. K- R( f, W3 U" o
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);) @% T7 k! }+ S
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
: J; I- x- ]2 R& o; e1 e BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% @* {6 M' `4 h+ i0 T
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
! Y) m/ T2 ^) H. O BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 W& C. Z& `; \$ q# B' T2 G6 P& G$ Z
0 X" e# M. |& i, Q: O' l3 Y% w- P" A
TGetBestInterface m_pfGetBestInterface;
" v$ q" s) \6 b1 G6 o TGetIpAddrTable m_pfGetIpAddrTable;
& J" i g" K6 u TGetIfEntry m_pfGetIfEntry;" @- X. {" i1 _, K9 D7 c
# A# n- F0 p9 \, S: I, M4 D" m8 c9 Q- w& ~4 u
static FinderPointer CreateFinderInstance();
- G1 n3 X$ l7 S' g! N9 Y struct FindDevice : std::unary_function< DevicePointer, bool >* ^& w# {4 W+ p# `4 L
{: N( j/ W, w1 ^; T- ~# s
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
6 N; [+ e7 O+ ]5 U& n; q$ v: T% w$ h result_type operator()(argument_type device) const/ Z" a5 L, I% V( N# r; m- W
{* W; b3 a# p8 U# b9 f' o7 ^5 n) F
CComBSTR deviceName;
: i- e9 [1 y+ r r; h% V HRESULT hr = device->get_UniqueDeviceName( &deviceName );
$ n6 w0 @1 Z) l) y
9 w0 V: `1 J, T
0 i5 A) n1 n" \* _ if ( FAILED( hr ) )0 U: f9 i1 I0 J' ?7 u- q
return UPnPMessage( hr ), false;4 K6 H$ x" x7 [( Q" _: Q
6 g" [7 B( m& y8 f6 t. K
2 u/ D6 f# p6 @0 ]
return wcscmp( deviceName.m_str, m_udn ) == 0;
2 h! n! J- t+ N, j& l+ f& Y }& J, ]5 ~- R, X' ~ t+ }6 {! N( n) J
CComBSTR m_udn;
1 ]) o/ W8 h, o2 ^+ h };
2 m' g) G( P: L% @% [5 c/ A
* K2 Q, h1 s% x. D! c9 V void ProcessAsyncFind(CComBSTR bsSearchType);& e2 ?+ Z% o8 f+ n4 K& A
HRESULT GetDeviceServices(DevicePointer pDevice);
# ?, D- @4 }1 H7 l4 X4 i void StartPortMapping();
5 h- o! p% N8 V5 j7 l HRESULT MapPort(const ServicePointer& service);
# _0 b2 u8 ^# y% y* V: t, d: _ void DeleteExistingPortMappings(ServicePointer pService);
/ w3 A2 E- e5 X/ q3 c void CreatePortMappings(ServicePointer pService);% A/ J7 G8 y: C9 @4 N% m, }8 J# Y
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);+ N9 v' k# A' S
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 L# Z% h( P& s' y) a& d LPCTSTR pszInArgString, CString& strResult);
1 [; v& j0 w0 i5 H. R void StopUPnPService();
3 ~, c9 M' @! ]8 _; ~/ R! M8 \
- p9 n7 ]$ [7 |& ~; z+ I) ?
* `# ?- B% F- t" [ // Utility functions
- v/ I5 x9 s! d5 `$ ]* a HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
7 v( Y& k5 F- t; n5 v INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
9 ?7 L+ ?" ^% g% ^9 Y8 e ?4 a INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);4 y1 m ]8 a- H9 v
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
5 e- Y+ N3 u1 b+ y HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);3 ~3 {! Q6 b, W3 H! l
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
7 O$ Q1 u6 h3 M7 N CString GetLocalRoutableIP(ServicePointer pService);! ?8 u& z) ^2 }) S$ ~! k7 A3 }
# T, Z" H( X1 O' {6 U
# s1 O4 z5 x# o5 ~. @8 F' t8 ^1 c
// Private members$ t: L# N" F- I. F3 e
private:2 H o6 f! G9 T3 j( i
DWORD m_tLastEvent; // When the last event was received?- f" ?1 O# M: d/ o$ M. ?) [0 [
std::vector< DevicePointer > m_pDevices;% n' s7 L: W; M& t: {; T* s
std::vector< ServicePointer > m_pServices;5 Y) E% N [+ d5 @
FinderPointer m_pDeviceFinder;
( t7 X) H: r% Q7 t. [( N* D$ L' c DeviceFinderCallback m_pDeviceFinderCallback;
" I& u$ C( X7 J ServiceCallback m_pServiceCallback;
) {. w( G0 W4 b* c1 q
7 M+ L# Y1 W7 ?$ C8 g; S
$ t, A& A" G2 L8 A/ a$ `5 N* Z. } LONG m_nAsyncFindHandle;
5 k% X( f0 o$ H- W bool m_bCOM;
- f7 D) J) b( }2 f) d bool m_bPortIsFree;, Y3 g+ ^' X2 B+ P5 c C. ^' u
CString m_sLocalIP;) m1 z$ a, o/ {, l9 L
CString m_sExternalIP;
! q T" a$ J7 T' T' s: T bool m_bADSL; // Is the device ADSL? q5 A) n. U8 r
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?% i8 R5 ^9 n( Z! L8 G
bool m_bInited;
" f/ h$ m3 Q; Q. q* |$ R% o7 b1 K bool m_bAsyncFindRunning;( O5 H1 _8 z+ v4 S5 x$ p
HMODULE m_hADVAPI32_DLL;
4 f( G0 e- k9 y' R# W HMODULE m_hIPHLPAPI_DLL;
2 Z9 G3 A5 [' k) E# t1 ^ bool m_bSecondTry;
3 y w) b& ]6 x bool m_bServiceStartedByEmule;0 z: E8 n# B7 S5 M [
bool m_bDisableWANIPSetup;
" E0 u- ?( y* @ s' e5 ]# Z- ? bool m_bDisableWANPPPSetup;
/ g- C! F( T A) E/ I7 V0 l. a }
" f3 ~7 }2 ], @7 S5 d) @; o# \# }* t2 u" @! ]2 K
};
. Q+ v/ ~7 ]" z. \6 O- r$ V% A8 @& r8 @7 U+ |( r. G% \) v
3 ` M' ~+ z; R; U5 x" g3 x// DeviceFinder Callback3 @$ q6 F$ N* A& S4 W
class CDeviceFinderCallback8 [7 E6 R' i, M; C+ `$ l
: public IUPnPDeviceFinderCallback$ Y. }9 U2 t2 |7 K
{; E$ a% w1 M- h( x8 H v& s0 e
public:8 E" ~7 c0 l" n0 N* q
CDeviceFinderCallback(CUPnPImplWinServ& instance)
# U5 D4 _2 a3 T! a$ e: u : m_instance( instance )
( T$ `' ]6 i! }9 f { m_lRefCount = 0; }
( x* ]9 k, N' C9 Q' U8 W: v' H3 z" K, @
$ l+ C" O Z! J8 j
* ]4 u/ k! a2 P! U0 P! p# n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);+ ?) ^3 w. b! e" O, x/ t
STDMETHODIMP_(ULONG) AddRef();
, t! C- Q* ^: c: G& B. S$ {# [ STDMETHODIMP_(ULONG) Release();
- n3 x/ d9 Q) ]6 P& ^! l' z. q- m1 L! G( [
2 N6 Q1 {% I) D6 t// implementation0 c* A- P/ }0 ]1 o( p+ x
private:
6 ]( E) [' o& N/ H$ L; F& I# V, ^ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
5 k1 t8 H# `& K3 z HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
d+ r( v. i8 @) | HRESULT __stdcall SearchComplete(LONG nFindData);4 D. k: T8 i$ c* g
" a9 S3 T7 l% F* L: r Q0 a+ J, W$ B; L, j! I9 n
private:
7 {$ W% P9 l7 d8 ~ CUPnPImplWinServ& m_instance;
+ r+ H* ^! u% ^: L6 h5 F LONG m_lRefCount;8 @( }; Y' M. u4 a+ ~8 m$ E8 e
};
7 D! u5 r9 R( w+ r- r; Y# c# K$ l8 L t7 J1 O( ?- d8 Y) n) G9 f0 F: \4 H
4 O( K3 P1 K9 z2 p A6 `& |& q// Service Callback 6 p3 h, `. L* }6 f. v6 K
class CServiceCallback
2 t; X2 w, l* i5 y" V1 a : public IUPnPServiceCallback
) M3 d' o' N$ A/ \' N% ^{) I" ]0 W( p# [- u/ }* y1 F1 U
public:
! O9 I" M( E: I- T CServiceCallback(CUPnPImplWinServ& instance). H% c- f" H6 T$ g
: m_instance( instance )' Q' a7 c2 {' A1 X+ u
{ m_lRefCount = 0; }
! R; l# h9 S; y
: F0 D8 ~! @: }( v$ M STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% p; Z* r5 s( N1 n3 _
STDMETHODIMP_(ULONG) AddRef();
0 X# Y& [7 X$ a$ Q/ L, N% x# H" x STDMETHODIMP_(ULONG) Release();
5 ^; s* L. E! e4 o1 ]
0 I0 `+ w6 Z( g- J* o" I, |1 I, l6 d/ Z
// implementation
* c: H) W. u. T3 I) d) w+ mprivate:: y, G5 x1 v2 d
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);. p- C- w8 j# J! C2 o9 B
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& W6 C9 @2 [5 j- | e; D' p
) p% P3 x1 C' g v
+ G; U1 }6 v7 ]1 Z: z
private:
( s l* A( I' {9 j" S5 @0 S, @0 C CUPnPImplWinServ& m_instance;: M* l, d c( m0 z" x& Z
LONG m_lRefCount;
?+ H/ F" |, \};* u! Y/ _$ {2 {. U
# c0 C' K7 w4 j K- [ D
/ s. }, K/ q5 E/ o% Z; Q& \
/////////////////////////////////////////////////
+ V3 {8 \, a& Q( R0 i$ p
) a& N0 }* q8 n
7 Y7 S* T% \4 s3 B! o( R- C' g使用时只需要使用抽象类的接口。
9 S6 a2 s7 S1 V7 z. ICUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
^, N5 ?+ ~4 UCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 p" O& ]0 X, bCUPnPImpl::StopAsyncFind停止设备查找.0 H! d- B/ ]( K8 m" k ^
CUPnPImpl::DeletePorts删除端口映射. |
|