|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: s/ C* M7 W; X* E7 l/ G( j$ q) L& F9 o) e' m
+ ~% H. }3 \/ q F* X///////////////////////////////////////////
+ y C' ^, L- u# ], x% ]/ A o//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.3 C+ _5 x' f, r4 D; X
- X; L7 w9 B0 ?0 x1 S; O9 e/ }, T" f2 E% k: s" _
#pragma once
/ q# g% r. B, N0 {; l# o* `+ i, b#include <exception>
+ H, C9 J/ t# d- h/ J: Q
, ?+ r8 \( T" s& W6 v( q3 j, [9 U
' ~& a. ]8 T" N' w. q8 y2 \: I enum TRISTATE{) v6 D3 G; r- g) w( u% T
TRIS_FALSE,- W# `4 j$ p2 f# x1 h( T: }
TRIS_UNKNOWN,; w$ P5 A7 H8 E
TRIS_TRUE
( a3 Z' A& w- C6 V* j' Q5 M9 W};5 s& i: y: Q8 f* x
6 b+ j6 G7 X8 a2 Q$ F+ Q
* S1 T& ~( B+ R$ renum UPNP_IMPLEMENTATION{
& A/ M3 N" m7 }8 R4 { UPNP_IMPL_WINDOWSERVICE = 0,
* x1 z7 M* X( i8 z, {7 ]" k UPNP_IMPL_MINIUPNPLIB,
& s; l) h! q! j! ^9 g/ U: B UPNP_IMPL_NONE /*last*/
. K) N0 _' [8 N" _- p- u5 ]};1 ^5 z6 h: x# E, B" u# w: L% q
' n7 r1 ^. g/ X+ P) M) C* u
7 A6 I m. i$ C9 a- D! H- f7 H: G6 s+ G# s
H9 b" K" T c
! U4 C1 @4 u5 k
class CUPnPImpl
/ T* J+ N4 }) D# U V' s4 {{$ M0 v1 G! R4 S3 g( E
public:
, m* z. [# j& a2 S# E$ H CUPnPImpl();( f( C8 r/ P( U5 ?* F
virtual ~CUPnPImpl();" d' C, Y0 D: x. Q" S
struct UPnPError : std::exception {};2 g- @: o: I5 z- k
enum {% S, Q$ Z/ G$ _4 _, b
UPNP_OK,
' t5 y1 V$ s+ R6 ^2 S) r7 \6 v UPNP_FAILED,5 A* f$ j- R; m0 C
UPNP_TIMEOUT
2 c7 T0 d: w, J };/ v# F* T) u. k& Q
( S# h8 M2 v& p9 N! M! V" C$ z* w- k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
1 Z" V. z$ z& i' X, e: k$ H virtual bool CheckAndRefresh() = 0;
& A& Z+ t, D1 l& D9 C virtual void StopAsyncFind() = 0;" C# _! b; G' D, }+ G& c
virtual void DeletePorts() = 0;
8 @$ r+ C* n! U4 ], X+ O9 {0 n) o' x, r virtual bool IsReady() = 0;
$ a" ?! v$ K+ O9 r8 Z- G W virtual int GetImplementationID() = 0;
+ B6 b+ Q; S O- \ ~
% i* @; v8 [% G6 R1 S void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping0 w' U) ^# O! J n V( F! S
: S% C6 d; [% {' ]
: G7 ^. V# ^0 H4 c5 u" Q5 a2 J void SetMessageOnResult(HWND hWindow, UINT nMessageID);
, a4 c) f: Y9 c* j- F) E TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 @. p' n4 ]+ l7 f0 r
uint16 GetUsedTCPPort() { return m_nTCPPort; }
6 m2 d9 z, L5 b8 E/ A) A uint16 GetUsedUDPPort() { return m_nUDPPort; } $ `; t4 U ?: Q2 \% a
! L: _- f3 x1 m( i1 E2 Y l) y# X' V h5 c' L! g6 H2 r+ j8 A
// Implementation) a2 N0 k0 q( y& ]9 w$ K1 z" w
protected:; E7 E9 J# E) \; r
volatile TRISTATE m_bUPnPPortsForwarded;
/ z9 Q) K6 V7 Z, n/ q void SendResultMessage();
) C+ ~0 K# g1 r$ U! {& T uint16 m_nUDPPort;
7 N% ~( a c( u$ S uint16 m_nTCPPort;* ~5 a% N2 r" k" }
uint16 m_nTCPWebPort;
) K6 r6 e' O- M' Q8 U bool m_bCheckAndRefresh;# V1 P1 z7 m% W" h l
2 K2 q9 m4 @8 u4 [0 W4 T9 n
2 v% l6 U" J+ F9 o- l6 Sprivate:
* n! s7 p/ Q7 ~7 i8 h! k HWND m_hResultMessageWindow;; v& N8 O5 p# a" K+ M0 x- P
UINT m_nResultMessageID;
: _% Z. t k8 ?3 c) B
! w) e) n; G' R, l3 A2 Z/ @" q& U2 z; Z
};
2 N, {4 J) w v% c: J* l
6 N- x) r1 c- a3 ~5 }: @/ \3 K; e) i9 D9 f6 \' V" G9 a5 Y
// Dummy Implementation to be used when no other implementation is available
) _# g5 v3 b3 l% F& J+ A) Dclass CUPnPImplNone: public CUPnPImpl
: T$ O% J7 H; d4 x1 O% L{
# M, F3 ?* @# B7 E) Ppublic:
# R+ V1 [0 G- `' Y' S+ y virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
! x6 W; D" `1 V virtual bool CheckAndRefresh() { return false; }
2 d8 l9 D, t6 G& k) N( ^2 s! n* n virtual void StopAsyncFind() { }
; v# n* q! q* K3 e8 Y8 S virtual void DeletePorts() { }
f& b5 ^' _) N3 ?7 s virtual bool IsReady() { return false; }& f( @+ G) S- I }" ?
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }: v3 q- ^ a- G b( ~
};6 B5 C8 V' |! D5 J
7 h/ m5 e: f4 ?! J
6 F0 p* M$ @2 ]0 @
/////////////////////////////////////
$ G% \0 T' O2 M. X//下面是使用windows操作系统自带的UPNP功能的子类' o9 X% A4 {" L0 G
& E9 U+ R" B6 [
0 p( L! r2 ]' u4 G4 o% {3 a- C
#pragma once
' _! L$ {4 d; A' P* e! g$ R( _#pragma warning( disable: 4355 )7 Y1 y" H5 W: M8 U) U7 O
) I7 g. ]* I1 A0 ?7 w0 [ @$ j. \4 G, L- C4 e
#include "UPnPImpl.h"
I! P: T) E2 _# O# |9 `$ K# W#include <upnp.h>. Z0 Q2 O- U- e6 n, z
#include <iphlpapi.h>9 R. |, T% Q }
#include <comdef.h>
6 j- c4 L- S8 ~$ }0 l7 [# _#include <winsvc.h>
& n9 m* B& z. ?" n* I5 h9 }
# C" \, P, [1 M( F
2 z; z" x" W, v#include <vector>& v+ h% `/ d, r$ S
#include <exception>
" {' {' R+ r& Q! S* b8 H#include <functional>
1 c+ x4 u+ |# J# [8 X. y. w
2 } x' s7 s& q6 K# x2 ]7 v' l: d, T
, `: M& |& C1 K+ L/ y
, k' {7 ?4 ^2 D& G" S
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ f7 r/ V) C0 i7 A' ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
- K( P" C, U1 N! x; u6 ~typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' a- `* n0 [, f& w: n5 |typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;% ^0 |# T/ u$ n+ w6 h' r7 A
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;8 F& p4 |- H2 G' i; l
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
r! Z6 b, e2 q( U* i5 ctypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 U& L6 k. E& S( R+ @0 \
) _) l% \* W4 Q' u/ P v" o! Q- J- _, L1 X1 S2 X8 F
typedef DWORD (WINAPI* TGetBestInterface) (" X3 Q# z, O- `9 y( {( F6 k
IPAddr dwDestAddr,
. H2 k9 Y# V; q PDWORD pdwBestIfIndex
- W( R N c( y! [0 `2 O);5 `6 @+ v) a1 w' d% M" H
; F7 G+ W7 g# J8 ~- C4 w
, N% f+ S9 d8 Y4 T/ b+ c, _typedef DWORD (WINAPI* TGetIpAddrTable) (
, o+ F3 z' Q L$ C0 A1 p, v PMIB_IPADDRTABLE pIpAddrTable,
! G6 L4 z6 Z! } PULONG pdwSize,, J T' G2 r2 C; G4 p% R2 \' p% [; I& b
BOOL bOrder [+ Y) w/ l. ]" M1 Y& z# s' a
);
- t' \2 T i1 l0 O1 {! p1 T3 a' R8 C
/ q' X' |4 x% Y& c# W( o% v
typedef DWORD (WINAPI* TGetIfEntry) (; G6 @/ u- ]# A- g7 W5 k% F
PMIB_IFROW pIfRow) l3 K) _ I- w) G* q3 G1 S
);# ?& n, S3 H5 K& e+ U( a
/ d/ m" {$ d5 b6 b
] l3 C! U$ D# p: N8 lCString translateUPnPResult(HRESULT hr);
6 r$ Y% u/ A' V( @HRESULT UPnPMessage(HRESULT hr);% H5 t/ W& N' ~3 k$ j
I3 k8 i }0 L( T. p
~* y' C( P' P$ nclass CUPnPImplWinServ: public CUPnPImpl3 h' ?6 l Q+ z3 p" U
{' x+ Y" {- q0 I5 \5 D2 H# Z% y
friend class CDeviceFinderCallback;1 w4 r$ k% z) d5 }6 |
friend class CServiceCallback;
9 A1 J8 T# c- B) F, m0 O// Construction9 ~) |% e2 M* P
public:3 T, @, u% ?+ u! G; U q3 C
virtual ~CUPnPImplWinServ();: p+ `+ t: D; y5 W+ i
CUPnPImplWinServ();
! s( x5 Z1 D" i& k4 e1 D0 v2 c
1 J" B0 _2 T4 I6 Y ^
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% M" C2 D# y) E" Q) A5 V virtual void StopAsyncFind();
9 J" b" j; X, j) q- `, r virtual void DeletePorts();
/ @9 \ _, g j virtual bool IsReady();
4 G( @. A5 a. y- ]) X4 _ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 g& C# s. r' P: m4 s( X
) Q" K- `3 f" F: J
2 {! L, C8 ^* T* q: O# A // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
7 n, N- S3 Z" h; t, c' w( c) b4 p // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later P* q4 W; T0 D1 U
virtual bool CheckAndRefresh() { return false; };
7 a6 v* W) H3 A- b- v$ e8 L% b! I1 H; v
. u9 q# G8 ]; A6 r9 [, Sprotected:
" h: L% K3 E, H3 K: u$ l void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 {; V2 [- g+ a* p6 Y0 s! h r void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
! k! t) _/ @3 ^: z void RemoveDevice(CComBSTR bsUDN);
7 _" q: T* _1 t# ^# j2 o bool OnSearchComplete();* I% J, f j7 {2 z
void Init();
3 }& ~$ H2 \) L) K& Q' L8 y3 ^1 b6 `; G0 S/ C# Y# d
: f; \ H) G9 s+ E H+ ]: g inline bool IsAsyncFindRunning() 3 ^- Z) D4 a9 R; t {8 K% E2 T J
{
& H$ n/ q% l6 w# p+ Y6 x7 y if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
* s0 a# ^9 L# r% ^7 c6 S {
8 |6 j# n9 q( a4 h) e# N5 o m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 u% ~6 S. ?: q6 q
m_bAsyncFindRunning = false;" o4 \& |6 L0 {: H; L
}
2 T' c! r; Q2 i2 R( N/ I MSG msg;
# e, Z8 F6 u9 v+ F while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6 y/ ?6 B9 A, }$ R& o8 H# v {6 E6 L* u3 X) N5 d+ R$ H
TranslateMessage( &msg );
- `- g" x4 J& d" N- n+ p DispatchMessage( &msg );* I) _" H8 r3 n/ g- V
}
9 t0 M$ g. ~; K d0 e return m_bAsyncFindRunning;2 e' s- _/ I+ n! o4 F
}5 R6 u( b3 h' |+ b
, o, i' v- V( z8 H! |
, C+ E. h, F$ k) H, ?' u
TRISTATE m_bUPnPDeviceConnected;
# F6 ]3 v( X) y, S
; o: ~9 H) u4 M- i0 w8 R
: K+ T- _1 {( }% A// Implementation
1 M8 h- {# D, R3 L // API functions- p T' t. b; I6 }# K
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
9 G$ `& b% \9 z( Y, j" M% E SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
7 n- O0 T- ~ I4 B# [6 Z6 ?, P BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);8 V" |0 C# q; k; P3 i2 ~- y: d! {
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! ~% M+ e3 }- E4 E$ n5 z. z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);3 b. b1 |" p& @
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ Z2 g) e- j7 y( p" L1 Y: y1 m7 |) L' \( o W3 @
+ y( n+ q2 o/ } TGetBestInterface m_pfGetBestInterface;
q3 O7 V1 s& A* E2 L TGetIpAddrTable m_pfGetIpAddrTable;8 F5 C1 H: a- b% ?4 z, d1 H J
TGetIfEntry m_pfGetIfEntry;
% h! V* ?3 |. C2 e$ K& y! V
+ E# D: T" Q" F( ?, o0 v/ o$ n5 Y3 a& ?9 i3 J/ f3 `
static FinderPointer CreateFinderInstance();
! s9 a. p7 J+ y) v struct FindDevice : std::unary_function< DevicePointer, bool >
5 I- f5 _( }6 _' S+ v7 q5 @ {
. h. W( ^( R0 e) o9 a3 i# ` FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 t2 _9 W) V) g7 n
result_type operator()(argument_type device) const
% u, ], f; p& c* h, D( ? {
- w2 G' _" v/ O6 E4 E" ? CComBSTR deviceName;* y+ v; ?; G- r B- O! i v2 U% H
HRESULT hr = device->get_UniqueDeviceName( &deviceName );& s2 I! g; N1 u/ f( j: q
/ O( `& D, b0 ?* D/ \. ]- {# n- c, C: w- t1 ?0 {" ^& i
if ( FAILED( hr ) ); E+ T# v8 s) X z) h* L0 ?
return UPnPMessage( hr ), false;1 f/ }( x9 M# E x9 E" G1 T: Y
2 }; ^; q. ~* ]4 {3 F
0 L6 g) k6 p+ y3 C# b% T0 L: {' C
return wcscmp( deviceName.m_str, m_udn ) == 0;
+ a- q# H! c/ l, G8 R }9 h. b/ p( s: k: k
CComBSTR m_udn;
- _! o* d9 v- ?9 | };2 z7 G8 [* V: `9 V8 S o
; u# `. @( Y. H N7 s. W8 J$ m void ProcessAsyncFind(CComBSTR bsSearchType);) L. p9 X5 j5 a0 Y% ?
HRESULT GetDeviceServices(DevicePointer pDevice);* a m' Z) K1 I5 x4 x% g
void StartPortMapping();
1 J) u9 J! |0 N8 X9 L HRESULT MapPort(const ServicePointer& service);
6 X9 r( l0 I. M6 i x; Y void DeleteExistingPortMappings(ServicePointer pService);: ~, p% v4 r4 o. f2 Z8 k+ J* ?
void CreatePortMappings(ServicePointer pService);- p6 ^# |$ M6 R0 p8 {" M+ l
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ r9 n- n# x) T _, n
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 N$ E4 B; B; E/ S( A- u7 ]
LPCTSTR pszInArgString, CString& strResult);
1 r* B$ H1 W4 Y# b3 H4 ` void StopUPnPService();# G- N, c; s( p- ^1 p3 h$ X2 t
. B6 [. { T( F) n
4 p: M: z5 d) U' s# P+ s$ ~ // Utility functions: P" f& q) S: [$ S
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);( \- V3 |- K8 @6 u6 W$ |( o5 u* V- [
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
+ f1 C/ m5 ?# r INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 X0 _/ V$ `) C- T( ^& D6 t. d
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
( ?! M- U* s# r) z HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! G3 a' K9 _+ P3 r: Q; {7 X+ K$ ~& k/ | HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
; s2 y% N+ E% |8 _9 @4 P: n( B CString GetLocalRoutableIP(ServicePointer pService);" r# X+ X1 R4 U3 }9 \1 f* D5 m) e
: x. s7 e: k0 E o+ g
" g: r2 J5 j2 F5 X& q// Private members
8 @- s* u8 R$ T6 Y" w& ~; Oprivate:; f6 e+ x! W( T/ \
DWORD m_tLastEvent; // When the last event was received?
8 {2 k3 N# a2 a U; S std::vector< DevicePointer > m_pDevices;
. d( h, f2 P6 Y' @+ v' p std::vector< ServicePointer > m_pServices;! Z. o* o I) K2 E* e# Z3 {8 z
FinderPointer m_pDeviceFinder;
3 p3 {2 v" k; I- M6 H9 y" d DeviceFinderCallback m_pDeviceFinderCallback;8 [. v. M. Y9 `, g# D5 e
ServiceCallback m_pServiceCallback;
: q4 T3 f8 G* p; i1 N- x0 P R4 i5 s/ x5 L
. g, p) _/ o; k: o LONG m_nAsyncFindHandle;6 G6 ]# L3 T; N7 G! B
bool m_bCOM;& b! z6 ~% t' O; U; `8 j
bool m_bPortIsFree;
: t/ I/ a* b+ T. _ CString m_sLocalIP;
/ N/ E" M/ T3 y) V" A2 R, R CString m_sExternalIP;' m, H2 i4 B8 i, z: D
bool m_bADSL; // Is the device ADSL?
% C8 |, j N, F5 x" l bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ O+ E. Z. ^+ [& Y1 O7 Z8 P bool m_bInited;9 [, B$ G% e# X
bool m_bAsyncFindRunning;
# p5 N! g& b. y HMODULE m_hADVAPI32_DLL;" L9 o& ^1 E7 f, K; w7 J
HMODULE m_hIPHLPAPI_DLL;
6 s) |- Y- e5 S& F bool m_bSecondTry;
& v; f- `' r1 C) }& a bool m_bServiceStartedByEmule;1 U- U( m5 t: g+ a U2 z: ?
bool m_bDisableWANIPSetup;& M0 `+ w) B" V5 F4 b3 G
bool m_bDisableWANPPPSetup;
, h( w: P x$ D n- O( j
3 S6 f# o# s6 o! q2 h! y, R
* [- T! z9 i [! \4 K' Q8 E! B};* M% R/ ~! [" p; ^7 `( l
Z X! |7 N/ V* Z) u! }1 {' k F& W2 f. t+ Q" }7 t1 ^3 k: H7 _
// DeviceFinder Callback
7 k3 s1 Y' D K6 ^) qclass CDeviceFinderCallback( Y, O4 @5 o7 k5 h$ R* _1 [! ]
: public IUPnPDeviceFinderCallback
$ {# N' l; L+ e$ [7 G+ K{: P l3 e, _0 W# q( E
public:
: [7 M* D5 M' |' r CDeviceFinderCallback(CUPnPImplWinServ& instance)
4 s' N; ~1 J$ s% c, L: [4 X# d2 _% k$ r : m_instance( instance )
+ E3 I9 ^ P$ O/ U( f3 v4 [ { m_lRefCount = 0; }; O" s1 e& i e9 E0 u- G2 ^5 V; K
1 s- o' o8 O: {2 E
: ]* U. i* ~: x m$ U, X( L
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 D. u! F/ h9 w) y4 v' s, o; N7 U STDMETHODIMP_(ULONG) AddRef();
7 g. [/ O# b w- ^4 D STDMETHODIMP_(ULONG) Release();
) ~/ \% N" x# N* ~ s" Q- y4 k- D5 ~# l, r7 u% w$ E
! s* H' W4 P- H- q// implementation& r; K# `4 X+ W$ d& _; ~* c
private:
) ?6 H" L3 m; G HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);1 v2 R/ i$ N+ ?+ Q$ k
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- Q& \( Y+ a+ Y4 C! n& U ~
HRESULT __stdcall SearchComplete(LONG nFindData);
% b6 b/ z' U. [( [
9 D% i* I) Q5 @3 x1 Y6 J
( F. k2 y; t2 L% L; E( y' d5 Iprivate:( c8 L. _& n$ @7 }* q9 u/ r
CUPnPImplWinServ& m_instance;* t# [4 I$ S3 l
LONG m_lRefCount;8 A& A; M9 x' ^( G+ B
};
- A5 y" l. N' \( k! ]& l4 B2 x Z5 {! r7 G1 S4 D0 U
# W" G' z; c. O, i2 Z
// Service Callback
) E& }( J- J/ F) jclass CServiceCallback7 @* y2 k$ L0 ~5 l
: public IUPnPServiceCallback
( d9 C- _) Q8 A. a- z, Z{) p7 p r2 n: z; D# Y, s
public:
% u2 h) E9 ]: G8 F! i/ ^2 p CServiceCallback(CUPnPImplWinServ& instance)* J, M5 G$ y" i2 B
: m_instance( instance )
" X: A( {& V* F) t2 A1 R { m_lRefCount = 0; }$ c7 k2 B$ u3 c
5 |/ @" M2 S- H
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- q0 ]' i, L2 T4 H1 k
STDMETHODIMP_(ULONG) AddRef();4 `; Q& y' C7 c2 }
STDMETHODIMP_(ULONG) Release();
v }( a1 n p9 A0 J
1 [+ L/ H b* E' y$ G' `9 F3 Q v! j! _
// implementation% Y1 q# C! W$ O- K1 H
private:
: o$ B: d! _1 g; w. n HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" _# e! Y5 `* N' N$ ~) s
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);6 x9 o- Y: I" Q. I/ b8 n/ I2 W
9 e/ }4 W) H+ ^$ [7 v) p! N
! w# \( w7 J& m; b% M9 k2 Eprivate:
* Q0 T3 | Q8 ~- F) q; K9 {) a6 W CUPnPImplWinServ& m_instance;1 ~: ?" C3 J. `0 m7 ]
LONG m_lRefCount;; V& t U: s+ g, I7 p: d4 |
};( z, Y1 X& p k \% C
' L& r% f/ v* H& p; s' l2 Z) F# Q# \
( c1 \/ A( ^1 A" _ s" ^3 j S/////////////////////////////////////////////////
0 K9 }/ D- p9 g9 }
* Z/ _, ^) m) x3 z& V* Y1 k# I) K! O& ~, E4 M- g
使用时只需要使用抽象类的接口。9 V6 v3 n/ b- \6 L% @
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
. b, ]& \/ ]# q; k( Q5 k: v7 c% MCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
$ q8 ~- `. o4 d U0 U; ~CUPnPImpl::StopAsyncFind停止设备查找.
. h4 |3 U: |4 vCUPnPImpl::DeletePorts删除端口映射. |
|