|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
- h/ O& s2 b8 A, W: ]4 i) k
. }' l3 I% V, r$ R/ }! `5 Z7 G+ N; M; y- B
///////////////////////////////////////////
* [$ B2 c- y8 ~6 v- I//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
1 k0 y; l$ [2 q( e. O2 P* L5 V% ~) ~/ w4 D: _) j, \6 Z: M2 q
" v& Y; |/ m5 b#pragma once" b( H2 Y, l( U! ?6 t
#include <exception>
& |" R$ [4 O- r. x! q1 x2 H" A. y1 {" V4 ?+ { D* R3 g* m
; K6 r( Y% u" M& |1 Q& q& Q, F+ q7 l1 b enum TRISTATE{5 e3 o, o% Q! ~8 B+ L' c
TRIS_FALSE,* Q5 C. V0 q, p, d' k3 X
TRIS_UNKNOWN,, v8 |0 U9 C2 Q& O
TRIS_TRUE
9 |$ J9 T3 |: v- V};
4 x/ k8 ~6 C/ V1 y Z6 E' W& ^' D. c. m7 o' W3 x7 p
. J8 E) _) E' U9 M) O# V5 L; U. o; u& [enum UPNP_IMPLEMENTATION{
8 |1 d* j8 q7 v& _. D UPNP_IMPL_WINDOWSERVICE = 0,
& S# d( m: Q# C- C' K UPNP_IMPL_MINIUPNPLIB,( J) J2 }4 E! d- g' T
UPNP_IMPL_NONE /*last*/$ r) T. P9 h7 `
};
1 i0 j2 ^5 r$ q5 y2 X) F( Z5 [3 i
# D, ]3 ^; t$ T; V8 V$ b
' y) _9 G% E5 y; Z% F- e9 Q7 f! t5 c) I+ h P
9 ~6 Z. V! h" C m. ^class CUPnPImpl
8 i4 x/ Y- ~4 P{
! v9 M, v5 l0 Z; Zpublic:
8 G% b% t* O! \' v CUPnPImpl();! _ ^$ p/ y$ K1 R) L4 o- K( e9 j
virtual ~CUPnPImpl();4 d+ l$ }- r. h9 f
struct UPnPError : std::exception {};
* Y+ P! R {7 I: h6 y enum {4 Y0 X$ v, E9 s, E
UPNP_OK,: L0 G4 J4 I; B
UPNP_FAILED,+ n% r9 ?) F5 U5 a
UPNP_TIMEOUT& w, I _% n4 j2 p7 w" x
};$ _3 P5 u: l8 ~# l) M0 ?
5 ?2 S& M" F4 H: b
; w. Q' V$ j; n% o/ B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
: C( x' }& ~) y5 ^2 P) W7 g# ^/ q virtual bool CheckAndRefresh() = 0;0 ^" N8 L! Z' y) r9 s
virtual void StopAsyncFind() = 0;4 v$ Y4 c; H: x; D" x: `
virtual void DeletePorts() = 0;$ ~- C1 z% G; Y$ I6 P# I$ A: Y
virtual bool IsReady() = 0;7 Y; \& P6 t" S
virtual int GetImplementationID() = 0;
; D1 E7 v6 r: {. h# g/ S; Y$ a4 @* y( m3 P
9 f" z/ }8 V0 i$ a( ?8 t void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
" @- \ b7 W4 c0 i" N& i, j4 P5 Q( {8 ]% @: w
! P" S- }2 O/ | S
void SetMessageOnResult(HWND hWindow, UINT nMessageID);$ }5 m! M4 s: P/ Q+ p3 N* `, ?% h* |
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, n; k$ |. ]$ H% l9 ^
uint16 GetUsedTCPPort() { return m_nTCPPort; }
: E" N7 R& n5 M0 O- _ uint16 GetUsedUDPPort() { return m_nUDPPort; } " v$ C# P6 u/ C. ?- V) B' B
, N- ~0 n9 X! C" ~, m4 \9 A; ]
! r' v5 I1 h& ~- `// Implementation( M" o+ } H9 }, M
protected:+ O5 [7 s1 O" V" |5 ?9 \# h
volatile TRISTATE m_bUPnPPortsForwarded;
, `& X# S: i2 R( \: B& q void SendResultMessage();' m2 [1 L3 q6 _5 G4 K- I
uint16 m_nUDPPort;
' Y5 q& X4 U) B/ R7 k- ~- \8 N uint16 m_nTCPPort;
2 C: }! C' H/ h% a uint16 m_nTCPWebPort;
; L5 f! S) d( b- O. m k bool m_bCheckAndRefresh;3 Y8 n. |3 Y1 L! \+ m" `
' m4 k7 J( g0 T4 A3 A
# q( y7 f f. N3 zprivate:
4 l! u J3 N! j/ ^2 t* }* V HWND m_hResultMessageWindow;/ M$ A% \# k* S; C
UINT m_nResultMessageID;' k( ~( X/ T! ?" A. F: l# x' S
- Z4 t8 v# B* d! q1 d! w0 [- P
; Y' m, [! `+ i- n! G* r1 Q; @4 X};
5 X0 b; q& j" X- [- f I! k( I0 ?! e% Q! w% w9 \, S
. B8 d4 ^# _' V; [( `" }
// Dummy Implementation to be used when no other implementation is available
6 y' e) l' G+ s7 v- w" [class CUPnPImplNone: public CUPnPImpl( n k# q( `( i f, k% y
{
; `0 t8 z6 t( ?0 g# Qpublic:
9 p2 f% J {. R, O' n( l. Z' B virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }, l6 S J$ R; e3 U/ ^$ F
virtual bool CheckAndRefresh() { return false; }3 j& r0 V% w) s2 G% [. E
virtual void StopAsyncFind() { }) H: X& Y$ R, u. M3 [$ D2 ~6 ~
virtual void DeletePorts() { }* a4 J2 [( f; f* [0 y" j
virtual bool IsReady() { return false; }1 f3 Z( X2 K0 t
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }. ?: Q n* }9 J2 S$ Z/ X& k
};+ d, Y& s/ O( t# I" i8 Y( b
' X# c. A) A* e+ @
2 d+ z7 S0 O$ Y; k/////////////////////////////////////
* n: [% [7 \0 T+ o//下面是使用windows操作系统自带的UPNP功能的子类5 w5 T* f% [& i7 R- p
/ ?# C& e% ~# T3 l
% D. P: k' a: _7 Q, C' r7 h#pragma once
& s: b& A$ \ Y+ L+ q; V#pragma warning( disable: 4355 )
; i, |# N0 ? C/ U6 f! k3 E4 s: j' A/ H* u5 u% X O
5 V; \" Q# F, \ i4 o. `
#include "UPnPImpl.h") S' X: @+ n4 O+ w1 i
#include <upnp.h>
7 I, Y0 @5 e0 t7 s1 D1 F#include <iphlpapi.h>) G9 f2 G* ]' ^2 t: E; l4 U- X; T
#include <comdef.h>
8 y+ F K9 N; j$ h1 V0 a4 M( c#include <winsvc.h>0 p, X8 ^. L+ S4 l) D: ^
2 U, A4 ]- v. b4 v0 f- }
! \! X2 M3 F, g* i3 u
#include <vector>
9 G1 }) W" e9 Z) [* n5 z$ I#include <exception>
; O9 Y3 i2 z8 m: ]$ F! w#include <functional>! M: X: q7 F6 ?6 f3 h
O& I4 @ L7 p4 B- O6 t3 X0 ~& u
1 r( p& m( Y, c" B& @: t5 Z
# X; C( q( O8 ]! G1 q2 L5 k9 ~$ e$ T- k0 U# p( n& q
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
# t9 `3 J' m4 H9 Ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;- Y8 h7 j" l1 A# c
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
, v5 M2 N$ }: x, m5 I- G9 |typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
) s) M/ u$ ^( k+ m5 m; U' jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
( x% l/ z+ Z& J3 u& U1 b" vtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;6 S6 P. d) C! ^; g) J$ c. D
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
9 i( N2 |6 }: j. u! s
' ~* U* H, R0 t! q$ I; a- q1 q: }$ b: A
typedef DWORD (WINAPI* TGetBestInterface) (- N2 ]) d3 P: F) D1 O
IPAddr dwDestAddr,& @( r" ^( u* d4 ^; g0 j9 X4 X
PDWORD pdwBestIfIndex) L, x( t' d) v) |3 P6 ~/ F) v' A
);% `8 n. v9 q3 |9 Z0 ?' ?) S+ T+ F
9 r6 u% `, v, F3 j) S
6 r/ m& n' O) ^' m+ Y( h7 m* q. l( `" Dtypedef DWORD (WINAPI* TGetIpAddrTable) (+ M7 V, v0 g; p, ?
PMIB_IPADDRTABLE pIpAddrTable,
5 u1 D( t/ o" p2 l2 V+ Z8 o6 { PULONG pdwSize,
! N8 G7 u' N) p6 N BOOL bOrder+ U" z. E- L) x4 z w
);1 D8 P' l. I+ P7 A' g, J
, R% F& c5 f, T, d! u0 N& K ^% \% @5 w9 E: Y5 U0 ]
typedef DWORD (WINAPI* TGetIfEntry) (
1 p" t, ]( J3 t4 S, X PMIB_IFROW pIfRow
- n! l+ E e. n);
: L' s0 w# E" H: ~: Y r8 `$ ~0 j9 l' }
2 M* f# ~" h/ VCString translateUPnPResult(HRESULT hr);' z* E5 E- K. Z0 K
HRESULT UPnPMessage(HRESULT hr);- @4 ~3 x: c1 G) ^+ M7 O' I
# X% m- Y/ a6 M" V4 z/ _
1 `/ ]# G) X( `* P; p) kclass CUPnPImplWinServ: public CUPnPImpl. G* \2 A. j4 Y9 R3 d& e
{8 G, d* o9 P( D- Z+ F% n( j
friend class CDeviceFinderCallback;; ^4 _" b* l( E
friend class CServiceCallback;
; z* w+ s& }4 w" ^& B// Construction
( Y0 J+ `- Y( |2 l4 jpublic:3 e! u- X9 V5 }6 B! G* N# A
virtual ~CUPnPImplWinServ();$ V7 M4 U3 ]! m2 J
CUPnPImplWinServ();& } _6 S2 ?: \/ F' R4 p
' b( e5 Y2 j# T9 Z/ C) C: x
; e( |+ }( h1 }- ^5 N9 x- Q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
3 \. G% s7 N/ V& g4 G virtual void StopAsyncFind();
* W$ N+ d0 k* S1 F; O% L/ n- a virtual void DeletePorts();/ y0 \4 I; X9 }* U5 ~; S6 q
virtual bool IsReady();
# h* r1 m$ w& @2 `1 [+ n8 F virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, c! A" F9 D0 X8 ]+ v+ D8 R6 R( q+ ~! Q7 L- N3 j) V0 L) ]- C. a
9 O2 {# E3 j3 v6 ~+ H // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)6 b1 e- O+ h) ~, U2 O0 ~4 l5 c
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
6 a$ v' g. i* w6 C- W; R virtual bool CheckAndRefresh() { return false; };
9 a% E% L( ^# [2 R6 C1 b- y# [& ]) v3 x3 v
0 G( F- i+ [. X p& i
protected:
7 {' c3 m( s/ v void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
9 }6 O: U8 q+ [6 P' e& w ` void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);4 Y4 L- M+ N! k* N+ F
void RemoveDevice(CComBSTR bsUDN);
. [! _" m( J7 p: t7 K bool OnSearchComplete();
& G' f4 w: W# ?" k! W \ J7 n void Init();
8 g3 {; }+ T% h ]( r4 f
3 p" A5 Y: D* D, b5 x7 R2 k, ^, ~# T+ G b3 P3 B
inline bool IsAsyncFindRunning()
O; @' l! C- o; p {1 Z; U7 o" d* O. ] Q8 V& e c
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); x( h3 E2 ^5 L7 k, l1 Y
{9 p( A; J. Y2 \
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );% P; c X7 y# H3 [
m_bAsyncFindRunning = false;
2 D9 P! y& K* a& d% g# \2 ? }( I: {% H& d. p4 b4 f( B
MSG msg;
7 c" Y% U: D2 M9 e while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 C/ B, l4 u+ f8 K) I' d {+ G+ G' s5 O! D+ t
TranslateMessage( &msg );
9 t0 `6 E+ {, o, ~0 C. A2 h5 E! } DispatchMessage( &msg );% T9 P5 z2 W( z, f& i! y
}) x7 f% H; N p$ j
return m_bAsyncFindRunning;
! d, a' p2 N1 k2 A4 B) W }
( ?. t5 _% h6 }: S% H/ Y' X3 Q0 a5 ^$ c7 p" G$ Q( d$ |
, E: m0 y" p% X) A% o
TRISTATE m_bUPnPDeviceConnected;3 X6 n$ `, q3 D. ^8 U! \
0 d6 @3 e* ^& i4 f% G7 @9 e% I% C3 v
& v s0 q* V. q! i4 P// Implementation8 J& H0 H$ _8 E: c+ y; y* [
// API functions6 S" f0 G4 d) E& ^9 k/ f1 \+ D3 D
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
6 R/ H1 B% s2 |: [. r SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 l6 G2 N9 z; V BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
+ N$ D2 G/ @) \+ U( e( f5 |9 G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
/ q' j# }# k- R* [2 h0 M BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
B5 T; Q1 ]) h6 m- ? BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) H/ Y# H3 p$ \' F' A* ^, v0 T0 ]# p/ k/ s/ Y( A
! H) [) V! H, | TGetBestInterface m_pfGetBestInterface;
! T2 ?! ] B' v0 T TGetIpAddrTable m_pfGetIpAddrTable;
3 ]) Z* d, n3 f+ A, ` TGetIfEntry m_pfGetIfEntry;- ~* l1 ]; R' P1 {4 P! F
4 f: g8 @' X( y, |+ Q1 r
1 ]8 {0 J- _, F9 B X2 ?) s
static FinderPointer CreateFinderInstance();
! y1 g8 d: U, d% G! [# @) ]. { struct FindDevice : std::unary_function< DevicePointer, bool >
+ s5 r' H' H; Q6 i+ C& G7 k {
5 `+ c; ?$ R2 ^) s+ E, P FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
2 u% W8 t3 V0 h+ L7 i* b x. }: | result_type operator()(argument_type device) const6 L% _% F' o7 c. J3 {$ |
{, } @- O$ B, R$ O' b! A' x9 U, ?
CComBSTR deviceName;
1 a$ E- P! n8 I3 M3 f HRESULT hr = device->get_UniqueDeviceName( &deviceName );
* T' ^! a4 J: O' i4 C& |) T8 @
5 `* p5 W# _. V# Z" Y, U% H6 y8 ~/ ]
5 @+ y1 ^' O* F2 S) U8 e$ _! S' w, R if ( FAILED( hr ) )
7 O: {/ S. [, w return UPnPMessage( hr ), false;
$ ^# f: l) T, C* {
7 C V; X: v3 P( z& k7 e, t# l0 `) t7 J9 b9 x0 Y% `4 ~
return wcscmp( deviceName.m_str, m_udn ) == 0;
) t4 J+ H1 _) T- K# `0 U }
) S o2 x" x' a! M CComBSTR m_udn;* _- L& g2 _% K
};
6 h( ?3 I* q# S! h2 k5 }6 p: q - ^% q6 ?% A9 o9 m2 j; P& V* K1 P1 Z
void ProcessAsyncFind(CComBSTR bsSearchType);; G5 u3 j+ T+ [ A3 `8 m
HRESULT GetDeviceServices(DevicePointer pDevice);8 D, G, _4 e" w, B
void StartPortMapping();
: b: d' ~* R9 { HRESULT MapPort(const ServicePointer& service);
5 l3 N% Y: m* _% Y' s. W, I void DeleteExistingPortMappings(ServicePointer pService);
3 b4 V% `' w. a; M void CreatePortMappings(ServicePointer pService);# R5 d8 S" A1 L3 ~
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
6 Z1 v) m* C" Q. v HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: L$ P: j1 g- e8 R7 S6 ^( h0 l LPCTSTR pszInArgString, CString& strResult);% V2 `' Q! a6 Y, p( ^' p
void StopUPnPService();% I4 l$ |- e; U7 g3 X& t( D) a
: o2 H) E6 m2 J1 @1 q7 i g U# d
0 X3 e, I9 u- w j7 R5 J- Z; _ // Utility functions
: V- W5 d" y$ S: M! f2 o. B HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);) r3 w( K+ @' ~; Z- |0 `3 t
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ g! ?3 |" \+ S; W9 }4 A
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);( A7 T+ H9 b }. K- N! [0 C( N
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);) F& s# I+ B2 R: O1 t
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 x8 q2 S, j" @4 T: X* Q6 q4 X
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
2 ?$ I9 T/ S9 I% C CString GetLocalRoutableIP(ServicePointer pService);
7 b, c' P! D; V& c/ E" r7 a3 R' m3 H" J; B
& X- N* l6 K& Z
// Private members( K% \) Z4 q, ^/ F
private:. _; u3 s; t" k# x! p P5 `* n
DWORD m_tLastEvent; // When the last event was received?
3 Z6 W" Q9 H. Z std::vector< DevicePointer > m_pDevices;
. U# S, \* \0 b, R9 [ std::vector< ServicePointer > m_pServices;
! |; j; M( l3 s; @* ?( ^ FinderPointer m_pDeviceFinder;
8 E5 O4 U/ J f! M$ N" q DeviceFinderCallback m_pDeviceFinderCallback;2 Y$ b/ U8 Y- t7 r" z
ServiceCallback m_pServiceCallback;2 H/ w* s0 B5 ^+ @% r
) }" \/ T/ i% t; n0 s: t: @- s r3 O5 A, n
LONG m_nAsyncFindHandle;
) V f2 }6 f$ b' H bool m_bCOM;
. V: q4 V4 Q: k" r, P! u) a bool m_bPortIsFree;
6 T% k* A3 U4 s0 u8 w CString m_sLocalIP;2 O8 C: G( E& P) t8 j; \
CString m_sExternalIP;
: N6 {- Y7 b. D1 @! [# K6 O bool m_bADSL; // Is the device ADSL?
+ k/ ]# Q& R: `3 ^ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
+ x0 b2 f0 W) P( d0 A; p bool m_bInited; Z. e, B. v( o/ _
bool m_bAsyncFindRunning;& D5 j# E7 @' v- [& ~' Y% @
HMODULE m_hADVAPI32_DLL;* O4 S5 ?, f# S' K. [7 O
HMODULE m_hIPHLPAPI_DLL;9 g/ B! h+ z' k
bool m_bSecondTry;
i' _2 V/ @3 X( }! o6 ? bool m_bServiceStartedByEmule;
5 O4 y5 m5 m- T9 |+ T bool m_bDisableWANIPSetup;, @* V" b4 W* N* v% U& l8 P# R
bool m_bDisableWANPPPSetup;0 m) t7 m5 g/ p
9 u+ q9 B& G1 b% e1 D5 k3 u Y0 k
};, H$ o2 ~ v, {; U
9 A: K. F \$ U# e+ ]$ D9 a
: J" t1 A; h* y* ~8 ~6 N6 \// DeviceFinder Callback
9 {3 b- p/ |) yclass CDeviceFinderCallback% ~$ W' J8 c+ e# r, r1 x% Y
: public IUPnPDeviceFinderCallback" Z2 V6 l8 {4 j8 Q) A; r9 f% `
{
, E$ \4 R `3 [7 U. y Hpublic:) v7 t1 j+ k' Q) n! b) x
CDeviceFinderCallback(CUPnPImplWinServ& instance)
; p6 x/ X2 g/ O6 P : m_instance( instance )
2 V3 P' k {: Y* x9 | { m_lRefCount = 0; }
+ u% i' w4 _, D" \$ f2 [! L2 `) d+ P3 K, W' F
( a2 ]4 ?9 T; l& N$ f& o* B( ]
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( {3 v) g% x; G: K4 f5 H
STDMETHODIMP_(ULONG) AddRef();; L" i4 A4 l( d" X9 a
STDMETHODIMP_(ULONG) Release();
' D5 m# H; W/ W/ N* Z4 E* L' V3 I1 {! @
/ \1 G& ?/ q( A+ t
// implementation! m0 N; ?0 R' L# M) N6 p i
private:
( Q% m; F4 j7 p: i6 \$ I3 A HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& w2 v% [- ]2 x* ]% W
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
! c! s; S* d/ K) ~" z& C9 E8 r& ~" O$ Z HRESULT __stdcall SearchComplete(LONG nFindData);, ^ z e, A( ~. l$ i2 V$ G! e+ h1 H* g
, Z, Q( F1 x" E4 Q2 A4 N) \6 c9 q
+ K) r6 U% T* K( @. n. [private:2 \! _: n; T1 r }7 \2 n7 S4 v# J
CUPnPImplWinServ& m_instance;. x% @: }5 y0 m3 X
LONG m_lRefCount; U) ]* b* g/ w% U. P( ]
};# b" U% S0 ~, p: m8 K5 h2 {
( y- h# f3 R5 t4 ?) [: W6 t' L p
; M. N& S- {3 c// Service Callback 1 b% ], y0 f& H% V5 Z8 k9 Q; z' W
class CServiceCallback9 s) v& A& Y5 N O
: public IUPnPServiceCallback e" i. e p; f+ X
{
$ }( `/ M: z* d8 \public:' ^$ @5 f: `0 k
CServiceCallback(CUPnPImplWinServ& instance)
# r- ^6 A5 ~' B2 T Z% a# j : m_instance( instance )
: l1 X$ m8 y* q; Q6 ^+ l { m_lRefCount = 0; }4 I+ d1 A! n% a$ o/ d
3 z+ h) K: }, N+ U
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, j8 a- ~! H* ]; g STDMETHODIMP_(ULONG) AddRef();% z [) z. A/ G# f
STDMETHODIMP_(ULONG) Release();
9 B2 h- d8 G- l) O( ?2 g G+ z1 T0 b1 F. n; Z
8 [8 K$ J( a' d, Z, U# N/ O5 p// implementation
$ L) K3 |$ @) A) gprivate:! d, S/ ~% R' Z1 y2 U
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
( j, N! u1 `! t* _ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);: D+ [7 g7 c( J" I* h+ j( A
! r$ m9 c! W8 k3 R7 [4 }( {! ?$ a0 s4 H3 |' O) I
private:
$ _2 E* {& o2 J% i4 w6 O; F CUPnPImplWinServ& m_instance;( \7 D2 X" r$ X' T* x
LONG m_lRefCount;& c4 L/ J* o7 u1 h1 e
};
( @' s8 R- B$ f. ^( y2 V: ~9 O$ W, c8 }" E0 t7 L
+ l) o9 k! r6 j, V! o4 M" z
/////////////////////////////////////////////////0 n) w/ M' e q! S( O# x8 z5 V3 W; s
\6 i. X! T; M$ g c& C$ y
" D, Z% t9 g5 {8 ]6 [- k& `. u使用时只需要使用抽象类的接口。* t9 q& i! _! @3 n0 h
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.9 A8 y& Q8 G: l0 K
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.6 \, s+ Y6 r" u( A
CUPnPImpl::StopAsyncFind停止设备查找.! ^" [. w- P. X9 c
CUPnPImpl::DeletePorts删除端口映射. |
|