|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 T j: ^) n) v- |$ W$ I2 W; F
) ]0 _! y7 Y" f" y- O0 ^0 k" {, L. L9 N2 H9 u0 ~
///////////////////////////////////////////
5 p' L( W0 n0 R% K+ d: r; F1 b//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
1 D8 O5 R" y$ [0 k6 s* m% R! b) @* t+ M0 d
8 m( h2 t; x% s8 W# B#pragma once9 J; B! ~8 c0 Q @3 e+ e+ k
#include <exception>; {: r% d- J$ [& ?1 O1 q
& h: ]6 Q9 H& }: g& @* g1 c
% l: y7 l# M$ E* { enum TRISTATE{ d8 K0 o! M! y; F) N
TRIS_FALSE,
) b% H5 s+ y. E; ~9 J TRIS_UNKNOWN,# {; g- ]4 n0 c3 ?8 d
TRIS_TRUE1 [1 n0 x; _6 }) D& e0 q
};: F3 y8 P8 k' r$ p. U
; n' q0 w: ^9 z5 t! d. u
% A# B- d& L) Z2 ]- M5 k& Benum UPNP_IMPLEMENTATION{
( a# r2 @2 _* y' s% f UPNP_IMPL_WINDOWSERVICE = 0,
. ]7 i0 k* L$ C$ W/ d5 D8 ?0 q- N- f$ l UPNP_IMPL_MINIUPNPLIB,
& v; G, [6 `9 {: U5 y UPNP_IMPL_NONE /*last*/
+ v0 Y Z7 B. Y. n+ ]. J};
" n4 G9 j$ @, B# x! X$ k) y+ B- `, V3 t1 G
. R5 E* z0 V$ T: E
/ u. m% B0 p: `+ M
# |' ^; x3 K" b+ ]% ~
class CUPnPImpl
% ~. x& f* N; M5 ~{! v) X+ D4 E! B" I! v _
public:( T$ i8 j+ a8 b0 b" z
CUPnPImpl();0 p# i' y- m. H: k3 t& n7 a8 ]
virtual ~CUPnPImpl();5 y7 W+ U4 e9 g) W# b
struct UPnPError : std::exception {};
, l6 s/ a( Q t0 Q* V0 z enum {
; g$ V0 V$ u4 b( \/ ` UPNP_OK,5 i* b4 s7 \) ^' Z! B
UPNP_FAILED,5 o6 {9 I: ]3 S) n6 k+ a5 i. L
UPNP_TIMEOUT
1 L" q0 L$ d" U B( D/ w9 F };( g- r+ ?1 ]. n5 X& F$ k
$ V* r! E4 G+ j) I! O! d6 g
# x% _- B& O/ z+ ]; s
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;8 ^# Q: [% V7 V8 I/ f* y& u0 P
virtual bool CheckAndRefresh() = 0;6 X( ~! R7 [$ k0 N+ \8 Y9 v
virtual void StopAsyncFind() = 0;
$ y/ s1 o- j$ Z# a7 ? virtual void DeletePorts() = 0;* |8 b3 ?+ c# F* s. B
virtual bool IsReady() = 0;1 S- q& \3 ]/ s
virtual int GetImplementationID() = 0;
% `' S$ b5 Z/ u0 h) _ % h" ~9 E; i! u8 `8 S: M! a+ U& q
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; k, W5 A6 G# y6 ^9 j: n# l
2 o( ~0 `9 p. V/ }, ~6 ~
" u& o7 n6 Z8 g9 ]; k" h$ ] void SetMessageOnResult(HWND hWindow, UINT nMessageID);
5 v% Q4 d. f! a# A6 | TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
# b4 w( t7 K# B- F" E9 a uint16 GetUsedTCPPort() { return m_nTCPPort; }
" w$ @/ }' C' ~/ I uint16 GetUsedUDPPort() { return m_nUDPPort; }
, B* T( S, y5 A9 |3 }. t# w5 h: R" |( o2 Q0 Q; k6 L4 L
0 C' o# C0 ?" J! v; W// Implementation# G0 [4 t; h& i+ O8 w( M2 |2 I
protected:
2 K/ V4 s7 e. i6 K4 t volatile TRISTATE m_bUPnPPortsForwarded;0 a9 J' |7 p) |* h5 N5 n3 P
void SendResultMessage();
6 v9 @2 s* s5 G uint16 m_nUDPPort;* z7 Q0 Z2 l: @$ b: [
uint16 m_nTCPPort;
3 k+ n! Y2 c5 d: v$ n$ o7 M U% F uint16 m_nTCPWebPort;
6 s w R. J6 R, \+ m4 F bool m_bCheckAndRefresh;
+ F3 y3 @% \$ Y8 r! I- `
' H; y( p& f8 S7 l1 a* z0 w
; O. B4 K5 H1 d/ e3 U3 d8 pprivate:
3 ?0 |) l- j$ e1 v* q: O$ g& t) a HWND m_hResultMessageWindow;
, ~+ o2 d- q( m7 {4 ^ UINT m_nResultMessageID;
( Q3 |* v* s5 \+ z6 R, l7 ]0 ?: P6 j& A; O
; u8 O, F a1 V! q. z& _3 H: O8 u};
6 F" w& V# A+ H
* l9 a% y5 q; ^) f2 z# c
; m8 ]1 _9 R2 n0 J* k# O( _" }// Dummy Implementation to be used when no other implementation is available
2 s9 B0 p: y6 z6 i U9 [7 iclass CUPnPImplNone: public CUPnPImpl
1 }' p6 b+ A8 U) v G/ v{; B" r2 Y) A9 V8 a0 b, {# @
public:
8 R0 N/ L4 A4 i- L% j virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }2 o, w" J- p7 B8 \) B2 m6 r2 _4 [- R
virtual bool CheckAndRefresh() { return false; }
6 Z! E1 i& R, Z virtual void StopAsyncFind() { }
, b8 N# @) I; l" H virtual void DeletePorts() { }
3 x! {& x1 j2 p# K1 Y; \! ] virtual bool IsReady() { return false; }
/ f# [! E; Q: d virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
4 X; ~4 U) l2 A* A2 f ^; ^7 Y W};
+ ~4 O }0 N2 v5 i
- W2 U0 R; J9 d3 i
% z8 E7 m( }5 f2 O+ G/////////////////////////////////////
4 T3 K; h- }5 [5 d3 s8 `% \, I//下面是使用windows操作系统自带的UPNP功能的子类" C5 h1 y( K* o$ v# N, U. G- Q
* G$ K7 `; X- {. O, H8 H# d
* m, Y7 R1 x9 q: y: ~2 a3 F. m#pragma once3 K" ^8 d/ G2 P3 T% f
#pragma warning( disable: 4355 )
) M7 W, `" l) A6 n
6 l5 Z2 g" |6 _% p2 \) O7 _' b' A8 J! O4 B1 Z& h7 h5 D: q
#include "UPnPImpl.h"
$ {/ p6 j7 X3 l) v y( d7 A#include <upnp.h>
/ _4 _; u" ?3 t( ]7 N! l3 p1 w& V# u#include <iphlpapi.h>
) t. T4 X4 \6 |" `. ~#include <comdef.h>% r F. N4 _. C" Q* n& ^1 b+ K
#include <winsvc.h>
8 g$ o* r( f8 f1 r; M7 [: E) l S8 e
/ y/ `% Y' _6 X. ^#include <vector>- o1 \% H% L# j' y3 V/ \
#include <exception>0 ~8 |( y" r! ]
#include <functional>5 A* `5 W- Z( G7 R
6 f# M/ X) U7 \' B* V2 N* s/ I
+ m0 r, }2 {3 r2 a& I
9 a7 ^* w0 b1 j0 e( N y: C# k; ^* Z ^2 P1 l
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
4 {! [! _7 f/ \# @typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) b7 Z& z- M z" E$ `* `. ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
, o2 j1 D* f. j- f9 v* N/ Utypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! f* R+ f+ S6 r1 t1 O* w
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
# U+ U( [, b3 atypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;" ~4 t1 r& e; T& M1 c7 O# L
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
! u$ d, a8 }$ `" Z, C* k; Q$ s4 [2 @+ h4 K8 C7 C- l: A5 \
* n1 ]+ w- T) Dtypedef DWORD (WINAPI* TGetBestInterface) (
( C! @% }. m" S( O IPAddr dwDestAddr,: y- Z0 q6 Y# T. b! q, o! \( E0 w' s
PDWORD pdwBestIfIndex
) l7 a! C( q/ x6 G% a7 [. b);6 c( D: P/ q2 x
8 M. c; t0 v( y, G( H: N4 {" o; R/ z3 t/ x) O
typedef DWORD (WINAPI* TGetIpAddrTable) (
! n3 b& {% k% p" ~ PMIB_IPADDRTABLE pIpAddrTable,
# \# ?# `& J$ ^+ P% z& ` PULONG pdwSize,
0 M. Y: S2 A) \/ Q' H, C BOOL bOrder
% D& M6 k( v; M& k# a3 N) \);
) F2 W A9 [8 }9 T; K9 [5 ^# d0 G5 Q
- k, C1 p5 {: }, ?- h
typedef DWORD (WINAPI* TGetIfEntry) (! x3 _5 @% {3 T) l5 Q+ @. V
PMIB_IFROW pIfRow
! b5 P3 \: m. \- q& k' H);6 H& k! k" g% q$ v# I
( y: c1 h; z1 ^9 b0 v. n0 @
7 s- m2 L7 L% iCString translateUPnPResult(HRESULT hr);6 j/ G9 q! T5 W5 b3 ]5 Z& ?+ X0 O
HRESULT UPnPMessage(HRESULT hr); \6 L! { |& s3 S: p* @5 C
7 h/ C: ?2 f, J7 ]" |7 m% _
7 c, \$ p$ B" d6 j) y9 Y0 W; O
class CUPnPImplWinServ: public CUPnPImpl
6 x* W! e+ X& o; W: B2 G: Z2 j* s q: c{/ ~7 [) g' z: k: X( H
friend class CDeviceFinderCallback;
0 y/ M" t) w9 g( p) P" D friend class CServiceCallback;
) y5 w# L$ `- D6 }9 O// Construction* y! p0 q/ Q1 J/ k3 b
public:
# V& e1 g$ B8 g0 l# \7 E$ Q virtual ~CUPnPImplWinServ();
6 y# {# x1 |* ?/ B2 d CUPnPImplWinServ();
, K) a2 x# N$ V7 F" R$ b6 o2 m$ ^7 E1 s
5 F# l# A, w5 L4 k; e+ m5 x
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
3 Q5 i9 g8 u* Y4 l C virtual void StopAsyncFind();
: L4 k) I7 Z% i# n7 v virtual void DeletePorts();
2 M) L- ^5 c" ] virtual bool IsReady();3 B) r, R9 q1 }# B3 L7 U
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
5 V0 K! e' a& i/ y( c1 r- I Y' |/ U6 Z
" c! @4 o& z- ]4 i // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
z: J& z$ h) U; C7 n // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 E1 C7 z6 l. Y2 V3 V( n' Z virtual bool CheckAndRefresh() { return false; };
% |, i% P. n6 R+ O( L y3 W m9 v
4 y/ p& J4 r1 \0 P9 y5 Z8 y8 n: M5 Q1 r- E
protected:
( L' a$ a( ]0 C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
$ d- x7 f2 J1 r void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
) g8 b+ D2 v+ j& _ void RemoveDevice(CComBSTR bsUDN);
+ p* ~9 f, _4 Q' B# `* z8 b bool OnSearchComplete();7 @: \7 a/ T8 q2 E; k
void Init();" |9 N3 Y" ^' ` x
2 V# Y) U- Y- a2 B+ b: a; y7 Q6 S, f5 {+ d0 }* ?
inline bool IsAsyncFindRunning() c; Z/ o+ z5 p
{) R2 Z2 ?0 K2 U0 d( I4 |
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); ^7 ?1 o2 }# h8 L" R
{
8 t" V, k. ] i' P$ h h( t m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- F6 a I/ y* a% H$ E
m_bAsyncFindRunning = false;
+ }* s0 }9 \. U }2 }6 V6 ?% T1 r8 \9 {
MSG msg;
! Z7 o7 c) h, A8 c T while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
1 g) V1 o4 o# v, ~% ~4 U" u) ] {% L! j# P8 c6 m ?+ p, p1 }& _
TranslateMessage( &msg );
5 w, f, ]7 x% u, X8 H7 m DispatchMessage( &msg );
" ~5 I3 R# C1 \! H$ _ }
, y! n0 `( e& ?$ {( {& r return m_bAsyncFindRunning;% D6 m/ \% X- M
}& \+ C1 Q8 v/ t7 b* q- d
0 g: ]5 q: ] ~2 |9 w: j; w
- z! O' ?, J7 u0 j- n) z8 g% Y# ?$ |/ D TRISTATE m_bUPnPDeviceConnected;
( u/ k, x, h Q d) j7 ^, l. W4 T4 ?( d' j: O' V
7 S1 _. h0 C1 U$ z& M, a- p" [// Implementation
% e+ ? d7 L, \6 K // API functions5 T; O+ {' L8 [- ~, C' h6 I
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
1 E. M( n! F- w6 Y% X F( v SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- e( x5 Y) Y' f0 _ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);" w0 C% Z/ M+ \; K
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 J, D( l5 m& g: `. z
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
% N7 g9 P8 ?- J4 Y BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' @8 D: u4 C& d/ b1 M4 V( z
8 J5 h4 M$ |( u4 x5 q
% i7 j. V0 x0 Z4 u6 h TGetBestInterface m_pfGetBestInterface;9 o* [( t0 m. b- r* O. O3 Y
TGetIpAddrTable m_pfGetIpAddrTable;
# E( T0 U3 } j6 {5 b9 y TGetIfEntry m_pfGetIfEntry;
3 z+ T) J$ s* X* @" s, f
7 P; s% X& o/ f
' o0 S1 {$ P; {5 z! F static FinderPointer CreateFinderInstance();
6 x6 O2 d. T! H) V" d: k5 n* b+ B struct FindDevice : std::unary_function< DevicePointer, bool >
4 U8 Z+ b, k9 E& @& x( T3 k {
) |+ R+ X& D0 R- [2 P0 E FindDevice(const CComBSTR& udn) : m_udn( udn ) {}# P# W% a2 e$ r: @# a K
result_type operator()(argument_type device) const
1 u+ j5 p% e2 d! j5 O1 A$ C8 ? {
3 s$ Z& n6 C; H, ^4 J4 f+ J CComBSTR deviceName; y* G! N# R; a) i: c
HRESULT hr = device->get_UniqueDeviceName( &deviceName );+ ?* z; C' z1 r: ?
. y5 g0 y6 o) \" D) B4 S0 K
- E$ E& T, Y$ Z+ ?* |$ d p7 H# l& S6 U if ( FAILED( hr ) )
+ C' Q- C+ |$ g+ I, V return UPnPMessage( hr ), false;1 T ^' E3 ~& ^4 n9 H
( g3 a ]$ k; c2 A0 G
: L: D/ f0 Q6 I
return wcscmp( deviceName.m_str, m_udn ) == 0;# v+ \1 o, V! R! h
}
0 H& S* k# m! g$ B# V: |1 z( _ CComBSTR m_udn;8 A3 Q4 T! |" P. R
};: {& J. F8 ]- f; y* c# \
2 L+ s' D- ^; Q0 N0 x$ S
void ProcessAsyncFind(CComBSTR bsSearchType);
4 e. B4 o& ~2 s$ Y HRESULT GetDeviceServices(DevicePointer pDevice);
3 z6 i# S/ ~' _3 j, y* \9 Q void StartPortMapping();* k: _9 J4 B3 O) F2 q9 F, |
HRESULT MapPort(const ServicePointer& service);# W d, |: h% S z( c
void DeleteExistingPortMappings(ServicePointer pService);3 A* B9 f/ x5 J+ E
void CreatePortMappings(ServicePointer pService);* M/ b& t8 e( [% y. U/ I* S% G
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);/ t! v% W+ l5 Q' k; E
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
$ h: m: u6 R) i6 {; Y LPCTSTR pszInArgString, CString& strResult);* s) c0 t0 h ?9 M
void StopUPnPService(); e' d! H. G4 ] J' D3 I; Y% h
; N( x5 O4 B7 p2 V+ R H/ ~- s3 C R
// Utility functions& K/ O* P% p9 M" q% R7 v
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
) e$ D# ?( l. y- j5 v$ \9 \* @8 @ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);" G9 {" `7 R& d7 {8 ~
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 d% s( q9 g' J2 Q. h1 q void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
$ B S N: o) K HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ D+ @# j- z9 R7 u2 h8 n/ k; k HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 c8 i2 [9 m1 h. r CString GetLocalRoutableIP(ServicePointer pService);, b& ~1 v* Y; X7 _7 @
( O. K* x0 G3 K1 b2 V* ]
; t6 a) M4 q' w, l: ~
// Private members
# Y! B/ j2 V0 n* z9 m) [' oprivate:' L' s8 A a" }9 ^4 a% ^7 k+ z
DWORD m_tLastEvent; // When the last event was received?. p' X; _" C6 S: \, ]
std::vector< DevicePointer > m_pDevices;" m* n" C5 A% |$ B/ V6 }
std::vector< ServicePointer > m_pServices;( o, `2 A( D% l; D9 D% @6 B- }
FinderPointer m_pDeviceFinder;
: x0 M) }8 ?4 O C' T5 \0 W2 m DeviceFinderCallback m_pDeviceFinderCallback;
, u1 P) O. i% V* t( v8 K ServiceCallback m_pServiceCallback;
1 c! Z! R6 k+ G. D! q+ o
5 ^6 h8 s( g6 ~- e3 n
4 i, z" W4 C0 d2 T$ \9 L( g LONG m_nAsyncFindHandle;4 X# U: d0 {" D8 u+ k: s( K! ^
bool m_bCOM;
( t& L( W3 C/ \4 Q, W" i) x5 h9 m bool m_bPortIsFree;" e) G/ y: C. ~5 C* }! ]
CString m_sLocalIP;) J0 u0 g+ s& A
CString m_sExternalIP;
, D! P' C' Z4 W0 E" h a: { bool m_bADSL; // Is the device ADSL?
; q" O( f2 F1 x, c! |& d& E bool m_ADSLFailed; // Did port mapping failed for the ADSL device?( p6 C+ {! z ?' Y1 M+ }
bool m_bInited;
5 |2 \+ {8 A7 N: D. G bool m_bAsyncFindRunning;. v7 P4 d3 V9 h- ?" ~+ }
HMODULE m_hADVAPI32_DLL;
! a; j0 S5 u: c HMODULE m_hIPHLPAPI_DLL;
U' j& j7 S5 g+ F4 N' z ^ bool m_bSecondTry;
+ ^, O8 S p k7 i8 x- @0 j bool m_bServiceStartedByEmule;7 J8 G! i2 w8 l* W: Y4 n6 a
bool m_bDisableWANIPSetup;
; ^% N7 u+ C1 K9 r- a) y X bool m_bDisableWANPPPSetup;: i9 O% K W" y, m, p$ a+ F
! S% u5 J: o1 ]4 ~/ n) D: Z
& k) [4 F' M% K
};4 Y2 h; V3 v3 V
, `8 b! p) }: n2 g2 }% |$ S5 G% |, [* F% b7 H$ s R+ B
// DeviceFinder Callback
1 n9 O t& i! xclass CDeviceFinderCallback+ k; c9 K6 @% \! y# E$ l
: public IUPnPDeviceFinderCallback# V. D; f8 h9 ?
{' D2 m/ f4 c8 o7 p6 z
public:! F1 _2 H. a3 P4 J6 X/ v4 k
CDeviceFinderCallback(CUPnPImplWinServ& instance)6 j* O* B }! i ~6 ~3 x4 V
: m_instance( instance )
. ~7 i" k0 Z6 Q; f) J { m_lRefCount = 0; }7 e+ X/ a! l4 J, b
, X( \6 L6 f# U4 D( U: Q. B5 r3 V6 \
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- ~! z4 B- ^0 L STDMETHODIMP_(ULONG) AddRef();' z4 R {0 G9 g3 @2 V a
STDMETHODIMP_(ULONG) Release();
8 G3 Z8 W+ @) @/ t; c8 `5 ]1 k5 H) Z& z' N+ h
$ R* H! `6 J4 i& h! N
// implementation
- P6 R2 S2 V$ M& \private:+ o) B8 p, d/ p" v/ l$ [: \. x) ~6 N7 p
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);! P/ M6 }) k; ^5 O* r
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); F: H7 m o! V* k3 P
HRESULT __stdcall SearchComplete(LONG nFindData);' c7 ~: r: e4 V! i5 B% O( W' O* E! K+ T
' E* N7 d/ @$ R5 U1 ~, {6 S: \
private:
* x* @+ E7 G) I# W0 j5 l! I CUPnPImplWinServ& m_instance;
7 }1 h, A- [8 _- N: R LONG m_lRefCount;9 d3 i( S! K4 H0 ^! f) ~
};4 Y: B5 |- A4 E4 V* o
& e* j. n( C# c
, [+ }$ Q3 }3 \6 @2 u/ a. W// Service Callback 5 F( N+ u* }7 L9 I
class CServiceCallback% H% i- p2 i5 ~
: public IUPnPServiceCallback& s0 C8 t; {/ ^. M
{) C: E& P/ v) R+ J
public:
5 f9 o5 b0 [" ?* ?% } w CServiceCallback(CUPnPImplWinServ& instance)4 V) H3 j1 ]1 r5 s' y
: m_instance( instance )! y3 S2 g G+ Z3 Y$ }/ e2 F
{ m_lRefCount = 0; }' g; b/ \% I- Q
* K# z* k [2 p* X. s
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 n% `% R, |/ d2 V7 ~3 G STDMETHODIMP_(ULONG) AddRef();- F5 L8 g- `# n; G8 h
STDMETHODIMP_(ULONG) Release();
' X" t) K$ r: S. Z g! ~
6 D$ \ q: t- ?1 ^( n
: U# R. i( D% H2 [( L// implementation7 v- G8 s* G# C1 ]3 F2 u) z
private:
" f* K1 {; b2 _; P4 l HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 `0 d: I, L, ^! y7 G HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);, f/ T( w* i# j" x# o3 Y! H7 n! ~
" m2 c4 G ^- s& t/ ^8 `
9 x, l; u% d8 K7 V0 g4 Dprivate:8 m0 A A3 i, R8 i; [) Z- Z
CUPnPImplWinServ& m_instance;3 q' z8 L/ T4 T% a
LONG m_lRefCount;" \6 `) E# F1 x2 n, g% N r
};
6 E1 \: c5 ~8 u8 x7 C# @6 `$ b0 k1 T3 ?, K* X, o: C c
" x+ S( D0 v: a1 }/////////////////////////////////////////////////
9 L, s# k7 @" I2 T* x, p9 u: w( Q! n, Y! N) r" i$ U# K9 E
3 ]" V3 r6 X! @% p w( U使用时只需要使用抽象类的接口。
" p- h8 r3 z) F2 J) f: ~" s0 f/ ICUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
/ \5 a% v0 D7 ACUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.. \5 E8 k4 V& I3 t! f! M- E% p
CUPnPImpl::StopAsyncFind停止设备查找.
! H; v2 D5 R( I( fCUPnPImpl::DeletePorts删除端口映射. |
|