|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 J9 K2 G: ~- ~/ M, S9 _, z
`" y0 _3 L. u6 g9 l
, R$ x1 E. `7 @///////////////////////////////////////////
+ @. r# K) [! j//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
, N# z$ L. t5 m) @4 X: T
! Q. S/ U3 M g( ^$ \5 v( W
H: f6 x' e2 ^, r, T8 O6 _#pragma once
* q8 l$ E8 u% Q& Z+ v#include <exception>
0 D7 \& G. U" o9 C$ K$ f. Y2 i/ u
" ]9 j8 j& n7 S/ h) y0 t" \- \1 D
enum TRISTATE{
* ?2 ]" M. V) C7 p' |1 N+ `5 J TRIS_FALSE,( a( X: |5 Z, z$ [. ]- E1 F$ a
TRIS_UNKNOWN,
! c" i1 j0 f8 ] TRIS_TRUE9 t0 l6 y: t8 x' V0 J; \' A
};
) ]. Q% T- ^% E* H. C" ], u0 _: G
+ R: q; s3 Y r3 l3 h2 G- T4 W) C3 S2 R8 }2 i% U$ D# K/ v- t
enum UPNP_IMPLEMENTATION{
' W, Z% z; @- ?! ^# \7 ] UPNP_IMPL_WINDOWSERVICE = 0,
3 @7 H4 } m* M5 M. `( p* y: `( d UPNP_IMPL_MINIUPNPLIB,
2 w- _2 X' n# u+ [ UPNP_IMPL_NONE /*last*/
& }/ a( D V. z}; l1 w# \! l) B7 N
% x4 v) R0 ?8 a, {! @: i9 ^
* P7 h9 ^: }- C$ j, ?- D) I$ R+ d( x' i% o
+ U6 {' r8 Y- K# x% Mclass CUPnPImpl
q) _# E% |2 ^: h3 F2 w V{0 E% n/ B, y$ v% h" L* |8 `
public:
- _2 |" V2 h% w1 X- W$ l3 D* R7 e0 h CUPnPImpl();# L5 ?- Y5 H1 e
virtual ~CUPnPImpl();9 C% R' h9 c0 l7 }9 G/ i
struct UPnPError : std::exception {};
) A2 p+ s4 F M* L( M enum {
I1 D8 @4 F& c- b UPNP_OK,
: f. b; u+ y- }' u: P9 B5 q$ D4 K; M UPNP_FAILED,
7 N9 |) S3 K% A$ I UPNP_TIMEOUT
! L6 q! G; U! q! f };
) T7 s4 q9 G' j) j7 o' ?# X* S) V5 x' Y
* F6 _1 e/ T8 J7 s virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;9 G) P9 Q' y, P' P' B+ o9 Z
virtual bool CheckAndRefresh() = 0;
% k* X# v! |6 h9 [& t( ^ virtual void StopAsyncFind() = 0;
! ?0 ^2 @: ^" C) f) E# ~ virtual void DeletePorts() = 0;' f9 j0 n! v1 S
virtual bool IsReady() = 0;
- v$ Y7 ~& N+ B# l& \5 K virtual int GetImplementationID() = 0;
& G- k4 Q$ [- R# H+ K/ P4 p$ B0 w ; k7 ^$ i: J$ X5 w0 n7 I% N4 W5 D; e
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
' w* q( W3 a$ G- Z: d6 o5 {0 B3 C6 y- G7 p* d9 T. U
- W( \ d/ P3 N2 w: t$ n void SetMessageOnResult(HWND hWindow, UINT nMessageID);* ]2 G }& n& i- N4 R0 s
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }' N1 ?9 ?5 G# I' v% B
uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ N( p: F* M: a; U& _ uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 x4 f1 B7 w/ W0 h
# F0 F7 j: D7 d- m5 N7 X; j" g% A9 _, M8 V
// Implementation
$ {7 z* i6 K: i( t \0 G: L/ @protected:
, C) z% y7 D4 b, [9 U* b( j4 @: `9 _; ? volatile TRISTATE m_bUPnPPortsForwarded;7 W- P4 I! T. I! z& J, }0 T
void SendResultMessage();. o/ V+ l1 E: D) e
uint16 m_nUDPPort;
1 U$ N1 u; {$ m) Q/ B- R uint16 m_nTCPPort;
2 |+ O g: A. O: h5 P uint16 m_nTCPWebPort;# \! C. }) U( f3 A9 l Y
bool m_bCheckAndRefresh;5 J6 p. D6 }- p5 K) ^
* Z0 Q' r8 f2 t* V# y; J) T5 i
/ Q( f& u& w0 f/ m( D nprivate:
5 B3 [3 a; u; c, A$ R7 G" U HWND m_hResultMessageWindow; l$ o: E9 x* Z* \
UINT m_nResultMessageID;
. L$ y; Z2 @/ f" D) S- H
; I9 y( I @( V6 I, Z4 C
5 i2 I) J% v& j) r7 T+ J};3 E- u4 }$ o/ q( g8 Y8 H
7 R7 Q+ t. u6 h. S! D3 i
* I( a' f0 a% O, E2 r// Dummy Implementation to be used when no other implementation is available: e" E6 U: m) F
class CUPnPImplNone: public CUPnPImpl" i4 }+ ~/ c0 V" \4 k
{
1 T5 S5 d! [+ V* Bpublic:
# T2 f- c1 B) |' E# v7 n. k9 ~% V, } virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
! {' _( v& F# q+ G2 w virtual bool CheckAndRefresh() { return false; }
. _3 b, u, i) o8 B virtual void StopAsyncFind() { }# {2 c0 c0 v$ I( D9 A2 ?
virtual void DeletePorts() { }
) O; G+ z2 B3 y1 f z virtual bool IsReady() { return false; }
2 X0 s/ R( s( F/ B virtual int GetImplementationID() { return UPNP_IMPL_NONE; }5 o1 }' L: {+ {$ f2 H1 K+ B, I! H
};$ `. K4 ^6 H& M$ D- K: q
: |7 W9 n& X8 R6 l' I6 |& i2 ^* b5 M, ]% s9 y* U0 ~ E
/////////////////////////////////////5 W7 g' Y3 L4 W0 Y* i$ a* {
//下面是使用windows操作系统自带的UPNP功能的子类
' k3 j0 O1 [0 M/ X/ r- S5 s
u4 ]8 S8 ~1 o; l7 d* q0 j4 ~3 v9 y3 z
#pragma once
; r/ ?; M5 `& t0 e#pragma warning( disable: 4355 ). J0 }( ~: a6 {: a1 }" M
% m/ M$ k( r6 H7 Q5 [2 f' g) H0 {$ D# a, c
#include "UPnPImpl.h". H! ]+ v+ o4 v: z. Z1 H2 f' B4 B% s
#include <upnp.h>: L& r. v$ o5 O' x- ~3 ~# t/ c
#include <iphlpapi.h>" N' J0 N& G# _4 ]! B
#include <comdef.h>
4 N% x' b2 s5 S! y, E" N. a- s#include <winsvc.h>
: k2 t& a7 Y9 P* T* P* G# j+ r9 |1 t, v6 K
3 G# R4 n; F& b
#include <vector>
0 F4 {. n( V2 R: O& ]#include <exception> P- L6 |6 N8 U6 j
#include <functional>
& H$ x: [2 H' d/ d
# Z7 ]& c, F5 n6 |& }' I
6 q; m. H' x0 Y( R3 S
0 \( O1 s$ s9 [- Q+ f; ~: M) X5 G& m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer; M4 N# q' S: K8 L& w' }
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
4 H* H2 K3 y) Z/ E' `% Mtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;( O1 `7 d1 y$ w) [4 i. Y/ u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ X3 ]6 N) T! ~. w
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;" J' Z; ~/ U3 P' P1 H+ n
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;% r' B" K9 f5 o& E( r6 W. \/ y1 f6 `
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 f% f9 G, K& g- v* N) `% F1 o
0 @, J0 x( Z2 E1 S) o
: \9 l6 V: c$ n$ `) W
typedef DWORD (WINAPI* TGetBestInterface) (
2 ^" {' A0 q9 H# f3 ~ IPAddr dwDestAddr,
7 ] L4 R$ u `4 S) W PDWORD pdwBestIfIndex
! T! t- p! b( N: W5 N4 D% B' I3 D8 q);: o3 n* C3 `' w
8 g5 A g7 d3 d5 b
9 T! `3 N9 c( h! Z) d( T* [typedef DWORD (WINAPI* TGetIpAddrTable) (; a2 G6 e& n5 L7 X# J. W$ y! v' I
PMIB_IPADDRTABLE pIpAddrTable,
1 e& ^8 J+ E# B D, b0 w& s6 L PULONG pdwSize,/ Y6 U; h- t" m9 i3 D0 X
BOOL bOrder
. N6 Q' T, W' u+ s6 V( M0 w);- T& j, q; ?# v3 ?4 y1 X
% V& T4 V& } c- j
* a+ w' C% O1 B4 h% b0 {( Jtypedef DWORD (WINAPI* TGetIfEntry) (, L5 b4 g& N8 X
PMIB_IFROW pIfRow
% Q3 e3 X9 l o6 H. k, S);, x2 }6 V" @: r4 o' [
+ [& X2 |" ?( K) S
! R+ `; u) b1 KCString translateUPnPResult(HRESULT hr);
4 Z" v( w8 q* Z& B! wHRESULT UPnPMessage(HRESULT hr);
9 s( G) ~+ ?6 @) o% y/ X) C4 I
Y# M& M- D/ L% E4 M: a0 [5 T
G4 s/ u0 [1 ~9 y' Uclass CUPnPImplWinServ: public CUPnPImpl$ y8 M5 z: N; Q" i- `3 _
{
6 L6 v! ^/ g9 v8 g" U* y9 U( P friend class CDeviceFinderCallback;; Y5 C M% ]4 |! |6 f/ C1 a9 E7 f
friend class CServiceCallback;! u8 m( k! ~" r' Q2 z
// Construction
7 n& P# Q9 j( e/ f9 y/ jpublic:
- h; M0 A9 Q: x C* V) O6 x: L virtual ~CUPnPImplWinServ();
! C1 @3 w1 v( l. P4 {* F: W' H CUPnPImplWinServ();3 C: F" p- T/ w% X; A( D
* S; ?5 Z \$ G0 t4 ]7 e
3 e( z+ p5 D+ B& j! K5 A
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
) ~0 Y1 P5 f# H" a1 J2 o: G) n" S virtual void StopAsyncFind();7 ]+ z& N2 P( C" m+ d- `
virtual void DeletePorts();
5 |6 V8 x+ l% @* x# u virtual bool IsReady();" d4 ^( I6 B2 s2 I' \
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
& `6 M1 }7 Y" A- k: ~9 ?4 r! c0 \' ]1 E0 A# T( m# Q
' q0 i6 A6 o5 g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- l7 s( U! i w$ _% e# E // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later1 v4 M5 S( M; s# d7 z% ]4 B) }
virtual bool CheckAndRefresh() { return false; };' O9 R m& W; j" j
' a m. K2 O* j: R4 p
; Q/ M& T: a5 I5 F
protected:
$ m; A! B5 J) p) N1 \ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);& X. D9 P# ~- d1 O0 z' S
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);* M7 [0 @, H- a6 M1 ?- x
void RemoveDevice(CComBSTR bsUDN);7 x5 V" X. o' t q: `6 w' V
bool OnSearchComplete();
/ N8 |2 h m* K. I7 ` void Init();
n+ O. k" A- v: k0 l( Z2 P0 I. y
- d- V R0 Z# n5 j/ B inline bool IsAsyncFindRunning()
+ }* o4 a4 @2 ~+ N6 t {$ ]* H6 w2 M- K1 Y2 A. Q5 Q2 b
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
. S, J+ v/ k5 s9 Z" I {3 V8 w, k* d! M, q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
7 h$ o) Z( C* J: D* B4 _2 a m_bAsyncFindRunning = false;/ d0 l( V" m- ?* H6 q* X! H
}
+ Q& F7 P7 Q) @# i# E MSG msg;
0 `' a) j& ^8 s1 ~6 `/ k while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ Q6 Y+ t0 _! Z4 _5 _# f0 F
{
/ A, ?8 z$ ]2 J- n, P- T6 k# Q TranslateMessage( &msg );
- W: ]- l3 I$ E DispatchMessage( &msg );* r) R$ I/ u0 F7 ?: j2 s. G
}
; F" ?7 J$ k, S; l return m_bAsyncFindRunning;
A- Q3 A) h0 s' D5 q }
0 S" O9 a( ^7 G) J. d! ~0 I/ P3 [
4 w$ f/ u5 M e" w( w# S
TRISTATE m_bUPnPDeviceConnected;
- [, Q& i5 [, E. b. i* \9 ]
, ]* J0 z# z4 ]6 ] H# c1 Y" {
' F: J1 V$ m1 n( A4 y2 S// Implementation
" v/ V$ ?1 A' l% h$ h" V // API functions, B. l8 d2 B% y
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
: h6 N9 P" ~% x E SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);4 |0 }( p0 q( L: x0 z) I0 f
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! G# Q9 I/ Q- G' F BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' J) `3 X" B' Q, ]$ g" _+ D; W! L BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* C" e" }7 m" Z8 a1 G# u- }: [' i
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
# ]: q- ^6 d- h+ i7 g/ p# i6 b8 i2 {- Y& H
/ e* U# |6 Z/ f% p( q! y- v
TGetBestInterface m_pfGetBestInterface;- a. F& p! h0 r* B+ I1 E' O' `+ H
TGetIpAddrTable m_pfGetIpAddrTable;1 e- O9 A8 j- \' f" U. `0 v+ `
TGetIfEntry m_pfGetIfEntry;
, [( p7 I* C# @ _, _5 j, u- d3 c7 q( q+ M" t6 K& |' P
- P4 _' w; ^1 I2 l: Z0 C/ _
static FinderPointer CreateFinderInstance();
6 A; N ]; _3 H' p3 g/ \! T2 t struct FindDevice : std::unary_function< DevicePointer, bool >
1 l* U3 o$ S+ C {% d a$ f3 e+ R) O4 g' t% u0 C& K8 s
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 M, n1 c a) e, H1 g1 T/ t result_type operator()(argument_type device) const
' Z6 f/ `1 F: `7 s+ F' j( g4 v5 f+ Y {
( A9 Y; j* j- V5 o# T* t3 [8 x CComBSTR deviceName;
7 ?4 o, H$ g1 r7 P/ }5 n HRESULT hr = device->get_UniqueDeviceName( &deviceName );
$ D+ f+ S; F: C1 j9 q( e9 ?
3 E4 ^! y. v8 o9 H5 J3 n8 B" M! \- [6 c* R7 f' r" j0 `
if ( FAILED( hr ) )
' C8 N9 i6 y- v' I7 c Q% I return UPnPMessage( hr ), false;9 W7 u: @7 a6 d
) [& k3 W+ `. \$ U: U5 |
" V3 ]" S; e) k% z
return wcscmp( deviceName.m_str, m_udn ) == 0;; U1 e& ^: V' O) f# E
}. h) ]) o0 f' z7 a3 u& k
CComBSTR m_udn;
: A( G* Z: u5 o1 ?. r y; W3 ] };
# @* w$ U( u' V* e, n. b
2 g2 c k# X; K/ T! Y/ T' x void ProcessAsyncFind(CComBSTR bsSearchType);
) a3 s" b, X; J2 W' F4 \ HRESULT GetDeviceServices(DevicePointer pDevice);* O* G. \$ f) i' D0 ^( q' C0 |6 n
void StartPortMapping();
1 A, Y4 x, T8 t C" I HRESULT MapPort(const ServicePointer& service);
1 Z5 {! N; O8 d5 |: t% c* j void DeleteExistingPortMappings(ServicePointer pService);
' @. Y) @" H6 F- c- J" {# S- v void CreatePortMappings(ServicePointer pService); Y! T2 I% c, s
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
& @: G( x; k5 [ HRESULT InvokeAction(ServicePointer pService, CComBSTR action, & \6 i' q4 ^+ x1 G
LPCTSTR pszInArgString, CString& strResult);6 n: P( N6 y3 B' y
void StopUPnPService();
0 @ h5 `2 T" o, g9 V2 D, v, C! i4 M: b
% _" W1 Y9 R& \. k // Utility functions2 Z% j8 y8 N0 y8 T0 @5 `" N( F2 n
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);5 p9 Z( E; ^- U. L. J9 A/ i
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);! R6 q4 e: q6 X
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
% O1 i& {9 |( R! I q; y1 x8 R7 I void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ w! K( j2 ^) u6 c9 ^$ X0 i
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);. Z! Q' P5 G* S# [3 q- y
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);/ m* }4 X" w' H4 L, B
CString GetLocalRoutableIP(ServicePointer pService);
1 N' J8 w! N/ K: a0 F, b+ x8 w( s& N& S! z: w Q
x5 G( l0 V: z3 I
// Private members
9 O. g( ]! _- L; T3 Aprivate:
( W+ O3 f5 g: i6 P6 ?8 A& x DWORD m_tLastEvent; // When the last event was received?4 D6 _5 [' Q' s$ u: G/ w8 ]7 f
std::vector< DevicePointer > m_pDevices;
4 _2 d' v' L" D9 j) F std::vector< ServicePointer > m_pServices;
! E6 Y" Y% n q FinderPointer m_pDeviceFinder;
7 w( b8 s% V7 H3 }, m' C1 ` DeviceFinderCallback m_pDeviceFinderCallback;7 ]( `/ T% x( U9 w( F
ServiceCallback m_pServiceCallback;2 ]1 G8 X" M u
/ K9 e4 w* S4 e, v/ _4 [+ z2 a/ c2 ^9 E- A1 @& V% ^0 {$ U1 t
LONG m_nAsyncFindHandle;0 w0 n7 [2 C; _. E) K, A6 P
bool m_bCOM;
& k# D( k1 g, I$ Q) C( S+ Y: I" ] bool m_bPortIsFree;
0 u3 B$ W7 {5 O5 D1 }( C8 \ CString m_sLocalIP;: x2 [/ m6 B5 O! R" C
CString m_sExternalIP;
9 [9 ? f& z" s( f+ L5 E1 o bool m_bADSL; // Is the device ADSL?
' J3 z( Q9 H# F bool m_ADSLFailed; // Did port mapping failed for the ADSL device?. @5 o; t* i0 ]4 C: ?
bool m_bInited;
1 C* x& f2 J2 T' E( L; r4 { bool m_bAsyncFindRunning;1 Y# C0 g5 C; x& t9 o
HMODULE m_hADVAPI32_DLL;
5 i8 F6 Q/ s8 |' R; H- D HMODULE m_hIPHLPAPI_DLL;
! v2 Y2 M# V' Y$ J5 G$ I bool m_bSecondTry;
& Z- m- |( z, z0 a- B7 v8 ]$ m bool m_bServiceStartedByEmule;; @. D; t: E/ |% w
bool m_bDisableWANIPSetup;
& k( O" J: ^0 a/ G8 u0 Z8 K bool m_bDisableWANPPPSetup;5 C a& E7 t( M6 R9 [- k
* u0 M) M/ @/ B1 f: F% k
4 u; q: V# [2 _};) |4 q1 i$ M: C7 r
5 e- U& v+ K8 Z/ t6 \
& J% H( B+ O* }/ i5 F// DeviceFinder Callback, W' ^* j* z0 ~
class CDeviceFinderCallback7 W6 E- A5 V% d: {" e
: public IUPnPDeviceFinderCallback, m# g# ]( W V. G
{) i- o1 B+ H& ]
public:
; S0 B' w% P" [: U- t6 T. a% D o CDeviceFinderCallback(CUPnPImplWinServ& instance)
0 D+ h) D8 F* W4 J : m_instance( instance )
) @1 y: b# l/ m4 C7 ]: ]: h { m_lRefCount = 0; }# Y, _4 N8 x# l% P! [# O5 ]7 C% @1 F1 O
G! Y3 H# j9 u9 M6 C4 q
. f7 l w8 c( P3 Q& L STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);: y1 i7 |& T, z
STDMETHODIMP_(ULONG) AddRef();
3 T G3 Q0 d5 |* H: e8 J6 B- a# i STDMETHODIMP_(ULONG) Release();
) N! U- D4 U- f2 N( O% L
2 }! |& L: l# |) @0 M3 W
4 \: C, O- L$ q5 ^8 ~& ]// implementation- Y x5 T6 K3 W: M! y* Y
private:- a5 R( l7 a* D7 k$ }% E' {
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
0 X2 q* {/ r5 K8 D HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);) A5 {7 `) s9 z0 G, e; N) n) d
HRESULT __stdcall SearchComplete(LONG nFindData);
- {' W- Z3 Q% Z3 A! O9 L% K- s8 c ]& C6 e" X0 r" ~
# g. Z/ a0 ?+ z2 c% c+ o. Q
private:/ ]$ ^0 ?7 T7 Y/ `; h
CUPnPImplWinServ& m_instance;- Z. A5 |1 _. l! U# y
LONG m_lRefCount;
: L0 O) e# W& H3 Z5 S' P: m};5 u3 S' h3 h3 n) `, m! b, F
& m N% ~- X* H9 f9 @7 }. g. w; I8 {" P1 Q. P- ]0 B, K: y1 C
// Service Callback
5 I- ^) `# d0 Q9 L) L5 lclass CServiceCallback! P- [0 l# u) d
: public IUPnPServiceCallback b9 \" I# T- T( c
{
K0 S" j- H1 b: H% n9 h, h) Mpublic:
9 c F$ W+ x1 b! z) N CServiceCallback(CUPnPImplWinServ& instance)
% `: m' ~) q/ M. A% }6 F : m_instance( instance )4 N) B) D7 ?, }4 M
{ m_lRefCount = 0; }7 M- z& o8 ?/ [, D0 ^2 D
; ~* q0 o/ z8 K4 i# _ b
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
( V2 \0 q! w1 W2 j: \ STDMETHODIMP_(ULONG) AddRef();
# @4 T5 ^) x5 t4 | STDMETHODIMP_(ULONG) Release();+ c' Z% c! R' g7 V
$ }3 W; T9 I$ t, N7 q
% I$ U! M8 j( N# B' j// implementation9 d" j1 w- Q" g4 ]
private:$ o# T! [: G4 Y; T1 _6 k* _, V. |
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 \9 `) G: {$ ]4 P5 @
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);( D/ Y f& s( J( ~# j% W
$ _3 g2 N$ M+ R1 Y' T h
- ^+ t) l( C* d
private:4 C ]; Q5 h4 H7 H3 Q
CUPnPImplWinServ& m_instance;
: X6 O6 o8 P& J1 N3 m6 F7 f LONG m_lRefCount;
0 R1 j! U* w- G" x3 [2 l) C& Z};
2 O" ^9 ?2 |2 \& d
' X# j1 |- H( k; p. w% C! o& W4 h0 E4 R6 d
/////////////////////////////////////////////////" G* p4 h+ [; K
5 z( [+ g* @# j% A T0 G2 [/ s' ~3 |: Z+ Q3 d' j4 L8 O" g3 D
使用时只需要使用抽象类的接口。9 ?3 n7 O4 ]* `. a, m
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
/ Z b& A$ I8 r) \7 `( B4 v& _6 `CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! u# ], Z' Q' b1 B( n8 x
CUPnPImpl::StopAsyncFind停止设备查找.
, |- J$ n/ x. gCUPnPImpl::DeletePorts删除端口映射. |
|