|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,( G* z! H( U- G6 P0 ]( b$ E- L
9 Q4 O6 a2 _5 b: ]0 H" y' C3 Z: g- p6 a1 _$ c* K( R
///////////////////////////////////////////
0 h s' V) C) f- ~5 n& {7 L9 p//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
1 T% @. b7 A+ p/ y( |+ i: R) R+ U3 Y# f M
. Y5 k- {% r- D5 k3 S8 @( w#pragma once
' u) E V% K, G! u5 Y#include <exception>( u. U& }8 @3 U- {& d6 r
5 f" O- \5 B8 X6 E9 [
! M9 o' ?7 V# z enum TRISTATE{
/ |6 Y; j7 W% Q3 u1 o TRIS_FALSE,
" h. E N8 d! S& [: }0 p" \ TRIS_UNKNOWN,0 ]3 k0 [# l& e1 o- |/ p
TRIS_TRUE% Y# ]# N8 Y1 I! |3 s" {5 g; B& d
};
4 G1 j$ R% ? d& ~1 @1 \
2 u% P5 j1 s$ C7 h# N$ S3 \! N/ y7 z9 _* s& |! A& d7 n" M& {
enum UPNP_IMPLEMENTATION{# Q' e7 _0 A2 E
UPNP_IMPL_WINDOWSERVICE = 0,2 ^/ W8 @& H, k1 K" G. H
UPNP_IMPL_MINIUPNPLIB,
+ b6 d: }) Q! i& D UPNP_IMPL_NONE /*last*/3 k/ Z( e( F0 ~8 R, E6 M
};7 @' r }! v v2 V7 x
) Z( m* c! @* R: \5 P+ M8 K+ G; U# ^) P4 E' C
% i H ]. G7 x, S1 x) \9 t6 \6 k# g6 N) O! `
class CUPnPImpl3 W! w2 M* _0 f7 i+ w9 y# t2 a( G0 g
{. g: p7 l8 K0 M$ I% n
public:
7 B/ @) G" Q/ J& s, E6 J CUPnPImpl();
9 O2 l; _: D. Z/ s6 i% k4 N' h virtual ~CUPnPImpl();/ g9 c' {9 A: M0 @( F
struct UPnPError : std::exception {};
, M$ b0 ]+ }" [- x8 X& k enum {
) }) x9 ?4 h3 D ?" R UPNP_OK,
( g1 }* Q ^7 N7 c UPNP_FAILED,
' U6 X) v0 F( ?! q% c7 j4 U4 s0 n2 H UPNP_TIMEOUT' e2 `, d5 E4 V# c/ ?1 g# D
};! Z2 b) v: _5 i- U
+ o5 L/ z9 V0 C2 ?3 E
) q* \; j9 H/ E1 M' [) | virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
, {9 j7 a( f+ ~. A j$ ~ virtual bool CheckAndRefresh() = 0;
! i& J4 {+ @# q- J4 e0 r virtual void StopAsyncFind() = 0;
- K+ z& N5 B6 N0 p. C virtual void DeletePorts() = 0;
" P u6 n/ s" T7 ^- g virtual bool IsReady() = 0;6 }0 M( S# q2 j4 H# g
virtual int GetImplementationID() = 0;7 i! w+ P4 j! H( H. p6 ]: h/ D L
# N8 d5 |' X) J2 A8 U* y) ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
5 P7 Q! ~- N1 p" D% t+ A7 B! i) a. c' }4 Q" Q
2 t6 R5 K3 p {6 R void SetMessageOnResult(HWND hWindow, UINT nMessageID);7 O7 ~: o+ @ m5 p# m
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* H2 n4 P! V( Y" Q3 Q9 t# t; x. p# K uint16 GetUsedTCPPort() { return m_nTCPPort; }( y5 {( t5 E8 \, B: M$ b' ~
uint16 GetUsedUDPPort() { return m_nUDPPort; } ) f: V3 H& l( H$ b; [) t% k
9 w) W: {# x4 d' W k
; i4 I* v3 J! k/ c
// Implementation
9 a' F6 S( @/ i6 kprotected:
+ A9 \0 }! w1 w3 R volatile TRISTATE m_bUPnPPortsForwarded;% _* o* a5 \% J% a; @* K
void SendResultMessage();
0 T6 Y: s6 R+ i, p uint16 m_nUDPPort;2 I; h4 W4 w% S4 Q
uint16 m_nTCPPort;% @# K4 e5 b3 F1 B# N" E* d
uint16 m_nTCPWebPort;- P1 C0 _5 U3 J- P' v
bool m_bCheckAndRefresh;8 B& C! T' f& t. I: V; t9 G! T
( n5 u8 g Y0 n
5 e7 q2 e9 A/ Q1 j5 ^" gprivate:
* t1 ?) i" n, ]% | HWND m_hResultMessageWindow;1 B9 ~: ?! U0 } F# p1 m
UINT m_nResultMessageID;
! f3 A0 w3 i' W6 V0 ~
/ X ^3 n* ^* C6 w; I# ~8 Y! y" {. U1 B
};
' J: N; d1 Q4 M! e
: ?9 {+ n, y' ^% b' z) E
5 A) J' ^, `6 J4 @' G% R9 K, K3 ^/ `3 i// Dummy Implementation to be used when no other implementation is available. T. U: G% E- J% F
class CUPnPImplNone: public CUPnPImpl7 V6 g$ e$ ^! Z0 ], K9 F# I! [6 m5 o
{
5 a2 t; r$ U0 c5 V* |. O }public:) V% x# k. H8 A$ w1 o
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
% W) ?7 ~" g/ ?; ^ virtual bool CheckAndRefresh() { return false; }- O# u9 ?- D* j. Z0 r) K
virtual void StopAsyncFind() { }
8 ?# u. s0 q: c2 K& U- e virtual void DeletePorts() { }$ C( [( I; L1 l. Z2 z. ~
virtual bool IsReady() { return false; }
7 B$ z( y( k, E2 U3 J. B9 ] virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) ^! L( N9 A6 K; X9 F( |
};, \0 F0 A! Y5 H: l7 t; ]
+ D* n! c" Z5 \' x
; [2 ~5 L: z: n4 N( W7 r8 u# {9 [/////////////////////////////////////$ e8 L- C! D5 W& h+ g
//下面是使用windows操作系统自带的UPNP功能的子类8 `& _' P5 p6 f
1 Y: x4 r! Z" B+ U
) T% b7 Z5 }% H5 u9 a4 d" t#pragma once" f; Z! G0 J% k% A; a9 T5 q7 _
#pragma warning( disable: 4355 )7 D+ l* W7 g, o3 X% E; N8 m
1 j0 @9 h6 {3 _# i
/ Y2 h2 N- c: }% g9 [#include "UPnPImpl.h"4 ]6 P; p1 K' ]# Y
#include <upnp.h>
% J! ~8 \6 Y9 }#include <iphlpapi.h>8 b( `: R6 d4 k' k4 F, p
#include <comdef.h>" D' |1 e" O3 i# {, F
#include <winsvc.h> A r' G8 z7 \- h! ?& j/ b
! L- A% |* ^: a8 @) V/ M
: e% ^. j; y$ \2 d! r0 \#include <vector>
g `. E: E% d, I, m& y I! a#include <exception>
( V! i$ D: E) G$ O2 w0 g# T1 `#include <functional>
) G7 |5 C4 }) Z8 T5 s
3 J6 G. s2 ]( w
p" D7 Z8 j r9 W4 Y& |. ~( W8 q5 r6 J" j' i
1 E5 Z; o9 m7 F. m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;& b# l; W8 B1 L) I, a F
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
. K/ l- E t$ o3 Y4 L' g2 d) Xtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;% i( \" m4 J$ F+ m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback; h4 g0 m: z/ i9 Q+ h
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;6 P7 s/ D: c: O6 x T
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' o3 d m# F: Itypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
/ _ i5 ?/ R' l5 S( A7 ~* v
* D% c$ w4 `. g+ n6 Q% l) q3 R$ s Y+ c! _
typedef DWORD (WINAPI* TGetBestInterface) (8 B) k6 N+ C" [9 M
IPAddr dwDestAddr,# Q# _+ Y! v/ H3 u: C
PDWORD pdwBestIfIndex
) {" K6 r9 Z8 \& p7 R) u8 C( J);
# \2 d* I) C. a6 F, a t8 a0 e# M( x1 `: M% s3 H T
" }6 ?( t' U$ f# M8 L! s2 J
typedef DWORD (WINAPI* TGetIpAddrTable) (
5 g$ g/ n+ H: f, B PMIB_IPADDRTABLE pIpAddrTable,
7 R/ M- ]5 g2 _& m8 r9 P* c PULONG pdwSize,- p, j! t6 R- J. Q/ Y
BOOL bOrder' S# v( P& ]9 J+ j/ e; ?9 |# W
);( R( a1 K# J: Z
. X7 Z* t# O, Q+ }
; |( E3 ], N5 t( S* A" xtypedef DWORD (WINAPI* TGetIfEntry) (+ E3 ^& e- d* v
PMIB_IFROW pIfRow; S L6 v: P/ m3 c; t( D( K
);+ A' m+ b z6 J2 j9 }
4 n' p% J; _2 a2 H0 x4 I$ U* Z. D: i( |- z
CString translateUPnPResult(HRESULT hr);0 e" @' I$ h7 X0 t
HRESULT UPnPMessage(HRESULT hr);
- v* M2 {6 V/ h! I" ]8 s7 p) b/ u7 S8 T6 P/ c i8 ?( f3 F- h
0 P Q) y7 V, X/ g6 ^6 Gclass CUPnPImplWinServ: public CUPnPImpl
1 t2 q7 j" w) t! a1 i{
3 r/ v/ T, ]- q friend class CDeviceFinderCallback;
8 P- K! `* ], ~; }+ B friend class CServiceCallback;% ]+ E: a6 Y5 C9 D
// Construction: m- n& p" Z. L7 i C4 X
public:
+ l8 Q9 X& d/ [# X, m. E virtual ~CUPnPImplWinServ();
- O* W! Z8 V" d9 i) c6 V( _1 L CUPnPImplWinServ();& ]9 }4 f' b- R" U' V: _/ o1 K
+ m$ R8 `0 L2 X/ D+ i
6 y+ q5 Q) y. f3 u* k) n5 c2 `
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }+ a8 N# J: ~! _
virtual void StopAsyncFind();* z9 |# e2 `# {; l
virtual void DeletePorts();
; x1 ^" r u1 y1 ^8 G virtual bool IsReady();' h# Z/ Z8 ~+ z" y8 _" A
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, R( @5 b) Z) n) e
. ^; ]' G3 N& j5 S, I. m9 x
2 }: b! m5 c/ O* ] // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
3 e v9 }& D) Z z5 X // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
- z* K: v, R' R0 A6 [ virtual bool CheckAndRefresh() { return false; };
* F1 Q4 V& e" ^' P4 F: W
, V& R6 U2 ^7 h) q* U8 Z# H; G& }5 D0 a8 m2 c1 g+ g8 _& |( \8 O- [
protected:1 ?7 H6 q. A/ B r6 z t! ^8 }
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);; u; O! ` n# {/ U6 \0 b
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
$ c; h0 }8 c& m9 d3 r- } void RemoveDevice(CComBSTR bsUDN);
' `! a5 J; W* A8 q( x bool OnSearchComplete();( _2 c. _' \. f$ J( T& c8 ~5 Z
void Init();
$ @ X9 u( o) I7 c# m1 X7 {7 _
! P! Z- P' g5 R; z3 _( P: ]' Q3 ~% O8 I; {; _8 ^* o
inline bool IsAsyncFindRunning() # k$ q) W" x( G3 y$ L
{
. X ~ C& f9 G E1 D# ^7 I. G if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
( n: I) p$ P8 E1 D3 m/ `/ ~- R {( G+ u# i1 s4 P9 X; @5 k7 f
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );$ c8 O8 O h& c0 U3 H8 l; Y' U
m_bAsyncFindRunning = false;
& M |# `; H+ W b; s7 K }' B) P P. a; V
MSG msg;
! d. E- |# ~ o+ V$ y while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 L2 X6 i4 ]- z6 Q8 o9 V7 r
{7 |& w- G/ C9 F9 k! m! `
TranslateMessage( &msg );
# s8 |" _1 R( ]8 ]$ e b5 g5 z DispatchMessage( &msg );
% l' Y" m. R1 I }
$ k X- b" c0 z" B9 B0 ~ return m_bAsyncFindRunning;4 {1 ?! a2 X, P1 O
}
}: o& W2 f, l9 s% O" E6 k6 q
. e) ?5 Q% U$ h- j; x% Q
& }: T) R& l# h+ D2 R TRISTATE m_bUPnPDeviceConnected;
$ Y- g. @7 m0 K
2 P6 @+ N+ J9 J2 S' n! t/ \( {0 a: m* o9 k8 ` u" ~
// Implementation
0 q8 a. V% J8 J7 t( ]3 ~5 n // API functions/ A, h! z4 s( I5 ~
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);: B! N7 r: H8 V' X8 F! s6 o
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);& L* l. {! ~( g
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- e5 l7 h6 s& H/ ?( q5 N- Y
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 a5 O% Q6 I+ _$ ~# @7 R) \
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
+ H, s7 a2 b5 s& D6 `/ n( [ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
4 d+ ^6 b6 m5 R$ H
9 R/ `( L* z; Q- _
% F/ h ?: q2 V TGetBestInterface m_pfGetBestInterface;" H2 x; w" P8 h5 G! `
TGetIpAddrTable m_pfGetIpAddrTable;
8 g6 }5 M6 ^, L+ t% e. n! G4 C TGetIfEntry m_pfGetIfEntry;# B! E* Y( J8 d/ m
`- k' u8 a1 _' a Y
6 u9 Q0 R7 d# o# \ static FinderPointer CreateFinderInstance();
3 f p; D7 }2 E) A struct FindDevice : std::unary_function< DevicePointer, bool >+ V n) V+ y5 [9 b& t6 I
{6 N! l6 @8 Q3 b. L' P7 R' g2 ]
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
+ E6 z) i- V3 G, N5 \( l result_type operator()(argument_type device) const
1 k# K7 o+ f0 Z* p; U {
1 W' g& k) Z. B# G6 [' z CComBSTR deviceName;
- B( w+ D9 l. K- ~1 M! } HRESULT hr = device->get_UniqueDeviceName( &deviceName );
, S/ j! W; V2 j3 e) c
: I* I7 G+ X, L7 D' b [4 L2 C8 C/ a/ U2 i
if ( FAILED( hr ) )5 D( }9 W0 y" H& b0 z2 g
return UPnPMessage( hr ), false; }1 G, A4 @' n4 Y8 `- ]
+ o% b+ `6 Z2 s) p4 ~$ i
8 ]. ^4 H) J% x0 y
return wcscmp( deviceName.m_str, m_udn ) == 0;' p D+ c9 @$ t3 D2 Q
}1 V! Z4 z3 z; q. i" x0 n
CComBSTR m_udn;
% Y- D7 i4 Y6 N4 \ };
6 s% J, c4 [6 G# S5 C , j! G3 ?: a4 J& [& S
void ProcessAsyncFind(CComBSTR bsSearchType);( J( K8 g7 I: S( Y. g
HRESULT GetDeviceServices(DevicePointer pDevice);
; B: I: A- ^8 q/ [% {/ E+ i void StartPortMapping();
: R5 }8 y5 t1 I. \: L) O: Y# O HRESULT MapPort(const ServicePointer& service);
+ @1 s' `2 k" a' a( b8 s$ V7 o void DeleteExistingPortMappings(ServicePointer pService);8 A1 D5 M" K0 s0 H* R$ }
void CreatePortMappings(ServicePointer pService);
. ~3 h* c$ ^2 M HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
' M) h$ Z4 X. {' Z& j+ i, T" O \* J HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; B! j& s( b2 Y0 i" ?1 R LPCTSTR pszInArgString, CString& strResult);2 y6 D8 p/ J I% }4 ]
void StopUPnPService();
8 S5 A2 N$ w# F& a w! U' Y# Z
5 D4 ~: a) N+ n, {) Z; ~. M' v$ \5 s9 ~( U. H7 p
// Utility functions
4 g3 \! L4 U$ ~ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
/ `! \! N! U0 h5 H, _, H INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);8 \. S3 G# M( ^
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs); F9 O5 \! f8 h z" O7 K
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);% b5 w) K. ?$ w2 g5 G* Y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
4 K2 f0 o0 a9 X" x7 f HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
7 B& o- T1 u! {% l, i CString GetLocalRoutableIP(ServicePointer pService);8 F: j# k5 B. g; `, O6 D
& v# h& {4 w J/ x4 Z( n2 }( j- ~% ?# \8 ?' h+ @4 }$ O* u) i
// Private members
% i& m- P0 D! v1 U- |private:
$ o- z K5 G- o$ e6 ?8 g$ _ DWORD m_tLastEvent; // When the last event was received?
5 K7 R: ]8 L/ N, p, z7 b std::vector< DevicePointer > m_pDevices;
, g* ~" R* l, q9 ~) | h5 x std::vector< ServicePointer > m_pServices;
5 x, ^& I9 \. d7 E% P! _ FinderPointer m_pDeviceFinder;: Y6 j! c" I, q, T" H
DeviceFinderCallback m_pDeviceFinderCallback;
. P6 C6 a+ n, Q; Q, V. Z+ w ServiceCallback m_pServiceCallback;. b2 e$ v3 k0 o& d5 ~2 H
5 `: B( e1 b+ \, n# \5 p7 h: Z+ X% z$ A: @# ^7 \$ i" |
LONG m_nAsyncFindHandle;
* N9 |4 H, v. |) O bool m_bCOM;
; ]7 ^' g' J& S% t; b1 U4 T) ? bool m_bPortIsFree;
, l; i6 |+ h2 ]: z0 [1 i CString m_sLocalIP;, O+ w& u. A7 S
CString m_sExternalIP;
% \9 T5 F9 z* }6 m: i) t% w bool m_bADSL; // Is the device ADSL?
1 _9 N3 W! T$ \6 A7 V$ h0 k3 U9 u5 Y bool m_ADSLFailed; // Did port mapping failed for the ADSL device?, `$ h( L& `2 z5 P" W
bool m_bInited;+ _& E9 F! U9 |% T6 ]* ]
bool m_bAsyncFindRunning;
% \ k0 s7 i& _; e- m0 b HMODULE m_hADVAPI32_DLL;) F5 p3 {0 ^3 V8 w& T9 N$ `
HMODULE m_hIPHLPAPI_DLL;
+ S" p2 f9 [ K( d' G* }8 [ bool m_bSecondTry;: t7 U& v9 ~! z8 Z& I: A. D1 ^
bool m_bServiceStartedByEmule;
' E6 Z+ H) B7 A4 D bool m_bDisableWANIPSetup;3 G) o* b$ j$ O1 ?2 ?9 y
bool m_bDisableWANPPPSetup;! E) V ?+ g |# i4 t& D r3 g8 G
4 X3 w' y/ `! S2 [( j
$ j" e9 a6 ~1 e/ q& J};3 ? j. w8 W/ C5 m' {1 z" Z, M
3 e( a4 h z/ z* `1 @* N
* R( p# A' s# c- w; K// DeviceFinder Callback0 t* I: {9 t4 W: v8 }# }
class CDeviceFinderCallback
5 z( X) B, d) J) o : public IUPnPDeviceFinderCallback9 ?& S) T: q0 u0 Q B. l
{- @/ ]0 z- F. H: q1 S5 P" U# p! g
public:0 P7 [5 z( A' T* o; D- R
CDeviceFinderCallback(CUPnPImplWinServ& instance)
% v$ S& @; n6 _! O& s& c) P9 U/ | : m_instance( instance ). Y1 }. E% S+ d, \7 y: e/ ^/ R! \
{ m_lRefCount = 0; }% `& d0 } z8 W9 p$ L! _9 F
8 q* J9 T2 W+ F2 b/ \& u9 z, T% s
5 F6 K3 j- g6 p, q3 A: L- B STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" F3 Y0 b8 x4 L4 \6 o- g STDMETHODIMP_(ULONG) AddRef();# y' A( K: y( H
STDMETHODIMP_(ULONG) Release();
8 l* e3 f, _# r U* E$ M
+ A3 }7 v8 i7 |6 ]& e1 O$ `+ h. k1 I: W9 M
// implementation0 c: z$ F. d& Q9 q
private:
7 v* }# ~$ Q- V' o8 b HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);0 U; f8 E5 l, H: {( p8 b! N: N
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, K- v) A+ R. A
HRESULT __stdcall SearchComplete(LONG nFindData);0 g% [# H2 g$ |' d2 C. P
" _* H0 m: w+ k( t
0 O) V! P3 [4 H+ l+ C$ S
private:2 p! H# u) m, O& h0 D0 w
CUPnPImplWinServ& m_instance;
. c2 T$ Q9 M- D: y" G5 F& F# O LONG m_lRefCount;) u& k" m9 g! B( }
};0 ^+ X3 O6 F, o' Y4 g" j4 d) G
}) W+ W6 S/ u$ Z0 ?' P# @( Z3 U
8 K2 V% A4 C% I2 y// Service Callback
( H& a, r% ^7 ?' U" G. N, Uclass CServiceCallback
5 S# S& D# B: J& i3 K : public IUPnPServiceCallback
6 Y" X5 [/ S( ~3 Y: o$ l7 }: P{2 V5 n; J6 A: |9 e; \% m) t
public:
3 K7 ?7 e( |0 s$ a% i. Q4 Z' f CServiceCallback(CUPnPImplWinServ& instance)5 z M/ @+ S* j. T9 E; c6 Z
: m_instance( instance )0 N" ?4 u2 p2 g1 G7 e
{ m_lRefCount = 0; }: I& v' `7 `. S& o7 w
& X& j2 Z( a8 h. V/ ~
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" y, d- a- v! J STDMETHODIMP_(ULONG) AddRef();
5 \* F" \9 R5 O STDMETHODIMP_(ULONG) Release();. Q- {) g8 S7 J5 s
- S6 [- `2 u* v: U1 m
& S/ k+ L$ k8 M% r3 ?* v3 r) _0 F
// implementation
! j2 B8 Z9 `2 f4 u: ]private:& R" {$ G8 C7 C
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);0 z6 \0 z0 l3 |4 s
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);8 Q6 e+ X1 x5 z1 w& O, z
( v* J# s, r) B
/ r }! a% Z8 U" ^) d' H' O
private:" [ h- u& z" h8 e( a
CUPnPImplWinServ& m_instance;: l3 [0 S2 E( ?' d- t
LONG m_lRefCount;
7 H N: D4 \4 P5 a$ `};$ {$ A# s- f' K# c
" e% J+ S$ b! D2 {4 q) g, t6 R6 t6 A, y J1 y' C; Y9 X8 ~7 J' `9 Q
/////////////////////////////////////////////////7 ~$ f( ~% j( i: F7 @3 Z
8 g+ f6 h/ g% C* K4 a" ?# }* f$ b+ p1 r# z" j
使用时只需要使用抽象类的接口。- b) l# c! R; Z: M
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.6 \: }, g- _6 |: {" r0 V& z% T
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口., Y6 k U: Q2 E2 d
CUPnPImpl::StopAsyncFind停止设备查找.
! R V; u1 b6 Q8 F' K, r! }( l" lCUPnPImpl::DeletePorts删除端口映射. |
|