|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,; t4 Q% |) m3 ]
$ q+ d7 A$ [* [8 F- v0 a
* }4 w( v P8 D" h//////////////////////////////////////////// ^& B Y. i5 q Q% E+ w
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- U3 h$ k F) N1 `! j$ |2 F7 _
5 u3 P) C7 c# u6 ^% m9 k( h9 E: i! i8 T. U* T" I9 c0 W1 b! O
#pragma once! _! N& |: P3 e; m1 X' h% w2 `8 Y
#include <exception>
0 U0 l) i$ T: p7 z8 V4 E- y1 E$ t
+ S {! t8 K1 t2 D
% z1 D# q1 r- n- m5 I2 F U# K enum TRISTATE{+ ]9 m4 s& {2 y0 B$ T' V |
TRIS_FALSE,) R9 q u* G& R9 U
TRIS_UNKNOWN,
/ o! C, K; A; f( g. [ TRIS_TRUE7 ~! y, g3 z6 c+ e
};9 S2 R t7 V+ L( X: x% E% B
4 c1 v5 {+ \1 A! v2 j6 r; Q; |% [
* Z7 I* s4 I- | Renum UPNP_IMPLEMENTATION{
$ V! j6 h' `5 v" ^8 V- T UPNP_IMPL_WINDOWSERVICE = 0,
$ u- N- X1 r) \2 O3 q4 g UPNP_IMPL_MINIUPNPLIB,3 R# L d+ [9 ~' ?
UPNP_IMPL_NONE /*last*/: r5 l4 X* q" `+ F2 T/ z
};
# t L% [; @# T+ `: |$ m
! V3 W2 d1 F+ X8 H# ?( G- \. `/ X% V; n
3 s. y- y, v. e5 l9 r6 Z3 f: @! h( V: n$ V
class CUPnPImpl
% O' g; }: Y& t* F{
% O- P- n c+ B W5 W# D% P9 bpublic:
% T+ T- K5 O F CUPnPImpl();8 h9 W d( p# o! U! `8 Z
virtual ~CUPnPImpl();$ |% R1 \/ n$ L$ d2 i; ]% U' S: r
struct UPnPError : std::exception {};% d- Q6 Q4 l; o3 i- q7 t
enum {( |; j1 C8 R0 Z- I
UPNP_OK,
& g# [) R) ?+ J! K UPNP_FAILED," }2 X$ j: h% C2 R& D$ P, f" S, Z0 j
UPNP_TIMEOUT$ v" ~0 \) k, {7 t. U
};, e3 p! P# R$ o4 A! R
7 l. u$ }. E2 W; g2 b9 d6 |% M x2 }- I7 E9 }
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;4 R, O) U& H! M: X2 R
virtual bool CheckAndRefresh() = 0;2 ]8 ~1 O; X% ^8 w u2 ~. @3 @
virtual void StopAsyncFind() = 0;( a) E( ?$ T9 ^% P9 C$ I7 t! f0 n) O
virtual void DeletePorts() = 0;" m4 }. o3 u8 N& \5 o: Z
virtual bool IsReady() = 0;4 p }% t0 Y9 R* Z
virtual int GetImplementationID() = 0; C4 \5 K2 {9 d- h9 \/ G' ~. f4 U8 S
3 G, o& }) y. s! p! C void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
+ X) ~0 x4 F5 W# P4 r$ Y& P( Z" Y/ v. F2 Z. B& f2 g
7 S7 \" D! _! H; O0 P void SetMessageOnResult(HWND hWindow, UINT nMessageID);2 }: Y! V, Y, X+ @4 L3 H( Z3 @2 D
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: M! V( }" B: e! C
uint16 GetUsedTCPPort() { return m_nTCPPort; }. M+ c. G6 L! Y9 ^! E% Z2 r; j) S
uint16 GetUsedUDPPort() { return m_nUDPPort; } $ a+ ~1 s2 ^; T5 P
# _0 [ q/ J n; }9 `
& W& {/ l4 Y" H) R3 t* S
// Implementation
2 X; q* X0 @0 w% M* \protected:
+ b0 G7 ^, B6 b# s0 w volatile TRISTATE m_bUPnPPortsForwarded;# w5 P2 }: k# G2 {, P
void SendResultMessage();
7 G2 S/ C% L1 _* z uint16 m_nUDPPort;- k T" j) O9 D% @/ ^8 y! Q: j( X
uint16 m_nTCPPort;7 T* y9 T* V6 a
uint16 m_nTCPWebPort;
% j* `+ L/ x% H Y bool m_bCheckAndRefresh;- r8 K: ]/ k4 y9 M# H. W1 p
' P" h9 R' c& Z$ v# B' R9 [- }8 A2 V- n& t( D3 s) g
private:% I* U: j) K2 U, u
HWND m_hResultMessageWindow;' p9 y( r1 A" B3 K' g0 ^0 u) R
UINT m_nResultMessageID;
+ v0 i- s4 ~ C' Q) y* I' c) I7 G) J! ^5 p$ ^
, T f/ ~; T7 Z
};" K0 G9 h! ^# S2 _) d
' i+ T7 ^5 z5 [2 v! }7 Q2 w) Z4 J; j, ` g% K0 ]( }
// Dummy Implementation to be used when no other implementation is available9 P t9 u7 Q/ a4 W3 [2 U
class CUPnPImplNone: public CUPnPImpl3 K, C4 K# K$ g/ Q, ?
{
3 u# O/ b. e; ~0 s- @" o9 S r0 C+ jpublic:
7 z! ^; K# G, r/ y& g1 a$ f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
; q* d' }/ p; ?: p" E, i virtual bool CheckAndRefresh() { return false; }) p1 C; a0 R1 W9 E# _' Z1 N( n, B
virtual void StopAsyncFind() { }
8 \* x4 H/ p, J+ T! x virtual void DeletePorts() { }0 ]( d$ o/ x+ q
virtual bool IsReady() { return false; }+ a& \" t4 \- l
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }2 _, z% s( s2 @* B
};
) p7 e% { O$ i, |# M# v# U. _+ `
6 E. T0 x3 {: I7 p$ p. Q6 Z. A/////////////////////////////////////
' m4 w. J' u3 S& ]//下面是使用windows操作系统自带的UPNP功能的子类: }4 q/ v7 g+ F9 v; J, E
& M0 x: ^0 e7 r/ f" ?! T% |9 \5 l
* U& J I/ Q9 ?3 o$ e! b#pragma once- D$ K+ L3 I5 h
#pragma warning( disable: 4355 )
- x! T. L' V; E. V
2 V( m4 u. S) P- R+ R7 I8 ~
! Y* H- H; f6 N! p#include "UPnPImpl.h". W" D7 O4 U, j* S! ?
#include <upnp.h>8 M7 I4 M1 y( d2 ]
#include <iphlpapi.h>
9 \9 `' Q/ P0 y/ h9 D( Y7 R#include <comdef.h>. ~7 M5 u. _; W
#include <winsvc.h>' `, i7 F& }3 z! _: Q
1 N0 h" G; `. x+ [1 k) d# O* p; A0 R/ X, D& y) K- i
#include <vector>1 Y: C7 F3 y$ S( k
#include <exception>
! M \1 {1 L! f+ Q& t/ t#include <functional>
+ I1 G3 [+ X. S7 v/ E: Q
) l" o4 [9 T1 ]/ R9 v( F# U5 l7 g: B+ C% }- ?+ o+ C6 m
5 j/ v; c# l2 E4 J1 j, T$ n& o
6 ]/ m. c* m: U( c h1 [9 ztypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;/ N1 w+ V t& D6 X4 \
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;9 ]. o9 ~/ [ s/ y
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
# @8 J0 c) z" N8 stypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;7 ^3 i7 q7 B" A
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 B/ R3 ^8 U/ a" a9 l
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 n# `% F, ^7 I
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;' h8 J. f% G1 E* e; W2 P6 q" {- F
; j' |" D2 _ P0 s4 K! h; @0 T; U9 M, g y1 Y
typedef DWORD (WINAPI* TGetBestInterface) (2 ?7 y/ o$ h" S# i2 } a8 }
IPAddr dwDestAddr,
# c) H, I$ Y( X$ Y% s' \" Z PDWORD pdwBestIfIndex' X- H9 O7 V, Y0 P
);
/ u5 t, {) j2 k$ h4 S; ~7 W# m* y! A. e
1 d" X2 e" |+ F* X
typedef DWORD (WINAPI* TGetIpAddrTable) (
& p) J8 M' B4 c. T' s# a- v PMIB_IPADDRTABLE pIpAddrTable,1 J+ ^0 d; M9 t4 U* p
PULONG pdwSize,
9 e/ O% a, \- u( w0 ~ J& j2 A BOOL bOrder
: B" ~1 t7 j1 z: p# q);
) ?( Y! b0 C+ F' @4 p1 R) ~! i
# W$ k7 b" D5 C, i
" x9 m; @4 s# J' L9 Z2 ^typedef DWORD (WINAPI* TGetIfEntry) (
$ W% w' M9 \- B9 M; x PMIB_IFROW pIfRow; F$ b" P9 l% S# c
);
" h- p8 M% D( j6 K) B3 L9 \/ L) k. k
3 S0 |* J6 S& _7 N" b, I( L
CString translateUPnPResult(HRESULT hr);* `* J7 i8 S5 ?$ A0 y
HRESULT UPnPMessage(HRESULT hr);
T n/ V' P/ j: `5 C% ]7 s$ u/ z9 \* I$ }
( M. l# J0 d/ g3 C. L7 {1 e/ U" aclass CUPnPImplWinServ: public CUPnPImpl
, |5 X( ~& p- R: z' ~* E# M8 ^! U{0 c- C; S4 j1 s: P/ g' M4 ?# u2 h9 `
friend class CDeviceFinderCallback;
- `; } n& I4 {9 `8 d6 { friend class CServiceCallback;
5 w5 Q- _$ i0 c3 s# Z// Construction0 ^, U, D: ^. {* k
public:
: X0 O4 ?3 r$ h9 r5 Z% X virtual ~CUPnPImplWinServ();
$ U: `' ^ l1 h* b2 N% n& t CUPnPImplWinServ();
/ s+ R# i( u, O9 a! j* B' h7 u2 ?8 b- n6 V5 j' `5 ?( }" J
* l7 J h. ?: }+ L2 [5 N z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }' g. U0 r0 G2 y8 ?- G6 g+ Y
virtual void StopAsyncFind();
, H3 T/ J" y& c( g v6 _+ N virtual void DeletePorts();4 \3 Z3 v2 d9 o0 e( Z2 u! V
virtual bool IsReady();+ P# L/ x' \# I: I7 t9 y
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
' W* l/ h, m7 W8 [- o1 Y& J( C7 E& k2 B# l0 d+ `
" Y# A! ?8 j) z
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)" J4 H. s8 A0 i3 B
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later) u; h( o; K9 C" m" R& \" Z1 p- P
virtual bool CheckAndRefresh() { return false; };- A) _7 _$ P- K; Y
! i/ ^& r, m1 r9 `( [5 v$ q$ H4 ~: c% ^6 ~3 p
protected:' V1 Z* [9 h5 a- Z k0 ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
. }4 l$ i7 P3 t) O K/ _ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
) v% Y# ?3 o O+ D* t void RemoveDevice(CComBSTR bsUDN);
" c) P7 o, X3 l8 o; T bool OnSearchComplete();
1 w* I0 h2 @# i void Init();
* j% `. h( u- O n, O$ T; o* w* [' P5 z$ s5 N. Q3 v. z7 y9 v
0 | A. @$ @; ^% S8 N3 Z! R: ~ inline bool IsAsyncFindRunning() G9 n* w1 B! X7 m! X; f. i+ W
{
! `2 f$ J) _7 o0 C% [6 H if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ), j2 G3 Q- W$ ^6 ~; F3 j1 V
{
- |, z5 J' e( n3 S9 m m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
3 N5 m% B# `/ j m_bAsyncFindRunning = false;* `! v9 u0 n2 K: v8 [
}# B# P- `* O6 L
MSG msg;
" d. m8 Z+ R9 }' v2 q9 e3 q while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
( U' O3 J( Z2 k3 f. u' I {, Q1 h }1 _- S# t2 y$ M
TranslateMessage( &msg );# m5 Q( W C' K5 N
DispatchMessage( &msg );2 N( H1 b( \6 W7 @9 D
}
! z' _) {4 V; q return m_bAsyncFindRunning;/ K: K+ i/ x- B5 e; Q3 N
}
% U5 i% ~. l) L8 P
1 g* s, K/ I# ^4 e8 w6 o7 z3 L' u& f L4 m" N- K
TRISTATE m_bUPnPDeviceConnected;0 M6 @, ^7 X4 A3 Y5 [+ L
, n. W% q @( d& X) I
% m# B" c& o' u1 N' c, b
// Implementation
0 [) Z! A7 h' }2 ^ // API functions& O& m8 g0 z0 q1 h
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' w( K; d @/ {7 X5 H9 h m' U
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);/ v+ d4 Z( m& l2 n, q5 r% h4 Y
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
, B C. n+ a6 N BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);' O6 ~* X, V3 x& a+ P" J% _
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 A) Y/ P+ F& C) K2 A5 v; C
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);1 H/ U! p0 m+ s
4 e* \' ^1 h$ A1 C
! v( a* u9 R, z TGetBestInterface m_pfGetBestInterface;
, V2 q: j2 b' w7 G+ s9 i TGetIpAddrTable m_pfGetIpAddrTable;
) d0 J: ?0 w" S0 g, w4 e6 ~9 Y% |7 Y TGetIfEntry m_pfGetIfEntry;
2 V: `' U; C$ M( E
0 a' o4 G6 i1 k6 v! T! {+ B' v. e4 w4 _/ d+ b& F
static FinderPointer CreateFinderInstance();
+ Z. x V0 x& ]9 o4 p5 R( x struct FindDevice : std::unary_function< DevicePointer, bool >7 v z0 A9 V$ D8 O5 P
{$ K% g, _6 w" P/ ^& G) ?
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}; i' O$ V2 N, w& A6 k- e6 @
result_type operator()(argument_type device) const* t' D' j0 n7 O6 d g; U
{0 H1 [ m" `$ p* d- o. l
CComBSTR deviceName;
- B) N4 r$ G+ {/ T6 u% Z* o HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 t5 g3 {* J4 j5 H Q; ?
! \4 r+ b. s1 G0 [ a! ]% U0 t0 G- D# w
if ( FAILED( hr ) )
N% |2 D. a) m8 Z+ Q return UPnPMessage( hr ), false;
5 }! m; }8 x6 |" v- [( | Z/ S) A, t. }0 w4 D3 W/ O6 U
^, J7 N$ o& t% B3 F return wcscmp( deviceName.m_str, m_udn ) == 0;
: g5 F( ~* C4 {4 b. Q: I$ C }
0 f7 i P; Z' @( i$ D8 E CComBSTR m_udn;
3 z$ x2 y; G% u( }, Z4 y };
2 g! e7 s7 @, E( F0 G9 h+ A2 S
2 ]8 l5 Q* l5 |' [3 v void ProcessAsyncFind(CComBSTR bsSearchType);* F7 b" R4 N. I( l
HRESULT GetDeviceServices(DevicePointer pDevice);( W7 D7 g8 M+ H( _4 |, S
void StartPortMapping();& H' F. ^! g9 R, z- ~' b
HRESULT MapPort(const ServicePointer& service);& U% S. B# D. t
void DeleteExistingPortMappings(ServicePointer pService);8 F. h9 z: ~( ?% i4 Y- R
void CreatePortMappings(ServicePointer pService);
' S- n0 `6 S J4 g8 \5 g( C1 y6 v HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);0 Y+ K( q% E8 j R
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, , o8 {1 x( ~% N" n- P' I+ ~" `+ V
LPCTSTR pszInArgString, CString& strResult);
- x3 ^# \4 M* l void StopUPnPService();
l: ^, u, T+ v+ O5 S5 W$ E& B- o7 Y1 s, [* V
' Y5 A; b3 V" E z // Utility functions, P4 ]- B/ A9 @) j4 i7 j
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 y u) i+ B8 a3 y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);& L \% i0 a% X5 J
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);4 `8 v$ }& e, X/ X! h8 M
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
$ w, E, Y- M. y HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* w3 W0 m( S( t2 [6 | HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
) [% T+ p8 J' @0 b$ K' A7 g CString GetLocalRoutableIP(ServicePointer pService);9 h4 Q+ F* l c7 |
6 ?: D' y. {" P0 x X4 J- }8 a3 }' P, x- b. C5 {
// Private members C) k0 u7 a6 L) T
private:7 A# N, |' |3 o
DWORD m_tLastEvent; // When the last event was received?% C/ G; T! r V/ |; V( J
std::vector< DevicePointer > m_pDevices;
$ b* u, A# |* ?6 u: j2 ] std::vector< ServicePointer > m_pServices;
0 t7 A- u$ x+ I2 p) ? FinderPointer m_pDeviceFinder;; r8 o' |6 e; ^$ [ r2 r# y; b
DeviceFinderCallback m_pDeviceFinderCallback;% O( | k% _2 o! L9 p
ServiceCallback m_pServiceCallback;" i4 }& q& b' r! S; l8 ^
. D& A, x6 z$ ?0 A# O: c
* |+ j# Q2 A2 |% }
LONG m_nAsyncFindHandle;; Z, r' E, P0 F" N0 v, k
bool m_bCOM;( o7 r( G( u* c6 m2 a
bool m_bPortIsFree;& d' v4 k% x% t/ F! E7 o. B
CString m_sLocalIP;
& a& _0 `0 W- H' [ ]+ d2 F/ X CString m_sExternalIP;
8 p' Z" Z% \/ q0 Z5 U2 a bool m_bADSL; // Is the device ADSL?
+ Y0 r# D0 n; `! ?. T% r+ f bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 z2 G) v4 Q" O7 J k; @ p bool m_bInited;
1 a# P- w: C Z8 G- b8 b/ F) x bool m_bAsyncFindRunning;' i4 M! H+ |& P' O: [
HMODULE m_hADVAPI32_DLL;
% Y* d% G/ h6 d6 d& q HMODULE m_hIPHLPAPI_DLL;
6 y# \3 |3 R5 d8 \8 V0 J bool m_bSecondTry;
8 X( }% G% Q' A5 b* U: l bool m_bServiceStartedByEmule;
! {5 S2 ]# _- T, z/ q0 U( o/ [ bool m_bDisableWANIPSetup;
, g8 y% y# E, l. P bool m_bDisableWANPPPSetup;: B1 m/ J% R' J5 X1 w
4 s i8 U3 n: M2 v
7 W. R( X) g/ e+ x};
' J- y1 U0 b& l3 z$ f6 k, |4 J
' b- d: B n( I3 D7 J. j$ n6 j
" C% [3 M) l# M- F// DeviceFinder Callback
& d/ p% I/ V9 `$ J" iclass CDeviceFinderCallback
4 h- y) j1 v5 Q2 z : public IUPnPDeviceFinderCallback
0 J& i0 G. E# q/ x{
; ~8 S0 z& ^9 N0 ?1 upublic:
0 b1 G( d7 `$ V, K3 i- B CDeviceFinderCallback(CUPnPImplWinServ& instance)& P4 K( D/ I5 k4 _ B
: m_instance( instance )$ m7 x# z) f* H) S
{ m_lRefCount = 0; }
! G" ^) O* `# \, k2 R
& F4 ]* k/ D! A) N7 H
0 P! S# m/ ^' T8 J' E& ?/ D# ^8 d STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" f. V' Y8 U' G, |/ g3 a; g+ y
STDMETHODIMP_(ULONG) AddRef();
7 t$ u( i' S% N) x* i3 H STDMETHODIMP_(ULONG) Release();
$ ]3 E# A1 i8 ~& L- o- v( N: b$ v
( _' Q/ R1 w% Q% [: e3 }
4 K0 }+ P, S K// implementation
6 f& K7 \' q, F5 ^4 U& a* U% tprivate:$ P' i2 ~5 ` O5 }3 S& M' _2 Z8 E' b
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
2 N+ s' W0 F/ T, a6 j" m- I( h HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
( v& m2 w& I: J* ` HRESULT __stdcall SearchComplete(LONG nFindData);+ P0 O1 u% Z, N
2 G5 _/ k: K/ K+ Q; O
8 f* J$ q4 g1 B' n0 @4 Uprivate:/ M# c& d- y8 b& z3 ^! y& T1 E
CUPnPImplWinServ& m_instance;
6 X& E3 r% _1 D+ o5 u LONG m_lRefCount;5 M0 O4 o; J6 f9 }4 V& J* e) P
};% o4 ^! d8 H2 X& e5 X
7 m$ K' `0 n, R
- A5 n! @& A5 J1 O' ^& k4 }// Service Callback
, a, F6 @0 n5 qclass CServiceCallback$ ]6 o! i& u7 |! Z* V
: public IUPnPServiceCallback# g, z8 w. T5 g
{
9 ^3 Q2 d' L2 s; c1 vpublic:
3 w" m; T1 t3 k: S CServiceCallback(CUPnPImplWinServ& instance)' r, L$ O) t, L' S- k# [: c1 o
: m_instance( instance )
1 d5 @) s4 ~& I$ h. L5 l. _ { m_lRefCount = 0; }
/ F; T8 |% L7 G
2 \! w: O Z ~+ E" o; `5 I STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
7 X$ h2 b5 k4 h5 H- X( F; m STDMETHODIMP_(ULONG) AddRef();
" |, p- V2 x: E7 x( J* q9 |1 k1 x7 } STDMETHODIMP_(ULONG) Release();7 q; ^5 W3 d" I: X9 _
* E9 G) F/ h3 N7 @/ H2 H6 p
% ?# u: `; s$ m" s// implementation
+ g1 E# _2 U. R& Hprivate:
2 |2 k* s) n# e* @( i. ^' i" b HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 t/ C) N- _0 }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 p( B# h9 P V: [7 J* K* x2 ^ V7 D1 B8 W4 `# E
Q* p8 b; l0 [5 O3 M/ a! g
private:/ F0 F# o1 z0 y5 ~# X. u$ Y' y% a
CUPnPImplWinServ& m_instance;8 M) r' ^& H: |; [$ K1 g r7 s
LONG m_lRefCount;% E' P2 o# S6 q; l/ M2 [
};
. L: |7 B: f# K7 D6 M
2 U4 I+ }7 [' ^, D! j5 B
n$ }% T% \! V, o/////////////////////////////////////////////////
( i- r! _6 E, {. f; O& R: g5 I: z$ i: S& M8 B- x# T7 O2 R8 m6 E
) r# P2 N! M+ Y! }; L使用时只需要使用抽象类的接口。
v6 C! b5 B* \5 C$ N& CCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
\* _) p5 ~$ O# [" E3 L2 _CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
1 ^- F1 _& T' b7 Q2 ?) n; v* yCUPnPImpl::StopAsyncFind停止设备查找.* k9 z# L: A* N( s: F0 y. p9 j% m
CUPnPImpl::DeletePorts删除端口映射. |
|