|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,# v/ u! N: I9 }1 k; x5 {7 Y+ ^# O
) J9 D$ D+ J2 `- ?4 M$ ?
; f7 v% u% V3 c. G3 ]( W
///////////////////////////////////////////
7 v0 E; L2 |! M% O2 Q- D//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能., D O# S I' Q+ y+ Q3 J7 U* C/ L
4 s! ^* l9 f6 _* `* q+ ~
" q& _9 V b/ i3 S#pragma once
9 A7 f+ a$ z9 Z2 E: e( w#include <exception>8 W% X) U u3 G' {+ |
" J, g+ J t3 @1 g$ |
7 C, c, l1 o1 c1 d/ X! X
enum TRISTATE{
- G" i0 D1 y* F. \ TRIS_FALSE,0 y7 {" p: c4 e, I
TRIS_UNKNOWN,' V' ]3 d; |9 d I% B3 {/ H
TRIS_TRUE& p( G* y: c$ M) P! ?; C
};
4 s' l% e, [, d, s9 g( ]7 [9 s( a" ~7 V
$ L. H* X" I8 O* b2 t# Venum UPNP_IMPLEMENTATION{' b! m) v; w5 V! A4 @ I8 d
UPNP_IMPL_WINDOWSERVICE = 0,4 I3 l8 v4 D# O2 v; D ~; S% E, U
UPNP_IMPL_MINIUPNPLIB,: T7 F, y2 P: |- G) F( a9 v
UPNP_IMPL_NONE /*last*/8 K( k/ k0 }: I9 b
};2 \0 \0 ^/ D2 r& x. C
m) Z- L1 m# b. z9 `7 ~" I& S
^6 {, u: Z& m0 e. @
. n9 V% [2 Z& I' s) V p# D/ |5 ^! L& B y3 r1 P
class CUPnPImpl8 S7 v) D4 X. \0 D
{) D$ p5 R& i- q8 ^/ U% [, K
public:2 }) a/ p8 q1 g$ C: y1 I
CUPnPImpl();8 ~/ k+ J. d- f. v/ R
virtual ~CUPnPImpl();' S8 |6 i2 v! U( E/ n" s- `) Y" y
struct UPnPError : std::exception {};
8 q9 q. Q, L l& c enum {# J& l+ [3 n, I- l* |4 y) A
UPNP_OK,
3 F Y* k8 N( E UPNP_FAILED,
# t3 R* ?8 Q0 L+ Q0 _# r% ` UPNP_TIMEOUT4 ?* Q. c8 l/ d' Q! s$ a% B% \
};
& y. C, s2 j& i4 F! ~0 A- D# B" y) [' d# }2 S
* P: J j" {) Q! [2 _2 ^6 l7 a& a virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;) C1 ^ n7 P- r1 ?% f$ c
virtual bool CheckAndRefresh() = 0;
7 m+ i9 }# C( F( r" A. F virtual void StopAsyncFind() = 0;
2 t2 M+ q: j" i3 O virtual void DeletePorts() = 0;
8 a& i9 B( q- F. K virtual bool IsReady() = 0;
6 t x4 H! o9 y7 \+ P7 i+ F# v virtual int GetImplementationID() = 0;6 O2 b2 E4 X( S0 n
) t: K& t$ k+ Y& r1 ?4 ^) H void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
U% l4 H1 J' Y2 S& o+ X, ]; o: Q7 W
1 P( N" O( @/ c' D7 D$ f1 A5 R
void SetMessageOnResult(HWND hWindow, UINT nMessageID);) Y" l, B1 g1 _) w# `) T4 ?
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: `" C }. K# l. K0 @, L F9 A
uint16 GetUsedTCPPort() { return m_nTCPPort; }
1 k; j2 B- N8 D5 c8 R9 g uint16 GetUsedUDPPort() { return m_nUDPPort; }
- o4 Y+ _( |+ {) I- P4 P$ U3 R% D! u8 `) q. Q! P4 k" I0 M, H
: _ e) B0 h+ a( |/ | @! W. b// Implementation
9 O9 T+ F1 M: Y6 `/ fprotected:
$ T) h; X4 p3 S4 G! E volatile TRISTATE m_bUPnPPortsForwarded;8 J) S5 N; M( m A4 A6 g! L& j9 q
void SendResultMessage();
: o4 Z( K G& x5 J$ p uint16 m_nUDPPort;
8 S+ g9 q+ ~7 D* S/ ` uint16 m_nTCPPort;
|" J4 }* H: {0 I" A- Q$ Z uint16 m_nTCPWebPort;" K1 ~/ R# _! Q: g
bool m_bCheckAndRefresh;
. ^) G9 j% O( L+ }( o( u0 P2 S$ q/ l
5 @9 ]% {: C0 J: r4 X2 Y2 f: J6 H- C4 E
private:
! A7 l1 i' p E x1 O HWND m_hResultMessageWindow; R$ }/ c) ~' B1 z1 ?3 `* p7 y
UINT m_nResultMessageID;
6 ~3 r# ?, q* ?, U2 h5 S, u
6 s/ a9 q7 V, I4 X4 N% E/ C& ]0 y8 C# T* x& |% Y" S* D/ b. y
};0 d( A) B( R# }0 `/ e! K: \) ^4 P
g# N* L0 K2 E
. u4 _* K" o, o- ?// Dummy Implementation to be used when no other implementation is available7 v7 L! x0 O- V) f
class CUPnPImplNone: public CUPnPImpl
' t( m8 p. j' [{ |4 G5 u4 y' @3 t6 R- p5 ?9 f
public:
7 ^( n: c/ R& @ \1 T4 _ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
& ]3 G' Z, n- ^% R; E virtual bool CheckAndRefresh() { return false; }0 g2 ?0 r: _$ a! `0 J' j! S1 c
virtual void StopAsyncFind() { }
7 M. G R8 _& Y$ W: [+ x7 ^* ] virtual void DeletePorts() { }
/ ?- j1 N0 K( P1 Y: s virtual bool IsReady() { return false; }
. P. J" _3 |2 L* b virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 @0 ^8 v z/ E* d" K2 Q: M};
: X2 e* w: t* i5 S& p0 A4 h$ {! p8 a# b# [8 p
. b* i; |# n+ ^% V9 z9 C$ J
/////////////////////////////////////9 A( o& S7 i0 e. \, g
//下面是使用windows操作系统自带的UPNP功能的子类
' G0 M; n m/ b* t7 y4 t- l& k7 ~ U5 K( [3 L8 B
- [$ T, }$ o/ R7 P6 E
#pragma once. B! s# t/ \( t- r
#pragma warning( disable: 4355 )$ \9 a. e' s6 M, W3 h( J! Y
: F8 k. Y: }# j" z
7 D# ~4 s/ |% J! ]( g# X& M#include "UPnPImpl.h"
2 n/ L) J! |' R#include <upnp.h>
9 ?) _5 Q$ T0 u6 {& q; T; R! R! y& u#include <iphlpapi.h>. m. x7 k% v7 Z+ B# D
#include <comdef.h>6 I3 D% q2 A! J$ d
#include <winsvc.h>
% u0 A+ V; |/ m5 I' E1 R" E4 M- v! R2 I1 T# n6 }) `
6 R6 X: i' y5 M3 l& Z: S7 e7 D1 P
#include <vector>
8 x1 t: K f6 s! I! g#include <exception>% [; c4 w6 ?. E- U' J( q6 s/ p6 ?% K
#include <functional>
9 o* E2 [8 G. U/ u
5 \* E. l) n) P, @, a0 S0 V: E! R( B- u
& g! t% I4 Z! I7 ?- n. U4 X# I. l& M2 ^5 X, i. n& }
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;5 f$ Q3 Z3 k$ J" d
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
% y3 b5 i- t$ V" y, \2 ^typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
# N- E( M3 Z* m5 d( T& ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;% B+ M5 s6 T" T% E" m
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 `0 F8 M& u( E2 ^2 n9 w1 V
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
8 _3 k: X: P! Ytypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;; t& X9 Y) Y2 Q4 |$ E
* m* l' R, J) I! P3 w
! k3 K% ]) }$ J0 ~. Y! y2 ttypedef DWORD (WINAPI* TGetBestInterface) (
- p3 u. \$ J2 Y6 |8 j: ^ IPAddr dwDestAddr,
5 O1 `4 U& `, A8 X PDWORD pdwBestIfIndex) s3 U9 ]; p$ [8 r( z: {
);! j3 a& U9 R& O* T0 Q( J7 b
6 g; p( z1 q4 n9 y5 o
( ]5 e: `) C8 \" Q! E
typedef DWORD (WINAPI* TGetIpAddrTable) (
! A; h2 b9 u1 O PMIB_IPADDRTABLE pIpAddrTable,
8 S+ Y, k9 }4 T. K& R {, y PULONG pdwSize,
- C3 ^. C2 o' q: P6 P$ M5 Y9 n BOOL bOrder
2 s% M7 I6 E `1 ^# c' S);( y2 L" c0 k2 `! y
5 f/ X0 D6 \1 k9 ?! e, ]& T2 U Z# U
typedef DWORD (WINAPI* TGetIfEntry) (- e# ? V3 q; U2 I3 l
PMIB_IFROW pIfRow1 x, l8 H. o; H0 U
);
6 \- | F' Y) ^4 o$ U, Z1 ~
1 J2 ]! j+ e! z, ?" b4 o. C+ L. j$ w6 k
! h( D, F8 d; H- e& a$ @CString translateUPnPResult(HRESULT hr);$ N7 Y' C% Y) X1 `# R: o' V
HRESULT UPnPMessage(HRESULT hr);
/ c0 e& ] f- k( i b& M8 ]& ?1 Q
+ ^5 e1 t2 k. w# q* H
" g' E! X' x0 H3 \: ~( E5 r, fclass CUPnPImplWinServ: public CUPnPImpl
' q1 e" [+ [9 W3 r' q5 \' }# Z{( u; r- h! X" h ]0 `
friend class CDeviceFinderCallback;
7 [* b- q3 q! X2 `5 ^5 A8 l friend class CServiceCallback;
& p3 {( K. y; b* E- N// Construction
' @% }- i) J0 I6 Ipublic:8 |$ w) k$ K1 y4 K8 J7 Z" l- P( p1 p
virtual ~CUPnPImplWinServ();
8 B- K E8 N4 s CUPnPImplWinServ();0 R+ {6 [3 ~/ N8 Q
, s X: D6 w: {' @
$ v) \# E$ B6 g$ y/ s/ b! ~+ g6 V
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }; G( W: g6 m4 q' q" ^+ C% L7 g+ s
virtual void StopAsyncFind();
& z. k2 M# Y- q4 y virtual void DeletePorts();
9 b$ q" D3 Y) u, U$ D" `: c virtual bool IsReady();% a' k+ H8 j5 [! v
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
9 c- t) m: E6 z* \& _
$ u+ x* w$ e3 Y+ p: y2 L6 C: F+ v2 T% q$ H8 l
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 a0 J# H+ R$ o, ~ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; i" f7 D$ D, l, N9 O2 M6 E6 m virtual bool CheckAndRefresh() { return false; };0 W. I6 o9 W+ A1 ?( ?/ v
; k n# E* Y% Z3 Z2 y- P3 t
/ C* ?& V. i0 ?# V' {
protected:
: `' R( _* x( B# Q void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 t! S: G- R: R6 U% I. ^6 \: f void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
; s( H3 d# W6 D; y3 l' A) e2 U7 }% X void RemoveDevice(CComBSTR bsUDN);
7 _1 B, \1 f7 W: @- s% H% o6 T7 s& W+ K bool OnSearchComplete();
$ s5 l; y- q' \ void Init();4 N- t9 \' Z% p. ]: h& }8 y
5 U% Z5 ~# _/ D- N9 @" D
/ b2 v$ R8 G q inline bool IsAsyncFindRunning() 5 i7 N7 ^9 k, V1 n& `
{9 ~0 Y6 W# [) u% h$ {7 P
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 B7 b9 O9 U; p1 U2 ?
{
# A* D8 \1 P- |' L m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
. y2 w& }3 S% k7 h m_bAsyncFindRunning = false;7 {3 c+ f$ f# f( m
}1 F# f3 ?; Z, t) [
MSG msg;/ o O* Y7 `3 x. l9 N
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 q; I: y/ k6 [
{
, _% m% c0 q' ]+ X7 t) n* j TranslateMessage( &msg );; K8 M }; a5 e# `- I" x; C" z
DispatchMessage( &msg );! Y. d6 j/ x% i4 u, r
}/ L: g b5 U8 F2 H4 `- u
return m_bAsyncFindRunning;
0 i2 j; r' R- C4 J }7 ]& ]$ o2 [( f
; W, s$ L5 l1 F) `, D/ |5 A1 {5 G% X. ~
; {) [" C1 T3 q w. J( ]% e TRISTATE m_bUPnPDeviceConnected;
2 [5 Z0 p# N+ Q5 J7 r; \" i& ]7 X+ L0 z4 d) Y' d
# B4 w, `, [' O: [7 y
// Implementation
. { R2 r6 k8 q1 ^3 `8 i& N // API functions
' P7 t5 U* h/ v! F6 t: J$ ~ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
# B, H4 A) N9 P t1 R SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);& [8 O; O! Q6 D+ L' `
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 X( W; \/ G6 T5 E6 d, r1 Y t3 c BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
* O; d; W% j/ h) u BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 J$ V c' b1 r2 y8 L. V
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
7 ^& ?0 T5 I. L+ F' `
' u. I* L9 O; E& _& y. a
- o# j( ^( H a" H TGetBestInterface m_pfGetBestInterface;
w) k) U3 ~( W( L TGetIpAddrTable m_pfGetIpAddrTable;/ M/ Y% f2 r0 k* ^
TGetIfEntry m_pfGetIfEntry;
# b' B3 e6 H5 \2 q5 e) h8 ^4 \" e+ Q- I, `2 h
( [( }) M' K" ?% S4 M } static FinderPointer CreateFinderInstance();$ v9 n/ U9 U3 N9 _
struct FindDevice : std::unary_function< DevicePointer, bool >% I! M0 z( h0 c
{6 r- `" e9 o% {* t8 _
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
( c+ p/ N' A- W7 B6 D result_type operator()(argument_type device) const4 ?# [( \& b' b! A
{
. D) k/ T) d8 N7 R h CComBSTR deviceName;
9 z* [0 d; M9 y0 ?8 [ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
7 y# o* x9 D) V- p6 l6 T, G8 ^! H& b1 p. [3 ~5 c" j
+ ^$ V. `1 t$ V! M+ p. T9 x( I! D3 H if ( FAILED( hr ) )" v. p0 m9 ]' D4 r( r
return UPnPMessage( hr ), false;
@/ ?" \! d' k" L6 J
9 o+ i+ l( E8 S7 [$ R5 u7 K. n# o6 }9 T% ?/ E* C8 L
return wcscmp( deviceName.m_str, m_udn ) == 0;
% J: [8 w: n A0 i6 T7 K- C' m }
0 _+ C% i& M d) F- n CComBSTR m_udn;! w6 U) c0 k# z" v7 A
};
$ }% z5 ?3 v9 k. X5 O" Y! e
+ j' q" W+ N9 C! k( L* ] void ProcessAsyncFind(CComBSTR bsSearchType);
; t# r8 E6 @8 } HRESULT GetDeviceServices(DevicePointer pDevice);9 [+ N2 y7 F. x( v# Q6 S
void StartPortMapping();# U8 D0 z; x3 P$ L
HRESULT MapPort(const ServicePointer& service);' r- R3 p3 `2 k; {
void DeleteExistingPortMappings(ServicePointer pService);7 k/ E1 v* f# ?
void CreatePortMappings(ServicePointer pService);8 L9 G5 P, c5 L4 H& B! F
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
1 z( R: E% Z1 X9 } HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 0 I& ] I3 V& T4 d
LPCTSTR pszInArgString, CString& strResult);
: a" E6 E3 O* T2 S, u) P void StopUPnPService();$ d2 d- |+ t5 C" U' Y
; i- Z# d. ?+ c1 A: @, \, D7 l
1 t' x" p* L" A( x
// Utility functions
M5 y q4 A) t9 e HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
1 \0 K/ H7 N' v9 k& R# _ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);3 C! _ ^- f$ E2 B( ~* x
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);( j+ n! }- r' \
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" U3 _4 U; ` t4 E" ~( {/ Q5 r HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ z" F) m2 ]8 b; H5 D4 C8 X HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
( ^1 m/ q2 b2 ] e CString GetLocalRoutableIP(ServicePointer pService);$ t. a# e7 N$ x- i
) l u# g4 J, y* n
! a" E% j, C1 S4 F6 O( {// Private members+ I2 M3 ` S1 m
private:0 e5 O" A6 q1 Y i' ^6 ]
DWORD m_tLastEvent; // When the last event was received?
. L. H, Y" r+ b% a B4 a$ S+ \ std::vector< DevicePointer > m_pDevices;; i: \% {7 | T' h
std::vector< ServicePointer > m_pServices;2 l: g) ^- t, R8 s! \. F
FinderPointer m_pDeviceFinder;
- O' h+ T! l! R6 p- H- L DeviceFinderCallback m_pDeviceFinderCallback;( d9 a( t3 g2 i M. T
ServiceCallback m_pServiceCallback;
0 h/ r- X+ Z; V1 I: Z
, c% s2 Q8 J1 J4 \' O5 ~+ R$ O9 Q [0 o7 y" `8 O. s, ^. Y) q
LONG m_nAsyncFindHandle;2 L! m' J. @+ {+ {5 O
bool m_bCOM;
- l' K3 [7 g- d9 |+ g bool m_bPortIsFree;
) l6 s( _0 p, n1 ^ CString m_sLocalIP;
) J# ^1 `* K1 C% v CString m_sExternalIP;
( J4 Q- P- Y$ s( \1 E bool m_bADSL; // Is the device ADSL?
- E) e1 S* O1 e5 M: T, b/ b1 A bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
1 F( R; ]0 F5 a& Z9 b* o bool m_bInited;# I, B. V/ u% N
bool m_bAsyncFindRunning;
. Z+ M! Z; L/ B k HMODULE m_hADVAPI32_DLL;8 h0 c( c# h% L. K6 }
HMODULE m_hIPHLPAPI_DLL;
% O' i0 I$ @* r) L4 `) P, a bool m_bSecondTry;0 g' r8 E$ R; C; _% |
bool m_bServiceStartedByEmule;8 Z2 K$ Y6 F$ x0 }) d% Z4 |; i
bool m_bDisableWANIPSetup;
1 \' }3 `4 O0 }+ B2 }& T1 t bool m_bDisableWANPPPSetup;4 U0 u1 B F T# R" A2 j
6 [; F' Y. k+ ?+ c' o1 i6 M+ ^" t0 U
};4 X. G. [+ s$ G; k0 F) ^) ~
' U' m* J5 y8 h. n9 ^6 ~
! u& n! v0 ~. E8 o A* N// DeviceFinder Callback& j2 V. A$ s% |
class CDeviceFinderCallback* A# d* M3 w( j
: public IUPnPDeviceFinderCallback
) f$ t: ^" w" l3 U7 O0 Y{) C. k, Y$ X& d( O3 A& l3 ~
public:" E. f- N2 e' y$ E
CDeviceFinderCallback(CUPnPImplWinServ& instance)$ A8 Z% z8 @' V+ j$ a
: m_instance( instance )
2 A" u- M5 A) \5 s0 p) r { m_lRefCount = 0; }
) {: p$ z& P' `9 @9 m4 r: h9 x' N3 \5 {
B, \8 o8 {6 H* D
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ r8 ^$ D! r6 m8 L, a" ~ STDMETHODIMP_(ULONG) AddRef();; B0 V2 l; ?( E" a. y
STDMETHODIMP_(ULONG) Release();$ D6 |/ I2 M: @# F+ R8 J2 T
- }! x% Y& Z2 p' Q" A w; Z' A/ [0 |" K% p
0 s& B( K( _" ]) Q2 V
// implementation
6 T% P/ N" E; {& dprivate:
) d. d$ n" K6 J" _9 h& M HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' p6 n( Z0 j0 U# Q, d J5 _9 m HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);4 k# z4 s5 l& `2 v, V7 b# h0 D
HRESULT __stdcall SearchComplete(LONG nFindData);
$ w# ^) @* S4 ^8 z
7 J4 j, o* K* S. d' R8 u- P4 |0 s+ B& ^" t$ \. j
private:2 U, R4 }1 P4 H' L: |( w
CUPnPImplWinServ& m_instance;
1 i% {1 ^) z) u2 g! m LONG m_lRefCount;
" a! _- a8 J' G1 u7 p& L% u};
& `& h$ }2 ~2 I" b, c f8 ]) q9 p" K* e* `5 Q2 Z
# R6 i! v7 v( M' C+ K$ d// Service Callback 0 G! S% t: Y* N: `& b2 w
class CServiceCallback
r+ e) N( j1 S9 ^ : public IUPnPServiceCallback7 A5 h) n1 C: O# a9 }
{+ ~- z7 l" ?% E0 w
public:
8 ^& j5 k* U8 M' z6 Z CServiceCallback(CUPnPImplWinServ& instance)8 O& e p6 I7 D
: m_instance( instance )& n0 I$ a n9 @# d; M5 G( t1 |" f
{ m_lRefCount = 0; }: s e/ j. K* ?( o7 s4 m# @
; `9 ]0 U( H8 B+ S) ]. z( \9 p4 n' M+ k STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! |7 a% ]1 a: A) p0 z: G STDMETHODIMP_(ULONG) AddRef();
1 W' N- `. R( g; Y5 Q! O% H' l5 d STDMETHODIMP_(ULONG) Release();9 ]9 L0 i, [, h) H: x* P
3 W2 H3 P! B3 ^6 _, \( J% \
2 C0 e# D0 W+ O t$ T// implementation9 u& P: R5 f) d6 G+ O8 Y. Y7 c
private:' y0 K2 y# M$ c8 c4 F
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
3 K) [0 Y- b! S; G. [1 p HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 @5 \; p9 m, g6 o+ G
, l: T9 H, r9 R Q9 o
\6 @: x: a1 A$ `/ Jprivate:
& G* _+ x# w" F( _* ]. M CUPnPImplWinServ& m_instance;
1 W0 W) Y% m# G2 P LONG m_lRefCount; s3 F* k$ \6 z$ v: S
};
' O7 p9 n. Z/ r. Y" v
, v! b- E/ L; F: c/ a% A9 m& r$ {0 r6 f& ~) X& |6 ?& @
/////////////////////////////////////////////////
# G1 _! T1 e# m1 C( W7 p. v9 _% g5 f3 r. s
% H" {4 J3 n& ^
使用时只需要使用抽象类的接口。
/ \4 D0 u4 K; ]4 J, SCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
( E% T% J2 e2 D. }4 B$ T% ^CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.* w2 g. V' p4 D& J% e6 R/ a4 F
CUPnPImpl::StopAsyncFind停止设备查找.
. y! l- B' l; P. o- A2 O. [4 \; UCUPnPImpl::DeletePorts删除端口映射. |
|