|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
8 T, {+ N+ q) r& o, k2 W+ v+ P' O: W1 ?; z2 G4 B+ ]
' [6 S. z5 `9 _( T1 Q
///////////////////////////////////////////
8 `' Q, \. f! B$ H @+ l/ q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.' E# H9 s4 E* s. k; d/ y4 u
# ?! g: p: S$ b, l. f& e& }2 [' `$ \5 V
#pragma once
, {5 n$ I$ H5 ]/ r" e#include <exception>4 A* v9 Y" e$ d) S
5 ^! J8 O) }+ Q1 B- w, P
8 v; Z0 Z% G: b' q6 g, F _8 c8 i
enum TRISTATE{
2 M N6 v ~% p2 z, I& l TRIS_FALSE,
) a8 r* J% a) B( H4 @ TRIS_UNKNOWN,3 Z' C* B4 @9 T3 p8 `
TRIS_TRUE
8 L( _6 m8 {" X! I};3 s3 P# V, M) x% r& T) @
( L' r: i8 e" s' U1 E
7 e5 M) e I3 c: m. a2 C: I. G
enum UPNP_IMPLEMENTATION{9 H: }% m. X* m: T; y
UPNP_IMPL_WINDOWSERVICE = 0,5 d/ L) n/ q4 s6 ^# T8 O
UPNP_IMPL_MINIUPNPLIB,1 X. @; R, o% U! ^$ R A
UPNP_IMPL_NONE /*last*// W" h- Q1 ^$ L& m$ b+ U; x4 b$ P
}; ^9 q( n& d7 U
! K+ z! `% y E' U3 u; l/ |
D& x4 G& Y- h, O& L) D2 o5 M) e/ S
; k1 N/ v8 |2 L( v4 \class CUPnPImpl
- W. a" }/ t! n4 U4 a, q" y{6 C! R$ [5 [4 c
public:) z# `' @& i) L% Q# \1 |5 ^, m
CUPnPImpl();
: h$ H, E" ]* T5 H) }2 x" M virtual ~CUPnPImpl();
( e: C# q5 B2 U g) \% f struct UPnPError : std::exception {};4 c7 o# B" C% ~1 e, P( T; O
enum {9 ^! g4 |9 H! t8 C/ X* J
UPNP_OK,6 Q; m! Q0 ~+ L* {7 E
UPNP_FAILED,
" x6 C" \& C$ z4 l' o UPNP_TIMEOUT: B/ @. O1 H+ B6 C' V q, }
};
" D/ ^5 D" E3 N7 Z; B; w R l) c a0 ]" G6 ~' u$ e. c8 r# @6 M
5 f8 p% ?0 W N! b, d$ A virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
: ~: r1 m& v# S+ `" `7 s: f virtual bool CheckAndRefresh() = 0;
2 _; f( U1 q6 B# x F: E virtual void StopAsyncFind() = 0;" U q2 M3 ^: @
virtual void DeletePorts() = 0;* b' F& a4 F7 B& b
virtual bool IsReady() = 0;. [8 n( a+ e! P7 M* p7 i
virtual int GetImplementationID() = 0;3 T" @/ G( F% B2 T% r
; l; T6 s5 B3 P$ z! O. L$ { void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" Q1 [1 K8 n9 [. \ k
& z0 N2 D; U( Y; c- `! s: u
2 @' s# [7 K* H) {
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 O1 H/ [6 F$ R: B7 e8 u. Y9 c TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } ~. V* o% {, {* P3 P H
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- j; G7 A: l/ F) { uint16 GetUsedUDPPort() { return m_nUDPPort; }
. [* J- `7 m" m! j% u# q+ H4 r- N( T% B5 x8 x' F
% p% |' {4 B: _8 V// Implementation
2 h' m" q" y" ^- ~1 O6 r. y% \protected:, c% Z, d7 [; R
volatile TRISTATE m_bUPnPPortsForwarded;3 f5 u# q7 X! h2 f4 i( Y
void SendResultMessage();' O3 {$ O8 m% x, p4 l) h+ L
uint16 m_nUDPPort;3 o5 A8 M* Y4 D+ }! `2 B& X; }
uint16 m_nTCPPort;
b" R* S+ M/ T/ h U; O( } F uint16 m_nTCPWebPort;
& v) q* w6 t3 q8 m" D/ R6 H4 t bool m_bCheckAndRefresh;! s% Y. v; Q4 |/ l
2 z: S% S0 c- i! ^0 X# ~1 D/ b" z) j5 l& @) ]" I' X3 D
private:; I( d& j3 ^3 X& Q7 v0 E/ W6 h N
HWND m_hResultMessageWindow;
! G* N& a& _, J1 R% ` UINT m_nResultMessageID;% g) p$ D- R* i/ Q& F/ Q* U% u3 H
0 j( L4 R# s) z. H
( _ ^; H F! H
};9 e& H+ r" G! X; Z
4 M8 `$ W! w/ w$ Z4 p6 _/ h6 p7 ]
) q4 ?4 k. V1 O9 g// Dummy Implementation to be used when no other implementation is available7 Q( {; l" e+ Z, f
class CUPnPImplNone: public CUPnPImpl
5 G+ ?2 x* j5 z9 h7 v. v& E6 Y{
/ m; X' y: p4 Y' @% _% mpublic:/ [0 I [* @6 t2 B
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }+ g/ H; i% ]: l: h) X
virtual bool CheckAndRefresh() { return false; }
1 T2 d( X6 P0 C! ` virtual void StopAsyncFind() { }
) @5 |( |2 x' [7 t virtual void DeletePorts() { }
8 @' ]/ s# v" b! _ virtual bool IsReady() { return false; }* ?# b# i [3 J
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% u: \, `% l' S+ G: M( ^: l
};: S/ g0 [& {" n: y* B
F1 J9 H! w1 W% d% Z8 v. i7 e4 c* O3 L9 @% ]5 x! [+ @
/////////////////////////////////////
6 N9 M3 f O: [) X* j V//下面是使用windows操作系统自带的UPNP功能的子类3 B, [: p( j" ?
0 _# S8 O, G- a. p2 e! o
* p' l( u' l a) y* o. J- N#pragma once' v. H) Z3 X' W4 C# f& r e$ j
#pragma warning( disable: 4355 )
" S; j' X6 Z/ x H* T$ f
% H* f6 H- Y6 H3 u5 U9 f
9 m" v- ]7 `+ t. v: x W/ l#include "UPnPImpl.h"
3 V' D t X2 ^6 j0 \! T$ J% _3 l#include <upnp.h>
) r% E: H3 }/ Y. }#include <iphlpapi.h>2 k: D9 K- O; r- d( K# W& _
#include <comdef.h>. l1 ?7 P' `# P4 I
#include <winsvc.h>
# a' M8 i& y3 M% K, R- C! s8 a0 @
& {+ j/ G$ Y8 o4 o( R
#include <vector>
4 D( `/ Y) M- f* [" t#include <exception>/ a6 i+ }8 E$ I2 _' \, j1 R5 l
#include <functional>5 p* U3 p' M3 o# f) X) c9 x/ @) S
0 R/ Q& O9 ?# ~* |- Z! Z) D, D, k' w- }1 `
% [# V. I, D! u4 k0 S
. H0 @- v9 c0 E5 q6 Z" `
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
5 ]4 H, e# d- d4 B% q6 Ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;, ]8 k9 Y. G% u) G9 d( N; u
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
& Z% ?, t% g& @, R5 s# d' T, ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) \" c! F/ |* J8 @/ I9 ~
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
4 J. A# i) Z+ Ctypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
& k: x- l/ ?' K! \! ptypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;. f# W) o- C& G* B; @
- T8 |. K9 @; ^% l3 ^
- H+ M3 E2 n2 ^. z3 Xtypedef DWORD (WINAPI* TGetBestInterface) (& }) o/ \# f8 i) V8 [" |
IPAddr dwDestAddr,
. `! W* c) Y4 `9 i( _$ n PDWORD pdwBestIfIndex
2 |) j* K) i8 ^: O);6 o! p$ x- p8 i6 } C
0 B0 @* }4 u' C, L$ @; C5 b
, E! _* ?1 Z2 q- V/ _
typedef DWORD (WINAPI* TGetIpAddrTable) (
# e3 G$ V" M' Y; R. { PMIB_IPADDRTABLE pIpAddrTable,9 [* t! ?9 a4 A
PULONG pdwSize,
9 b- L; G1 |& a BOOL bOrder
9 X$ e9 ^; |6 x);
) v1 I) I' h0 \& M* C1 w
2 h0 t: W5 q* A2 `9 _; a9 M: t8 V3 y9 z( i! Z) v
typedef DWORD (WINAPI* TGetIfEntry) (
& U7 M% Z7 D1 }$ R5 ^: m PMIB_IFROW pIfRow; M7 l G" E# F3 E& a8 A
);
% E% z! f5 A) j$ [" [0 j5 g% ?. I
/ O, h7 P' \# @1 f& l, A* t6 [* i: }$ |) g. {7 x+ U0 k7 T
CString translateUPnPResult(HRESULT hr);
* x9 r1 t8 u" Y% \. O7 ^. `HRESULT UPnPMessage(HRESULT hr);/ [# r$ Y8 a, x$ E
; l& H( o' M4 u& B. w0 J* {
X8 Z% T8 e" Vclass CUPnPImplWinServ: public CUPnPImpl
- o; Z# \/ W2 ?$ Z{+ a4 u/ @- ?5 w8 W
friend class CDeviceFinderCallback;
) ?0 I8 ?# p) o5 K6 L( G V friend class CServiceCallback;% R2 N% W# O" {4 B7 O
// Construction
" G+ g ^1 s( T( Mpublic:- e0 j" c8 l' k$ w2 f% i6 m+ e* i3 `
virtual ~CUPnPImplWinServ();7 ], g3 [9 O: J, d7 y; `7 N- M1 h3 ~$ P
CUPnPImplWinServ();
$ \3 E. k' G5 l9 V, `3 |4 N' ^$ V5 s+ Y& A
- V2 p" `" C, ?, H: l, _( f5 m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
* d0 n8 I6 a" v9 J/ f7 B5 k virtual void StopAsyncFind();' s! k% a& V9 u. W5 N
virtual void DeletePorts();: _; |$ n* C ?& w! r2 G
virtual bool IsReady();
" T' [6 `% B! L+ a virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ c7 M& S8 i' `$ j& `' v
: A7 X7 ^" h5 ]; {7 @
5 O$ }$ t2 [: q
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)# M4 m$ c$ j- h
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 u" D. \2 b! ?% E virtual bool CheckAndRefresh() { return false; };; l- M2 c5 P# e; f# G s* \
/ y) E& i- @, P; \0 ` J
: }: k9 Q7 L. ~, g3 I, s7 I; i9 J) T, Iprotected:
8 B' C0 Q O2 B# P void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
, r( ] @; H! X) c void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 [/ D1 y) Z! F* `- Z r/ ^. g void RemoveDevice(CComBSTR bsUDN);" c( j5 J4 ?) \$ b; f
bool OnSearchComplete();; F* x$ }* g7 r; e( Z
void Init();7 l( {; H6 ~" f* i. F/ v
5 [( _% m! }0 v( J4 q
$ D0 q6 w% m6 q4 G/ q/ ^ inline bool IsAsyncFindRunning() ( Y2 c& T" v; b* Z
{
9 k$ D$ M4 b& n2 D( g if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
9 Y6 _( s" }4 c: ^ A {
# \" N; ]3 ?" I S m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
' l2 f: A8 i2 y. C0 y, w3 E: Z m_bAsyncFindRunning = false;
- c) r# a2 q2 N' C }
`, W, `: E" e) S MSG msg;$ T3 B' d( e7 d% |
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )( c" u( L3 z' Z& b
{. N) x, ]& u# t$ w4 B4 ?, T
TranslateMessage( &msg ); y8 o3 h4 n2 Y3 ^) N2 s
DispatchMessage( &msg );
3 a0 `; n5 d' J# U) @# x- Q' @5 | }0 D% [$ h3 {- j* B
return m_bAsyncFindRunning;
, H8 @9 t" A. u/ x6 D5 t( y }* G6 s- `" s% m2 P5 V) d7 E* ~5 N
2 Y6 W/ g, k$ _
O( E+ H& ~$ ]2 A o+ c TRISTATE m_bUPnPDeviceConnected;: |9 V- H/ E; E
3 ~' @! s# T9 z& A% ]$ S0 k& ~8 x9 A
// Implementation
0 H9 T( x$ p: z* P |( r // API functions! P1 u. K/ S0 D4 u4 K
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
, O( n' Y3 k% F' ~1 E& ` SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);# m0 M& A. f, E2 y: p
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
- I" y8 r9 l$ f* u$ g; ~, q7 M BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);) D L2 n* ]# S6 G3 T
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
' ~- B+ H6 N' B3 a* j+ U2 K BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 G; h A& o! `0 p/ `0 j) s* e5 T& W \
~! a8 z& M4 N. p6 u p* {2 b
TGetBestInterface m_pfGetBestInterface;0 w6 J$ k# Y# F [4 j7 L6 |8 C
TGetIpAddrTable m_pfGetIpAddrTable;
% v1 Q( o# U& ]. `! o0 _ TGetIfEntry m_pfGetIfEntry;4 N' p5 ^3 N1 W# {
( r$ y" i+ |4 b7 K5 }7 Q9 w8 Z
5 z5 h% q& } S( X6 E. p
static FinderPointer CreateFinderInstance();
- `. w/ H5 [$ m5 O* ^. b1 J struct FindDevice : std::unary_function< DevicePointer, bool >
; T; G1 t5 X- P' P% O; p. x, n' R {7 |3 e+ s5 t, T, r& L- n9 k
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 ]' q4 c: a' [3 [7 }* w* o @
result_type operator()(argument_type device) const
' n3 ]9 L5 s% ^' N- ~ {) o# W% A5 i# a* d
CComBSTR deviceName;- j) d; M$ y8 F: F0 d5 L! E8 b
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
9 m. B2 m ~: |0 m' g+ N5 g& v: j8 H4 l% f/ \' g c1 x
' m! N4 u' }6 `9 g if ( FAILED( hr ) ). b$ T! n- J! O$ c
return UPnPMessage( hr ), false;! L: i; d D7 ]8 Z
7 R' c8 L/ ?% Q6 J9 n0 g w F5 m" z
: `) x4 x! a; N9 d a2 I' C return wcscmp( deviceName.m_str, m_udn ) == 0;3 d5 m, |" B, {" s! `+ Y
}! [, \. s) W. M4 ^
CComBSTR m_udn;
1 w* ]. m$ x/ p6 U! l7 Z* k };7 ~* ^" s) a# T' |) t5 r; L0 t9 Z& q
+ E0 p* j2 H' \3 Y! M* g void ProcessAsyncFind(CComBSTR bsSearchType);9 R3 R# Q) g7 |! M0 k" s8 ~
HRESULT GetDeviceServices(DevicePointer pDevice);& T5 [$ ^2 O; q5 a* t2 O* G
void StartPortMapping();' s8 T! w* T9 B$ F) O
HRESULT MapPort(const ServicePointer& service);
3 x; F1 Y0 F- \5 { void DeleteExistingPortMappings(ServicePointer pService);) H3 g1 ]/ x1 X- `7 t/ _1 ]6 O. D5 k
void CreatePortMappings(ServicePointer pService);
! n4 Z" w7 T! f! ]7 i, E9 N& V HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
p* F: [0 t, F, b% e HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
+ e" E, ~! C' r( r: w LPCTSTR pszInArgString, CString& strResult);4 G, n3 n6 Z% ^9 p
void StopUPnPService();: w8 X( A v+ w2 l* W
# T7 d5 ?9 }1 V$ ?9 ]3 O9 K
* N1 J; h0 @) v: c // Utility functions8 B; N9 B5 [, m- R( t0 b0 T
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);' ~1 u% z. ]6 |4 ?$ T! X
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);1 t! ~) H' W) e5 ^. z
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 [5 w1 H5 S- R% H# L) ^ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! j' i9 f, _ w X' |; g& }/ p' t
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
( j$ n: F5 y7 X3 ]* t* l HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);) Y6 z8 P9 K6 q, _9 M: E- S! \
CString GetLocalRoutableIP(ServicePointer pService);
" t, _; g6 o4 N+ O3 H8 h
' G0 a3 Z8 |) C! n$ L) Z2 m# e) M1 s7 e5 x, {' G
// Private members
. m1 C G+ S$ rprivate:$ i6 ~# n& j$ u& t% o" e7 g
DWORD m_tLastEvent; // When the last event was received?
+ q% W% T9 Y' f( R# }/ Q. i std::vector< DevicePointer > m_pDevices;
5 H9 F+ K* x5 F- r std::vector< ServicePointer > m_pServices;2 X! Z, ?- [5 M8 C) A8 p
FinderPointer m_pDeviceFinder;
3 e, z+ x3 p& a# w$ Z) k$ U6 D DeviceFinderCallback m_pDeviceFinderCallback;. o+ q' r7 J7 Z" a' p7 @0 n& `* Y* `$ s
ServiceCallback m_pServiceCallback;
4 l7 |- j6 U4 E9 R, x, b% S, D: \' t/ t- X- G
( W; v! c" a" p1 s ^% p. F LONG m_nAsyncFindHandle;
! j* { L: J& V' ?' K! c% Y bool m_bCOM;, V/ P0 D3 o( T% M/ {( F2 G
bool m_bPortIsFree;7 P# [% i. C$ T7 f
CString m_sLocalIP;
0 P' M3 x4 `1 H$ u2 c+ U CString m_sExternalIP;' b$ }+ i' t. y" T) T/ y
bool m_bADSL; // Is the device ADSL?0 N4 |2 A# K0 K1 C, m
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
, ]' k" ?8 V) v" H7 G+ ~' C bool m_bInited;
# u/ r; R3 @3 \/ n) x' A) ^5 { bool m_bAsyncFindRunning;
0 D c; a) ~% {- a. U HMODULE m_hADVAPI32_DLL;, R0 `' z# S2 G8 O' v. P+ b2 ?
HMODULE m_hIPHLPAPI_DLL;2 g( H1 `, f" u! H0 r( a4 |
bool m_bSecondTry;
$ G8 `- n- V/ O! v' t" y/ \/ W bool m_bServiceStartedByEmule;1 {3 v4 @% M2 } B% h$ t* c
bool m_bDisableWANIPSetup; c! Z8 {) `. R# F: P" e
bool m_bDisableWANPPPSetup;
, ?2 x, e4 J" ~6 T) |! j; s, x) `: A( Y4 P
6 ^9 a, |, i* B( z6 e};
6 `8 r/ [: R( W/ _$ `/ N# M& x6 ?# z! O4 O
! y3 ~) M. l. S( r8 t y! `1 `$ P
// DeviceFinder Callback
# n$ R+ d/ K( n) j5 J% tclass CDeviceFinderCallback
; ^2 a3 c! s9 O1 ` : public IUPnPDeviceFinderCallback4 I2 l$ x) k* x" `- O" O4 M; b
{; C# M/ k0 a* x/ y; t
public:
# M6 f' Z( u3 g z4 v CDeviceFinderCallback(CUPnPImplWinServ& instance)
! S! y$ I& k/ q O/ T- U4 r : m_instance( instance )8 a# k2 S: D/ H$ v1 ^$ L: }
{ m_lRefCount = 0; }2 E/ w9 S* t% }/ R; V( i+ S
# ~/ G' W+ r1 L# |% j8 @! R) W
; d( Q9 o/ t& J% i) ?4 r STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); m4 w- F& V) @; A
STDMETHODIMP_(ULONG) AddRef();# r: f M& S3 ]+ M
STDMETHODIMP_(ULONG) Release();
% N' E" `% o1 u& U; W
: m0 k% P! K8 ~& F+ `* R% d/ c9 X% E! s& J
// implementation0 \- Y" ?: k' [$ U
private:
! h( R* C3 x$ r# k- R; z HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
) M3 S& v# h3 Z8 v HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); k* \* n+ R9 J, E
HRESULT __stdcall SearchComplete(LONG nFindData);
' o5 B* T) r9 t4 o9 S2 q0 I( S% V( i4 ]! f4 m. g) f5 r
$ @. W' e. f. D3 y7 c" d* P
private:
2 p8 A% ?# H/ P2 A* l2 r CUPnPImplWinServ& m_instance;; |$ ?" |& J* j+ _9 b( e
LONG m_lRefCount;
& R+ D% c( r2 P5 r" }! b# e};6 T" @7 o2 B# T9 [" v
" v( } Y6 }+ \6 O" B
9 r# n3 @5 u; n% Z// Service Callback
Q! h0 j4 X! t- Gclass CServiceCallback* x; K }" a L, h U
: public IUPnPServiceCallback3 M7 S, A ], b
{$ L( m; l) D/ F- m4 v( o4 R! R$ {
public:
% [! ?! F0 x ~1 `" p CServiceCallback(CUPnPImplWinServ& instance)
4 o9 x, T" H/ {# Z: u. v4 i : m_instance( instance )7 r3 D* \% A* ?8 o. ]
{ m_lRefCount = 0; }
9 X' g$ c0 }% P5 {
& n5 J" ]+ ~1 f7 Z STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% ~6 w2 A# g7 Q; S) R, t& `: L9 c STDMETHODIMP_(ULONG) AddRef();
) v& T8 I& N, `; R$ C" C$ y$ R, K STDMETHODIMP_(ULONG) Release();- p& Y- ~6 N a" h# x! p: g
) p/ z. p( B( W U
1 }% p0 ?+ D' y// implementation" N+ Y& T5 J7 l# p
private:
: k! B3 Z2 t8 \- T+ m" o HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 J- `- n1 c L HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);4 @- Y' z, T7 D) ]4 M5 |. }
4 `0 ^) u. j. v: Z
) v* E: b& s7 c; F) Gprivate:
" O7 I9 v3 H. U6 e# ]% A( }3 G CUPnPImplWinServ& m_instance;
+ S/ M* ]4 D9 ` LONG m_lRefCount;
8 ^% T) P7 r Y4 K. s};
5 X! g9 k3 b) e1 N5 ^- B2 O" s% s2 V/ m% p3 X/ K( J' m0 W4 B; U
' M% S! V$ F9 f9 ?
/////////////////////////////////////////////////5 m* Z' q% u* P! P6 e- k
' t& w2 @6 F. W
# W1 ^0 Y9 o4 B' Q0 n6 V
使用时只需要使用抽象类的接口。
/ L7 ]* J0 h/ W, A- lCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 A5 S8 R( |' r& f7 ZCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.& @( P9 g9 ?6 D
CUPnPImpl::StopAsyncFind停止设备查找.
+ v" o6 \# j8 h# O0 n- G% HCUPnPImpl::DeletePorts删除端口映射. |
|