|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ ~, j8 b: Y, e1 @$ }" z ^+ W/ E+ c
* A8 L5 }3 k* A2 h
///////////////////////////////////////////
2 u( {1 a5 [6 d' V2 o; b0 G//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
& P# h3 ^ G$ _; v" C7 A3 E
! B! Z( v4 E; R
X& d4 [+ T3 k" p" Y* A* v9 j. t6 n#pragma once1 T8 L" i& l; e* o
#include <exception>
4 F/ }& Y+ u+ a& D* h9 u" {. t+ p4 [& ]4 [9 ]/ @6 b
( Y, `7 ?6 C: }8 @$ r# B5 t R enum TRISTATE{5 P1 C/ E0 Q1 Q- i. q
TRIS_FALSE,1 ]8 w, I& ^/ c0 p$ i: a$ T
TRIS_UNKNOWN,, Y# i4 x) g$ P1 C( b% N
TRIS_TRUE( u/ g& j4 y" G
};
2 q- b/ q" L6 e2 |; o8 C
3 z6 m( J. H! B' X8 c" [5 d$ P( R- o' N0 c
enum UPNP_IMPLEMENTATION{) ^' T' P! A- m! w4 s2 j( D$ e
UPNP_IMPL_WINDOWSERVICE = 0,
% x R* b3 @- e0 a% [, a1 M UPNP_IMPL_MINIUPNPLIB,
4 z3 `9 j& H3 w ]5 x4 b7 [ UPNP_IMPL_NONE /*last*/
1 K( @) }. z: u/ v6 P) A( `};
" q( i! M- i7 X' t8 {( v, \1 k4 n5 }( T5 m+ ?
- V: w+ s/ w) P. \# m
2 s0 b8 l3 x0 P! J' z* F
6 q. g+ I. g2 p6 d) @ d5 Mclass CUPnPImpl! t$ b3 @7 x( {
{6 u1 E7 W* Z: T* Y( [
public: M0 e& U# q4 E+ ^6 N8 V0 ]# X
CUPnPImpl();, q* j/ T5 f$ q; V
virtual ~CUPnPImpl();, }3 S" {+ L/ H9 R
struct UPnPError : std::exception {};
/ Z5 }( D4 s0 d* d enum {
: k1 a" p. F( k. C1 Q UPNP_OK,6 ]- h( O& j' X) i/ l$ x
UPNP_FAILED,
/ Z: R$ @6 _' V5 v' y UPNP_TIMEOUT
8 k1 s2 H4 E H, q };
8 v8 m$ e; o. F. j$ Z; ?; I7 d* _# B% s
3 W1 u& D% v8 E7 n @ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
) G. a* s/ r) C; Y% w virtual bool CheckAndRefresh() = 0;8 f5 G9 w) m1 a; g
virtual void StopAsyncFind() = 0;
' V7 L/ E: A' a5 s( u" o! t) ?& v virtual void DeletePorts() = 0;
/ X5 d% n" S$ p; m% j virtual bool IsReady() = 0;
0 T. F& Q8 |& |( q virtual int GetImplementationID() = 0;# j [6 L2 q! n
, E7 d: _; Z! S' c3 Y; n/ }7 a" N void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping6 o- ~; z8 ]8 p8 N$ |# g* }/ T
! S' A( W$ N9 L" i
l# p; [- e/ C7 C# H
void SetMessageOnResult(HWND hWindow, UINT nMessageID);6 O7 w" t+ G4 I" R' w& [
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }9 N4 j8 D E( V Y" o
uint16 GetUsedTCPPort() { return m_nTCPPort; }: Z6 M: `* X' @- W/ b
uint16 GetUsedUDPPort() { return m_nUDPPort; } + E# m& `3 g( k Z0 X, z
3 E) Q# j1 v ^, f3 f4 D
& w' H8 `4 g' `) A8 S. }' l; Y// Implementation9 \; R+ K; }9 G9 I0 g4 t$ u
protected:
$ l8 }* s2 R3 I( I- l5 x volatile TRISTATE m_bUPnPPortsForwarded;
: D, O& X5 ]* B) a void SendResultMessage();$ m& X6 S9 T& ?' i# W* e5 k) t( i
uint16 m_nUDPPort;1 _4 V3 x/ S9 E
uint16 m_nTCPPort;
7 O5 t+ O* ~, N; ^& H0 M* g+ y uint16 m_nTCPWebPort;
) ]: M8 c7 I6 | bool m_bCheckAndRefresh;
: k' p+ R4 ^/ v* y* D j: j3 a, S! k1 J
5 i+ `5 J; T: b) e1 O; sprivate:; v* p4 J- r+ q4 R
HWND m_hResultMessageWindow;
5 C1 v; S- r. m- V5 M; D UINT m_nResultMessageID;
- T5 {6 Z5 D4 P3 T( [0 Z4 i$ w f, f( [1 ^4 B" o
2 _8 x5 @8 u$ W
};5 @- r6 C, D: t! j2 Z; a. D
$ f9 c4 L9 c) u _ A9 u$ f# n
! h" H" c+ _! n9 i8 k+ P
// Dummy Implementation to be used when no other implementation is available! S+ B5 o9 z9 D- W5 M, B
class CUPnPImplNone: public CUPnPImpl
5 `; p0 G" F" |% V: W8 r% C b{
0 r6 \6 [ S: i" U& ?public:
* X9 G! N; z# x virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }# K3 A- v1 I4 |- t: U( Z6 x! E
virtual bool CheckAndRefresh() { return false; }& i& H5 r- t' U; U3 A/ [* ]0 d+ R
virtual void StopAsyncFind() { }2 c4 }: J. K8 e
virtual void DeletePorts() { }/ _0 e. p6 Y( R& B- Z$ p/ T
virtual bool IsReady() { return false; }
9 {0 d9 z# M8 x$ W6 Y virtual int GetImplementationID() { return UPNP_IMPL_NONE; }4 \: X( t9 Q. O
};8 ]: m2 X; Y6 k" {4 ]; b2 |: N
, h. }% }. x P% t9 _; X, M& H! F. b: ]( @3 K2 Y& l/ \$ K
/////////////////////////////////////# G' o8 b( s* U, N8 p; R
//下面是使用windows操作系统自带的UPNP功能的子类
& v( {4 y4 l0 A6 A& J
5 w+ v/ G: G2 U4 x% g5 u; B, @4 j, L7 u9 @7 c3 {% W. A5 J
#pragma once$ W6 ]! \/ ~. j; a: ?* \
#pragma warning( disable: 4355 )
* @- b/ c! b/ J: {5 e/ U3 u! m0 ~/ v
9 L5 y0 g! i' X" Z( x3 y& G% B, t#include "UPnPImpl.h"; H/ p; C6 E* g
#include <upnp.h>
& t% ^$ G0 u. o& d9 b6 D' C#include <iphlpapi.h>
7 N: u* {; ^; I7 W; l, X#include <comdef.h>! m9 u, ^: q4 c
#include <winsvc.h>
0 Q" Z: W4 k: o7 }, X
! g# l7 P( Y- M+ ?* T; e: m7 K( z/ [6 v" G' Q( m
#include <vector>
! c' R* a$ }5 Y/ G1 M& U/ A#include <exception>2 y1 T( z8 c" u9 r" \$ o6 H. y; e G) e
#include <functional>5 k. w7 Z+ J% J* f7 m
+ y) R! D" X/ E. o$ N' U' f J* F2 U' ]2 F
; I, Y X- z; `5 b
: ] C) q& }/ K X$ E$ T& q
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;' K' P% L. ^# W( {/ ]7 N! |
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
2 J* Z5 R. G$ p- ]. ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
" [) E* K+ V1 C% ztypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
5 Y! E8 p) E* Q9 ]0 gtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;$ K4 D$ `# D/ N, f& I) n5 |1 M" x9 z
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;% @0 J9 s+ B) x) E
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;; _' G( R! C/ p9 G* s1 P
& ?9 D9 U6 J/ M8 f; X! q ~3 F6 a: ]( h6 h% s
typedef DWORD (WINAPI* TGetBestInterface) (& d J& S& O/ y" H
IPAddr dwDestAddr,( i5 j0 y' G$ n/ T, s
PDWORD pdwBestIfIndex' \. `; `3 M7 A( F& x
);
. y) Y" P" ^$ ?
# h% X7 i5 G3 g6 f% O2 O3 Q; h6 z8 c* c' z
typedef DWORD (WINAPI* TGetIpAddrTable) (
' x b# g- k: i Z% F6 | PMIB_IPADDRTABLE pIpAddrTable,
[4 L# J$ l" T( O. x7 g PULONG pdwSize,
5 s, k, w: ~& F; V/ F$ h6 B3 N9 @ BOOL bOrder
- Y9 W7 _# b* i3 n5 ?6 n2 Y);
_' f) I9 g3 k& c+ i5 _6 b8 O0 F" ]* M
5 e* }/ x1 S+ [ P1 @typedef DWORD (WINAPI* TGetIfEntry) (, O* R: @* H6 p3 ]% q
PMIB_IFROW pIfRow
2 H* h1 D: h& Q: [9 Y# Y);0 q4 Q% A# j4 S' n# ^' V0 n$ O
3 O0 |! M# M( J! [* j5 l
0 @! `& {( D7 x$ ]6 S- d
CString translateUPnPResult(HRESULT hr);
' E/ g" c! I) }: _( tHRESULT UPnPMessage(HRESULT hr);4 H, J; r' G. x# `% y' h' D
7 ~; H8 }* b& x+ W3 p" ?0 L
3 c( o& X0 @0 h7 @1 [7 }% @class CUPnPImplWinServ: public CUPnPImpl6 R+ ~1 o; j- |6 l. m
{3 B, G" S9 d$ O9 J. S
friend class CDeviceFinderCallback;
4 F8 t, H+ _8 z: G friend class CServiceCallback;. [' V! u6 t: ?
// Construction
# R( f; g) N u1 i) @public:
7 S6 E0 u# g) u virtual ~CUPnPImplWinServ();
- ?1 b' ]& W# }) `) j3 r3 D. K; G CUPnPImplWinServ();
, L# w% V0 p( ?( C* @
- P- _# |# w& q2 m& K! ]& J" J2 o# n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% A8 `, h- E; [! M virtual void StopAsyncFind();2 [& D* N* O6 m; z w& P# y, w& \$ F
virtual void DeletePorts();" u# b1 h" o3 U% M) E* j3 c
virtual bool IsReady();9 B7 Z, C2 _/ v( y r! O3 _* a8 L
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
' q3 K* z! `# ?+ R. i5 q; C/ h' L4 O, M0 v Y; _
0 _. z t5 ?8 A6 u# }4 L; P
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
, c$ d4 I, y3 Y9 i; H$ r // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
1 @# f' N2 p/ i5 ^ virtual bool CheckAndRefresh() { return false; };! ]) B5 u8 J5 w
$ F" R, K7 _0 ?3 E5 M$ y( ~" j* ~; Y
5 {$ ?5 T; O) ^& [8 f
protected:3 C$ u8 A2 Q" t8 A$ e
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( w' T8 ^+ ?! k. I void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" Q* \9 G0 e k" P( b4 f* `6 } void RemoveDevice(CComBSTR bsUDN);# C2 e7 I& @3 J! Z+ F0 m7 {! i
bool OnSearchComplete();1 j2 q# O- U) J- A
void Init();) K# c- F2 u3 K! E( ?; D" W
0 N) {" e, k. F3 |
2 V" K: t" t |' z; r4 G
inline bool IsAsyncFindRunning() * Y% E) w7 B b. v3 {' ~. e8 X
{2 b C5 k6 G' o6 \
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
" G; G' g4 E" V {8 l! z% F& s1 G/ w) ?5 t
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );' h9 ?8 D) X1 I x
m_bAsyncFindRunning = false;6 x$ }: D1 z' v- U& `
}0 h2 ?: g4 { K2 v$ m5 t
MSG msg;' G( x. k6 E4 c! r% F
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )% W4 @ Z6 b) M2 `3 b/ c
{( f3 o: `% A7 Y! U8 V
TranslateMessage( &msg );
3 C: @. H+ p" w1 u DispatchMessage( &msg );. B% h7 r7 V3 O5 u5 f0 _
}
$ R- k5 t5 H0 E$ J: I' q return m_bAsyncFindRunning;" i& ?3 `& ]! w; u
}
) n1 k1 C( v3 m8 J/ M8 A) n+ M
! e8 L- \2 O$ k- B
5 A1 g) a0 ^7 b5 b TRISTATE m_bUPnPDeviceConnected;$ U6 C; S. k4 T6 J
f. E/ U& h3 }2 y! S" _" d9 B3 a# D. y! Q) _
// Implementation
, L% P4 l" @7 O2 }# i, e // API functions" T t5 L5 \) E# ~
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
0 Y/ I% @) O( ~ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);! ^1 g# \( B) ]1 X: o, Z
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
, _4 a) b8 K5 h d1 b7 t BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);& A% J0 [/ \' B3 g" [' h5 I% x
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);$ o; s, b5 J, |. p4 `
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);; K/ W c# g4 P3 g
+ Z) ]7 D) B' s5 j8 A9 U) g& i6 @. g; {6 M' r9 c. t' b
TGetBestInterface m_pfGetBestInterface;
4 T P( U4 I' ?) V TGetIpAddrTable m_pfGetIpAddrTable;
& _+ _& V+ r" V TGetIfEntry m_pfGetIfEntry;
, D; P; W. Y, G# i! {( o# j$ ]8 ^) r6 c4 n
0 [2 T( u" K* d- ?9 @. w6 c D* ^ static FinderPointer CreateFinderInstance();; q. h; y) O7 F3 g. y4 O5 F- @
struct FindDevice : std::unary_function< DevicePointer, bool >% T, Q+ h: k7 ?
{. \$ }7 t9 D3 w- N
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}# {* C$ S0 n7 i# ^, C) f
result_type operator()(argument_type device) const$ b6 Q( D. F" X$ {) V! a
{
: l7 t7 ^) }! S" c- ? CComBSTR deviceName;+ ]; H, i5 Z/ r: u' u4 U1 P
HRESULT hr = device->get_UniqueDeviceName( &deviceName );) n% w0 m: u7 R7 {- }! ^
- x1 R" }, ^' j; `
% _* d$ `% r( k0 ~+ W
if ( FAILED( hr ) )/ K" _" y4 v8 P5 y' `
return UPnPMessage( hr ), false;
8 B, ?) h( G* b0 }0 Z
7 |9 y: V! W; A4 K: @; r' {% p0 ~2 d3 q
return wcscmp( deviceName.m_str, m_udn ) == 0;: a" W' R8 l7 S9 T5 s$ z
}
( L( [4 {+ c* }" J# m* B3 L CComBSTR m_udn;
" P( f' W0 H) D2 X3 F( T };
; L3 i! I! Z$ r+ H1 Y* X
% c+ e2 X3 P. d0 z+ j$ Z3 X ^ void ProcessAsyncFind(CComBSTR bsSearchType);3 A* p7 T) a+ M$ D/ p, j. L
HRESULT GetDeviceServices(DevicePointer pDevice);4 L! z5 B6 ^ N6 ~' V; e$ s$ @! o
void StartPortMapping();
0 E: D5 j9 Q) l, Y' _ HRESULT MapPort(const ServicePointer& service);
- w0 ?' [4 K, d: ?2 e$ l void DeleteExistingPortMappings(ServicePointer pService);
. S. D5 e9 D7 g: q9 }, z void CreatePortMappings(ServicePointer pService);
8 o9 `7 \3 D0 P Y9 k* [ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
1 {' R- P# J: O HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
2 D6 ~9 J4 i" d' \4 N' N2 n4 L LPCTSTR pszInArgString, CString& strResult);
8 v5 l. B9 E1 ~$ m3 v void StopUPnPService();+ ]% N! z2 [0 }; O; X: ]
) s8 b! E; X# P0 b$ o. O" a' D
2 O _' M/ S! @6 F P // Utility functions& { Q+ j5 p# J
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);: B3 ^# E% x% ~1 m+ t
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 o/ d$ ~7 b$ k/ c$ L INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 @2 a o( w j void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
, o4 L6 _0 {; c2 e8 p HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
3 ^6 {! \5 q9 d& v/ }* \ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);0 E2 \8 ?( h: m
CString GetLocalRoutableIP(ServicePointer pService);) A' [6 n% H6 ]5 u
$ `, @5 ?( N6 s: p. Q% q/ n a$ x; i. Y" F' o+ ?! q3 ?
// Private members$ O( b7 N2 @/ g4 j S5 z
private:0 ^6 Q5 S" Q$ K6 _4 x7 h
DWORD m_tLastEvent; // When the last event was received?
7 E+ |) [8 U' Q std::vector< DevicePointer > m_pDevices;% R$ r4 C. x3 k4 Z3 F! @2 _
std::vector< ServicePointer > m_pServices;
2 s1 V" d( H, k+ _- P8 `4 m FinderPointer m_pDeviceFinder;& U4 f# }6 a8 |; V4 ~2 z$ t
DeviceFinderCallback m_pDeviceFinderCallback;* P' F4 |' k3 b: h4 o! U1 X; J4 {
ServiceCallback m_pServiceCallback;
7 ?6 R' s: Q3 F" \. o( V" c. K% z- ?& M4 q/ W# ^! }3 q
5 [' D8 w9 t1 D' K! e
LONG m_nAsyncFindHandle;
- E7 Z% U* T2 V bool m_bCOM;0 k+ E* i; c X3 |! i
bool m_bPortIsFree;6 n! V6 q8 N$ V) Y8 S# _
CString m_sLocalIP;
% u5 K" m: Q8 s; J( T CString m_sExternalIP;
/ z; M" t$ F/ z bool m_bADSL; // Is the device ADSL?
0 j X/ F0 f; o1 x$ H: [( v9 i bool m_ADSLFailed; // Did port mapping failed for the ADSL device?8 S" ~$ l' z/ [2 ]" g
bool m_bInited;
0 x! N( |# F! e6 h/ B bool m_bAsyncFindRunning;
: I1 e+ E7 ~, H HMODULE m_hADVAPI32_DLL;
- a9 V5 X* t9 K! l; v HMODULE m_hIPHLPAPI_DLL;- e* c6 m8 e! t4 i) F# W( \
bool m_bSecondTry;4 \7 A+ N9 Z4 o
bool m_bServiceStartedByEmule;' F0 F; V8 ] N, G( M( ?
bool m_bDisableWANIPSetup;/ H* b1 W; ]) V) R
bool m_bDisableWANPPPSetup;
# F" u" t3 `6 T$ H/ _' |) i1 O1 |3 t+ p: J) M9 g
9 D0 g6 U2 Y! c8 Q' _: q};' E1 Z7 l1 _" w$ t2 h6 k2 c
% h7 e+ j( ~# k
8 ?; E1 N9 r2 A1 n; E; c// DeviceFinder Callback
4 x+ L( l9 r6 k- Y$ r$ bclass CDeviceFinderCallback
9 E* q- d" t+ h6 J! h# [0 D : public IUPnPDeviceFinderCallback u- u+ }0 k2 [" w" V2 M9 T5 e T
{
1 ~: v$ l; ~9 F0 b6 `: e- `public:3 m; D5 l* Y! f
CDeviceFinderCallback(CUPnPImplWinServ& instance)
$ f0 G4 Y c: d3 m& X1 N : m_instance( instance )
! V5 T; {7 M) B" |$ l$ L4 I { m_lRefCount = 0; }: b0 W7 t& d+ W! C" R4 q
: q* l' O2 n( N- o
, b/ \+ U* C8 }" m, N STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
7 y9 ~4 o" A( c STDMETHODIMP_(ULONG) AddRef();
) a& Y; a1 f! V% L2 ~+ a; Z STDMETHODIMP_(ULONG) Release();
) I1 h4 I8 L3 [ D* A$ k; G& w+ R; e2 C1 I- v! }8 z' J( D
! P' K# F5 R" m& z
// implementation
$ G" }) G: J4 T. P" Dprivate:
8 [5 P7 O0 J7 i( f8 x$ o0 f( ]3 T4 q HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
( {5 o9 ~' b/ `5 N HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
& l% Y B1 j9 P; T8 E HRESULT __stdcall SearchComplete(LONG nFindData);( {+ A/ d, V: D5 p- s% D/ T
' M8 g1 p+ j6 M
/ Y. ~0 E" j4 B' N. K" l1 Cprivate:6 m% j' e; ?. O
CUPnPImplWinServ& m_instance;6 `5 S4 {' ]/ |: D7 k d! s m
LONG m_lRefCount;8 F [9 a H5 [4 L( r9 r, W. d0 }
};+ B8 `! I, j6 a4 ~
0 g( o1 @7 J! `
# }; F, R6 [0 s0 V// Service Callback
. o1 M6 C$ T7 X3 e4 P' rclass CServiceCallback, T2 V* Z+ I8 r" A8 [6 |0 |- h: i- M, E0 c
: public IUPnPServiceCallback8 q" _" f! B2 a" `2 {, n8 ^% F
{5 o Z$ W% h) _9 h2 K& G
public:
& w b. Z2 D% e" F" G. j e CServiceCallback(CUPnPImplWinServ& instance)
, w: q: v$ N/ ^. h( A# U : m_instance( instance )
2 E1 M+ ~8 S. j# Q2 ` { m_lRefCount = 0; }7 m' c8 ?- l7 P- `7 C
. o; p7 M, x1 ]" v STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 Q/ g3 H0 r+ D! ~! P$ n! F6 O" {# \
STDMETHODIMP_(ULONG) AddRef();3 Z( M5 ]6 Q* M+ L$ W
STDMETHODIMP_(ULONG) Release();
" ]" o0 x9 F& w6 h0 E4 ~5 U6 C& m& {; R% J/ G* a
6 K# @+ h7 `) C) v9 b- Z
// implementation
3 V1 z0 V% `) Y6 E* O5 z: rprivate:% ?$ Z4 m5 E+ E
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 t( f; D6 r8 J2 Y6 ~0 n+ Z- Z
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) x9 [+ J/ m; \0 r4 N$ ^
2 I; ?9 W& i* m. S/ `1 R
# V* u, a# h6 q G! U/ v0 z( u) ]private:8 ]0 [ e% ] J! x- ^5 s
CUPnPImplWinServ& m_instance;
; W6 p5 v0 d# x8 j' l LONG m_lRefCount;
) l# n4 Y! [9 h% r# x" g. X6 E};
& S S4 N) |6 O8 U' j5 r" B& S( y3 n8 |4 F2 s6 v
8 y2 W" \4 B7 }/ z" x. |/////////////////////////////////////////////////, b1 V# l; L. t+ T! r
. O+ K: s' J7 L/ B7 C( T; _- r" p3 M/ }( T* v. O A
使用时只需要使用抽象类的接口。
9 m7 W( L; N/ }8 i D$ `CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
9 i7 c; `# |& s8 f+ RCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
, P" i0 R- o( a. {# eCUPnPImpl::StopAsyncFind停止设备查找.8 v3 X; Z! ^* |2 Z+ d2 G$ X
CUPnPImpl::DeletePorts删除端口映射. |
|