|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ z7 I% x2 ~/ M, z0 S9 t
% g! @8 J9 ~, X. c2 `; T
: T# _! e" l. H: ] _4 z u///////////////////////////////////////////
9 s/ r0 Z+ j; U//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
8 z! P5 Z5 }1 @( G0 a# T$ ?) c. O, A+ W0 @
- ]/ ~$ @5 `1 N1 b1 p+ \#pragma once, V, x5 F$ X E2 L3 M& s7 z3 Z. H1 ^
#include <exception>
; d# Z. P- i5 @, w9 L. [* N5 }' r: u/ P9 r" ^' X# B( [
! B# ~1 x" Y/ Y8 | enum TRISTATE{3 E( O* {& h, [ A+ c* ]5 d
TRIS_FALSE,
6 ^9 P$ Y$ O2 d TRIS_UNKNOWN,
& R5 X9 \& H. D# Q+ G2 w TRIS_TRUE
; D- r7 x7 [- T% z5 k# I# R};
; ~+ Z! Z: O# r! Y( e
/ `& G) {9 Q# _% E3 b6 D3 N: \1 w4 G$ _) O, C! m
enum UPNP_IMPLEMENTATION{- r z7 @. k) a# y6 m& _0 e, ?
UPNP_IMPL_WINDOWSERVICE = 0,
) z: _8 r+ E( _9 o3 C( j UPNP_IMPL_MINIUPNPLIB,/ M* _) ~; J0 U
UPNP_IMPL_NONE /*last*/+ h. R5 A- O' m; }- C
};& y: ?; ^8 {8 P- @, O
* b3 i# w3 z, @. N$ v) J" O+ b- k- y! {! s) q( _9 K; n
P8 s: T6 Q! e" o! M4 L4 B
. C' D' \' D- k" P; ?9 S% U2 ^class CUPnPImpl& W4 s$ T) w. T4 S
{! g9 a& [$ |, q) o( r+ y* U# C
public:
8 D1 e( ~0 i j" F9 F$ o/ H CUPnPImpl();
5 H# P6 b7 x* r! `9 c: L7 ]& d virtual ~CUPnPImpl();
2 E& T% F9 u% H/ f4 d& T struct UPnPError : std::exception {};! }! f- {1 j" @4 n( x- B
enum {
/ ~" ~& ?% y( ~, J& x9 f UPNP_OK,$ `8 ?7 m& Z7 z, y" {
UPNP_FAILED,0 J$ E& A. z9 }, T2 j3 j4 i: _
UPNP_TIMEOUT% q3 i* Q* s" \* _/ Y" O9 S
};3 f" _9 P% l0 t5 s- g8 y; t5 h P
5 ~! i# s' r8 ?8 C9 J: Y H% S2 V# E a( u' R3 t D8 R7 R" t! W7 m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
' o0 e: c3 A3 r2 T, k virtual bool CheckAndRefresh() = 0;$ f. q0 Y! C" s" O% d3 N/ q, t
virtual void StopAsyncFind() = 0;+ m6 b, K# ?$ t/ P& D7 P/ n1 u3 g# y
virtual void DeletePorts() = 0;
! ~, t( x+ M0 j" [ virtual bool IsReady() = 0;
- x/ F2 p2 n8 F virtual int GetImplementationID() = 0;" T! ^9 j# R5 X
- ]; y0 ]5 a6 O! N2 E; ]
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping& f- ?! @( }# U L
' L" {$ j+ W/ d! H' Y" E
$ m4 @& w4 u9 A+ l) o
void SetMessageOnResult(HWND hWindow, UINT nMessageID);% d8 Z7 }* l: T/ Z$ v7 C1 X
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }" F' I# n! V% |7 u7 a" }
uint16 GetUsedTCPPort() { return m_nTCPPort; }
" j6 p5 n$ D; h( @: k. k8 d, z# R* n uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 w/ r" `# o5 K6 P7 V! x# O) X4 R4 n5 V0 o! W4 t& t4 B4 ]# _
+ L) T2 h# Z0 G
// Implementation
5 R* Y& J% Z7 x V2 Gprotected:, T1 a7 k* r' H& j1 u1 J. L2 Q' g
volatile TRISTATE m_bUPnPPortsForwarded;
3 W, k% p( L' Y- N void SendResultMessage();
# ]% Q5 @4 `8 |. E, S7 {/ p: h u9 I uint16 m_nUDPPort;3 D& f, H. g1 n" \9 ^% y
uint16 m_nTCPPort;
4 V& I6 H/ A9 _, ?# w) _8 Q uint16 m_nTCPWebPort;* Q% W0 V' `1 T$ Q7 i+ M$ y1 F4 C
bool m_bCheckAndRefresh;( @+ g+ f! f) u2 j$ `" c
3 i4 s5 B, z8 [, N0 E0 ~6 z3 }- {* m
! ^/ y0 z! }& W3 M8 a1 kprivate:
& W1 h( T1 E8 p% U HWND m_hResultMessageWindow;
; O- f4 z$ D5 c s9 d UINT m_nResultMessageID;6 {. E; Y3 E6 }+ @' \
4 u! ^8 _# ?3 Q s( u
7 K3 w( c& r. r- v) e ~) g
};
: |0 c8 C! u' y( z: ]; e& o
1 C, \9 I ^6 ]. M6 V( S
{, t/ C) T2 H3 S1 h! J// Dummy Implementation to be used when no other implementation is available
: Z: A: Y. b9 u mclass CUPnPImplNone: public CUPnPImpl
, l' A+ j* ~; a+ u. j; x" o# Y{+ f) ^, x+ n6 [) Y
public:
6 ]; ]& x) [ m* i virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 @3 Y V1 v4 ]1 ~/ U9 H( ?, L Q virtual bool CheckAndRefresh() { return false; }
/ j+ ?$ ^7 ~$ s; f virtual void StopAsyncFind() { }' _, o: I! _: F9 z7 G; I& l" m
virtual void DeletePorts() { }
2 A3 s* v4 B* ~- ~ H9 ]* U8 e virtual bool IsReady() { return false; }
8 i! b3 |5 K6 q8 x virtual int GetImplementationID() { return UPNP_IMPL_NONE; }; a( Q9 N! M) V/ a9 }
};& S6 _# U; c8 f7 n" [
% r) o6 k: P t, j) |
$ H" S6 G5 W' L5 a% _7 }$ K/////////////////////////////////////
6 o& E4 o/ Q/ Z% J0 i6 _//下面是使用windows操作系统自带的UPNP功能的子类) W0 ]6 n0 D& }: v; [" k
4 p6 U. W U& c8 I+ o# U
7 V. G8 A) y% c, h1 @#pragma once
% l8 ^3 _5 H0 A6 p; H2 ^" h#pragma warning( disable: 4355 )1 N& r6 M8 @' B! Y
8 F6 M- }6 ~1 {8 ?, Q9 F7 Q
0 W: n6 V$ \6 N9 Z#include "UPnPImpl.h"
$ Z8 x( d$ f [7 i# y! Q#include <upnp.h>7 ~$ u) Q' b( v6 a& `* f1 y! S
#include <iphlpapi.h>
' ~' c6 Q5 j% h6 F9 i#include <comdef.h>
! _* z4 y4 g8 s0 T#include <winsvc.h>
* h/ G6 c7 D2 u6 }& |- d# l9 ^; h( H0 M" u7 x
+ f& {4 }8 |9 E* ?+ I# h5 u% C#include <vector> u9 r1 N1 l/ m' r9 k4 z/ N4 U
#include <exception>
x( N e6 v3 W8 w#include <functional>
: y) n& [# `$ b- @1 \" u8 j
9 ^: K0 s* G$ g/ @ ]
6 }& g: _& A7 n6 o; b# O& m( H9 P, w' x* A$ T" S
& S; ?3 d% C/ P* Ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;0 T$ v# ~ H1 p! ^( t' T; M
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
3 ~: ~- |6 \* h1 v( t- h, ctypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
* g; S* O2 a r" utypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;# O. N$ J- r }4 i* I
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
( G N( j7 n {. Itypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;# [* o! X: r2 h' a% A) B: t8 v
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 ^7 T" p4 e9 d/ |
, _1 [' u& L4 M
, k; P! |3 R& ]# f* C4 i6 A3 Wtypedef DWORD (WINAPI* TGetBestInterface) (
2 M( N$ t' j% X) @& h$ B" M IPAddr dwDestAddr,
1 I! S. R6 I% j# ~ PDWORD pdwBestIfIndex
& Y$ t5 L& u5 b) i);$ K# k0 M: |9 b6 W5 q& \5 k S3 s
8 K# Z. i# T7 M
3 r# O- S. B: x3 [1 C
typedef DWORD (WINAPI* TGetIpAddrTable) (% i- y4 S A) K* s
PMIB_IPADDRTABLE pIpAddrTable,
( z8 R) T! I+ Z6 Z" x5 t3 u* _ PULONG pdwSize,
& N* U+ X! r; `) i5 w BOOL bOrder
) `, ]: g0 s1 U: D);
6 ?' q7 Y' D1 G( V, [+ ~0 S0 L0 l3 r: } U2 m1 K
3 g9 A" g- ~. P4 W
typedef DWORD (WINAPI* TGetIfEntry) (
# _# v7 w- D$ ]; m0 h PMIB_IFROW pIfRow4 s( u0 r" H5 k
);' E4 ^! ^! |. B" m9 n& _ c
6 V# h9 s: I: J& |7 o$ q: \
& e* d, m* F; }; G; \
CString translateUPnPResult(HRESULT hr);
% Q! @; }& M1 B! w e q1 `5 dHRESULT UPnPMessage(HRESULT hr);5 ~4 W& Q4 h9 o2 t4 \% F
, M; y1 D7 J& r Z; k+ F
0 `3 |' d0 o2 Y2 J* ^" Z5 w) Xclass CUPnPImplWinServ: public CUPnPImpl, y$ Y5 |* o! z r( ~5 \% A1 O
{6 O% _2 F; y( s6 a3 C, |7 P. U
friend class CDeviceFinderCallback;
0 w9 H# v! |( g7 d friend class CServiceCallback;1 @- \+ i% s9 U
// Construction
8 g, O6 d7 b& L O8 npublic:' Z; c: @& f8 c N* V* g
virtual ~CUPnPImplWinServ();% _5 ]! o' D. @/ k: [$ i$ B
CUPnPImplWinServ(); o0 K, @9 w' R
* \7 _( ^. s; h: W% E2 e
; ^8 q' c0 N4 i! O: s; ~ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
7 j/ H# ~3 _( v) d virtual void StopAsyncFind();7 S, J! k/ Q) b N! P
virtual void DeletePorts();
6 w# K; n7 _* p8 h virtual bool IsReady();" a3 u3 x0 \2 b! n" T
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 R* y0 i+ U% L: n* ^" ^) U5 s2 d) X* m$ ^8 M2 z
8 J# ?: N9 L# D$ \! o' i* j // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% c2 z8 b9 ], k6 A* @) |8 n // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 L& v* Z9 p9 }: s+ h3 s virtual bool CheckAndRefresh() { return false; };
3 p$ F E% h2 X% g) b A$ ^( E- B+ b
0 c* N2 w% T' f# S
protected:
, z) P6 G+ x; e3 v3 K( V void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);* E3 B8 N+ M* Q! Q
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);/ d' S9 F5 H4 _" d1 j
void RemoveDevice(CComBSTR bsUDN);
1 i2 Z8 [# t0 I* A0 y bool OnSearchComplete();$ n# F |+ j1 G) s- `" Y+ f
void Init();
5 S8 _* z; \6 w. e1 f( y o& @7 |; f/ h& w9 ?' a2 H3 p( D
' D1 d P- `- O; e, E& g& Q- T
inline bool IsAsyncFindRunning() 8 Z: e7 c3 p2 Z: j/ M- Z
{
3 n0 e8 n4 Y/ m# Z4 A if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )% I c' |0 M0 v9 S, c' ?" r
{
: x/ S- y Q. T0 R% O* Z9 v m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
. ~# B' g/ k s6 L m_bAsyncFindRunning = false;2 j. f2 o' N& h8 I
}2 A F$ g/ [2 X( G8 z
MSG msg;
% ^3 Z5 G% O0 q/ _. j while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )% S! s) P$ I7 A0 Q: L" ^- q
{* r$ C8 T+ O2 a8 O5 c* U: N: M
TranslateMessage( &msg );
' q G5 B& s4 a. M2 Z6 y DispatchMessage( &msg );9 r2 b9 w1 |# N
}, e3 p; n1 h. s Z; Q( R6 M
return m_bAsyncFindRunning;
3 b, l1 @ Z, p; y# {: E/ M }
& A. Z. z# ]2 \$ u) P1 O4 S4 b" T# s( J/ t
8 D0 g5 g _$ z8 Q7 a TRISTATE m_bUPnPDeviceConnected;+ Y/ Z" i, t: l$ h! ^% C
! H- r+ w! B5 P$ x/ n
4 O; P* R2 T9 E4 ^// Implementation$ C9 T! y5 o: y7 z ]/ K
// API functions8 J4 X- }% L5 X& @5 ^4 `
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);) E2 s) R! R$ ~4 }5 o
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, {/ l1 K" p/ [3 ~# N0 j& w
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);6 \8 \ v& l1 w- J; F
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
1 h* y, M2 q3 k+ T BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& w6 g9 m* O, i7 J: P
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
. }+ Y, u* w0 z( C! v. a0 G/ m3 o0 ~/ L2 L$ G5 h% u1 }
- v% O+ q' k7 _/ C8 j! C
TGetBestInterface m_pfGetBestInterface;
- P: B: s5 ^9 G+ z2 G8 ] TGetIpAddrTable m_pfGetIpAddrTable;7 m) i; B$ m7 T q( {- ?4 l" u% K+ h
TGetIfEntry m_pfGetIfEntry;1 p* \( k/ ]8 Z; K
1 L) f" x% ~6 g% i. m
Y- E- O, |6 m/ U4 R+ ~ static FinderPointer CreateFinderInstance();1 H9 |% a: n' K# Z2 A! m
struct FindDevice : std::unary_function< DevicePointer, bool >; F9 ]( t3 p" n& }& w4 k2 T5 H* @
{! J! r' Z: e+ Q0 T& v J9 J
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 K# K5 _) w* `2 N% g result_type operator()(argument_type device) const
+ t1 Q# n# j0 h3 @ {
. K9 U& @' P, B# |( T CComBSTR deviceName;$ E: |: W6 O' F( H- s9 Y9 v n8 C
HRESULT hr = device->get_UniqueDeviceName( &deviceName );! X( u5 y# p* e" {. @2 m
4 v: T; O$ V" b- \% n- p" }8 ?2 W; v1 j9 {
if ( FAILED( hr ) )
7 e* m. m+ Q. x: _8 q5 E return UPnPMessage( hr ), false;
! I/ z+ ^- O) t6 X4 d8 {1 R% v! r6 Y
: c0 ? \. W, t
return wcscmp( deviceName.m_str, m_udn ) == 0;* {/ I3 C% J6 t3 I6 O* D- Y, `) h
}
* V9 I- {5 D% S6 c. P CComBSTR m_udn;
/ d: p3 \- j( s; \5 M };
/ Q+ ^$ C4 e+ P- e- V W
9 N; W; ]; P: K3 k void ProcessAsyncFind(CComBSTR bsSearchType);
5 |! j; `( v- E E HRESULT GetDeviceServices(DevicePointer pDevice);
2 j* M2 U! L$ H1 l void StartPortMapping();
0 r( a& l7 T8 p- n% Z" n" e8 U HRESULT MapPort(const ServicePointer& service);' l/ F. s. N0 `/ [2 n7 d
void DeleteExistingPortMappings(ServicePointer pService);
+ T* S1 d. l* _& s9 V void CreatePortMappings(ServicePointer pService);
& n5 H# M% p5 P! h+ g+ k6 U1 G HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
; `# X m u/ } HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
4 b8 H7 H9 `$ |* f1 g LPCTSTR pszInArgString, CString& strResult);
6 ]* T& S5 ]. p: l" R+ E5 D) T1 H void StopUPnPService();
% R' n1 _9 Z' E; T1 @0 `$ v$ y% f0 L% w T& \# K \" b
7 ^% A5 M& q! }7 v! ]" w0 P8 M // Utility functions9 R8 }. _: Z7 w8 B0 G0 r. c
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 S! K# f+ Q1 j& \ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
( e( Q8 B" I2 f! a B INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: X2 P |: d; D8 V2 } void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ l3 L" F% ~( W1 F8 d* I% x2 W; J! D
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 {8 e6 s6 ~2 @, S; s9 L( R
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);. v; H5 s6 |% D( Q' v, H& F
CString GetLocalRoutableIP(ServicePointer pService);) [( g" ?2 h' Q$ ^
- v% X; a% W% ~( D$ v/ ]
9 P/ ^3 c% x2 N: q$ }// Private members, R4 L! ?2 V* \9 S' z3 E
private:
: x6 y0 b% F3 `6 o/ Z+ n DWORD m_tLastEvent; // When the last event was received?
7 L' W; V3 s9 w- x3 v std::vector< DevicePointer > m_pDevices; T- m8 K* f6 K4 y( e
std::vector< ServicePointer > m_pServices;
& R1 N( }* s7 O FinderPointer m_pDeviceFinder;
4 \& R, S! d) t# G+ c2 w1 y1 s) y DeviceFinderCallback m_pDeviceFinderCallback;
3 W6 F8 ]- ?0 W5 d8 k$ f ServiceCallback m_pServiceCallback;
: e" x( `' ], O! w$ I$ N' Q6 j/ o: V+ [' p+ ^4 v
4 ~& E$ o ?& z' f, h
LONG m_nAsyncFindHandle;
+ X& [! l4 `' H) b6 p6 v* Z bool m_bCOM;
& K% j& r* v4 Z: f6 E( M bool m_bPortIsFree;9 ?: U; X/ O9 V3 I
CString m_sLocalIP;. I- o0 ^) e& D6 A6 f
CString m_sExternalIP;; J, M3 X2 P4 }8 b1 j/ j) _
bool m_bADSL; // Is the device ADSL?
2 S; _% V1 Q0 N+ Z4 W- ?5 r7 ` bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ s( B2 M3 ?' t bool m_bInited;
& `' q- p9 J# s* V/ t x bool m_bAsyncFindRunning;
5 B; v4 d0 n3 k7 e2 d: h HMODULE m_hADVAPI32_DLL;
& N' R) G$ |: k' S W HMODULE m_hIPHLPAPI_DLL;6 f" P }9 S+ M5 E& l
bool m_bSecondTry;# p3 I8 t2 r$ C( j( L& P) r: _
bool m_bServiceStartedByEmule;) w% [2 a1 M+ F7 u
bool m_bDisableWANIPSetup;
( Y6 }# i3 `0 k) J7 v+ I bool m_bDisableWANPPPSetup;: m" H# d! _1 Z" g
2 b+ F6 w5 O! i
# j' K& V( r7 ]5 f: n/ ?
};
5 J6 y+ @9 C! `* G+ J) z3 m& B6 P6 G. B; O
" g: z- o& Y5 w8 Y9 Y* K
// DeviceFinder Callback
7 M$ |4 R/ h9 |5 fclass CDeviceFinderCallback
; ^- n& z, L1 | : public IUPnPDeviceFinderCallback
+ J. h3 Z* [0 M# { U! `8 z% ]1 o{, k. ^8 t5 z, Z, g. f% V
public:, F1 G: E6 r }% g0 ?
CDeviceFinderCallback(CUPnPImplWinServ& instance)
* J: h5 f: H% | D : m_instance( instance )
# s: z+ N3 ?1 J { m_lRefCount = 0; }9 V- ~5 K: E4 b$ C0 v
- M$ E) J3 F( ]# i! e% w3 W, Y# O9 s1 z* |6 ]
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 } _9 F3 ~' a/ _4 j
STDMETHODIMP_(ULONG) AddRef();; u' F: G8 p$ G. f
STDMETHODIMP_(ULONG) Release();
" h/ h, P0 {- c% a; J8 o. u) e. a( y5 w
. ]4 v6 ]7 y1 c( T. J1 `/ e// implementation$ O4 I! R' c0 f' c& n
private:% w' k# V8 \2 a& I! y7 P- P" Q1 A
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);* K( X0 t! t; v( w2 ^/ F2 u
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. Z, S9 P( ]0 Y4 Y
HRESULT __stdcall SearchComplete(LONG nFindData);
, X1 d: g% O) [6 p: W7 Q; t6 R- T( o* Q
* W/ T" W; T5 _ e9 ^; S' c; vprivate:( ~% e3 R; s3 Y( x% Q ?
CUPnPImplWinServ& m_instance;* k \9 K% b/ W0 x( I% u/ l8 k
LONG m_lRefCount;
* S6 S4 w. e0 j/ k};+ P+ D$ J4 t; B, f# M3 I, T; p" F- W
4 k, {" d$ z% i
6 F( e" J5 d8 U- }7 L
// Service Callback
: g2 s8 E* X5 m T6 z. xclass CServiceCallback
2 J1 I9 e% l3 i1 z7 U5 q : public IUPnPServiceCallback0 b# G8 n0 H( T! B
{
4 k0 `4 _$ N$ |' T) |" i; tpublic:. a2 X7 i! [* q
CServiceCallback(CUPnPImplWinServ& instance)% Y/ m% a- ~& U/ B- k& i( q4 F- G8 G
: m_instance( instance )
6 h- J7 b0 v, z. p { m_lRefCount = 0; }* k0 h+ q1 q1 h J
2 E4 A# l+ Y* c: n5 `; V
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# `. p' W$ t L; k& _ STDMETHODIMP_(ULONG) AddRef();& J$ u6 v6 E1 O- y" W
STDMETHODIMP_(ULONG) Release();
* K# K& I5 A3 i5 |
7 _- o; t- l/ K/ v, R ]; n" m R) T
// implementation/ x1 {! l# }' w& s8 _# W) K# C
private:4 W2 w" L) N, h. { s
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
& j6 C) i0 c9 v/ z# } HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);! K }) d* ?$ `5 J. H
$ n( | C6 B5 c c
8 R/ U+ [' G0 k% Q8 S3 oprivate:
% t3 `+ O, W+ A: Y7 g$ r; t( E CUPnPImplWinServ& m_instance;+ u+ L) x, O& \' r F
LONG m_lRefCount;% R- t" F! e w2 }( H9 F
};4 E, q5 {4 P. G3 H# h6 N+ b
9 c8 d( N7 ?# U
: S, G) v; z* B# h+ [
/////////////////////////////////////////////////* S* D$ o3 H$ ?! o
' H7 ^+ S. u P$ n0 K5 k: Y
( _- a' D" u; j* l2 U7 p2 B6 d' u使用时只需要使用抽象类的接口。
: z4 W2 T4 h- l" GCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
5 E) M' T1 {. m5 R; u$ b; wCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' `# a" s. f% ^' |
CUPnPImpl::StopAsyncFind停止设备查找.( s! L* y& |# y3 A) V0 K6 p0 J
CUPnPImpl::DeletePorts删除端口映射. |
|