|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,. Q& O4 d% z! y
9 ~2 b; |0 A- Q8 h) v2 H; ^: u3 W
///////////////////////////////////////////2 z) L5 R) G8 z
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能., H, f" X# r6 W
( ?* f1 x+ D L
; V6 c" w5 j! C( G: z#pragma once9 a& L7 a2 g* _, r! ?
#include <exception>
- }% u: \3 c, [9 q) n: a5 Z {' a5 ^
( G% z' \$ r0 D' i8 W$ C# D: _
, `& A, x- u6 [1 h1 z* r enum TRISTATE{% H; y" Z+ b$ ?# R& K; v6 n
TRIS_FALSE,
& ?- f" O( @5 O5 ^! f* }0 R TRIS_UNKNOWN,
' r: i5 L9 g) U3 l0 Y TRIS_TRUE; d4 a7 E" A4 j7 R6 P* D1 ]5 n
};
- @4 b& n+ M4 _0 D# r) { p7 V( Q( e* }
4 B) |& E2 w( H, o
enum UPNP_IMPLEMENTATION{5 g3 W c) D. @0 ~! J% s5 S4 g
UPNP_IMPL_WINDOWSERVICE = 0,
7 w" ~/ O: w3 h' B7 @, R9 p { UPNP_IMPL_MINIUPNPLIB,+ R+ ^3 I! r' G6 c
UPNP_IMPL_NONE /*last*/0 a, c$ L: n2 L& w( W; L/ u3 ]3 q0 J
};
: @& M5 P( e; `1 d$ w `/ R
: j% P8 a q# x, Z- N1 V+ k/ _4 A0 W3 w; Y2 g, B/ Y
9 {8 N. \ H2 B1 d5 z& Z& z" e% y x6 u1 @( C7 f5 `$ n8 @4 E
class CUPnPImpl
' @7 y, v3 B" Y+ S, J! K{
6 P" `/ J# |/ \/ opublic:
- q7 o/ y" a3 {9 o# c CUPnPImpl();
* z2 ?2 P$ ]! f# z virtual ~CUPnPImpl();
7 v2 i7 N' B0 o8 R' a struct UPnPError : std::exception {};
$ U1 o y# H: p9 Y7 I# l# ] enum {4 T' v$ N) a( B; W' a8 H
UPNP_OK,
, b& ]: \9 x! V7 f2 c UPNP_FAILED,+ e- P. j8 G0 N5 {& q
UPNP_TIMEOUT
2 Y$ V( c* d# s- M9 V5 T };
2 p# ~7 F+ W' ]3 V; X8 D8 l. S+ b- N9 B$ f: Q o( Z: U
9 m& F0 ~. u: a9 l$ X8 n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;3 n( m5 ?* w; G6 ~4 s
virtual bool CheckAndRefresh() = 0;8 X4 T4 ]$ J, S4 E9 A3 M5 P- S8 M) y
virtual void StopAsyncFind() = 0;
/ @" [8 K3 L& ^7 ~( a( x virtual void DeletePorts() = 0;
p- x* b& h# r+ N5 Q8 Z virtual bool IsReady() = 0;
2 X& U+ w f& ~8 p, m3 \ virtual int GetImplementationID() = 0;: q: p6 b/ C8 I8 i2 b0 H0 ^+ X b$ {! i
& m. F; @( w* @1 h; p% q2 [, q7 _
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping# b0 j4 Z: y/ ~3 r0 j1 Y/ `
6 ]8 y2 z# C, h
* \4 R0 a6 J- z/ ~5 B/ P/ O- g void SetMessageOnResult(HWND hWindow, UINT nMessageID);
; r' j# S3 x& O2 x2 k0 | TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
- z' M, v5 B2 a. d! ^ uint16 GetUsedTCPPort() { return m_nTCPPort; }, I& Z& L, u9 M$ u: \9 H
uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 M5 i v! e5 x3 G: J" x/ G2 v" I7 S A4 L' r! ~0 A
4 x& W8 z, O" X: _% F
// Implementation9 W3 i4 G9 A2 b8 K) M+ R
protected:+ P9 M# N) q* o0 t1 i
volatile TRISTATE m_bUPnPPortsForwarded;
5 c: G( k+ s: O: j# Y void SendResultMessage();
+ U- b7 m' |8 P# f9 d2 |2 i0 K/ I uint16 m_nUDPPort;+ f3 q+ l& J4 u9 Y, G; _7 m$ C6 P9 O
uint16 m_nTCPPort;+ ~; _4 U) t- b, V
uint16 m_nTCPWebPort;
( J& r9 \9 P) z" a; b+ J5 p bool m_bCheckAndRefresh; i% y) v9 S& R. R! z
- E S `/ k. r, r
1 f" v+ x9 c: Yprivate:
6 H7 ^4 S9 O& H' A5 Q1 T: X/ i HWND m_hResultMessageWindow;
9 ]1 Y- {7 Y8 M+ l7 l UINT m_nResultMessageID;
" V. N& `4 _5 c- U- A( I- p6 v# X$ A4 ]+ h$ l
. R, J6 R; l" q& W9 _$ Z};
2 H3 c0 W+ h" y! n6 T5 p& B; ?$ r, {1 f' [) ^& h1 u, M0 s
) S; z g( e C
// Dummy Implementation to be used when no other implementation is available3 Q* X! M5 i) y5 l) K7 {: P' ?
class CUPnPImplNone: public CUPnPImpl
; z6 I- t) d. P& { a{7 J, e. p$ f. L- R+ u2 m2 i
public:! W/ G& W; K ~
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }7 M+ [& ]1 Z6 f4 s& O; ]2 B
virtual bool CheckAndRefresh() { return false; }9 w5 Y. b3 Q6 a
virtual void StopAsyncFind() { }; i& m9 `% o! H" M/ [2 b% v
virtual void DeletePorts() { }
# J) A4 k# _6 m6 m3 l+ ?! b" ^ virtual bool IsReady() { return false; }
; y. {1 ?7 z. ]4 a1 W/ ^! W virtual int GetImplementationID() { return UPNP_IMPL_NONE; }: c& i, [+ Y) i
};
. T0 i4 m1 I; M0 R# D6 y6 _8 d: Y
! c4 I3 z( T. j$ n/////////////////////////////////////3 D% @1 ^, v- _ d3 s
//下面是使用windows操作系统自带的UPNP功能的子类* {! e" T2 `# E9 i( k" q
# E3 u* F( f3 `+ W: }4 {) f$ E
, W3 V7 u6 y( H5 r1 C2 b#pragma once8 x% F7 i5 ?" f# m2 [, D
#pragma warning( disable: 4355 )
' C$ V' j7 l2 d, s* t- [2 U& R. s, R
$ z) k2 N( B: q5 }+ n
* [; h \- {2 A7 C#include "UPnPImpl.h"+ |, e b$ H; C3 Q( s
#include <upnp.h>
5 H, b9 Q, v4 Y6 {* {" w#include <iphlpapi.h>
9 A" j e0 [/ Z7 P) b: K#include <comdef.h>
6 f# l) `2 P b) g t#include <winsvc.h>2 x( q. ^5 X3 Y+ Z, n
. {4 M V3 W! b a) u
. ?, p' b+ s8 }+ P- E& D8 x' F$ j
#include <vector>+ A# u% I" @( P- q, D$ t! ^: f
#include <exception>1 @7 o8 E1 y9 G3 Q1 n" B/ q- O+ s
#include <functional>
! B1 Z4 J* P. i7 b$ Y$ T& v5 F- o/ }
5 s5 |4 o: i; o0 C3 P" z- s, x) u4 v! I8 F. N: |" R% N+ t+ H
( s0 i0 ^- T$ B/ M. f
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 s( B+ V4 O6 L6 m* {
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;2 e3 Q* c4 T5 o* H
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 w" Z& ]7 |' o5 v$ u! n
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;& v2 \! t0 W9 N+ k# n' S
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 k5 V" |# {/ }" c1 ^% D. a3 ctypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;- Q' e2 S& |# W( `1 `6 Q9 C
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;, h- y' Q' q H
9 w5 q. @% t/ ?" x- D! n' Q
7 J/ B# F# Z/ v3 qtypedef DWORD (WINAPI* TGetBestInterface) (
, u0 Y; E* {9 f9 v& n IPAddr dwDestAddr,! u! }1 P1 U; t4 T/ ~
PDWORD pdwBestIfIndex
4 G6 ]1 A# ^# H, B" _: a); _! E% P! @( `" r; l( N* g
+ Y( _2 x d/ |6 p3 ~+ f# `- J( G& r6 T8 B1 @( J4 c
typedef DWORD (WINAPI* TGetIpAddrTable) (
2 e7 Y7 |6 B6 ]4 X PMIB_IPADDRTABLE pIpAddrTable,
2 T; C$ B' D3 R' o3 Y& { PULONG pdwSize,
" R0 z6 Q! Y5 O4 d6 ? BOOL bOrder' ^' Q: t" p) x+ v) M) a: I
);1 a7 { A# Z! D! O. M" b: F
' v0 N) `! [* k$ r: P) x6 r
# Z; e+ O. {' |- T2 }0 r" H
typedef DWORD (WINAPI* TGetIfEntry) (
' W9 k: O2 X! J4 L, _8 [1 u' s! V PMIB_IFROW pIfRow
d( a. Z" L+ R6 {);
) R$ S2 k1 n# {% X" B
: X7 {4 v. W7 z+ X. ]# Z9 Z( K: v5 R
CString translateUPnPResult(HRESULT hr);! b+ `4 X7 r) |5 h6 q5 Z! z
HRESULT UPnPMessage(HRESULT hr);- a, P P' }. o8 T! [! Y
4 j! f5 x5 S) A( n- v6 m+ S
; |7 T7 w1 s nclass CUPnPImplWinServ: public CUPnPImpl/ |$ ~6 r$ H7 H2 Y0 a
{
, [$ S/ i; w* O% Y. v friend class CDeviceFinderCallback;8 s) t t3 H- _0 B, |* k9 W y
friend class CServiceCallback;- s( P+ B" r( ? ^8 m* W$ q
// Construction, V Z2 o6 I7 ^" @3 d3 T1 U5 f4 \
public:; m9 {8 q2 g' N7 ?
virtual ~CUPnPImplWinServ();
3 f7 `& Q0 w- X9 o4 E CUPnPImplWinServ();
0 q2 t* C8 |2 E* C+ \# Y$ V. w" t$ W3 d0 C ^
5 D" `0 L( ~: c3 V2 q+ m4 f3 Y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }1 n3 Z) g# E2 _& U& G
virtual void StopAsyncFind();1 u. I* }1 L" M5 a" l1 d U9 {$ d
virtual void DeletePorts();
* t1 t: i) [$ a* h& O virtual bool IsReady();- F, r9 ^/ H! ]) g( R' y
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( [0 A+ }# p1 O4 [! I+ y' \
5 J+ U' ~# @- F- e
* L7 Q, ~& o& u! v6 ~+ _, _
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
* e3 {* V3 K: b! a- _* ~ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later+ m$ {1 H1 w q8 r4 U
virtual bool CheckAndRefresh() { return false; };
( E& F5 @8 j4 R: |5 N5 B, f: L) ?% D# ~! D
; i7 x; g; \$ V/ N' I: _1 w5 y
protected:
! }8 f' g! ^3 } void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);% d2 U9 n$ i) a4 _6 [
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
6 l# g" O% C: V- g" f+ V" D void RemoveDevice(CComBSTR bsUDN);+ n" T f3 {, h2 z, ?8 _/ z
bool OnSearchComplete();7 _! N; ^; }* ~# C1 b. m
void Init();& J5 `% W8 q n- h% n# ?1 \: ^ W
7 @1 |" N9 b8 |/ o
5 N* C9 p, G8 W2 ]6 }) s inline bool IsAsyncFindRunning() : g" @. N; v8 @; a9 X
{
' o. @/ {4 S7 _/ r' S if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
) s. v! A$ C' p* k1 ` {
% l. g0 E8 B3 s9 y& g N m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle ); A4 [1 M, v# W3 y r: i7 A( v$ i
m_bAsyncFindRunning = false;
) `! I1 ~4 [ ]% Q3 K% {/ R, O' D( t }" p! o; m' P+ E
MSG msg;
- ^2 d7 u; S, T% D4 h8 U$ _, Z+ U while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ l ]5 m1 }, T: R/ v {' m2 l# Q, U7 z4 G2 _* ]
TranslateMessage( &msg );
/ F1 V3 H3 p5 _2 \+ X- G# Z DispatchMessage( &msg );
9 N1 W# s5 q2 |7 l& S/ J }
& g5 k, p+ a) Y9 \0 Q& T. S return m_bAsyncFindRunning;" U" x8 I& _9 ^
}$ K/ A1 U) Z/ ^
) H& e6 z) u0 r0 p3 G
5 c* }2 g7 s$ H; }) ` TRISTATE m_bUPnPDeviceConnected;
, }0 b( x; D$ L- B1 c$ x( J; j! f4 t( b* K7 b8 @0 I
& x2 A' d+ g2 r) T// Implementation
$ @5 Y) K. w7 t1 D // API functions
$ Y- m# Y+ J& f* V: i SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 t+ E5 d! P, x# W0 c8 W SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 }' r' h8 c3 { BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- d! Z/ H& t7 r7 H
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);; N- q( S& \( r# G z! S4 k
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; L% V6 F6 h3 t+ T: e/ L BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);3 v+ t P5 {) C+ l/ R9 z0 E
; f7 b1 `' d. `( e0 `, W/ n0 ~: J' v% ^3 }1 X( i# J" L2 ?6 d
TGetBestInterface m_pfGetBestInterface;
) q2 Q7 I2 b$ g6 H+ o TGetIpAddrTable m_pfGetIpAddrTable;) B: Y. R3 W; D/ v4 S, p
TGetIfEntry m_pfGetIfEntry;2 s2 B# V4 b! ~: E, L. ~
7 \3 ?7 k0 h! K% \# E
+ Z" ~1 b9 ?' j- d8 g: m static FinderPointer CreateFinderInstance();; Y8 P; q+ j8 w6 b
struct FindDevice : std::unary_function< DevicePointer, bool >9 H6 b. `0 }, U9 t
{4 P& H. w- V* V& g$ c9 ^
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
- @9 @- `4 I5 k result_type operator()(argument_type device) const% C- e2 N b* j: g
{ `+ u# G5 _2 i) @& j3 \ ?8 a
CComBSTR deviceName;
1 a6 M/ u1 T* D( O P HRESULT hr = device->get_UniqueDeviceName( &deviceName );
2 \! H$ ]5 j; n4 E8 p, }' a+ f. G7 b
% c- i% O# K6 ] w if ( FAILED( hr ) )
. r$ i) {# R4 ]6 @" Q return UPnPMessage( hr ), false;
1 a. I ?8 b6 T. X) Q$ q4 \- x$ I, r; M
% y; O- m# e. m% t% _( b
return wcscmp( deviceName.m_str, m_udn ) == 0;: L- m, M) Y; R& x, ?2 m2 R1 a
}3 I9 P( {8 B3 A3 u6 x0 B7 X1 S
CComBSTR m_udn;
) f8 a i4 t. l };8 ^0 I" G8 s B! G% u; R6 J
3 g9 ]/ O. ^; `! P3 B void ProcessAsyncFind(CComBSTR bsSearchType);% [6 z, a( L3 ?4 w
HRESULT GetDeviceServices(DevicePointer pDevice);
- W) u- I$ X1 V6 E$ j void StartPortMapping();; P% y1 j. L" b! F+ T
HRESULT MapPort(const ServicePointer& service);
3 ~0 W6 k0 ]0 x Q: b7 q. B! n+ {8 X void DeleteExistingPortMappings(ServicePointer pService);- H5 |2 C) M+ d! k* e6 b8 D$ U
void CreatePortMappings(ServicePointer pService);% W$ b. \9 F" c, t
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);7 K ^2 |) _3 o9 y e. @4 n
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
$ ^/ T4 Y9 M4 V/ k. e LPCTSTR pszInArgString, CString& strResult);
# v9 _6 i! h+ {8 o, X void StopUPnPService();
7 g) |" d# S. ]. C. b2 c; `3 d5 Z; Z) r/ R# T
9 Y* O0 S( S) x" b' y+ `- L // Utility functions
1 D0 O) K {/ x- q. u4 ]* n- P HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
' G, [5 b5 M! @9 ?0 W% W; o: F8 `$ q6 g INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
( A m/ Z3 N: u: e4 j' Y INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);* [4 `) c: ~1 K: b1 i, `/ r6 K
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);& ?6 {8 y& W# u; t) M" y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ o' C' Q& x8 ~. _ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);( Z: u% w# A) |: _
CString GetLocalRoutableIP(ServicePointer pService);
1 @% V, d" j$ Y% p2 S, K) G# M3 a- e( n8 z- S; W7 y
`% D5 v% {% ^! O
// Private members
$ C5 a8 f& F {* Vprivate:, N! B# S: o" s8 s" F
DWORD m_tLastEvent; // When the last event was received?* P3 f' ?; I+ _2 r& H
std::vector< DevicePointer > m_pDevices;
0 N; d, v. s/ o1 O* [& ]5 x std::vector< ServicePointer > m_pServices;
2 L& e# Z" x, I2 v0 R FinderPointer m_pDeviceFinder;, ?) S% B2 M1 a! M& j( D8 T* J
DeviceFinderCallback m_pDeviceFinderCallback;! R" k; T5 Y% k" {7 }1 C! {
ServiceCallback m_pServiceCallback;/ n0 s! i2 c" `! m
% y! Y/ ]( D3 U1 R- Z1 U. k* w) ?
3 j' r2 p! g% a5 c) a0 c+ s
LONG m_nAsyncFindHandle;9 C o% b, x& u0 W) p4 |5 L
bool m_bCOM;+ z7 o2 C r- d0 R1 T3 t% H
bool m_bPortIsFree;6 p7 W$ o0 f z7 t x2 _+ T
CString m_sLocalIP;6 L$ X9 m: I. ]4 q/ m3 Y
CString m_sExternalIP;, H- m4 V6 }6 M- q" Q( v
bool m_bADSL; // Is the device ADSL?& @* A% S& _& a
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?1 |( o. k7 P3 ^( K# P3 M+ u
bool m_bInited;
l; i9 g" ?$ Q p# ~9 q. i bool m_bAsyncFindRunning;
$ U1 N" @1 I$ L HMODULE m_hADVAPI32_DLL;
6 M+ \8 @* i+ _# O; s) K9 E: G HMODULE m_hIPHLPAPI_DLL;
, E) s. u* t6 i% t8 F; b" e bool m_bSecondTry;5 ~- A- ?2 Y% Q* T( |
bool m_bServiceStartedByEmule;' I% o5 ^! k$ a; N
bool m_bDisableWANIPSetup;
$ v% O4 V2 o9 Q6 [# t bool m_bDisableWANPPPSetup;3 i% d2 i- W; [) a* ~& G, z
y( s9 M+ Q2 S& q5 {6 r* j. k. v; w2 p$ \/ K6 N3 r; @4 z4 R
};
2 B5 }9 j+ I" a& y P
% m& @3 k) v( P( L. u! R+ u8 g
// DeviceFinder Callback F2 @) N: n+ b
class CDeviceFinderCallback
J3 n0 q1 s7 l! z" c4 L : public IUPnPDeviceFinderCallback
3 f# o8 `. i+ O; R, G{
' }$ X. c7 s7 b! mpublic:
+ v/ y) ^5 `4 r1 N CDeviceFinderCallback(CUPnPImplWinServ& instance)/ W/ ?' x) P$ x6 Q
: m_instance( instance )' O n; R) P& I! ?
{ m_lRefCount = 0; }! B% a- n0 _2 j4 S
8 G8 L1 _$ i: w: b, H/ m
( x$ h7 n" o9 n( S" ]: Q+ X( q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' \* b- q V( D5 h
STDMETHODIMP_(ULONG) AddRef();
+ b5 z4 C) ~6 y9 a STDMETHODIMP_(ULONG) Release();0 q& {; ]+ m K3 j7 {
$ E) l" E0 e6 a; {4 ~. M, \& v: Z/ U% h2 O% h
// implementation/ `* t9 v; s; [- K0 w& _" x
private:
8 f7 Z2 ^* b L( z' f1 z/ |/ ` HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
, ~$ @6 }9 D8 ^2 A: N HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
i, @7 L% S) r# N2 l. S2 `7 U8 r HRESULT __stdcall SearchComplete(LONG nFindData);
( _4 |% w; c" m$ D# U _1 G9 I5 D
7 s. N; ~7 C# o: w! [+ R$ c! ?2 _+ ~% z
private:6 l7 d6 F( O' W5 g7 h) G
CUPnPImplWinServ& m_instance;' t2 \6 j% i- ?, O
LONG m_lRefCount;
- ^( C9 `. i% ]" |# i};
8 S7 h) j; n$ T9 \5 H& [* e: a. C0 C) q, [8 x2 Q1 J4 [
( N; B0 `7 W! X3 C8 ^% n# @
// Service Callback
% b# l* N! T+ Q2 jclass CServiceCallback; T0 T. [7 M* o
: public IUPnPServiceCallback+ e& d, y% ~! M6 `# `
{' }6 T+ P; @8 N1 i2 }- w8 W
public:5 [ p$ I" T) y/ }" i. p j: z* d
CServiceCallback(CUPnPImplWinServ& instance)
/ k- ~8 W$ {1 z5 G : m_instance( instance )8 }% I+ V' O1 T) F7 I3 X3 [
{ m_lRefCount = 0; }+ a! A, T/ L! f4 a, p$ k
; m/ u" }* c, I" T" _ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 ]0 ]# ?; F& n" W$ I( {
STDMETHODIMP_(ULONG) AddRef();+ m$ j5 Z) M# P% U: }! P9 Q* [
STDMETHODIMP_(ULONG) Release();
, M/ c! D5 b! K% t( A
" Q P6 |, ?0 M
5 w$ V B$ \) Z7 N, `/ f W// implementation
0 }" n9 B& y9 t& K) a) Xprivate:$ K: X( B, G/ a
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" Y) R- e9 I; t, T& K
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);1 l6 O q8 B% G9 y- p/ j
% R: T d' ?0 e" P+ }3 r# j4 a2 o
- ^2 G. Y+ X% O4 Q" x' ] Qprivate:3 |# } ?3 G2 b, z& S, X1 S! t2 [
CUPnPImplWinServ& m_instance;7 A& j4 f2 y4 [0 |+ z" I
LONG m_lRefCount;6 q7 L* f% ^6 G/ q
};
6 C( k% I2 x- V; R i* U3 V' a1 z' P! g( n w' h( f
9 @8 d N! ^6 H
/////////////////////////////////////////////////. z. m7 T0 p. b1 b! N8 o
! Z: A( `4 e# I: {% f
5 w% B7 _' }, D# H使用时只需要使用抽象类的接口。
: z- V s! P* L" p' ]& q' @/ Y. z5 nCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 t* @0 w/ K% N0 \# Q! i/ qCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% ~0 z# r8 x5 l7 f# {6 GCUPnPImpl::StopAsyncFind停止设备查找.. N) P4 M2 Y# \1 T( i
CUPnPImpl::DeletePorts删除端口映射. |
|