|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 l$ \9 Y8 V3 b ~4 s8 }
$ }$ V; Y4 {0 j6 {( ~+ w5 n
" e9 E* D% \( k; \///////////////////////////////////////////- B% b! G% @$ J( j6 {
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- j' R8 z# b+ @2 d
- u1 }( u8 q! B/ D% u* z' s3 i+ l q8 \& v/ K8 e4 _% f6 u1 F' G
#pragma once
! V5 `5 u0 r" v#include <exception>4 }# N5 k- C; h2 G6 U( @/ `" w! m
. a- D8 X0 Z- Y2 [6 N% F. O$ H4 c1 I$ }2 I$ w; y% k0 r* ? g
enum TRISTATE{
5 v8 }# }- p# M5 Q, ` TRIS_FALSE,. @: P1 D& f" X: [: h) R- a
TRIS_UNKNOWN," Y# v$ I( X" |8 F
TRIS_TRUE% Z" ?; U! x U- A1 _
};
' C& ~# T f2 `' z) M Q; X' S0 u. \5 ~+ i i; T8 T, O3 X( X$ J# \
7 L1 C/ H. J) I8 q" z. V) `5 k2 \) `enum UPNP_IMPLEMENTATION{
! |3 U4 m6 Y: L: ?# J2 O UPNP_IMPL_WINDOWSERVICE = 0,
7 d7 @( @+ m5 G2 P UPNP_IMPL_MINIUPNPLIB,% R8 m# o" G' K; h( J) E
UPNP_IMPL_NONE /*last*/
$ W e3 \, _3 D8 q8 W" W};
8 P4 ^. P: _2 e g
9 c1 q5 G( I& k& |7 L7 c1 y5 v* o2 z* h j9 ~) q
8 G1 Q4 F+ O/ J$ A8 A
& s; [. S, p* n7 wclass CUPnPImpl4 A+ H D {& }0 f, f+ q
{' k3 v K' [" u: c8 t
public:7 p! A4 J7 p" ?9 O
CUPnPImpl();8 U9 \: v4 L7 r* ^! M- a
virtual ~CUPnPImpl();, D4 v9 E- P; ?7 k
struct UPnPError : std::exception {};
. j3 e" P! U+ h: i% g Q8 m# f1 X8 w enum {) s/ V/ K+ J5 h5 c: R$ l3 ^
UPNP_OK,& I: y `# ` p8 o! M9 g6 {- U
UPNP_FAILED,
% ?4 o( a4 B% g1 S% V UPNP_TIMEOUT
9 R& g8 g. d. D) O- C7 r };
& D6 e, R. y X% {! f$ ^, O* i. d$ Q& M" \- _/ U) o% F
+ Q5 x8 {" S, K( W; l b5 F: B virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;0 t; x, K1 b. v; W: W5 S- V Y
virtual bool CheckAndRefresh() = 0;/ X: j; X2 |3 B) D( h8 K
virtual void StopAsyncFind() = 0;6 M" C0 X+ Q3 J9 J# J( J; G/ d- b7 ~
virtual void DeletePorts() = 0;5 L C* w7 _2 r
virtual bool IsReady() = 0;
7 @$ n' c$ j/ U3 F. S" a2 P4 K F virtual int GetImplementationID() = 0;
" J) i! H) q4 T% ^9 ?0 W $ N# m" m* e8 H8 ~" U& l8 G1 }5 U
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
$ f, U3 D+ f1 ~2 b! k& z2 \& T- Q8 Y4 w
/ R' G$ D& N' h; F0 l7 Q void SetMessageOnResult(HWND hWindow, UINT nMessageID);/ N5 w! a; E/ X" {$ B6 F, S
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ p, h& W+ T8 {1 U
uint16 GetUsedTCPPort() { return m_nTCPPort; }* S% V ` |: o
uint16 GetUsedUDPPort() { return m_nUDPPort; }
5 K. @4 s8 z% ~& m
+ G3 `6 b- t2 ?, Q5 v" U- a( k4 y3 y$ P4 s$ B# B0 [
// Implementation
: v' C% M! k" S9 a: \" Q, kprotected:5 e$ H; m$ ]# Y1 \6 |/ Q
volatile TRISTATE m_bUPnPPortsForwarded;
7 V- n% T; q# J6 a& A% Q. I6 ] void SendResultMessage();
! ^3 }* p+ t5 R8 @- g5 s uint16 m_nUDPPort;
1 ~3 r. k4 E$ P' P/ p' Z uint16 m_nTCPPort;
% [' ?3 K5 H. P) }2 ~ uint16 m_nTCPWebPort;4 L+ [$ T3 l2 X% i" p- |! n
bool m_bCheckAndRefresh;
1 E9 N6 [8 s1 ]/ S/ @2 B+ @5 x
3 e+ W3 j1 g v! i. u) z
( H8 |5 k+ e, H" H4 k$ \private:% F N( E6 j* x1 {% U
HWND m_hResultMessageWindow;) E# e, Q' u" h6 j) h3 A1 O, ^
UINT m_nResultMessageID;( y, L! Y* C# \5 r7 X( e
* L' {( f4 H1 p$ y+ ]6 N5 u; N
# J+ I* H8 Y ?};( z h# C" n7 v" l" E Y. Y/ O( K
8 Y; c; [- T4 O/ S
9 D# @( f: p. Z8 J# u& V! u// Dummy Implementation to be used when no other implementation is available; u$ j0 {! @6 d
class CUPnPImplNone: public CUPnPImpl
d* r8 C5 n, N- h% ?: m Q- A5 ^{
# J7 o" u( r+ dpublic:
# [) u, |& o- S, [: A4 R4 T3 o/ u virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }3 {7 X4 z B2 i
virtual bool CheckAndRefresh() { return false; }0 u' X5 |; H* n* O6 V
virtual void StopAsyncFind() { }
6 N2 s% t: r7 H1 ^& s% P virtual void DeletePorts() { }! N y4 L/ b4 K; D: ?
virtual bool IsReady() { return false; }6 C0 \: q0 O) |" @# G7 v3 c6 T& f
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 w2 S, l) q% @/ s/ L6 [* ` [};
( _, c( O/ {4 h. `7 }
- `+ W1 R( W' b/ f5 h% v* u8 f; G# s% Q% |7 _( n& y' S
/////////////////////////////////////
J0 T2 t2 ]. k2 Y, U& ^4 S8 v//下面是使用windows操作系统自带的UPNP功能的子类6 W. ^ f' V9 F: j' ~
$ t' h: P$ H& z* G. t6 o/ p
/ _$ L9 {1 d9 T3 L* l& g
#pragma once( `" H3 R# i7 E
#pragma warning( disable: 4355 )/ x* g+ r% N5 |8 n
( `; T# m1 W# d& M7 q: U7 f2 J# l9 S2 k' L' a* {
#include "UPnPImpl.h"
1 {+ E) W2 G/ H* t T6 m#include <upnp.h>
- ~: H, \& |/ C/ F3 p3 W. ]8 v#include <iphlpapi.h>& B' i8 F o+ n, }5 f4 u$ O
#include <comdef.h>
: ^" e' }4 M" C$ z. V; U#include <winsvc.h>
# C, a& q. V2 o- N( g& O* U3 b5 i. o* z0 a) S- y
`6 A) h: J, x( l9 o: I* l
#include <vector>
8 q& L) F( L; r: ?! d6 ?0 U" i#include <exception>" r) C) [3 b# u; t9 l9 V
#include <functional>* K8 a) w' O$ r
- \( \% A! p3 H, P0 i" j. J& Y0 o. W1 I( P4 g6 m" i! g7 y/ c
3 o& [) ~; c' d6 V* s2 h9 H$ P- o
) U4 r: ]5 u$ A8 }) Z! l. ~
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
) M- C; u- C! `9 X- Etypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;7 a2 R. g) [" D7 v! s9 X) O
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
+ {# J6 a! t+ X' Gtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;' b: ~1 j7 Y: d* s
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
7 ~/ @: E: G( v# N3 ytypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
- X7 A4 m' o8 M. o* Qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
/ V! E! f8 ?' X( d! `7 c( r% r$ ?( I' X6 ]1 `# F# n& i
5 Q3 D9 d) e# [: _# K
typedef DWORD (WINAPI* TGetBestInterface) (
D# t0 N9 h* s9 L5 w' ]0 O2 t IPAddr dwDestAddr,
0 q& ?2 q. k0 o+ _& ^/ D PDWORD pdwBestIfIndex
! U, D0 A6 \+ w, W+ ?( P);
5 \$ A$ f3 F- a- L
1 w N3 D! N! @. {6 V% M+ u/ h0 }( }5 b5 \" M) Q
typedef DWORD (WINAPI* TGetIpAddrTable) (
; D( |# z7 p% N7 _. ~4 s% Z2 f PMIB_IPADDRTABLE pIpAddrTable,
$ v, ^ g+ b" a8 D4 _ PULONG pdwSize,$ D: j. |/ ^' A- S, U
BOOL bOrder% M5 ] e* u- p( ~7 `9 t) C2 W, _
);
( a! y* Q2 a8 V f: g2 S
5 R$ j- r9 O z; A+ p
) n- x3 h4 c( W3 ^8 Atypedef DWORD (WINAPI* TGetIfEntry) (
( _1 i) m! B3 F2 d PMIB_IFROW pIfRow
7 e9 I, F2 o7 P6 }4 |- M);
9 ?3 X0 @( Z( O8 `
- }2 m! R# ?" }2 ?$ I- N( p" K
! G$ H, V: N* |0 RCString translateUPnPResult(HRESULT hr);
* V1 P" z0 `& g% L, K5 D2 a4 a1 pHRESULT UPnPMessage(HRESULT hr);
7 L( |+ W# a, M" y& h* R& C( s9 d, a4 {
8 w7 X$ T$ G: k7 c+ l, R& U% _class CUPnPImplWinServ: public CUPnPImpl6 c: m, T/ d& [0 ]+ U1 i/ I
{
" }% p" u# i2 C7 P1 J5 e. @ friend class CDeviceFinderCallback;
9 j5 n$ X" ?9 {9 a ~+ p friend class CServiceCallback;
% Y4 d8 K/ ~" g( o: `! f- J. l8 m7 A// Construction$ a# o; r5 y& _( p* Y& N0 g! C0 K
public:
" r" e% N! l- n( _7 G$ j% n) B virtual ~CUPnPImplWinServ();4 X1 y; ^. q/ W# z
CUPnPImplWinServ();% Y" _( \' [4 ^; I; M5 S
( A' |6 K2 U/ n5 f- f. q1 ~, b$ n" G4 Z+ {+ m' G: K8 _* u+ o
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }+ g4 F; c$ a& P! u: N
virtual void StopAsyncFind();
l3 q- B! z& P& m. D virtual void DeletePorts();
( m: g" c# i' w& L2 k5 T- ]' V virtual bool IsReady();
+ P& S. E! I$ w) x1 X* l5 Y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }# `* X! i0 k5 b
' q8 p0 J; i1 `! Q- I2 V' o1 {) k* F, h5 p( t* d) J6 t J
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)2 P5 m' b1 Z, C7 n, Z
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later2 c2 p6 _7 _# ?. |
virtual bool CheckAndRefresh() { return false; };" K J3 Z) U9 A0 U
1 v: E3 G! m+ Y; l
* @- @! m8 l) L0 p7 {protected:% W8 U( T0 Y. Y0 I( D$ |
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);+ v5 _9 q" Q# d
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
, `2 v9 G0 T6 t( H7 x void RemoveDevice(CComBSTR bsUDN);2 N: ]) }% _5 U( f% L; t0 U
bool OnSearchComplete();2 w* ?# M1 J, v2 i, {
void Init();- b7 T2 U% g% F8 Z5 B
" G$ I, ^# Y2 B
2 j& M5 R4 }1 a" |. x: J+ | inline bool IsAsyncFindRunning() & a& B. [ q& U9 |5 n1 _
{, J/ p- n+ l% L, ^9 |8 T
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
B u# d2 d) A! a {
) x: I9 z3 q0 b1 S# w8 X; C m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- r' W& x, ^1 k L4 K+ E m_bAsyncFindRunning = false;
9 E+ }$ u" x+ a* ~8 Q0 _0 D( X8 @ }
* {% D W* H9 _4 e( C+ A4 x; N2 z MSG msg;- d0 y# {- x" u. f
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )* c- X4 z* Q: D5 d8 |5 `
{
: v, ]3 d# T% P: `* i. _ TranslateMessage( &msg );3 k9 C& o, U1 Q1 ]! B0 x7 |6 p m
DispatchMessage( &msg );
" ^, z* `3 S+ a0 t1 _/ y! V }
# t1 G' o, P& s, m, M- j8 |" i2 \ return m_bAsyncFindRunning;- P; s0 B- V6 M) ~
}; V0 ]6 j9 I. I
+ ~; O( ? Q$ \3 D5 ~0 j2 ?1 y
2 z3 O: C$ I; k3 I/ y TRISTATE m_bUPnPDeviceConnected;' u) {' C3 S. Z: w: ~; p
9 [' l; n5 f2 k( C% y& g, w' D
" r" z1 l& S- a% R! } v
// Implementation! p( u& S& l2 s; I
// API functions% Q" [0 O8 S. ~3 P
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);& c4 Y: r% g6 v3 ?# D
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
+ q+ ~# r8 z! f/ b/ L BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 Z a# ^1 y5 ]% w0 |: N3 D9 G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
& E& D- W+ b1 x; x" f& | H5 k BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
. y0 [2 x& c! v4 b' Z BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
- s; h9 j) l6 d6 F% N# K
3 ^) `' r( k3 N! ], Y k& ^! `: U1 ^6 t
TGetBestInterface m_pfGetBestInterface;
+ A$ l( T, U* A TGetIpAddrTable m_pfGetIpAddrTable;
: p" `! }' ~8 ?( G TGetIfEntry m_pfGetIfEntry;
) \2 J% M8 r: C$ X" e8 Z, \# Q! n/ J# R* x
' [ f9 w! J* h5 T& d- F, V2 l
static FinderPointer CreateFinderInstance();
* f* b% ?2 w9 q- f1 Q struct FindDevice : std::unary_function< DevicePointer, bool >) o! r" g& L& w( a- s* V
{
$ m, v, e) O1 M2 v6 h FindDevice(const CComBSTR& udn) : m_udn( udn ) {}+ X4 V X" O9 Y9 V
result_type operator()(argument_type device) const3 G7 ~* R! ~0 Q9 I
{3 E# z' z5 f1 b7 w# \
CComBSTR deviceName;
? S: p+ T. `+ H! l8 ] HRESULT hr = device->get_UniqueDeviceName( &deviceName );* y3 E" F6 f5 t9 m. `
: M5 z0 j# t( b7 Y, E# Z3 {) ?
" w) _4 S7 m" t2 T) R if ( FAILED( hr ) )
9 z" |3 G! N: T! M5 P2 G8 n6 y return UPnPMessage( hr ), false;+ d3 `5 x0 D0 d4 u$ a
- A u" T( Q. D0 F4 D
+ @/ \' j& P: Q1 W& P6 I return wcscmp( deviceName.m_str, m_udn ) == 0;
2 J9 Z, u1 t: L& ?7 c$ o }% \, m& r4 V" ]: Y$ u
CComBSTR m_udn;. _ c. h+ k$ T$ ^* B
};6 ?; @3 Q; e) m
G$ S2 z$ i7 i. }& a
void ProcessAsyncFind(CComBSTR bsSearchType);5 m2 r, V2 q. A l2 H6 ~
HRESULT GetDeviceServices(DevicePointer pDevice);) X# k" ?: I& h
void StartPortMapping();
+ o4 m# T: v: N* `& F HRESULT MapPort(const ServicePointer& service); j9 I; h! {0 I0 g5 u) i
void DeleteExistingPortMappings(ServicePointer pService);
. Q2 V; t! p5 `+ m! [ void CreatePortMappings(ServicePointer pService);6 M; ^& t* {+ F+ V
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
/ t. J5 u" x; ^5 d( l HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, v3 r# _7 f, Z7 D8 a% R$ C/ d' D LPCTSTR pszInArgString, CString& strResult);* J% o; X; d8 a
void StopUPnPService();4 ^( ?3 a; F. ?# U' D
3 ]( _% [( h' |& G# [
/ A/ f6 b4 W. w
// Utility functions
! N* d/ \: ~; F7 j% r5 n4 C: i' G: H HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ b, G: e# i, B8 b# k7 X INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);( i4 ]; D1 H# r! U& N& j# i
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
( O7 h1 J r/ @! m: T6 R, w void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' q) ~2 l5 x3 J H) W* y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);" }6 k! o; r" s. f8 P. ~
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 q6 r- @" c& n2 @! s0 Y3 \: V
CString GetLocalRoutableIP(ServicePointer pService);
4 ?5 t3 h8 Z2 n; q2 R* d- z
! d% M( e3 v7 s# p2 V9 P5 x6 s. o2 W) h( H$ J
// Private members
# U. ]. `* c3 W T4 v; _6 g" ~private:& \' B$ U' [* `6 G5 l5 N
DWORD m_tLastEvent; // When the last event was received?
% g1 p# j1 ~. o5 ~2 m. T, h: m* r std::vector< DevicePointer > m_pDevices;2 Y, d! ^/ K5 I; r2 C( F
std::vector< ServicePointer > m_pServices;! I0 ^1 j+ x2 B% h+ t7 x) y! \
FinderPointer m_pDeviceFinder;1 O" {! N+ O$ e1 ]% k
DeviceFinderCallback m_pDeviceFinderCallback;0 | ]1 p$ j2 A, F* {' q/ h1 O1 ]
ServiceCallback m_pServiceCallback;$ [. O. N% t$ x
* h- |+ f( f3 a+ u J/ [
+ p3 G$ u+ q1 T) m3 Z LONG m_nAsyncFindHandle;
9 g) b. y' `$ n( r+ P. Q% V6 p bool m_bCOM;0 B) b$ Z4 D" _$ m" L
bool m_bPortIsFree;6 N7 b+ ]6 s9 d9 p; c
CString m_sLocalIP;
7 Q6 T6 S2 ^% e, t! _ CString m_sExternalIP;
. t7 f% Q; f# v) J) I bool m_bADSL; // Is the device ADSL?) h" n5 k6 S8 \ i& c
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?+ i2 `4 ]* C1 J, a# o$ y
bool m_bInited;4 n- d/ K4 e( n1 x h6 c
bool m_bAsyncFindRunning;2 U' c/ M0 q) ` h+ T
HMODULE m_hADVAPI32_DLL;/ C E/ u# y: V( K1 s8 f
HMODULE m_hIPHLPAPI_DLL;
7 _9 b6 C) p* s# L bool m_bSecondTry;
1 r! X% n1 ?! B- I5 j. Q7 U: ` bool m_bServiceStartedByEmule;
' o& Y, `. r9 a2 ] bool m_bDisableWANIPSetup;
& h/ q6 _4 T3 Q; ]. ~ bool m_bDisableWANPPPSetup;( j2 p0 q5 j! j$ `3 K, z! c
& w; \& Q3 x1 G6 r' b% N
4 f4 H' r3 y6 a};( K2 j* X+ M7 _7 N6 R( u
7 K7 z7 f/ [- y7 U* H! k( F$ @* j/ ^
- }7 J" m2 l5 Q) Z: N5 g) d% U// DeviceFinder Callback
( M, _/ s$ |4 a" F# _8 qclass CDeviceFinderCallback
0 G( O3 l2 K4 Z( J. L : public IUPnPDeviceFinderCallback: u; r3 L+ Z1 b" \
{
# j3 H: N. N: rpublic:
7 u" A5 V% `! b( ~0 P6 t* W/ X CDeviceFinderCallback(CUPnPImplWinServ& instance)
9 R/ Z w. H; h+ b- l8 J : m_instance( instance )& j9 B; _0 z) [2 c) f
{ m_lRefCount = 0; }
2 l o/ D6 `! h9 I" {0 A! `3 k1 v! u, B' X6 F2 a& a9 z' u
! T. ~, z2 T U2 G STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 N$ X$ z7 p& H
STDMETHODIMP_(ULONG) AddRef();8 ] N2 v! B: u" X' I
STDMETHODIMP_(ULONG) Release();
8 w x/ V; N0 M7 y9 ?6 W8 O
7 b) n! h3 L$ r' q+ H1 U6 ^
k' v: u: Q. [; u// implementation& I& i! v+ V0 d+ |- j: L, P
private:" E0 ]" X; A7 |
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);3 A g8 I% @" x; v2 C) C% s3 r: U
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, H/ z* f+ l7 B% ~; K3 E
HRESULT __stdcall SearchComplete(LONG nFindData);
1 L% J7 Y+ L1 D8 ]+ D" T
3 k% }5 o" \$ ^# l
" e% t6 Q- v- s+ D6 i/ m( rprivate:
- y$ a4 j& h- u1 n% z4 |- T CUPnPImplWinServ& m_instance;, E. u- [ d6 p5 m
LONG m_lRefCount;8 n5 \4 q: `0 d Z! d* D* u2 {
};
$ N& C" N* J) l6 Z6 {# j( U+ ?; e9 G
0 ]+ z3 v6 J9 [$ T. M6 T// Service Callback : o2 r$ S/ W5 f& H+ o
class CServiceCallback) ]1 ?4 ^! A! g' {7 I4 y# e! S5 y
: public IUPnPServiceCallback
1 c9 S/ T- |' j* {$ I9 p{
$ i/ D1 L( G) ipublic:( T3 y* [3 o- [+ o4 ?
CServiceCallback(CUPnPImplWinServ& instance)* e+ L; y7 Z: |! L7 d
: m_instance( instance )& |& y+ I3 y% C" p, m8 V* z, y ~
{ m_lRefCount = 0; }# m$ z" [+ E; P5 e
! S- p9 m5 W4 q, Q6 ^( f3 @ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 f: m; C: M& @. [3 b6 h STDMETHODIMP_(ULONG) AddRef();
8 B+ _0 u; a4 [2 } STDMETHODIMP_(ULONG) Release();% b& B7 Y3 s& N2 t! H8 k: y) i
( f6 P$ z; y- {5 F8 N2 |
1 k+ K& c) S8 z# k// implementation Y& t8 i2 M* Y+ }4 f- g
private:9 W) m$ u+ O1 n. g( Q+ O) B8 B
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 I- G$ T2 }8 S' F; B1 e( O
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
3 ~* y( d( i* i3 a- V$ ~
2 v+ X* T& P$ Y6 [9 c! D* ]
1 l* V m9 W. U9 S5 V: pprivate:3 g1 T* S3 k4 q
CUPnPImplWinServ& m_instance;
) y! Q1 S. r! l8 w( @' ^% b LONG m_lRefCount;' W$ r- C: z5 d7 b' N2 ?* d% E
};1 j, ~4 I8 p/ h6 a, Q1 {
5 O/ k9 \6 _4 F& t I4 y" t
2 d* H9 K9 f) K
/////////////////////////////////////////////////5 H- j& B3 c8 n" _9 S% P3 y1 K
+ \4 U4 @+ ^+ ^/ r# o/ \! i! @8 z3 h/ ^, g; X5 N+ U: }
使用时只需要使用抽象类的接口。
; b/ i2 j) o$ V( d* e" FCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.2 l( V) T0 R; ^3 j2 [" D
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.9 G6 J4 n3 X3 Y/ Z/ g* O) A
CUPnPImpl::StopAsyncFind停止设备查找.0 d# }' K) H( y: l
CUPnPImpl::DeletePorts删除端口映射. |
|