|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ \& i/ ~( ]# u% T9 {1 G
+ ~9 o4 O5 I; K" I, d# [5 K" j# `8 j9 K7 ^
///////////////////////////////////////////, B. r) X. ]- f* W- P$ ?5 `6 l5 T
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.# g8 W- Q1 O, E: b8 X
' E8 z; y: S! ~9 R2 ^8 i
7 N' {$ z5 D) h#pragma once
0 w- B1 a( S) H: c8 Z2 A \$ K& U#include <exception>
7 T/ g- @. `# c( U' R8 U
0 K* Y! h; {$ Y' ]
8 \! D8 t2 t: G% P enum TRISTATE{
d# j( d" l8 L7 A TRIS_FALSE,
5 X+ _& e% ]% t# E, A TRIS_UNKNOWN,) Q# h1 b6 J( ]
TRIS_TRUE
5 d7 K. |8 k8 t# e! @' z2 C};5 r+ H5 L; R3 v4 H
: t5 T7 q. b4 J0 ^. N) m" a" K5 m# t; \( V8 a; {
enum UPNP_IMPLEMENTATION{% N( ]4 E; c3 ?3 e6 B
UPNP_IMPL_WINDOWSERVICE = 0,
& X! j+ R7 s0 f9 E. ~ UPNP_IMPL_MINIUPNPLIB,
% U+ w( g" ~3 M UPNP_IMPL_NONE /*last*/% Q6 v- B1 A x9 G" |. _2 b ^
};6 f* e& z, t; d! @
' d& ~& b5 J0 Q+ z, x# S- u$ c4 v
9 j9 y; T- f" W: t( d+ t0 P9 w4 S( @" d4 p: K
' c) \+ y0 c4 i6 @8 w4 L. oclass CUPnPImpl0 x8 ?* I+ T( ~7 F5 w
{
3 y/ c; k3 a* D/ i5 ~3 bpublic:
2 ]$ _9 g, F* N6 W( F CUPnPImpl();
7 b1 a& L7 A% l- B# ?' B virtual ~CUPnPImpl();
1 }9 r9 ~# Z5 d7 _+ v struct UPnPError : std::exception {};
5 E W: X; i5 ~, w9 ]5 M enum {' P2 v, q/ V8 a3 y$ ~) P
UPNP_OK,
; z3 Q6 I$ m* {" d7 B UPNP_FAILED,5 S3 _* N" ]: U) M# ^7 ~
UPNP_TIMEOUT! s3 T1 J6 h6 f u
};& v- K; p' {' [+ ]
k( S- a& f2 t1 b5 U& v% O9 O6 Q, B% T p4 i
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 \& \- Y3 a% v E7 d. b6 J# n- S virtual bool CheckAndRefresh() = 0;4 e @0 c% t: s$ w
virtual void StopAsyncFind() = 0;: p3 A' f' c, P4 s7 {: X. s. Z8 o
virtual void DeletePorts() = 0;4 L/ F4 p' @4 E
virtual bool IsReady() = 0;
# i5 M" y/ b! \( B9 y1 s virtual int GetImplementationID() = 0;6 U( [) W/ ?* ~9 S6 x; h, j
" f& k$ _; Z" R- @' V9 x
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 p. i0 x/ @) Y( S) y. g* |: u
0 n) C$ z6 b3 ^9 f3 ~7 K$ l# J& f N5 V
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
: i7 X2 E& W1 ^7 @ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
$ _0 E9 p+ F5 ?1 J1 S/ z. k uint16 GetUsedTCPPort() { return m_nTCPPort; } h9 j. @6 a2 _3 Q, q
uint16 GetUsedUDPPort() { return m_nUDPPort; } ! J9 l+ D8 g" l& b$ w
3 [- c* w N2 N8 S
; B! E- d& e5 I% F0 |0 y// Implementation0 E. S, J( b9 O; o. u
protected:* D: E( p: E- i0 e# V1 A
volatile TRISTATE m_bUPnPPortsForwarded;
- f5 a: g$ e. q, R" O& F" y2 b) j void SendResultMessage();
% q( S! p+ {7 ` uint16 m_nUDPPort;
0 [2 s% ^ \# d/ ^' T uint16 m_nTCPPort;4 ?+ z, y& W5 S" L! U
uint16 m_nTCPWebPort;! e$ i3 M3 _ T B, K. B L1 ^
bool m_bCheckAndRefresh;
; w% B' j4 E9 R8 Q( i" T5 R3 |( X- `
" k! _: ~* D# a9 B2 Y
9 J, M, F5 O; `% ~, u$ \& Jprivate:6 U8 j. p6 i# ?+ [1 Y( l
HWND m_hResultMessageWindow;" Q( D$ X" |1 M% @
UINT m_nResultMessageID;
2 z- o8 \0 a+ _) N7 h$ X5 d `: |* g R$ w
$ z5 L) R! x; J" n};
; c* e5 T+ d5 Z. X; p+ Q& V3 J
# e6 ~# N1 [& `; y) p( K
3 _, A! N+ P5 E2 i% j// Dummy Implementation to be used when no other implementation is available' C! d B( }# i9 `; Q; ^
class CUPnPImplNone: public CUPnPImpl0 P3 M3 J" m! M* Q
{
1 y' d* a! }1 R# w- D9 J6 lpublic:& Q: p$ m& j Q2 t8 c( h( D
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
4 x' N+ S$ q# w8 \, G virtual bool CheckAndRefresh() { return false; }; n3 S, F. U9 u; f
virtual void StopAsyncFind() { }& ]; p& b/ C4 R
virtual void DeletePorts() { }5 C7 X- c! S: B6 s9 Q1 z
virtual bool IsReady() { return false; }' c# G! m# x' s( \0 b) Y3 U* _
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }* A, T' o' g |, ?$ v8 q
};( f, b. S3 K' k' k
/ [; v$ S' H: h4 S
" ]9 F- p+ S# _/ i; C& v2 }4 B) t
////////////////////////////////////// t; n6 {/ B* |! U" c/ Y9 P6 o3 J
//下面是使用windows操作系统自带的UPNP功能的子类& G% D4 a* [7 C
$ w/ R" t* d1 ^& _
+ z/ t4 V4 c( G) V! ?& K# \#pragma once
, P0 H$ P% ?) X3 p2 ^, t$ |#pragma warning( disable: 4355 )0 H0 o0 b' d+ i5 t
9 R% f r$ n5 B8 F, E1 j
$ y# b; \2 v4 R#include "UPnPImpl.h"
! }0 \9 L* z. W3 a% u3 v#include <upnp.h>) Y. M0 P1 i; [( Z/ V
#include <iphlpapi.h>
9 ?* @6 d+ Q& R#include <comdef.h>4 w0 y" G9 a3 g3 ?$ q g4 Z
#include <winsvc.h>9 v4 P6 R% B; v) p. G' @" a
v- z/ |) W# r8 ^& D- p
* Z1 h) y) T8 k2 J/ i! ?! g#include <vector>) U# x/ X0 X B6 d0 \: o0 R0 I
#include <exception>
+ E5 |) }, d0 C, ?4 q#include <functional># M0 v& K8 a1 N! T0 V. i/ t/ L( a
* J4 r$ b- Q$ h/ C! q) L. h; N4 \; K4 ]
2 D( Z1 p5 }/ Z4 V+ G3 j+ a1 u
5 b0 P8 @1 {( \/ e7 }) z8 G! Htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
/ s& s+ O- n- k( s7 Y' Ytypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
2 | R0 V7 @3 C# Gtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;3 O8 _( @" g+ N
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
- \1 l% p% @$ p8 W* Htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;% V9 s0 b g$ R
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
: q' T" b E' g, ^typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
2 t! m- M% n4 ?$ y/ f2 q/ g; ^/ p
/ E, R: G$ i7 K5 E! Ctypedef DWORD (WINAPI* TGetBestInterface) (& o5 j0 {/ Z5 H
IPAddr dwDestAddr,2 s7 V7 B @ W* _& a( H% S- N( u
PDWORD pdwBestIfIndex% K) v2 @- m1 _; @* N `8 ^3 i
);8 a6 N5 ~- e: m- I
, l& v$ I* j! v6 j4 J" B- B! p+ D$ q1 r s
typedef DWORD (WINAPI* TGetIpAddrTable) (5 e% b6 G; ]( i( Y
PMIB_IPADDRTABLE pIpAddrTable,
# [! r, F1 W Q. L8 _ PULONG pdwSize,
# O6 E; ~- H; C1 {4 `& M/ t9 { BOOL bOrder1 D, e5 P: }4 K
);
/ v/ a+ I+ m$ q5 K5 {$ ?
, Z5 b# _- T& F
2 f/ l- N! r& X1 _typedef DWORD (WINAPI* TGetIfEntry) (6 }" i5 I3 d/ |+ z9 z
PMIB_IFROW pIfRow2 t: \/ \/ D& z# ^" e2 }
);) {" x0 k+ n, D8 i. E0 w/ |0 n
1 a5 x/ R# J2 n# ?$ T( i2 h! O1 ^ |2 f
CString translateUPnPResult(HRESULT hr);
# k J2 z4 }1 x: |/ RHRESULT UPnPMessage(HRESULT hr);
5 {, v$ @# m+ J7 N1 ^3 ?+ r
7 |+ W& A8 \, q" |; K5 T# m2 K; m# R! C/ p+ X4 P6 c3 I, ]$ u
class CUPnPImplWinServ: public CUPnPImpl
4 t7 \+ V0 h5 P7 e% [ y4 q{
! } t) Z' J; D( V4 S friend class CDeviceFinderCallback;2 e' A( U; L3 j
friend class CServiceCallback;- k4 j8 `2 K; \$ U- K9 t! i
// Construction# N' I# Q8 s n, s
public:/ w7 q) W1 A& c8 L5 o2 [( k% t
virtual ~CUPnPImplWinServ();
6 B+ }8 [9 _& I CUPnPImplWinServ();7 v) J( I3 @- v d9 T: U9 r
# d1 t. S$ c* A* G! }. _
" C% O4 q+ B+ a1 U" T
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
9 d0 l! r% p! N) ?/ G virtual void StopAsyncFind();3 s+ ?% M8 R' `! `! Q/ M; o: D% U
virtual void DeletePorts();8 W( t) S: l! E- ?) J1 x$ C9 F
virtual bool IsReady();
F- n/ y* S2 A4 A8 M virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ E6 C N) a; S- U: _
, m% E( N Q' ?, h: W
$ L7 F! Y0 K3 X: U; l4 k // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)# }( S5 d4 `3 {" g, @% ?
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
! T( z9 V2 ]! Z$ d1 n5 { virtual bool CheckAndRefresh() { return false; };
2 T! a5 F0 a% A+ U- B0 a/ V, r" q
! D/ f# g+ A' {8 P& O+ F
5 E, H' u( V! V9 S1 P9 Bprotected:3 z" x/ P8 X0 G5 e$ A/ B' `
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);4 I4 b2 J. }0 C
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" F0 P! w6 m0 U: o* R' k0 Q2 z void RemoveDevice(CComBSTR bsUDN);
2 ^3 y0 {* r9 B& |% [. w bool OnSearchComplete();5 I2 e; A- \" m. X% w( H
void Init();
" |9 J" ^+ u* S/ x& M+ _6 P" n
2 P! S$ B& Q# I7 w% _
inline bool IsAsyncFindRunning()
3 G3 o. w+ i" k: h/ ^ {
# e; L8 L" C$ { if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ), }$ C& ]$ A E0 w( m5 f5 i# p9 g5 I
{
9 F9 K& q0 l- ?+ c# r m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );8 f z5 e% p6 o1 t+ b6 w8 Q
m_bAsyncFindRunning = false;
! n: g% O5 k1 ~0 M- B/ h: c/ A( g }4 X8 F5 ~2 Z. m$ _
MSG msg;
1 H. a7 u6 _3 c" f, J5 M( a' P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )- g& @( g8 M; G
{6 Y( j% d9 _: d( R# ] }$ u
TranslateMessage( &msg );$ ^/ ^8 x3 P- v- Q8 [! {6 Z0 b4 W9 e
DispatchMessage( &msg );
, O+ c3 K0 n1 E) i, y4 O w/ J2 j }8 K$ R; d O0 E2 \0 d. O5 ~
return m_bAsyncFindRunning;+ H0 x0 n( i, j
}( P8 n3 H6 D. L, s
]! f: Q1 G8 A7 L( L
* z7 C1 {6 y: ?8 e TRISTATE m_bUPnPDeviceConnected;
5 U! M4 U: Q# [: y" S" ^
, ^2 ?7 Y! o3 ?+ [" I% o2 u+ G. U; d( c, u. K
// Implementation
: ?1 k0 y, ~5 q% k // API functions
& @! w$ I, r" C9 j* W! D* I. D SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);6 {9 t7 q3 m5 g3 @# M8 \' K
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);; f W7 U. P x; \! {7 L, N
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);, L/ V/ m3 A' R7 C' s
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);" v1 M0 t* E9 Q& _/ G: F5 t
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
# [3 L4 K% y5 @* G( | BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);4 a4 H' {1 K7 Q- |5 \
( j* [. z& y6 O+ G
- k* o5 ]4 f9 }+ ^0 n9 ?
TGetBestInterface m_pfGetBestInterface;2 k: e& I% R/ w" I8 Z
TGetIpAddrTable m_pfGetIpAddrTable;2 r% ^) p/ s e1 b1 D! S! v
TGetIfEntry m_pfGetIfEntry;
^+ Z) x( @( ?: T2 ~+ B
* h5 O4 l) c( ^9 Z. ^; g! k* v) y9 L" I' y! P& k1 Q/ Q
static FinderPointer CreateFinderInstance();
4 u" V Q% e, I7 a" e2 h3 |/ @ struct FindDevice : std::unary_function< DevicePointer, bool >
9 f% S1 c7 M$ r5 y- C$ ?+ T' o* U {. Y9 {: Z; j Z }; n* c
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}7 t! W4 a2 P/ e& c0 b
result_type operator()(argument_type device) const
! m. }5 C3 v7 t; G6 R$ q {
. D3 x' |& O, Y4 [ CComBSTR deviceName;. c8 u) U2 g0 I x& k
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
0 p* @" K: }* X1 w0 a7 W$ {3 l6 J3 V ?$ @- t1 t
' e) k# r- Z- x: t2 D
if ( FAILED( hr ) )
4 G$ R8 n5 B# O; \- p* @9 Q G" @ return UPnPMessage( hr ), false;5 C, E! R' G9 i. f. O
# K7 ~& C" ^$ R8 W" G; z9 B
2 O" ^9 i, z% A, b; S! t return wcscmp( deviceName.m_str, m_udn ) == 0;
& D( f$ e8 v7 ^1 V, x. l; Z2 v }0 t5 L M- `. x% R4 K
CComBSTR m_udn;
! r; O$ S d8 ]& @3 F4 \( z };
4 |8 ]* V8 q/ Q
7 w" _- r! O/ t) H void ProcessAsyncFind(CComBSTR bsSearchType);8 g9 N) l1 b/ h! ]1 n" p% b
HRESULT GetDeviceServices(DevicePointer pDevice);; F9 ]/ r1 E) O+ X: P, n
void StartPortMapping();
: c# m' y x x% g1 ]! y) V HRESULT MapPort(const ServicePointer& service);" ` N* I+ I7 ^
void DeleteExistingPortMappings(ServicePointer pService);# F- R- Q5 _ l; Q
void CreatePortMappings(ServicePointer pService);
4 o4 O7 J5 Q# H+ n HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
- H/ i$ k8 q7 ` HRESULT InvokeAction(ServicePointer pService, CComBSTR action, : j- X, q+ m# X! U1 T- F% Q2 I
LPCTSTR pszInArgString, CString& strResult);" x( ]4 q+ P9 {( S
void StopUPnPService();) }" q: p, _* V4 c8 y; O- J' }; }
6 g$ \9 E3 o D8 X4 d% F" V' D; _6 J& n$ p1 L7 S
// Utility functions8 |. |* {* f( }: f
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
" D- [' c. @" i7 n2 J& V INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);# {& G0 h- m$ e/ ]0 I( x" |5 U
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
$ S- m/ t3 s" Z# H void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
9 |1 y7 c$ v. ^# f HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ d- g @; H3 ^4 f6 [ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
! I2 c4 @+ t- j) l6 ? CString GetLocalRoutableIP(ServicePointer pService);
% A- @: Q5 b; x& W4 E3 E4 S6 L2 L8 E3 w* A: j/ |% u
% v! g8 D- C/ N2 Q6 o/ ]2 x
// Private members
) [( Z9 P' M4 f. jprivate:
6 V. J0 A( W \6 A0 R: E DWORD m_tLastEvent; // When the last event was received?
) S, x; D" h; o std::vector< DevicePointer > m_pDevices;
8 d3 S' e' c4 w5 v* A5 _1 j( s std::vector< ServicePointer > m_pServices;% }, }7 [2 W8 L6 ?. [8 A. L5 |
FinderPointer m_pDeviceFinder;7 `2 ?( w0 E7 r: O: ]" k8 h. H
DeviceFinderCallback m_pDeviceFinderCallback;
/ X( `5 A5 x+ w ServiceCallback m_pServiceCallback; \6 p4 r, h. f
4 [, s: {7 k5 E' l) j2 ^
( t* {; A& ?- y5 F7 j( {4 X1 A LONG m_nAsyncFindHandle;
# e! a, t3 X5 h. X7 \& g* ?0 S bool m_bCOM;$ Y' X5 Z+ Y2 x2 z2 Z- F1 E* O2 @
bool m_bPortIsFree;# I. O' u2 v5 C2 _7 N+ @1 \
CString m_sLocalIP;
' f0 F8 P: {1 D8 B6 v CString m_sExternalIP;
: F4 r. k8 K ? bool m_bADSL; // Is the device ADSL?
@) C, O @0 n5 n, { bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 m- p+ O9 h# B! C6 [; m6 P; c2 r. O bool m_bInited;
; j# `3 M9 s2 o5 V4 j bool m_bAsyncFindRunning;
1 z4 n1 X. c% U HMODULE m_hADVAPI32_DLL;( F$ S% |- {% _" ]+ \2 S* A9 c
HMODULE m_hIPHLPAPI_DLL;; P4 M: y9 k4 @" ]$ A% b9 Y3 g
bool m_bSecondTry;5 p) a8 U- ]& M3 z; d' V+ V
bool m_bServiceStartedByEmule;2 c- ?- \4 I2 E) e% t
bool m_bDisableWANIPSetup;: g0 R7 h( q& t3 g4 G2 r
bool m_bDisableWANPPPSetup;
1 N* ~' t. }2 ]+ D( K% a% `/ a; c% S& ^" x2 G8 b2 r
2 |( O" W7 I+ e6 [5 P+ x
};) g( F" Y, n9 D! V# Q
/ I8 s& u' {4 e; ?& B
* d) d6 S7 m4 z; r% ]/ v0 z// DeviceFinder Callback
0 G; [7 A0 f" k: p8 iclass CDeviceFinderCallback
" c8 L5 G+ O1 u: Y' `4 k( M6 [ : public IUPnPDeviceFinderCallback
' K/ ]2 W: e$ K J. ?{8 L9 l0 j v5 c' i- P& r1 k7 V, ^
public:
4 b$ M) g4 Y0 b# y2 b CDeviceFinderCallback(CUPnPImplWinServ& instance)
6 C3 _! P' C2 Q : m_instance( instance )" Q& A/ W) r3 ?/ \9 j2 T
{ m_lRefCount = 0; }6 Y: L) M& X) A" P
, h, [3 [( r `4 L2 r, H" O/ ?/ z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
6 X. a- ?- Z, V$ Y, p- \ STDMETHODIMP_(ULONG) AddRef();
* E7 M2 Q9 w$ J STDMETHODIMP_(ULONG) Release();5 z. o' C5 f. F4 \8 P
- R1 ]6 b1 A0 g1 A0 `4 C
5 E% [, I- N! |1 U
// implementation
, k' Z+ x9 O8 V0 r* q2 ]private:
+ n' N, F \6 w3 m HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( q: {9 h8 V1 x- s/ @3 {
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);0 d- s5 c, s: ~* C5 G. Y
HRESULT __stdcall SearchComplete(LONG nFindData);
) ~1 s& Q# B9 @) ]: G7 O7 h" S
: h; t$ q7 ]/ C7 } |8 X+ D9 h3 W$ `/ L a3 f# r
private:% I: H* ~* S& c
CUPnPImplWinServ& m_instance;
$ z5 v z9 {9 ?. C7 z } LONG m_lRefCount;
2 Z6 o- |: K, G6 e7 t, K};
6 c+ R# X- L+ v
+ i' H# q% j4 F, G% I0 k; K7 ?1 |! w8 c% r7 Z3 D+ J
// Service Callback - c1 R7 F; B2 Q9 H
class CServiceCallback
% d |" s1 l: P# z4 u6 F! s$ l) o: } : public IUPnPServiceCallback
" y( d, ?0 g& K" e9 @+ X ?4 z{1 l! Q9 } |7 W& A
public:
& L" r1 H1 r7 o B- J CServiceCallback(CUPnPImplWinServ& instance)
@( f" g& t. w, L9 B : m_instance( instance ) }% v+ S0 H! z, s$ J) K
{ m_lRefCount = 0; }
) F- l% \ s T8 p0 h4 }% I
% w7 s4 { V/ `$ p1 e- K5 Y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 N5 X) L( F8 o2 j5 k/ _ STDMETHODIMP_(ULONG) AddRef();
0 S8 L3 U- b6 R STDMETHODIMP_(ULONG) Release();# r; O* z: t0 o( z4 Z; A
( b8 y3 y0 a: V5 R' m7 d7 A9 M: I9 ?
/ j& ^& J4 V2 t9 `0 z- B// implementation
8 g/ [' g6 X5 |3 K% D7 Y- l' ^( r' z- Bprivate:( E" L: ?8 Z/ i8 m2 l% _# ?- o
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 H7 c) K1 x7 [4 B HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);1 Z; k6 ^. ~& X6 ?
7 ^! [# ~' n: Y" F6 W
/ t+ L6 @+ l' g b
private:
. o2 x5 }4 W: ?* s( d CUPnPImplWinServ& m_instance;
8 X* v/ j" L$ a! E6 S& C9 ] LONG m_lRefCount;
1 V2 `* G' g. V# U6 Q% B3 E};/ F! ~6 Y& Z' z* ~& b! u* ^& l
1 ~( D4 ^3 T9 e" k. Z
' |' X* R) S! z
/////////////////////////////////////////////////3 g: N2 h0 w" [! t- E8 k
w0 `0 A0 {2 L
" A0 ~2 F: B4 J使用时只需要使用抽象类的接口。
& B* r: {3 u' L3 ZCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
0 X6 Q ^7 Y; ` ACUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.9 r3 t) y, C; d0 W$ Y' Z# X
CUPnPImpl::StopAsyncFind停止设备查找. s j. A) E! a5 j2 O5 |
CUPnPImpl::DeletePorts删除端口映射. |
|