|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
1 v3 P. D2 D- v; N K
_. s2 R2 O% n( i. W" \9 ~! m4 [+ L: A' u) W$ ~; \! ?, ?
///////////////////////////////////////////
" n8 n/ W( y# _9 W; d1 i//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." g3 s' B" Q) a, I
8 F+ x& Z4 p: V3 k0 M+ R
% \* {4 W/ C6 L' y: C#pragma once
0 p% e& `6 l# a' K) @#include <exception>$ m" l- U$ [8 l" {
" |9 l% \6 }9 t: {6 \ [' B8 ]2 h4 F
, d+ \% K7 X% i$ p! L+ E) g enum TRISTATE{* ?, R2 G; r) n
TRIS_FALSE,
% h+ c! y: U' F$ F/ `2 P, m TRIS_UNKNOWN,, ]7 e' U$ D9 x* f# ^( }
TRIS_TRUE# a! x- z' F( U( C( j9 {
};7 `1 T2 z( p" E0 [7 _2 I% c' c
& J& F# m) g: V0 [
0 c( y* N4 _: Q8 y, `# qenum UPNP_IMPLEMENTATION{1 _* e; K M6 w+ r. `8 {. I" L1 E
UPNP_IMPL_WINDOWSERVICE = 0,0 C/ b0 t- V7 u* u2 j1 F( V. m( t* V+ i
UPNP_IMPL_MINIUPNPLIB,
- A0 H5 L% j6 J& i* \0 f UPNP_IMPL_NONE /*last*/
; L9 Z$ A/ s' e6 e! T};- _; _: E6 N5 o6 {$ w
5 d/ ]# F5 H: U b& [! u. ]; H. ~7 C2 Z- p4 d0 }1 }- o
3 E, ~1 U( q2 g+ F' V/ t1 V
5 ]% n. w3 T t- |# r$ sclass CUPnPImpl
& E O5 \5 L8 y! v& _{' C) N) i& W S! u/ K' {
public:2 o! I8 v& B9 C. v* ]' }
CUPnPImpl();
+ @6 K$ Z8 v% Z5 H7 J* e& E$ U virtual ~CUPnPImpl();4 ~; {9 @9 y. B- a9 w9 S
struct UPnPError : std::exception {};
4 Y% B6 s0 ~! g9 Z enum {
+ V3 y3 g. M% ]- m UPNP_OK,: Z! R3 w& f* ]" }% ~6 f& X
UPNP_FAILED,
$ {7 ?0 l; L5 G) f }9 Z UPNP_TIMEOUT% b: I$ l$ C+ c! j
};
8 D- j+ C4 V! e7 e5 M7 @. f3 K8 j! I% Z: ?3 u9 Y7 t" ~
U/ M) c8 Y& t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
$ @, ?$ r) C$ `! l% a/ R virtual bool CheckAndRefresh() = 0;& R- ~/ s# f% K/ L9 z' e
virtual void StopAsyncFind() = 0;
7 g7 j5 v& v9 U7 q virtual void DeletePorts() = 0;" O. P2 ?( c* c3 N: b" T% v
virtual bool IsReady() = 0;, e" ^! Z+ E+ G2 m9 h0 D
virtual int GetImplementationID() = 0;# Z' U. ?6 g4 X
4 [" e- B. Y) R ^: B' w' }
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
' L! L+ Q7 i+ Q7 h
, t* U+ J- o8 |# b$ R+ e
, U o+ x+ E1 \) L void SetMessageOnResult(HWND hWindow, UINT nMessageID);, d4 j+ p: n8 `. s" R l! h
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }5 B; P6 L1 P) i. X
uint16 GetUsedTCPPort() { return m_nTCPPort; }
0 \$ I7 m, y3 j% i* S3 J uint16 GetUsedUDPPort() { return m_nUDPPort; } " F0 H3 f; C8 a8 p
- |% }3 I5 K& Q1 D/ I! U
9 D0 d* y& X, [3 ^( Q& n
// Implementation
( O8 }" d0 t7 |6 ^1 K1 Uprotected:
( [% j1 S! { v7 D; S+ S% V2 s3 M" D+ b- @ volatile TRISTATE m_bUPnPPortsForwarded;
/ w0 g. f1 {) u3 `( \ void SendResultMessage();
* k* `/ F' U2 w" k uint16 m_nUDPPort;- C A0 V6 S" L5 r
uint16 m_nTCPPort;
6 e# {3 W' B0 ~" _3 h! I uint16 m_nTCPWebPort;
. i5 E' {( J) p( ?# O bool m_bCheckAndRefresh;
: Q0 H( @3 P- n
/ A( b8 W) I4 b0 j- Y- z" c" A) i
0 S( S$ E9 c5 T/ ~- n6 {private:9 v, b: \6 f, R7 K$ k
HWND m_hResultMessageWindow;
" M+ ^0 @9 g0 ` UINT m_nResultMessageID;
4 |/ x3 R- i n+ k, T
, o3 V. g- @# Z' v7 e) |) y5 E" `! K# z- i. K4 v+ ]% f
};
+ y5 S; ^( D' M0 ^- O
% \3 D- z; L& l2 J
2 o3 q& [) M/ o# z/ k2 Q// Dummy Implementation to be used when no other implementation is available- E8 n, \" s0 j
class CUPnPImplNone: public CUPnPImpl8 R, y) Z5 q0 E4 |* n& Q8 X8 h
{
: O; k8 R+ P0 Lpublic:
( F! J% u0 K6 H, b, F# |- ^' G virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }: b9 K! z# p* H6 x! K
virtual bool CheckAndRefresh() { return false; }
8 L; T6 I% c# | virtual void StopAsyncFind() { }+ F2 b" y: y8 S0 I% h+ Y
virtual void DeletePorts() { }
- _- G- {- L, d3 f virtual bool IsReady() { return false; }
9 _$ j" Q) u% B* h$ \6 Z2 R virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
& S& o8 g) j, i};
5 [2 d) ~+ v0 ~2 _. n/ y
. H% @5 g* I# s& e0 g) B. \0 s( m% v4 A) s. Q( P; s' H3 d" v
/////////////////////////////////////* y6 `# @: i3 [/ W1 g6 f& z
//下面是使用windows操作系统自带的UPNP功能的子类
( L% ^ o+ V" T: f( E, f. l
# I M0 q" D i L$ Z1 L
8 n! A. }: H& q+ m }5 Y#pragma once! X( V) a! e2 w: b0 L
#pragma warning( disable: 4355 )
: ~, Q8 a! a9 P7 a) ~. H9 i
+ K5 \% c; Y- n# O! _, P( l8 ^' b( w3 W
#include "UPnPImpl.h" [+ w: _, V% L& N
#include <upnp.h>
4 ~; S- U9 @& P4 d4 B, e' D9 I#include <iphlpapi.h>9 R7 X6 e }( q$ a- I+ X, x
#include <comdef.h>
" g B! T) G0 e6 \. _& O# b#include <winsvc.h>6 u* G3 e# `; A, g/ u9 Z$ I
* |6 ]8 f' N; w7 u4 N+ u# B4 |
$ v" Z: c+ D; M' @' d. X#include <vector>2 C: V `1 A2 W2 j' `( i
#include <exception>7 L+ ^) e* U$ S+ b; I2 ]1 `
#include <functional>; x7 f' q# j( b5 z4 Q* e) H: s& U
2 j+ E* b1 x" X4 z ^
8 ?: E* Z8 {; e" ~0 p: t1 ~+ y7 `5 Q# d
2 T: f- g* V) v6 G7 Z# w1 Ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
) x* z: @' Z6 [- K3 n8 htypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
0 h# z- Q- u5 e; X0 Ktypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;, w- N, e" |7 T
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ Y. N( D% |" atypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;* D- o8 v- x# F- L: |+ j2 F8 Z
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
" O k0 \! h4 m6 c9 T8 z2 @8 D8 Q- stypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ J! \* [# S" ?- |: Z$ x7 v
& S- r/ M, ^- p3 `
: M0 T' r) V. R' A9 itypedef DWORD (WINAPI* TGetBestInterface) (
: N( o/ g: F# x) i C8 x IPAddr dwDestAddr,9 E2 F' o S' m$ R9 N# }$ K% |
PDWORD pdwBestIfIndex
( h& {: E8 T2 @! f);
) B3 c z' f: E4 o3 u/ ^2 c6 a* p% b4 n
9 |8 e1 ^5 D9 n ?- c W3 X3 ktypedef DWORD (WINAPI* TGetIpAddrTable) (9 Z5 d L' Y8 W) e8 S, K; z
PMIB_IPADDRTABLE pIpAddrTable,
& @- @% P1 }4 N0 U; ]) G PULONG pdwSize,9 p0 N+ q8 i2 R: D T7 X
BOOL bOrder: O( f* u% L) Y
);/ T1 W$ |' ?$ [+ f5 p9 f+ |
+ R; O# U7 E( u# Y5 Z+ E
' P0 U/ Q' l2 X# A1 ctypedef DWORD (WINAPI* TGetIfEntry) (! u- j6 q [$ x
PMIB_IFROW pIfRow) u; g, j/ G o9 j. ^! R% g. J+ r
);
, l: k* J. _) L) y9 G' {, _2 d8 }
- t6 T/ l$ @' d/ v0 i+ w( x
1 L5 a% ~4 W+ L8 dCString translateUPnPResult(HRESULT hr);3 N1 L9 h! s$ r; R) Q
HRESULT UPnPMessage(HRESULT hr);
& K2 H3 R. y/ Y" X; @3 v" T. @
$ s# w. ?0 d, G' k* D" y3 x p5 f* z( ~4 u2 O/ b
class CUPnPImplWinServ: public CUPnPImpl7 o/ n, s4 J1 `* @# k, s' n$ J* y
{
6 j [, J* n# s; \' O, g* l friend class CDeviceFinderCallback;
8 U8 }: q4 o, x& N2 A$ o friend class CServiceCallback;1 B- ~9 z6 p; N$ p* L% Z/ A
// Construction. C' e, d& [5 H0 X% e
public:
3 S$ L" m y; U$ w virtual ~CUPnPImplWinServ();
6 h) n! [! y6 E- ?( u CUPnPImplWinServ();
2 z5 M b Q- K7 Y, [ A4 B1 b
& L! h5 {3 c8 S$ |" s+ J
) a; n# a4 @7 O. h virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }4 z* f' e' ]7 z; l1 \8 L. I9 X
virtual void StopAsyncFind();/ c$ P3 |6 v! \4 i: n1 f, h
virtual void DeletePorts();
9 d/ L4 A/ Q$ C, H) ]! e6 [ virtual bool IsReady();9 @% g/ X7 j1 D9 K6 b6 J+ J
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
$ @( V% L0 J2 x4 T- o5 J" @
, Q9 f9 a' X7 {0 W. m8 G
/ {$ U3 r* A/ c- j( p, p$ B6 \ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
, @7 a( ?$ T, M! ] // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 \8 u1 R) M3 v- q% ?) T* i! P virtual bool CheckAndRefresh() { return false; };5 D: E) r5 i3 ?1 [% E# ~( v/ U
, _* G |( `/ P$ E$ L8 ^% I) ]8 G# a8 r: ?. g
protected:
* c4 B- q! n9 ?9 K: T8 e void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);4 H: p# w* F, r- {, C
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
; t( k9 i" O: i; w* O# [ void RemoveDevice(CComBSTR bsUDN);
) p @3 w! ~# m6 O4 r! _- D% U bool OnSearchComplete();; g! M8 H! i2 C) ?+ J z
void Init();# H. N( J( I" z) `
3 O) R$ O3 W, b3 q6 o
% ]6 t3 {+ ]! P+ _; l9 ] inline bool IsAsyncFindRunning()
! M" N- ~! J1 X( s6 F2 }$ w {1 J8 w+ I! C2 b3 M. r
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )$ ^* |! O7 P- M; y6 e
{! [+ T/ X; y' ]+ ?) e
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
2 c) q' P8 S8 M+ M& b. \) b m_bAsyncFindRunning = false;2 Z1 D: f6 Y G* G3 I. n
}% A# T7 V- @- m3 ~! m
MSG msg;
7 [" d" l5 E1 I* F/ ^' J while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )5 @. O+ j- S, a3 j5 Y3 `) o! e
{( k/ H5 n& Q* s5 E
TranslateMessage( &msg );
, x+ U4 B+ v& J$ u5 W; E$ Z- H+ f DispatchMessage( &msg );& ]& p& T* a- r
}
" z3 ?, e& H# n3 f$ Z; C4 t. t return m_bAsyncFindRunning;
1 H! I9 f9 U f- F1 r# { }
9 B4 N) a2 N! B' \2 d" [5 l1 u0 A, E8 S" R0 R3 {* \
. \2 C0 B7 p& i8 Y: D TRISTATE m_bUPnPDeviceConnected;/ j( |4 w# K3 G
8 k1 E5 H( H0 u+ J( ^& V
; ~; {9 O3 c9 B [6 }) U, x+ ]3 r
// Implementation
d/ L8 c$ N& f6 i; N // API functions
$ x" r- R* J u SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);- ?+ ?6 R1 ^; {
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);5 M' y1 q) c3 m6 t) g
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 k8 _& _# L; g) s7 j- D9 G, ` BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
4 S1 ^& [, S' ? BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
/ e4 J) }" `1 R& M. J BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
0 v" Q- a+ W( O0 N! [% }) l) Z$ m3 K/ x. d3 H
- z0 g: m% @$ K ^0 N
TGetBestInterface m_pfGetBestInterface;
1 {2 s: x% T# s% \5 }% a! s! j, o/ f TGetIpAddrTable m_pfGetIpAddrTable;9 z" N4 D( ~$ d2 ? k
TGetIfEntry m_pfGetIfEntry;
5 I3 k8 L; x# s& K$ f3 O8 l
; f& m- ]+ C. f8 q% o7 H
# h% q9 ]2 ~" s) C' {- y static FinderPointer CreateFinderInstance();: S0 }% _4 O9 c% H* H
struct FindDevice : std::unary_function< DevicePointer, bool >. z7 R- k: @) o% Q) v, O
{
h W1 t# I8 ]: p+ m! A, \ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 n, l, n& }! V) L) i. S
result_type operator()(argument_type device) const( l- i0 X f0 q
{
* \( x8 G/ D. V- J* R: [) D& ^4 \; s: H CComBSTR deviceName;
# l( Q8 L4 t2 L$ q HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 @7 p$ |! U3 L# a$ `8 r3 r: I4 g% Z% f
) P0 F0 D E: o: ~% k) ~3 n. E, C6 t
if ( FAILED( hr ) )
) U( E9 {8 g( p. e/ l" q v2 X- @0 F return UPnPMessage( hr ), false;
# H3 l, f" r" P _# F8 q& y0 A
6 X5 d4 X4 }- q0 j3 i8 B, ]( c3 m
return wcscmp( deviceName.m_str, m_udn ) == 0;
. Q b* Y5 C) q. _. _+ L& Y( S+ I$ z }
. u! Y# _* p2 h6 q5 E2 m$ w$ U CComBSTR m_udn;: c3 Y8 G5 _4 a+ ~
};
# C/ l. h3 ?0 N7 F* b2 e+ k' ~9 r + {. d& x0 M+ T' }, l$ A
void ProcessAsyncFind(CComBSTR bsSearchType);
% F* B' W* n; |2 D- i. ~9 [+ c# _9 n HRESULT GetDeviceServices(DevicePointer pDevice);
% K0 n- P: R- Y: B/ ^9 E5 @- K5 h void StartPortMapping();
0 {$ R7 }- V! x0 m+ ^ HRESULT MapPort(const ServicePointer& service);
/ ?7 M/ C; P5 y% C2 _ void DeleteExistingPortMappings(ServicePointer pService);" b9 G1 O3 @! o4 t; e4 l
void CreatePortMappings(ServicePointer pService);
* L' Z4 C% a# N$ ^ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);" W* t% j: t o* J1 U6 N& V+ @
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 9 M1 k6 f9 C- d
LPCTSTR pszInArgString, CString& strResult);
4 U. f: w+ m* ^; h void StopUPnPService();. y5 ]+ S2 S B
( G) M' Q( W- x& f/ U; t7 x( g# Z5 ^
0 r, v& i% X% }8 }5 G/ a // Utility functions
3 R* f) S7 y" R" N HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ D/ V# A9 ^4 F- W p- P INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, I6 R& f) R& o4 A INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 P' T$ e: c( Z8 O4 T
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
0 N$ O* F% F6 Q# ], L HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);/ U) m; \/ X! q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
, p( W& Y7 z% x X/ S CString GetLocalRoutableIP(ServicePointer pService);" ~ k f4 o& o& N" R: A) A
* i" \% Z h3 n4 X5 A' p7 k+ j, s( i0 }, L9 N* M' I
// Private members* h' g$ l1 y( U& S" ^% l
private:: S/ i# D: v' P2 ^. n
DWORD m_tLastEvent; // When the last event was received?
+ `) B# A0 S$ {2 K) y" f std::vector< DevicePointer > m_pDevices;
y# J2 ?/ r' H' V& G std::vector< ServicePointer > m_pServices;+ d# ?) z- i% ^! k
FinderPointer m_pDeviceFinder;
+ ]9 u/ ?7 i5 ~: s' A8 U) ? DeviceFinderCallback m_pDeviceFinderCallback;
4 k& t* X! t- t; d ServiceCallback m_pServiceCallback;
5 j1 G. [' E$ @3 _) i1 G
& x/ i9 g1 i& @+ D, g4 A3 d J! |, Y+ |' `" ?
LONG m_nAsyncFindHandle;& V2 d& P; ~+ F( v6 B* d
bool m_bCOM;5 Z: `( Y6 S0 A' y) U- a
bool m_bPortIsFree;9 f/ ?; L6 i3 K6 t! T% |: F. ]
CString m_sLocalIP;4 O, X% i; \# a& P% b, o
CString m_sExternalIP;
0 }. A$ a b8 @/ G7 u2 r: @6 B bool m_bADSL; // Is the device ADSL?
6 ?2 Y2 k! U! W5 ]' b, P5 |6 a/ V6 L bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
7 o- \$ ], F$ y( C5 u% ~4 t' D bool m_bInited;
4 ^* x7 i/ e4 H# I& Y2 c bool m_bAsyncFindRunning;' t# A" H. l8 F) k( @
HMODULE m_hADVAPI32_DLL;& U8 X4 p; B" R$ m
HMODULE m_hIPHLPAPI_DLL;
- K/ ^7 {8 C0 R1 C8 ? bool m_bSecondTry;/ J; g0 i3 G. W; s6 v# k
bool m_bServiceStartedByEmule;8 |5 ?" i7 a/ o
bool m_bDisableWANIPSetup;
. O# t- @- R; l" E' |+ C bool m_bDisableWANPPPSetup;7 Y7 o1 V' S$ Y
3 k6 h ?' T7 [3 z
2 v/ A/ J1 Z% x1 t- f' v: J- s};9 z& ~1 k0 ]) V! H a: F) N$ \
- V2 M) ^: S' J# J; i! B/ q& @1 l8 m; K# N1 v. y' s u
// DeviceFinder Callback
: q& O. d. ^" ^% X3 i% A8 I: ~class CDeviceFinderCallback; h6 k/ T$ }0 g/ h P
: public IUPnPDeviceFinderCallback0 |' F* ?- o2 }
{
& f& q( @9 P% j( s9 V6 @* n& |public:# X4 X" ^/ |6 P; S
CDeviceFinderCallback(CUPnPImplWinServ& instance)
3 R2 J1 D6 g9 m% e7 E1 W : m_instance( instance )' \7 L5 e7 y& C0 y- Y
{ m_lRefCount = 0; }$ z. `$ P g6 o" v# a
$ z% D- [1 [+ j8 P/ ^/ U( g# j3 r r, D1 x( i/ t
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 V9 N# m9 U) o STDMETHODIMP_(ULONG) AddRef();; B0 n+ u( E$ _- h$ x L7 T% ^
STDMETHODIMP_(ULONG) Release();* X1 i" x0 G4 s9 L' A9 U b, c
- H3 t3 y3 s3 U( H+ t4 ~8 t
7 F' y |1 d9 y# p& N( ?
// implementation
/ k$ g7 @/ k( `2 g. O. z, `6 zprivate:
$ S( d) I8 w6 z7 [ y HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
5 v- Q! M6 ^5 J) ~ HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
5 o9 v0 q" D- ~- p" `- G( m HRESULT __stdcall SearchComplete(LONG nFindData);- [9 v8 @; P% i. F; y
$ T( b, r; d s& l3 [! i' z$ g" Q9 n! h- F' |" D5 U* S/ r0 k
private:8 I5 I y- n/ L/ \/ ], ^, G
CUPnPImplWinServ& m_instance;
3 R8 j `: M5 k1 ^ y& j LONG m_lRefCount;
1 ~4 r, ^+ Y# b- X. f: e! U};
; [3 @4 l4 C3 C; x& e- i! r# S5 l& m7 n, l6 R8 b" M
2 O! h0 L+ h/ Y/ |8 X; j// Service Callback
7 ?; Z; g( T* ^$ e5 Rclass CServiceCallback7 _/ ]( f9 b5 s. y
: public IUPnPServiceCallback
E, U$ R5 `, D{- F0 l, C5 x8 u
public:
1 k; O/ n( f& p9 u7 y: b CServiceCallback(CUPnPImplWinServ& instance)
- I: L$ ~8 |& c& \3 ]6 f : m_instance( instance )
; m6 m2 D8 c. N: p: l5 e { m_lRefCount = 0; }
: k" o! q8 Q# H: U; N % T: ~* h1 r ]* a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 r6 o% @: E5 R STDMETHODIMP_(ULONG) AddRef();
+ c% n. P% b7 R4 H; O9 J3 P STDMETHODIMP_(ULONG) Release();
& B# k3 N4 T& {5 z
+ C/ {: d" _6 z8 O- m3 j" m! ^+ v$ U2 C8 X! S
// implementation' k# I( S7 |$ S
private:
0 P D7 _; B/ }. u HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);! z7 z0 T& v) a" p' D+ m
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
' x! R2 W. R- ]$ B- O
- ^& z! m Y/ O0 Z7 K# a1 l( C* m, i8 d$ c9 c- ^* P( B: W
private:
4 k( K" {. t: t. P# K8 m CUPnPImplWinServ& m_instance;
9 }2 D+ ~, g! { i! }8 P2 c LONG m_lRefCount;
" X8 p# t( p; L# `};
( I7 L0 `3 D! P* l l8 ?5 m0 n- s4 N
2 P" r' ?( q2 e x, n( P9 R! `
/////////////////////////////////////////////////5 L& G1 W2 V* e- ~
! d0 k: v' _3 U5 e L* S# b* m W) j1 j+ ]1 \
使用时只需要使用抽象类的接口。
4 T0 M+ @- \- ^; [; t5 ICUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
! A+ g; R8 u( O, tCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
( G* T2 _3 @5 w: tCUPnPImpl::StopAsyncFind停止设备查找.
8 ]1 @2 |6 h0 M4 f) ?CUPnPImpl::DeletePorts删除端口映射. |
|