|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: D3 A/ A$ q5 c6 A6 O
) C; R5 R, B- v! ~- C
# E+ T. K7 d, K, ~( T///////////////////////////////////////////: @' ^" T, }2 `& O
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
" R* N Z# ~" |/ q# d( [
/ z/ m& P, d6 ? V% X8 S$ J) Y+ o+ p$ c) P' x" e* n" @7 R
#pragma once
6 h) T' [1 J& a6 e#include <exception>7 Q: U5 Y( v- E1 U) y$ ~
7 w' G0 t/ ~% ~5 Y
( U2 _& C% _ Q2 O
enum TRISTATE{: B( _1 G& J8 A% z" p) b _
TRIS_FALSE,8 _5 [+ v- ?2 K. b
TRIS_UNKNOWN,0 r0 L1 W0 {* e, D* m! t
TRIS_TRUE
. @3 ]; ?0 A. G1 r! t2 {7 O};
4 f* E& \- Z# y7 e/ L( e3 |
; Q, C+ U" v" m: E, [* x% \! i4 Z0 c: |. X. _
enum UPNP_IMPLEMENTATION{
+ i+ }6 _5 E7 H4 X2 }% H* n UPNP_IMPL_WINDOWSERVICE = 0,
$ F% D: E6 Y+ @ UPNP_IMPL_MINIUPNPLIB,
$ T" O! P+ }+ O6 H: {+ N UPNP_IMPL_NONE /*last*/5 S# m. h& ?) w% q5 W
};
' t: T4 L2 `! r, g
. G) r& L* U9 w4 Z* ?( o/ _+ g- N. ~0 Q& Z& G: M+ [3 b# k- N: |: I
3 ~, R6 o3 t0 l! ]+ v
" p9 l6 @. a% J& \( q3 I- V
class CUPnPImpl
# r$ W. \0 w" x6 `{9 D) ~ D1 Q H) e) u7 K, _, x
public:
. S0 @3 U8 _: g4 b3 _ CUPnPImpl();0 M: I" X! z7 [0 M# [
virtual ~CUPnPImpl();
# M, g% E+ B6 M) \2 {8 }+ w* D; G struct UPnPError : std::exception {};
+ D9 i" Y3 r e& n* ]* E enum {
: I8 U0 k) e$ m% g+ s4 P UPNP_OK,
3 g% O @% G0 y n, T4 m7 \" s; ]/ { UPNP_FAILED,
0 A7 ^: w- {! Y4 n; [, w3 L( O; b UPNP_TIMEOUT3 b# }' d& K3 A4 r, ]' R3 k
};
0 w" N3 h R" \! b2 e; @0 g$ T, P' i% w( A. E; n1 V$ `
- o/ r" |- i* f' _) ]2 }3 E
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;0 }, ?, o, O* b- I5 j% g
virtual bool CheckAndRefresh() = 0;. `- ^9 v: z5 R# ?6 `2 y
virtual void StopAsyncFind() = 0;4 S6 M6 F+ q# W- E3 s
virtual void DeletePorts() = 0;& d8 P9 Q3 I! J5 V9 X5 k Q
virtual bool IsReady() = 0;
' U- O+ t, S9 N5 }: Z# k; r virtual int GetImplementationID() = 0;
8 G0 @ H1 `- l/ ]5 o + A, R2 t4 i) {$ g$ Y& `
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ M& {* s( |# w: g8 H% i5 p" Q2 q3 n5 N9 R
% H" {. b+ U4 Y; g" O; t
void SetMessageOnResult(HWND hWindow, UINT nMessageID);" h9 R; K1 H* U( B, h2 W
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
; M6 _1 {4 S/ r. Z uint16 GetUsedTCPPort() { return m_nTCPPort; }
- t# T0 ?. v/ g+ m( A9 \" M1 m9 c uint16 GetUsedUDPPort() { return m_nUDPPort; } * e* c% M6 w& ]# Z H
7 a, R: t2 u+ ]* |8 u0 j
2 o$ ?! G4 s& n// Implementation( h( u( g: X6 T1 U% K" m% |' Z; Q
protected:
0 }' _$ P& c0 r volatile TRISTATE m_bUPnPPortsForwarded;
' z0 B) L$ Y& ]3 q void SendResultMessage();. J6 B) l- j/ C2 y/ n0 U
uint16 m_nUDPPort;
" ]8 u( S$ T6 J" u; q! ^' |; g uint16 m_nTCPPort;6 J! t, i: q$ F0 h; A! ]+ j
uint16 m_nTCPWebPort;) H% C" [: S( z/ F6 i, D. `
bool m_bCheckAndRefresh;
6 J) E. ]! E$ f @" b1 L4 C
+ c j7 r6 \& l0 k, Z4 Q& H% a2 {9 k3 [4 x
private:$ d. u- r9 g5 Q" t" P. z
HWND m_hResultMessageWindow;
+ t# A0 @" ^/ ^3 m, d' f' |0 P UINT m_nResultMessageID;
. a7 g( Z+ N2 T! @: T) D$ t1 p/ J! P4 S6 D
" }( @) z& b% o4 b- R6 ^};
1 k9 D- i; {: D5 o6 `/ Z0 k. i7 L+ ]6 b* A% j
; B. K$ r( F* X& z4 W; Q+ O
// Dummy Implementation to be used when no other implementation is available1 ] ~2 o4 I S' F1 B
class CUPnPImplNone: public CUPnPImpl+ C6 {8 z. v9 M
{
6 a7 F, ]2 H! |$ k7 l! A: Hpublic:: p: x% G, r1 b0 D8 c6 R7 I- p
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }- P X( i! x0 v$ ]" m; B3 b1 Z4 o
virtual bool CheckAndRefresh() { return false; }3 b7 b% q& \& D0 M& E
virtual void StopAsyncFind() { }- E5 j" P, ~3 t2 t9 v) B" Y6 C
virtual void DeletePorts() { }" `. L' Q: r2 s8 o+ \0 I) a- W7 K
virtual bool IsReady() { return false; }) S4 m D1 ?% w/ X
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
- t" `3 ]4 i3 A9 R- S};
$ r& n2 s6 a' V- e0 ~$ n% ]1 n( l% U2 V* U k& k* P
N6 `% W, c4 p5 y/ |6 {/////////////////////////////////////$ c4 C1 @, B) ]" y
//下面是使用windows操作系统自带的UPNP功能的子类6 s4 W; E7 X" P" R% `' J7 Z
, ?# A& a& B5 _: Y% M: t
! ]# A& g' m" J! t; Q/ I#pragma once
7 [, l. t; k) j#pragma warning( disable: 4355 )
7 Y1 ~ o {& e# q4 y& [ n9 ~
/ q: W6 b* [. \ f# W) D3 E) _
& A, p3 Y+ \. W* \$ j#include "UPnPImpl.h"
& \' s( N) _7 x9 F#include <upnp.h>. \' P( Y5 I, K. X- Z
#include <iphlpapi.h>. `5 D7 U2 A$ J$ ^; o# w% m
#include <comdef.h>& U% t: _. k! F; W, S
#include <winsvc.h>- u' P4 Q* Y( ~' _
& K p1 z8 r6 L$ B) V0 u
- @$ m: T* o! k$ V- H& @* S% s#include <vector>
; W% L9 P4 t& Q( S+ D3 o8 m- G#include <exception>2 z5 A4 ? e! N
#include <functional>3 \* l1 ~, N7 z l( B
1 n; c, T' L/ V9 h- e! H/ n- y
" o' L8 Q% k- ~! @% c& M7 f3 j
3 U8 s1 H& X+ _2 @! @" \$ u) T: D, b( p2 u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ C# V- g J1 H" B2 F. Itypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;" L3 N' F1 c' O* o" j7 t' `
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;# g* T, w0 {6 Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
# ]/ L: U5 J/ h! e) C `8 _& jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
4 r- S+ ~( W# H; s8 H( m* Xtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( C: a. X! W1 c% b% F$ B1 Xtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
, L' m2 @& q2 z5 h
C4 P* {9 _: t9 q f5 ^
8 @; o" u. {+ `; Z; k8 c* Utypedef DWORD (WINAPI* TGetBestInterface) (
) a d2 y+ }' ? IPAddr dwDestAddr,9 s* t% L6 V) ^* l+ `/ i
PDWORD pdwBestIfIndex
* f$ O- }" K9 I( ?);
8 x8 R) c6 |6 D# h7 w$ U+ m6 W2 T2 s
, d+ X4 Q J9 R" F% utypedef DWORD (WINAPI* TGetIpAddrTable) (/ ^% o; P0 S- e: n" T4 m$ r( {. A: g
PMIB_IPADDRTABLE pIpAddrTable,& E/ _* D9 q/ O% ~" q) P
PULONG pdwSize,
5 o2 s8 W- H( e" p" V BOOL bOrder
5 s! W# C% }% E);& S2 ]9 J) q. }4 [+ {
, b8 N) T* g w. b! O( `9 U2 r
: Z( ?) K' }6 v; ~
typedef DWORD (WINAPI* TGetIfEntry) (( w P' j% [% R& o
PMIB_IFROW pIfRow+ E' t$ y4 ~7 Q7 s3 c7 x" R
);' a( i/ i4 D1 G
$ _" s: l, d) ^' P. v. [3 X
2 K/ z1 G; Z/ K" @2 K h
CString translateUPnPResult(HRESULT hr);; N+ a: x6 H; H& e$ j2 B) f5 X. J
HRESULT UPnPMessage(HRESULT hr);
' k9 q4 j7 A* C0 {) K
! |* i" |# \2 K$ X$ V$ F" e, [: z( ^9 V( l
class CUPnPImplWinServ: public CUPnPImpl
! L5 c' ^# A2 S l% e; z* m{* u$ {. w- s% v: R( i4 Q9 G
friend class CDeviceFinderCallback;
/ x2 }( n& v9 Y: N0 } friend class CServiceCallback;
6 k* D+ a2 ?* z" r) v// Construction
5 Z: G' C6 Q3 C( upublic:2 G) U1 Y6 }- k {7 F% `! d& q0 ~
virtual ~CUPnPImplWinServ();
0 y" Y* O; n) M CUPnPImplWinServ();
# z% u+ \$ U9 D8 n: e' l) b$ [" ` v! I6 k9 F7 {! V
' s. ~3 O1 l+ R% R% U% [/ J
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }5 o1 T' W. n( n6 M* ^. v0 J
virtual void StopAsyncFind();
- H, K4 ]: y+ N) n, a1 p virtual void DeletePorts();8 Z$ b; p$ t7 G
virtual bool IsReady();
, X% i0 M, G. x8 v* O4 r0 ~8 Z virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }, G5 i. e8 ?& f5 x: w+ _
& G& M$ D# R) r
7 I) \( i5 ?* [8 z$ a
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
_' F0 w& w- t4 R2 R4 W7 b // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later- b9 ?( i: u! ~
virtual bool CheckAndRefresh() { return false; };8 N" l ^: v: v% b+ H
9 N5 S- Y! J) Q* a" j. D" t" c- l; g1 m2 e
protected:' x5 J: `0 f( G+ @* m0 M
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);5 ]2 k9 D: f$ q t' C! Z& ?
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
. B+ R. c k- W7 G3 G4 L void RemoveDevice(CComBSTR bsUDN);* G" P5 C9 H* b* t& d
bool OnSearchComplete();
8 D2 O8 e. G) T4 |, ?+ b5 V void Init();
6 |0 I) W4 q0 f# Y
& Y3 Z' Y+ b- h; }. z4 `+ [. L8 ^
2 {+ O$ T7 b4 f9 n. u inline bool IsAsyncFindRunning() 3 V5 Z6 H( \5 D, S/ C
{
. x" s8 \0 W6 n5 i! S5 m if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )0 o+ [3 d( `2 M( C
{
$ T; a1 C$ I% s- f0 u3 ~8 y- j m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
; C# s4 y# A: q' p; G- y0 p m_bAsyncFindRunning = false;" N7 L: T" T# i
}1 X; {) a5 F) X+ w
MSG msg;7 ]. s% r2 a" |/ ?2 D+ x
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% M* }8 d& V" m {
! u# d6 K- d+ y' s9 L TranslateMessage( &msg );
6 t! W2 ]' m3 C7 T- L- I DispatchMessage( &msg );2 j6 I6 `: K- L* b
}
! r- z( C3 o$ E( y' C return m_bAsyncFindRunning;6 ~+ {& G. [# T) J& b
}
( B) O4 n% i/ q& @, f7 @- I3 v9 @4 v( D1 r7 j6 ]
/ X. a% d4 m3 x% {
TRISTATE m_bUPnPDeviceConnected;
; G' u& R0 T6 E
1 }5 S. S8 g; |" |; l2 w
% f9 i& n3 E7 f, p// Implementation7 Y2 P# t/ ~/ \! n& [
// API functions
# \( C& v- |$ M* { SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
% ]- m- b9 f& e% g% S$ K SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 z4 `/ X- a2 j. z6 a BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);2 {2 B7 i0 z/ ]7 _/ r! F+ c# J& f, l
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);# a4 l# ~9 S. t* T
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);$ y& j, U+ o6 e) H" l1 M
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);3 t8 b- b5 Y d) `% k( x* U
& a; C( Z! d8 c4 Z' I/ O# y0 Z8 `( B8 \
TGetBestInterface m_pfGetBestInterface;, o" ~' |% l' S7 A3 _% B! O
TGetIpAddrTable m_pfGetIpAddrTable;' s; g, J, e/ q, J( x
TGetIfEntry m_pfGetIfEntry;* Y4 _: a1 b" c. j! Q7 z( x
" t* E' W" o6 ]& ~& g
4 G+ \) H1 w# I0 I
static FinderPointer CreateFinderInstance();& x& [9 @3 t/ l9 l
struct FindDevice : std::unary_function< DevicePointer, bool >6 H" _! z# E( O0 a$ o0 D# v3 ?# q3 Q
{ Z, o! J- V3 |' b+ I
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
1 g; |- K/ p6 h result_type operator()(argument_type device) const
* Q1 ~$ R2 P% f, X. I! a/ h- ] {
! c4 \- q: H* t1 Q F1 [! P0 H CComBSTR deviceName;
, G. m0 t" K7 ?5 _9 y HRESULT hr = device->get_UniqueDeviceName( &deviceName );' x. v+ z5 d/ E
' H: o" b& X X9 A( Z Q) n* B
% b3 j. H$ s' ~) N if ( FAILED( hr ) )+ O+ q7 N9 w" \
return UPnPMessage( hr ), false; V5 l4 K4 ?: ?9 E- t/ @
7 ]8 l! Q! z6 |0 f6 N G2 `
2 o1 Z9 n L- \2 Y- @ y! Z return wcscmp( deviceName.m_str, m_udn ) == 0; [- P* i" I1 ?' M
}
: }6 w/ U. q" J( T! i4 K; p- A CComBSTR m_udn;
" T3 v4 t9 o9 l h4 e: U6 l! t };2 ]1 ^" A, d6 T
/ A" e0 Z. L& p' `3 f: n6 {8 B
void ProcessAsyncFind(CComBSTR bsSearchType);
/ t) j# |9 P) ]; T! { HRESULT GetDeviceServices(DevicePointer pDevice);
6 R+ p8 w6 V1 X0 G void StartPortMapping();/ `6 f; X" S3 n+ O; M+ J! ~
HRESULT MapPort(const ServicePointer& service);) O( ~# j+ M) e* y. t
void DeleteExistingPortMappings(ServicePointer pService);
+ D$ M9 W% K7 Z. R* ? void CreatePortMappings(ServicePointer pService);' a' ^/ B( m- l6 {
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ d) V& _1 O5 f
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, : Y1 q8 O: r/ n- Z
LPCTSTR pszInArgString, CString& strResult); c* D o2 ^9 m5 ~2 x, d; D \9 b
void StopUPnPService();7 X0 \% o: m% w# S
J2 |0 v& B) k; ~9 f9 w2 I( V- N/ O( O5 z
// Utility functions
1 U/ ^/ e$ f- b: q HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
. M/ `: S" ~& U& y6 }6 z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars); J8 ^; D$ j! \
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);* B3 Q: c9 Q* m( e1 b9 [2 G8 t
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
: i% }7 @2 }7 W0 Y HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; ?. E" i% ]/ H" K' o HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);, \. u7 r7 ~, H) r% g- i
CString GetLocalRoutableIP(ServicePointer pService);
! F5 @. ~3 |4 m) p
* @3 K) c. h* M, e3 H5 X7 }9 O$ {) I& i
// Private members8 A* Y: ^# ~# W5 J {2 P2 w
private:1 d: D2 p7 `2 J$ T- f W# t% O
DWORD m_tLastEvent; // When the last event was received?
" S: u' ?% w- G" p& b std::vector< DevicePointer > m_pDevices;& Z x$ {" {9 C6 P
std::vector< ServicePointer > m_pServices;
) {% }7 V8 E% Z A2 W FinderPointer m_pDeviceFinder; k- Q, p! y' s/ ]
DeviceFinderCallback m_pDeviceFinderCallback;
1 l6 R7 \% y6 @+ o9 [6 K& ^1 F: \& g* } ServiceCallback m_pServiceCallback;- n* z# S$ s, Y) C
) e! ~3 [7 L' J
: d! V9 @6 u$ Y/ j" C' [. X, E+ G LONG m_nAsyncFindHandle;
4 b9 X7 J/ Q6 E5 ] bool m_bCOM;0 Z# A1 b3 ^6 o) ?/ l9 T
bool m_bPortIsFree;
6 k4 r: {$ x) E$ M CString m_sLocalIP;+ x# C9 l8 b, G
CString m_sExternalIP;
" I( P5 w; [) A bool m_bADSL; // Is the device ADSL?
+ ^. t6 y1 ]; ]0 g: o bool m_ADSLFailed; // Did port mapping failed for the ADSL device?# p, e* T( J: T A+ C t
bool m_bInited; n, ^% M( H/ d% R2 F. l0 K
bool m_bAsyncFindRunning;1 N9 z, ^/ e# i n
HMODULE m_hADVAPI32_DLL;
# q( v. I, m1 U3 k* J HMODULE m_hIPHLPAPI_DLL;
% I7 h3 k, F" _2 i/ _0 E bool m_bSecondTry;
7 e3 I& b, U" d2 M8 i bool m_bServiceStartedByEmule;
# ?9 I) A( b. j, b% J7 ^9 ? bool m_bDisableWANIPSetup;8 p/ w" n7 i/ O" u2 L0 C4 }% n
bool m_bDisableWANPPPSetup;
5 q2 ]* @- l# e% w* s7 L2 x
* |+ c- y, v- N0 O3 @+ F: N. Y
, U1 Q1 F, S2 L+ k! `% w- K};( \, u- G" ?7 Q: f: v! Y6 @
* i9 ]" P8 W4 r- C) J, f* O- i! g4 B3 b: O5 h
// DeviceFinder Callback+ w# e, r" b, H. y6 ^
class CDeviceFinderCallback3 S _% W, I8 ^. r+ ?- R! h
: public IUPnPDeviceFinderCallback
0 k& i2 ^- K; Y' s3 K{3 z5 X( G: ^/ X, Y2 @
public:- e) O, k" R1 q* K8 P; M* P# ^6 j
CDeviceFinderCallback(CUPnPImplWinServ& instance)' ]5 P: g" e5 b1 n! |
: m_instance( instance )* i6 r4 |: Z w: l
{ m_lRefCount = 0; }
0 ]5 t' F+ U- h6 P9 c* V* [
! f! e* e* V V6 t( {- e; Z: J; g: M2 c1 z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
* [, A6 {9 L) p+ Z" s& f* X STDMETHODIMP_(ULONG) AddRef();- I4 M! U6 Q- e) @. V# A& v
STDMETHODIMP_(ULONG) Release();
% ^' \( \/ r% O, J' k( H* o( g% h$ A+ d4 t/ H' }0 x
5 l/ H1 S! f k5 D/ Z; D
// implementation
+ W7 ^8 U) B0 v0 R! wprivate:6 \& {0 _' D1 T% ^; U
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);, O; ~ c6 W3 r. p( L2 Z9 w% ~% \; [
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);5 o/ S9 d9 ?0 B+ O* z( V. Q
HRESULT __stdcall SearchComplete(LONG nFindData);* N, A- c2 a( ^- b" |
/ ~' r. R6 ^: Z1 a+ |: Z( ]5 @2 }' T: D
private:3 @9 Q# G( C- u1 w2 ?" @* z
CUPnPImplWinServ& m_instance;
/ R* ]1 a% J5 |; r- N1 C& @. g LONG m_lRefCount;9 t+ l6 E Z2 m
};
: I6 o9 ]# j$ o, Z8 ?9 C0 T) U; S
: l# v0 J, H* i4 V! G" k
// Service Callback 6 X# X4 Q! t% q- `7 M7 g4 s
class CServiceCallback
, @' A9 x) X; j1 ~$ Q$ ^0 I& y& G- V : public IUPnPServiceCallback/ R, m: y) j" h% D2 O+ S. u
{
, z% ~4 l- Y ?% ]5 h/ Jpublic:
5 k/ c% o* {- C3 m4 K. R CServiceCallback(CUPnPImplWinServ& instance)
/ Q, n9 W, t, H : m_instance( instance )
% Y `0 C' v. ?1 l { m_lRefCount = 0; }; |; b% u2 g& e; c: a- D
" ?( m1 a0 O8 m$ P STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
* E1 t& k. j8 B( u! F4 T% ^ STDMETHODIMP_(ULONG) AddRef();
# D: C3 ^9 P4 n4 W6 x; }+ G STDMETHODIMP_(ULONG) Release();0 _3 f( G! ~' V5 b6 L
: l I, W% U \. B
8 c* A( ^' M& x f// implementation+ K* m: @5 g$ I/ d2 [( n' b
private:8 \2 K8 Z9 x6 \2 S8 a: ?
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 Y2 f* {6 X7 |1 C4 B* J
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
* K* w# P" d2 L( [7 Q
3 s6 h9 c( z- P5 Q# G7 o4 y) r/ P8 N) Z; ^; F! ~
private:! _/ @' p: @; U; I* I% ~9 A; d
CUPnPImplWinServ& m_instance;& }; p4 I$ \ a, E
LONG m_lRefCount;
7 a, \- V2 `5 M, f8 f};
6 P- c7 ?" O( g/ s/ r
* u. o) k. z4 `. ?+ i/ m
2 ~2 a; d' @+ @% Y5 G/////////////////////////////////////////////////; F7 `' t/ C+ m
# n7 D |; i7 A" ^& q
- i: ~' H; t8 t) a使用时只需要使用抽象类的接口。
$ B3 h8 ?0 N' gCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' \! L* _' u# ?0 Q7 w3 A& n7 @CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
) ]& d# y+ Q# {; g0 p$ K3 JCUPnPImpl::StopAsyncFind停止设备查找.
) H, `% m! i% ]: W3 T( W- v: nCUPnPImpl::DeletePorts删除端口映射. |
|