|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ p- x- o1 H8 }; m9 L2 Z
- U5 j% p1 Y7 P) o" G8 l# n. X) d4 e1 X- q3 o8 D, l
/////////////////////////////////////////// u9 S, ^- F- r' `( H& y; j# }
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.; A3 o# P# K/ Q, e, `
4 b* J* P( e3 N- T# O- @+ I( {
7 N" F0 t$ P; k ]: A#pragma once, H+ W) k6 K3 n
#include <exception> Z$ Q: Y; U$ b! L: F4 K- J( j
2 m, O5 l5 M! f1 }9 l) b2 L
2 l2 B: m o# u; ` enum TRISTATE{
( T" i9 D" W# {' k' G* `+ M" r) K9 E TRIS_FALSE,
4 s; @% Q; ^* Z& ] TRIS_UNKNOWN,
# B% U2 e7 p9 z# N TRIS_TRUE/ H: O# Q) o+ L! E
};0 W" h3 I, y$ D
' _; G! }. q" H! Y8 t! y1 y' ^) [3 j
2 m% n/ h7 F: R% Benum UPNP_IMPLEMENTATION{
; D9 Y/ @% A* H8 ], N+ s UPNP_IMPL_WINDOWSERVICE = 0,
# F" l# l& A! v UPNP_IMPL_MINIUPNPLIB,( J. c! M& R% n/ g% e. n, L. m
UPNP_IMPL_NONE /*last*/5 r0 _9 l- q+ t6 ~1 G4 E, O
};$ C4 C2 _4 N" J& o y4 a8 V
# x O d1 }( S% s/ r4 R4 |
% f5 v( N# y( t2 D' C
, q, G* V. y/ p8 o
3 Y# I7 a* N& D. j1 q' gclass CUPnPImpl
. |, D' A$ i1 L3 D. S, e, x{, ~5 N- b& @' }! o3 @3 w- d
public:6 {3 I4 L. y2 @5 ^: C* B
CUPnPImpl();) x7 x( q4 X8 X7 [) h
virtual ~CUPnPImpl();/ w! W7 x$ G& m( a/ W( c+ D# Y& \: B
struct UPnPError : std::exception {};
9 o5 B# s+ m- T; H5 h/ P enum {( L+ _6 ~* |7 G* T$ F
UPNP_OK,7 D" }% u' P' @$ |7 r+ V. w+ [
UPNP_FAILED,- A, j; O( [( F7 i0 ?
UPNP_TIMEOUT
^4 O. X2 u' ~9 s };; z$ Y" ^$ s# Z( d% \
( o3 Q& L" l0 V, ^; P. h' O; N, B& t. k' n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
; i% Q T5 @7 `" J) {. [9 B3 n! @8 _ virtual bool CheckAndRefresh() = 0;. R2 D) o6 {- @. j: e4 C
virtual void StopAsyncFind() = 0;
1 b% C% V6 H0 T/ E! M r0 O% l virtual void DeletePorts() = 0;
1 l# m( }% Y) S) E- I# q$ V virtual bool IsReady() = 0;; F& T4 p) ^% _- S
virtual int GetImplementationID() = 0;% z6 Q' _6 U) {4 [
' _3 y( M$ o/ c9 \$ r# \7 b
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 q7 q" R- T3 N1 C J& N+ E4 w; A- [3 T, e
% S1 z T" T {" O
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
, Z( e% Z8 A: p6 U# y3 f TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
3 x3 {; T, i( @0 o& c: B/ b0 k uint16 GetUsedTCPPort() { return m_nTCPPort; }
- h0 h3 K) K' [3 e$ Q- X+ [ H uint16 GetUsedUDPPort() { return m_nUDPPort; }
/ r& F& a6 i" y% n0 v* {8 y) J& l$ f% a B1 B5 o% `
; U" r' o+ i0 ~/ p* y
// Implementation0 }' N7 m9 d# U
protected:
" w A7 x$ H) e7 P+ x7 { volatile TRISTATE m_bUPnPPortsForwarded;
/ k( A6 H$ Q" y void SendResultMessage();. O+ V$ o; y* P/ B5 u
uint16 m_nUDPPort;
- z" n q8 ]* W uint16 m_nTCPPort;6 J( J7 t9 Y0 o# B! R. Q
uint16 m_nTCPWebPort;* Q1 e9 o# M; x" O7 o$ ] m
bool m_bCheckAndRefresh;
( e6 T( U1 {) r9 @/ z e/ s& y0 N: R
" Z1 _- M! D1 T7 K/ c9 Q1 K$ f
& E; E1 O: }5 \5 y- o3 U4 ?9 i5 eprivate:# x# K6 R4 Z5 L3 b6 ~0 J( r6 K
HWND m_hResultMessageWindow; U6 S1 P; b! R" c( _% [9 x% v0 F
UINT m_nResultMessageID;
2 W$ y9 ?' R8 N+ p' h* t: a0 r; `+ |* _. E; X
6 r5 k! k! h1 D' a% t: ]};
$ P6 Q7 H! [" }9 U% W, R5 u. U; z% s6 ~
7 [6 C5 H+ W8 S% n
// Dummy Implementation to be used when no other implementation is available
1 R/ u9 B8 F0 s0 n+ a' M6 |. H. hclass CUPnPImplNone: public CUPnPImpl1 _) c. B* g7 O$ }; N( X( ~! g* F
{
/ k- s! f1 e( tpublic:
8 D+ j8 y& E! k' ~% A virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }$ R' Y0 G$ q% @' w* |2 y2 X9 F
virtual bool CheckAndRefresh() { return false; }4 f7 I( ~( g/ m9 ]) S
virtual void StopAsyncFind() { }
/ @6 M2 b* b4 L& Y) { virtual void DeletePorts() { }
- f) o; j! ]" Z$ b% Q virtual bool IsReady() { return false; }
$ g w6 o8 m- j- [/ y$ n4 d virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
A' [7 Y2 T- H) d1 Y4 ^' {};- T+ \: R g% i: X( s% [2 l
/ L+ g6 S( j) {8 ?, a
' ?) ?) u0 G6 Q0 k+ q4 G/////////////////////////////////////5 o) v$ }) F$ I6 N# ~$ W+ u9 F
//下面是使用windows操作系统自带的UPNP功能的子类
7 U0 n9 Z! ~/ {* j8 Q8 P5 c. q% H2 h5 ]! ~/ _; _' _& O; b0 H
! g5 _+ Q/ r1 Z. u& V7 C( h#pragma once- ~* {! J# }) S/ W: Z
#pragma warning( disable: 4355 )
+ Q* L" r% C6 {6 J
( Q% B+ V6 s" `! b& z2 P% {7 c4 x4 k
#include "UPnPImpl.h": h3 d4 q8 X& f$ G
#include <upnp.h>" O5 Q; D, f+ i2 }2 a; K
#include <iphlpapi.h>
/ l! A, j" d5 r; B6 s8 f#include <comdef.h>6 Y$ E" p/ @, t
#include <winsvc.h>
' H; I2 A) |! I% J& _
9 C9 L7 q1 z3 S1 y9 X6 _, k
( J4 I6 ?4 x* x2 s, s#include <vector>
" t1 P4 A8 a' W8 l#include <exception>
8 \, S2 T& K8 i. Z1 U; W#include <functional>
! a( r1 a( t( ^4 r6 _; N- S. a
$ M6 t6 z7 B \3 j' M8 G- F& a% V% ~- k% e& M( s! g# Q0 ]/ \9 [# r
: P& ~ `) g5 q' `4 E
! f( q3 C9 S/ n/ c! D: E" y' gtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
9 }! ^+ ?' X1 N" K# h* ^6 D+ K4 ]8 h: @typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
y o' w6 d( W+ Ytypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
" V) E, t3 ?8 L, Y+ Ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
6 k! K" H1 d- y; g4 a& X+ }typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;! k& c6 G* E$ q2 Y2 S M6 G+ P
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;, E/ {) T4 ~. E: e- n
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' T D2 r' n. W- l2 f# |5 I; M* S# I1 s$ i0 X1 O( {7 E9 Z: x& ?
3 V7 k. ~7 \. R- y& s7 k* ~8 l7 k: b
typedef DWORD (WINAPI* TGetBestInterface) (, \# O/ B& F' |
IPAddr dwDestAddr,
, K3 v4 j1 ~/ ~" P0 ?) `. ~ PDWORD pdwBestIfIndex4 o: M$ H' t" L1 Z
);) w7 |3 }$ N; ?# Q s9 k, J/ B
1 C9 a* `+ B3 E: B3 `0 U; s! r2 V: Q( v4 y
typedef DWORD (WINAPI* TGetIpAddrTable) (7 P9 Q7 T4 L {+ ]4 p$ r5 N0 a8 P
PMIB_IPADDRTABLE pIpAddrTable,+ y8 ^" X# l e. d& |
PULONG pdwSize,# q6 T/ V$ M2 V/ `8 K# D
BOOL bOrder$ n( @# e4 |9 r* x( m& o, n' ^! C* P' q0 a
);4 i* F5 a1 Y/ V
3 o1 H3 K$ k! [" `
* G& B+ s+ }) }' ^$ c3 [
typedef DWORD (WINAPI* TGetIfEntry) ( T4 j; z! Q; ~* Y
PMIB_IFROW pIfRow
5 S! O& Q% Q9 o9 ^# v' e);
e; v8 G4 ^1 C3 ^% @7 Z) V9 r g i3 D: k; P
7 l# z$ S$ Q, R6 m( v: Y; FCString translateUPnPResult(HRESULT hr);; P9 J" S/ j# D( ]& ?: \1 |9 O5 ^
HRESULT UPnPMessage(HRESULT hr);
( _ T9 n' O) `0 I+ Q8 f( j7 t( w6 e6 A# E- |
] I8 f# ~% F+ ]class CUPnPImplWinServ: public CUPnPImpl6 @* w: a+ u) }+ w8 K0 `( s0 Q {
{
# O9 y9 q) ]. t" W6 Z friend class CDeviceFinderCallback;7 x; G9 x/ [4 r& L
friend class CServiceCallback;9 C% d6 O" W) F2 B% H5 F+ N) M& I
// Construction: N: ^8 a/ c7 Y; ]. N( P3 U
public:
5 u! c: P- p7 O O; @. h virtual ~CUPnPImplWinServ();
, `! F5 A$ p3 t" _% P% y9 k, g# J CUPnPImplWinServ();6 [2 y& T; {: J \
) W( J+ m3 u) |0 d
5 r/ g$ m" w' Y2 r virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } f% U) n1 B9 j* _! c
virtual void StopAsyncFind();; B& i: u! l! e6 \2 T% w
virtual void DeletePorts();, Z7 i1 n1 ]7 d6 ?( C; x4 ?
virtual bool IsReady();
8 n& Z& L- M1 V virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }5 k8 s4 I& i/ q
: q0 m3 L; ^* D4 Y: X# P" D* ?8 d; M* R5 `) d, V4 l4 t" e$ f
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)* T' W- v0 Z$ E7 ?3 x
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
( K% l3 t* M% p: }: F. L virtual bool CheckAndRefresh() { return false; };' Y5 D, d, m8 T4 J3 F" V
% f0 }( [& j& ^* m. X
% g( c( C! L9 a7 K2 x7 a( R0 y2 a
protected:
4 S5 V6 m6 |* U void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);( p/ Z7 t0 I$ D; l1 Q$ `, U
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);+ i! H9 U$ E6 I
void RemoveDevice(CComBSTR bsUDN);
3 ]" J' Q( g# F* D, d bool OnSearchComplete();
. n; [( H# }, D. J6 F( o void Init();
! G$ x$ r2 k5 n7 w& k
9 \$ K5 D) b+ U7 R! a/ N2 ~) \. f( L0 L
inline bool IsAsyncFindRunning()
& |1 X7 l# B, B' B9 t" a {, W, Z- ~) L/ U4 w0 \
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )5 a" V$ l- t& h* ^. ]1 B
{ g5 b% R% F% j% a
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
8 D I6 Z% ~- E! C4 a% t m_bAsyncFindRunning = false;8 ^ ~3 t& d! c/ I+ k G6 ^
}
: L- Q1 U. x2 g! n, I' m4 b$ g MSG msg;' e' |' G# q0 S$ ^
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )2 h( W) e" d# l' j
{ k* W! s3 v! h+ A/ m( X
TranslateMessage( &msg );
8 Q% G c5 M, @) B. h5 D2 b: { ^# ? DispatchMessage( &msg );
3 O3 a4 n/ K# D0 P( ` }
3 x/ f6 x' L& G. q& m' h/ G return m_bAsyncFindRunning;
) b- M# q) h- X& D- D$ n5 { }
& w! z( J6 \7 _! e7 k+ b$ ?* a) c5 N9 w; `: n
, x" I6 Y, D" a3 V
TRISTATE m_bUPnPDeviceConnected;; k0 L# L/ \$ H- ~4 Z. k/ m# v% Y
( C/ B; A. v l; B# y# I6 g( q- C. v8 U6 O
// Implementation( ^- T! S& m, {9 e. y4 [/ D
// API functions" q# k: e7 G' Q1 k- W% u1 {
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 ^# {3 d9 @. Y6 C, O3 m SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);- r, s; N( P2 u2 P: U# S6 {/ |& \
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
+ K8 Q# @" q3 x2 Q1 D: g2 K BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
, F, A( z4 b# c+ r e4 p BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; ~* Q8 F1 n" Y3 p* z* @0 } BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS); y! S3 B! _1 N$ l
- a5 I) n1 p& \5 E! v7 y
: C) N) s. A2 d3 J
TGetBestInterface m_pfGetBestInterface;# d4 n' l3 x f; |% s) D/ x
TGetIpAddrTable m_pfGetIpAddrTable;
$ R) j. W/ a( ^/ S" R$ B TGetIfEntry m_pfGetIfEntry;
9 ?, x8 q1 D& |6 e# O
, q& I/ i; Y! B' E* J# N4 s8 @9 ~! ^) g" e3 l. z' r& `- F
static FinderPointer CreateFinderInstance();0 A: P# t3 N* K; N" I2 g6 x4 D
struct FindDevice : std::unary_function< DevicePointer, bool >
. ~# O% Q* U% | {
8 o: c7 O8 B' }5 G FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ \+ f: N6 H: A2 h: o result_type operator()(argument_type device) const
) h# n* V, Y" `$ v" W {/ \+ f5 T9 N) d5 y% o+ f# O
CComBSTR deviceName;0 m. a# U( [/ ?. y' {
HRESULT hr = device->get_UniqueDeviceName( &deviceName );) J" w) c! ?& U5 _' U
+ G# S3 d7 W; B. I
( I; T( G2 H; g
if ( FAILED( hr ) )
- G4 `6 T* ^/ d1 j# u return UPnPMessage( hr ), false;
! ^& g' P7 `+ A3 I: ^ k8 H8 g! k) t. \/ P. W y/ }% M- L
0 q% {$ I" N& b$ V, _$ _ return wcscmp( deviceName.m_str, m_udn ) == 0;3 [& t) a: g. p2 W4 n, |
}( ] b. c# [3 C1 q& w
CComBSTR m_udn;' i. g5 g7 v. R2 n
};
5 s; ]# o" Q0 j4 x1 D$ G 6 M! i0 I- g+ w% t2 u( L5 x
void ProcessAsyncFind(CComBSTR bsSearchType);
! l+ |) R7 Y$ `9 T HRESULT GetDeviceServices(DevicePointer pDevice);
3 W' i+ o) y/ n" u: J void StartPortMapping();" G% o: V0 i7 C; {
HRESULT MapPort(const ServicePointer& service);' a4 E. T5 g4 C$ E" | A
void DeleteExistingPortMappings(ServicePointer pService);
`/ S- g9 A+ p5 ^7 g void CreatePortMappings(ServicePointer pService);
$ t) u# {9 N' Z/ l4 r HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
. _3 ?! f1 X2 i0 |! }8 h0 r HRESULT InvokeAction(ServicePointer pService, CComBSTR action, * E, z8 I1 a: _% o3 U
LPCTSTR pszInArgString, CString& strResult);
8 K: Y5 |0 ^* L" k2 Q void StopUPnPService();
' {8 x4 \; e5 z) m1 w, E6 @; a+ t" ~& n; C+ z6 p
2 D4 t# [+ O5 V9 t% K
// Utility functions' h3 T9 s( P( @* p* C# {
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; t9 R% j- b* A, h; L8 p* |, r INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);: h) @) [, l L& w% u/ k( ?2 m! B
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 p( V P6 A; Q void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
4 q. T6 i! h' z3 G. C HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);4 U) W5 h4 t6 x# X6 j2 P6 I9 b
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
: @9 s! J; K: X- A i' e CString GetLocalRoutableIP(ServicePointer pService);8 u- C( R: J; g0 B4 Q
& B. y2 w# U8 ?% z$ M8 N) t0 N6 w% ?) ~( E8 E
// Private members6 o) H$ g% u( x4 q! f0 F
private:( t' [6 n3 H# \! S, y
DWORD m_tLastEvent; // When the last event was received?
; w- p3 R5 K, l$ d) ]* @) y std::vector< DevicePointer > m_pDevices;
+ |. ~ g* q' q( C std::vector< ServicePointer > m_pServices;$ R' o, K! o& ? |5 B1 `6 R! _) F: U! {
FinderPointer m_pDeviceFinder;
/ [0 Y% t' R1 i: q) ]' K DeviceFinderCallback m_pDeviceFinderCallback;
5 M4 I- n! H1 } ServiceCallback m_pServiceCallback;
0 {7 y6 ? \3 h) ?, G
& |0 N/ q( c b5 X4 Y9 Y4 i# E/ `+ C" o0 Y9 m5 u
LONG m_nAsyncFindHandle;
) X, I: V; t" b: h7 l. n* R) k bool m_bCOM;
/ U9 [5 [; z- | bool m_bPortIsFree;2 ~- v4 L, I% I3 P
CString m_sLocalIP;7 l( \* R# g, U% J8 t
CString m_sExternalIP;7 N5 a, A' {% Y! @$ c. E
bool m_bADSL; // Is the device ADSL?
/ x: N( w9 S7 V& ] bool m_ADSLFailed; // Did port mapping failed for the ADSL device?+ h9 L: e% V1 f7 j
bool m_bInited;" ]( H) T, u$ i3 l+ {7 e8 Y1 `
bool m_bAsyncFindRunning;
- n" ^) `; V$ q8 Z+ L2 b: t* i HMODULE m_hADVAPI32_DLL;0 F [; l9 C/ o4 Q
HMODULE m_hIPHLPAPI_DLL;
+ ?8 X6 U# x" L) e9 h6 y bool m_bSecondTry;
9 R+ _, B9 X# I( o n- [ bool m_bServiceStartedByEmule;2 e5 Z- }( \: U, v8 D- J# m1 c
bool m_bDisableWANIPSetup;
7 t( [/ h: }/ M6 B bool m_bDisableWANPPPSetup;
2 o' ^ L# L% B2 s4 J" G. W0 v( z% I$ U* a3 f1 z
. S) S1 g( K3 \' X; w4 `# ~};: b* g/ o+ l# N5 p
, s+ r$ i8 l# k! b; [( `) y/ Y6 [ K4 _
- j9 K' H2 {) J' M; n( `
// DeviceFinder Callback+ i$ @0 k3 z5 x! e
class CDeviceFinderCallback' g1 p" I" p& D- V8 _7 x
: public IUPnPDeviceFinderCallback1 C/ {( T3 P- y
{/ J$ Z. a; Y3 {- Y
public:
# |0 S8 i) v. ^ CDeviceFinderCallback(CUPnPImplWinServ& instance)
( D* q8 S( t8 {) u8 n : m_instance( instance )4 N6 P) o! q4 m( f. Y
{ m_lRefCount = 0; }* U- ]3 E2 e& o5 |3 k
{5 X% v9 R2 d+ X: M4 S& o
7 t! h' ?% A8 E4 S$ j( t! i STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 f" V8 X F ]$ l1 i
STDMETHODIMP_(ULONG) AddRef();: ~: a% T. P8 x/ t
STDMETHODIMP_(ULONG) Release();1 z# N7 i+ r# v
. |9 s5 X' y! ~8 ~" {/ Q0 \: @0 I f, I
// implementation
. [% G0 b% Q" z' u. k) O$ uprivate:
# Z. d/ X4 E' {$ o9 U3 M HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
" c- W" H$ S/ B' @- ~- F; e8 r; t4 H HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
) O% H1 @4 [( N: ]$ I4 C HRESULT __stdcall SearchComplete(LONG nFindData);/ L* X; R0 {* K# n9 R& f1 j
# p% V2 S0 _; c6 A
k. |7 X: m+ u0 }9 e* D8 k/ aprivate:/ v: w1 D# x/ r d" p% J
CUPnPImplWinServ& m_instance;! ^* y, j" J. X0 [& s- ]
LONG m_lRefCount;4 b8 y( m3 t# E6 s1 ~
};) t; G+ ]" H2 r9 [7 k
+ z0 h: R$ U8 O6 u
1 \* X6 B2 f! v$ E
// Service Callback
! x+ \- W2 t# h- dclass CServiceCallback
# j0 E! m8 [1 M- T3 A : public IUPnPServiceCallback
" {1 o2 m2 G( t% T2 [' N{
% s' b3 A9 C3 F& fpublic:: ?! x o- w5 h) G3 v! c4 }4 H/ Q
CServiceCallback(CUPnPImplWinServ& instance)
" Z# C5 I1 n/ L! u& T : m_instance( instance )
( m5 k6 C4 e2 p0 F/ t { m_lRefCount = 0; }6 @7 u: j4 d# r, G
$ j" e, y% s5 }. r% n/ L* s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. [; x' b* q V/ s$ }4 ` STDMETHODIMP_(ULONG) AddRef();
. z; [) E5 j' ^/ \ STDMETHODIMP_(ULONG) Release();$ ?! n2 Q2 e( y; o. B
# W% R/ v- i# k- U- P3 J
- D3 P+ _# R3 c# }3 L// implementation
8 [; {6 r$ u7 S5 U+ oprivate:0 G" U/ ~- w/ c/ n9 M
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
) s8 v# ]# Y) X& m HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
6 Q8 B$ W: O( @) h8 C* N. u- X5 p W9 V; T# k
, r* ~( e& |1 z% c, A
private:1 }+ @: w1 u% s
CUPnPImplWinServ& m_instance;
* ?1 P0 N2 s% g% Y1 A LONG m_lRefCount;
0 ~ {8 g5 k4 Q. {};
7 ?: t3 ~' ?5 }% H
( E7 P. ?/ a. [5 L, P4 H
* ?6 O$ X! m+ K$ p. o/////////////////////////////////////////////////
" m! d( v$ Z# i9 ?/ B
. J7 ?8 N) E5 h4 R+ X
7 m5 D |9 s/ Y使用时只需要使用抽象类的接口。* T/ H0 U7 H0 j; H
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.+ Y: u) R2 ~3 a0 n
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.4 _3 C. U: }( o0 V' [: |4 g, x
CUPnPImpl::StopAsyncFind停止设备查找.# h$ d% {6 S# L- D# O
CUPnPImpl::DeletePorts删除端口映射. |
|