|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
) ~+ b9 R& ^: Q+ e; w- i; V% G- c' |$ B) k: C
4 Z3 j9 v. L a" m* V/ ^3 z* e$ M///////////////////////////////////////////
7 b8 i) U) M' {) ~% f! I/ C2 W//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.. i- P4 F; w) E+ |$ z9 V# G, I
# U) L1 m& c% y
2 S! P' D" @, r7 i: S#pragma once5 s- A7 ]5 v/ B! ^! Q* Y. O# S
#include <exception>/ h% M, r9 S! N+ u/ M
/ I$ V2 J9 k1 c- v8 F+ Y
! L9 P- w, [. Q6 C1 w& T$ B# U
enum TRISTATE{
5 U E1 [/ e% u" H- n+ t TRIS_FALSE,( J2 ^4 {9 H7 J* l1 c; w4 B
TRIS_UNKNOWN,9 l$ T' X6 E1 ^
TRIS_TRUE. y* r% B. k( f9 v. |6 }
};7 m; K7 {; o# \
0 {- [) J% T' g7 P/ }- G+ D
4 k( y1 ~0 {5 ^" q) W3 Aenum UPNP_IMPLEMENTATION{/ \8 w5 i4 h$ { g' S# ~" i! R
UPNP_IMPL_WINDOWSERVICE = 0,
! F8 U4 ]7 p, P% L2 c/ g3 O UPNP_IMPL_MINIUPNPLIB,3 N. J$ Q) M) Q+ H3 o8 Q
UPNP_IMPL_NONE /*last*/2 o; l- w8 k5 j3 C! k( ]
};
: C9 ?; o9 o8 F0 x; b8 }, w" Y( D1 o G
" l, Q' v8 Z0 j5 _4 o2 T( Y
( z' c2 c: B2 \6 |' ]! {
* }* y4 Y% U% Jclass CUPnPImpl) B# K8 L1 J) l6 c; Q! F
{
, d' @$ B: R0 @- [) Y5 ^public:
v9 D u- R+ ^; T! o1 u CUPnPImpl();, v" L/ o4 C* \& D- Y# @
virtual ~CUPnPImpl();
' ^% A Q; @( [# M8 V/ S struct UPnPError : std::exception {};( }! V4 S8 c: _, k/ E! l' R
enum {
, ` D6 a4 h8 D) r1 I UPNP_OK,' M) j8 ? ?) ^% q$ z* K( Y; K& X
UPNP_FAILED,! ]8 p7 ?9 Q# y, {5 O6 e1 c9 {$ x
UPNP_TIMEOUT
6 K' V" }& K6 i$ x( z };
6 C& j: Q/ l- J6 n6 Z" r" W
" b& Z0 Q. A* Z7 V2 d3 c. X* P, Q/ ]% r
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
: q/ H; ^3 n% y. M virtual bool CheckAndRefresh() = 0;
) D. S, b3 k8 t" P virtual void StopAsyncFind() = 0;
7 _9 z9 B1 g+ d: l+ s% j# N virtual void DeletePorts() = 0;
+ X! i! [8 r7 p M$ S" u- f virtual bool IsReady() = 0;
0 [$ L0 ?! g% e1 G. |9 O. h. c virtual int GetImplementationID() = 0;
6 U$ ~- {9 X; E, w* r
7 J1 K) `+ p n/ w5 d6 M$ M3 u$ z void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping* g/ X$ X4 i# W7 q! E" W3 f
( R+ p1 D4 a3 t7 ?8 R, g; Z5 [. T% `
. m* Z0 t0 f% B2 U, |6 v
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
8 z$ j9 ?. H4 o0 Y& G1 ^1 E TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
. L5 S e X* ~ uint16 GetUsedTCPPort() { return m_nTCPPort; }
- g- n V& `5 |& S5 c uint16 GetUsedUDPPort() { return m_nUDPPort; }
! v! I! }3 L# { v0 y9 q2 z: j7 v5 v& ~' M. q+ V
% S' ~7 I# ?. [// Implementation
# n) D4 S/ D& o& r0 lprotected:0 m" y' ?/ G9 E
volatile TRISTATE m_bUPnPPortsForwarded;
( m6 N# u: B8 g void SendResultMessage();
2 G6 \) d& G7 l: d8 F- K uint16 m_nUDPPort;
0 Q( w) o; _* ~& y" _ uint16 m_nTCPPort;) Q5 [+ a( s2 e0 @$ y( ]' n [2 x
uint16 m_nTCPWebPort;% u; n# S J: [
bool m_bCheckAndRefresh;2 r) K* L0 ]/ l: P3 Y
5 x, s* N, T. w' M
5 ?: y" S1 Q) n7 \* g6 W
private:
" {: `% S' A0 V" `! ^ HWND m_hResultMessageWindow;# D7 J7 k {8 |, J$ a i+ w
UINT m_nResultMessageID;
) F6 K3 k7 \0 G8 s) Y) {' g0 f
& y% V2 @$ ?. {7 R# {' n# P
+ s( R3 }1 D/ H" I};
$ C3 b2 A o+ r/ x- J3 u$ m
( }4 q' }" Q& Z" e
$ k; w# _% B ?// Dummy Implementation to be used when no other implementation is available( p5 q$ B# X' Y& |) ^+ B" D
class CUPnPImplNone: public CUPnPImpl
, ~, x( g* p% M* j {! Y! |{
, {3 ^! I& u9 xpublic:5 k) z: x1 {$ T+ n5 ~/ u; y
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 r; Q0 ~% d7 m: t
virtual bool CheckAndRefresh() { return false; }
: i9 q% N) D0 b! E9 v6 z virtual void StopAsyncFind() { }
4 h. f; ^7 n. _8 L virtual void DeletePorts() { }( l$ V$ m+ }: k4 n4 U, a# w- j
virtual bool IsReady() { return false; }
1 y" y. H! I( L! z: _& R3 W virtual int GetImplementationID() { return UPNP_IMPL_NONE; }! \1 I* s1 z" f8 P3 E3 N4 z
};) F6 c9 l. [5 x8 w. P7 z0 @
& w& s6 s" P& ]- B
3 x, O* @: G& c" O( R: x) i" o
/////////////////////////////////////. ]$ `4 j1 s$ a- d3 s" @- [! i- J
//下面是使用windows操作系统自带的UPNP功能的子类
" u; B& ]' G5 ]- I
~- Z% s* a/ E2 I
# N& Z; i/ n3 N#pragma once
$ F1 O* H# q# _, b#pragma warning( disable: 4355 )
4 l! a/ |0 F0 z7 f! ^4 M) D8 Q, P9 r3 b8 X3 ^* Z# Y, m, W
% F K% v5 ~# T/ C% Q#include "UPnPImpl.h"4 g& h. [0 t/ e5 |
#include <upnp.h>" ]1 R; Y2 x4 w: s- `5 r% P
#include <iphlpapi.h>2 Q$ u2 {( }( I4 W# m0 g
#include <comdef.h>8 m" S6 i2 s+ L% m* M" `9 M: i& V! G
#include <winsvc.h>
: U5 x( O+ u- u1 u, U% f2 g" Q
/ _) N9 z! F2 L8 g' h1 N* H6 |
#include <vector>
1 P! x: r3 r( C9 f$ N! Y/ R#include <exception>
* L8 P' n: R+ J. z4 o. l: _) H' r#include <functional>
7 U' P1 K, e2 \5 x) T, U n: c H+ E4 ?/ q5 R: R4 D3 Y" J
% |; p4 W( U( K, C2 E. D
3 c5 f- Q& D" t& M( H- \6 o6 H. V+ v( i2 c Y8 y$ n2 G
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;4 D3 {! R- O' @3 U
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;+ a0 q* b3 ~) Z+ E4 W9 r
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;0 I. t( P2 H- u9 [# b
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
y8 `7 o6 i9 D7 \/ Ntypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;& U) S! `+ U8 M( {, L
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;, V2 V9 C2 U) ?7 h
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
6 n+ w1 B5 a: |- T- U: w3 Z' t/ I
/ V6 v5 R2 l) [+ D
c4 M5 A* c6 o p5 v4 ^' {typedef DWORD (WINAPI* TGetBestInterface) (
( e- J4 Y4 f) W G5 ~6 r IPAddr dwDestAddr,
: D$ V: m* U0 ?: v; L- g7 n3 H L PDWORD pdwBestIfIndex
/ S- e7 g2 C, P6 B);" b/ W2 `6 \6 v! N5 y& D
' s5 e# J. |) p- H! I$ ?% j1 ~
% c } k4 C) N7 J6 F
typedef DWORD (WINAPI* TGetIpAddrTable) (2 _. K+ L* }( S d/ r1 _" P
PMIB_IPADDRTABLE pIpAddrTable,& ^9 _3 E3 `- E
PULONG pdwSize,6 I1 O6 ?3 a4 l9 _* n. u* q
BOOL bOrder
9 V& a: w4 e \6 t) _' w; r);
0 `$ t% }2 a! y, |8 i1 w3 ~6 n/ \7 v( j$ O6 F1 }
% a7 n0 a& I* D9 [+ Etypedef DWORD (WINAPI* TGetIfEntry) (% B8 f6 s* V# {0 v% O
PMIB_IFROW pIfRow
& _. [& z' R5 ?4 y) Y7 d);/ V1 \2 @. Q m/ P. d. [" b9 s4 d
6 C' |' N/ w9 V9 I) p1 \0 ]2 D& I/ H7 j* e9 b; ]* F& V/ k
CString translateUPnPResult(HRESULT hr);
' }4 r- ?( C, h6 @9 `HRESULT UPnPMessage(HRESULT hr);- d5 x" W$ H2 h
+ y8 a' @3 I# `# I! @/ h8 y
! a' P9 l9 C y: _4 ?( B' p
class CUPnPImplWinServ: public CUPnPImpl9 _; r2 v- i# w/ y) n$ v
{
+ F$ q/ Y, B# g' i2 [ b friend class CDeviceFinderCallback;2 ]6 a8 u2 V2 K2 _! p* U7 e) J3 x
friend class CServiceCallback;
- J- U& M1 _$ o: G) }' f// Construction* q/ H6 G7 x* E1 ]4 a5 ?& {% i% n
public:: |! `, l% Z9 B( t6 @* `0 ^
virtual ~CUPnPImplWinServ();
0 C$ ]# R; G0 c$ z/ e3 `4 ~ CUPnPImplWinServ();
2 K- j2 X+ X" W! j- {5 n. A' {$ ^! Y9 u' v2 ]0 o
: |! c3 f! X2 Z7 ]( v7 H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
: n% z# _; I' p8 a6 a) [ virtual void StopAsyncFind();
7 m3 L! a2 U' a& ?) V: m; F virtual void DeletePorts();
( T7 g! Z/ h: C6 D8 J$ R$ | virtual bool IsReady();
# k$ S% G* ~( { virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
6 D# n* r- V+ H$ ?5 Y1 A9 R( J) Y' C5 s: _
$ |6 o! U0 s8 s& u
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 X$ Q: L/ e" w F: B // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later# E2 b1 O: f3 v* |# M# {! \: e3 R
virtual bool CheckAndRefresh() { return false; };% X+ B( e2 }% N- F5 {, B8 d
& ]+ [% P0 w$ `- A5 x6 E5 N
: X, U9 y& T/ O' iprotected:5 ^7 H- M1 J, s# i0 f" u$ r
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);# @* d# B& E2 R# V+ \' n! h1 Y
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 x8 J6 b. o4 X8 p& P1 c void RemoveDevice(CComBSTR bsUDN);7 {7 u# y# K( C: a! I
bool OnSearchComplete();6 ^ d, _/ n( t v( A* l, }3 z) B6 x
void Init();
k; F) g; B( }, x0 b# {7 D% t1 }$ ^6 I1 W/ n
3 ?3 E5 F' M8 I+ K/ l- t( S
inline bool IsAsyncFindRunning()
+ {/ G# ` b) d( ]" N { a; H3 p" L- v/ |0 C
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
2 b k* q) I3 L5 s4 F- w8 l" w1 ?" \ {% ]: f/ u- ]8 i, N5 k
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
" s" V: }7 o3 [1 d m_bAsyncFindRunning = false;. Q: _ o* V: i) U
}7 G# F: _) V4 J2 I
MSG msg;
; |1 W& R) ~: h' I7 m8 A while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 k0 o2 l& C% K- B1 p
{; g& @. ]; n& A( O$ b. X' W2 U* Y
TranslateMessage( &msg );; i! u. W# i1 v
DispatchMessage( &msg );
6 I' K/ Q, i" H0 ^9 Z h: V4 I }8 k* {3 L( T9 L, r
return m_bAsyncFindRunning;9 L/ B& i% Z6 [% H
}
; u- [% | j$ w: k" ?
8 ]1 d, e: x4 {, l, p. c7 q: `' b, z V
TRISTATE m_bUPnPDeviceConnected;
* A. r& o2 W8 v6 U" ^
2 w+ c* _$ H% o3 u' P! ]' }5 [# g, o. o$ ?$ ^& d
// Implementation
% e6 i/ u+ f" K0 C- M- J9 Q // API functions
% m: }( ]+ d+ R8 E8 _9 s SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* r* C1 O: ^$ l% T( Q SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- f: W+ r! a9 N8 {# U; W; o; o' } BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 I! T* C: h+ R( O' @ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
) J" U D L: G. R* M1 E! T BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
4 @4 }) I1 N0 u& b } l BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
' J2 a% C0 @; L( [6 `
@5 _$ \# n4 I4 N* ], x0 ^- l% z& E2 K8 O _4 R/ x2 w
TGetBestInterface m_pfGetBestInterface;
, k* T+ e5 \* [+ X TGetIpAddrTable m_pfGetIpAddrTable;; j* a! t7 O( R' ~
TGetIfEntry m_pfGetIfEntry;
( Q4 z" U3 Q- I$ J' a) n8 x [% Z; r2 f$ H* ^- {) ]
" ^' O* E$ C/ f: s* u9 {+ h
static FinderPointer CreateFinderInstance();
- B, ]0 m5 I4 E8 i. b struct FindDevice : std::unary_function< DevicePointer, bool >
; \: j. f: p* H: M {0 F% F& w: o6 t- N) }# _- h
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
- v, A5 K- `. D/ X8 {0 U1 P result_type operator()(argument_type device) const+ t, |1 p3 I' T# e
{
' j* j1 X& Q" ?" u CComBSTR deviceName;, o( b% t# l) o1 V
HRESULT hr = device->get_UniqueDeviceName( &deviceName );1 n' z( ]0 v8 m3 R; \
) L7 T; \! r7 U2 n4 d! P0 v1 e- C' ?( p6 {8 o/ ~2 v, y# ?
if ( FAILED( hr ) )
% r9 z5 ^. p3 Q return UPnPMessage( hr ), false;, C/ b3 z1 k3 J- T/ v6 |. `7 P
& w4 L9 r$ [) |3 a" ^4 S7 ^. K3 B1 k/ H0 ]: c3 [# `4 G1 X; v2 @
return wcscmp( deviceName.m_str, m_udn ) == 0;' k/ g' m: g. X3 b" [+ q* ?# f" `
}
0 G1 P2 m: R7 `, x# T; N8 v$ o CComBSTR m_udn;
$ W7 F1 c5 u+ \1 s5 F };# ^: V3 z& I q9 w
7 V6 t$ B5 a0 S* c& I- d, r2 C$ O void ProcessAsyncFind(CComBSTR bsSearchType);
' e, M2 E2 _9 \. V; G HRESULT GetDeviceServices(DevicePointer pDevice);( V- w' p$ |2 L1 `
void StartPortMapping();! v* I( t% t3 F4 P
HRESULT MapPort(const ServicePointer& service);. Z2 _4 h0 z) j" F( w
void DeleteExistingPortMappings(ServicePointer pService);4 S: ? o+ K+ ^' B) N. v" }+ d' ]
void CreatePortMappings(ServicePointer pService);
* V" r6 H: x" b HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);7 @+ m% J. f. W
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
4 B; P6 A5 Q7 d% {2 r. B LPCTSTR pszInArgString, CString& strResult);
0 {% H E' i% T" S* W void StopUPnPService();0 c2 f9 _4 W; ^; U: v6 Z7 b# f# m
1 y6 M, H8 y( l! n8 u l* R
8 D4 p+ D4 B( v1 o" L // Utility functions9 ]. d! t7 h2 j; f- _; n6 j' `
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);, w1 H9 u( x! K$ R# z% s+ ^! E
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
( N. b, m2 N3 z$ S2 I INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
" o- f5 `5 ^/ ]+ F. I" |$ I void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);9 B4 B7 n. @; C( f
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);' l. q7 w6 t8 }% u$ l( N4 A
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
0 I9 l" j0 m) G$ p3 ] CString GetLocalRoutableIP(ServicePointer pService);
3 L/ E- w2 i# W0 }+ U
8 p: l- R2 O* e7 S b: g
7 n: s V. S5 `$ l) ^) p3 C// Private members* T1 B* h0 k- Z$ _, z
private:
1 g6 L5 ~* M4 _) l. a3 ^4 D DWORD m_tLastEvent; // When the last event was received?
- b; k% o6 `7 M k5 I5 b* Y7 a std::vector< DevicePointer > m_pDevices;
3 o" d6 w3 c1 c std::vector< ServicePointer > m_pServices;
. `, U7 G$ y: V FinderPointer m_pDeviceFinder;# ]9 n: y, {: n+ I
DeviceFinderCallback m_pDeviceFinderCallback;
2 {; e, i6 o) [& N7 x ServiceCallback m_pServiceCallback;
/ L2 Q. X) e7 K( G Z+ F% T, i
3 {2 M" o8 v i/ d) v+ F& K9 b$ i2 d S! l8 `6 M9 J" a) a6 T
LONG m_nAsyncFindHandle;
3 D* K, Q- }) ~& x& l( x3 n bool m_bCOM;
1 U9 P9 k9 u" u. ^ bool m_bPortIsFree;
+ F7 j! H* [* c9 K1 v; h1 L" R CString m_sLocalIP;
& C" v# Z% e* I# y CString m_sExternalIP;$ F( Q% ]& `2 }" M) |/ @7 W
bool m_bADSL; // Is the device ADSL?
9 R' I: k! e- Q bool m_ADSLFailed; // Did port mapping failed for the ADSL device?) d$ S/ \/ Q# R, ~! @4 f) e
bool m_bInited;
* f& q/ r7 S. ^' \+ w bool m_bAsyncFindRunning;( T1 d) B9 q2 e3 C" B1 f. d3 r [
HMODULE m_hADVAPI32_DLL;- s4 a8 O$ }! ?% }* P: M
HMODULE m_hIPHLPAPI_DLL;4 L: a7 s7 F0 W. |- `9 n7 i
bool m_bSecondTry;
7 y; g& Q( K" ^) i bool m_bServiceStartedByEmule;; c) F/ t/ _& C4 `) m0 n. x( B
bool m_bDisableWANIPSetup;
6 t/ S* C2 ?& \ bool m_bDisableWANPPPSetup;$ t8 U/ W/ Y$ T `7 D) e
; N# e" y _% }4 s+ w( T" T& P, g1 _ |1 Q: u2 k" b
};
& r: t5 q; C& a$ @) P$ ^
; ?+ \8 k( { r7 e3 b1 s) e x- c
$ m0 C9 O1 ]& ]. v5 l1 D// DeviceFinder Callback
3 x% L3 ]6 s9 }2 Lclass CDeviceFinderCallback& z8 x( u4 I! W# L7 j) ]
: public IUPnPDeviceFinderCallback' k _' z4 D5 T4 Y( ~3 i. l/ k
{
N4 F' p$ W; d, k i! vpublic:
$ _7 R0 T' X! @2 S1 z1 B CDeviceFinderCallback(CUPnPImplWinServ& instance)+ i" {1 s5 H/ F7 j6 [+ c$ x
: m_instance( instance )
# l) n$ I' Q0 S* \ C# r0 ^: W: j { m_lRefCount = 0; }
' ?- U8 P% Q Q8 C5 V3 V2 u/ Q1 n6 m: r5 B2 c7 f3 F
& x* G" U. f! e6 K1 x' g4 V STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; G4 Z2 F- v5 c& {1 U/ Q+ x [
STDMETHODIMP_(ULONG) AddRef();
2 R& |! o; [, I& w: q( H# ~4 K STDMETHODIMP_(ULONG) Release();
4 B2 x0 Z- i9 ]; J/ j. Y+ S& e0 o3 ^1 G* M8 u- g6 ?
2 e( T- m. n3 F% @7 R2 L9 e4 I- {
// implementation
2 y9 P8 L- U2 B. e+ e( oprivate:; F9 ?* A2 h4 n
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
4 P: }6 W" o: B# u8 ], h+ Y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 O1 N n* ~( I HRESULT __stdcall SearchComplete(LONG nFindData);
9 G" T. {1 j1 }- M4 ?) G
2 ?5 d. J( i2 h& O8 H
0 C) W j! B8 I" z/ O1 g& Qprivate:, S% k) S/ z! k# e$ k
CUPnPImplWinServ& m_instance;
* F4 |" j3 {4 D$ v4 A LONG m_lRefCount;' b; H7 M& ?# f+ ]. u8 ]
};$ ^9 |* E# J2 w* l
, g2 w7 ]5 P" M q9 H1 o* ^9 c8 p
// Service Callback
- i4 l1 Q+ Z d' @- Jclass CServiceCallback9 D) }4 ?8 ?5 _7 K+ r
: public IUPnPServiceCallback
3 d- T+ q9 L2 g" d W{
/ \4 q- r# c5 R) G9 t7 apublic:' f: q3 m; t5 n* i" ]
CServiceCallback(CUPnPImplWinServ& instance)3 W# a1 |+ V1 z( j- a1 t% [4 I
: m_instance( instance )2 Z3 y+ I$ {' \! `3 D: F, M
{ m_lRefCount = 0; }0 a' M9 `3 i2 z1 r) o7 x
; `' x! U$ @; @( Z/ a0 i ~+ h3 [
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- H! u' l) u& b/ z+ m# k% W
STDMETHODIMP_(ULONG) AddRef();
+ S# j# h+ U, W STDMETHODIMP_(ULONG) Release();% W8 ?$ m& w, s
. O. K& r; w0 k& |* r2 K- @+ b) s1 I- L# H: o, f
// implementation% W2 |. n# N- w& w) ?
private:# [0 C) T- g+ q
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);$ N5 M8 a! `9 @+ Q9 {$ l( ~
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 C. ]5 R8 p; a" e! E7 Q- X- A" U0 o( `2 H
* n/ p3 S3 I/ w Q9 k
private:; C1 g% Z7 C( G; Z/ @
CUPnPImplWinServ& m_instance;. o4 p( X1 q. ~+ Q. w) k
LONG m_lRefCount;
3 T) b& U- @8 K9 F5 L. c7 _};% g% H7 W. X, a8 M0 x' n
% W2 C; l$ h3 E5 \2 S' L
& p4 e& s t2 _/////////////////////////////////////////////////( ^ U2 L/ t( [, r
3 i& y- M, Y' L* y) s4 R3 G) [
3 c9 Z: r k. j! j, K0 B7 c6 o% [
使用时只需要使用抽象类的接口。% ^' o! R/ J: J0 ]1 |
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
- e) K" j( a8 qCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.* q% d3 B4 Y1 E- }
CUPnPImpl::StopAsyncFind停止设备查找.
; F$ x9 d! Q8 MCUPnPImpl::DeletePorts删除端口映射. |
|