|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) Y {$ p5 k# o" F/ m
. \5 l- C/ t" |* U7 y$ X
+ L! e% W4 ~7 v! q% j$ @
///////////////////////////////////////////' D/ v/ |9 m6 \6 @$ A
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.3 X2 r. n6 a0 T6 Z$ s
0 W" E& [7 F% G N8 L; @' \& d
$ v. O3 a" t H" Y3 D
#pragma once; q' l: I* W# X- [3 Z2 V" o0 [+ z/ ~9 P
#include <exception>
3 g. t1 R7 j2 h2 T( u
$ e: [0 Q/ {2 q9 O7 ?
2 y/ U% }' j$ Q: y1 j- Y+ Y7 m% u enum TRISTATE{* T8 H& G6 i7 C5 J @
TRIS_FALSE,
& ?9 O! Z5 d, _9 R3 z1 G TRIS_UNKNOWN,) U7 L7 r1 H) a: H
TRIS_TRUE- y# R8 d2 }9 F; G( v" j1 P% D0 u
};
/ s8 n! c8 l& e+ f" l! s1 n6 S
# J3 _: Q3 @% }
: ~2 J* w! z; I# L! L* }& Penum UPNP_IMPLEMENTATION{
: L: u. d8 C% _* @& Y; F% v UPNP_IMPL_WINDOWSERVICE = 0,
" \0 S* z4 f5 r1 F UPNP_IMPL_MINIUPNPLIB,
" o; j8 R( y4 w9 H# K1 F UPNP_IMPL_NONE /*last*/
' S. J H' P) V: p W};1 U+ ?& ?5 C' a8 v- u2 `4 j
4 z1 {# T/ K$ s1 R$ A6 X/ M0 {4 x4 }) G7 d- h! N) K* F
, j$ o2 I* z1 [+ D0 a. I$ m' h3 r+ n" U+ V U* I& a
class CUPnPImpl
& }1 e! x& ^* r: H; w{4 A2 J- t) @, R. w
public:
" o* P& t9 Y Q/ P7 e; l CUPnPImpl();+ l9 K$ C [$ k! v! M
virtual ~CUPnPImpl();
- z, U3 E' l8 v! y# P struct UPnPError : std::exception {};
0 P( p( w* X8 ^% z' D5 Q8 D enum { e2 |9 j0 M2 B/ x
UPNP_OK,
; c( A: ^# h" W UPNP_FAILED,
% ?6 q8 z3 g1 w, T( K UPNP_TIMEOUT
* z. C: A. Q& p- [ };% b$ c5 B4 \0 E. f# O
$ u* X0 a/ h" R& a4 H
3 \/ p0 z6 @, Y2 B4 t4 E
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
, q$ T6 C# e% ~- m) W1 N virtual bool CheckAndRefresh() = 0;' s% L; x4 M3 n+ J5 b
virtual void StopAsyncFind() = 0;
7 w3 e4 H6 A" z* C5 w$ ] virtual void DeletePorts() = 0;% e W6 h+ J* E# \( }: C7 q
virtual bool IsReady() = 0;/ B) h; m& B/ | t
virtual int GetImplementationID() = 0; h$ ^ F5 t7 l) @
/ i8 A \5 O3 o. O9 r void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
- F7 f1 x ~2 O$ H
* n( V2 s. d1 @) Y2 x5 `& A8 y
* D0 v3 u& ], Z! l/ g9 W+ v void SetMessageOnResult(HWND hWindow, UINT nMessageID);, h, q. d& P( `( q3 d1 H
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
- ]* Y* W& R5 H: n& W* f/ t2 _: n uint16 GetUsedTCPPort() { return m_nTCPPort; }! V' q. [* X) x4 B, p
uint16 GetUsedUDPPort() { return m_nUDPPort; }
5 @, T% J! w' j5 _% {: b
1 e$ \# O* m3 x" m6 c. J# p" B) t c& g6 J- G. w5 D
// Implementation
7 V6 _6 `( ^' ^# s9 k: Pprotected:
: [! U1 Z% ]! b volatile TRISTATE m_bUPnPPortsForwarded;
' F5 O+ I9 e* M. i8 k9 M( l void SendResultMessage();
+ n; p# X. A2 I) N( H& K uint16 m_nUDPPort;+ G& m: H; E- X$ [: h3 f7 ?
uint16 m_nTCPPort;) m! X/ H- r" M. a# C. `# U, ~
uint16 m_nTCPWebPort;$ r: P0 D, t7 r9 O0 v! a) ~) @1 C0 }$ c
bool m_bCheckAndRefresh;, H! x! v0 T' [- i
! g5 C3 l9 p ]: h! H, V' F- }6 w
8 V1 n* R$ j! z" ~1 Y" d
private:* Z8 ^' W+ ~/ n q
HWND m_hResultMessageWindow;
" f; C; K. k3 k! e% P( F UINT m_nResultMessageID;
2 x, \, I$ w9 F5 p" ^. q! g4 i3 A0 X/ f' h( b
. D& o; e+ K. v/ H
};
4 Z* C# g- `) z7 f& K3 a& M# ?/ T( H& j3 T/ Q% L
" S+ {* E' ~' A
// Dummy Implementation to be used when no other implementation is available% d. l, R. u7 H+ x: S/ i& [
class CUPnPImplNone: public CUPnPImpl
9 a6 N" L6 h9 h3 r{
. Y7 I* ?# b. s9 H( @0 Y$ w3 H7 opublic:
- B; E: \* M+ j virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
+ l& c7 U* `6 R; H* f virtual bool CheckAndRefresh() { return false; }
9 n @7 ~- ?, i( v! `5 j virtual void StopAsyncFind() { } @: C! r, y) w' U6 R2 ]0 l
virtual void DeletePorts() { }
* h, g$ \! P. S2 m2 k3 e- X0 R virtual bool IsReady() { return false; }
- c) g: m" d$ T2 C& F virtual int GetImplementationID() { return UPNP_IMPL_NONE; }$ C" L; M4 a4 a2 A, e
};/ b w2 z4 E( }1 b# C$ A
. V2 F% R. p7 K
! J% L9 I5 Y; X8 q
/////////////////////////////////////
2 \( N$ ?; I4 Y& n' D( Y8 G//下面是使用windows操作系统自带的UPNP功能的子类
5 P! W3 G8 l% Q, {/ h) z
; f/ L. n% X P* C: q! W
& }+ z2 L% l _' |4 E: q#pragma once
0 M7 y! v& E! [#pragma warning( disable: 4355 )2 {/ U$ J: n, z$ L0 U
. p b) y5 f" G. x i E; q
! @9 Z( T4 D1 F/ Z l1 H# O: v#include "UPnPImpl.h"4 g1 F: b! f& f P
#include <upnp.h>
- X' u3 O# `- N5 k#include <iphlpapi.h># h/ n) s+ n/ q- }
#include <comdef.h>6 P5 z$ r9 ^. Z2 n
#include <winsvc.h>
; |7 ?) n+ B& d! f- j& S$ Q$ v, ~( p0 O7 j9 v3 h8 \" L% n7 s! d( [5 B E
8 K, B$ E& b/ {9 {: i
#include <vector>
2 f: ]$ h( E3 p1 A( B5 @% n#include <exception>) _- l# j K# Q" ]0 z+ ~
#include <functional>
! f B; q# s+ z% F! @# D" r- l+ w8 X7 K, l+ Q6 a
% v) o) ?6 {5 E, ?! p% ~% A) a! J3 h6 ]/ M- ~8 f+ m
4 T7 ~1 z0 m! P( M0 S" r
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
( h$ j- A, G. A8 gtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
, D" w, F# W+ \; f8 m9 s0 p6 ltypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;3 W' {- @& c/ M) ~/ u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 K U. O+ r1 H% g J7 Ntypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 f# y' S$ L+ ~ q5 wtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;) c3 N7 M& [3 a
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
% Q" _7 z4 V+ G) Y: G! ? o# s( Z
; X8 M2 ^, r1 O4 x/ _: d/ e* t P3 x6 }8 ]
typedef DWORD (WINAPI* TGetBestInterface) (
$ S4 ]/ C. i) P8 x" n' [$ E3 o" I2 v IPAddr dwDestAddr,
0 h6 H$ z, W; C PDWORD pdwBestIfIndex9 i) h& }0 ?( x0 @$ |: a( B1 ?
);
: @% z7 m" G& q: R/ h( R' K1 Q% r* C& z o5 H6 E
6 [! r5 W8 `! _- d# b2 ctypedef DWORD (WINAPI* TGetIpAddrTable) (
9 k4 x* B2 R8 I1 w# x# n; I8 k PMIB_IPADDRTABLE pIpAddrTable, b% X6 s6 Z/ g4 }$ Z' t% b J" q
PULONG pdwSize,) z9 S2 E( \1 v" O
BOOL bOrder0 R, c4 C# u' e, H" l% F S
);+ F; y$ O. N4 ~5 o# T
0 y: R1 j `/ Q" o
3 a- D! }# a* }1 T8 p8 I; G3 J
typedef DWORD (WINAPI* TGetIfEntry) (4 S6 F$ A. l8 q; I, y
PMIB_IFROW pIfRow* [: l2 @4 j7 t. N4 @9 d7 r9 U# g
);
9 q3 N" q6 C) }3 s5 m, [% Y
" \% m6 q8 u, c4 Y9 \. A7 ^! ~ E0 w& m1 U7 U& p
CString translateUPnPResult(HRESULT hr);+ q+ f- f6 \1 t- g
HRESULT UPnPMessage(HRESULT hr);# S3 X. t' A5 k0 o+ q* m2 s/ L
3 y: t2 r; D. p" A5 Z+ e
# d. J. ^7 p2 ^9 Dclass CUPnPImplWinServ: public CUPnPImpl
6 x q v$ B# n Y, b{8 W. m7 K4 l" `7 ]" C
friend class CDeviceFinderCallback;
: `( I# t1 m0 X friend class CServiceCallback;& Q, k/ y/ H8 u& y! ~
// Construction0 I4 w( u- G) `5 ]1 _8 o: j# X
public:3 ]8 m# Y1 Z' h( r9 s b4 {* v
virtual ~CUPnPImplWinServ();
; B4 v. R5 l7 k CUPnPImplWinServ();7 t+ I8 M* c1 V1 ?( x) S+ g. j" Y. D
/ t" s5 q: |. F3 N% F. _
9 Q. F! t H/ T3 C
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
6 w# y9 M" c" d7 C, z+ l8 A; C! q virtual void StopAsyncFind();5 I5 h5 \) ? x, H2 B
virtual void DeletePorts();
& P& J/ U" e& L& a# }, j) z; D virtual bool IsReady();5 B9 ?/ p1 w. c( b- p9 W5 {
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 Q/ e+ {$ _- z2 |2 h
4 Z6 C, t! z' H5 r
, g& [* e, `2 J& l // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)! ?' T* O# N; |5 R3 |: Z
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ s$ {2 o- W0 @! {5 l. W virtual bool CheckAndRefresh() { return false; };7 V% Z1 x. y; J$ u# I2 N
9 W. h% i3 |5 l! `8 C, K, B
/ C; o8 W% U, e* g# f
protected:
+ V, q% \, F4 x( }5 t# Q8 e: _8 P void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
5 u1 \' F$ S" W5 C$ L" M5 o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" s% U+ w! j# h0 K4 t$ s+ J void RemoveDevice(CComBSTR bsUDN);& X8 n5 `: M4 ]4 R) l C
bool OnSearchComplete();
: I/ M: W7 F6 p, r" J- S9 } void Init();
8 t! G+ C: Z( B9 ?+ c( W
6 A# S6 c4 `- u1 J7 G7 j" g" E/ c9 M, _- ?
inline bool IsAsyncFindRunning()
2 t' G% Z# r) I: C9 r7 K {" ^+ k! V, w2 ~2 i5 k1 G9 d0 }# U- J
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
0 C' x# y; Q4 D$ f1 B {$ p' F% F" _, L1 v J5 V
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
0 N# [, y% I P# f: b m_bAsyncFindRunning = false;
- N# R: V5 I8 j" I* _1 q$ S! ^ }
" o' u, p- s* H( f MSG msg;/ e7 y5 h# K- P1 A2 H. T5 U
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )7 t4 j+ O* l$ Q
{
( i! g* B* N$ c6 g TranslateMessage( &msg );
3 e/ v" U- p: \ DispatchMessage( &msg );
# V6 U' B8 u! e x) ~& @# z/ ~ }! O N3 U. g3 e+ r
return m_bAsyncFindRunning;
( k7 |/ d7 E4 ] }0 ?& E( s* v/ e5 Q% h9 `5 |
4 i. }1 L! ?/ @1 o1 [; g$ t" T2 t
" n4 |0 P s3 h( p/ R: x7 T
TRISTATE m_bUPnPDeviceConnected;) R5 x0 o. B0 \. `+ \
+ n1 O7 K$ `+ H' o! w# d6 x
@' |3 t) _2 H2 V// Implementation9 O: A' }. o+ r. k# ]! N
// API functions
9 K. T% g( I$ \7 e% w$ V SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 i9 o6 l0 c- c% l# p6 } SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: E2 v5 D2 b! X! ?- j: x BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);; W- K3 t; ]) X1 e3 E! Q7 x
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
/ d% e/ W( m/ \% s BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);9 _6 }' v' J0 \. x) l, S5 ?
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
. X/ Q+ ~; W% s# j+ b# \
! u6 N4 U; ?( b0 ~* }. t" I5 V% @+ {: ?9 `- I
TGetBestInterface m_pfGetBestInterface;
3 q. a* e L+ P0 s6 c P( [; G' w TGetIpAddrTable m_pfGetIpAddrTable;
. a4 M- S6 a8 a: K4 k; \9 e0 B6 a TGetIfEntry m_pfGetIfEntry;
# P9 e( Z, l0 `* _
4 P% p1 C l% l( |" M6 g3 ~3 z2 e! B2 D7 p0 C3 g, s/ Q
static FinderPointer CreateFinderInstance();: ^& k* W3 }, e; @# t' Q
struct FindDevice : std::unary_function< DevicePointer, bool >) P* @) G" r% o. | m* b6 N
{. D: L6 B: h6 C$ S2 d, I3 G5 d
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 | @. |: M; y4 s1 M result_type operator()(argument_type device) const
5 R* M5 U. L/ d. z( r2 [ {5 d9 o @/ f( A% _ K9 K6 i
CComBSTR deviceName;
0 V8 w& b0 _, U+ C% n. F1 v( F HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ I0 E' O" ]9 x& e4 S
5 o* B' F# `) K5 T/ q
, F& T) V e. F' K7 c
if ( FAILED( hr ) )
- {0 E1 Z. w! i! E- J+ J; }0 w) U6 B return UPnPMessage( hr ), false;% I* M+ z1 v+ P4 @9 G; T1 P+ y
4 |) w1 N* ]' e+ V
* B/ z- p3 g; ?: M. b, e* [* W+ ] return wcscmp( deviceName.m_str, m_udn ) == 0;( ]/ N- i6 ?" |0 k
}* x$ X# c. ]) g* j* l. z* V4 B
CComBSTR m_udn;
. D' d4 K5 S n };
, |& H3 T, R% V2 U
9 ~% h6 H! i) v# J8 Z2 ?1 S void ProcessAsyncFind(CComBSTR bsSearchType);
- X. D" g/ ]0 x+ Y1 X7 O HRESULT GetDeviceServices(DevicePointer pDevice);
. D% T9 Z6 l) {( H4 |& V. W8 |2 z void StartPortMapping();
* T& b _# c; o, A: ] HRESULT MapPort(const ServicePointer& service);3 J- {2 R, Z, [5 ^) l) t+ z
void DeleteExistingPortMappings(ServicePointer pService);' B* f6 D" N! e T; M I% X
void CreatePortMappings(ServicePointer pService);
& a& X% B4 Q6 w HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);+ X* ]! E7 Q2 K8 p" I" ~8 y
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
. c/ `" m6 p1 J; S; N LPCTSTR pszInArgString, CString& strResult);
) L* ?9 D- e4 \+ w+ a) q void StopUPnPService();
* y, d/ _( f/ V5 W* c5 Y
: v3 q( y, H+ F v: z B: L
' b) Y$ y: i5 {# |* I3 y+ K // Utility functions/ v9 _' J* L" X, R, g% L% X, p' _3 Z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
6 ~) |' j; U* Y0 }" H/ b+ H* Q INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);# J }5 Q& y) T+ Z5 U) l
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);) }& f! I' w+ I1 N! F1 ~- p
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
5 K4 ^, X. A, C, G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);2 F: L$ ?2 D9 L# O/ a
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
) m+ J0 g- B' J) z9 f4 v CString GetLocalRoutableIP(ServicePointer pService);
4 S! F$ i$ `4 B, K+ u. k4 O1 T" ~# }6 Z+ V+ W0 Y
% ^* [. X' D1 X- x
// Private members; e, ^& ^$ @5 [( l- {/ A
private:$ L* R* I0 L. b* v& Q6 U) J
DWORD m_tLastEvent; // When the last event was received?1 Z' E$ \+ `7 F. b
std::vector< DevicePointer > m_pDevices;1 r- v" _5 ?! ^% D2 ~$ i. E9 B
std::vector< ServicePointer > m_pServices;
& S' P. o0 P8 k' q9 C# a$ d FinderPointer m_pDeviceFinder;
4 z. B% M: |% D3 o& c' o% k- I/ |# v% I DeviceFinderCallback m_pDeviceFinderCallback;+ }" m) L- |6 x5 {9 C8 q
ServiceCallback m_pServiceCallback;! |' m) v8 U5 Y) B4 }$ y
4 e/ q/ r. W8 B. ?0 j/ X6 G& X1 e8 m6 K; u, g* D
LONG m_nAsyncFindHandle;
0 P. m/ I$ R9 @. v7 \ bool m_bCOM;
; T- S" N9 ?- ?4 ^ w Y bool m_bPortIsFree;4 L8 x; a1 x7 G" J
CString m_sLocalIP;- {! V6 C- D. v& |& \
CString m_sExternalIP;# o5 J5 k/ z- c4 \+ J2 d
bool m_bADSL; // Is the device ADSL?2 h# M8 k% B4 v) t( u
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?2 @- a) v0 m3 c7 ~
bool m_bInited;
! g) `& |2 F! s% P' t# k bool m_bAsyncFindRunning;
0 m9 [/ j2 u# O5 I1 V6 _ HMODULE m_hADVAPI32_DLL;0 Y, v3 i" @; j R& E( y! ^" d
HMODULE m_hIPHLPAPI_DLL;
3 e* Q* |) c0 S- e: R bool m_bSecondTry;
8 a7 C$ R/ k2 X% ?; {: ^" v bool m_bServiceStartedByEmule;* G5 m& X7 P" j/ D! y/ `
bool m_bDisableWANIPSetup;
: h6 C- [/ U+ m; T bool m_bDisableWANPPPSetup;2 k" ]) j1 z9 e5 s' A) R6 M9 F
' B; U0 ~9 _9 q6 |8 ]
+ V% R+ t% r' p, p+ e( [# a8 b};
$ d9 t* K$ k0 C2 x% W/ F. h9 L! l# z" w
5 i5 d& n7 G! z7 c
// DeviceFinder Callback
" x" J( U# k" u" u" _5 Uclass CDeviceFinderCallback
7 p: I8 F: }* E. d : public IUPnPDeviceFinderCallback
& B. L3 q& C1 }3 O. m{) O j3 B" N# c- v* N3 M# F9 g
public:
4 Z$ n+ k% K4 N4 ` U+ ~5 u1 n9 b( [ CDeviceFinderCallback(CUPnPImplWinServ& instance)
: N0 T5 W, ^% A4 o. ^ : m_instance( instance )
3 L3 x4 ?% a1 ?; B# J+ Z; }4 l) _ { m_lRefCount = 0; }
1 _& B. a" s* A/ e
( F/ e, {4 V* X/ J4 D: M% [
% v* q0 C, [: M STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: c* Z! t& ?# i$ ~& a3 C STDMETHODIMP_(ULONG) AddRef();
9 h: U- t. v# o4 ], F3 Q! e w STDMETHODIMP_(ULONG) Release();
& v: l) k5 n' e
" z, \4 \* o) t& u; c ~0 c+ f
) r: `: m+ a; l: g6 D+ }// implementation5 f! v+ c; ~5 n% l
private: T9 u9 p( ^+ `! m3 k3 ?! ]- U# V
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
0 [- Y2 [* U& y) r9 u HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
$ I- g' Z* F; l1 h' b, D. i! f HRESULT __stdcall SearchComplete(LONG nFindData);
( [. Y8 _% S6 w0 Z" K
/ D/ E0 `8 I+ c4 b, t# c$ X; ~( Z/ X! a/ Q# ^0 _8 p0 y0 d z( k
private:
( Z' I' v: k) p# V# `) Y CUPnPImplWinServ& m_instance;: o# R, A( N: b* e8 h# P% n2 E1 m
LONG m_lRefCount;
: f6 v0 p" p* M* D# E7 c};0 X, Z* }9 J) E' w7 E( k4 k" l+ D
3 f3 y9 m; z4 \& M8 `, |
7 o) N$ j6 a) P// Service Callback
, v( `8 t, g( j' m# |% D' Lclass CServiceCallback
( \4 U' _/ F8 r9 R1 m; n : public IUPnPServiceCallback
W# Y9 o+ k5 F" c! }! i{9 `! b) [' m9 y* R
public:; u- c1 q& v4 _. |0 }
CServiceCallback(CUPnPImplWinServ& instance)( q3 Y* K& L2 ?
: m_instance( instance )
: y+ j$ j% m; W( R4 l9 Z& B" O+ p { m_lRefCount = 0; }
9 F7 z9 ~, m2 ?8 v3 `
/ F# q9 Q( X3 ]9 E' n$ S STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);) g0 |/ c& H1 T6 z
STDMETHODIMP_(ULONG) AddRef();
4 G/ O2 {& \5 M9 p2 a( p' W( z STDMETHODIMP_(ULONG) Release();
$ U& b% v' {' U; f6 W# j& Q
" N# ~; l" u. u$ n" r( V: m( ]3 O5 E H1 _
// implementation4 A' T& B1 N6 F8 V6 q# O$ P
private:
+ t; f: j! ? h" V0 l# B HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
/ x" ~. \4 i/ s; q1 l4 ~ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
: M+ ?/ [8 o1 L: O: {0 Z
: B# z* F: Q% v* @& e/ ~0 K e6 `; ]/ Z( l
private:
- V* H- ^1 o9 ? CUPnPImplWinServ& m_instance;
8 P, ], W8 c7 y LONG m_lRefCount;+ A9 y g( I F
};: k1 r1 s2 W7 c4 t$ G
v2 u9 l5 c2 A% t2 h% J% t1 x" l0 Z% c7 e
/////////////////////////////////////////////////( v+ J. ?) n4 ~
, h M: C6 `) w+ ]. ?- r4 k
; Q" x" `+ m- w使用时只需要使用抽象类的接口。
4 a1 y4 S- _/ h. u/ z; O% `$ |CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
5 X7 O& B i2 j" Y0 tCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
/ e, C2 ~3 ]' gCUPnPImpl::StopAsyncFind停止设备查找.
9 Q3 Z' y u& D! O7 BCUPnPImpl::DeletePorts删除端口映射. |
|