|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: z3 a, l9 Q( v" ?) U3 U2 i) s& Z, Q* |7 p! o) b
, _' B( @7 x- I# ]; h! [& \///////////////////////////////////////////
i7 w% U: B6 \, O. j//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
. ~3 o) r6 G7 a M& V2 u
" w+ }4 @6 a6 I" B3 d3 m! L* B( Y( q
#pragma once
0 `: h u5 _8 H- k#include <exception>
" }3 L5 M) X* Z L7 k
4 R5 o) M* K' W9 A
: p6 _. X6 z6 B7 f6 ]5 W/ w enum TRISTATE{( F# n+ G, R8 ?$ y
TRIS_FALSE,3 }4 c! K& s% B
TRIS_UNKNOWN,
|5 B" v! G- N% b+ L TRIS_TRUE
& G8 `/ w) _, Y) k0 f};) V |8 Q0 N- I& o
( T$ K0 N* z. R$ B' [$ f* g* X' ]- `
enum UPNP_IMPLEMENTATION{9 ^& T3 G! `8 D6 |
UPNP_IMPL_WINDOWSERVICE = 0,
; _$ ? e: L* S1 T$ D7 j, M UPNP_IMPL_MINIUPNPLIB,
/ P! W; F/ I9 g UPNP_IMPL_NONE /*last*/
$ u8 x4 v0 X- \2 S* s};
: M: w9 U. j# @0 ~: u4 V% D$ a5 ?7 w# A1 t+ d7 r- l
2 {* S5 U" U0 P* k7 T9 F! k7 W, _$ R8 G! r. Z; u
' H2 G5 t/ Y E) X. ^; E8 {
class CUPnPImpl8 X8 g. k2 |( q4 S. |6 A
{" _0 p( u- ~- f5 w. x+ z
public:
" z1 H2 {7 u- |$ I; Y, A0 C CUPnPImpl();4 r8 w5 ]/ x* M( t W! g" ~ p9 E
virtual ~CUPnPImpl();
& h6 ^: B- I1 U, f9 j: I3 E8 s, Y struct UPnPError : std::exception {};
# W |. A' ]% u" u$ `- { enum {, a6 y9 N& K7 j+ p7 R) a
UPNP_OK,
$ Q4 ]! o, S' g& Q S7 Y UPNP_FAILED,7 [! X2 S5 j) K Z% ~1 b) w
UPNP_TIMEOUT# h( L, E& u( I( k, r* S4 ?
};
9 h; ?: Z8 ?5 |- v) _6 J8 ~9 q6 [* G* q3 z4 X
; c2 w$ d$ k* H3 }) A
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
1 o1 U$ G5 u% O6 \* s0 f& H- S virtual bool CheckAndRefresh() = 0;/ a( @7 ?+ C3 d* x- H/ n! T5 O
virtual void StopAsyncFind() = 0;
/ J2 L. k) @( [/ T virtual void DeletePorts() = 0;. J% ]. @" u. D- d
virtual bool IsReady() = 0;
8 q6 z" D p2 E3 i; z virtual int GetImplementationID() = 0;
: ?) M4 }& \( E
( Q$ F5 e- R! }0 i$ ]6 K% S7 o void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping' J2 _ \& A5 Y. S
1 Y8 N5 W: G i" z: N; a2 y, Z
void SetMessageOnResult(HWND hWindow, UINT nMessageID);+ l7 F5 y* l" L
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
/ U' Z0 O& U/ z uint16 GetUsedTCPPort() { return m_nTCPPort; }
1 j3 p: q6 |; {, q& X uint16 GetUsedUDPPort() { return m_nUDPPort; }
9 M' H( j; P& b* u5 g7 V6 ?. C; V8 \7 W4 \. w6 @0 Y& w+ T7 b
?% C7 ~, {; b1 Q# j" ~ W// Implementation
& j. R5 T/ D9 A" @4 K5 p5 d' Yprotected:6 ]6 S& L6 f4 x) ?7 K
volatile TRISTATE m_bUPnPPortsForwarded;
; q1 F5 R3 u2 k+ P, q6 `9 o }8 s void SendResultMessage();
- Q7 p9 Z) ?! I& o5 h6 t0 B uint16 m_nUDPPort;
; }8 w& ?: Y- o5 A# g) j uint16 m_nTCPPort;9 P5 B, f3 m; e8 p6 H% ^6 g) }+ ?! A
uint16 m_nTCPWebPort;
4 I4 Y: O6 U* v: A% M bool m_bCheckAndRefresh;
5 x3 K6 m- w& o! B4 `0 y- W. I2 T0 r7 |2 O# j6 m, X# ^- m
, s4 `. D( ?2 _/ Y1 M: t
private:
; i. Q# m# L1 G: V' E HWND m_hResultMessageWindow;' [. `, ^* }/ J, c/ r
UINT m_nResultMessageID;
! P$ e+ S; ] C0 {5 b
* `# V# }/ M+ |! w" } F- z3 x9 d& W+ j% X% J
};
. H4 s7 j1 }% }% f( [" W5 k7 T6 d& F& s S7 _
# B6 }8 x5 o. e0 p+ K8 L4 ~
// Dummy Implementation to be used when no other implementation is available6 ]4 d( ~. y3 E1 M
class CUPnPImplNone: public CUPnPImpl
# F4 \( ]+ }" U6 m0 \. M{' p8 s/ h& U9 A5 q k# }
public:
6 x! L3 e% p7 n/ ` virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }2 H1 L/ c+ N5 Z# e8 E! d' G8 @
virtual bool CheckAndRefresh() { return false; }
0 b1 V4 r2 e" ?' p, g2 R9 w; U1 O virtual void StopAsyncFind() { }. E0 O. y6 W) N
virtual void DeletePorts() { }
0 f% x Y# E3 O6 j: u8 S$ y/ @ virtual bool IsReady() { return false; }( Z% u* n3 ]) K; u2 @7 M+ W
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
! p9 }0 S6 Z# r \3 I" C};3 ?$ z1 c7 W4 |9 p/ \
T9 B% w! \& b: u. q( l# j
# A ?+ v) S( j$ ]/////////////////////////////////////7 c$ h7 `9 @2 ?' Q* R+ i" ]% s7 r
//下面是使用windows操作系统自带的UPNP功能的子类1 R" n* Y" V8 A" G6 Q0 X P2 N
3 |. ]' b; k9 _, `# D I6 S
# y6 I; ?2 C1 Y+ z
#pragma once) F# d' i, B, p1 u
#pragma warning( disable: 4355 )
( w# j# b6 Z4 W1 L! }7 M0 z4 i
9 t' ~' B# L% n9 ~2 D$ r4 L
; u4 ]5 V6 u, U# R/ b: r1 ]4 f#include "UPnPImpl.h"
5 z2 l2 h) Z1 @3 p+ C) @#include <upnp.h>
1 u Q/ P, Z6 l0 l- {) d+ ?5 ?#include <iphlpapi.h>
O2 g( H, l K' _7 w( ?#include <comdef.h>! r1 u3 Y- V) B7 t) V5 l5 N7 P( D: C
#include <winsvc.h>
) X {# F% _% V# H. n9 L
9 e3 r$ v, s2 ^7 Y$ Y& r4 Z, a0 O6 U7 l6 t& [
#include <vector>- X- ?$ l/ X* I' W/ L( M
#include <exception>
( s4 |* p! S) v4 Z* w#include <functional>/ v: y3 o% T( H" F# o, E C
" c1 Z6 j( `% ^# g1 ?3 ~' K0 D% l" c/ K
. ]2 I" N" a* d% z. w* \* {
+ c7 A9 P+ [+ T1 O" Ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
, Z& I2 d T) X8 R5 u! ?. wtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
' {8 k% ~2 Z/ i8 Jtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;( r$ b1 Y. Y; W
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
, B, B' N( d% k% H/ Dtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
) j! Z9 b; ~8 x/ r# {+ g4 _9 ?typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
8 m( {( _3 ~' z. ~2 I! Z. L3 {- qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* l. Z Q' u3 Z+ c( ~2 y
' D6 l+ y" P& l; |7 F o( V1 O' M4 i* e) ~
typedef DWORD (WINAPI* TGetBestInterface) (7 R5 Y5 S/ o6 T3 h
IPAddr dwDestAddr,9 O4 F* z4 T+ w6 ]
PDWORD pdwBestIfIndex
; U- @4 `# a9 U) m);2 q# Q7 P$ x: A6 e9 {' ?: \
+ d* f# s, F% t0 ~& o" d; \) ]4 P5 e& Y/ w. a2 ]/ C2 O9 @
typedef DWORD (WINAPI* TGetIpAddrTable) (
* Z/ E8 N b" E" A. K( Z PMIB_IPADDRTABLE pIpAddrTable,
+ w$ U0 ^3 X" b4 A- T PULONG pdwSize,8 i. H8 E# \, \7 H. l
BOOL bOrder
6 l" O+ o9 k( l' d);
8 }6 t/ Q7 U8 H. _- o' P! y/ g/ x% i4 l2 r2 b5 p9 M
7 H/ O" a/ v6 i+ ]+ a
typedef DWORD (WINAPI* TGetIfEntry) (3 ]7 s; S/ c* P
PMIB_IFROW pIfRow: q+ R' b9 f9 T) [+ v
);& A% v* d$ Y- t# L% p1 k. a
* Z& ^& }5 B i4 o+ K
" l0 w; T; u1 F: F2 A" X8 e5 KCString translateUPnPResult(HRESULT hr);! Z% U. v! }- V, c$ w, v
HRESULT UPnPMessage(HRESULT hr);
$ | K/ W" {8 u9 n
- z, p b3 w# ], O+ v* y0 K5 ~8 g. H" y0 i: r" z9 `! ~
class CUPnPImplWinServ: public CUPnPImpl3 H9 K+ P0 d1 x2 ^6 v! c, Q
{
% e/ R6 G1 g, ~; ~8 F7 e friend class CDeviceFinderCallback;$ n3 c: `# O' m& A. m
friend class CServiceCallback;
' v4 j$ F5 }/ C6 H4 j// Construction
1 `0 q+ V' L8 cpublic:) I r$ l2 q' Q s3 G0 E6 H+ p
virtual ~CUPnPImplWinServ();$ }# c# q: ^, u" Y' }
CUPnPImplWinServ();
" K J7 d% @+ U& H% L6 `3 A; j ^1 f, P( C7 T5 t' S {8 T9 i
/ r: }+ a. o5 h8 s5 n* u) Z. g
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }% `; ^0 P; N& t) `8 D) ]
virtual void StopAsyncFind();8 U9 B* ?, S+ I; w' ^% n, f
virtual void DeletePorts();
' \ R1 Z8 c# S9 a virtual bool IsReady();
7 ^3 P& `; C6 x. Q4 o6 U# q virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }) O: `0 [! Y P9 S! }
: z* ?' O% a- f* P- W
3 a9 L; R" k1 G: [4 E+ w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
) |7 H, d- ~ u9 U // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later) ?( x, _5 [5 k0 ~8 h$ I9 n
virtual bool CheckAndRefresh() { return false; };9 Z" b! R) E: i5 b! }* _
) K- N+ I' k# h; p X, b( o; d
: z0 p7 @0 c1 Z" q1 e, x* H" |
protected:8 X* q M9 m1 @4 V- y
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& u& H+ p: k1 k2 a- u# p M void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" D( H* ^+ c% \5 @8 z* |! o& ?- n void RemoveDevice(CComBSTR bsUDN);5 ^4 x8 w) I( h4 e
bool OnSearchComplete();
, {0 ~# W ~1 Z; H4 q2 ^ void Init();
' |- b/ C# Y1 `3 p, }7 X- v* X- k+ g# L8 U% j. P Y
9 y# o1 g! C3 i6 i inline bool IsAsyncFindRunning()
( J4 t" p2 W, G {
( H# E3 f6 ]. r8 n if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ). n8 _% B# L7 D+ E0 K
{
8 i( R- x' l; f7 | m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 l2 `" f. @0 A& u
m_bAsyncFindRunning = false;
% ]1 S2 u2 o7 {* G }
. ~# }) Y f3 U, J MSG msg;
5 Z) ^. c: K4 c" N1 N while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )) B7 {; P# v& f3 v7 J) R2 T
{$ ^, O- A5 B" w* Z- r4 }1 ]# w
TranslateMessage( &msg );
" J& d i5 D( S! `" z DispatchMessage( &msg );
; K- D3 A! O) ]' h }
' i3 K: S0 G7 a$ j$ u return m_bAsyncFindRunning;
5 L: h, M: P# Q2 K3 n( c }! r8 F7 h( I# Z5 \' o
# Z: z/ H/ S G }! S" Z! X4 G! p# n( p0 j
TRISTATE m_bUPnPDeviceConnected;- X& p" o& b1 z! H* n. l
8 ?) v2 c& t3 o4 e. c# d2 m, h% }( S" C5 u, t9 ?' Y
// Implementation
' L4 w8 n7 T$ V" f // API functions
" o2 L f) u$ W/ l/ n6 g SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
' @: f' P5 ~7 X/ D. ? SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: {/ N n/ l6 ^- d4 G$ L1 c: ` BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);$ w: f4 B- Z' V) `# ~
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
, R2 v$ k2 x" u) q BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);5 m o; X# y9 e% B: m- C6 e
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);1 n) }* ?* O1 Y O" w
" y% D) \5 X& v7 d' f' K
9 C5 D* D# ]& E TGetBestInterface m_pfGetBestInterface;1 P6 v7 Y4 E* ]8 S: H( I- x# w d$ C T. g
TGetIpAddrTable m_pfGetIpAddrTable;
% S# f a$ u8 [, _ TGetIfEntry m_pfGetIfEntry;
, m* D( k& |0 t* [" {3 L( E# S* q
4 c, S* o( I( H( M9 \- u
" h5 p& l8 }8 m) n' H static FinderPointer CreateFinderInstance();
1 S# W. l' s( b; [ struct FindDevice : std::unary_function< DevicePointer, bool >
4 z* R% \8 O% G1 Q: z- i! D5 ] {% |! q( O( J3 `8 n# |
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
3 e( y" | R7 K a result_type operator()(argument_type device) const
7 z, g2 R$ w: T7 s( y8 i q {$ f9 e7 i% ^6 c: G* I
CComBSTR deviceName;
; m1 H U: R0 h1 D HRESULT hr = device->get_UniqueDeviceName( &deviceName );
A/ z' r5 ? @% v2 o1 E& ?% l' O* E6 R. S0 ]4 N- S4 o M- J2 B
& S+ e; d4 f& l if ( FAILED( hr ) ), ?" Y. f7 B* w( z
return UPnPMessage( hr ), false;1 O$ J. `. z3 L( r+ V
, }# \+ r, d$ |6 X7 y% g$ u7 ^, R2 m$ f6 f5 D) g
return wcscmp( deviceName.m_str, m_udn ) == 0;
- G: d: n; Y3 {2 f }
8 ]- t5 Z+ ?$ v+ F" V j6 O CComBSTR m_udn;# Z# Q( ^/ Q- L7 s6 G' x% Q
};
* Q- c3 V/ m# a% N4 U
' _% Z# \( z, B7 H' h1 T void ProcessAsyncFind(CComBSTR bsSearchType);
' s1 |8 F4 S7 A% s HRESULT GetDeviceServices(DevicePointer pDevice);
/ @; R! n3 u5 w( i. C void StartPortMapping();4 R5 r1 h4 G7 `& c& Z! U
HRESULT MapPort(const ServicePointer& service);
. y" f, N% t, D! Y$ v) y3 o5 J# B! f void DeleteExistingPortMappings(ServicePointer pService);& U$ c0 N% V2 W
void CreatePortMappings(ServicePointer pService);
1 o( p/ V7 Y* p& w+ ? HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);) f& G5 v- {0 k. p# X7 O+ I
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: {/ e! r2 F( o# M+ R) b% L; G LPCTSTR pszInArgString, CString& strResult);6 l& ~4 V7 _) N: j. }/ T. R( I' E
void StopUPnPService();
" G0 p3 E& M# x' ~, L% y5 \! l9 d8 K$ r w+ y
, v' ]! Z( l: I
// Utility functions: E* Z8 C1 I! h
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);; O, A0 D X- \1 C, W; I0 o$ _
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, _$ p8 b( Z5 f1 a9 W INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
; ?) z) Q m" @7 |- n void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
- v/ f: w% f! s/ f% s. L HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
9 h' g# w3 g; C1 \ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
$ H+ y7 E# H$ t( o8 }8 |: W CString GetLocalRoutableIP(ServicePointer pService);
6 K( l# ]0 @, x5 I8 u" O w8 R. `. x* V) M Z& i0 K
" w, z7 g0 `4 [% t// Private members3 R; m# ^# s* s3 N
private:& n, x4 a- k% J3 @, D& Z- z
DWORD m_tLastEvent; // When the last event was received?
8 @+ ]6 n9 X% T) l. R0 s std::vector< DevicePointer > m_pDevices;& m3 K* [/ b& W$ }* U1 T
std::vector< ServicePointer > m_pServices;
$ E# b4 |+ I- A2 A3 @2 m0 c FinderPointer m_pDeviceFinder;/ A3 Z$ Z2 F/ b/ L
DeviceFinderCallback m_pDeviceFinderCallback;" W( R! t! G4 Y5 N) @
ServiceCallback m_pServiceCallback;
4 r$ w6 A4 e) \/ C$ @ T2 v: _/ ?! W/ `6 e9 j/ L) D1 x- o5 g
# L8 W$ e C) K( l& C9 R LONG m_nAsyncFindHandle;
9 G! P9 I, B# E" o$ X bool m_bCOM;
* A: M! h' e& ? bool m_bPortIsFree;
( d% E9 t s# j5 E% C CString m_sLocalIP;4 q# t4 @: k/ B
CString m_sExternalIP;
; X1 o0 y( y$ C bool m_bADSL; // Is the device ADSL?
3 P0 c! u: M3 i' w' ?7 D( q0 D, c bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
' e) r$ p' `: n0 C- Y- u bool m_bInited;/ |/ [2 j$ G1 o+ ]& o
bool m_bAsyncFindRunning;
& j/ }4 N) R4 S, g& P: b/ [# t1 c/ H HMODULE m_hADVAPI32_DLL;8 p% \1 B3 `5 M* v( [
HMODULE m_hIPHLPAPI_DLL;4 R$ h; r V/ u; R
bool m_bSecondTry;
# d/ F8 n6 T' c# i) {+ z bool m_bServiceStartedByEmule;- O5 X! L* \) e" P6 R V
bool m_bDisableWANIPSetup;
' i6 m# d- |- b: Z bool m_bDisableWANPPPSetup;
. f1 c# w, n2 I4 ~% e Y8 ^
& M0 Q& @0 H8 Q8 K; o/ x( o$ r
' D1 c+ p! Q) @9 g. J};
8 }4 A3 @7 M, w4 s# U# y- N
/ S; p7 C8 f4 w9 _
+ c" J+ B3 `: H6 t// DeviceFinder Callback
9 b7 T2 T# K2 f. Yclass CDeviceFinderCallback0 w$ }( e0 d/ ^7 U& B8 s/ a
: public IUPnPDeviceFinderCallback% `: z1 r1 ~* {
{
0 e) {- w q' t# q5 D2 p! z0 q+ J) Qpublic:# V/ \8 @, ]* j
CDeviceFinderCallback(CUPnPImplWinServ& instance)3 Z1 w% }" o# K: j( ~) p* A
: m_instance( instance )
) |& \/ V! f2 h3 \ { m_lRefCount = 0; }
" \ R, [6 W2 y4 B
; d7 R+ D: T9 P* ?& o w8 y R9 Y: f& V* P0 D
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! R7 E8 |/ y7 `& ~ STDMETHODIMP_(ULONG) AddRef();
* Z' G8 `9 ^8 k" J+ R3 b, t7 O- v0 k STDMETHODIMP_(ULONG) Release();
0 B: s- P; D6 r" I3 A J5 k
! Z0 \1 Z7 I0 W; n0 P; P* H
( n. Z; b9 D" z8 U4 V- R& A4 \; R// implementation" `8 c0 s4 o* @# z
private:
5 x$ Y d7 v, O X; a, p3 H/ b: I HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
; R; w& s) Z* B5 y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
2 h% ?/ ]5 j- }& A( v! D! c0 \+ X- P HRESULT __stdcall SearchComplete(LONG nFindData);
, f6 g# B& }6 Y
( V, P* d/ [6 }' ^; z! i
n& n; w& I ]7 ~7 Yprivate:. a% f! k. i4 M' j6 m
CUPnPImplWinServ& m_instance;
/ x" e: x1 e+ M, O1 M5 K LONG m_lRefCount;0 t+ d9 l* c$ U$ c
};1 s) i5 c- D; h' D6 s# f
5 q, W) L! i. T* i! f
" k+ |6 O$ f& S
// Service Callback ) U6 T. Z, k9 ^$ a; C& ^
class CServiceCallback# q. `$ n& f7 h; m$ C7 B
: public IUPnPServiceCallback
) {' W, S7 _9 m: T$ X1 \{9 Q) x `+ a- `: B* }
public:; c5 W; |# `6 E
CServiceCallback(CUPnPImplWinServ& instance)
- Z9 ~4 K8 j+ l4 V. D/ E : m_instance( instance )
9 Z4 y: k3 ?6 Z( A6 z& H2 c { m_lRefCount = 0; }3 g* H+ q0 S1 v
2 i9 [7 g7 T+ y% S: V' ` STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ u# N8 H6 v1 X" ^- x& B& O STDMETHODIMP_(ULONG) AddRef();: y- i7 K0 D' e0 M( j
STDMETHODIMP_(ULONG) Release();
4 [3 m& l3 T+ S& ~* q. Q$ D9 h# f. G# L/ D
, ]( R0 ]* _) _' q) ]
// implementation8 \5 Z/ Q/ ?5 k1 `3 `/ L
private:
4 O, p; {& e5 U ~1 ?8 A% Y HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
5 D6 Z0 o# V% e6 }0 Q c5 g5 v HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) w; H) n: w$ h+ D9 E7 J$ {
v4 Y" t; c, ~8 z) Z0 J
1 C5 A7 a/ M& u9 R/ Oprivate:8 I7 q* e2 G: K3 L- h
CUPnPImplWinServ& m_instance;! K9 @) L( [0 R! N5 U' ?" q* K
LONG m_lRefCount;* I" ~0 U. z; m0 _
};
+ q1 u1 z# }' i" }6 z
/ f! V* P6 H7 ]
' g0 J+ ^* ^, R8 W- [! e/////////////////////////////////////////////////
2 @6 e* ^- g2 O0 C) o' U
B4 Q4 z( h# n- {+ D1 C
8 c: F6 A6 A" z8 Z3 ^0 k使用时只需要使用抽象类的接口。% T* d) T7 U2 x
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.5 Y2 ]" G# m$ O- H
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.: g* ^6 }7 v3 c5 I
CUPnPImpl::StopAsyncFind停止设备查找.1 w( J9 I7 Z; `& Z- y$ r7 u
CUPnPImpl::DeletePorts删除端口映射. |
|