|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,/ ~# F3 d8 W- ~, S4 e
: F1 C3 n6 W7 \ f. I
4 c+ p1 Q4 q) h4 H3 ^5 B///////////////////////////////////////////
* v* ]' ^0 b$ E" f//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
7 Q; \: v) o% n; Y2 \6 o( ? b8 A; \- X7 S8 v& L# v8 ?
0 `5 e$ q# E5 k1 K M- U. P; v+ \
#pragma once
* y; b$ B5 Q @7 S#include <exception>) ?2 e0 S& T2 n! U8 y8 ^
4 @: K" a$ b! L" C- W( f% ?) v
) @) K# i" ]( g1 H% N3 W8 |
enum TRISTATE{
+ v! s7 M- i& q- j8 r/ N- ` TRIS_FALSE,
0 q) W, Y( V# q/ J# g3 | TRIS_UNKNOWN,
5 r# Z. l H+ A) W0 g TRIS_TRUE
8 ^. \ ^, i% L; _5 j( X# s9 [};
; z( l, V. \4 I% R, G% U' g
8 j% K# D8 B! S- N' D i+ s4 I0 l/ D0 f4 v# U8 g8 S: b. b
enum UPNP_IMPLEMENTATION{
5 ]) N9 |3 O7 {7 M2 J$ G$ c- A/ X UPNP_IMPL_WINDOWSERVICE = 0,
- {, f' _# G2 Q4 h2 I: z5 s UPNP_IMPL_MINIUPNPLIB,
. A4 A6 j( ]2 P2 s; \9 k" c UPNP_IMPL_NONE /*last*/
' J! @! X- Z( m U) N9 o};
2 l* \$ v/ p0 D' Z/ F* ?/ M) A& j* Q: R
* F. |) W/ T: D# M3 J" E6 ?
6 h( [7 H. X: o8 K% e$ ?# X4 _
& I& Q) Q, J+ w, _+ Y; N; x+ o9 Tclass CUPnPImpl
& o( E2 r/ W0 e1 f2 V8 L& n! s5 V; K{
# t, r' K7 Y5 H: b3 k! |& O$ gpublic:
/ N1 }0 y- ^2 R( }! R; k* m) }- Z CUPnPImpl();2 ?4 r- k6 f5 ]) y& D
virtual ~CUPnPImpl();- j, t- p9 J- c6 k# S
struct UPnPError : std::exception {};. f/ v7 g# e, O2 H& r8 r3 e# N7 I8 B9 T
enum {- c, l( D3 c8 K. ^7 [* o+ K
UPNP_OK,2 H5 H; \+ B! f+ m# h; Q h8 j
UPNP_FAILED,
/ K5 b! T- b+ p UPNP_TIMEOUT7 x4 Y& J& k- ? B7 d' f
};+ V5 Z7 [. w R4 [3 ]
9 B1 I. N: h" Z* T* t8 e
; v: u0 `- Y7 O virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
0 ^ m5 a& F; o1 d# ]. g& J virtual bool CheckAndRefresh() = 0;3 g g. g1 O, C0 s
virtual void StopAsyncFind() = 0;/ ?+ X, b6 }' Y I4 C2 `
virtual void DeletePorts() = 0;
- ]& |2 X& b& K; U virtual bool IsReady() = 0;8 y+ t s* X3 v
virtual int GetImplementationID() = 0;, F L& _. D$ g4 N5 G' b$ v
) E: x# s& |1 |7 }7 R9 J, o
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
% @! c9 e9 F# o6 T, F' D% ]+ B- O! M$ ?6 C5 Y5 w- ] w
( `/ e1 ^6 g7 g/ D) s; w" D
void SetMessageOnResult(HWND hWindow, UINT nMessageID);* s+ @- O! s$ w/ L( O0 b; X
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }) @+ h/ O" y0 {
uint16 GetUsedTCPPort() { return m_nTCPPort; }
$ Z/ H9 e5 r# |9 H! Y+ _* z uint16 GetUsedUDPPort() { return m_nUDPPort; } 4 A: x+ j* _& j( p
f3 g- x; b* m4 B2 T' Y* q! i
: P; m* R4 o/ w) N2 w
// Implementation& c; L* X, V6 U! d$ A
protected:. S2 S3 }# f/ x0 c4 C* q( Q
volatile TRISTATE m_bUPnPPortsForwarded;
* r4 E; G ~: R1 | void SendResultMessage();
8 s, t0 E. F# @$ u3 m( b uint16 m_nUDPPort;+ R- B8 A/ m2 p
uint16 m_nTCPPort;
6 t# J, @4 r# C uint16 m_nTCPWebPort;3 N9 k" Q3 H, h
bool m_bCheckAndRefresh;) V5 {$ f9 o- J/ s% B% v
8 C# P6 f+ D S
5 z2 z8 }4 N1 V& i; dprivate:
! v* h: b9 P2 O HWND m_hResultMessageWindow;
" K9 n- c- C5 V1 }+ @ UINT m_nResultMessageID;1 |- \. F; b! _! l3 E# n0 T z* Y
5 d% i2 v! A3 l/ \0 M' \, \5 p, N) \5 R& o2 i! x
};
! o9 X& H; r( j$ @, e' T4 g r6 ], D- h5 {- g4 D
6 H4 S$ @4 X e$ b% B// Dummy Implementation to be used when no other implementation is available
, q* P# f u Y) F1 f" I- [6 O7 _class CUPnPImplNone: public CUPnPImpl
, I4 h5 a2 X4 X% F5 w# X{
) |. y" {2 L9 A) e8 Q6 [) g2 [public:9 d2 M: P% i$ l3 D5 A
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: ~1 T, Z, i* p+ U& U& m, d$ y- z virtual bool CheckAndRefresh() { return false; }* f2 Q0 F, L! M" T i) F% M
virtual void StopAsyncFind() { }) k6 O- h1 z5 b3 m" d
virtual void DeletePorts() { }
/ i5 W0 k3 \: ^ virtual bool IsReady() { return false; }, Q9 c& ^& Q; u# h1 k
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, ~8 K1 Q5 g4 i/ f i};
" ]' J' Z, I! c+ B
) g5 @: {& b! n5 N8 g! Y Z6 d. e# a8 r
/////////////////////////////////////+ b+ Y) s }0 n! U2 t
//下面是使用windows操作系统自带的UPNP功能的子类" E' l7 {$ n3 S9 o3 ~7 g7 ^
& C3 v0 b% R* u8 R
' c5 e1 F1 E% ~* H/ T0 u7 e) t* Q
#pragma once
. {' e& e5 ] e! e: M2 `2 W7 u#pragma warning( disable: 4355 )) u, i6 y) p& h( m
. N' S+ i# \; g9 O/ `1 F; W
+ l4 F$ t% X: @: b! f
#include "UPnPImpl.h"' x4 b- J! R) l% P, c$ y7 s
#include <upnp.h>
8 | C8 u. ?; i* h7 R# {0 w#include <iphlpapi.h>$ v _% [' `/ x9 x8 s- L& a( Y: s( W
#include <comdef.h>! H' ^! V1 R" v2 d: |
#include <winsvc.h>
0 s4 @ i% }0 j `1 M' o3 M [( A1 C/ t2 P4 L
2 _- T) ^8 a: F2 q* ~" b8 k" t#include <vector>5 h9 t$ x8 ?; k8 I$ [% e
#include <exception>
8 z1 I6 k9 ]1 O1 R( r( F1 ~& k+ m#include <functional>2 S! w; H. |2 G& v* g, n
1 ?% B( |( H" o* Z1 f
0 l' u, I4 k' O* D
" V6 }5 Q% R* e1 A: B) f
4 `) H% i" l: p7 U) Qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. z: L3 u. r" s% h# ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;. i+ j) T2 }6 G: j* n L2 C; f; D& e8 ]
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
) f" G& q' L3 A6 ~0 U% Mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;4 b1 ]+ L/ v, Y
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 Q% ?6 c1 Z; E- |( N* Ntypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;+ Q, y. W0 ?. k& k' O; z5 W
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* ]" _8 A& Y5 t8 Q' w! |8 M0 C- [+ ?& T& b+ C- O4 q
, _/ C' X7 b6 W, }3 y1 J* {7 r
typedef DWORD (WINAPI* TGetBestInterface) (
- h K$ o" y6 ?3 V IPAddr dwDestAddr, n, ~- x; H* f" p5 t
PDWORD pdwBestIfIndex' F% w& o8 G1 e/ A
);; k1 L: {, ]2 B" a& ]& o4 \& r" Q$ M
8 }( ~2 J- o e* g! ?
b, F: u# A" v) j' h$ ^, u6 V
typedef DWORD (WINAPI* TGetIpAddrTable) (
( d- [* V: ]+ k/ }+ K4 t PMIB_IPADDRTABLE pIpAddrTable,
C& p- Q( T U( z PULONG pdwSize,3 ^3 I) e: h1 ?9 z
BOOL bOrder0 q$ L( r" Z( Z. B' b$ z0 Z6 l& G
);
1 W) Y( I9 E. [
! m+ x0 N) c) T* d9 O" C j6 z# R# R
4 K# S) _. @6 r6 p7 k6 Otypedef DWORD (WINAPI* TGetIfEntry) (
0 p$ G4 a$ z$ r3 m5 Z0 h: u/ R PMIB_IFROW pIfRow- G7 ^- U/ T0 H. V
);0 q4 V# i9 d- B; b; Z
& D$ u4 s. X/ X$ K1 M6 l# ?, ~: S B U- G
CString translateUPnPResult(HRESULT hr);* u8 I4 Z* M8 r5 h+ M& j5 R
HRESULT UPnPMessage(HRESULT hr);5 L/ w* M- y$ _' I6 a8 ^; c9 f
0 q8 c4 t$ f' ~/ t
* x8 g/ x7 ^; ^+ mclass CUPnPImplWinServ: public CUPnPImpl
$ E& G$ c2 d/ E/ o4 ^{
5 h x( t& I. x friend class CDeviceFinderCallback;2 ]+ W! p$ Q- F8 E/ t
friend class CServiceCallback;
# D! y0 L$ a: D6 ]3 G// Construction% w/ m- K) ?2 E0 |( O. N
public:- j( B9 O( i" R% `! s
virtual ~CUPnPImplWinServ();
+ i8 k% G5 m: n4 y! q: E9 f CUPnPImplWinServ();
( A+ V" q7 e- M1 W4 O7 x4 m) a U7 P `
# r! E; t C( e+ v. P7 T
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
: ~* y/ Y5 k$ c0 t$ w virtual void StopAsyncFind();. v5 w8 n* x0 Z3 \( j
virtual void DeletePorts();; V: f- ^6 `6 a0 @* `
virtual bool IsReady();
3 @9 R4 Q! s) P' _ S0 U8 D& h virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
1 F# p# t4 {$ D7 ` b* L9 h7 n; c/ N6 a9 U: A9 b
5 _8 \" ~/ H0 |* Y* v
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
d; [) y3 Y- P3 U& V // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later2 W, @4 Z! A$ J8 g4 |
virtual bool CheckAndRefresh() { return false; };% \% Y$ E" f0 }; z) g* g
# [( j8 G2 `$ P, x0 X2 \$ n7 z2 |3 d+ [( l* `! B/ l* D, g; P
protected:9 x$ k9 M: O# S- m, K' F: B
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 p+ U: u' L3 J& D void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);0 k- |: q' |5 N" ~% G4 i! U: i7 N
void RemoveDevice(CComBSTR bsUDN);
$ b- J/ Z" ?9 P5 Y0 l bool OnSearchComplete();
. A2 K; v9 d/ c( {7 W void Init();
: ~- C* P) V4 [1 P" a. d W; X( _) H- s5 _/ U# R
6 I8 [& C/ W6 \% G inline bool IsAsyncFindRunning()
4 z7 Z3 @; W7 s M# e( k {
3 l" W. z+ u. L o3 i& w5 Y if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: g3 L" q& q- D7 A7 l( b {
3 K) s0 P, G8 G W h/ B2 W. T7 u m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );& I# r* q& y( h/ H- ~% s
m_bAsyncFindRunning = false;
# Y& a9 q; }1 n' @ }
5 T* ?: }. ^# X& v, o$ }* N MSG msg;
% E1 \5 E( r3 d/ Q v$ v while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 @1 o& r5 f# z R6 `) o$ b( O {$ x6 Y. s3 y0 Z. H5 q6 S
TranslateMessage( &msg );
3 g; f/ G% U- Z9 ^) p5 |1 J DispatchMessage( &msg );; p: k3 J) i! A
}, ^8 U/ e4 v. `( k0 v5 B) N: |+ G
return m_bAsyncFindRunning;
; m, w: p4 S% t+ h7 J }
+ K! ] l t+ m" `
0 J* L3 L% x( t b: x4 ~& ]) ?. r) N- k2 n" `
TRISTATE m_bUPnPDeviceConnected;4 L+ M4 Z9 ?" e
+ | l- N ~, v
4 `5 y% `" K# T1 g* w$ W// Implementation
3 N$ A1 _" K5 y" W. C3 s/ h+ s8 F' { // API functions8 a2 k8 l: Q2 a& V
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
5 e; }4 h) W0 m8 d- R$ I SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);0 W3 a8 M/ z! l7 `2 Z
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
" W6 E0 `7 F6 O; ~* q+ l, G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);1 Q( b- g7 O0 o
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
5 `7 N8 T$ P ], s- O- H& h BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);, c( `; X" P7 ^
' A5 |% B' t1 J/ Y2 e
& _! q4 I1 f/ v TGetBestInterface m_pfGetBestInterface;
_" q' W& D& p, b$ x, y TGetIpAddrTable m_pfGetIpAddrTable;
) \, h7 ~" M/ _+ ^ x$ U TGetIfEntry m_pfGetIfEntry;
- [$ [1 i2 F. v% J# n
2 \5 o7 S: j) Z- c: m! G4 @1 y$ C# [/ \4 M% P% b' A6 f
static FinderPointer CreateFinderInstance();4 U) t; M+ n8 M) v2 ]' N
struct FindDevice : std::unary_function< DevicePointer, bool >2 p, d9 }- u3 W. L7 U
{: j8 X5 ~& z1 p" K; k! B- G
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 p# ~% B& X% N
result_type operator()(argument_type device) const
1 z# [: l. v X {
6 Z+ i6 E( {- t% w6 _ CComBSTR deviceName;4 i p" Q# _) r, D2 s% b
HRESULT hr = device->get_UniqueDeviceName( &deviceName );3 x: i% B) [( e) S5 }# R
$ G" `# O x, _4 R2 }& [
* g8 k: q& M% V: }% n' m if ( FAILED( hr ) )
& n" h/ T% c8 Y( w: _ return UPnPMessage( hr ), false;" ]2 g K/ P2 `: N( _7 {7 t4 V
$ w0 F! p" Q) V4 l0 r5 V1 b6 w4 t
3 K- O* e3 \- y, _7 F* f( N
return wcscmp( deviceName.m_str, m_udn ) == 0;
1 A% i/ j7 Y7 J9 K. B- d }0 V1 k1 `. p, Z" Y8 E( i4 N5 b6 K
CComBSTR m_udn;
; Q) X# B% V) L) U };3 o/ j* b; m- L0 \9 w
9 ^/ S7 f s; \ k- m/ @# v
void ProcessAsyncFind(CComBSTR bsSearchType);
* m0 \- }. R2 R1 ?1 {- W HRESULT GetDeviceServices(DevicePointer pDevice);
' f9 r2 f. ]+ U- W void StartPortMapping();
# w2 t' h8 X0 R( ?& F& _ HRESULT MapPort(const ServicePointer& service);
* q2 r% P, f8 I3 f$ v- D5 { void DeleteExistingPortMappings(ServicePointer pService);
- U7 X% m$ d, t9 a i' _2 n/ _% M void CreatePortMappings(ServicePointer pService);4 o# F5 b0 r4 k9 P
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
8 e U3 d5 s4 X! @8 E HRESULT InvokeAction(ServicePointer pService, CComBSTR action, - i/ w- j- P! }; w
LPCTSTR pszInArgString, CString& strResult);2 c2 Q) E) A% V4 L
void StopUPnPService();
' i' ?" O/ y! o6 ?- U3 ]+ Z7 {/ Y; f/ x+ J
5 ?& s8 ]: t3 q L [2 f // Utility functions0 Y: q" m/ N$ e5 e6 v
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 l0 e% e, ]1 g/ I7 a4 u INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
2 [4 z, e: E) j" r INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 a4 e! _$ t( u, o
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! q" }6 H7 N) I. [% k! g1 Z1 h% e
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);) m. W& K/ o0 @( e& s
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);0 Q% c: `- w% t/ `
CString GetLocalRoutableIP(ServicePointer pService);
$ }# E/ j, u* r2 k$ D- c
, h4 H2 z7 p. t% G( U6 y" a
6 c* r' v8 I# ?" k2 L5 O// Private members
0 ^" ]$ P% i/ Dprivate:6 J' P. A: D! P# u1 P* d6 }
DWORD m_tLastEvent; // When the last event was received?
- \0 [6 C( n; m. B3 R; n7 [& i( R std::vector< DevicePointer > m_pDevices;5 v; L2 }, A$ K) O. C" R
std::vector< ServicePointer > m_pServices;
/ ?; a+ C: R7 e }) _* ^ FinderPointer m_pDeviceFinder;( z, q% t0 t6 v4 k8 |
DeviceFinderCallback m_pDeviceFinderCallback;1 D" p4 [; N/ w, Q {5 c4 O% @, H
ServiceCallback m_pServiceCallback;6 v* X; P* B) _& R3 n1 e: j* \
: e6 H0 }- L1 j3 [
( e* S! }" c* m' {3 \# _
LONG m_nAsyncFindHandle;3 I- w7 W9 P3 i5 ] J r$ ~& }
bool m_bCOM;
) ^1 j* b0 V9 r. s- f" J bool m_bPortIsFree;/ t! m5 T; v. M2 D% |
CString m_sLocalIP;
. b; |' I( ?4 H CString m_sExternalIP;
( d; F; b2 J4 x. X) O bool m_bADSL; // Is the device ADSL?
8 d& j! |- r: _4 b bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 s" ]) X4 q8 C, r0 ~" O1 B; O
bool m_bInited;
- e+ t J! U8 C bool m_bAsyncFindRunning;
" N& n6 B" H- b9 P" g/ c2 g HMODULE m_hADVAPI32_DLL;8 Z& ?: Y, [ G3 M: a) G# A) n
HMODULE m_hIPHLPAPI_DLL;
3 J r: v+ t( W! ?/ B bool m_bSecondTry;: b' R4 x4 t8 f# t
bool m_bServiceStartedByEmule;
2 A: C* r9 y8 Z$ o2 B( |3 Y bool m_bDisableWANIPSetup;
. ~8 N S3 l7 L4 W bool m_bDisableWANPPPSetup;
/ h' ^; k5 X, W8 {6 {" B S3 \: f! m3 e! W: w* i0 j
W! b, d6 l2 Z" a. p9 y: @
};
4 J& O: k$ A) a# \( }
/ b m7 R0 q1 u6 ?) W/ m, \/ m$ s' X
// DeviceFinder Callback2 b( g6 g; a4 R' d0 q9 N9 q1 b
class CDeviceFinderCallback
3 ^8 v: w6 j" b* k. V, N% w : public IUPnPDeviceFinderCallback
% ^& j& j: w; `8 \/ m{
' f* |- a, Q7 D0 N' `1 p' Opublic:
5 H, w$ R8 B5 [, p5 s/ ]1 f CDeviceFinderCallback(CUPnPImplWinServ& instance)
* X4 A2 t& {, r" `, s. | : m_instance( instance )
$ ?' l& s4 _& D1 U1 o+ y) |' I3 y { m_lRefCount = 0; }
% y s. a& H. S' h( P; C) \# n- C, J1 a7 d5 `& }1 U
& B5 a; E2 I+ ?" Q. b- V4 b- r STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% V$ k& x6 Q. b# I
STDMETHODIMP_(ULONG) AddRef();
8 Z0 h) T+ A" g7 U" l9 }. g STDMETHODIMP_(ULONG) Release(); K/ q0 _! y: r8 J# q: B
- y7 z2 C! k: o0 t7 M# p. ^: B) V
4 L* n7 h. U- E* R// implementation
* K& i! V, j( x2 [private:
& l5 K& I+ W( ^& M/ \ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
" M g0 L- Q) o3 ] HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. D( H; g% H% h
HRESULT __stdcall SearchComplete(LONG nFindData);
+ p3 ]# }/ g* g3 k. ~
3 v3 _6 A( K# U1 a' P
) y1 {( K) m- }) Y' I6 z9 Zprivate:
3 H; x0 r( u$ i; T& |7 Y CUPnPImplWinServ& m_instance;) k* f% Z8 O! u7 K: _* [' ~: d
LONG m_lRefCount;3 [4 u- G( w; ~0 ?2 F" E: O! h0 z- ]
};
& `2 f4 w' J( H1 a$ n1 O
% L0 f6 \2 d; G7 n( R+ [! H( M
8 P, \* F! Y- l U// Service Callback
2 @6 v5 R% I% X6 t' H+ r6 oclass CServiceCallback' w; u L0 h! H+ \
: public IUPnPServiceCallback# M+ f3 N9 A4 s
{
5 R/ G& ^( L; B- u0 Upublic:! \- ?0 V) N# H, a! s0 L2 P# `( D
CServiceCallback(CUPnPImplWinServ& instance)
! U' m' [0 _! P- r/ d: r : m_instance( instance )7 c9 G$ J P: {" y( e( g( Z
{ m_lRefCount = 0; }
i+ b( U& j" K. F5 v$ D: _ 3 }* i- ]" p7 _8 u
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& i+ n* {6 t! l9 o w5 V x STDMETHODIMP_(ULONG) AddRef();% ~1 ?: H$ d% t
STDMETHODIMP_(ULONG) Release();
" ?: c6 l: o1 Z) U' g% T( H, q
- W8 g) I3 o5 T( |. j8 @6 Z0 x4 b1 t8 K
// implementation. T% x$ ]. F T, |8 B" d
private:/ B+ F& A4 Z2 a# s9 G; ^3 J
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);/ p$ Y8 G; G1 p, k/ a
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);; U- q4 p6 @! Z* T3 w2 N
& r- i' y( k2 V; E3 e
! H0 S' K1 U& vprivate:
' ]9 e+ ?3 O A7 E8 ^/ _; A; y CUPnPImplWinServ& m_instance;
9 B+ D; I1 u/ O% y: o! k6 g LONG m_lRefCount;/ u$ A& R* c7 Y8 q) l& I, d
};
$ A2 `1 S% D. K0 s& X O$ a" ~) Q0 @" q7 z4 X$ h, i8 } j$ Y! d( H
! F- E! ^; D5 c7 L, ]
/////////////////////////////////////////////////1 X4 g- {' \* }2 W3 G, e# N! H! @
7 H# ^* X. D" n" z
" p: L0 A; Z+ D, O; H使用时只需要使用抽象类的接口。- B L) F2 X2 H6 v! K& k
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.2 k4 z0 ]. K Q5 {
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.- }) h6 T7 C) P& E; }! p
CUPnPImpl::StopAsyncFind停止设备查找.! H0 R, z/ w$ V
CUPnPImpl::DeletePorts删除端口映射. |
|