|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! i% Y: e" ^3 d! t! R( m
5 u x q& _/ V3 p! u* M5 o5 v
5 h2 `: {- r7 p2 W///////////////////////////////////////////9 ?% A2 i' R. `# z
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 J/ k0 `3 z6 _4 C" J1 f
- g% S$ F. u6 g4 `( }! ~# p
+ P' k1 A! [2 d# }#pragma once
2 Q# f+ G& K2 ]- G#include <exception>
0 u2 l5 M' f& P$ g5 @9 D. @- R6 f9 u0 J/ i7 [3 d
, ~- A. P! I! Z enum TRISTATE{
2 K8 Z( r4 d+ g! d, \3 Z! _7 J# ~ TRIS_FALSE,+ V T2 j, X: X/ r t. [0 U9 Y) c4 P3 ^
TRIS_UNKNOWN,
! _3 x |# Q# u _( Q1 h TRIS_TRUE
5 M' [! A$ w" M' M, O5 ?};* K. k# q& K" g) i% p; I4 S( Z
# L; J, V& L, a* |
; R5 c. X6 s! I7 _6 I9 N1 N
enum UPNP_IMPLEMENTATION{1 Z. J" F/ {: P3 b2 M; m
UPNP_IMPL_WINDOWSERVICE = 0,
* D8 m1 a' ~, r& G9 X' \9 Z8 T8 P UPNP_IMPL_MINIUPNPLIB,
! J2 m; q$ f* w L* e1 j UPNP_IMPL_NONE /*last*/4 Z7 n1 A; G3 l$ `1 l: p
};0 e7 R1 J; w' n; \5 @8 ^0 v
$ @ X& {& X( @: n) ]! i2 D
; t: d0 f" k% ?0 @8 t' |
. l; G# C; @. _: c. e
7 l+ M2 U7 v, l3 I1 B! D( R/ Jclass CUPnPImpl
1 |; g8 r8 O) {$ I- U% n M! m{
S: h! w q: h$ gpublic:4 E9 g# ^7 }/ e% q6 Z3 p5 a8 o
CUPnPImpl();
* c" I6 k8 _: t' H' o9 h virtual ~CUPnPImpl();- t Q! D& D, ]7 h
struct UPnPError : std::exception {};
& {9 w/ f7 C5 |0 h" n enum {: i- B& z# M9 t8 N
UPNP_OK,4 n2 N# s) L% q: |6 Q r
UPNP_FAILED,# ^* m9 O% k( t+ ^7 ~
UPNP_TIMEOUT6 Z$ P$ H; ~' d @
};
7 T$ p: d% p* R* ^% }: O: k# X$ R8 \, F3 G* Q2 k7 W* q8 J
2 F( L: S3 _( O$ \8 |; z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
6 f9 i. D+ m2 y# J virtual bool CheckAndRefresh() = 0;
$ I) Q% k: L7 ^8 u1 \ virtual void StopAsyncFind() = 0;
( M* K' c7 Z; I* ^% m' p virtual void DeletePorts() = 0;/ i2 Y1 {9 v! [' D$ W, g
virtual bool IsReady() = 0;" R9 N* P( B/ d: b3 m2 W: ?6 L
virtual int GetImplementationID() = 0;
~! I' b9 s1 I, E) B# D 6 {6 b {! [4 J9 \
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
& P$ A w% T; h4 v" z" U. x& }. c) q, u5 z" S. n2 k9 ?9 X. c
+ h# ]; Y- P0 g* D/ i5 A void SetMessageOnResult(HWND hWindow, UINT nMessageID);
: z% O9 i% V0 l( A" |- x+ {2 @ M TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }2 _/ h! x9 I! h6 x4 t s: p
uint16 GetUsedTCPPort() { return m_nTCPPort; }9 l+ B( W5 h( i
uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 `) J& K2 G* H
# {* P$ a6 L6 k- v/ N
, K4 A$ c8 ^5 U* f3 ~+ l// Implementation; \/ {/ h) z$ H; L4 l' `
protected:
6 f! m& I% H& [' a9 l) V9 [ volatile TRISTATE m_bUPnPPortsForwarded;
& q) s0 g! m" Y0 [6 r8 H) @: R void SendResultMessage();$ K" A# s O7 x# m
uint16 m_nUDPPort;
0 a g* u, H% O- L uint16 m_nTCPPort;, h/ @* z# O2 |8 j( n- Q
uint16 m_nTCPWebPort;) O8 p- ?8 y6 I' e. N
bool m_bCheckAndRefresh;
# s& t$ a3 d. o# ~6 K+ v
! a9 M7 T- F' [# y w6 ^- O2 b! s9 h8 D" ~
private:
4 G+ i; W" T" n5 ~, @ HWND m_hResultMessageWindow;
9 i$ O- K* Q* f/ ]6 } UINT m_nResultMessageID;4 W2 c. O8 M; v) Q0 G, U
* y( ?, F H, b; X( ^& a
5 ~- f& V# u8 c9 d/ [5 I X% [};0 l: } O$ Q ^2 ]+ b$ z# p# @7 z
( a" P& x( w- g
1 x2 Z3 i% V/ b& C$ n7 ?- _8 @; n0 S. d// Dummy Implementation to be used when no other implementation is available9 x* G9 i1 e8 W# x9 F N) _- v
class CUPnPImplNone: public CUPnPImpl, [$ I8 M7 Y& P4 ?
{
6 S6 r0 A' k) n" Z5 u9 npublic:
$ G, A$ W2 A0 @6 C2 }8 H7 G/ ~9 d* D3 O virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
H9 s5 k1 K/ i& s virtual bool CheckAndRefresh() { return false; }
6 y/ w8 [' d2 q" B- O; U virtual void StopAsyncFind() { }
# x! L, M' Q3 K6 o virtual void DeletePorts() { }
. Y0 |: s8 R. x/ k4 ]0 g virtual bool IsReady() { return false; }5 t: w' Q+ ^& y+ l
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
/ V/ S/ W) ^1 z, G};9 w) b4 D$ q1 d8 ]0 h- d
& v+ `9 ~. w7 s+ a$ u/ ?* {* ~
8 ?+ i. m. f! n1 W( l1 P/////////////////////////////////////" E' C4 I& o; D s' [6 v
//下面是使用windows操作系统自带的UPNP功能的子类6 d; t! l, T- I8 ^- @2 Y
Y& X7 h0 ?4 ~8 H% b6 ]" L r
% O. X* H" G2 J; X#pragma once
: d0 e- K! c1 N#pragma warning( disable: 4355 )
3 ~ J1 Z4 I, [! u4 r! G3 d# f/ }: g3 o8 o' K( ?3 H
A" t1 C9 g4 B6 W' ] g& s#include "UPnPImpl.h"
" g5 K, G8 |: l. d#include <upnp.h>: g5 T0 f1 y$ e
#include <iphlpapi.h>4 E& Y) m0 d; |( c' p- e
#include <comdef.h>
! P- T* A2 ~% o- i#include <winsvc.h>
2 F8 s4 z( f" G& y% K5 P
4 l- [8 i8 {. p" h0 b( o( f- ^. `, }0 q
#include <vector>
# \" _; |/ `; @; b#include <exception>4 j0 ^/ p }3 ~1 f J: ?
#include <functional>6 `* h) U# N8 R( M6 f, P
" | F( @# f* ?1 b3 Y( e9 C S
! ]8 y: p- W' T$ n: S
! ]9 u9 @3 M$ e" h. `
5 h; i" E7 F8 p# ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;2 J$ |( B6 N1 s9 b) U2 G
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;/ {8 ]4 ^5 p3 e# q) S7 s
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;. j6 _. J0 a/ Y- ^. p/ Z7 w
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;0 J6 \+ W4 M+ c& ?) C: C
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 j( ?6 ?1 M' A' ^7 }6 Qtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;7 Z' q+ P( F7 I: u% C
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;" \2 h5 W$ p T# v( U
7 p/ e. v6 t$ Q1 I# F* y3 H
Z" `5 @% O! n& J9 N
typedef DWORD (WINAPI* TGetBestInterface) ($ [6 Y/ G2 ^" C# S2 B% M( m
IPAddr dwDestAddr,# b8 m, K* B: }; b" D' I
PDWORD pdwBestIfIndex2 U+ |! f. `8 T
);8 D0 b; o3 ^7 F9 D5 e
4 }6 D3 j: N$ p7 k5 F
; q. D i+ y }
typedef DWORD (WINAPI* TGetIpAddrTable) ($ i7 i. j% r' X/ a$ ?9 I! }
PMIB_IPADDRTABLE pIpAddrTable,$ Y. P, K; T* |+ R) [, _
PULONG pdwSize," Q& i$ U- i: W% y; A2 o, G1 i4 L
BOOL bOrder4 r, q! C0 H0 O* H' B, M. Q: A
);
" y/ O3 s+ E- d0 R3 W+ n
0 R- y* Z- l2 b: D1 J7 Z* W7 H6 r; X! D. }1 o
typedef DWORD (WINAPI* TGetIfEntry) (8 R, J9 q* N9 e8 r* B2 Z! m
PMIB_IFROW pIfRow9 B/ m1 S3 n/ Q! R- A
);, z* n: ~2 {# G+ r+ X5 j p; z
! v; [1 G' ^5 c7 d4 |5 G8 Z) ~
; ]" G5 i; F G3 J9 E5 f5 {6 E# ^* D. \CString translateUPnPResult(HRESULT hr);' R2 {" r. L4 Y# Y& p4 d& d+ B' |
HRESULT UPnPMessage(HRESULT hr);6 `1 |& Y7 s% L
. ~/ v# R: v) S- I) ^
7 i M' M: X4 u& D$ F7 M( S+ Cclass CUPnPImplWinServ: public CUPnPImpl
) j/ e' g' i6 Y" P6 K3 ?{
6 _ z5 g( Z; J- M7 K0 k friend class CDeviceFinderCallback;, {- }7 v3 G! B
friend class CServiceCallback;
. _2 s) X0 m( ~. h" s# o" Y5 U// Construction
' }( B- ^' E9 ?8 l! apublic:
% R& C. @8 G2 b R: R9 E" y virtual ~CUPnPImplWinServ();
3 u7 b3 m, Q7 @, Q; b) l CUPnPImplWinServ();# d; Q9 [4 g# }
3 y2 d1 E0 W/ Y. w# U0 T# H9 d# t+ R# K, {
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& ^ P# o% G1 B b virtual void StopAsyncFind();% C8 v' ]& k- t( I5 a5 o) A
virtual void DeletePorts();
- @. w5 n- r* j virtual bool IsReady();: Q' R) p% d. X! {! }
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( U/ m& M6 Z- z% v3 }; I4 S
# [) M k& C7 R4 A( u
0 U2 g: y) q( F z9 C' q* Y9 ^. |
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 J6 e3 e6 } i5 U* A // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 v. V% n, e' p: h+ w# `
virtual bool CheckAndRefresh() { return false; };" }: `$ E' U3 `$ F8 G: w4 L( x
/ i9 J, M6 K1 a7 Y& T0 z0 \7 Y: {1 b# V
protected:7 b8 ~% a: d3 T9 v5 ~
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
{& ]2 e @5 w$ B7 F4 I void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
3 K# b5 r9 [ M5 _9 @6 W8 \& \ void RemoveDevice(CComBSTR bsUDN);
+ A0 C7 m& J1 N+ a5 X bool OnSearchComplete();2 ?# A" A2 h& B9 w
void Init(); [4 R5 ]2 t3 g. M6 J/ t# n+ g, j
( a9 E+ p; A% R" w: G$ @+ X$ S9 e- j3 c K( ?$ y6 e. f( n% I
inline bool IsAsyncFindRunning() & S1 n" a8 F" _
{9 m* l" w) L. |
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
. ?( ]$ x V6 G9 V1 f2 C) u {
1 N- v7 D0 G, S% m m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
0 _9 N. x. h' F' y3 h8 z m_bAsyncFindRunning = false;1 T2 c8 V; ~3 B: W5 C
}
* `) p. ^! S$ |- \9 @8 e' i MSG msg;
8 ] T) D0 z1 i* c* G0 v while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 @! y9 l( i2 Q. u( p* f6 `+ C' h/ l
{
: l! ^# p" ~0 w" @8 h3 E TranslateMessage( &msg );
7 C$ ]! f8 n7 k4 @ DispatchMessage( &msg );$ u, e5 m3 @; G# d4 F3 \
}
1 o+ K5 t8 W8 c1 p1 g. J1 O( ~ return m_bAsyncFindRunning;3 e& w; H9 J y$ s5 V# }5 J+ ~ B2 Z6 E( N
}
?! _3 V0 A1 g. e! y4 B3 @' k) H% B7 {7 A
4 }1 ^3 ?: P# b% G2 H6 m TRISTATE m_bUPnPDeviceConnected;+ \, l/ d" O- c
3 X2 y( u, O: `2 _) Y- Y6 H1 k; `! K: _: M. _% X6 E' N) }9 F0 R
// Implementation1 c) W' m1 e0 n! a7 E' X
// API functions
( ^* \, p9 F8 k9 g; b' m+ e5 b) V0 d SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
9 |8 i( s! \% t9 \+ G- A SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
* S. K! f+ R; ^5 i- B: M% G BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
, @# V# y; @+ M: A! B) z, { BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
+ ? x( I3 \/ y- n/ [, g0 V BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);, G3 y4 O D* ?3 k+ G/ E `- X
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);- ]# c. ^; @; h- K: c. Y @& ?
* N# p1 I8 v! ^8 ]4 z- ~
) G8 E' A4 ~8 E TGetBestInterface m_pfGetBestInterface;0 @) `+ Q0 Q q
TGetIpAddrTable m_pfGetIpAddrTable;5 f* @4 g* X6 R ~6 x9 `) T' S, n
TGetIfEntry m_pfGetIfEntry;
* z7 H7 T# ^# G2 [
, Z9 f( f$ x5 }- y$ |& _& M* g" q, r! \. w X- w6 S% Q
static FinderPointer CreateFinderInstance();
2 p. K& t* x6 X% Y! a# ` struct FindDevice : std::unary_function< DevicePointer, bool >3 y( O! u* Z6 v) @" o, `& {
{
1 j1 T" I" R/ R9 b& G2 k/ X& E5 Q. k FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
" `+ P) k: \6 K1 f/ u: W$ Q result_type operator()(argument_type device) const
8 ?& ^5 p' k% U8 @% e {
3 g8 o3 J2 Q( f/ k7 i CComBSTR deviceName;7 a' N; ~# }4 C# \" I2 i2 ~6 U8 E
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- f s8 f K# F' X& R) T
$ |$ R4 q3 s$ a. x. r+ m/ z0 I9 @% A1 m( X
if ( FAILED( hr ) )
4 B8 l% l3 Q& p- x- J7 L8 U return UPnPMessage( hr ), false;3 o1 ?8 E, p K) U
+ u2 E$ [ g1 q$ n. l& k" U
$ W3 h5 @* i4 o, ?4 a) |2 z3 y& h return wcscmp( deviceName.m_str, m_udn ) == 0;' R4 e9 g# X1 N G
}: H0 v4 Z7 ~/ X9 U; i1 ?
CComBSTR m_udn;8 Y- b- P% v4 J+ h
};
3 [. H! @6 a( w6 p
2 R! B# O/ U/ D9 S void ProcessAsyncFind(CComBSTR bsSearchType);: U* G; W* k, u0 f$ g, q
HRESULT GetDeviceServices(DevicePointer pDevice);3 i% S. }% g" Q& }; ?* r/ H) U
void StartPortMapping();
; C( @8 S, d0 \! d' e! v HRESULT MapPort(const ServicePointer& service);
8 a/ J h' M$ A# y# G- F void DeleteExistingPortMappings(ServicePointer pService);
. e; a. U; s7 z9 {/ k void CreatePortMappings(ServicePointer pService);( ~; E" h7 w8 z! B* i! [/ q( Y9 Q) {
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
9 X, B4 H5 M. M3 y HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
9 T# d. h, F' y- A) ?& Y( d/ f LPCTSTR pszInArgString, CString& strResult);% c5 S; ~7 _, ^- A6 V# @, H7 g
void StopUPnPService();
& F8 Q0 f% _. n4 x" Z) U
: X7 l' o7 ?0 I
7 P0 Q; J# V* ^! p/ U3 A // Utility functions* a9 R1 X" K+ Q3 i8 ]3 G
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);8 g( `9 y* x ^
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
- l* ?% j& ]& n INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
8 G* [" y6 [# N. U1 j$ z- j void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
. r6 y: `& q8 R HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
4 M, b2 @! j7 w8 I7 t HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);( w- o. ?" I% a3 E1 X. H5 B
CString GetLocalRoutableIP(ServicePointer pService);
/ o1 z' o6 |! h' C4 h! w* Z4 U1 x
3 \" _) J# X t0 I% y* D5 X& \+ C. `; p1 |5 t: `/ Z# E8 L
// Private members; C) ?2 o% M8 a' c
private:; @ f3 g$ w/ H, ^" V; `( `
DWORD m_tLastEvent; // When the last event was received?
* I* F, @3 z( M* S4 M std::vector< DevicePointer > m_pDevices;
; }! m$ O+ H( w! y std::vector< ServicePointer > m_pServices;$ e1 @! q( h# f
FinderPointer m_pDeviceFinder;
, ]; U, d: b2 @9 \% n DeviceFinderCallback m_pDeviceFinderCallback;) Z2 C O3 V( `* z
ServiceCallback m_pServiceCallback;
8 }: ]2 U1 F# h' ?% I+ R$ @
0 R/ S8 b- b) F% H" A! C0 y4 I, L8 I: j# F6 r
LONG m_nAsyncFindHandle;
) V+ f. I/ V8 Y9 G9 u bool m_bCOM;9 U9 I; G4 v' m/ |- \
bool m_bPortIsFree;+ ^9 y6 ?- k q! P2 [
CString m_sLocalIP;2 c" W) v4 v6 S
CString m_sExternalIP;
" A6 V* y; C/ }2 q% W+ d0 b* d bool m_bADSL; // Is the device ADSL?
# i/ H& w; G5 i3 }0 V! m5 p bool m_ADSLFailed; // Did port mapping failed for the ADSL device? h# q, s/ A* ]6 j
bool m_bInited;
; F" ^& ?& D% p5 r9 ~ bool m_bAsyncFindRunning;* K! |; ~1 N. N! U! s3 v1 E
HMODULE m_hADVAPI32_DLL;2 `6 F& O7 ]8 c1 k
HMODULE m_hIPHLPAPI_DLL;3 P, Q9 e( D$ ^& `# _8 O& X& ^
bool m_bSecondTry;6 G* L V6 S3 j
bool m_bServiceStartedByEmule;' x1 m* ^1 d4 t* J
bool m_bDisableWANIPSetup;7 h/ b& b3 M. ~8 P! r8 K! n
bool m_bDisableWANPPPSetup;" y5 {3 N; Q+ I' |
, F: {3 E, O5 D( {9 ^& L: I9 n, P* v! ]: G/ Z% E! D7 f6 X
};
2 F! t+ ?& Q" e+ E4 c# V( ]* W* O, i- O. @& r4 x7 g4 I
( X ?8 M3 G! I# m# |+ i
// DeviceFinder Callback2 ]6 o7 f0 d" w6 n+ o& g
class CDeviceFinderCallback
3 A4 Q9 N, j" w/ w : public IUPnPDeviceFinderCallback
! x. j0 `9 Z$ ]! R% |$ j1 f{2 v' z* R9 ]. r J' n( s
public:
/ \7 A, R) k5 x0 X CDeviceFinderCallback(CUPnPImplWinServ& instance). C1 B- J# J$ N( d7 V/ Q* |
: m_instance( instance )
+ Z' K2 I0 V2 Y- A! O7 \9 R { m_lRefCount = 0; }& Y7 I/ p# W- [+ c" a
- M/ A6 L8 |' ^; E/ K
8 n$ j8 o4 ^8 w; O% t& o, { STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
i& J9 l% h! R8 x; {5 M STDMETHODIMP_(ULONG) AddRef();
$ R9 L/ n$ z; D STDMETHODIMP_(ULONG) Release();2 g0 w1 D0 e. q7 g2 O- b) k2 {% T% M
' E/ r$ u& D; W. v( J7 {
+ d7 x2 z, ]4 o& w# r// implementation
) v* F0 M g8 v3 V' \( Iprivate:1 K/ q* o9 f- ]. J
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
/ W% I# K+ x' N0 q! F HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% u6 v4 Z" v; ]; }% |4 C
HRESULT __stdcall SearchComplete(LONG nFindData);+ \* H) d4 t$ A# b
- g, g; a' t) c9 q, i& F& f, X7 F; M, D. Q, ^' L( j
private:: g5 x; m" k7 J8 H+ B
CUPnPImplWinServ& m_instance;5 ]. N8 X s- F8 x( _+ [: ]
LONG m_lRefCount;
; l* d2 s% e2 c( k2 O) O( M};
* V; ^9 y5 R# f' l( V4 d3 [
) T9 o) r; k% J9 y- w0 T% G5 T: L9 ~9 Y: r I; @ W
// Service Callback # Z" I4 p9 l, ]+ e( f8 M* T: P
class CServiceCallback Y# S! \/ E4 z- Y
: public IUPnPServiceCallback
1 G: F: ]% v* |$ t) \2 g{
6 m" T' U& q% |% L7 ^( `public:
1 E k( W1 C. ]( a6 r( V CServiceCallback(CUPnPImplWinServ& instance)
, }4 J* R! x' W& \) E ] : m_instance( instance ): }! r1 w& U+ `' f
{ m_lRefCount = 0; }; Y& L- o2 Z6 `. Q `0 e
; I4 R7 h8 B4 N2 p2 j4 J/ e
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- p @2 k; Z: U, l STDMETHODIMP_(ULONG) AddRef();
9 K' ^& N# `( k! Y' a STDMETHODIMP_(ULONG) Release();* ~# B: j! a& O" ]" ]$ }1 B
5 v2 E5 |. y6 a/ ^' J( a4 N
$ i% j2 L, }5 C$ E5 o$ ]
// implementation
6 ~" x% B% [+ a- ]" Rprivate:1 Z5 n4 \* u; ^3 v' j
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
" A/ l: x9 a9 n7 x, L' Z+ d HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
9 {3 e* n" C T4 I
$ C) w e2 o: u, Z% Y( |; N8 f7 S8 U: u8 o; ?% h
private:
# Y" y+ C% \( S! o/ T CUPnPImplWinServ& m_instance;
. j2 V; I: @, U$ Y9 j LONG m_lRefCount;
5 \( U- D, P0 Y+ H+ S0 O};
9 K/ X6 y0 v: N& x4 O' B' p; J5 D" e+ a l- `& O) V
, k- U/ ^, }, q% P/////////////////////////////////////////////////; p2 J- Y& S0 M+ N5 M# j B
+ ^( \4 r; z( V' \8 J) [
, D, ]# K0 f% A0 l3 H使用时只需要使用抽象类的接口。* {! L& p, t& I6 D" s4 I/ s) U. u* g
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: B1 b7 g+ w; u# G6 P) }3 L
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.% c/ J( N3 a/ w/ o
CUPnPImpl::StopAsyncFind停止设备查找.) u. F( u" ?. \! ^; H3 r" n
CUPnPImpl::DeletePorts删除端口映射. |
|