|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ h; K2 y( \2 R& w: t/ X
# Z; I! K$ |- |$ i' s( m' V
9 b2 l" @" N( g& N/////////////////////////////////////////// G# m# q8 _1 h) I' @
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
' l4 \% K* G. B9 U* }' l E4 P$ K9 k! L& M
+ N" Q6 M, T0 `3 x
#pragma once$ @0 c3 k# l0 H/ Q6 _/ t
#include <exception>
$ v5 _% ~( [* A9 w5 v" {* P, ?1 h9 r
5 }# ^, }" Z, m+ |9 y& x
enum TRISTATE{
! r- h& H: \" [. G% U+ K6 [2 | TRIS_FALSE,
; l% I2 G p3 ?$ J TRIS_UNKNOWN,- u2 A9 R+ B+ B( |' W
TRIS_TRUE
- M/ V2 S f: ~- M" A};- \+ W3 n. B! i" |
8 X A) h# d% h' H
! |. v5 S, J, `, e. \( A' n. fenum UPNP_IMPLEMENTATION{
1 \4 u2 t! }' [ UPNP_IMPL_WINDOWSERVICE = 0,
. f; B4 z/ \( f4 R) b6 }0 V0 X UPNP_IMPL_MINIUPNPLIB,4 l" [0 P1 x& T, a E" a. E* R0 z7 M, l, T
UPNP_IMPL_NONE /*last*/+ Y. Z$ q; p5 b( u' y. s" T
};
0 _- F* F. \+ m& U9 c/ z- T- f1 l- H: p
R5 q3 y- A* |2 W
2 L" G [) |9 f! ^
( M' @1 Y! X0 g1 tclass CUPnPImpl( _6 l1 ^' [1 p* B5 r
{6 A B: k( ~8 P
public:0 ~) `6 \9 t: l5 ~; |
CUPnPImpl();
* l* a& w( \! O7 N3 t4 n virtual ~CUPnPImpl();
* K G/ X6 e4 W3 v struct UPnPError : std::exception {};0 T7 ~, X, `. ?
enum {* X" t6 q9 P9 S$ y% {
UPNP_OK,) R! t$ Z2 m2 p( m _* v
UPNP_FAILED,5 r2 n8 k. N; j# A0 i% y
UPNP_TIMEOUT$ e. H; q5 Y9 p/ C X2 r
};9 H3 p& i( b* I2 B ^1 ^8 w
; n& Q6 p {, o7 j
2 `) k+ q( \, x7 Z- m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
/ O( V7 ^; q9 \! A0 O+ b. y virtual bool CheckAndRefresh() = 0;: q* B7 ` |/ P$ [
virtual void StopAsyncFind() = 0;
9 y- e' c8 w$ c5 y5 o virtual void DeletePorts() = 0;
; t% o0 ~* b5 l! x& z; t virtual bool IsReady() = 0;
! \' F$ ?, u; M" m C" H" l virtual int GetImplementationID() = 0;
7 @% D/ p) r, E9 i # K7 p l9 O! B0 d* _
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, T3 p/ w2 f Y& P! O; c# w, r
; v2 _' W* J: ]7 X$ V V8 F
1 J4 W$ ?3 ]' v4 k. ?& d: S
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
G# u9 w, P0 Q6 a- M& W0 a TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
# \) D2 X* ^) `3 ?) T7 w uint16 GetUsedTCPPort() { return m_nTCPPort; }
* N8 |! A9 H3 D9 [% f! q1 Q uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ C: L3 X& Q* q# t# z( h% T/ S" ?1 J3 D, _4 D
) \- k3 q0 c, i4 ~+ h2 D9 e. [$ ^
// Implementation" g1 [# f+ E, |- q2 u
protected:
( r. g, t* k! i volatile TRISTATE m_bUPnPPortsForwarded;* P. G9 @2 C8 w9 D$ V; _
void SendResultMessage();4 P. S) H5 g( I z+ S" s+ k
uint16 m_nUDPPort;
" _6 K# Z& r( C1 O- A. K uint16 m_nTCPPort;& m# r# w% W ^. Q. J( i n
uint16 m_nTCPWebPort;/ c; m F' z" D0 F% t
bool m_bCheckAndRefresh;' b- o( I1 T/ ?+ U+ P
5 C9 z* G& [$ `/ L7 u- h* {- r5 y6 n0 `+ Q
private:
+ t& Y T. R r8 S HWND m_hResultMessageWindow;
; U( D6 j+ ?% N! s; U UINT m_nResultMessageID;
; F$ Z% K" Q m. l8 Z- p+ [# c, D( Y0 S2 e$ u
4 M2 J; A5 p& k& l7 K};- Q$ g3 S$ M( K8 R) H T2 i7 B( E
# M( x' C! c: ^6 {% P/ _
' J# T3 w/ b e1 r( y// Dummy Implementation to be used when no other implementation is available
# ~, C5 a9 q# T7 U3 N( @2 z5 z6 Eclass CUPnPImplNone: public CUPnPImpl
- }5 N+ G) |' w+ \. D1 I+ F{
- Q. }+ W; t# B8 N; _1 Q$ a$ |public:
5 P B3 U- B. a; K/ @, z- W virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
4 q' I1 r7 C- v- x; t virtual bool CheckAndRefresh() { return false; }
6 G/ d; L: B! {. K) j, ? virtual void StopAsyncFind() { }
4 c+ N0 V) ?! I: c/ k* C virtual void DeletePorts() { }" K! b- `7 f; S. e
virtual bool IsReady() { return false; }
4 w9 H3 c& g- A6 r virtual int GetImplementationID() { return UPNP_IMPL_NONE; }! O/ M( S5 G! x8 [
};
& W. O# i! c m: j, s+ j( R0 d/ C: K6 `9 \7 _1 o( B
+ m" F/ x1 r+ u9 C" i3 Q4 p2 m/////////////////////////////////////2 ~0 r7 E# z6 B. [( R- R4 A/ i' ]. @
//下面是使用windows操作系统自带的UPNP功能的子类
% d/ t1 |, r9 ?5 y6 d
7 ?! T' v" b1 U& w2 O% T6 d+ g( f8 S2 p* P) H* v' n% z
#pragma once- l% o3 Q W3 `' ^1 L# B
#pragma warning( disable: 4355 )
. P( G. }. ^" l( s w2 r: Y! t/ o) N/ n' w- f
+ A9 R& N/ x7 B
#include "UPnPImpl.h"; |; |/ {# Z) b. x; U: g
#include <upnp.h>
/ i+ O7 C u: v- J+ M#include <iphlpapi.h>& |; w$ S8 J. y
#include <comdef.h>0 \$ k9 r9 e2 F; |3 N5 r
#include <winsvc.h>. b8 F; k5 o3 e8 b% Q" W
) |, n6 @1 w7 c# v6 l% `
+ }+ Y( W7 O; U5 j! A#include <vector>
4 v* e, T4 ^: |/ n3 G% z#include <exception>9 x t k* P% L
#include <functional>7 f5 G( K n) N/ c' C, J* ~" w" h$ w
. d& H7 W# X. d5 E3 q
) l# J8 k( B1 a9 b
2 K# {. _! J, G2 V, C: u Z% N) u# Q' Y0 L7 t
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 j, W& Q4 R- D- h1 rtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;9 u8 j3 G+ }7 u1 \4 b4 r# ?
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;/ r1 u S6 W6 b# M7 n
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
, T0 `) b0 u* I& b& D- E7 Qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;/ `% J; x* F4 p( q* r6 r
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
! ?+ Y+ O1 c6 Q# q' ^typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' d& O5 A$ U6 ]7 [3 Y3 u
! E+ {" |! r/ r- ~
. h# C' C. |! p, l% ztypedef DWORD (WINAPI* TGetBestInterface) (
4 t5 t2 i/ y$ h" f! D/ ^ IPAddr dwDestAddr,( j2 Z. U+ ?% J0 N+ a: W( u
PDWORD pdwBestIfIndex
8 J) ?5 g. u/ u& _' b);4 l8 U) f: v9 B8 r
' U0 S# C2 |- h; A }8 |$ Q& K5 s, Y! r
typedef DWORD (WINAPI* TGetIpAddrTable) (
1 \; J1 W7 O+ V- X" I PMIB_IPADDRTABLE pIpAddrTable,4 J7 \# d8 Z: P/ i I# }
PULONG pdwSize,$ _* S/ {0 n% \6 z4 V
BOOL bOrder/ W" U W$ |3 ]
);
' Y$ x) J& N: B0 e" i B. l1 S2 j2 c+ a: d0 o% R0 W) n! I
& e w. n; w# V' }
typedef DWORD (WINAPI* TGetIfEntry) (; e6 m/ Z0 n$ r" J4 n% y5 i
PMIB_IFROW pIfRow
+ e: T( S' O* p5 B5 h2 T, ^8 v& F* Q);) G+ X3 v$ e& |1 u3 z* J3 `
% A! Q# @/ S1 P" |& j! R0 z, M3 I
' m Q. m" {4 x& l- n% l l$ C
CString translateUPnPResult(HRESULT hr); E9 u; C% k9 O) x0 r/ h, @
HRESULT UPnPMessage(HRESULT hr);3 ?- Z. X8 a0 l+ y
, K$ B+ Y% @3 H6 c' V, m- f
5 k; _ Q L$ bclass CUPnPImplWinServ: public CUPnPImpl
: m: @ ~; U% Z$ d5 G{( ?: B2 ~, O4 o* A
friend class CDeviceFinderCallback;
0 _0 [3 a" r- S6 Z friend class CServiceCallback;
- h/ A6 q2 o! p9 ]1 I# {// Construction
& n1 Q0 s! G( u: V# V! ipublic:
. S) u, e7 o: X( G9 I7 \* \3 P; D virtual ~CUPnPImplWinServ();
7 w. e. u! {- f1 A! q/ f- B. Q3 U CUPnPImplWinServ();
4 j/ m( F& [: n0 l& E, {; [* M- x. s/ Q ?, X" Q5 Z
, i" b/ B z' o8 M
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& ?* z) \, r5 u4 O virtual void StopAsyncFind();0 \/ K2 y' h8 d3 {
virtual void DeletePorts();( u+ O) n. O; [& w( H; L/ U
virtual bool IsReady();" g! @. ~ X" W& N% z5 {- h8 w% b
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }/ u0 r! j$ K& \' K. z. r
\4 [0 \# k2 W- ]: t& @1 P% {4 z( k) p" {; b
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
/ b; J5 L( F% C t; f9 T' T. @ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
0 ^: J3 m! U, ]# ^6 j% s virtual bool CheckAndRefresh() { return false; };
) s% x7 b7 V) f/ \% d
4 D4 O+ k, d% p% a8 W/ o3 {
3 R* m3 s/ m4 ], Hprotected:
! c/ i4 z/ f( E* p! b void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);8 f$ O+ O! H( b0 E4 z
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
: k- S- \: P+ T, B void RemoveDevice(CComBSTR bsUDN);6 G. M/ X7 ^ \& B* X. ~. J z
bool OnSearchComplete(); v( O. ]/ G4 i* ~* C
void Init();' l( I) b2 v6 e2 j5 y& L
3 r: B( Z/ _1 \0 @& _) E) F( X2 [! L/ x$ i5 b$ }
inline bool IsAsyncFindRunning()
% o6 f3 q# G0 [" Q' _2 {& w% E& r {: t, f4 S" M' p+ h" T; r1 c$ p
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 X- K! f7 P8 C
{
' T# u; d, v0 w7 r% m$ ?4 U m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- U) H, V2 P" R( x9 S7 t2 e( Z, E m_bAsyncFindRunning = false;$ H3 h( S3 V @# x6 `6 t
}- p2 f& S5 P N5 M6 K4 l w
MSG msg;4 T- t* d: C$ ?) Y
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" L- @1 \# \" [( F; Y a {/ y2 F( Q! L" @
TranslateMessage( &msg );( n& _' w( x/ m/ ]1 c! _
DispatchMessage( &msg );3 S* P% k4 B- m* J
}/ w) l3 U7 m$ K8 A7 F/ S9 c" x* E
return m_bAsyncFindRunning;
4 c5 \. e' l) \. U7 J* s }
% \% ~! S# [# h& ^! m* X$ N
! [0 z- g2 h5 R( Y
6 h; a! o+ k1 h6 q! L, S8 i0 ] TRISTATE m_bUPnPDeviceConnected;' }* o! I. Y. I, p
; a; V% ]6 f% w
; h( @- K: f5 a! d3 k6 C3 Z// Implementation* c% y& K- f; S. C4 N
// API functions7 @7 w) k- j8 ^* ?
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);; M$ d2 W K; A7 u8 s
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 W/ l, j4 M4 f: O+ _3 ^ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
. _" k$ K7 n/ f3 C6 b3 o' A1 V BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);; C( ^: G( I# P. w+ j5 j! K
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
8 v9 i) x3 e1 u6 X7 o/ n* W" a& S BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);& E8 `; |/ T, ]& O- d; C
) h, \5 g+ S9 l$ r: e
/ e+ r" V0 \# P9 U& B$ w
TGetBestInterface m_pfGetBestInterface;! A$ R$ H" {9 q7 {! B
TGetIpAddrTable m_pfGetIpAddrTable;/ a& i* |2 f' f, G# K
TGetIfEntry m_pfGetIfEntry;
/ Y( v1 j+ j j# |* x* T& T0 Y8 `1 U' ]; h1 G
( f- e; K, w4 V l( z0 Q9 Z G
static FinderPointer CreateFinderInstance();: f' h8 j6 ^# _& b/ G
struct FindDevice : std::unary_function< DevicePointer, bool >
3 L0 ^9 G) S- `9 }9 x% i: Q; t {, C3 y. P& e2 R t2 v
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}6 F/ w' e3 ]1 o3 Z" Q/ h8 W
result_type operator()(argument_type device) const4 ?3 c& ]6 |' Q' T# W% H
{
/ S' ~* G8 Q" V CComBSTR deviceName; R5 N" b2 i. z' x+ B& j+ |2 W
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
: o! \1 W# b9 p! V# t7 n. Q1 X B y5 u- C( o! V: m3 N
+ ` F- F$ ~ N# |/ ?4 F' t if ( FAILED( hr ) )9 w {# ]. k% `4 y. y
return UPnPMessage( hr ), false;
- i$ t0 O' c3 J: y0 c# }8 q4 N: t" e" _" Y, j& l
5 u" }: ] F; w2 G- l0 Y, V+ B( v
return wcscmp( deviceName.m_str, m_udn ) == 0;, j3 Q; q2 q; n: }0 X9 l1 Q4 b- Y
}' G2 y4 H- F8 g
CComBSTR m_udn;
& y% m3 a7 ~* j( H3 Q' N };
& k( M) y7 m1 Y0 ^
5 {: a; t0 y6 e! V& c4 p, H void ProcessAsyncFind(CComBSTR bsSearchType);
& P2 C7 L' t6 w2 h3 g; U HRESULT GetDeviceServices(DevicePointer pDevice);
1 `5 _$ y+ [, F void StartPortMapping();
; e( p. J1 y8 Z& P7 ^# ^$ ?6 r% c HRESULT MapPort(const ServicePointer& service);. r. @2 I3 n# L% V9 h+ O) u+ r2 ]
void DeleteExistingPortMappings(ServicePointer pService);
. |3 g% m2 n) q- _ void CreatePortMappings(ServicePointer pService);
/ x9 L# d" c4 g1 V HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);9 w4 X/ M' q# I" p
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, * d: P% w& Z3 l& \* |4 M/ P& \
LPCTSTR pszInArgString, CString& strResult);% U0 ?/ {9 C6 s" U Q" z" ^; u
void StopUPnPService();
1 G1 \1 O1 O; p- c" v/ u# s# {/ y
z4 n C& q( V6 A/ T
4 q+ d8 i- m( {5 g. h8 a // Utility functions4 S: B: l7 E" M
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);& T5 V9 ~' ~- _6 u T
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ e" f' W7 \! ~# q' {( _7 M7 H o
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);" K, H/ _/ n( \" \
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ p3 m$ l" g. e! R# z
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
# r# \ `: Q' | HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ T7 z* K. M) H; ?% X W6 h
CString GetLocalRoutableIP(ServicePointer pService);
9 U( k3 g1 i4 K0 K2 V# @! L+ `0 n, d1 ~ ~: F8 ?6 |' r5 Z
2 E Q7 P) \0 w- O% n* _4 N// Private members5 B- q2 x5 P" |7 t" J) ?! @) i
private:
& ?: ]: X. l% ]) b7 z DWORD m_tLastEvent; // When the last event was received?3 X b) u+ Y/ U- p _' ^+ k
std::vector< DevicePointer > m_pDevices;% E7 q5 g' |; y& t* G0 e
std::vector< ServicePointer > m_pServices;
+ E4 D. p J% J FinderPointer m_pDeviceFinder;
( T( y8 H1 C- b) F9 [, z, n* n DeviceFinderCallback m_pDeviceFinderCallback;
5 k8 Q! @- Q0 u5 H0 I9 F ServiceCallback m_pServiceCallback;6 t* {$ c+ o# E% ^
: g' [, @( ]" c4 r4 E7 d% B
( O$ d! b; H$ ?. I3 c1 ~, d& B LONG m_nAsyncFindHandle;. `* n4 u/ s( r$ o
bool m_bCOM;( @% r' [ o% k' p1 J0 I, N$ H: Z
bool m_bPortIsFree;+ r- F& Y/ m0 s+ M
CString m_sLocalIP;
+ a6 \ L. v( ?: Z CString m_sExternalIP;
6 }) o6 _$ s# U4 u5 T/ F bool m_bADSL; // Is the device ADSL?- H# i5 ?5 d9 Z" M9 ^. B! Y+ Z
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
0 F& Z ~: V8 A& x& B bool m_bInited;
$ t1 }* g6 y+ x2 b) V bool m_bAsyncFindRunning;
. ?1 `0 t$ |1 x, S HMODULE m_hADVAPI32_DLL;
' O! ]3 y2 d! \# l/ }" p HMODULE m_hIPHLPAPI_DLL;
, [- M8 }2 K% h" h0 x- d bool m_bSecondTry;: w+ {3 Q$ S( A) B* n% q
bool m_bServiceStartedByEmule;
3 o! J. P- @# m o6 c9 k bool m_bDisableWANIPSetup;
! O" D! J1 [8 u bool m_bDisableWANPPPSetup;
' }9 O; r; c( z$ ~0 O
( @1 P& H! t7 U/ N8 y- l( _7 {8 G0 g
};1 g4 i# I- L5 s% ]) I c7 P0 k4 V" J
r( s7 d& R1 X# }. q
3 g$ S3 A" ?7 Z8 b
// DeviceFinder Callback
6 z( i5 @$ s. P0 i8 y2 p, qclass CDeviceFinderCallback
" _( q5 C/ ~/ u0 O) t" c : public IUPnPDeviceFinderCallback
: x5 H3 K; P- D0 K* x' g8 W2 X% a5 T{
0 T- q2 I5 c5 B! O& c5 @public:
- A& q4 a# `; ~' L9 e0 B% ]/ s CDeviceFinderCallback(CUPnPImplWinServ& instance)
! c! O2 y! z4 Z* [, c$ u+ K7 W : m_instance( instance )
; k ^* L* z5 [9 x1 x9 D* L { m_lRefCount = 0; }5 d6 p8 |/ o; w
6 k, h2 Q2 v5 i( U) I7 t2 H
0 i! o' @5 u* h STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% i/ O9 X9 A/ o
STDMETHODIMP_(ULONG) AddRef();' V% e' p: S6 ]6 e4 u3 K9 n
STDMETHODIMP_(ULONG) Release();; K" [$ l& T1 V0 K1 l8 |! B
9 v: w4 g# ?- T# a j/ ^
( b C, [5 b d. z7 Y// implementation+ N6 q( C: K. f! r7 H" B
private:9 O& P4 X9 }- i
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);. i# |' U/ |4 X- F
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
4 X3 q1 p+ J/ C1 o4 G9 f% w" D HRESULT __stdcall SearchComplete(LONG nFindData);
, Q7 U. @. a- ?+ `0 H
. p$ r4 m$ }: F6 r4 Q9 h& F/ j- \8 Y+ @9 i4 M: c7 C8 Y) ?5 |0 z
private:
+ {3 M6 E! b r CUPnPImplWinServ& m_instance;% h X& C4 `3 a& `0 y; T
LONG m_lRefCount;8 Y9 M2 P! i- j2 }" }
};
; w3 x2 X, ? Y% E' S+ [
$ ~7 u. u2 u# d' y% u9 C, U$ K: F8 X* v2 O
// Service Callback 7 Z5 x: X' T* [1 j" }3 }& x
class CServiceCallback
( S, `/ K& k3 m- e$ y0 h6 C : public IUPnPServiceCallback
# G% ?$ \& I) R{- ` O5 ]) s0 d' l' g: S
public:$ |- ^- H5 u" K S e4 M
CServiceCallback(CUPnPImplWinServ& instance)# q5 c; k4 m( @# ?
: m_instance( instance )5 D- V3 i3 N9 z) Q. d# K+ f
{ m_lRefCount = 0; }
6 V2 I. ~1 g3 r) x8 }
! S& K% r/ j& J3 D7 |/ w, g4 h) D6 H STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; V: U$ k2 |8 c" v1 G STDMETHODIMP_(ULONG) AddRef();
1 G Y+ r3 D- I/ m STDMETHODIMP_(ULONG) Release();
' U/ {" k) j! ~
& Y& K# U7 ], y1 D3 M1 I2 s9 x% h& B3 j% p
// implementation
8 |! s# r. Z+ ^$ e- wprivate:& z+ `& x, K, L b( O9 ], b
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);. N7 o7 X5 v ?
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);, x+ x& U9 J) z
% j- |% R2 b8 p
! z3 Z8 I9 A9 L* ^& N- Fprivate: H8 A( V5 V4 Q6 I
CUPnPImplWinServ& m_instance;
9 @1 e3 t/ u* q) B5 f, j, N LONG m_lRefCount;
1 Q: v8 H& X3 u};
; v) h. |2 ]- j8 C- _
4 ^; X' s; \! n3 {4 S1 X6 F$ x+ U7 ^+ `, b A, D$ u
/////////////////////////////////////////////////: Q/ ^- v6 Z3 I4 H+ _2 J
, t, g# g8 E9 C a Z. ~' L. A$ W* G6 @2 T
使用时只需要使用抽象类的接口。
0 ?* I2 j! R9 F6 p( t/ b6 N, Z5 ECUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.! Y- }* Q6 x# V* i0 \" L
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
j3 h% _) d8 rCUPnPImpl::StopAsyncFind停止设备查找.
) [3 C8 Q) I; ACUPnPImpl::DeletePorts删除端口映射. |
|