|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 c$ Q( B# k8 c D% W
5 `5 J I7 k* D) |, y5 T1 X/ j$ G7 ]& n& }
///////////////////////////////////////////6 c* X% \/ c3 d7 `
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
( {7 _: X( S2 v# C! E; t
& J5 S4 v7 B9 R7 I) ?( Q; V8 X8 ]3 G" z
#pragma once6 ~3 H0 l$ f4 y; b" k; e+ @6 Y2 V2 g
#include <exception>7 Y' v# O& P8 y1 ~) e+ K* d7 |
" ~. a. ?: p8 M3 E# L& @. I3 J& g7 L- I
enum TRISTATE{6 G6 _( f t( s" H
TRIS_FALSE,
; q, q0 D" w; {4 N0 e% q% j* a TRIS_UNKNOWN,( q% ^+ P8 }7 a3 u& [6 \3 l
TRIS_TRUE& t/ }5 [1 s4 D; g' r/ ]5 K5 R" k9 ~
};6 e8 d* m" a% B D( E9 Y p
7 `5 x5 \) q9 E8 y9 s6 ]
: m" `# R* Q) ?
enum UPNP_IMPLEMENTATION{0 I) y% t9 r: Y6 D+ { e
UPNP_IMPL_WINDOWSERVICE = 0,
8 K7 D, L+ e, x( ~, v3 c5 @ n UPNP_IMPL_MINIUPNPLIB,0 g! k' X) D! E- b
UPNP_IMPL_NONE /*last*/
- L* l5 [' X5 o; ]5 G0 v7 k1 x};
; m9 v0 n/ F: n7 T/ I B5 G% P6 I6 e- w. N5 B1 Z; X" F# S4 \/ L
" {6 m1 }7 u$ ]
# c/ R5 j3 |7 Q! z5 ~; h% ], Q1 Y! M/ x5 E( T
class CUPnPImpl
( z4 n( w+ v, T+ ^{* S8 p; L) s' L4 y7 S2 ]+ y! r
public:
7 G# [8 Y: b/ C% w! ` CUPnPImpl();
2 n5 [" D5 Y7 s* ~ virtual ~CUPnPImpl();
% o& z3 X9 F7 a }! j1 l0 g& V struct UPnPError : std::exception {};
7 y8 y& p6 ^- Y5 d+ J% y enum {
, o1 \; M Z. Z/ X6 ` UPNP_OK,
! q! J6 o0 w2 [0 l1 z UPNP_FAILED,
! D8 i$ _$ w3 u& M) _/ I6 V UPNP_TIMEOUT
7 T* W3 Y" i6 g# @5 t5 U };8 i% H- v/ t2 U! k! O! I# P- q
* [( [* G0 F/ H( Y
5 h) `( L" ^# g8 X& u virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;' }; T+ X, o f8 A# c0 O$ x
virtual bool CheckAndRefresh() = 0;& C+ ^5 u' G/ F0 J {. k
virtual void StopAsyncFind() = 0;
2 f: K7 f7 x, W% [3 O' j$ ? virtual void DeletePorts() = 0;7 C# `" f$ W$ M0 A3 `" i: Q
virtual bool IsReady() = 0;
0 @; l8 t' Q9 |" s) S: g8 r virtual int GetImplementationID() = 0;
- V& T3 n9 Y& s: ^; ?7 h
, E$ e! Y) {3 o: W; p$ o void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping& e2 d& A9 E& b6 D
' @# m* h4 t# V% k6 m) T R6 l. i. w) |
void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 n3 u- K! n, |6 b' O X9 G
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) R& D1 q. \6 B' b F' U; N! W6 F" @' S uint16 GetUsedTCPPort() { return m_nTCPPort; }8 u7 Q: W2 d; d+ Q9 F6 ^- Q4 ^- Q# u1 L
uint16 GetUsedUDPPort() { return m_nUDPPort; }
3 Z) L, p6 J$ x- t" w$ [9 y& r X$ }4 N- `& F$ r
. r" R/ _) E# ]7 l% W0 J
// Implementation1 S8 g1 E% h$ D1 B1 ~
protected:
7 s) D% ^8 g2 A5 H5 |. A0 j volatile TRISTATE m_bUPnPPortsForwarded;, R, K; e* j" }
void SendResultMessage();9 j- c; B, n# ^9 T. @
uint16 m_nUDPPort;
$ w# [/ J! ?7 M: J( p uint16 m_nTCPPort;) k% _. i1 H3 }3 v
uint16 m_nTCPWebPort;
+ _; e4 j, l1 _5 c. X$ ?: D. l bool m_bCheckAndRefresh;
3 k9 f. t# Q5 ^" @- N
. v' w, ~: X r0 w- x& s
! d( d( A9 i( E0 Zprivate:
2 A" @4 A& `: d% H! `. S2 F' H. z HWND m_hResultMessageWindow;
+ c$ Z1 q* H% v# z4 q/ G UINT m_nResultMessageID;
! p& B/ j2 ~* O0 l" _+ Q, R$ G- _5 i. Q/ G
" ?3 w/ K4 m4 M0 f6 y! Y% @) c) Q# b
};- x# ^3 h- X& ~' J1 }/ p) z- w
2 E C. t9 B, C: Q$ u4 _& [
3 D. x5 r- K7 Z7 l3 }+ d// Dummy Implementation to be used when no other implementation is available4 w, r# [( k/ n% ^7 M. J
class CUPnPImplNone: public CUPnPImpl1 p* G* S* x2 P$ [
{) V5 k; n$ ~% Y* q6 C8 E4 ]+ f& _' _
public:
8 r. H9 Z* o, t virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }. e% }9 ^2 Z7 [. X' z/ d. h, u2 d
virtual bool CheckAndRefresh() { return false; }
" K4 s' ]2 A& H# P virtual void StopAsyncFind() { }7 X; Y& j' X# W" I9 K+ w& [
virtual void DeletePorts() { }
( F6 [6 D" }% H virtual bool IsReady() { return false; }, W1 E: O) c8 S3 h. p! e; Y) V! e8 d
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }, [# I0 F$ [* r- {
};4 f* v8 s% R. s( Q
2 K" `% L1 D' `2 Y6 s
/ s# j6 f: ^5 ]( y
/////////////////////////////////////
9 s- u+ `& u& O, _ D//下面是使用windows操作系统自带的UPNP功能的子类2 y- [" h7 s1 u- u2 V! @2 _
0 ?# U5 ?, e2 Q2 |
3 L4 { v/ |+ L$ J. Q5 k- Z p- k#pragma once
# g0 P0 A& j8 C4 I#pragma warning( disable: 4355 )& ]: M6 W- P: R
2 M ~: T- q1 v6 f3 D8 s0 d
5 G6 v2 E$ K' J5 g; _3 p/ s#include "UPnPImpl.h"
v) _+ \; w3 @7 J; u0 ^- l. c#include <upnp.h>8 k! [. J3 r- a8 H- i3 g3 E
#include <iphlpapi.h>
9 Q1 y; e/ q3 S5 i7 @0 g#include <comdef.h>6 B# s/ p/ F6 H6 p, t
#include <winsvc.h>1 Y! E( F% q( C
$ j9 a* E; |. d7 ?; J4 S
- J- [5 Z4 R$ x7 N' y, G3 t1 K#include <vector>
, b" O7 ?* j, Z" X; j7 t#include <exception>& }" t, p: O; S( R1 _9 q" t
#include <functional>
0 ]* ^) l- `/ V1 R1 e) C8 S: L
5 `6 N9 N* M) T7 n7 x
r! w, ~# Q3 W
5 e# ~- v( L* B, K8 P4 N# p; l+ M% n7 ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;8 X$ O0 L0 z/ x; T4 T
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
7 s# g" ]! c4 s: V1 Vtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
" G/ z! c/ T* A! I$ D2 N0 atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
7 J" i) m, c E1 |* `4 ]8 }typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; A- O- \9 U [4 u4 N! @4 d2 }
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 N3 _4 T$ R! W& k+ b# j! ]: ytypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
" B! Q. ?) q5 J5 m% Q: I0 ?
% G5 C; z' s! p! f1 t7 F* \6 c$ j% g8 {) Y5 o/ p- T% E' K
typedef DWORD (WINAPI* TGetBestInterface) (+ I8 A: i+ C. K) m9 |2 M! E2 C
IPAddr dwDestAddr,0 p& U% H2 t7 X- ?* p
PDWORD pdwBestIfIndex8 P+ y( U, F* `) Z' m
);" S2 u$ P+ O+ Q: G, H; |
8 `* S: }9 ^6 ?4 R i6 j
B' T0 ~5 B( L, Z+ Otypedef DWORD (WINAPI* TGetIpAddrTable) (
) c2 Q$ o8 z+ e3 _ PMIB_IPADDRTABLE pIpAddrTable,( x' { U( }+ g. T* h
PULONG pdwSize,1 h$ Y; B1 g9 u+ H' [
BOOL bOrder- ^" }2 }0 C' C# z: O1 w
);3 A' p6 u' o$ P' x
: n5 y; ?: ~" t9 O8 ?' B
5 }3 f: n. f, w& ]& t) ~6 t4 Stypedef DWORD (WINAPI* TGetIfEntry) (
, g' _. C' {% m' { PMIB_IFROW pIfRow
: `' T# z& k0 p9 R* r& p);
# C% i5 m% H f* |1 z+ z2 C
" h0 Y2 h) @" a1 \- i. [# k5 Z/ [" x
( s; K3 L$ d1 ECString translateUPnPResult(HRESULT hr);
Q5 S( k( J5 Y* D* Z; ?0 kHRESULT UPnPMessage(HRESULT hr);
& Q7 Q( J ]5 S2 S- s: j8 w. [
5 e" H: Y) Q) d9 w' Y& G4 p5 H) r
, ^ ~1 @8 P. ?% \8 |class CUPnPImplWinServ: public CUPnPImpl
2 f2 O/ r- u9 W9 b- {. c7 G{
4 P" w' C) n/ B- l friend class CDeviceFinderCallback;
* m* s8 y$ `/ R friend class CServiceCallback;/ w. L- E6 i) L* f9 O
// Construction+ y' v& c: j: n
public:5 G. G, t$ P r9 o
virtual ~CUPnPImplWinServ();$ s& w- a# V" E6 X
CUPnPImplWinServ();6 I( K! a+ V+ t1 q" m4 e6 |
* l: }& @' q5 s V6 i* w
$ w4 m5 X) O% t z5 N1 p: y virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } N: v1 m; f+ y* h/ t4 l, C1 r5 z1 U7 X
virtual void StopAsyncFind();
" {9 V! G! H9 n+ x1 M8 e virtual void DeletePorts();
9 t# V: _7 v% C1 A) Q" q virtual bool IsReady();1 F d2 c M3 _; V6 {; ~8 T
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 o) P. T/ x3 ~5 L
0 D9 ]4 c4 W, f* U
( y2 O9 n* Y' o4 h+ K; h; e2 I$ a // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
: {+ ]3 x/ Z, _/ D/ \& }' c+ N" B // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
% u% A/ J& [" p: F+ N) a virtual bool CheckAndRefresh() { return false; };: N: S! Y3 a! `2 }6 @1 \
2 |% O9 h1 M8 ~5 y" @& R, g
' s5 V0 l3 K' u8 wprotected:
7 _ j( J7 l- O, j! f void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
2 |0 x2 }1 A2 w8 \; O: Q void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);+ n' b& y) C; x X. \4 d: H; S
void RemoveDevice(CComBSTR bsUDN);' a0 H! u$ t- b* c, s2 ~( k5 S4 h
bool OnSearchComplete();9 E1 H+ ?8 l& ~6 {
void Init();
7 c: @" @; U# n5 n/ D# j# f' N* P0 Z4 f8 {9 m1 ?4 f* R3 E
( Z9 R+ B! `. }/ ]* Q
inline bool IsAsyncFindRunning() 9 _6 M ~. x) [6 y% {, J
{
5 K3 f, J8 C' Y6 f* S' w' y6 ? if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )- X' K4 Q9 [. u' ?5 g- o: D
{
& T, t( Y/ N& o m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );' M+ e$ a1 j' z
m_bAsyncFindRunning = false;" {: X% @) G8 ~& G, C
}" B. e& l6 T. I5 n, V7 [' F
MSG msg;! T2 E* r+ a3 G' C. ]0 C
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
5 N8 J2 T9 e. ?. e1 K' _ {0 E5 H. f! v9 a8 F4 X
TranslateMessage( &msg );9 V. W( u. _3 {5 w
DispatchMessage( &msg );
0 z" X/ K, F5 {- Z" k- k }2 q0 T. T, U/ n" k% n
return m_bAsyncFindRunning;6 c j$ S$ X% N) a/ ^) e( O- v
}
2 m+ F* v6 Y! j' D! C* o$ U y0 r. G& l7 e1 H6 k7 O$ q* D
/ X+ Z; u3 \7 w. R; b$ I
TRISTATE m_bUPnPDeviceConnected;
. j5 V# H1 |/ \+ w& G0 T6 ?) Z0 T, U' _
+ v9 r! F$ ]9 [7 S4 H: h7 o& x+ Q7 [. S0 n! v, z4 ^
// Implementation
) q$ |, |& U9 t/ u // API functions
7 ~3 b5 D: d" A. V! p SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);4 w$ J# K$ i2 d E
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);8 K6 x) ^: `% z# c
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);$ N, r% _3 T* }# f
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
) E4 B$ W3 ?9 A+ a BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);; ?, ^7 p; B. r0 ?7 n
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
2 y6 }- V' F' {' r
) G' q$ g8 G5 B# M
1 M# C; v7 H8 m7 b# _ TGetBestInterface m_pfGetBestInterface;* ?* F$ B8 P Z8 L
TGetIpAddrTable m_pfGetIpAddrTable;- |% i- C1 A% \( X- T% C6 f+ f
TGetIfEntry m_pfGetIfEntry;" C8 D9 |8 ]( r R J6 X
+ U2 j( w) n/ @: @2 Q$ n* ]8 C e9 Q
) q5 w) E8 K% o5 a& O2 ~6 p5 Y+ n9 [+ R) a static FinderPointer CreateFinderInstance();
# L; b5 I; g/ I8 B4 X struct FindDevice : std::unary_function< DevicePointer, bool >
; W; x% B( y- ^/ Q; a, ]1 Z {
$ Z( R9 M$ W+ Q7 U& j! W FindDevice(const CComBSTR& udn) : m_udn( udn ) {}% ^0 o1 M' F5 N- o1 d# D% u: h
result_type operator()(argument_type device) const
& e2 L, f; c9 z+ y7 V4 p) J {
4 _ h3 H. j1 i* K/ R5 Z CComBSTR deviceName;
( H; l/ F: d2 \1 M+ o; T/ G HRESULT hr = device->get_UniqueDeviceName( &deviceName );
0 k2 i* _$ m* v, C7 ?6 N5 d( @+ o7 e7 ^' F3 s
& [! R* z* B. }6 G" D
if ( FAILED( hr ) )
4 G" F4 y; E, K" F( J- c! K3 Y return UPnPMessage( hr ), false;
* b$ t7 x' u" m, Y
$ V3 {8 ~" ~# o# @4 P# _$ v) c8 _& F1 F I' K D- s0 T1 B$ k
return wcscmp( deviceName.m_str, m_udn ) == 0;0 A) E) C7 \ L. g6 ^
}* t% ?/ u0 k- v/ M& x
CComBSTR m_udn;
& D4 h$ i: G. X8 Z9 h* i };
& @2 N' C' g9 z" m6 @' e- _
2 d7 u8 R/ V" f; E4 _9 ] void ProcessAsyncFind(CComBSTR bsSearchType);
. S9 o* y) w1 O2 K' z- | HRESULT GetDeviceServices(DevicePointer pDevice);+ X7 q2 r4 G1 E" t6 W
void StartPortMapping();
9 W% C" J8 \( W3 V HRESULT MapPort(const ServicePointer& service);8 K: O( K5 T, ^% `) ?( y- G
void DeleteExistingPortMappings(ServicePointer pService); i+ {* S1 }& r
void CreatePortMappings(ServicePointer pService);
+ Q g: a! Q9 V6 L1 x HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);, y- v0 E5 O( L# I( U0 `- N
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
8 Z" r) C1 z' @ m( q LPCTSTR pszInArgString, CString& strResult);
4 ^! T* U- t% E8 ? void StopUPnPService();
1 X, l6 Z# c3 Z+ ~. r- p% q2 \7 V! I( R/ }9 |" {6 T
+ a4 c) {. P0 X# x: M2 G! }9 I! }2 J // Utility functions9 `1 M7 Y. @3 a; |3 Y0 w3 y
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);* {& K+ c( w! B# R6 ^" m$ H
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
6 d1 x. ~. C0 G5 t1 [. C INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
) s+ w: P. ]5 e/ }' I5 T void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' `% ^# m) Z, f7 @5 e, P; j
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* h* p- P1 Q( k# u% Q) s HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 @9 p* N9 l* q
CString GetLocalRoutableIP(ServicePointer pService); y$ ?" S* [* [4 x; T+ l& ~
0 a& v# s0 {2 J) b+ L7 d. k$ x
+ a. X8 _& c" H* C% `5 W// Private members
! Z) W/ ?1 b/ l- m- V+ Wprivate:
" C& x, ~# D5 a$ P DWORD m_tLastEvent; // When the last event was received?
4 y9 D2 A2 ~9 v3 b std::vector< DevicePointer > m_pDevices;3 I8 R0 J9 r' V/ E( [. m1 H
std::vector< ServicePointer > m_pServices;/ D' u8 j4 R& l( l
FinderPointer m_pDeviceFinder;5 k+ N2 G' H/ l* E8 N& }
DeviceFinderCallback m_pDeviceFinderCallback;8 X% r& [* l o
ServiceCallback m_pServiceCallback;3 t6 W, _$ }! W3 i
% `; h5 B( K/ R7 B& H3 r q% k) F* y$ A& x9 s& i: L1 J$ l7 h6 ~4 T3 d
LONG m_nAsyncFindHandle;
. `+ m0 P+ w/ L, f6 n8 i7 J bool m_bCOM;- c7 e; p( a. F m# M* D3 d- S
bool m_bPortIsFree;
8 N; Q$ M# p: a! U5 D# l' I( ]1 p1 F CString m_sLocalIP;
. C4 B4 X/ W6 L, d4 C/ K CString m_sExternalIP;
8 W% M! q1 p7 t$ X; J bool m_bADSL; // Is the device ADSL?0 W3 t5 ?# F- M4 k$ @
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?/ M8 T) ^0 }3 h" ~
bool m_bInited;
+ k& h. h# n2 K5 [ bool m_bAsyncFindRunning;# N- ]3 v: T- S/ R, a" j
HMODULE m_hADVAPI32_DLL;
; S% V% i$ D& z9 G HMODULE m_hIPHLPAPI_DLL;8 Z1 |- Y2 x+ e: X
bool m_bSecondTry;
( ?# @! _" z; ~' z bool m_bServiceStartedByEmule;$ f c u# _% ?; ]4 y
bool m_bDisableWANIPSetup;* ?- @. w. G9 D t5 F; e
bool m_bDisableWANPPPSetup;0 D' @; ~% I: C) A: k2 L
* d: ~. b9 n9 z: \) U, D
; K4 N3 z# K$ l. \# J$ T4 v};
$ ~& u; E7 g) U. V+ J& d1 V. }) x6 s# f/ m: V5 L6 h& n) f
8 k; I3 f6 {4 j9 D+ {// DeviceFinder Callback
: y+ Y1 t% E; e# Dclass CDeviceFinderCallback! W8 p1 h' B* L! N* H2 F
: public IUPnPDeviceFinderCallback; a0 e5 h- ^$ N# |9 n2 O5 N% x4 L
{
+ n2 m2 }* v. q9 I4 |& G" Z- Hpublic:3 D$ @% J' W X5 A8 j
CDeviceFinderCallback(CUPnPImplWinServ& instance)( T( g5 R' K0 k. q9 ?0 C2 k) Z' a9 }
: m_instance( instance )
, x- `) ?* }0 b2 [4 e { m_lRefCount = 0; } w o' F" t1 T( c, U5 e
* g1 u" R9 ]* D! e. W7 j; y9 W) x4 b/ X: v
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 b4 f$ F2 w) D( g5 ~! Z STDMETHODIMP_(ULONG) AddRef();
0 C9 d* }; n# A" R STDMETHODIMP_(ULONG) Release();
C3 T' ^7 P6 y4 }6 `' N
Z9 d5 Q) w4 {* s+ L% ~7 S2 ^' L- S. h& e
// implementation
& }( ]% L0 L- {& p% i9 p* tprivate:
# w- {! y9 r9 E HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);5 C- q& q* O. Q: o/ y2 T4 C9 o
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);# a* ]7 g# N) a- Y7 T. W
HRESULT __stdcall SearchComplete(LONG nFindData);
+ o% G! t) B, d2 h" J8 l6 s6 a, i4 l; @9 ]' [( ^
# P0 }- ^( O' B* U. N
private:. i& V R: j* L8 X
CUPnPImplWinServ& m_instance;2 y" b! b! w( ?6 d9 h# L* x. M
LONG m_lRefCount;& `9 O& p7 ?# i3 y/ }2 R" L' B
};* x( O' v/ j0 D& y9 Z
: X7 M8 g, I6 T, T9 v
# d5 b& c8 @9 r5 ^6 x: o// Service Callback " }* {6 Z% U) U$ E
class CServiceCallback
4 e3 ^& f9 s$ x) i; } : public IUPnPServiceCallback! Z' i9 |: E$ o9 Y$ l/ B3 o
{
. d& @, X$ w' N/ I: b" qpublic:- Z' d) Y' I8 D( U2 `8 t
CServiceCallback(CUPnPImplWinServ& instance)9 q) k1 d' P5 x0 h! E" R# w
: m_instance( instance )7 k6 Z* M- I9 M+ ^) N2 i- J1 T D
{ m_lRefCount = 0; }' w5 e, L5 l$ T
6 i, x1 G) Y) Y! ]& @4 f' |
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 B ]" n2 F! i; r# d
STDMETHODIMP_(ULONG) AddRef();7 ]- e. O7 V0 r" p- ~. |$ T
STDMETHODIMP_(ULONG) Release();
0 Q, x# S( P; h( f9 _" g4 A1 Z/ C; Q& Q7 O* T
" r, M, Z1 S7 J! r0 g1 q+ a// implementation
4 g6 D5 S0 U: T" z5 vprivate:
" G" K7 g! L7 H3 ~ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
( S) S& i5 m% K0 A# y4 T8 H7 ]' I HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
& t* M$ a5 x1 [# x# `2 N
1 M" n! V' S- @5 t4 H2 b* ^) q# a7 ~, p( Q0 F0 z
private:& E$ `" y% T9 C
CUPnPImplWinServ& m_instance;
% \) I; s0 f1 l9 s% w3 k$ t LONG m_lRefCount; @4 p+ n6 D4 Z0 w
}; w6 y2 H* x8 w2 ^" |" c4 p6 x7 {
8 S! I g! D- w0 e& y& y, [' i
/////////////////////////////////////////////////* B; A! b% C* k) A
. ?$ w" [8 R0 a, D& q- w
2 E0 u7 t+ @# V% y! B' g$ L) O! a7 j使用时只需要使用抽象类的接口。; w% X* ]( ^+ Y: K( [( V
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.8 l) n; U0 |6 G, f1 `
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.4 V. k4 p* v+ ?+ F5 S E
CUPnPImpl::StopAsyncFind停止设备查找.
, j0 J8 V% o4 g2 h# C) RCUPnPImpl::DeletePorts删除端口映射. |
|