|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' Y0 V& ^0 ~5 U( Y! J
5 R8 {5 L+ Y, P/ m
- h, }5 o7 |) @* p+ G, K5 t///////////////////////////////////////////9 u' u! A. l- V
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
/ N1 @! G* \5 D& T% ]2 r2 a
" ~8 O8 O6 G' y7 O; y2 S
: t! s. g+ p8 m' N+ C: D2 L% ^#pragma once' `" y+ E! z' J" B$ L
#include <exception>' g* F! m; T, T8 n& t
* Z) F& X) G) U
' X8 {5 n) W3 p0 z+ e/ r( Q) b7 |
enum TRISTATE{8 [7 a. q# U# _6 L9 u( W
TRIS_FALSE,
* v+ x) x) n* u; Q& b. g' B6 T TRIS_UNKNOWN,
( }: E- R9 ]. L8 ?9 E1 t TRIS_TRUE* c' e+ Z! o# P
};, M8 c7 V' J* R% K4 u& Z
/ q) Q6 R/ P( m. w2 R. }0 d" V/ Y* B; Q( Z
enum UPNP_IMPLEMENTATION{
2 f* s. ]# c! b; H! G$ J) b! L UPNP_IMPL_WINDOWSERVICE = 0,) N2 K0 w7 C6 i8 F1 B$ D
UPNP_IMPL_MINIUPNPLIB,
& l0 F: {2 {$ z8 H4 z& o UPNP_IMPL_NONE /*last*/9 | ?( t, ^* ?3 ]2 k# p! G9 f
};* ^3 O7 j5 B! I7 ~$ S0 W1 P
. U8 b C- O7 \; y/ P6 a3 H
( N- G- D' R$ |7 z) a y$ S7 F- B' a/ r, s
/ i( X7 v7 _0 u: q ]6 m; [8 s
class CUPnPImpl
7 F, N1 Q, i( w8 P/ `6 P) B{
, }, D% h( a. ?. C1 N5 M$ r Kpublic:! m J# t7 ?# ^% e7 J G8 x
CUPnPImpl();5 @8 D1 R+ k* ~6 { C' s$ n
virtual ~CUPnPImpl();4 m! D/ I& q) _$ P+ W: L
struct UPnPError : std::exception {};
0 G4 X: V, P$ \% C2 V enum {! V2 _1 F* C% J
UPNP_OK,
# ^: C2 ?% x P4 |8 {* r UPNP_FAILED,
$ Z7 j1 ?$ K$ T5 Q: N5 ~0 L UPNP_TIMEOUT
2 i7 ~/ F' V& B) @ }; o" w; {- O# V5 L( E' r2 J% b/ t2 J
: x4 z$ l. H# A7 ~! ~" b; ~" X w& Q
2 Y1 X$ r0 J. }& g virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
$ q- c& i. \. V# @% r6 f% h virtual bool CheckAndRefresh() = 0;1 B7 {7 H9 ^) X/ b7 s/ D! }
virtual void StopAsyncFind() = 0;
, [% k% h& i$ L/ f& n- {* @5 c virtual void DeletePorts() = 0;
7 t; ?! c0 g3 [) Q3 ^ virtual bool IsReady() = 0;0 ?- K8 f3 }6 @- d' n; B
virtual int GetImplementationID() = 0;/ e! V; r' t% W% v: J! H) D$ F% E+ k
' m. l" b4 {6 ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
# N& Y# Z2 Z0 g3 x$ _2 T2 x1 l0 r8 J9 t# |5 @
* P: Y$ |% d7 x1 z9 u% j6 h4 _ void SetMessageOnResult(HWND hWindow, UINT nMessageID);# h' o: n1 G7 ~0 v8 h" Q. {. G
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
9 @: }; `( g. Y E- @! ]' D% m uint16 GetUsedTCPPort() { return m_nTCPPort; }
: u: O# s! |' b5 ]+ D1 T) x uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 e: D; s' M; p) e4 b" Y1 P" H* B$ x
7 \5 a( M* k9 {( B" e1 D// Implementation" W4 r$ y5 S, B: ]. X- T0 L. u
protected:
2 r7 x( X3 o4 T$ a9 V volatile TRISTATE m_bUPnPPortsForwarded;, Z7 g q, T8 L. Y+ J6 J
void SendResultMessage();. w2 b* X: N, v: ~' l
uint16 m_nUDPPort;
8 k4 J, s, n6 d s y- c# b5 g8 w! @ uint16 m_nTCPPort;1 S& `& L3 C- y" h( N8 G& L, Y
uint16 m_nTCPWebPort;
; G1 j5 F6 o; n9 j1 | I+ ~9 } bool m_bCheckAndRefresh;7 v( W0 e) D& U% C, A/ @
; H/ w$ g, `- d& e
6 y4 x$ M) Y$ N3 _/ v+ Q- c8 p
private:/ ^' P- j( `' e3 x4 o+ d
HWND m_hResultMessageWindow;
% P3 C3 R; @' D9 E5 m UINT m_nResultMessageID;
% ]4 K' S' L. O) X! k6 z
1 h' B& M9 Z i- ~$ |5 o. m
+ Z$ `* D( Z/ y" S3 I: @};9 n. q) `8 [* J/ u* a6 P, i- d2 ?0 k
$ J5 [+ v! V3 W; I6 `8 h; `0 F
/ x5 p8 F8 y9 b. G
// Dummy Implementation to be used when no other implementation is available) {1 v5 g- G: Z/ r7 u. o
class CUPnPImplNone: public CUPnPImpl# n m( Z C, w6 E6 y8 L8 v
{
" ]6 W( B; u! L$ e3 X% O3 N' _public:
' D! e. S* D" x9 ?* U2 f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); } M- ^8 Z$ u2 Y) B
virtual bool CheckAndRefresh() { return false; }3 D7 i: r1 L* y# H
virtual void StopAsyncFind() { }
4 w6 n; `8 F/ B/ n3 ~5 q virtual void DeletePorts() { }
+ @6 r9 p0 o! h# g% w8 {$ e virtual bool IsReady() { return false; }
' J4 l0 ` f( A3 e6 ~ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
. d; ?( J( [' k4 {5 J};
* @8 i4 A8 J" t! \- H% j9 W( M+ i$ O& Y$ m# e7 W) ?/ F0 F
! p0 K+ W) z8 k! n* O( T! w& _
/////////////////////////////////////
4 J+ J+ l2 V* j2 W' f& x//下面是使用windows操作系统自带的UPNP功能的子类
+ z3 b4 I4 e! i, q
& S9 ~# h. }; l* y, y8 d+ l) j' Y
0 Y/ B" r, m8 w- h) ^* B* n( }3 @#pragma once! y/ X5 B9 R- f) k$ A
#pragma warning( disable: 4355 )
& ^0 O6 p. U' q
' `5 X/ x U8 V
" r: g. w' m: d7 B8 L#include "UPnPImpl.h"* E; [9 P2 i, r0 J2 [6 A% T5 J" B2 s
#include <upnp.h>- n% y% i1 C6 g# o/ ]
#include <iphlpapi.h>
# b% G$ P0 d* H#include <comdef.h>
I/ b# Z, ?8 h( f' u#include <winsvc.h>
8 R. x/ a$ `. q" ?8 f* u; G5 h8 }& o# `( w- N! C% h/ U
, U4 G7 i1 @' \2 p$ ~5 j9 d#include <vector>
. X3 @+ C, U5 T$ |1 x#include <exception>" V0 A4 E$ Y: [: s U9 h3 X; u4 T) K
#include <functional># b, p: Z1 k4 j, P9 h6 }0 j1 }
2 f5 g* s4 P2 B4 I
2 i% ?7 X" }) E- l: H, P( W, K8 e, D* d% i8 j- x
- n) j+ b0 G1 C0 p' X( Gtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;: O& L( z9 I0 \8 [4 y" s
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;$ H8 d( r$ b+ R o: b( d$ g9 J' q- j
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" R( [. w. p2 V" ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;/ Q/ w$ a! `( W8 W4 A
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;- }. ~6 V- h: N# S4 E- e
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( f" B( d8 l' I* G5 F# rtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ J! m* X( ~1 @, S* H) }
1 g+ a# |+ L3 e: u
. t# V# f) H7 X% E
typedef DWORD (WINAPI* TGetBestInterface) (
6 H1 Y5 c' A" O* _: [4 y. A IPAddr dwDestAddr," n8 o6 E5 K" C4 W; ~+ j: K
PDWORD pdwBestIfIndex4 [# @6 l: z X, j3 E! E
);/ b! ]+ `% \1 j
" `! l' G" i& A. o" ]8 d
$ o% [8 U) C3 m+ I" ^typedef DWORD (WINAPI* TGetIpAddrTable) (+ M* J7 Y a) g: y7 R: P
PMIB_IPADDRTABLE pIpAddrTable,
. U$ Z$ B1 u7 Z, b6 T- u4 K PULONG pdwSize,8 c$ M+ I- h' V+ S( z9 g$ }
BOOL bOrder/ f' a) |0 E+ A5 R4 B
);* ~" V( p# ]2 I4 ^" v: @3 B6 U; {
3 ?3 f2 x2 ]' y5 L* T
' e7 h# E! T: F3 [1 L1 o" m0 D! Qtypedef DWORD (WINAPI* TGetIfEntry) (
$ Y( u, p8 Y. r1 ?# c% l* C9 U PMIB_IFROW pIfRow* I3 `& l! D5 c1 |
);
4 m& H$ `4 m0 l) ]% o* w" `; R, z9 _4 m# k1 u! B
% }+ @, T7 F: A: R" S# T# X: Y
CString translateUPnPResult(HRESULT hr);
0 ^6 E7 w5 K( @, H8 gHRESULT UPnPMessage(HRESULT hr);
' D B |( p' y, A% r6 v& r1 x3 l8 j. P9 J
# b, L: e# @% Y/ \, P, c/ S
class CUPnPImplWinServ: public CUPnPImpl
' p( [0 ~2 r3 W" v{, K' Y$ r5 e! J4 |: [$ n
friend class CDeviceFinderCallback;
: g3 A" i- H5 ^5 I- h friend class CServiceCallback;
% h k: y0 `" z( [: G1 F, ^8 \// Construction
6 a$ c3 {6 m9 U B% Z1 N: ~public:
7 w8 m+ T, [7 g. g% H virtual ~CUPnPImplWinServ();
+ K0 t- H' r$ b; A, `; `3 k. C9 q CUPnPImplWinServ();: g* V: V% |' m- \
2 V/ U& f7 I ^4 {' n4 H
2 j/ |) m, \8 p+ c0 D9 u virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }" v* N" k6 j5 J! a( f8 T8 x
virtual void StopAsyncFind();2 W# H) u* {' b7 @+ L m! H
virtual void DeletePorts();
2 M* \) d+ |3 j& h0 A8 ] virtual bool IsReady();7 @5 g* H- Z& Z$ w3 w
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; W! N! V+ K7 N
- i" p1 ]9 F% e* {8 C+ ]: ~6 u2 }0 o R6 y2 e* P4 t; _
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
; `* C1 H' K9 v // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
9 \" O, B+ h* l( [5 ?. O- I virtual bool CheckAndRefresh() { return false; };
5 ]: m" z; M# b# g3 Y; c( p3 K' o1 y8 @/ c7 S
1 k/ C" @, U4 W! V8 q- r# x
protected:% y" |& Q) S, F
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 U$ e( v) L* b# w( q void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
8 Q2 S, B' b' G5 v L7 k, J+ o void RemoveDevice(CComBSTR bsUDN);6 k" a$ l# v9 L t2 d
bool OnSearchComplete();
{1 n1 x7 A/ G' F1 `) c void Init();
) [* s% _* h6 j/ j+ N8 ]. }. Y5 ?
8 J$ \) H d/ w, O, j% b
; C: T; M3 r. G, D% V8 u' @7 U inline bool IsAsyncFindRunning() , f! T8 k7 Q6 \8 I5 Y! {/ T4 t
{
4 C& y: E0 H$ Z3 W; w if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )- G1 o( z# X0 }' w
{4 J1 I+ g ^" v
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
# a! [& o% X( Q3 q1 g m_bAsyncFindRunning = false;6 K* i0 ] r- [) h5 t( P/ [+ l! |
}/ d6 d; D* B# s: Z- d& k
MSG msg;& q! G& j' B8 C2 `5 b+ G
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )# l7 h: l) p! t: O3 x
{
# @' [/ T; F/ a TranslateMessage( &msg );# _6 f$ d7 f3 h9 K" |" M
DispatchMessage( &msg );
9 ?0 w( Z5 |* [ }( z( q3 H2 \$ ?/ D
return m_bAsyncFindRunning;
( i6 |. q1 j5 ]! G }) K6 \+ u! I2 ~ o S1 g
" H# H) d$ J% O5 ^5 ]( t: r2 q, o3 m Y# l7 z
TRISTATE m_bUPnPDeviceConnected;
" L" d. j; y7 z$ I9 I4 H3 E6 d7 q- \
5 o' X' K2 M4 X; `+ o// Implementation5 n& n1 `/ K; b
// API functions3 q' V0 K; }$ N- ~$ [5 p% o
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
$ Z4 b( S6 N6 Q; @5 t) a& I. a SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);8 R' u+ U; d# X
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
& `9 c% ^2 A. `1 e) ~; y BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
7 k$ q; V3 p% w5 Q ]. } BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
T" c5 O( E6 a$ X BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+ M: n9 Y1 _ v, J
4 ?4 O% b/ b. i6 D7 W: J0 U9 }# L
0 i( V( y$ ^# r U TGetBestInterface m_pfGetBestInterface;
7 K; ~) E' M8 U$ e7 Q TGetIpAddrTable m_pfGetIpAddrTable;
" T* x% U) B* w$ n" x TGetIfEntry m_pfGetIfEntry;# T' A8 @/ f% @ m/ u1 U5 u
" }- |0 j8 ~2 r5 Z8 \
& a( a# O. X5 z! f! \ static FinderPointer CreateFinderInstance();
; c3 V7 e4 N; q) p, g5 ] struct FindDevice : std::unary_function< DevicePointer, bool >( X$ _' v% \& x: |& [& w( v) u
{5 E) \$ }- d: `& F' T. E
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}' `, T( u" |& H
result_type operator()(argument_type device) const. u P9 {: g6 w( Y$ f$ ]2 Y
{, p h% d! p" S n2 r
CComBSTR deviceName;
+ a m* G, T2 g4 L+ j4 [ HRESULT hr = device->get_UniqueDeviceName( &deviceName );7 p+ Y' p! D. Z% d
& z) N# D1 s' I4 k/ w% q
% |7 t8 j7 o/ f; f9 G
if ( FAILED( hr ) )" ^4 | G* e% W: | O# `
return UPnPMessage( hr ), false;
+ l3 M' t6 V$ S, `& ~$ B3 U+ \: H$ G, y9 Q+ g/ t
+ O; R7 }& N, p1 A0 o
return wcscmp( deviceName.m_str, m_udn ) == 0;2 O) Q& ^( p* ]/ j- y- {
}( W/ X7 ~( x9 \, C/ E2 {6 \
CComBSTR m_udn;. F/ A @5 V% [) ]) ~# m* s: Y
};
5 @$ X( f. L; N& ^, ^( s/ }- \7 N " H% p: l: R7 D/ ]2 H
void ProcessAsyncFind(CComBSTR bsSearchType);
, _3 U- v5 y. C' J5 P HRESULT GetDeviceServices(DevicePointer pDevice);$ H7 U/ N7 B, N8 S' E, J9 l7 o
void StartPortMapping();
- y& U% v( e4 a# M4 ^ HRESULT MapPort(const ServicePointer& service);+ X/ M# g( ]- V
void DeleteExistingPortMappings(ServicePointer pService);
2 V# l. A5 O; W8 m" @, b2 N0 s7 t void CreatePortMappings(ServicePointer pService);
# O2 k0 d% f& ~; B* D HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 Q+ I+ Q% O4 q- ?0 B2 P7 h HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 E0 g/ K1 [7 [* b LPCTSTR pszInArgString, CString& strResult);
4 y# s/ w8 W' l void StopUPnPService();* Y( `2 q4 F& _% ]: a0 D
( U+ q" P/ Y" x" f: f- D
9 S$ Y8 x7 E5 E" L
// Utility functions7 p' d' E& I! g9 K8 w0 P
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
% ~! `1 C }0 F INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);1 U1 \7 c. @! k( |: O
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
z, n. m' `: `) B void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) v: i9 s# N9 m' w HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);1 C( d+ \4 M" @
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
7 w1 z4 x1 I& ?! W9 u! v' G CString GetLocalRoutableIP(ServicePointer pService);
, D2 ^5 U! T' ]- r, N( o: x1 @6 R6 Z% X( h
! ~( d: g* v" S* ~" D
// Private members8 v8 ?; f3 Q! w8 Q4 ?8 Q. s" F/ u
private:
; x; F# D0 e) } j DWORD m_tLastEvent; // When the last event was received?
0 B+ L6 X% }: n3 X/ } std::vector< DevicePointer > m_pDevices;
" v0 y: p0 i2 e: o9 ~ std::vector< ServicePointer > m_pServices;
% a9 f1 Z1 q" p% N# A, u1 L8 U FinderPointer m_pDeviceFinder;
7 T* E+ h! q( N- U4 w DeviceFinderCallback m_pDeviceFinderCallback;
/ s! m R @/ h5 s ServiceCallback m_pServiceCallback; u" g; E4 u5 E* I, P
8 M$ b1 _) n* s x$ q
5 c5 c+ H/ [0 P) x- \8 Y; T LONG m_nAsyncFindHandle;- c3 f. r& K" O+ U* ^
bool m_bCOM;
, ~; Z9 i% k+ `- ~* { bool m_bPortIsFree;
j- @8 P2 N6 ^ CString m_sLocalIP;
9 R3 r7 U( m: h# Z/ H CString m_sExternalIP;3 \9 p% g0 U' m) w) }+ R
bool m_bADSL; // Is the device ADSL?2 x3 a! O+ g. K+ r3 s8 X7 h/ r5 K2 x1 U
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
) Z6 r# R3 `+ e# ] bool m_bInited;* b& U/ C; e1 g$ X- B5 Q/ E
bool m_bAsyncFindRunning;
" @! B4 \- U/ s/ S8 I8 c' R6 k& ` HMODULE m_hADVAPI32_DLL;
( [" t. Z/ I2 p/ ]4 d" a* M# { HMODULE m_hIPHLPAPI_DLL;4 X u1 u& H: b* g
bool m_bSecondTry;
' K6 q" B/ ?; h# O2 ?) {- P bool m_bServiceStartedByEmule; a. x6 e, L h4 Q m6 z" A2 y
bool m_bDisableWANIPSetup;
1 @1 t! O9 i9 x9 e bool m_bDisableWANPPPSetup;
$ b5 ~/ V% T0 {: v4 D- {: z" j
0 `8 |' O; Q9 `' C6 V; A
. c* ^: q! W; G {8 Y0 d7 B};4 t7 c6 `2 u8 H1 ^
7 G# j4 o% M8 l# W9 n7 o
; \# T6 o6 M( f6 ?; o9 e// DeviceFinder Callback7 \0 a% E& r- _, P' u) N
class CDeviceFinderCallback
5 i+ q) i/ _1 |# `! I8 G3 S : public IUPnPDeviceFinderCallback
, c! \% |1 q3 g H: o6 d& z{( e9 H; H; m. _- b' m! N2 G3 u d$ q
public:
5 Y6 S- ]7 p6 p# }2 i: g CDeviceFinderCallback(CUPnPImplWinServ& instance)2 ^6 m1 S1 t3 K) f
: m_instance( instance ) K/ O4 K4 R$ z, b W% @# q* Q& {, O
{ m_lRefCount = 0; }
4 U+ P- `" ]* ]- }& [/ c9 {) |7 ]& U, R7 Q1 `! a
1 _7 t( M, h, W' H0 m/ H STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 X9 f- a! W* u7 \
STDMETHODIMP_(ULONG) AddRef();7 i( E3 b& h; @, O
STDMETHODIMP_(ULONG) Release();6 k+ N6 e/ ^& J! X- Y+ i! v; ] S W
4 g7 a. \& E; g
/ L: \( L6 s" {; A' }9 o// implementation2 x$ V) j B& C* Z
private:
" `7 j, \0 N: v0 b3 r/ Q9 v9 G7 i HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);) O- Q; S/ k$ s4 h, ^) e
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ D( B2 r# \/ Z, O% h/ u8 O HRESULT __stdcall SearchComplete(LONG nFindData);
4 P; R; b5 U ^& W7 c9 n% A2 @: T4 _/ J3 o! A% \# o0 f0 F* K
! U. B5 C* E }$ i. D4 H# O
private:/ n0 p: o. M4 ^# _" |/ L, P
CUPnPImplWinServ& m_instance;
" O/ g7 o; Y1 g5 W LONG m_lRefCount;
+ r! m1 j0 D1 X Z3 M7 I};( O, W$ `; y. y5 I9 |! l5 }+ E
8 o2 n" n' y; ^' @8 C) H$ r, d
; ^; `1 z) B1 E' l' x% a. w' T4 p j
// Service Callback
+ F! n4 f5 M, L. a* ?$ A- R3 C! Sclass CServiceCallback
7 o4 C$ v. x, P) r/ p4 } : public IUPnPServiceCallback# y3 P* f- ]7 l9 i1 v5 }$ q
{7 \; B' @; t7 t! W' c- F* P
public:' M+ Q* k3 t. E; H( A: [
CServiceCallback(CUPnPImplWinServ& instance)( ]/ m0 t& ?) S- t
: m_instance( instance )) z' l8 f' b: M1 b5 |8 [- b
{ m_lRefCount = 0; }1 [' b& E) [; t: G9 e( f
1 B2 p% k$ u& e- w STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 ]1 J' p% f4 Q" ] STDMETHODIMP_(ULONG) AddRef();
1 i7 [* C3 G9 L$ M STDMETHODIMP_(ULONG) Release();
/ `5 d# r) _# F" P" c3 G3 @6 _* C( K
3 J; ~, j4 A0 d) d) J// implementation
5 X4 k( v- a- \" i5 Sprivate:
4 B3 f& s v+ U2 G, z8 i" E HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);4 A) |( H2 |& H% i5 c9 P' }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ R' o2 n0 G. i0 b) s
" ^$ @* t- ]' _
! ?! e1 ]+ w9 c+ i- [- Lprivate:
0 d8 m5 s5 r: r$ ]/ p3 B CUPnPImplWinServ& m_instance;
7 b0 N( d: z/ T LONG m_lRefCount;
0 Z- v l/ _$ P};$ \; U& F5 K& T' N6 H* n: U! _
) R, a4 I$ D* l0 A
: k( l+ o4 |6 b# h% n) c: n/////////////////////////////////////////////////! g7 q& a0 K# E: C# C9 S4 Z
I3 _* i9 c! B+ B0 p$ m Q* r a+ |, p
使用时只需要使用抽象类的接口。0 c; m* \0 n7 |6 A0 r8 Y, I
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 d' q, e2 X1 E' x7 GCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.. q) h$ k o; q' o, j
CUPnPImpl::StopAsyncFind停止设备查找.
' ~( C. b8 f3 x3 h5 PCUPnPImpl::DeletePorts删除端口映射. |
|