|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,9 q8 b* r3 {1 D- f% m6 U! [
: H8 p9 A' s1 A l W# y
5 V, Z B4 N% \# b1 @) ^///////////////////////////////////////////( w m S7 p0 e3 E7 P2 r
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% h" {! y/ l( [( N! T( z( Z0 t
- y4 o4 ^; z7 X2 D8 k! Y* o( V
+ Z8 [0 H0 v/ C; d
#pragma once
& e% I1 i# \* y+ o7 p8 t( \5 x" D#include <exception> E/ q- Y' r- p J e0 N
4 Z( S0 A+ ?' D Y# ?! T6 m/ ~ z+ L6 B8 {! \( u6 T- h
enum TRISTATE{
9 @$ `& b% f$ d& n TRIS_FALSE,
5 R) o+ b$ |- U TRIS_UNKNOWN,+ z0 `, V9 Y* C+ Y. }
TRIS_TRUE# d* r$ W; O$ N
};9 K* C7 d l4 N- E' ~% Q3 |
/ I5 M K' z7 s
5 B& m5 ~7 `: h& Senum UPNP_IMPLEMENTATION{
) f: A5 D* ~$ `, ]' | UPNP_IMPL_WINDOWSERVICE = 0,/ h- \5 X( L( H! B8 f: @0 A. R; d
UPNP_IMPL_MINIUPNPLIB,, B& ]1 ~* j3 c9 K7 g1 N7 c j, O
UPNP_IMPL_NONE /*last*/+ K: a/ w: z+ z" u) X% q
};' @& M9 y g( X* R* J& p; w
0 K7 u# Z3 Y0 g
$ V6 ?& O; _. b- M- C4 a
7 s- D3 O6 n" w: K
' {6 s7 d/ D2 S) O, C) m9 xclass CUPnPImpl3 B6 q1 z, }- O" o
{
) R! E" |% T& _) o; upublic:
4 O$ A0 T6 _) k- Z9 e- i CUPnPImpl();
, w& M6 v' Y8 H t0 i virtual ~CUPnPImpl();
* k; x. e [, w" p1 N struct UPnPError : std::exception {};
' ?, W" n U0 m( O enum {
: p+ U7 I* m2 L2 u& ^ UPNP_OK,
8 H) a7 A4 s$ v( i UPNP_FAILED,
7 a& A: H7 L& U! b2 q0 N2 U1 q UPNP_TIMEOUT' t5 G; Y f" v) k
};! m. B6 ?/ |) C# ^
! m9 i; `4 N# \6 ?' u/ ]# C
$ K0 g [; l, J$ r, {. k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, a- E# |6 y: h+ r
virtual bool CheckAndRefresh() = 0;/ s* Y" m: R# s! Q, H
virtual void StopAsyncFind() = 0;
7 r% K# M. u5 }; R: T virtual void DeletePorts() = 0;: h" u* a) x& X x. U
virtual bool IsReady() = 0;
6 y5 t: H X4 _3 ?5 f- v$ d+ Q6 d virtual int GetImplementationID() = 0;
/ f) H8 f& ~/ ?. f( x / H- s% D- R, u" f9 V7 z
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) C0 W' l* p7 c' c7 Q- s% x
4 w) {( s" e( S- G3 ?+ x' C2 A d
/ R. R' P( D5 X% H$ T' ]" O void SetMessageOnResult(HWND hWindow, UINT nMessageID);: A" u" w( `0 @# ^' a- P. u
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }4 G3 _) @6 P8 I# e O) U4 |6 P
uint16 GetUsedTCPPort() { return m_nTCPPort; }
7 e% g5 ^8 S7 ?$ x uint16 GetUsedUDPPort() { return m_nUDPPort; } ' V/ d6 d4 ?7 d5 E$ Q
* [4 r9 N( s7 {# P* O! Y
: ^4 V$ `% n7 N) U$ f3 J. t// Implementation7 Q6 w) }* F* P5 R, z# Q
protected:
/ j5 `) V9 {+ q# H0 z volatile TRISTATE m_bUPnPPortsForwarded;
6 F/ n1 y% r* U+ ] void SendResultMessage();
% S- j+ Y" O: u uint16 m_nUDPPort;1 A* D! Y( c% f* \2 t
uint16 m_nTCPPort;
% j1 |4 M9 B9 M6 j* U3 u uint16 m_nTCPWebPort;5 y2 z! m* b3 ^' d# s! R1 D- d
bool m_bCheckAndRefresh;
( S+ c! i0 V/ ^3 x5 f
2 l& ]" O8 t/ @& M7 u5 ~# x5 U0 E8 R) D) O! S* H- N& P
private: ~2 R M7 ~% f7 ]: I
HWND m_hResultMessageWindow;
v9 I( {- |, }6 p& e; b: b$ J UINT m_nResultMessageID;
; R# }/ T: o$ L+ B
1 O1 { u" l* o& M( j$ _/ e4 R- g
) F% b( _8 T# \! ?( f};$ U- K2 z/ D: C1 R
2 H @, z- C% p; W$ ?8 g/ p p# m! |
" Z: |4 U1 \" c// Dummy Implementation to be used when no other implementation is available
# f# L# ]* U Gclass CUPnPImplNone: public CUPnPImpl
3 }2 y/ D# n4 X2 _. W, ~9 h{
1 i- c# w" r% L( y+ M S/ M9 U9 @public:
2 ]9 N3 I( l, U! W9 ~7 U virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }& c( e4 p! s6 R& K1 _
virtual bool CheckAndRefresh() { return false; }5 q( }8 |( L, d- D* q
virtual void StopAsyncFind() { }6 P$ P2 B8 M/ @. ^5 A/ y- L
virtual void DeletePorts() { }
9 U s$ U5 Q2 w% F7 u9 R virtual bool IsReady() { return false; }
4 @" B6 K2 J" x" `! \" H# t; G virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
2 `" t7 I4 V- z5 j, G};
" @" E2 J9 a" S% J
0 Q3 I1 O6 w9 J( y9 @/ M, n) [0 |# d! H
/////////////////////////////////////6 r2 s H! p! x
//下面是使用windows操作系统自带的UPNP功能的子类
- S0 G3 L0 R8 e" U( N
- q8 A( c, ^& H* p: E: V- E, a0 i/ h! U8 e8 Y$ J( W
#pragma once& }" p7 Z& v+ _: D9 h1 f0 N1 O4 k
#pragma warning( disable: 4355 )+ u& b! w$ A7 p2 E
" I% _, \! y% x' U* J. X$ R$ n2 K4 f. K9 _% c( \
#include "UPnPImpl.h"$ u3 L- m, L6 r: S* I3 B3 Q
#include <upnp.h>4 x. l# M* K& n$ V
#include <iphlpapi.h>
5 w) f r9 _9 W* Z#include <comdef.h>
+ @/ Q% w! e# @$ ?; h$ g4 H#include <winsvc.h>
. c! r, h- Z# d7 X
2 Y+ s& C( p2 b& v3 b. b5 E3 L
7 w; d* T- e% J5 k#include <vector>$ e8 @2 X8 U! ~% L
#include <exception>
* `# p7 T6 J6 E+ t6 u4 N2 f+ H( q#include <functional>" B. I( I2 T6 }
4 S5 W @5 z# g5 o1 F# n' A9 k- ~
% U+ [/ Z( }/ h% K6 s6 O/ h
/ t' ]; ~+ z5 v0 h: G/ N) ?
9 b( }- E' Z5 r/ ctypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
- Z+ ^- ?/ k4 M: ]+ Dtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;& b- Z% i" G/ A6 H
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
. \' D& u4 g6 ]& |2 y2 [typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
( n0 T* z5 R* O: w2 _1 |4 l2 qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
! _* |1 u8 x: n3 `' wtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;2 G7 ]! d& ]! t5 @. B
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
7 r/ E8 f) `2 ~( m- V0 d6 l2 M% I$ E& h3 p/ Z- q
" s7 v6 E3 j$ q6 Ttypedef DWORD (WINAPI* TGetBestInterface) (0 C, [+ ? |* d" X* ^
IPAddr dwDestAddr,
+ ~0 F( Y: H$ Q# Q PDWORD pdwBestIfIndex
0 n9 s8 y5 R7 L2 @);
: E2 f, N q5 \$ y7 L0 x. @) b0 G+ Y: V# F
6 `6 o; ^) ~& j1 H/ L9 l4 \typedef DWORD (WINAPI* TGetIpAddrTable) (, K8 n( P$ F* ~0 W4 q$ l
PMIB_IPADDRTABLE pIpAddrTable,
5 ^4 ]6 h1 I' h. L8 y& X& F PULONG pdwSize,
E& ^" O6 b) S- M# A- M BOOL bOrder) y3 S% T' {; D# R2 p
);
& _! n, }6 K: m2 F4 H0 n- i4 l+ I# `9 H0 q! d' a" w; {$ j* f5 ?
# h) ], ^( n* Ntypedef DWORD (WINAPI* TGetIfEntry) (: v, v; x% S t
PMIB_IFROW pIfRow
8 T5 N) s0 i) q8 ?7 E) o$ ?" F4 x);. s4 k- M5 A3 v: C6 ~, a
3 }0 D7 S) Y, Z5 ] T( g
3 Y6 v. X, v+ O* Q+ v3 b' Q. cCString translateUPnPResult(HRESULT hr);5 \7 g3 a M) ] H# b
HRESULT UPnPMessage(HRESULT hr);$ Q* x3 I8 U- v- |+ I1 `9 m
1 v. l1 _. k# {' M+ [9 k+ V" v
class CUPnPImplWinServ: public CUPnPImpl
5 e# \* d7 H0 Y6 x Q: _) f{- |. R0 {1 D9 v" U& m& p
friend class CDeviceFinderCallback;
9 L: ^+ }8 f7 R7 q$ o# V; x5 f1 o friend class CServiceCallback;# O& s" ] E7 `8 Z) P( Q
// Construction
+ f! N6 \# ^& s3 |) r: tpublic:
; b u3 [) ~% _3 X) r virtual ~CUPnPImplWinServ();
l, i# O8 s/ m1 N& e CUPnPImplWinServ();
9 W( s) X0 N# ^6 w7 ~1 P- R
: C, g/ ]! }% @$ k4 W4 i. ~' ^* A2 c% w# O: |" m! G- e" f0 T
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% a/ q5 f0 c1 ?' Y virtual void StopAsyncFind();" Q$ R1 I* R: S# i& u8 i
virtual void DeletePorts();% E" N2 Q9 ]4 t- A$ b! l; H' c+ J& C
virtual bool IsReady();
2 m% T+ v1 i! G3 w3 l% i virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }& L& [% ?) N6 e8 [9 |+ h0 W
/ X% X1 X5 _1 B
. W% @/ j$ y4 \* O0 ]0 G, p8 e // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 U1 n7 w0 o5 k% p // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later5 J6 m. n: k6 m* ?
virtual bool CheckAndRefresh() { return false; };; a( {1 }. n5 I4 U& Z2 f
# D; V4 l6 u. Q, q( \1 K W
$ v7 i1 c' @ K0 s$ tprotected:/ W+ j4 e" ]7 m& Z! c( G6 t% k
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);+ E8 M% e9 z' a% F( F
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0); n" I' N$ g8 v9 }/ [. O
void RemoveDevice(CComBSTR bsUDN);' E& q! }1 v: S& y( `
bool OnSearchComplete();- H) y K0 Z. C% }
void Init();
6 E0 U U" q1 I9 B+ U0 t2 z- K, B( p
- H I6 C' w, `) ]7 Y( V
inline bool IsAsyncFindRunning() ) A4 w5 E; g8 n7 [6 O& O
{
/ @1 w0 i5 W4 G. v3 L5 H if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); s! Y8 p% F& T' @ A
{5 C: n( C8 ~) C! c- V" J* P
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );7 I( F3 W3 x6 j, C3 V8 Q
m_bAsyncFindRunning = false;
- p5 l7 Z% Z5 W. r7 h( }% L7 ?" K }+ E% h- v% D# x) J
MSG msg;
5 `1 k9 J' L( r* A: f while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )1 M0 W: t6 M' i) B. Y; ~' T2 ]" v
{- s0 v. V/ b! W# f; z
TranslateMessage( &msg );& ]: C# z! n$ }% N
DispatchMessage( &msg );7 F& j# U0 v- E
}
. |2 }! N0 V3 b+ d9 k& u. H return m_bAsyncFindRunning;
- U) w; k x! b) [+ `% J }3 E* g! h/ R" u: L' ^9 R
+ U, [& ^" U/ A N6 \
. n3 c3 p$ u( z* `; B TRISTATE m_bUPnPDeviceConnected;
. s1 K+ r) A- S( \, I- ~( c" T( P' T2 Q
Y1 ^! a7 g- ]- \! K
// Implementation
! l) R1 o, G3 s$ \' k9 e4 L- [$ i // API functions
( b: b; [6 z( B& {/ U8 O- T SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( C8 D2 ^8 P% U' x; z Z: j
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
6 v9 o' o( `, {. {3 g+ t+ V BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 Z) U2 H: T( G4 Z+ y, H# u
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);# |5 K3 L5 D- c1 H$ w8 o2 ~4 I
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);- Y7 z% S! V4 h+ p7 U# f
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);( j! [5 D( K; ?
u1 E. v* v& t1 A o' o
7 R* a" v, d+ e
TGetBestInterface m_pfGetBestInterface;$ @8 e9 ]) v R. m& _+ R
TGetIpAddrTable m_pfGetIpAddrTable;: [+ E( G4 ]% c/ \5 n1 D
TGetIfEntry m_pfGetIfEntry;
9 P0 N& I% P4 i, i2 \! _0 N: }1 p3 D( g2 P3 ~
. K r9 L0 F+ d$ P static FinderPointer CreateFinderInstance();
+ N. N; s2 A# B& O! k' N struct FindDevice : std::unary_function< DevicePointer, bool >' ?3 V0 g5 Q7 q- r. Y6 j7 V
{& @: m+ o& M+ t- b, n
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}3 V6 L) c$ u" L1 K6 e
result_type operator()(argument_type device) const }8 @/ v) l' N. R" I* C& }& ^
{
8 m2 ?6 w% s' i9 s3 k CComBSTR deviceName;
; K, d4 j5 G1 L( f HRESULT hr = device->get_UniqueDeviceName( &deviceName );8 Q+ C8 p' i" D1 S% _9 a' j
# R6 l. {$ |& s( }8 t
, B! X. s8 p4 T5 r if ( FAILED( hr ) )9 u7 M3 X6 v* t# D& Q: @
return UPnPMessage( hr ), false;
1 P1 [& T3 {% g' F8 f" X6 T+ K0 o
7 U" i* L1 K0 b3 R: T2 P7 c% i& \2 \7 ~4 f: S" b2 ~ X
return wcscmp( deviceName.m_str, m_udn ) == 0;
x) w& j, j! z- x* q; Y( S% t }" Z z- }+ D5 e/ P- J! }
CComBSTR m_udn;
, F) ~( v3 f2 ` };* D% W9 O! Q* A+ x* a# V
7 Q* f4 E3 h/ Z, ] }' R, \
void ProcessAsyncFind(CComBSTR bsSearchType); C7 h" ?- {1 @
HRESULT GetDeviceServices(DevicePointer pDevice);* h* U. v$ a/ J
void StartPortMapping();
: O3 n% y# I0 W$ m HRESULT MapPort(const ServicePointer& service);
1 H. b1 j( D9 Z void DeleteExistingPortMappings(ServicePointer pService);
* S2 x( ]1 E) M7 m2 V. [" Z/ [ void CreatePortMappings(ServicePointer pService);
0 C2 o/ S% f4 f( M5 A# b5 q HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
2 v! h6 [% x& i, u) }2 e" v HRESULT InvokeAction(ServicePointer pService, CComBSTR action, $ ]9 C! q3 W( z! B k# U4 e
LPCTSTR pszInArgString, CString& strResult);
3 F/ U: I" \- [; o5 X( n void StopUPnPService();2 N7 Q3 B& z/ J1 Z
" Q$ o2 e2 F _' l2 q
3 c7 a' t D2 L; m
// Utility functions
' _) [ p# X& J+ v5 L' a HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
( L. s) |9 v y& a INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
3 o7 B; F; h- V$ ^9 a5 w( W3 } INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# \! {2 @ {8 O void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);% K' g, z% V f8 U7 v' H& M' S1 m: n
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
% t; x) G3 @( q4 \) m% m HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
+ ?3 ]7 Q) z; v4 P6 u& p2 U CString GetLocalRoutableIP(ServicePointer pService);) l9 N* m7 d( \1 `5 t r% Z
0 v: t' L2 V2 }( }
9 C( d/ ^2 e/ G- C// Private members5 I2 B( ]8 |- J; R/ Q
private:: n3 s% z3 F+ I7 h- \7 ` _( y
DWORD m_tLastEvent; // When the last event was received?8 g: k; Y# e; D& u6 U4 S5 H
std::vector< DevicePointer > m_pDevices;
- X1 V/ |& |0 n; u6 y std::vector< ServicePointer > m_pServices;
+ C+ J0 S- r* r+ `: d- _2 h FinderPointer m_pDeviceFinder;' t: V# \+ D% O+ n
DeviceFinderCallback m_pDeviceFinderCallback;
: N0 t- U# F6 a* U2 W- J. F8 \ ServiceCallback m_pServiceCallback;
I' [+ Z) c" i, X- x0 o, W( e& d
* u d5 ]: o5 @0 e0 l7 E1 N5 J- \1 Y/ D
LONG m_nAsyncFindHandle;& ~/ q( ?1 [& h" A- o' g/ P
bool m_bCOM;1 ~) D) |! K) j% D' q
bool m_bPortIsFree;5 L! N& k2 j/ j* [9 _9 C0 m
CString m_sLocalIP;
9 f# u/ h& g; t- f i, I CString m_sExternalIP;
- \8 L% v+ H& c9 I; q% c' C, R+ [ bool m_bADSL; // Is the device ADSL?
- }! }/ Z! _% {& J; z' I$ G bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
8 Z. P1 s! Q( w bool m_bInited;' p0 B7 `2 p: Z5 r
bool m_bAsyncFindRunning;
, O5 O+ T. C6 m( l5 i HMODULE m_hADVAPI32_DLL;" k$ X( t; a4 h9 J: P0 { Y
HMODULE m_hIPHLPAPI_DLL;% M7 u i# H2 e+ w4 ^! S7 Z6 H
bool m_bSecondTry;
5 |- _# g- w- t* n" o% r# C bool m_bServiceStartedByEmule;
# o: i6 g* I9 o4 r, V bool m_bDisableWANIPSetup;+ ^ r6 l6 l- h- {0 y( S
bool m_bDisableWANPPPSetup;
" O$ D: X7 f* o+ R$ n$ B' U5 ^/ N# t# D8 |0 J. T
6 f6 s0 u1 r$ A) X};
0 w5 @5 l8 E& x8 M
$ _5 D2 v- j4 m4 H
; X( ^4 T$ e0 i// DeviceFinder Callback( p1 C/ Q! ?% h7 J& D& W
class CDeviceFinderCallback
1 A1 |; n8 C/ W' [( Y% u : public IUPnPDeviceFinderCallback+ O4 p: H3 }. c, B/ r2 t
{2 Q+ f: Z. o! i/ L' \9 I5 K& J
public:
$ e0 r& J I* I6 f9 B6 C* h CDeviceFinderCallback(CUPnPImplWinServ& instance)
6 f* g& \% Q* I' J1 x. d : m_instance( instance )
* C9 \! \9 N) x7 Q. a3 x" J { m_lRefCount = 0; }% @4 L, a& \& l" Z8 R% w. G
6 z: v, ]$ c7 H7 H; e7 O P. S3 a
: [" s/ n% j3 |& W STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 ]. S' j# y9 L1 k- i STDMETHODIMP_(ULONG) AddRef();. |8 G, N0 j7 \
STDMETHODIMP_(ULONG) Release();
0 s' }$ W- p5 Q/ d/ S4 h! w& V' s8 M
' p; {4 T1 @' R% E- ^* Z- K// implementation* b F2 q8 b. ]9 s6 ^/ X
private:
) e2 L9 G+ y/ x, @5 x, N* Y HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);8 _+ l' O+ B8 `' X& u3 Y8 r! }
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);2 Z0 A. R0 A- a, t6 F8 G
HRESULT __stdcall SearchComplete(LONG nFindData);
6 d9 Y4 I' H* p# f: y- U- y5 i1 o5 J$ g, P. c! T
% o: x+ C4 e4 q2 Qprivate:- Q' d1 W7 h8 {$ s5 v
CUPnPImplWinServ& m_instance;! t% g+ K. M2 h% d$ `
LONG m_lRefCount;* J+ @9 ~$ Z; Z. l# k
};
) {; R B4 V t, Z. ]& k' z1 f {8 J) H! t7 Y
, c) D, N0 o+ ~- t
// Service Callback 6 I, j* b$ P0 _0 o7 `
class CServiceCallback$ U1 r" r" v8 l, J) S8 ~; v
: public IUPnPServiceCallback# j3 y2 i; }% ?, E# q$ x$ N
{
! Q8 W9 K& i& P; [; G: s1 M4 E3 Lpublic:
7 i) ?3 K5 K( k CServiceCallback(CUPnPImplWinServ& instance)& F; c Z' x. W1 I* y8 W
: m_instance( instance )* w4 }) p4 l/ E; v
{ m_lRefCount = 0; }! [" g) w5 Z3 _% X2 E& Q6 h
8 J& J) B% I. D* b8 \' e STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& s& x5 ]& g; N' o6 c( y0 }
STDMETHODIMP_(ULONG) AddRef();
h, ?1 J# b1 N: p! i( g STDMETHODIMP_(ULONG) Release();
2 B: z8 M7 n! G8 L+ x% ?' j; r' Z$ f+ K# E' G
( V+ U g" d2 s* ?. m; E
// implementation; F4 G7 n! a Z- V
private:
! t( j% M' [6 m: Y4 c HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
/ J# P. h$ n* m: s9 |' H$ l# U! T HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ v g l( @5 o" L. E
/ P" J3 q9 T( _, J$ |# N! B! n1 z, E
private:7 d# m# p# e$ G5 Q" d5 K
CUPnPImplWinServ& m_instance;
; c" r# G9 x; |/ `( o LONG m_lRefCount;
4 x$ H: u( E6 N/ s% r};
# Y! h9 Z; a7 g
F6 l: t1 X* x( {+ {9 N) |
% p, [7 `! J }/ F/////////////////////////////////////////////////' I. A+ r+ i0 }" b: i, |
3 C3 H" q3 |: d- l$ P
, R8 K+ |+ L1 \' @! b0 ~使用时只需要使用抽象类的接口。" w3 q8 X7 {% _& e% ?7 P
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.8 d: g8 b3 r2 l0 I
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
0 L: K0 \ u1 |$ h+ C5 j' xCUPnPImpl::StopAsyncFind停止设备查找.
: ?" A+ \. D5 E9 H1 Z8 iCUPnPImpl::DeletePorts删除端口映射. |
|