|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 Q# a+ n( [! V% D9 f
. Q- C# J) d" R+ q% h& ~9 X' f9 }
% p1 {( v& H( l$ u& F: }! }///////////////////////////////////////////
. O3 F. Q7 M3 h! ~//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.& [2 \. f2 J2 L$ b: T* @
* k7 J- ]9 R! k1 P; i- S
4 K$ i8 m( N/ n) h% w#pragma once
# {" U9 A, B6 t& p% j#include <exception>
. j- r2 @: x, G
' @ E; A; @1 q- P9 ?. E1 }' ~. x3 u: x
enum TRISTATE{7 E6 Y- Q1 z5 `+ f/ M
TRIS_FALSE,( y# X9 [8 }& ~- N
TRIS_UNKNOWN,$ z5 n, Z$ F7 M4 d8 K; N/ _8 G8 E
TRIS_TRUE/ d6 J ~, p' E; r$ E
};
+ o+ a8 E8 o ]# O
: h6 r" r1 Y. B
_/ e5 L- z8 M* jenum UPNP_IMPLEMENTATION{4 ` u# q9 r' h3 b# F+ Q+ R! E
UPNP_IMPL_WINDOWSERVICE = 0,
3 w! l0 k4 G% G9 W+ m UPNP_IMPL_MINIUPNPLIB,
- ~, S3 B& N' F% I/ R5 } UPNP_IMPL_NONE /*last*/9 x3 z, t, F) |" ^3 y3 Q
};9 n- q2 O6 s0 e1 k5 e4 R- R
' W& w+ Q" Y" Q# a# i) c4 D
: b6 B$ b! ]" O6 V0 b ~5 u( a( A* k" y2 z( q- z! h
* _- X1 v/ s+ S: B; N8 O3 k1 R
class CUPnPImpl
- |- e7 a7 ^* V7 N4 K{
# G6 j- b/ @6 ?public:
! r2 y1 Y$ `3 k0 }) ~) H CUPnPImpl();
, h2 p1 a) M4 d virtual ~CUPnPImpl();
* h; h& {% o1 e7 i: j% `5 ]3 L struct UPnPError : std::exception {};
; C0 y4 \; F( o enum {
+ E- N. J5 \- I7 n; t5 z UPNP_OK,! W1 t* _# U+ {4 |# {9 D
UPNP_FAILED,
6 N+ U3 g0 ]' C2 W" o7 | UPNP_TIMEOUT
% U& @$ c/ ^) O+ i6 M* Q$ p+ F- E) y: u };
9 T( G7 [ o2 ^4 O$ f* O0 D/ p% A6 i# z; \
; i1 ^. s1 E3 j$ h7 [- M! c
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;& ^! V! l# A9 M1 `$ I
virtual bool CheckAndRefresh() = 0;
1 [- f( p0 R; m virtual void StopAsyncFind() = 0;. p% ^! P) ]8 U3 s- O
virtual void DeletePorts() = 0;
4 r W0 W2 i* O; w; `7 N, S3 C7 Q virtual bool IsReady() = 0;6 }0 k1 X! O, m( H& a, w' ^) e
virtual int GetImplementationID() = 0;2 q& ~% x' O% A) J% k# Q$ e
2 I6 L8 A0 ~2 l5 c+ l
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
, D. ?+ I6 b" }/ K% v! d: r
3 }+ P C! `+ I& b; o* ?1 ]! W& K6 n5 |0 `6 B* Z3 K6 R
void SetMessageOnResult(HWND hWindow, UINT nMessageID);8 h2 k6 Z' v2 X+ f I4 K
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, D9 v6 G n7 R `
uint16 GetUsedTCPPort() { return m_nTCPPort; }
& q0 s2 D( P8 [8 J1 l) m. r uint16 GetUsedUDPPort() { return m_nUDPPort; }
" `/ O; \& L6 z; ^. z7 R: p Z: C& d9 u0 q
/ k3 K4 s/ r1 i, ?/ h# w// Implementation, k# K! b+ T% t" D3 \
protected:3 E: n: W Q* k) ^; ^( ?3 f
volatile TRISTATE m_bUPnPPortsForwarded;- @( G I/ P: {; r6 o5 z
void SendResultMessage();( [# h: p% w) @ H. R+ Z. q! b x5 A |. [
uint16 m_nUDPPort;
# j# S) ]5 q6 h) r uint16 m_nTCPPort;
; a, S% ^4 k& `6 T) J m uint16 m_nTCPWebPort;8 P: R- q# \ `- L$ y
bool m_bCheckAndRefresh;
9 m, ?8 x6 E+ m) _; }& b) Q5 n5 V4 u, w: G
2 i$ o, l, m4 o# f: b6 T8 q1 d/ L
private: Z2 G5 J! q# W! S& I4 u9 ]6 M r9 V) L
HWND m_hResultMessageWindow;- ?7 l1 R: N! a2 w8 u1 F
UINT m_nResultMessageID;
7 Q( P5 @% U- a+ u9 _0 i# v$ V7 E \, s$ l! w9 r6 m) K
1 S: n# q3 e# N};+ j7 d. N+ q% b0 G [
( Z N8 R- e" a
6 B9 X& y; k7 p8 T// Dummy Implementation to be used when no other implementation is available
, X9 e( u% h- X5 A* D1 y4 {class CUPnPImplNone: public CUPnPImpl/ ?: `7 V, f4 U! c3 W
{
+ J0 X4 v4 {0 U; S. w' Qpublic:
: @' I) X# A6 A/ C" U virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( d8 a. r. [! p$ Z7 p0 K# ` virtual bool CheckAndRefresh() { return false; }0 ]& j4 R9 t% X5 Z; W, [$ L
virtual void StopAsyncFind() { }' _0 A/ c8 f. R0 Y6 C
virtual void DeletePorts() { }
6 K) W0 C$ U f virtual bool IsReady() { return false; }
; H8 Q1 S8 P" E virtual int GetImplementationID() { return UPNP_IMPL_NONE; }: }' m& C/ s0 O x! }5 i3 Q# k) |6 l3 r# j
};
8 U# d( _/ a' Q, X6 h. x" D5 W
/ h5 q' F c4 G3 o$ a; n
8 X9 C3 w, N1 D X: ?/////////////////////////////////////% K2 @6 M4 l' J- D8 {; y; g
//下面是使用windows操作系统自带的UPNP功能的子类. @# D5 P6 ]3 Z- z7 h* N* f
' B/ k! R# ?) P- g( K8 |" G
' [- v9 E; N$ m; ~% z
#pragma once* G4 ], E; O" ~, Y/ J
#pragma warning( disable: 4355 )
7 D, h) T. ^4 Q1 y3 \. ~/ q5 c
: ]* \ D2 z$ R8 s" `# u: d
' k; R! e5 o& e% Y1 C( w) x#include "UPnPImpl.h"
~( a' Q/ `4 J#include <upnp.h>
# v- e7 m9 Y. ?3 k7 S( H8 T#include <iphlpapi.h> U6 T# n0 f% \7 }$ @: d; o# U
#include <comdef.h>
/ l% Y; ]' s9 l/ Q#include <winsvc.h>$ H8 d7 s+ e6 b+ [7 h
. ~+ B. c7 M) g7 B
' o1 J+ L. y8 E( s#include <vector>2 U4 ~2 g8 ~$ R$ r l- c
#include <exception>4 } A- V ~( Z! H
#include <functional>5 `# N0 t4 E3 c5 P2 T
+ b" A* n( I. A( \ N% O& C8 r- x: K* { J
0 I% a) Q+ B) B5 \: U
, H3 R+ J* s, w1 A9 N. Stypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;8 F, [: I \" l) c1 @# U
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
S" B7 B5 c M% Q' c8 V* Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;0 \' M/ v% r. L0 G/ Y. h' D0 E
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
+ R( L' I( }6 y; I/ q1 @typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;. p- v/ D: B) M* Q: O
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 n5 F+ Q% p6 ^2 ~# Q) f% G( Q$ utypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 A U ]# k, ^( Y1 o+ r. v
5 x6 m& ^2 x. `6 M: \: _( n0 N5 N7 z! u. `7 O9 H6 U
typedef DWORD (WINAPI* TGetBestInterface) (
1 {% {, b) L# E+ Y: s2 X IPAddr dwDestAddr,
4 i$ R3 R$ {2 d0 s4 q PDWORD pdwBestIfIndex
/ m/ _& n9 `1 z- s' i! z4 @& \);, d! _, u- ?- T+ ^9 T2 _! c
6 [3 Q- [0 E% q* n0 S7 S2 y: v4 J
& ^5 ]' j" A. \1 B; Q2 Q
typedef DWORD (WINAPI* TGetIpAddrTable) (
& W" ]) ~9 {! I' o9 a, }5 k PMIB_IPADDRTABLE pIpAddrTable,' L+ w/ ~, Q4 C8 Z
PULONG pdwSize,
# j9 J t% j& T1 p) [ BOOL bOrder
. R' U" T& t% W* z4 E; ^+ A);
" {0 M& @4 {. r8 f* t
9 \5 y3 ~0 b# O6 p, m1 r l! Z$ H/ s9 Y/ A* A: k
typedef DWORD (WINAPI* TGetIfEntry) (
8 A) ?% l9 q) B5 m PMIB_IFROW pIfRow4 _1 g& ] n v/ N/ D
);8 N. T3 O: O# U
* y/ p; X7 Y* M2 |, `, O2 p/ _5 Y. v/ n8 a; `
CString translateUPnPResult(HRESULT hr);
' P4 l( S+ g S. x0 fHRESULT UPnPMessage(HRESULT hr);8 Z, f6 [ w6 Q0 _- Q
9 M" z' ?. T! [ [" W. G7 Y
" A* N6 {$ k& Q) O2 H
class CUPnPImplWinServ: public CUPnPImpl
; O, L4 _0 ^( T9 q+ c/ R' V{
: O, p6 D m& E7 |4 M friend class CDeviceFinderCallback;1 I7 B& Y& W8 _, e
friend class CServiceCallback;
3 I( \, {- S! ?' X// Construction! d& \" E' V! X3 o6 g2 `7 Y: U
public:9 T ~8 L' H# s6 s3 y
virtual ~CUPnPImplWinServ();+ `/ m" e8 m2 z7 @# _; ?, e# V
CUPnPImplWinServ();! Q& E% N. Q/ Y. x* P; p7 z
2 Q9 c( m1 V' c/ p
0 Z. Y. y5 ~1 e8 b3 x6 e1 N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }- _5 Y% K* l# p5 ]/ t
virtual void StopAsyncFind();" q o& i/ L g, O1 i9 i% J# A: @
virtual void DeletePorts();
0 R: z, y6 @( P- O4 g1 V virtual bool IsReady();! J% {9 W, N- E
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: r% y" {% Z) x1 O
& D6 U b0 ~3 Y }& [; b' K
3 B4 E6 t- R' m& v8 n3 Q // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)! l) o& t- |- \ a; C5 i' h2 x
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later; f. s: i n( w$ ? T) D- ?% L
virtual bool CheckAndRefresh() { return false; };
' [6 n8 [6 f% b. c4 T% @8 N, A2 X- ~" V7 W; p
3 t, W7 O& ^, A" Iprotected:
, @' ` R# [0 @- F% ?( y! X void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
v2 U3 ] }5 }; S) E. n* Z void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);: b5 Q% Y" f5 f8 K$ E$ C# E
void RemoveDevice(CComBSTR bsUDN);$ u2 b4 ^; c: ~/ A- d- r8 L
bool OnSearchComplete();0 b. b6 f; x4 T/ _( p
void Init();% n( \. @" J/ W1 s( s6 a
; s8 Z# [7 h& @. n* u1 B
4 q2 e% g9 K3 Y inline bool IsAsyncFindRunning() ) S( E2 O$ W; H
{3 a' z, C3 A& T: U" U7 K
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
7 F0 }4 I0 A+ x1 m/ S k( ^ {
3 A, |6 p0 M" [% X m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
# }) S1 J% p9 q- ]$ { m_bAsyncFindRunning = false;' {7 K) L& n. X% r- o. H! ]( J
}7 H i- z# \2 N* f: m4 k
MSG msg;
" ?4 Q) _+ c3 M3 I, |9 j while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
( b8 L" T+ ]% G4 ~ p- s {! S! Q* Y4 u5 E- }- r8 ?
TranslateMessage( &msg );
, [5 D' w: D# l DispatchMessage( &msg );. m; d0 i0 l; y# P5 ~- P" l
}
" K6 |) _; {: g, E; ]6 s, f return m_bAsyncFindRunning;
+ {3 m; A: {: W+ g! P" p3 W }
j6 ?5 v+ u5 A: n' N( k
* J7 b" x4 q8 W* u& Z: {# P* z
. Z- V2 t* g1 f8 D- d; g TRISTATE m_bUPnPDeviceConnected;6 Y; _8 O, e+ e1 n! i
) |. |4 S q& y
( f Z& s- Z+ O& K% o// Implementation/ n+ v7 C/ c# l
// API functions& O% i" {8 D' Q+ E& x, M
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
5 P. Q* i* P$ f SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
6 g: a- h: v8 W3 G2 t; V! Q2 b BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);, a+ s* e& K) ~- M% y3 o
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);! J' ]" z+ [' J) {, i
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
- v7 ~. ^' P& N) @0 }$ J BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);2 v- L& t5 R: s- r4 s
: _: E( |9 ]$ v: v3 A. d$ ?( P8 |$ Z6 y
TGetBestInterface m_pfGetBestInterface;
' i. n6 J9 _. }3 E TGetIpAddrTable m_pfGetIpAddrTable;. |8 G8 X4 l2 K9 C
TGetIfEntry m_pfGetIfEntry; k' c" o; ]3 q* Y+ G7 C; X9 K9 A
- }. `# X7 X+ m% D2 x
3 O* n) ~& B2 A! P/ c
static FinderPointer CreateFinderInstance();
" a2 I+ Y0 a' p4 T L: ? struct FindDevice : std::unary_function< DevicePointer, bool >% K ^/ J" A( [4 J. N
{& P7 G5 W1 A1 _5 X
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 @- w1 e% |9 w% v% X result_type operator()(argument_type device) const( o1 \6 [2 D$ o
{
5 r8 c* `$ R5 `( B0 h CComBSTR deviceName;2 I8 P8 d4 O# @7 ?
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& \+ \6 W# l) k+ ~6 T4 Y& ~$ J. I2 z' I: N
4 o! M8 C- H2 ]- J
if ( FAILED( hr ) )
. n' o- [' s% f return UPnPMessage( hr ), false;* c8 O( X% [- r+ g
3 ~5 e$ H0 a* |
+ X0 j, E4 q- [1 J/ \ return wcscmp( deviceName.m_str, m_udn ) == 0;
$ ^" A/ j O8 x8 m" H/ T& S( ~ }
6 {' r; g( w- O" |/ R& p/ Q! Y: I CComBSTR m_udn;
2 C" a7 S0 b1 d9 `4 R/ u+ ~ };9 m8 O4 k/ `) h% x5 [: I" z
1 m6 L4 Q4 R6 {' P, C! @) ]$ m7 } void ProcessAsyncFind(CComBSTR bsSearchType);2 ]" m; I$ ?) ]# ^7 J
HRESULT GetDeviceServices(DevicePointer pDevice);* B. }4 x1 c! T
void StartPortMapping();
* s& J4 D: f: Z HRESULT MapPort(const ServicePointer& service);
/ f: I2 H) I9 Q/ Q; l/ m( r' r void DeleteExistingPortMappings(ServicePointer pService);
2 b5 u" E3 ?6 C2 B5 f( N void CreatePortMappings(ServicePointer pService);) Y. R& A6 T- g( M
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); m' L/ H, ^8 w- A8 G
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; f( ~# Y5 A# J: \: N LPCTSTR pszInArgString, CString& strResult);, H8 [( i; y! m$ B. l3 q7 j2 @" X8 E
void StopUPnPService();
, P. P- P7 U. Y6 ~% E; G1 M1 V: b/ a9 C
, k( Y# `- {7 H+ s- ? // Utility functions
3 G# A1 g) ?. @, b+ U: A t HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);% P+ b( m! o0 o" ]- P; u% r& W
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
% j7 f/ ^) D3 d3 d INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);: g4 _4 n( F, M. t
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; b. F3 K5 R9 W/ i1 k0 V
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
" N a5 P+ L5 L- b% t' t( z HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- M* Q* ?' d4 E/ ?; j7 `& { CString GetLocalRoutableIP(ServicePointer pService); V6 r9 |6 E7 s6 c0 o
2 z1 ]7 H" t; P% j! F( R' {2 n" c. t; l9 G, N5 i
// Private members; |/ f- U* R* T9 a
private:& P3 e; e: @1 ^ u+ E
DWORD m_tLastEvent; // When the last event was received?& X# N* y( w2 b
std::vector< DevicePointer > m_pDevices;
. K: R% m1 n' E0 c5 @ std::vector< ServicePointer > m_pServices;
4 I9 N, l) I2 c* o FinderPointer m_pDeviceFinder;) ~! F5 @" r; n( \8 K9 P2 j
DeviceFinderCallback m_pDeviceFinderCallback;8 d& M5 I; ]5 M
ServiceCallback m_pServiceCallback;
8 J/ z, a+ X% W" @0 K
3 ~/ a* f8 R, X& X$ M& D4 ~. f) `! w7 O8 i
LONG m_nAsyncFindHandle;
0 N% O1 b& W* V# K' |# [/ t bool m_bCOM;
& S$ F9 [. Z8 i* _ bool m_bPortIsFree;( {# ?2 V' W0 y( D9 i) q
CString m_sLocalIP;7 h' q6 r6 J5 E6 {
CString m_sExternalIP;
0 W6 z( Y q0 W9 Q) M bool m_bADSL; // Is the device ADSL?
5 N' E8 e* }- t* h9 K! {/ T bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
; F0 Z( @- z5 |1 |: D bool m_bInited;7 `2 }+ p8 x4 F! f1 s) Y" S
bool m_bAsyncFindRunning;7 s5 |8 v1 d- `+ O: k2 |2 H
HMODULE m_hADVAPI32_DLL;
2 z4 O# W9 W2 E: _1 G- P$ ^, g HMODULE m_hIPHLPAPI_DLL;
2 W/ n6 P3 I, E, C3 P* c bool m_bSecondTry;
- f) C# P& w1 ] bool m_bServiceStartedByEmule;
! w v9 X, f9 w* q8 X bool m_bDisableWANIPSetup;1 u7 X# _6 p$ F5 }( P# _6 ]
bool m_bDisableWANPPPSetup;
; E0 i6 y% }. a1 v7 |; l( l3 b% p1 E) x
! p6 P! l) Q( i ~6 M: H
};
* K( I' e" z$ c( v+ O1 X
; M$ G4 u$ K$ T6 q$ c; A9 a- c- |# d0 m' \0 W" `. U0 L
// DeviceFinder Callback
! W5 E! h7 M, q) Eclass CDeviceFinderCallback1 s! m {/ S: P$ m2 R
: public IUPnPDeviceFinderCallback
6 ?' m6 I& w' I{: j: Q8 Z* X7 Z1 T$ f. W! ~
public:/ t/ h/ A4 J) P, l. K' L8 ^/ p
CDeviceFinderCallback(CUPnPImplWinServ& instance): ]1 V6 D8 N, E
: m_instance( instance )" w. ]4 b4 p3 j4 S4 P: D
{ m_lRefCount = 0; }
9 V# `8 o2 Z* E5 j# Z+ d% a4 X$ _/ l$ o; V+ e2 G
8 e" L; H% e) M8 g4 C3 G: G- i
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" e9 Y" E' b: z* j. J STDMETHODIMP_(ULONG) AddRef();
0 W: I) [! s4 a- m0 r9 R( h- n9 u STDMETHODIMP_(ULONG) Release();
' b b% i% w Q: @: l4 J$ G7 u! t
) b- Y8 v- S# s! a. T
- T8 [' r: G. O// implementation
) d: z3 T6 H0 R3 t& p+ Fprivate:
' {+ R) M1 B* e( v: e7 q: K HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
) U( r6 [+ r( E, w- R HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
9 q' f! c( z. _0 q" C. R HRESULT __stdcall SearchComplete(LONG nFindData);
" K) _( h2 ]" d( y [9 g) r6 y0 y8 G
S5 N, _: k6 q( t8 J6 H
private:) Y' J" N5 H! \ ?0 V7 t
CUPnPImplWinServ& m_instance;7 @( n/ U2 V2 [9 e3 v2 _3 Z
LONG m_lRefCount;( s1 T2 P( G2 c3 D9 F
};
" @3 k6 E l9 e, z" Y: h+ k
7 p* D- h! J) J3 u$ x9 A& a2 B
( U/ \* U+ s. n- ~) O// Service Callback
( N( X! M) o1 t* |/ p/ _: z U* y6 D wclass CServiceCallback
7 v: Z2 s' {" i) _8 D+ f4 V3 g( F# D : public IUPnPServiceCallback
x( N ?: _5 z" R% i2 a' ~{& A' l! }7 z3 T$ d% p9 r' m
public:5 k, T$ }0 G2 r* d+ S
CServiceCallback(CUPnPImplWinServ& instance); Z9 Y6 \9 @3 k& R
: m_instance( instance )5 P2 y7 [1 C6 b' `$ K& s$ ` ~. _' ?; n
{ m_lRefCount = 0; } C6 i2 ]2 V' C* q! i2 K C
/ V Z7 J" ^1 M
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 y$ B0 F4 G) }) n; t STDMETHODIMP_(ULONG) AddRef();
9 C. h" Z0 f, Q6 s# p2 A# z STDMETHODIMP_(ULONG) Release();/ R% F) _- N7 r( ^4 e/ Q
9 h2 M( p( k6 Y3 k2 q7 Z
% S7 ~3 b' W; b5 E+ y7 z2 E5 n
// implementation, y5 x# @( r7 E) d" W5 S
private:! u; R6 ?- W& b% i Z
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);/ a g: r4 l7 H) g* a
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
. H% U; A. d+ l2 _7 h: M/ }# e2 [1 o. |/ {5 O+ S0 @0 T0 Y
4 @: l6 H1 u, y# Z# ^private: E3 [) U' H9 M1 P3 a" w& F0 R
CUPnPImplWinServ& m_instance;
/ |1 |) {7 t: z/ y3 H LONG m_lRefCount;, s" ?' S3 _2 S' |% g, N! `1 K
};
" H) ]: J/ w5 u
" P3 M/ n( J% q& V* J3 s% t. [9 A
///////////////////////////////////////////////// k2 @) P' E: ^' s1 o5 J
# ?5 i7 \5 `4 j; ?4 N+ w* T; J
+ G1 [# i; ~) y6 P- f! @4 A使用时只需要使用抽象类的接口。
0 m8 x! u8 W& [$ y1 t) M8 WCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.9 L0 c6 k. J2 k" R# e3 y" a. n
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 c/ S! j; m% XCUPnPImpl::StopAsyncFind停止设备查找.
4 _2 ?' H) [3 _( B, A6 d) HCUPnPImpl::DeletePorts删除端口映射. |
|