|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
" \+ W" I* ]+ n4 S
+ B K6 w( p j; F- r+ F4 z4 g+ b. K3 w: C3 A8 V
///////////////////////////////////////////
+ o% t8 L1 `: f0 Y//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能./ c6 w E4 C1 ^7 @
8 R4 N; m$ {4 u1 k
1 E; T/ Y6 \6 r# N0 B. L#pragma once
, [( y# E% t" T b. l#include <exception>5 o$ p5 w8 O' Z V, x8 q
& I6 {2 s8 T7 o: q) b) E- k8 r0 ^. h2 E" d( M2 f
enum TRISTATE{
0 b- u3 z, p, e% i3 B9 d# O, R TRIS_FALSE,
; B$ ^4 J a: @# `) {% X+ ~" A TRIS_UNKNOWN,
F, [# i- b4 e0 F i3 v6 J% S TRIS_TRUE
$ h/ x8 {2 i Y+ W6 T};
% C' x; ~1 r8 ]* w, {: C
4 \6 J, x/ B- t" \! Z) b2 c$ H/ C/ M1 W; K6 q
enum UPNP_IMPLEMENTATION{; c" x$ e8 w: J; \; u3 R
UPNP_IMPL_WINDOWSERVICE = 0,
& J# Y) e) w2 r* y4 q+ V- p4 f5 X UPNP_IMPL_MINIUPNPLIB,0 b- d4 D Y' d' ]1 V3 s
UPNP_IMPL_NONE /*last*/
$ |" Y3 F& M& `% B; \) t};
$ P* p" `' ~! n, G" P& j, @- P7 `& V. {# P% }6 K; Z8 e
# N; n1 c5 ~+ @& _
9 n9 d/ A* U; [: P1 ]
1 Q G2 j/ D4 Z* Lclass CUPnPImpl l% c' V0 F7 j2 r3 d; A( v
{: r6 Y% t6 }. ~
public:
6 r+ ^. h# u6 w( E3 t- ? CUPnPImpl();- S) S" ~, |) N: o
virtual ~CUPnPImpl();& I) k" Z$ _' x& j W
struct UPnPError : std::exception {};7 P: ?/ w; y& _" G8 ]
enum {7 `+ l) ?6 I$ l( G. d3 t& e
UPNP_OK,
) G4 m7 [) J: B) t UPNP_FAILED,/ O# K: g% j* W5 V1 j
UPNP_TIMEOUT
# q- h9 h, s! O! O( z6 J };
; }7 G# j$ M/ j! W" A) I
6 ]$ [( t8 [8 ]1 ]% a X
9 B! k2 X# z2 p virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 t( L- g7 G+ M" r/ I$ o3 C virtual bool CheckAndRefresh() = 0;$ ]/ e" G" k! | ~: t) w7 @
virtual void StopAsyncFind() = 0;
% Y5 ]! o% @% D* @- \# [0 a virtual void DeletePorts() = 0;1 z& Z3 s8 r9 ~: j# z1 \4 A2 T6 i' Y
virtual bool IsReady() = 0;/ B( B+ N! y$ f }
virtual int GetImplementationID() = 0;
* b! \) R! k- {6 L" h5 y- A $ d9 r$ l, N# B# p' b1 C/ ?0 t, J
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping Z, [3 R# ]8 Q9 l6 a: v
. x v# J" k! g$ Y5 J! d9 X, ^
4 `4 Z. v/ Y; K- }) T* e
void SetMessageOnResult(HWND hWindow, UINT nMessageID);- Z$ @8 e' N+ S6 [0 q8 e3 P
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }- c# q9 ]3 v$ D4 W3 {
uint16 GetUsedTCPPort() { return m_nTCPPort; }
; z( t) d& k* G+ R uint16 GetUsedUDPPort() { return m_nUDPPort; } / p0 V L% ?: t( ^+ ]
* f: _9 J1 k" C3 c& \) w
5 H3 R ~2 p& N, \+ I7 [; M// Implementation! ^8 k% T8 \1 S1 o d" g, Q7 B
protected:
5 W N9 @) b5 z0 H j( T volatile TRISTATE m_bUPnPPortsForwarded;( c* I9 x2 h3 l# }
void SendResultMessage();
; U: C, T* ]1 V* E8 b/ V* n uint16 m_nUDPPort;5 ?" p) [, }; Y) e1 R
uint16 m_nTCPPort;
9 m# T9 V, V" f$ r8 R- B8 [ uint16 m_nTCPWebPort;
& k0 ^* T6 l! G1 ~/ A g bool m_bCheckAndRefresh;; U7 d2 @8 O& g, p
' s" s1 K: T6 `: x( z
$ w7 Z$ D( t$ R) m# z9 L0 T6 K* pprivate:
, O4 q# O6 q% W ]2 V* N$ S HWND m_hResultMessageWindow;
- t L8 ]. g% g UINT m_nResultMessageID;
2 h9 C" z2 r0 A4 X0 B* `" C
( R d: |4 `3 P* N
6 S, @: [/ x0 B2 [7 u};$ J. P9 f' ]/ C, s" S* s$ y
|* k% ^7 n r( H( _" _9 P8 z
# ~, V- ^ `. \2 W* K0 t. @// Dummy Implementation to be used when no other implementation is available# H; G; p$ E3 O
class CUPnPImplNone: public CUPnPImpl
' H+ N8 O" ~ K1 M! i% ~1 j{
6 @% s" u8 [! U" @4 T6 `; Dpublic:
' b7 l0 H! D- |2 o4 H [7 c virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }3 j) U9 o# | ?8 Y% ^4 |
virtual bool CheckAndRefresh() { return false; }- d, m# E0 W4 u; h/ i, q/ x+ z
virtual void StopAsyncFind() { }
3 M: V* X# Y* u3 Y+ d/ J D virtual void DeletePorts() { }
9 }5 G3 S6 D/ K8 _ virtual bool IsReady() { return false; }
% D' Y* ~. R! b virtual int GetImplementationID() { return UPNP_IMPL_NONE; }# Z/ v* S+ U! P
};! }) k$ g, F7 o/ D
' t7 y( m2 |; D1 E9 o. Q9 J
2 O, V4 E- m+ D
/////////////////////////////////////
. T( R- W2 K0 r \1 r2 r k//下面是使用windows操作系统自带的UPNP功能的子类( L0 c# B6 W6 A' Q1 r+ S) u' \
8 T7 M, ]) y* y/ [+ r1 d( I' k6 F
3 ^! P' I7 \. ~( P u* p. w
#pragma once
- m9 k! L8 y; ?& x/ ?- k' c#pragma warning( disable: 4355 )
5 `6 d4 H* |5 r. J/ @$ k% L+ L1 s/ c4 b+ b" t6 h) m& q
o; j6 E% r$ Q# C" [
#include "UPnPImpl.h"
" L. _) j* M0 |2 r- w8 p#include <upnp.h>
! X; e3 [/ j6 H) _2 P: ?2 t#include <iphlpapi.h>
( _5 ?9 t$ v& @) N& @#include <comdef.h>
3 `% c, a( O" h" B#include <winsvc.h>
5 H0 s9 a. j* I( d
- R) ~+ ] J$ m& T b* S8 T" @0 ?5 C y! s" P
#include <vector>
9 O4 P" C, \& h+ d# x#include <exception>
" r7 O" t" x5 ~0 a8 B* K#include <functional>
7 G3 ^1 s( }+ m8 d$ a. j8 g
$ n8 J% J2 v* e; F* m( M; ?$ O0 M* y
' M3 A$ V" V3 E: i. S4 D4 R0 B8 r3 \ z( l) x; p
% L8 U5 [# L9 ]3 [7 n& Stypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
' D! u1 Q3 C$ s6 }9 ktypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
; A4 Z* p% {4 v' x7 \' _typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;1 q* P8 I( K4 z* W4 \) s: G
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;5 S4 ^# q% v; O0 H+ z( t! Q j
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
* ^, f+ ?- e. z' t4 I8 Mtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;- s9 H6 o; ?' C5 V
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& j5 y5 j: p1 v# K
0 p# B' @0 m' @- ~
* [) e: P' F: N+ t. |8 c( Mtypedef DWORD (WINAPI* TGetBestInterface) (
v. _* r0 o+ O9 U$ {+ c0 p IPAddr dwDestAddr,! E& ]9 h' l7 b$ `; u
PDWORD pdwBestIfIndex. _: j; ~, b) X' b
);
0 ?9 `- C# }& A: O/ g; b& Z$ Z. s% C7 n4 B% _0 G
& Z5 p7 O1 C! S$ |typedef DWORD (WINAPI* TGetIpAddrTable) (: I1 m* v- [! k' E+ o x ]# G
PMIB_IPADDRTABLE pIpAddrTable,
, ~ x4 E$ U6 W0 {/ ^0 J. | PULONG pdwSize,
( H1 u* g4 z) G+ v; }) H' |. v BOOL bOrder
2 ^9 ]: b. S7 i);
, T& u" f/ G C+ m6 ^& J2 k `+ ?( h1 b8 F# j& H! F5 h
# m) J! q' d8 d. Y6 m+ L }
typedef DWORD (WINAPI* TGetIfEntry) (
" D1 K4 [0 o1 s2 r# c- m- d PMIB_IFROW pIfRow, E/ U) o4 J+ D
);6 P5 |- ~- z7 s1 V* b
_; b1 D4 _2 [. v2 O; `
5 E4 ?7 M- |. A0 |& P* C2 |$ ECString translateUPnPResult(HRESULT hr);
. f) A& J0 O \6 ^/ u6 ?1 ~. [HRESULT UPnPMessage(HRESULT hr);$ H3 J( K3 n' Q& P1 j0 H
+ i7 e% k- _8 y* C8 x- _5 ^
5 u9 b/ G) `1 `; o3 I, Sclass CUPnPImplWinServ: public CUPnPImpl
: y& `9 v: l4 G4 Z2 Z{
$ {- D& o. X: E7 ?0 O0 s* _% H friend class CDeviceFinderCallback;. t$ _* _. G% o) C u% X1 ]6 B
friend class CServiceCallback;
3 ?/ F; t9 h0 {: y# [, I// Construction
. x, D) I( s+ ^2 |4 }5 p4 xpublic:
& o" d5 d" s0 _- X# v" e9 V virtual ~CUPnPImplWinServ();$ t N! `; H) ^& C4 i- \* f
CUPnPImplWinServ();5 q5 ?! k. b/ l. [: q _
+ x" K8 n, o- Q' t
8 _/ b' U: Q2 S! G% V virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. C; _3 w8 W0 F virtual void StopAsyncFind();" [* T2 k% l: ?1 V8 I9 E6 l
virtual void DeletePorts();+ m1 i, Y+ {4 s; {5 }: ]
virtual bool IsReady();
- A, B& I9 M9 |& o( J) D virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
) |4 A9 A Q5 F
4 r- O5 }" L& K, o. [6 e0 ~5 `5 n9 P+ W% ~" n! D! P8 K
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
; a/ @- r4 P. ?( |2 k$ B/ }9 b // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later0 j I0 e) B0 r4 `( s
virtual bool CheckAndRefresh() { return false; };
7 \* u7 _7 Q* ~4 Y: m8 J8 r& }: W9 {0 d" B
4 B& T6 I+ f* p8 u1 c. {4 H3 [/ e7 W
protected:
; p( N) Y* T _0 D9 ]( b* v7 r3 A+ |& Z void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( S( E3 n0 M" T5 }, K F void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);, s! P* E F0 g, H1 S
void RemoveDevice(CComBSTR bsUDN);7 x6 B; J$ Y1 @3 }$ W2 S# d' T0 B
bool OnSearchComplete();& I* F$ W9 e, |" o( {
void Init();
$ w: s0 ~( n. ?) f' s' k$ m0 @
8 _" I* g* ]: w& X# K9 i
: v! d- H$ O7 i2 T0 S inline bool IsAsyncFindRunning() & d" i' W/ t3 z+ \6 ^. W2 e# C
{8 s& `/ L. ?8 i! j4 C. X
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
% x; V/ A: }9 H1 X {3 \4 @" @8 L! ]
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );; Z& B/ z7 b; M9 Q9 b( N; D
m_bAsyncFindRunning = false;
+ G6 h7 a; I, D }1 r( M# l% M% T2 Y! p* a
MSG msg;6 w* }8 }$ s$ o2 L$ B/ y( S
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) f3 l s% v5 \% z6 g$ o
{# {0 ]/ @& p6 W: v/ D
TranslateMessage( &msg );! r+ {! ?( k3 I2 K
DispatchMessage( &msg );) C5 V! F7 [% H
}% d# D6 R* q3 y/ I" d
return m_bAsyncFindRunning;
5 i/ X* R0 }% T- @6 a }, P( e% Q4 F" W% X( i0 h! y+ i6 N
# G( L# v( Y: t
% b, O, @4 v6 h5 z z0 q
TRISTATE m_bUPnPDeviceConnected;
4 o/ ~) N# ~2 Q. J6 u7 o7 B1 F) D' a2 C. X6 {* j9 Z
0 }: x* U# ?5 C) K# Y
// Implementation
; i5 \, N& ^( X. k // API functions
6 V/ b+ |; Z# d8 N; l) ]' z, H$ ]" K SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
# u8 F/ ~6 H' ~# l/ G9 X" y7 s3 Y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
?4 n+ ?. u5 S1 O% J BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 t* J0 p5 l8 M( i { BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! t% A3 ^* R6 k* y BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
- \+ a: h3 E5 D( m BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! u: p* ^+ s7 [- e! {
5 F/ V9 A: o" u2 @2 g: w: q6 }& c! t3 z
TGetBestInterface m_pfGetBestInterface;
& Y* |2 p" c. Y. o TGetIpAddrTable m_pfGetIpAddrTable;2 l4 I, |2 l0 {( N* K z' b# J/ H
TGetIfEntry m_pfGetIfEntry;( K" @& d" P) _" E" ]( t6 l4 b
/ c/ w% x; k/ z/ _7 O) e, W K7 M( P$ J! O. g% |
static FinderPointer CreateFinderInstance();. v; \* c6 i6 B" L0 d8 {
struct FindDevice : std::unary_function< DevicePointer, bool >
: C! k( ?. F5 J { w9 T3 }. o+ S3 d$ d
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}3 R/ M( h0 k+ { ^5 q6 Z8 Q
result_type operator()(argument_type device) const
2 o- [$ G; o* L2 @ {
" I6 v% s% `3 l CComBSTR deviceName;
$ F: n0 o+ E% G, M% K5 j) ~ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& q+ f$ W0 R# F% c F& w( |- W1 ^' D, m* \
5 c6 d! S8 }9 I1 v
if ( FAILED( hr ) )
9 R3 w& y& H/ ^) x return UPnPMessage( hr ), false;" n) d4 o L" m: F \ P
% H" t) v6 G7 T5 k1 O, x! ?: g, b
" Q& K" u }+ C
return wcscmp( deviceName.m_str, m_udn ) == 0;
n. Q+ D8 B9 u& m }
( J! m0 s8 ^: M8 _" P, c CComBSTR m_udn;
3 Q$ ~' l8 D# E" ?% r6 l, Z+ G7 a };' z; I+ {6 H! S( O) J! @. r5 d8 N
% l/ z2 ~5 o& Z! l r2 ` void ProcessAsyncFind(CComBSTR bsSearchType);- H4 f5 J9 S$ R( A: M1 M
HRESULT GetDeviceServices(DevicePointer pDevice);2 R$ a, H; ?; r8 [, W1 }
void StartPortMapping();; R' h8 I- i& |/ x* W( S# J
HRESULT MapPort(const ServicePointer& service);
# ~. G _ K) i) G" r& b void DeleteExistingPortMappings(ServicePointer pService);$ r H0 x* ^5 j8 K, m! W
void CreatePortMappings(ServicePointer pService);
( B2 _( i7 \4 I0 Z' W E4 |8 K HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);0 d, q4 a4 T' L; N7 v
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, . B& @. @& D% f
LPCTSTR pszInArgString, CString& strResult);
2 C% G9 F; w. n7 X void StopUPnPService();" P, x: t) z6 H5 f" n: ?
- Z$ g1 L! n' y, L' g- F' L" b" ?
/ d6 G1 i5 R. d; U7 |
// Utility functions
2 |. i/ m0 X) G HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
4 F2 ~# `" e- w v* \$ E5 A5 g; u0 I+ y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);; {% e* }3 Q9 v* K. a4 k0 \3 P
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);- c9 [% J- C. o0 [9 L
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);6 o4 i- l9 h! x$ l- K1 h2 H( J
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
# m$ b; J, A" w4 S1 l: D! B8 y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ ^1 i' j7 {. O6 \( @: G8 b+ |0 M
CString GetLocalRoutableIP(ServicePointer pService);
: Y' p% z# E6 c1 I- H
3 _3 q/ f# f }0 C
) T c Y- n' d8 l5 [# f3 z, ]; n// Private members
9 x& s' X' ?2 m) xprivate:
0 E! Z$ F' A2 B DWORD m_tLastEvent; // When the last event was received?
2 M% S" U& @: @' A' ]) S std::vector< DevicePointer > m_pDevices;6 F4 {/ G: w: D0 }$ I5 w
std::vector< ServicePointer > m_pServices;: [0 e* B1 W; P! g
FinderPointer m_pDeviceFinder;& m2 X5 l6 K$ M8 U+ D
DeviceFinderCallback m_pDeviceFinderCallback;
7 u ^# e8 g+ H8 \1 x ServiceCallback m_pServiceCallback;7 q& p; w7 \* [' ?; e6 Q$ C# M5 c
6 O; c( }8 y1 A5 T0 @
0 C9 \8 |6 r2 A LONG m_nAsyncFindHandle;
) g! B* _/ u7 R1 W bool m_bCOM;$ ^4 y) T N5 d) U; J/ L2 G
bool m_bPortIsFree;! V9 X1 e q/ l" x7 |/ M/ u
CString m_sLocalIP;
" U& f% I7 W: [/ |# E3 ] CString m_sExternalIP;
& U i" Y/ U% e U' J$ e bool m_bADSL; // Is the device ADSL?
3 Q1 ^8 K4 N( ~( F3 [7 D bool m_ADSLFailed; // Did port mapping failed for the ADSL device? E9 E, T: Y" K: B$ }/ c$ X L# c
bool m_bInited;
6 g6 Z. ~, E* E bool m_bAsyncFindRunning;
1 g$ D; K* I) q4 A( i, j1 z \ HMODULE m_hADVAPI32_DLL;# [5 G9 q4 L2 @: G. s* t6 y
HMODULE m_hIPHLPAPI_DLL;; i5 e5 T+ ? |, t+ S. f6 p
bool m_bSecondTry;6 V; |8 S# w( d8 y% s( \
bool m_bServiceStartedByEmule;5 h) p3 Q0 }# U$ @+ i2 z/ m! H
bool m_bDisableWANIPSetup;
( l2 I, d+ K9 U/ v1 H! l3 q/ v+ k bool m_bDisableWANPPPSetup;7 m) d% D" q& i% K
7 C W0 K2 v( D, U: S: F, D
) Q, @* i! @, Y z( u; i* M};
) T( _. `# }9 s8 q# l- }5 H5 u* ~, \0 P$ U: e" X- g; [
" w8 B8 y6 S. `0 e% W# ]
// DeviceFinder Callback
: y" _8 I: N5 e. i. tclass CDeviceFinderCallback! v+ K6 K# p: {. \: R5 p
: public IUPnPDeviceFinderCallback; c% @8 I! h) u3 [
{
: G8 X6 s/ b1 W0 hpublic:
: G+ x+ [* G6 \ n% } j- H CDeviceFinderCallback(CUPnPImplWinServ& instance)' O# ~; k7 u* `
: m_instance( instance )
% l( p+ T7 W! J, M { m_lRefCount = 0; }
7 F% i- ]% W; J: Q4 ~) L5 q5 `* E, {$ t) [
5 D1 ~) M* P _% b4 }. m STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 G( \. ?" S2 c$ K# } STDMETHODIMP_(ULONG) AddRef();
- z9 ?. N! L- Q! }* [ STDMETHODIMP_(ULONG) Release();
* f+ R3 v& Z0 X6 @- F3 D0 l
5 n/ c, R6 D# E; u# ~) h e& h/ \- j% {
// implementation
( V$ h" U/ a/ T( K' Vprivate:/ O j u$ E4 b6 q0 ^9 c' u
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
% Z) g% t2 A7 D- ]6 |# M; T3 Z/ w HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);: _) ]# Z% `$ N
HRESULT __stdcall SearchComplete(LONG nFindData);$ f' Q% D) k, C5 Y! P. [3 L
0 G: G& ?0 O" ]& l
9 D/ x* l- t8 e% ~/ Q2 Xprivate:
: s' X Z# I' a% A, _% T+ U) i& K CUPnPImplWinServ& m_instance;
( B. n D% k9 c LONG m_lRefCount;5 P9 e' u' d' |5 }) q( K
};
0 S/ k9 O8 r4 M8 Z6 b1 I1 }" p
, M: n6 X! u2 R5 L& x// Service Callback
( v" \/ e+ K5 E& _9 [class CServiceCallback& D& H+ ~5 H3 y/ E- F
: public IUPnPServiceCallback
2 O9 a9 M. [5 T1 r) H" p; p{3 N8 J! r% Z& z
public: r: n7 ]: E! q7 y7 O# G: A Z6 w. k( V: \
CServiceCallback(CUPnPImplWinServ& instance)3 x* o* h, X- M1 W, Q, m" n
: m_instance( instance ). T$ p5 D8 V+ i! W! K& n; V/ P
{ m_lRefCount = 0; }4 B$ h8 P; y2 K3 d2 {: P: @
+ M7 `" E4 q$ o2 M# T STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% b+ v) V3 f/ q
STDMETHODIMP_(ULONG) AddRef();
$ G6 U+ Y' {& P. V% C* N STDMETHODIMP_(ULONG) Release();
! x( Y* u4 {0 s4 o7 o
* H, J/ c& |* C, n; s- [
2 `& O0 O' I1 g$ [0 Q// implementation
/ F* ?: a S' B, M( v/ K9 m0 e) u3 F6 aprivate:1 C5 y) A$ r( Q8 I& \) V
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);+ l% O1 E8 s- {$ d# N
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ Z& V8 a( y6 v+ h# ]; W$ F. O( l
2 [, F8 P8 i& F+ T: w
private:: O+ [7 F4 K5 D+ t! `) N
CUPnPImplWinServ& m_instance;
! I" C3 r% q" }& E' a: T" K LONG m_lRefCount;5 R% A8 V0 D' l N, |0 h+ j3 X
};$ [) a, M$ Z( X( u. b
, \4 b0 y' @! C& j
2 X2 S8 R1 N% d9 }& n! c/////////////////////////////////////////////////
6 {5 C1 \( _: a# L
/ W* x. d. }& l+ Z9 \' O( [
2 d ~6 l! g' { T( d* l+ x$ @使用时只需要使用抽象类的接口。
, b, w; m# v, D7 r- iCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
}+ g" Z/ |' e# E9 i$ o8 iCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.) e' O% H I/ H! ?
CUPnPImpl::StopAsyncFind停止设备查找.6 k& q+ `: j: p! K9 E: \) J' N* s
CUPnPImpl::DeletePorts删除端口映射. |
|