|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,% h; `9 I1 P7 q
9 o6 c8 \& Y. w8 x- E6 V1 O
2 ]; J# ~8 n3 g/ }- V) y///////////////////////////////////////////; F% }' |% U! v" y. Z7 w9 T5 N" F
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.4 t/ i( L- ~# |; L
Q- h5 y% M+ `- z+ r- a1 G. N# _. y# \* z
#pragma once+ D$ m& W6 G6 q7 O+ `( Q4 r# ^
#include <exception>
) Z% N9 A/ r+ J
& U, O& G' k- F) X8 ]& S/ t; ]( o9 G
enum TRISTATE{ ?9 F: k$ C( H6 {4 ?
TRIS_FALSE,
$ u0 f3 @) D* S9 L TRIS_UNKNOWN,7 \3 X6 v# s0 o q) ~
TRIS_TRUE
* E5 [* U; D' t6 x. C};6 z2 p* o1 v1 q. U7 \
, _9 P9 A/ D1 R% i, m) B
( H7 N# J/ P) i! @! L7 l c+ Eenum UPNP_IMPLEMENTATION{- B& j( O2 C9 k O( g
UPNP_IMPL_WINDOWSERVICE = 0,
" W) a7 a. O5 Y8 i6 i4 d( l- f. `! j/ i UPNP_IMPL_MINIUPNPLIB,
; ], f# |8 a9 y+ `; A( X& h UPNP_IMPL_NONE /*last*/2 U, ?8 @0 d! E( r% X/ m2 ^
};
+ B! [. F" Q2 i4 C
' B& |5 O$ B* V& I1 E' F
8 {4 P1 |& x% D3 g/ X+ L, X4 h% |4 P( s( A
, `, O! w G4 J3 k6 a' J' {5 J1 fclass CUPnPImpl
: f+ ^8 R& N, E f( V$ J{! a" N! |! t' I
public:% k- i1 M: `1 K1 ^$ |5 c
CUPnPImpl();
5 |+ [9 i* p1 ~6 Q- N virtual ~CUPnPImpl(); x1 t) c I( i! V+ N; P
struct UPnPError : std::exception {};
$ ?5 J. w0 C: B. A0 l enum {5 O! c; S/ J% ~( {# A' F
UPNP_OK,
+ L( P% H6 k$ S$ m+ k6 r, g5 s UPNP_FAILED,
; j7 O# r: E( t UPNP_TIMEOUT, j: g+ f) D1 I7 f0 k
};# W- R0 {5 O7 L
, x9 K! X: _8 y% k5 o6 \ }4 R) O" ?
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;0 Q1 T* n7 Z4 g, e2 r
virtual bool CheckAndRefresh() = 0;
# O$ x. J. j3 I7 t% I1 ` virtual void StopAsyncFind() = 0;
+ M4 e1 t9 D2 d% C virtual void DeletePorts() = 0;
. }0 ], `$ Y5 d" Y$ y1 O: H virtual bool IsReady() = 0;
" E# a$ A& _2 G9 r" v virtual int GetImplementationID() = 0;
% M% t( [, C. I- F( n! d$ n - n# z" L. [8 R" _. ?/ }
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping. l5 S3 T0 f9 s% Z
" h* ~& D! `% b$ l* j
( Q% b' ^4 D0 u& ~ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
. ^4 O G% l6 }( u TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
" y1 \1 [* X/ y* j9 W* E3 C, C uint16 GetUsedTCPPort() { return m_nTCPPort; }
' p6 ?: h4 z5 m. S" i uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ F$ L; c9 Q0 u
- P7 _% w8 [5 Q1 a+ v
. n6 u: ~! w% L% d+ c t// Implementation
4 f/ F6 J v' f5 |' dprotected:& o0 M( \; w- }9 k; K
volatile TRISTATE m_bUPnPPortsForwarded;
+ ?5 T2 l6 G7 u; m& _ m5 c void SendResultMessage();
4 f# [( D9 N, Q% Z uint16 m_nUDPPort;4 i( v+ t. `1 M" x
uint16 m_nTCPPort;
; M3 q% S+ j# v uint16 m_nTCPWebPort;2 |8 t3 T1 t" l
bool m_bCheckAndRefresh;
) Q( G" w& ~! o! s1 @! O
, z( i8 a% x5 E8 t6 W
- C" H4 Z: F) {, uprivate:
- t( [. {' T' v2 p) X& |* Q0 o HWND m_hResultMessageWindow;: Q% L1 G# w, x8 [; B( D
UINT m_nResultMessageID;- E0 x; u- J. `2 M& L
1 E: V$ {$ T4 N: Y7 _
1 T) _" Z6 a8 v
};
+ ^, t2 O+ m5 P
1 [3 C6 N, ]2 _% m7 T1 Q* i" E4 N
. w, e- F" T# X) O) y+ D! L// Dummy Implementation to be used when no other implementation is available
) P7 f( M( l" W# H$ e/ Qclass CUPnPImplNone: public CUPnPImpl
! @+ ]' Z0 H! M$ W. T{# b6 `. ], R) [+ U
public:
, m4 b! E" f0 d, @$ ]" t2 V virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" _3 Q9 }% c/ F! d) q% A
virtual bool CheckAndRefresh() { return false; }# N7 E% N# @! E
virtual void StopAsyncFind() { }, L; |" C5 Q8 N5 p6 Z) Z
virtual void DeletePorts() { }
% j9 i# l2 _, @8 v4 J3 J virtual bool IsReady() { return false; }
, R6 T2 ]$ i: H* n( w virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
* h e' {( f2 c- b* e6 h; \};- N3 |: x7 q' a. D$ @
% B9 T7 ?! u: P9 t8 y5 J
3 l% ` A% q1 [: K* [/ N8 h- Q' G2 `$ N
/////////////////////////////////////7 Z6 K6 @; U: f5 N6 Y
//下面是使用windows操作系统自带的UPNP功能的子类5 n8 O; H9 P- p q( y
9 j& T, l, \+ z k' f$ ]4 w3 k
1 D% d* o7 ~& u/ K ^; Q0 |. S#pragma once1 \" H' t/ N$ e0 t) H6 U
#pragma warning( disable: 4355 )7 C: M+ B+ i! g' d
. i- b9 ]" t+ }; \, P% g; X$ A( i6 s0 V6 g+ J3 z# o$ B: ^
#include "UPnPImpl.h"6 y) Z6 X- B1 R# O0 U
#include <upnp.h>0 F' E0 i4 X a: [
#include <iphlpapi.h>
/ H% q: U& S6 u6 {$ M) g+ ^#include <comdef.h>
; n5 ~+ k/ O& M5 `#include <winsvc.h>/ ~! x% x9 _0 E9 Y, z
; ^- M3 `8 Q5 i7 o; Z8 `
5 H- }1 z& A6 ?' F& M
#include <vector>
& }& v- Y U$ }6 N/ E1 X {9 `#include <exception>
4 N- I" k; ^' ]#include <functional>
) Q& G' j- G% a$ S
5 ~! r1 o& }5 m& ~9 i/ j( |6 r9 o8 A: t) n0 r' w" f7 w* j
- f1 H% s: T' A. _
; _/ a$ ]$ q" N9 i6 Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 U% l) f: Z* i6 b2 Q. a
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;' ?/ \8 A6 J0 r# i$ T
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
+ q% \8 x" G- z! Itypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
; f/ z8 ], m; G- a3 A4 ktypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
1 t1 K, Z" S3 [ X* A, S- Ftypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
4 v, L, J( m: S. o$ d- Y0 l7 x( Itypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
$ ^% G) A; @) A1 F* q8 B, T! U4 `) k6 D( B
3 Z/ D; v, I0 x; c$ C$ {( ?& Ttypedef DWORD (WINAPI* TGetBestInterface) (9 f1 u8 [: v3 c# }' d& w/ F9 I9 |7 |
IPAddr dwDestAddr,7 w6 L" t9 i, s3 v) z7 O8 a# Q
PDWORD pdwBestIfIndex" o6 P- X, w8 V( b
);- w! S; m* S0 O& }5 t
! z, [% O* s7 k2 u
% l. \. G' |% G3 b" P
typedef DWORD (WINAPI* TGetIpAddrTable) (
8 B/ p2 N% h" V5 F; p PMIB_IPADDRTABLE pIpAddrTable,* `9 Z2 x) b0 j% V% E/ I
PULONG pdwSize,
+ M- j% M4 ^7 S1 \9 F: q) X BOOL bOrder4 j+ n g" B, ^( R1 U. g7 F
);
( Q2 n D2 M: V. {# J( R) p7 x; w6 T5 _2 J& n% @, u( q
) f; \7 U3 N# ~) s) r% T/ N0 ttypedef DWORD (WINAPI* TGetIfEntry) (
( y8 [- J; j7 Z8 Z7 t& A PMIB_IFROW pIfRow, G g3 W; d" }; B T m8 o
);5 i0 f0 Z# I3 @6 q
0 f1 F$ n; Q7 S8 M' i5 \8 t# R
$ @: m" G7 W+ K8 o/ U- |; R! h' {
CString translateUPnPResult(HRESULT hr);
) B2 d& g. {6 r5 L; ^8 A* T9 }HRESULT UPnPMessage(HRESULT hr);1 j! x& V' s" W* P$ T
8 x5 t! N# k5 j: [* |8 h% a! H( z
4 a7 s& O9 L9 b! F" y2 Hclass CUPnPImplWinServ: public CUPnPImpl
U9 j" J3 s1 z$ ^& {( ?{3 m( p' m3 i3 k+ y. B
friend class CDeviceFinderCallback; l) z- a0 p0 S# e% Y8 o
friend class CServiceCallback;; c. X! w+ ^5 V+ u) j3 O* u+ T
// Construction
) r% B% r ~9 m7 X0 X* o1 h8 [public:
9 z5 Z! _. H' }* f; L* _ virtual ~CUPnPImplWinServ();
2 z6 [. _; ]! I# A5 o& A2 n CUPnPImplWinServ();
# @" m' ~" `( w/ G% A! f
1 a8 X# D, ?) h1 v0 [ E. x
% a% Y1 C) l' s. b virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% Y) h2 \( k' N3 j! A! _ virtual void StopAsyncFind();; @& i& z9 i' g4 F
virtual void DeletePorts();
3 C+ r0 e" L! O& E5 ]8 m virtual bool IsReady();
# f5 x# Y }5 r, p5 U virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
$ p4 @3 t4 {# R5 e( I5 {; O& D/ Q1 `- {8 q! _
- T& Y4 z1 j- L* ^3 [
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)' I4 K, F P( ^. W6 i- A4 R
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ _. p. ]& e) p3 u virtual bool CheckAndRefresh() { return false; };$ Z/ S- q+ b \- a" F B$ X9 \
+ }4 ?' C" k d) G
3 Z$ h0 s, s# mprotected:
$ W( C5 U, @1 L" J: M2 w: n, j void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& Q4 y/ a% ^) h0 F2 L5 ^( o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
z: T) r: v1 C void RemoveDevice(CComBSTR bsUDN);
# n+ \% {- g! z; V7 i3 g bool OnSearchComplete();( h5 L! q/ G/ O
void Init();% S1 G- M' ]4 h" i' J
9 V( A; }0 m3 }- d! \, r8 N% ]" I# f, q" k; i' j! ]
inline bool IsAsyncFindRunning()
; y8 l. t4 f D, u1 W7 l$ c# R {/ z7 S" T6 X3 W! a
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
' c' n. o. H8 x {5 ~& Y- N8 E& d e; D1 y
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
; y( m) k/ Z- ?( L# a) u m_bAsyncFindRunning = false;+ _ B& `, L& G) w; }
}2 E! C4 A" }- X
MSG msg;& S4 Q5 k- ^6 h' k/ u
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
2 M% H0 Q. z9 U/ k1 Q {9 T( C P4 Z y% f @
TranslateMessage( &msg );; P- g' T) D j
DispatchMessage( &msg );
1 K5 }" W+ p. ] }# r" b+ b( ], a! I
return m_bAsyncFindRunning;2 N2 X7 z4 g( \; n
}
3 d/ y3 }5 v9 J7 y( @8 x1 H
' V, {: d0 w) Z1 p9 B$ G% ?) S/ S5 o% k1 B, M N
TRISTATE m_bUPnPDeviceConnected;7 }5 L. c, g- _1 t
+ `& w) p" V/ G: L! I) ?
( ^/ p7 h2 \4 t8 H: L// Implementation' |" t+ [; o' ?
// API functions
4 a5 O2 x/ V, w) D7 P SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);. n9 w7 e3 n/ G" d
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
/ G2 {# w* z$ Q+ _( b BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
3 s4 J( z, d) d: V BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
8 H" k$ [! H$ f8 U% c) p BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* `" V1 d2 ^5 g% [: I: B
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
, G6 A. j- ]! Z( F; K% \- d# m2 H6 \2 V3 K. P
1 U( N! Z( N4 H5 o TGetBestInterface m_pfGetBestInterface;8 M7 c: T* O( t/ L! R
TGetIpAddrTable m_pfGetIpAddrTable;
C& i+ C+ E5 B+ o( z3 a TGetIfEntry m_pfGetIfEntry;, N& W7 d& W% H3 K/ _9 ^
) N9 r- q$ {; S9 U
9 `3 j5 y# s/ g8 O P7 o% f9 H static FinderPointer CreateFinderInstance();
" @4 {+ F) u+ g3 I. l' ?- L( A struct FindDevice : std::unary_function< DevicePointer, bool >* U# Q: u% D$ l4 c
{
: ]& Z" g1 a/ h: b) F! L FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ w% t9 h H9 G0 I result_type operator()(argument_type device) const
5 r1 g' [# ^" T {9 \. g- h/ g5 O+ {
CComBSTR deviceName;" D2 L9 I9 T, s
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
) N8 ?$ s4 d: H* z- p1 p& M; [6 F/ v3 d
q1 h8 W. S. |7 X: k if ( FAILED( hr ) ); A, ~ i+ k: v- L
return UPnPMessage( hr ), false;+ I+ r2 H$ p( W0 ` |& w
' m8 u: q& B- h
% N- ^$ f/ U+ _: ?$ d: A return wcscmp( deviceName.m_str, m_udn ) == 0;
5 U( d# s8 c6 ^ }
: e h/ v: b% U% d, M CComBSTR m_udn;
: _" B9 I( {4 k( ~5 ~7 {; w" z };2 U% [# X( ^2 }4 C8 d3 b6 L9 P. M" l" f
. L" E* v7 T( d void ProcessAsyncFind(CComBSTR bsSearchType);! K& ?8 X) E6 x6 j0 y1 A+ Q+ @
HRESULT GetDeviceServices(DevicePointer pDevice);
: f' d- L7 f) `; w+ R+ V void StartPortMapping();% E& h) B( B- E; k
HRESULT MapPort(const ServicePointer& service);/ Y& E3 D; c( l, [; \& z F
void DeleteExistingPortMappings(ServicePointer pService);1 ^7 ?3 b, E- O; t1 L5 I
void CreatePortMappings(ServicePointer pService);
7 W, `8 ^' V# g' r; [3 } HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);* z4 Z# I, ^$ a0 X% m2 I: a
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 8 H6 s+ r" ^, S" a1 Z; l
LPCTSTR pszInArgString, CString& strResult);7 ?; ]. t4 a" ~+ G1 p0 X
void StopUPnPService();
( `. ^* c) [3 F5 C. Y7 N
1 P Y R3 K0 N& i+ Q" X; V- B# N5 ], K
// Utility functions/ z$ Y0 v2 u* c& m/ h& M
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
2 }. K0 o$ [4 M2 I2 O, x& \ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 Y3 h. g0 V3 a j5 E$ y, c INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
( a* K/ j% }4 W5 O void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);: k% B2 B( t& w
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
& }5 N5 r: X. A* Y( b; c% @' g/ h HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
# y5 @% `6 Q4 `: I CString GetLocalRoutableIP(ServicePointer pService);
2 O+ `9 Y- l9 n/ q- u, L4 ]1 u* S5 z
: O: G% C& h8 M( j; M
// Private members
* o$ ?% @$ @3 ^" k" M( H; V* l: P& n; jprivate:
) h) n" F+ q, R DWORD m_tLastEvent; // When the last event was received?$ d8 {! L2 j# _* e- Y( H+ L7 a
std::vector< DevicePointer > m_pDevices;$ o4 O" P+ \9 L8 c3 v
std::vector< ServicePointer > m_pServices;3 i6 w4 s1 Y' q
FinderPointer m_pDeviceFinder;
* w. }5 `% {* u8 Z DeviceFinderCallback m_pDeviceFinderCallback;
7 h, ~' c/ f0 f, s$ D* A% D ServiceCallback m_pServiceCallback;
# L5 e+ ^ U0 p T/ C" i$ ]# c* \# P% `1 N B
" f& B9 g/ M; }% W LONG m_nAsyncFindHandle;# P$ b v& C4 L* V
bool m_bCOM;* @! r' {+ Q H1 r( L1 C9 ?
bool m_bPortIsFree;
) x4 {6 Y9 H g CString m_sLocalIP;
: K) Q d: F& o; q4 p7 d! X* X CString m_sExternalIP;9 o& u7 n5 ]! v9 C: f: I
bool m_bADSL; // Is the device ADSL?
% C1 N& A1 P$ Z4 [' @, R8 B bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
+ t+ e$ Q& v7 @+ Q! P. o bool m_bInited;
* X( T9 l% t- A$ O. `' q bool m_bAsyncFindRunning;+ E* X, V! d7 @) n3 N' F9 |
HMODULE m_hADVAPI32_DLL;& e! e/ x7 G0 j( f# i5 S" o& w) ^
HMODULE m_hIPHLPAPI_DLL;3 ^4 s/ G- T. v- E
bool m_bSecondTry;& g& v' o4 M" [- J8 S
bool m_bServiceStartedByEmule;; h3 ^" a. L* V5 x& n0 Z2 l2 a
bool m_bDisableWANIPSetup;& p1 `" T4 b& R1 c& v" ~6 c
bool m_bDisableWANPPPSetup;- M8 H9 y: a5 I3 S* t
- z' `- R( D9 X# v0 z7 y
4 [2 a* v" i- Q; Y* d
};
3 R: D$ S) {9 V& q: L( S4 c7 F9 u# ~$ J8 X. n
1 N; _# `7 O2 K4 Y: l \
// DeviceFinder Callback
2 o$ i+ @. N3 C8 I% gclass CDeviceFinderCallback' m7 B7 l) L# i( J5 y' Z
: public IUPnPDeviceFinderCallback( @5 L' n7 b' v" k, N- {' v
{
+ `6 D5 M$ O9 R6 _! Wpublic:1 \0 n: F5 n, Z4 @) C+ L
CDeviceFinderCallback(CUPnPImplWinServ& instance)* |' t' M2 J: L l0 e9 s9 X
: m_instance( instance )
- f j5 c3 g" p9 n { m_lRefCount = 0; }4 _! }/ K$ `& ?! [
! ?. { V; o8 i8 d0 c
( k! {' w& H) H( a) A STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 ?1 v# k9 R/ ?8 o STDMETHODIMP_(ULONG) AddRef();
; B4 _- I6 W, J+ @6 l7 o( k STDMETHODIMP_(ULONG) Release();; W) T5 p, s o: `! S2 T. t
- r, |; @5 t$ G( s, m
& L' t$ ^- ?1 p4 H// implementation: W- k% y( f+ D
private:
# T/ ]* Y3 u8 B HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
4 H! X+ y7 p& F9 o HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
( t8 e2 i/ }3 u% v- ? HRESULT __stdcall SearchComplete(LONG nFindData);
% f1 M2 g# x q( _1 O7 X! {7 F. X2 _/ P# i; |" `
; O5 K9 i, d P" i3 M
private:
1 r8 ]4 z ?: }7 H3 r$ t CUPnPImplWinServ& m_instance;
4 f8 b b+ X4 g& X LONG m_lRefCount;
9 F ^4 l2 u, L! j- t* B; z' m2 N. s};
, [; N' X! W0 w! u) U d% u9 j/ w' {
7 S) g1 f. n$ e" w" M// Service Callback 9 J* n7 ~7 }, X/ s* U; b
class CServiceCallback4 V& p) U c: n/ S
: public IUPnPServiceCallback
2 N; @4 ~% T! d{! R/ g0 A( x% ?: |5 Y
public:! M; L* B! A* u! K( ^
CServiceCallback(CUPnPImplWinServ& instance)/ I L" E. k7 b
: m_instance( instance ). _0 ^, ~' ] u( y2 T
{ m_lRefCount = 0; }: Y, T8 _$ P1 w" v! \# V
; P( o3 g; [( f7 b2 l
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ r. M8 x+ x/ v% J/ P$ w% `
STDMETHODIMP_(ULONG) AddRef();: Y' V0 z9 P' V# [. h# D' m' \" I
STDMETHODIMP_(ULONG) Release();4 {+ u; I" b v# M
7 \! A! I+ g. ?' m! n+ z
; i- T! b2 l! X, Q, ]1 o% M// implementation9 T5 }4 s0 [- }; y0 N, m2 L2 ~; h. Q
private:4 [+ e2 c8 g9 r# Y2 u! B% l: n
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; p8 I @5 T0 o7 M HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
* t4 B7 I1 L* z$ `( w' N* P" [$ u1 w6 |3 w/ k0 Y& |, X% e; A
5 i/ t, V3 M/ _$ U' G) cprivate:
6 k% R, [% G% `0 m3 Y; l$ ?9 Z. l CUPnPImplWinServ& m_instance;
( V: ?# R/ y' E2 }( J LONG m_lRefCount;) Z( M1 f5 t" j N7 h
};" B! A _. c4 m. ?9 s) B. j' a
+ s; |) g) s6 T+ B; b
, ~; V; E1 x; a7 `" ~2 v# H/////////////////////////////////////////////////
g U. ^, R. P" {
+ W g3 K9 e+ e5 X% i, S; l8 y% e u6 @1 C9 d
使用时只需要使用抽象类的接口。
; X( B# U1 ]0 t2 MCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
) y) R% L, _% v8 @CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口./ M8 f( K3 S5 ]! y. [" E$ G
CUPnPImpl::StopAsyncFind停止设备查找.
8 \# u+ C6 a# m0 BCUPnPImpl::DeletePorts删除端口映射. |
|