|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,. ]# Q: I9 \4 @6 _7 Y8 y7 @& f
* A* X- a( k$ N8 P& ]6 S
) R/ {7 l! ?: E; _' G1 T7 R* @0 f///////////////////////////////////////////4 S2 j! V$ G0 ~/ C9 p' q2 e. H
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.) X$ f" c7 O% ~4 M- ~2 W
5 i0 ]% k7 C6 c, X& s
! {$ s' w. E& x5 l5 @& I#pragma once) C& F$ d* J7 P% |- T1 c
#include <exception>1 h4 I. X; W& Q* s& I, m; S" O2 A
1 O9 S( Z. _4 @+ `. B
* {' ~$ M) K# Z, g3 P" o, A enum TRISTATE{
' E" ?; u- R8 x" c2 O TRIS_FALSE,
! Y p* b& a* N& E TRIS_UNKNOWN,
* P) ^) i6 k. G( V6 J- X TRIS_TRUE0 i M! W7 {# i3 M+ O
};
. x1 b, R" ^: I3 M i) P; a9 P# k
$ h+ Y) {' V+ I4 }8 penum UPNP_IMPLEMENTATION{# X$ Z# \0 X. U" M8 u4 T0 a
UPNP_IMPL_WINDOWSERVICE = 0,( ]+ Y) F. W% i8 q) Z8 S* r
UPNP_IMPL_MINIUPNPLIB,
* J" m3 E6 Q' K% o$ ^' {0 d* f" _ UPNP_IMPL_NONE /*last*/) V0 ~; \5 h3 b$ i
};
0 O0 D: X: [- \! u' z% _( Y0 \4 ^& x* E& x$ K. n
6 `0 R" |' }% x1 y
, X9 C q6 y* N/ Y- W# P% j: o: \8 z8 _, X' i6 m
class CUPnPImpl
2 [; K& W. V$ `2 t6 v2 Z{
" r; N0 Q+ x) R9 ~/ G, gpublic:
% X/ ~; I" e q! s+ M7 L& ] CUPnPImpl();
; l; ]$ l! k2 P! T9 G virtual ~CUPnPImpl();
; z( n5 N7 i2 | struct UPnPError : std::exception {};
. x5 ?; w$ ^; K/ J: o enum {
6 c$ }# S+ S. y @' }9 M0 g UPNP_OK,6 v. K7 ^3 \7 {( k0 ^5 }
UPNP_FAILED,
* q; ^* M8 |; v: v) p4 z8 U% o. w UPNP_TIMEOUT
7 h2 F! G) m# P) I/ C };, J* n3 r+ ]+ }
- ]" K9 p3 k* e9 i1 c, c; }7 s6 M8 Y4 i( k+ c3 ]- J% a+ {" X( U2 V
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;' F6 Q' n* e6 T% d
virtual bool CheckAndRefresh() = 0;
5 | `* c) r. f5 z+ W8 H: N5 s virtual void StopAsyncFind() = 0;
2 q# }) T# t# Q9 }0 D# T& I virtual void DeletePorts() = 0;5 z+ ^2 p. l, K3 A5 p
virtual bool IsReady() = 0;
2 `$ Y8 V/ ]1 e) z8 ` virtual int GetImplementationID() = 0;
& _; P/ H) Z/ m& U H0 t - o# B9 t& i5 ~; Q7 t4 E4 F
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) }7 F' T' |8 s3 Z' o: S. U
: e! e ]& O. L9 A$ t" O
: }0 A7 d6 ]3 `; C: t: V( r
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
( B4 a5 E& J- V, h& L+ B9 A TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
, R& r, H% W8 p( a+ b0 s uint16 GetUsedTCPPort() { return m_nTCPPort; }
, H% \/ I* F8 f# h uint16 GetUsedUDPPort() { return m_nUDPPort; } * }3 `# s4 w3 K# [" ]# p& S# r
* R8 S2 P9 |. s
d9 Y$ h1 [6 ?. ?6 ]7 `// Implementation
% y" z, p3 U" h1 j' Q$ C* s6 x) v6 fprotected:
0 c7 M! i) a1 x. l volatile TRISTATE m_bUPnPPortsForwarded;2 x. k9 ~" h# l) I i8 f9 N q
void SendResultMessage();
* @! r6 u& S9 i9 F- { uint16 m_nUDPPort;$ Z3 c/ m! @/ C& G4 `) s+ V# i$ n
uint16 m_nTCPPort;
) b- g, A( ?# I. b" _ uint16 m_nTCPWebPort;
m' w4 ?# i0 F bool m_bCheckAndRefresh;- y) l4 r- ^# A) _. y+ {: a
$ t8 J8 n% E1 }4 Q2 U; P8 U5 M) B/ B( o
private:3 g/ e6 P7 R; m* d" U1 b6 ?
HWND m_hResultMessageWindow;
8 P1 l2 C( b q7 F" k& B UINT m_nResultMessageID;
) _2 I1 m: r. M$ @! B" f7 m9 u
: Q7 b+ y: y/ q) s$ A- E/ \6 e, W# J$ ?! d) I9 v" {1 M% v; f1 e
};
( i( w6 i" b9 V- T5 c j$ A& o# c" p y' R$ z8 a1 q
: {5 B3 V" K8 j9 B( R% U, |
// Dummy Implementation to be used when no other implementation is available
9 ^3 c0 B' O) e0 o$ ?1 r4 rclass CUPnPImplNone: public CUPnPImpl
7 @9 L# M9 k7 y, z- I, L/ L{& l, e/ b0 M% Y' y; H) `
public:
/ K- S0 R( p2 T1 t6 C virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }/ T: c$ u2 }+ M! B: q
virtual bool CheckAndRefresh() { return false; }% T4 o4 t8 |+ o4 N% P5 w3 C0 ~$ _
virtual void StopAsyncFind() { } M' u: ^2 A& J! B9 u1 j }( _9 `
virtual void DeletePorts() { }
7 { Y7 r4 c* Y* T1 j+ `; V virtual bool IsReady() { return false; }
& S/ M* ]! Y- Q9 Q S- o: f" p- e virtual int GetImplementationID() { return UPNP_IMPL_NONE; }9 R6 }5 L0 s. u# _, X) Z
};# n" d9 e- z, J3 j3 u$ {7 }3 ^3 z
! ~/ D* P! E6 o s+ M' O6 q! H* N: P0 D7 Y" L5 _- [
/////////////////////////////////////
" e+ M( L* a6 @% |2 g+ @6 c//下面是使用windows操作系统自带的UPNP功能的子类9 a+ M+ ~7 [8 z$ m' K* n% T
4 H& p. f$ D6 D- r2 f8 e' H' @& h3 c+ ^! t1 a* s
#pragma once( R+ z# C# r* `. _8 X
#pragma warning( disable: 4355 )
# ?/ Q/ Y% ^# n$ \$ E# R2 A# _5 w9 b4 k' N+ ~+ E+ c/ c/ T
; B9 U" ` A% W
#include "UPnPImpl.h"
8 y K0 z: \& r- [0 d#include <upnp.h>
4 }0 C; s, S7 L$ Z3 k#include <iphlpapi.h>( `' g0 C7 m- u) T5 h) I
#include <comdef.h>
& J" o5 ]6 N$ R+ l& ^+ o; f#include <winsvc.h>
Q1 y" }! |- @0 _5 o$ o% B, ], z& I; S* i6 z' Q, N( b; ^4 [1 t
. i) z* X1 U5 T+ W! O; }+ G#include <vector>
0 l' z3 J. A# ?7 j0 [! s' Z#include <exception>8 @" o$ E* r8 g% W# W7 g6 a
#include <functional>
0 j# h6 Q) B' ~9 S0 }; q
: r2 k7 l: N) W! u" a5 W& q
/ t2 A; w# f5 X9 \
7 L# t. c- ?4 }- |: j6 D" [6 M( A2 F" u8 r* D/ X5 Z. z3 B7 q# l# n" a
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
$ L/ P+ B" p% } L) V2 u- ftypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;; d7 Y, }" b; f, Z0 ?; o" A" d
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;8 T U3 N" p. m5 n
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! m3 f5 T" |$ [% v' e8 ~. Rtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;+ m) T8 o4 @. D
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( w0 _; J) Y% `! Ntypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
- t: Z8 } u( T) O! }2 Y$ Q L5 |& h0 D: O: H9 w* S; ?
( o* q4 v* {0 n' |% P( q3 |/ C' a
typedef DWORD (WINAPI* TGetBestInterface) (
' y" |# a6 I0 o IPAddr dwDestAddr,6 O3 M; S" \( G3 e* p8 x: n
PDWORD pdwBestIfIndex
7 C' s) A0 b* k6 ?, B! n4 I: P);
; v/ @( E! R/ p. b
: N# N1 j) M7 r5 k3 _* F8 o; m% d7 e; M6 C- P+ I
typedef DWORD (WINAPI* TGetIpAddrTable) (
$ x% R/ U8 u C PMIB_IPADDRTABLE pIpAddrTable,. g9 I# E! a: I9 Z% f% B& P
PULONG pdwSize,* J/ ?. P: ]! q1 @9 A" D
BOOL bOrder' d9 k: d8 D$ {; N" y4 i: ]& F
);
. p6 ^0 u& c2 q3 C, K; U) T" s9 v
, z" g: p2 O" E5 x: U6 ~$ j& s6 h' B" I
typedef DWORD (WINAPI* TGetIfEntry) (. f @5 T( \! f. p- w
PMIB_IFROW pIfRow8 M3 w" Y" k& E- [7 m! n
);8 g" d8 U1 w; h4 ~( |: h' [
& F+ C! B l% D* g4 M
+ I8 k3 u) m* O- [ ?7 p3 K' |# m
CString translateUPnPResult(HRESULT hr);: [* x& s3 g, Z
HRESULT UPnPMessage(HRESULT hr);9 J! O. Q2 A) E2 E/ Y1 O
" s7 H5 L" }5 @& s1 V6 i0 v
7 }" a3 N4 N z$ Mclass CUPnPImplWinServ: public CUPnPImpl
8 t& l* Y8 s$ z5 N{) A6 o a4 M/ {5 W
friend class CDeviceFinderCallback;
, V% j$ N; a; n; p- m6 C friend class CServiceCallback;
! y, g9 V9 v4 t* }9 x' @, z// Construction
x( j; m: {4 h5 kpublic:
" h4 K8 f- u; I: E, u Z6 h virtual ~CUPnPImplWinServ();
8 k) t( W$ N4 i* S( N) n CUPnPImplWinServ();; Q2 [9 x+ S& k' Y
& T6 s- T% V9 L7 Y5 t7 i( D
- P3 {, V1 F( j+ Q: J6 j
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
4 N) |8 \) Z+ w8 b( N5 q virtual void StopAsyncFind();9 G) m* |& h: S! [# M7 ]
virtual void DeletePorts();
0 K- G: w' u; y) e# v4 b virtual bool IsReady();7 m7 B- ]6 F N. r: @
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( S' ]* Q! G- }' A: i9 D) m
/ P! O2 d: d" q5 u' a8 L3 d: b9 a
+ b) H" u7 j* {' }$ a // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)' s$ F9 S1 J1 y1 Y3 b1 {# w
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
" N K) M A6 j9 t) O virtual bool CheckAndRefresh() { return false; };
( W$ ^6 |- Y6 u+ Y/ c, L6 Y" S O( L/ F5 x
7 Z' _; v$ U, A2 Iprotected:+ }2 V7 N0 W d% y) O/ l; [: ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);" ^6 U% G6 r4 @/ W
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
( Y. r5 B/ |8 Q void RemoveDevice(CComBSTR bsUDN);
5 g F; A0 G( X* r' y bool OnSearchComplete();
2 _% h* h! P% {* k O void Init();
6 [' r$ D% z+ o7 ]
& l3 [5 W3 Y- I P4 g8 k( R# ~2 ?; N3 p# X" \0 i5 D, u( L% f# X& w
inline bool IsAsyncFindRunning() " G3 I6 W1 b# u/ X, ~
{# C7 d+ u# r* D. z5 l; J
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
& W/ A7 V7 b4 C5 X. M6 j# }$ r {, F7 f: u3 v7 O& |
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ Q3 i9 \9 f$ U
m_bAsyncFindRunning = false;: G y- d/ S! E8 L1 W3 [. N
}
5 ~ D, e7 {8 h7 ?, j+ b+ N MSG msg;- Y2 V2 ]/ K R q% |
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6 {* o* l0 `: @: `9 v4 D5 k. p! a {
9 p/ @* V( \+ I( T TranslateMessage( &msg );
& z( X6 n1 P8 R n DispatchMessage( &msg );6 A5 e8 d: i v8 d8 l5 C! Y
}. |3 Z- | O8 i0 a6 g
return m_bAsyncFindRunning;
& j( t3 e1 s" W }( O) R5 o6 ^. D) W" K$ k
- N7 x1 V+ }! m
7 }5 O' m5 N6 `' b: s# Y9 _ TRISTATE m_bUPnPDeviceConnected;$ |9 n3 @$ A6 \, _
8 z3 h6 M5 k5 z G' `
1 Q* P8 J9 { c- v
// Implementation+ q+ c/ f% t# V- g7 J
// API functions
: R3 w, Q( Z# Q o& V6 m3 ~0 n* D# H SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* h+ ~. o. A/ y& I SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
; U- S6 X( ?4 X# I) {. @5 \ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! H( X( D0 g. }5 u8 B7 B N; i5 _ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
: C. t: U3 b, b& n/ C" D7 _8 z+ k9 Z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);) p) u+ r3 l) K, b0 x, W7 G
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);5 L$ R; e$ v( c; s/ Q. Q
6 X! Y# W/ h( S
- J- ~! L! G9 b" G TGetBestInterface m_pfGetBestInterface;
) ?! M! t3 f6 @" f; C7 P: R TGetIpAddrTable m_pfGetIpAddrTable;
! |* C. I: G) |4 x; f; A TGetIfEntry m_pfGetIfEntry;3 [! R$ k" ]5 i, B% ~% s6 J8 o4 u& M
4 c- z) u$ p; Y3 U8 U' v" {2 \
5 s! A1 m& ^+ e% x! H
static FinderPointer CreateFinderInstance();
* c( e& `* n, C2 T+ t3 N struct FindDevice : std::unary_function< DevicePointer, bool >2 w( _6 j# I- l9 p: V
{
5 Y9 Z( o6 k( h Q/ N FindDevice(const CComBSTR& udn) : m_udn( udn ) {}- O" B$ M! b) Q9 S; j I
result_type operator()(argument_type device) const
M! u/ B- n+ R" m7 w {: f* ?$ d& J; @' i; V# M
CComBSTR deviceName;
1 d( G; D& ]9 l1 X& d U HRESULT hr = device->get_UniqueDeviceName( &deviceName );* o" a1 K3 y" N) E# k3 q% z
) U# ?* d& l* o* U5 E& |2 W& Z# e
' u, Y1 |# [3 } l if ( FAILED( hr ) )6 ]0 R- i6 \) f; x; g/ s+ ~0 Y
return UPnPMessage( hr ), false;
+ \9 }& i8 l+ H+ O* K8 D/ L" Y: i3 y) t2 }4 {2 \3 H" r$ k) b/ \4 P3 n
[3 P9 B' J- r% \( x return wcscmp( deviceName.m_str, m_udn ) == 0;
, ~$ h* v" l, r- d! @2 N }
8 M1 ]) c! s4 a& Y" X; N& i* Z CComBSTR m_udn;# s0 R5 Q3 c% C% }6 x
};) g' M9 K: [5 r1 n; [0 [
3 W r$ ^8 C7 ?, U- D6 o' a
void ProcessAsyncFind(CComBSTR bsSearchType);* b# u, F" A1 N5 q& M
HRESULT GetDeviceServices(DevicePointer pDevice);9 l+ F* @0 D& ^7 z
void StartPortMapping();
# G# D# R8 |* R8 P: t4 |) u HRESULT MapPort(const ServicePointer& service);
2 P7 ?- G, b" o/ _& o void DeleteExistingPortMappings(ServicePointer pService);* q; I6 B _: }- _
void CreatePortMappings(ServicePointer pService);
) b4 \+ D% r s& s1 T) ]/ J( ` HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ O! a: Y6 G7 z5 \) A3 @0 q
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, - o4 Y/ W5 c2 s- P! |, L7 a
LPCTSTR pszInArgString, CString& strResult);& R9 W! ^8 Q! m: e) o: p
void StopUPnPService();
7 E+ H0 a* S( Q6 N2 n. P4 u2 |" r0 U/ k
; y' m$ m& h) W$ G' o // Utility functions
" q: \: G. R1 Q HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);, i/ r( I2 l( x" t) c, d
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);0 D- W5 ~) w7 o1 d' c2 y! T
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
3 b: a; @( J. |. Y9 x& S void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; O' S: W+ Q$ \+ {. K
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);) y4 o9 B9 V/ D) \
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 t6 G& |: K# ^$ D1 x9 X& L CString GetLocalRoutableIP(ServicePointer pService);8 P! A6 \& s8 P% t* n7 c, y
' E3 F. B6 `2 F+ a7 P! I+ l
( B; x+ n" l7 g( y+ E# q4 P1 z1 {2 i// Private members- Q- V3 l) f: U6 V4 D: b
private:
( [8 ?4 H4 I0 ?$ W0 r- ?5 u DWORD m_tLastEvent; // When the last event was received?
. N8 E9 ]) `9 D! \ std::vector< DevicePointer > m_pDevices; \# S# r$ f% `% W e
std::vector< ServicePointer > m_pServices;; f. R2 h1 H1 s+ C
FinderPointer m_pDeviceFinder;+ C& \4 o) i3 @8 |0 s* n
DeviceFinderCallback m_pDeviceFinderCallback;2 h3 l' B- ]( E5 K( G6 y. i \; R
ServiceCallback m_pServiceCallback;$ K$ _2 v0 z8 p! ^, Q" O5 ~
" L) f5 V2 k- Q& D2 y X4 Y$ a- ]; I- c, g; |
LONG m_nAsyncFindHandle;
, A5 T' {% b+ Z$ B0 m bool m_bCOM;
" W3 F7 @: g$ v3 N$ h bool m_bPortIsFree;4 x9 l8 e2 W9 v+ B/ _
CString m_sLocalIP;) b/ @! [: t0 P% }. s# ~
CString m_sExternalIP;
' y0 @0 v1 T+ t& ~. C& g% @+ B, e# X% ` bool m_bADSL; // Is the device ADSL?% Z- z& g$ ~' B2 S S
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
K$ L9 O4 y) r3 Y2 @ bool m_bInited;
* L( @1 x) n9 J) b' V: U bool m_bAsyncFindRunning;
. \" \; [/ f0 @/ ?* U5 ^) N HMODULE m_hADVAPI32_DLL;
7 R% q4 `0 n: d8 |+ d. U' a G1 a HMODULE m_hIPHLPAPI_DLL;
3 a; W+ e9 ^* v$ U bool m_bSecondTry;
$ D' f: [! j( G" k bool m_bServiceStartedByEmule;
$ ~, i; a3 A# R( _ bool m_bDisableWANIPSetup;: P; D. f6 r1 F2 Q2 V4 ?
bool m_bDisableWANPPPSetup;& h: f7 I0 z* \$ G
1 n* @3 Z5 ?7 ^- l# H! v( y# ~' A6 ]. D; H3 O6 p4 g
};7 z7 R+ ?2 x4 b' i# a
0 f" _! X ?; \: n. G0 U9 b; p3 A; ~2 p. R, J0 a
// DeviceFinder Callback- i# x& \6 c: `: C+ i! A- Y! [7 _
class CDeviceFinderCallback) t8 D" d" k, A; A2 b( A. o1 O3 p2 {
: public IUPnPDeviceFinderCallback9 d* I1 j* z0 d* Y3 o* N
{4 n/ Z' M" m3 C; W- c6 |/ n
public:7 L' r9 a h ], y/ A% ?2 ^
CDeviceFinderCallback(CUPnPImplWinServ& instance). a7 E& H* O) Q( A0 ^- N! G O
: m_instance( instance )4 F; D; M8 K0 y* b6 f2 m
{ m_lRefCount = 0; }
9 h) |% _$ f5 F5 N4 A9 S( Y/ j2 @8 g# i. F( x% e# B3 E
* |/ R; }. Z! }$ Q3 L STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# q P G ?6 w% s STDMETHODIMP_(ULONG) AddRef();; ]5 C3 {$ s! i5 l, p+ Q9 C, U) k
STDMETHODIMP_(ULONG) Release();
4 C' N+ Q, W8 I5 P3 A7 J- e( u. p4 a' U# r
+ z, u$ P5 y5 i. `' ~- l7 E
// implementation
+ l/ r# I# C+ q; [' I! Q( m Iprivate:
/ y9 W% b1 _4 N$ ~ M# U; S& V0 E$ W HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);* W- h/ i: C: j" o# ~! ?& u
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);; v) ^- ~0 N; B5 F
HRESULT __stdcall SearchComplete(LONG nFindData);
- }3 E, h: A; y0 L
, `* H8 ~, n$ q: b5 H' D( @* b" U9 j
private:
: N0 S% N% c3 n9 p9 T. j% [7 V CUPnPImplWinServ& m_instance;( {5 w6 x1 G: f! H1 _
LONG m_lRefCount;
8 X, C6 ?7 n# v+ u" T2 ~0 c};
5 q( K6 d9 f, Q* u
" y9 z0 e5 w7 n3 B4 r, ^0 x2 Q% |! y0 Y7 H! b9 C
// Service Callback 3 } U4 L" m% w9 r( |
class CServiceCallback
# v& A. H2 ^) H3 U7 |' T7 n : public IUPnPServiceCallback
. o# d5 p4 q5 | K{
/ ^. \/ K7 h; J! E# Q0 c) U( \6 J$ Ipublic:
" z& Y" U9 B* l y CServiceCallback(CUPnPImplWinServ& instance)) h% s( k9 K! S+ E" ?6 T
: m_instance( instance )
' {' |* ^# x& W) {: Q9 Z) Z0 a { m_lRefCount = 0; }5 g1 _! Z; j3 X! w- G6 y5 T- P* ^) p
2 A% |+ p2 S1 | E+ s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, u3 F0 D( \/ ]7 \/ P3 ^- A STDMETHODIMP_(ULONG) AddRef();5 f9 Q6 L8 t1 M+ s' e
STDMETHODIMP_(ULONG) Release();2 @2 o6 M2 p5 \/ S+ p9 ^3 l+ m
; V" ?+ a0 c8 a
. {8 @$ ^# x' s, a9 F3 y# k9 a, {# B* m// implementation
( F' V$ h* x" s" B" Jprivate:
7 t% r, F% N6 i+ p4 m/ P HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);: q9 c* s7 x, F/ C/ w+ s5 }( U
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" Z$ ~2 z s% J" T$ \ F
4 f% N/ K/ e! S1 U5 Z" F, K. h6 W9 I. j N( q: `0 z% d, S4 K+ ~; `+ C
private:1 M8 m2 t9 C z D- L5 Q g7 ]
CUPnPImplWinServ& m_instance;( D9 q9 O1 K. q& L$ p* O8 a/ Y6 v
LONG m_lRefCount;
' J; p! _1 H" k* o& E, l( Y2 \};
' b' n+ _6 K# z+ B
1 v8 H8 W" ]* `$ _5 P1 Q$ d, _3 {: W" O# _+ _" a" W9 L
/////////////////////////////////////////////////
! V+ k, p. ?; w2 {# O* V% j2 S N
4 U7 V; x4 K+ q; k5 C0 \$ T4 g9 b& s+ u; j' Q
使用时只需要使用抽象类的接口。
d) ~% Z$ E6 s( M! j0 mCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: S$ ^, g, l/ t2 d! I$ [
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% U! {5 h& K; o) o: o; Y/ d' J& U- MCUPnPImpl::StopAsyncFind停止设备查找.
/ W7 u# j& _+ V3 z7 mCUPnPImpl::DeletePorts删除端口映射. |
|