|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' @# t7 h4 D, e1 y0 o4 ~: E3 @5 R+ n, Z7 `
: c$ C7 h- ]# j K. l, D9 K" {7 O: {///////////////////////////////////////////
5 y' T. K+ j" ~8 B+ t. \, {//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.2 y5 K* E( d# K: g
% D ~4 D6 x. S5 K( ~ a
$ A$ p6 u# s& T) V" |- B#pragma once
1 \; r i8 A0 n8 G4 x, Z- ~#include <exception>$ v# _/ Z" {) W. k) k
5 Q. D2 Y d+ ?& [" R
, E! r" B( H% B! Z+ r
enum TRISTATE{ h' p7 U3 b, f* h, A
TRIS_FALSE," j& X* g+ V& Z$ `4 q3 i; _# u" K! @
TRIS_UNKNOWN,
+ `' [' C1 a% C TRIS_TRUE0 h7 K( t- Q/ `2 j. u8 g$ r4 y( A3 K
};4 n1 o, P( y3 S2 J( A' q4 k" H, e
' z( N2 d. [3 @5 ?* D/ V
. L/ a; ]" n+ Y* u6 i* O& ~
enum UPNP_IMPLEMENTATION{
2 ?9 y# c. K: c; N UPNP_IMPL_WINDOWSERVICE = 0,
M( `9 J8 N% x4 D! s UPNP_IMPL_MINIUPNPLIB,
, T' a1 i8 b+ }) N2 p$ _) r- T UPNP_IMPL_NONE /*last*/: Y4 U3 A6 m* J+ Q
};
, I$ K- S# \" G% K `" ?
7 S; ` `7 J9 w% ?% S" n2 @- x. \
j g( |! v9 r) V$ c* |, {
& i) C( t$ e: f1 O; g. {6 R7 X6 D( q% W( M% C. X' s3 A7 ]# a, [
class CUPnPImpl' ?& n& I8 R& _ p
{
' R; I( M* O$ A3 ?+ spublic:# D+ n5 O% Y! f* J- p1 V
CUPnPImpl();- g; w6 g5 d; C7 n! M6 L- {: b
virtual ~CUPnPImpl();& |+ v% }# {+ i- P
struct UPnPError : std::exception {};% g1 O' p Y9 L8 G4 c
enum {1 ^; d7 a7 l# I( c7 t0 J) n0 D
UPNP_OK,
' x/ Q0 x) m0 y( F: X6 k8 T2 N9 E UPNP_FAILED,) I c7 p8 o6 V3 ~
UPNP_TIMEOUT
% x7 K! _4 o5 t0 s };, J1 x8 Q( v/ H5 l0 f& b0 Y
1 X& A% e- T; a. K" G
7 ]% {2 N3 t" _0 r) q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;# j' n2 d, J1 Z2 y/ a
virtual bool CheckAndRefresh() = 0;
6 r5 o7 q4 |! p5 @0 u5 J0 O, o+ m virtual void StopAsyncFind() = 0; v4 k/ C: E: h* o/ J5 ]5 t) h/ c. R
virtual void DeletePorts() = 0;
) a: I, K! D' k* x' O# l) R: t9 k virtual bool IsReady() = 0;- K2 X) H" e0 i3 l$ p) q) W- ?
virtual int GetImplementationID() = 0;
# w- h! F1 B! J) `+ n 3 [6 _" C% y7 x4 m; E) z
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ J7 A7 C; t9 o2 U7 X
$ _+ w7 }# |, V+ }
" T. d, L+ x0 ~) [9 V* F. W: W void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 X9 ]- U/ ?* ?7 I' }6 |0 r" u TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
1 y8 S+ i# _3 G, |# C, H( v% O uint16 GetUsedTCPPort() { return m_nTCPPort; }1 q6 q) D$ Y' Z" w
uint16 GetUsedUDPPort() { return m_nUDPPort; } 5 i% h# R9 Y" H0 Z( F& C
" ?5 a3 H! Y5 \; v( T, F) |. D" }& I4 P1 `
// Implementation7 p! d' r& k: k- z' i5 ]# Q
protected:
6 d" h) B7 W3 {! Y6 b3 l2 D volatile TRISTATE m_bUPnPPortsForwarded;
5 @& Z" t# d3 X" m" M0 x void SendResultMessage();
7 K! |* K! N e% c0 R uint16 m_nUDPPort;& C. O2 d7 U# \: t
uint16 m_nTCPPort;1 X) I: K. Y# g7 |' G# ^
uint16 m_nTCPWebPort;1 z% Y8 L& [6 P w) d# @) `
bool m_bCheckAndRefresh;
( U. r/ m: l3 H3 |* R5 [9 }5 Z% @6 P- \4 A0 e; @9 c* @) h1 {4 U
9 T! j& T4 a' ?2 N: w! fprivate:
$ U' U8 b3 Z% [* y8 j7 s& B* K% q# ] HWND m_hResultMessageWindow;) k' l0 U. @/ b; Y6 z6 ]! t
UINT m_nResultMessageID;
: e$ Y; {1 c# Q, c/ I3 O, r0 H
% c7 [9 U/ n$ _, x0 N3 Z6 U' B9 n! R# X; s
};; ~2 ?+ v% Y3 Q9 ^: S ~
. E) G. K+ U9 i* L7 Y
6 i: Y8 j2 m$ f5 `7 S6 a R- g ]8 I
// Dummy Implementation to be used when no other implementation is available4 ]# G9 Y! l2 X% c3 ?* N
class CUPnPImplNone: public CUPnPImpl7 b0 t+ r' J8 p: t. d
{
* y" A1 y$ ~3 x0 x5 C# u" qpublic:% ` l4 `4 ]7 O3 J
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
% e4 J1 O9 M/ A. t) }- N. N6 G" O virtual bool CheckAndRefresh() { return false; }0 m ?/ M% j1 Z
virtual void StopAsyncFind() { }
$ s; {$ D3 F; ]2 i! _, ?- v virtual void DeletePorts() { }. `" o s: w, S% X, T
virtual bool IsReady() { return false; }/ Z$ {$ s- { O2 M! Z* b! Y2 C
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }2 j9 W: |8 L* g! d
};
2 q+ G, {1 | w( l& E$ W6 J
% i$ E* v1 R7 s9 |5 F" a& R* i0 {: {/ e& n# K- k1 n% q/ {
/////////////////////////////////////% Q+ p6 O/ O' t" V1 d4 X5 W2 a5 H/ D
//下面是使用windows操作系统自带的UPNP功能的子类
* G' r: x1 Q7 n, {$ g
1 k! i$ b0 ]# g( Q. x+ a& s$ E$ P& e$ c1 h# `) J9 h% }; l, ^; f
#pragma once
$ ]$ p! J- q8 v6 j- O#pragma warning( disable: 4355 ): E( u e+ K8 O D! l3 ?3 L
3 l' Z& c! H# B
( E3 K% \- K0 @' \#include "UPnPImpl.h"" N# a# S. d/ B/ j* z7 e n4 a
#include <upnp.h>- L2 l& r* x: c9 v) L' O* M
#include <iphlpapi.h>) m; M, J& _. V$ A4 b1 {6 w
#include <comdef.h>5 k7 S. A5 P+ X& a% N4 K
#include <winsvc.h>
" C; d) U3 ? j) x6 u- I4 Q3 J6 _, R
: ]4 j4 I& @9 K" T! v#include <vector>
/ U$ T9 I' h; g. F#include <exception>2 G$ m. j7 r0 s9 O- F
#include <functional>0 j/ M$ {; e9 V- o! D7 i1 b
2 r+ j, `2 I& a6 b9 t
! d; p9 |# U! ?: _/ _9 `5 R# E/ a' b
& T! I9 _/ y% x& ^$ d8 V3 g. }; n# i
# D% H0 N& F& u8 v8 s$ ?7 b; @1 m5 O
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
: z: D- F3 }, G# F; j2 G& [7 Wtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;9 r8 O& n- S, h4 _# @2 k; M
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' U! W; S8 f6 F# W0 E* Ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 P1 Q/ d+ T8 m$ `6 q( Dtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 n. R! b/ }" k+ S: ~/ s
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;* ]' U: u! p. F6 g9 L
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;; x+ v" C! H; p- Y9 Z
" K2 h+ t9 V. n6 M, H9 `( F
( h1 m6 I# t4 ?% otypedef DWORD (WINAPI* TGetBestInterface) (: c- N- C7 G# Z9 I, q# F! _
IPAddr dwDestAddr,; ~9 t& w- f- C* H. W
PDWORD pdwBestIfIndex) N! h3 z: h1 x
);! j# i% W! A& x" H# v+ b
4 w* v2 r& k. P; E3 ?$ }4 \8 a1 [0 q1 L* _! }
typedef DWORD (WINAPI* TGetIpAddrTable) (
/ C: ^! b* G# T/ ~2 a' Z, ~3 @ PMIB_IPADDRTABLE pIpAddrTable,' J T0 s! ]4 ?' n! G: `
PULONG pdwSize,* `/ O2 ]* h+ }, e0 n6 r/ G
BOOL bOrder4 I% U2 [- g- r f
);
6 p/ W$ `& J4 d5 O; i* ?8 `3 x% j6 [3 R' z; r5 M
: Y' _4 K/ [6 {typedef DWORD (WINAPI* TGetIfEntry) (! a' o2 s7 d: P& _* u5 ^/ x. F! e
PMIB_IFROW pIfRow, C' o h* r* d- s% m2 E* ?. \
);
1 w! N3 o0 @' d5 S! T$ e: h
8 A! J3 O9 T* x& y) ~9 L$ Y! {/ ^! T3 f; T
CString translateUPnPResult(HRESULT hr);+ h& q H" Q) f3 F9 Y
HRESULT UPnPMessage(HRESULT hr);7 @4 i \' Q8 [. ?. e7 Q
" G$ p' {" q; {( U2 I# q: g3 U" J, C9 C* l* s
class CUPnPImplWinServ: public CUPnPImpl
/ M7 t' A& _. }7 V8 V' j% A: k M$ P{
9 }8 U4 l- @% Y3 ~/ z friend class CDeviceFinderCallback;" y7 D: k7 U% }6 h5 {$ m' Z
friend class CServiceCallback;
! v1 u+ o/ T1 h& V% R" E// Construction
2 G5 k5 T, o |0 |3 ypublic:
9 X& m/ H* K4 d, Q' a virtual ~CUPnPImplWinServ();
4 d% \+ V4 O5 S7 x# u2 B! P CUPnPImplWinServ();
0 a2 c$ w: a0 ~" D# b# u+ r- Q; ~7 P& ^" Y2 o
% v, k. i- Z6 O) x4 \
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& C: p) n, Q& [ virtual void StopAsyncFind();
( k- T5 S. L. s' ^- T3 f; J O3 G; y3 f* ~ virtual void DeletePorts();0 ^/ ~ z* A b1 r% M# B+ e
virtual bool IsReady();! w2 i4 R' G I3 K6 L
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, Z5 e! W: p% m7 y4 C; j. P
( t# v+ [5 E5 B2 H+ N* i
+ k0 _% T4 p' k // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)" D# r5 M/ k+ H/ y/ j
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later. |7 \; n- I/ L9 A" Z6 ?
virtual bool CheckAndRefresh() { return false; };
: P, ?$ B# ]" S, w$ C y) C7 [5 S2 k
3 R* `5 Y9 a# h; G9 ^3 V" K+ a- d$ b$ z
protected:5 R- o# J5 `1 ?! u1 S& U
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);* r, s% Q) K1 w! V7 K
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
7 i6 y1 t; G6 V6 l+ m: d void RemoveDevice(CComBSTR bsUDN);1 g! J. l. r9 w* ?7 G7 y
bool OnSearchComplete();: p, j N! E( N" }5 t
void Init();
3 L$ Q+ ^* V" i' y; b3 M# U- B
, K3 @* m& X2 w. [2 s
7 @6 O! _6 T ^- K: ^) ^ inline bool IsAsyncFindRunning() : _, W6 G1 {- B/ J% _8 }, J2 a
{
& h2 e5 Z5 j2 ]' ? if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: R" ~0 y- R/ i! { {$ n' T2 u9 h# N1 ~& f6 r7 J
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );) m8 ? o& q* h! E5 s6 h
m_bAsyncFindRunning = false;
l3 G" B1 s$ z% l' ^( S% a }
2 w& H. n* z% O MSG msg;8 I: w. ^' g2 I: ?& y- l/ _
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )2 H5 c# F7 l" R! }
{' y6 c9 T; q9 ~. p; R: Z0 o4 Z
TranslateMessage( &msg );% g% W: g3 w- }" z& M0 w
DispatchMessage( &msg );7 S4 p7 R5 r; u8 D% b- o- }
}
; e. t( Q1 I( {4 d! M return m_bAsyncFindRunning;! [! |) `; r% w2 K3 K
}
9 c0 _% F$ M( Q0 w" E& ]2 Z" ~5 Z9 u5 t- }
f1 e6 r. A. D% i. k) q B; g TRISTATE m_bUPnPDeviceConnected;
; [) o4 y, h. |# u% D' m# Y3 l: w. B6 A# @
: c/ U% B4 N& ~0 m// Implementation
" Y: Y6 i4 Q& i5 Q- A- _7 Z- p // API functions* y1 v8 }8 p, p6 W d
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);7 ^3 T0 p7 o" n, Z
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
( @9 Q- f. U5 d% b( `6 Q3 C* G9 p BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);! x6 x/ ?! E* e! e& A
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
5 ^* ]+ q; k" |8 @2 n$ q' W BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
! O, W4 {' Z8 l BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);1 A/ v! ]; Y" \- F1 p9 M
7 J( w6 S+ D1 u1 m& R. ]' ] ~
# U( k; j" l( u1 Q
TGetBestInterface m_pfGetBestInterface;
, x1 D; [# d7 x. W1 ~! W TGetIpAddrTable m_pfGetIpAddrTable;
. E" L' _& v9 e$ J TGetIfEntry m_pfGetIfEntry;
- r$ w6 X- j( P# z+ B0 V4 j, T3 V* z9 Y H
( f) b/ H; n% a3 B; A' f
static FinderPointer CreateFinderInstance();
5 i: x3 A+ e( v! R struct FindDevice : std::unary_function< DevicePointer, bool >6 l2 e9 V8 N+ G7 j+ f* c
{+ h- _+ g2 `) m3 \! F3 ?
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}, `$ J& U& [) |+ I. ~' ~9 D1 t9 d
result_type operator()(argument_type device) const( V% ^) ], O- t4 i7 e
{' d) I/ [: u( o
CComBSTR deviceName;
& B/ {! L9 p: Z- Q8 n5 ` HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 m0 [+ E& p, K# _ \) p
# [/ B. B# k4 P3 R+ m3 `4 m- x) m' S' @" k- I- v* U6 v. C
if ( FAILED( hr ) )
3 O( k& k7 ^2 y) c, q. O return UPnPMessage( hr ), false;, n2 A3 S# X1 |- q
4 }! b6 \' j5 U
+ W) _. [$ d. H; H, h$ P return wcscmp( deviceName.m_str, m_udn ) == 0;
7 u4 v/ x& `% {4 Z* P B4 { }
6 I$ x- q% ` `" Y1 l; m, E CComBSTR m_udn;
2 j& K2 Q3 T: W. i };" |* [" c0 Q* j1 m7 v" I5 E
, f1 j( U& l9 W* O1 N; H void ProcessAsyncFind(CComBSTR bsSearchType);. W" c1 h# i8 O2 \4 c% `4 D% Y
HRESULT GetDeviceServices(DevicePointer pDevice);& k5 n& h4 {* C& _8 q4 Y
void StartPortMapping();
3 F, s9 ?* l- L1 }8 u4 W- l& ^ HRESULT MapPort(const ServicePointer& service);
/ N9 h* X3 y- M' W7 r+ ?. s void DeleteExistingPortMappings(ServicePointer pService);1 O8 e" d) U# A4 x$ |
void CreatePortMappings(ServicePointer pService);( f5 h" T. t* N6 a3 K
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 ^% e- J* a% g2 {
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: {" a5 J# y1 l4 i& o0 L LPCTSTR pszInArgString, CString& strResult);6 j% f9 P# ~* F. t& \: I# u5 l
void StopUPnPService();
7 ]- M' s) [& ~: k' i
9 B d$ a& Y+ e7 e" Z
1 k( I) s8 w, E9 C9 d2 w# \- F // Utility functions
y2 T2 P4 V$ s0 |/ @ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);1 _" s( @/ a3 N: V. Q P4 K
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);5 c! k; R+ F6 W1 j! a. v, C% Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs); \) n5 L( Z8 y3 {; V6 ?. `# Y/ S
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ ^: F: D4 ^7 Z: {* y* ?4 i& j
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
( g% O6 x+ i4 e4 I. _ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);2 C( e; r9 `/ F, Q7 ?
CString GetLocalRoutableIP(ServicePointer pService);
- Z! J: s( h: j5 H" x+ n8 e, D1 u7 J- r
( y" }' }" c! ^' y8 H) w6 Q2 y
// Private members
, ~' y c' V* E: hprivate:
6 B! n4 h4 t6 W DWORD m_tLastEvent; // When the last event was received?
; `" T1 J' E( @1 L; _. |2 h5 D5 D std::vector< DevicePointer > m_pDevices;
! U9 x2 d5 [7 B I' M* u& g std::vector< ServicePointer > m_pServices;
: [, r3 K2 j" n6 ]' D% x- P1 p FinderPointer m_pDeviceFinder;) Z5 {0 z2 d7 u" f5 A A5 G2 B1 w
DeviceFinderCallback m_pDeviceFinderCallback;
8 {4 W$ `; Z, p ServiceCallback m_pServiceCallback;
; x2 C7 k4 l- h5 {
: R' L4 g5 _. e) t H) [4 f% W+ {' A9 |* n0 M/ W: v* \
LONG m_nAsyncFindHandle;
$ B5 ]; Y2 q% u P1 Q( K3 x bool m_bCOM;
- e6 \8 w5 D, z" {/ B5 l bool m_bPortIsFree;
0 u& _# z y# ?! L3 d CString m_sLocalIP;* q8 a4 j6 U: m; B7 {; j
CString m_sExternalIP;
6 ]) U! `: T( F/ h- ~0 h bool m_bADSL; // Is the device ADSL?& v2 F7 u* L/ E5 [, U3 J4 @" D
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
1 h3 \2 |$ F; W$ V) ?! R bool m_bInited;
( ~' _$ C/ s' c( A8 ? bool m_bAsyncFindRunning;# y A) s/ f- v3 r! i
HMODULE m_hADVAPI32_DLL;0 D; P4 O4 T* o8 y& t
HMODULE m_hIPHLPAPI_DLL;: T. U" _8 |/ ~9 w; P$ t$ n# v) g( N
bool m_bSecondTry;
+ u/ N6 @: Z$ b- A% s, D bool m_bServiceStartedByEmule;
# i+ ^3 }0 c. G$ o bool m_bDisableWANIPSetup;" x1 p2 K L" E& [
bool m_bDisableWANPPPSetup;: l, T5 Y' }1 F
& X5 i3 I* T+ C* Q5 `: |9 ~0 ^9 w4 J8 i) J3 }
};8 a6 q6 r5 l/ d# K
( Z [, [( Y4 {" q4 _6 }5 V4 ~6 t. H5 t {8 ~8 C" u
// DeviceFinder Callback+ k, _$ y7 Z' }5 C# X( b* H6 n
class CDeviceFinderCallback
( o6 u( p( ?- ~ w) x' N( ?: a : public IUPnPDeviceFinderCallback
1 d8 T) Z' f" q$ k3 [( b{# c' {/ ^( P9 p8 x5 W
public:
% ?9 _% y7 c4 q& D- x! Y9 X CDeviceFinderCallback(CUPnPImplWinServ& instance)6 X2 V# L6 Y' |
: m_instance( instance )
4 L% K9 E+ ^+ n1 ]3 Y: M { m_lRefCount = 0; }) o$ s0 Z% ~4 l7 A, K3 W6 I: _6 m
* m8 c# W2 K$ y- B$ G! \0 p1 G2 `. G" V( ^) m
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 M7 a" T4 J0 Z5 {
STDMETHODIMP_(ULONG) AddRef();
! q( Z. p( W8 D! J1 I STDMETHODIMP_(ULONG) Release();
' d/ T( H, T) f! E8 `& X
2 d8 C- }4 U6 a3 u
B7 x) q2 R% {& O3 l8 I// implementation
! W5 J' J: F7 X- v, y2 zprivate:# D0 o( k2 ^) p: Z6 K
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
0 ?; n7 {7 e9 S# y7 a HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, t; X: `1 h/ p' k$ P. ^
HRESULT __stdcall SearchComplete(LONG nFindData);
& ^0 ?$ X( ^- n) \: `
2 |9 N) ]0 J' A9 ~
, c9 w. Q2 m. L& G8 v8 zprivate:
8 C- B; c4 E$ W- y, g) E6 t) e* E; v CUPnPImplWinServ& m_instance;2 o3 U. f, L4 q+ B7 k4 T& m0 J$ d
LONG m_lRefCount;
! p1 k7 _0 o% C8 B};
; c) _+ u6 s2 O+ W+ o$ \. C0 o) c
9 K6 M, D& `1 p
3 x" R* l% ^, L: O6 i' m" h// Service Callback " ]2 q7 R, O4 N0 W7 G
class CServiceCallback, x7 M2 ?! A4 m: J
: public IUPnPServiceCallback) H. A3 a! Q0 h' D1 h
{
) Q( |$ n2 l& ~) F5 _# F) y! U) {public:
' a3 r# e" h0 {9 ^6 _ CServiceCallback(CUPnPImplWinServ& instance)1 X2 n- A9 l- H: W* z
: m_instance( instance )1 N, s; r2 Q" T: l+ j9 T6 V1 H
{ m_lRefCount = 0; }, c0 Z) [2 b% d
% Q& j- D$ t/ y" I. \ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
7 z" \8 w4 j ` STDMETHODIMP_(ULONG) AddRef();
* t; n, X, |' M/ c STDMETHODIMP_(ULONG) Release();
# ^. t( Y- `# h7 |' k! z4 n- W+ v" W. I) ` `! Z5 U# i$ h) y
" t9 K0 `+ y9 V// implementation% S; \! p: p; `3 V5 g3 q+ U3 E
private:. h5 E$ V# O+ Y' ]: W, y M
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
4 ]+ c$ _6 e0 ^" e' W, A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
" J- @( X k/ W5 o; p8 Q# I6 Y- Z7 @- T
: J; N0 D L7 G( W6 G1 J- _8 N$ J6 e* f/ M+ _, ~% A. T- x& ^
private:8 L; i/ Y; g U# n: V8 N. t4 `
CUPnPImplWinServ& m_instance;
2 i$ }6 f0 C2 o0 U2 w. u% o7 w LONG m_lRefCount;, e, C: D2 N( ?( S2 R$ _$ ]" ?
};
1 b0 p4 s, K! H! r8 g. p# j+ Z1 [* g2 x) W( U' c
: Y: p3 m( @) ]
/////////////////////////////////////////////////
2 Y5 }' t6 p5 ]3 f; l, Y# A A
2 L" p8 ]. w3 v& D/ q$ p" i* b0 c+ |使用时只需要使用抽象类的接口。: @) j4 }7 H' V: s
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 y1 b3 i) ]/ `* k0 Y7 a5 L! QCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.- d6 z p8 @8 N. r; \
CUPnPImpl::StopAsyncFind停止设备查找.* X+ V# `( Q( h" l9 |$ t) H
CUPnPImpl::DeletePorts删除端口映射. |
|