|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 M9 T5 Q& e' r( I7 a0 J
# H# n! ?7 m4 b! f$ E
& P. v: I% Y1 H- h5 i; V5 w( U/ {
///////////////////////////////////////////7 W5 Y0 ?6 y; Y8 M
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.: ]% N5 N! }" A5 I, M% ]4 D& @
9 P8 k+ V& U% q4 b1 d9 B: V; \6 V; R
: q; f0 y; N3 x" K9 n- T#pragma once
' m7 x& B( m1 o0 B4 W#include <exception>
6 Y3 \5 y7 }2 w! }+ e! b! \' X e- P3 }+ L
; ~! ]* ?; D6 D" z7 ^
enum TRISTATE{- T* p7 C6 O6 H! {! o" P' y
TRIS_FALSE,
+ ]0 D C! x) A8 V8 [3 \ TRIS_UNKNOWN,
4 X4 Q3 [0 y. r; g& b+ m3 I TRIS_TRUE& f( A9 Z1 t, v8 b' {* O3 H7 a f/ |
};
' {/ A6 e4 K1 b8 v; F% t% w$ p
, g+ n& a0 G) b$ U% s$ v2 \9 i
% w5 r; j* t' ?* H+ F! F+ Z% benum UPNP_IMPLEMENTATION{
: b. e! u( `! B UPNP_IMPL_WINDOWSERVICE = 0,, U+ S: V" J6 J& `" K
UPNP_IMPL_MINIUPNPLIB,4 p+ ^' a) M% P; R
UPNP_IMPL_NONE /*last*/$ V4 _* ]. \& r2 q# G
};# D+ a7 e" y9 A; A
" x- U& B; z( c/ ~8 d7 \# V
! w$ A, ]0 D( J4 V7 d6 J! [* r2 D [8 k3 [" P
: x) W6 L8 \: T7 r' i; ^
class CUPnPImpl0 }0 m5 O. {! N' y, k) J* i- u
{! a4 i! N7 Q/ B3 H, z: B- Q. L1 Q
public:' O/ i: g# W4 \( F1 V( C
CUPnPImpl();
" h# j7 R, ^6 K* G" ^/ \ virtual ~CUPnPImpl();& I& b0 L: B8 K( H2 F
struct UPnPError : std::exception {};
6 L% w4 b8 _, _; G4 |# p enum {
! ?; n' o/ T3 `4 B& _9 f UPNP_OK,
( A3 K& Z" S9 r: }: U7 W X( d UPNP_FAILED,; T' W9 h8 `4 I/ X" u1 F5 s
UPNP_TIMEOUT
& ^, Y9 X3 I. C' z; o, g; K };0 b, X/ y) u) A( Q0 |/ p
8 X0 n# u8 A( A$ P1 ]9 @* Q& L" A$ h$ `) P1 \: Y2 s
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. v& G( K& p/ g5 t4 Y# v
virtual bool CheckAndRefresh() = 0;
& h4 m o' Y& W7 Y6 T( Y: [ virtual void StopAsyncFind() = 0;! [/ n( \5 u5 [9 t6 o- K
virtual void DeletePorts() = 0;8 J; \! o- \6 }( o, w& Z
virtual bool IsReady() = 0;
6 k! y/ A6 \* g; Z) a) K virtual int GetImplementationID() = 0;$ r: Y+ L$ g" g; o& y* L) m' J
) l/ q, a( b6 \2 Q; h v7 h void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) U$ W3 M, \5 j0 G$ w$ S
1 m. a& O) y5 b7 p. d# q1 X
& `+ U' Q- U% q- _2 u/ X: B8 Z' _5 R void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 L3 O- O* L- P7 J( n
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
6 m; K. M( W }( P! J( } uint16 GetUsedTCPPort() { return m_nTCPPort; }6 l* {: i' o9 B2 r* K
uint16 GetUsedUDPPort() { return m_nUDPPort; } ' t2 |, J) w; u' F
/ Q( q' u+ D s( G3 \) m" K% g! ]8 o! F) z% }/ E8 Y0 R
// Implementation4 x5 C+ n, ?; L, X7 g6 D7 v
protected:
4 o; h4 }5 M* d volatile TRISTATE m_bUPnPPortsForwarded;
$ A# Q4 r) o2 l, {1 n4 T9 k( a* I void SendResultMessage();& D: v0 C; o3 E. ?; _ a1 g
uint16 m_nUDPPort;
7 j2 Y. Q {9 h8 Z* ? uint16 m_nTCPPort; S5 \9 { C- `$ g# n5 @
uint16 m_nTCPWebPort;% S5 b" R6 z3 o& T9 {, r n* m4 d( G
bool m_bCheckAndRefresh;* T+ C' O; q( {5 x1 @2 [2 s: [; P
1 k7 q8 b' l! g9 @# J7 q) i/ V Q
5 d( j n7 {" i) o* t6 k4 Q
private:
* L, U4 N! m! I HWND m_hResultMessageWindow;
# J s9 k8 |: [4 @$ m UINT m_nResultMessageID;5 y$ c3 C7 d- M
9 a, P! h) o: Z% |$ Q8 l1 S4 w
* @4 ?4 X7 H: g0 |1 L0 x
};8 X0 J+ I. S6 L9 @! K
) Y5 L+ ~* T% w5 _
: F, c3 k! _7 n3 N( W* s _/ B. C
// Dummy Implementation to be used when no other implementation is available& v, F& f; I% M
class CUPnPImplNone: public CUPnPImpl
: L8 {( {6 Y+ j{6 ^( D% s/ c" U4 ?" V
public:
, S2 _/ T( u0 K( V' @; `4 ~ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }, m) ?0 O6 `7 t$ G! c X
virtual bool CheckAndRefresh() { return false; }8 i& M7 V% O% b- U1 E: `
virtual void StopAsyncFind() { }1 V) [8 i, V X4 O& t8 G, d
virtual void DeletePorts() { }
" H% {5 K& } W; z' Q virtual bool IsReady() { return false; }! J) O. P, h. W9 m: C; Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) B0 B/ s+ q1 \" {( ]3 A( |* F};
- `& |1 e; |% k/ q( Q$ l
. z$ H' v+ H% `& y2 |1 i% q: Q/ \5 A1 s2 m' e2 Q9 |; H: h( B+ \
/////////////////////////////////////
8 \) X: s5 F+ E4 |9 V//下面是使用windows操作系统自带的UPNP功能的子类
1 J' i) m( F* d. {- N8 r
4 D4 x+ g8 F3 N8 ~/ M
7 ^- G2 z, y# P' v; l8 `#pragma once. q6 p0 z0 [/ b7 h$ U
#pragma warning( disable: 4355 )
8 }/ t$ }0 g2 ^- x; J8 b5 f1 E) [- x
- t- q8 h) C8 {* P* g0 g" v#include "UPnPImpl.h"
% ?0 P8 l& z( n- _3 x. [8 ~#include <upnp.h>* J4 ~" i% q7 X; F
#include <iphlpapi.h>; r6 y! ^* G' A8 m+ t! E
#include <comdef.h>
0 l- s9 Q, \( [6 K# G#include <winsvc.h>
* z8 N( k% g% H* A+ U+ c/ i& A; Z
7 ^& o* N2 I. _+ l
. Q) c( n/ H1 }. s! S#include <vector>% Q E, Z* W7 U8 J' @/ l9 d
#include <exception>+ e9 |" [& G" M+ G5 D- ]2 N/ s
#include <functional>4 f0 B ?" {* X2 A8 G3 V) z) O) J$ R
! o8 h" e, L& m6 }3 g# {: a
* W W- w) }/ v
8 H A2 Y" M/ a6 I9 U6 |; X5 V
, w+ J% }, h4 S: N- ]# O$ ^% c, e; qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;* O& D$ s( R" V0 X1 j8 G4 [4 t
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;0 T' S; @ t8 J h: G; P' [
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
) E+ t: ?+ l! M9 s* G3 atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 B9 ^; A- U9 j- otypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: F& \( m$ c2 Y5 f
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
6 }) B5 F- v5 S& G7 _typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ q+ l6 s/ P- B% B; b$ B$ ]
, o u$ N% G: r) K( T# `
$ I* J( f5 F5 Ltypedef DWORD (WINAPI* TGetBestInterface) (
4 F6 `( i; \; f( l6 X' F/ F: j! c! u IPAddr dwDestAddr,; p: N9 d6 R! q+ j' Z4 P, G8 K
PDWORD pdwBestIfIndex
$ N5 f$ t p8 @, W* Z4 a2 r( M);, A) o! ^. K: y* z! o
4 ]3 T: X/ q: d, f
9 k$ Q0 M1 c( x+ p P ~
typedef DWORD (WINAPI* TGetIpAddrTable) (6 @8 G s! Z: E8 c T/ l9 g
PMIB_IPADDRTABLE pIpAddrTable,
i+ C6 ?- Z) d PULONG pdwSize,) s# x/ j5 w" {2 V2 u
BOOL bOrder
$ M& H+ `7 _3 r: G8 _: S);
$ j1 ~- e- W w+ R- g" s, ?0 H# P1 p
3 T) T+ z7 H+ X
; n1 J5 O5 O. otypedef DWORD (WINAPI* TGetIfEntry) (+ O8 @, H! W8 n( P
PMIB_IFROW pIfRow" D4 y* Q& L3 T; S/ W, x- D
);
9 i r8 V K2 U3 E6 I8 [( y2 Y3 _, K6 E8 k& g9 y
% r: a6 p2 p6 z v# ?8 D! Z
CString translateUPnPResult(HRESULT hr);
* m: Y& }* V7 K0 o2 }& cHRESULT UPnPMessage(HRESULT hr);
7 m! D* z A- B/ E- {: A7 i9 }! K, S, u! i. e; ?
W" q, ?% {# |8 x9 K
class CUPnPImplWinServ: public CUPnPImpl" m( U2 W5 }9 v3 d) L
{& f( O# L% z3 m4 D* w; G: u
friend class CDeviceFinderCallback;/ o B2 u, o; {
friend class CServiceCallback;+ _- A) I8 I$ [& J) v/ D4 r# m
// Construction; W0 v# M8 A6 [
public:3 D6 w0 o3 f1 Z* X ~) [3 C
virtual ~CUPnPImplWinServ();
; a: j5 P4 T2 ? I/ P$ v CUPnPImplWinServ();) L6 E3 B- i* P4 w
8 w/ q* U0 o9 F! W& }2 g+ N/ P) ^: s! H: m, E# L
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }" P7 s6 V1 u4 H5 E# X
virtual void StopAsyncFind();5 a3 y6 L+ m2 R% f& K" ~, \$ k' }0 N% e
virtual void DeletePorts();
0 Z6 ~6 ^1 ]( o4 _) t virtual bool IsReady();) L5 C6 Z$ F7 W4 I9 m4 m
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
) Y# q8 | Z4 }# x) d
2 Z! v2 X$ N, G. S- v9 _" @ M3 y; S8 B$ @ `" n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% q: _. ~5 q9 {' t8 l // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later/ u% f- U( Z: B4 e
virtual bool CheckAndRefresh() { return false; };
4 \, n4 ~, r$ R6 s6 e E6 f7 t9 @; c
0 p" P& Z* }2 b1 J
protected:
, I! E/ s# y3 O& [ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);! Y9 ~; O; |" I# X7 F
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);) v- A7 X+ w0 M) {: r4 r7 S
void RemoveDevice(CComBSTR bsUDN); f( b+ j) K5 Y& f d o; }! u8 D8 i
bool OnSearchComplete();
" a! c1 F( s- n" m8 @; ^ void Init();- ]. b1 n( c7 {6 c
\5 q) _- d6 `; z5 Y0 F5 Q$ R U
inline bool IsAsyncFindRunning()
. [) ^; e% Y0 g) |& _, L {
, x2 L' \7 z" O L5 A if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: Y6 A# ~# b9 ]) n! E' I {
* ?7 N/ N2 x7 q1 p. Y, Q$ ^ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- ?* Z) B, k6 w6 P
m_bAsyncFindRunning = false;
' J- {7 c! \2 f2 y/ G5 C }- @5 F5 B# |) @% t6 N! Z
MSG msg;
5 c. C2 P3 s7 m1 c while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
) B6 C* I7 N* N5 \; o {" {& t3 o) ?& p
TranslateMessage( &msg );
1 W; B; u7 I9 C( u0 j( @+ I DispatchMessage( &msg );
8 c9 `8 p( A; J% w) M( w( I }
3 |/ U2 n- z$ X return m_bAsyncFindRunning;2 W) B) m+ a* g# f/ ?
}
) z" W& M; P1 x" ^* M8 t* Q3 R' A; z' g/ E9 X- A
! k* B+ S1 k$ ~! a5 `# | TRISTATE m_bUPnPDeviceConnected;9 }/ R; J1 c; s! H! S0 V+ g
7 h! u" B+ l1 A8 L
# l7 |3 z7 P9 V1 f2 i w// Implementation. V' s/ z/ {) t
// API functions
6 t& l5 X/ m9 c9 B8 o: A2 u SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
. }2 T/ ?" C1 B+ I* M+ z SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
G2 n2 R/ u/ y- K2 X5 X- j BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
# l3 u% \: h8 u3 z; P) m BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
. z; B( _8 f. n0 E4 Z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
$ n& {- V2 {, d7 `1 {1 P BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) [. g! v8 C; ~- c1 U) c4 q6 ] N6 q5 a5 j
! H0 x9 f0 N! @5 M TGetBestInterface m_pfGetBestInterface;
: m1 j- t4 i: G! Z' R TGetIpAddrTable m_pfGetIpAddrTable;9 g/ j$ F4 A* Z% ^$ a! j; z
TGetIfEntry m_pfGetIfEntry;6 m p, Q$ a6 ]# f
z Z' X1 ~$ i/ C% U ]
6 }6 C) m6 X, [" {" `$ d static FinderPointer CreateFinderInstance();! Z. f- u' B2 N' t
struct FindDevice : std::unary_function< DevicePointer, bool >% H9 n3 `. G) i
{9 T9 ~$ T4 W; [' Z+ M# b
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
4 [* O, J+ r; q; Z! p result_type operator()(argument_type device) const8 Z4 y& u5 u. s4 E# O8 |
{1 t7 H& ^- S1 V" v4 z
CComBSTR deviceName;5 W: J! O' {3 p: o6 q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
; t5 u9 N# @* y0 z8 p% E, ~& V3 \0 { s2 B5 M7 b! Q
1 u5 Q/ Z" b% c& m7 L if ( FAILED( hr ) )- b1 Y2 M( v6 H- G5 p0 s/ h
return UPnPMessage( hr ), false;- S' y% n: G( i4 O s# Z
: T' H* G7 ~5 r
& N# d- \0 g' ]0 |' M return wcscmp( deviceName.m_str, m_udn ) == 0;1 G7 E8 b& \2 K; J& ~+ V8 s
}
, @/ w) ~: e7 l* ?2 r8 H CComBSTR m_udn;
; D. G1 U- y [$ n9 ^. i' m6 L: W };0 `0 H5 d# u; |+ ?5 d4 v7 y
( B) A: D5 J, s7 c, G1 H7 L
void ProcessAsyncFind(CComBSTR bsSearchType);
; b; O; {. N8 D- z* n HRESULT GetDeviceServices(DevicePointer pDevice);: w8 i( x8 e. Y4 Z- M+ ~* Y
void StartPortMapping();
# ]0 V. e) Y9 K" I' U HRESULT MapPort(const ServicePointer& service);. u( Q" z4 b1 I. U4 H1 O" l) V2 \/ i
void DeleteExistingPortMappings(ServicePointer pService);
, U1 T5 x' z& D6 S3 X3 o) L, ? void CreatePortMappings(ServicePointer pService);2 p/ {) V$ s" R! j+ i' h
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; X9 y j. A2 {5 C/ G
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, % h$ t& ^9 Q6 i+ {0 d) V: P
LPCTSTR pszInArgString, CString& strResult);
4 P7 n* `" R3 Q7 j N t void StopUPnPService();
- L, d& x9 u8 N& w* [0 Q1 C" [" F( ]+ ~& d" d2 q% d3 a; I
. o) x. w7 w4 T // Utility functions/ q8 k: x/ C8 S% e0 m1 s2 P' A& E
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
9 s$ S" I {/ A& w* X1 H INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);/ [- X }+ m. B5 O5 n% }9 E
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: f: Y1 Q q# }) U$ p. f+ H9 \ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);6 P# d8 R) [: U6 _: l6 @/ P% x
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* e% s& m; p* r, w* B. p HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ K- d+ G. k& |9 u0 U, P% f# G
CString GetLocalRoutableIP(ServicePointer pService);* \" U/ F. l' t+ n# \
0 e* P! d" j2 f0 [3 t3 ?
4 R$ W' o7 G; p, m( ~+ t
// Private members
6 F; C4 B' O! l5 v* z; E& Dprivate:' I; w. ?* F W, q6 v1 b0 T
DWORD m_tLastEvent; // When the last event was received?1 y8 {- i# Q J( x% }. d
std::vector< DevicePointer > m_pDevices;
9 d" |4 {& I' i std::vector< ServicePointer > m_pServices;; P2 W) X. }1 j5 Z* R5 {$ j3 u
FinderPointer m_pDeviceFinder;; G4 n3 Y& ~+ p! ^2 Z0 `/ W8 M
DeviceFinderCallback m_pDeviceFinderCallback;
6 ]' X( J4 P# A- L) h$ U1 ~ ServiceCallback m_pServiceCallback;5 j% H) b- b: i6 r
' A* S P' D) }, l1 H
0 E* c, T1 b: B4 A; h2 Q4 b& y0 |3 } LONG m_nAsyncFindHandle;, U1 J# z3 f' x- i% N/ D3 X
bool m_bCOM;9 {/ ?2 `/ y2 c$ c; M
bool m_bPortIsFree;
" j3 a+ l, t0 E+ _" B4 A( {9 U# s4 E CString m_sLocalIP;
! b' w) |# l6 B* Z, e8 g CString m_sExternalIP;
/ F; e$ u/ _$ I% u3 Z bool m_bADSL; // Is the device ADSL?# I% G6 l7 J" B3 d7 n
bool m_ADSLFailed; // Did port mapping failed for the ADSL device? }: E4 j3 G8 U @( m
bool m_bInited;
$ a2 R3 D% N s% E& b6 D* H bool m_bAsyncFindRunning;
4 V% l) \6 C- N3 |% c+ M) J3 f HMODULE m_hADVAPI32_DLL;
: K0 G4 c& s4 X3 U6 a4 N HMODULE m_hIPHLPAPI_DLL;
( Y3 i* ^. g7 i* i$ B bool m_bSecondTry;
9 T' `# U: D( x% S8 n bool m_bServiceStartedByEmule;
9 T3 d) D5 y. M! X _( i! ] bool m_bDisableWANIPSetup;* t1 p+ n$ y; e- \/ K
bool m_bDisableWANPPPSetup;
, O8 f2 y8 B; b8 z. a, o
- D, I3 u- M" P. ]6 M, V: M7 K( F9 ]
};
. S+ u% k1 |: K
' n" e: u/ t$ `( t* f
2 ]# {2 t+ J8 r5 V" L4 x// DeviceFinder Callback% A% V. b! V# W. }
class CDeviceFinderCallback0 a8 `5 d" z# B7 V! ~* P8 Y
: public IUPnPDeviceFinderCallback2 W& U- c- {- C( E: I: ]. O
{$ o% b0 B' t5 ?. O7 }3 N) x a6 g
public:! K3 |9 N1 L: v6 f& E" m
CDeviceFinderCallback(CUPnPImplWinServ& instance)
* d* O" Z- i; ^7 B0 q9 j* d6 h3 a, ~ : m_instance( instance )
: c! g, O" j9 f0 }2 g6 m5 C { m_lRefCount = 0; }
- M) Q! X+ m% W/ j6 i4 Q
1 z8 N& @: _" G0 F1 X. d, {* d0 R! h4 |5 |# A) j; P
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, o5 p/ Q' Y# a2 N+ E STDMETHODIMP_(ULONG) AddRef();
+ [0 ?& M# A9 b; V+ [9 S7 E# } STDMETHODIMP_(ULONG) Release();" [7 s$ D0 D/ p5 _. B, |3 K
0 l6 K/ A0 i+ \ ~0 F
; [( f( z' W, o5 Z9 T, a! L2 i" k// implementation
2 a! _( Y ?$ ^7 a. a& Y% Oprivate:
/ k5 }1 A- k" y, L* w HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 n* |* W: A% D3 z! e* m
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
. G8 t$ r: M4 ], \$ B3 O" I HRESULT __stdcall SearchComplete(LONG nFindData);( p7 u' p. z, _, \" o- J% \3 g
: j# G6 w- _+ z8 M* M j
Z M: y5 n0 Q% f, d+ E& Wprivate:
9 N! ~+ i; W9 A7 ^: S! c CUPnPImplWinServ& m_instance;
3 K* `( t2 F% Q9 I# d1 [% m3 p LONG m_lRefCount;# `$ u" M+ i$ W, a9 Q6 U5 i0 A
};
) ~. N& Q) y% L7 g( e: L
& H# P2 x$ t. K2 H9 T$ u: v; \& U8 P0 E. c- M
// Service Callback + ?, ]# C# y* h0 F
class CServiceCallback3 U: a; x) i9 F2 n# g8 c; m
: public IUPnPServiceCallback) }- m% X: W/ U6 ?3 {5 H& f
{
3 a- i- h, m, v l% _7 Gpublic:
$ {# {0 o6 z( D6 w% h- D CServiceCallback(CUPnPImplWinServ& instance)2 a, B% U2 L! L
: m_instance( instance )
`$ Y- F: r+ h( d2 ~: O5 W" W { m_lRefCount = 0; }
# q1 F3 m/ v0 U8 B' l- s! C! v
8 _; i& N9 T, k& H8 d STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, ~; U8 L H9 S# U- R" C, G; @: j
STDMETHODIMP_(ULONG) AddRef();
. U6 Y0 w: y. ` STDMETHODIMP_(ULONG) Release();/ s6 O% Y* f2 l- b+ h. u w
7 J& |" ^7 S0 D3 y( O R+ j8 n
! A7 X0 o/ F1 I) m: T. [' t// implementation
; i" ?) l$ Z5 z3 r' @# r7 m3 Qprivate:
+ ^4 q! l' m. A HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" g; U9 |) n* B9 l- J
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);+ l8 w m' k9 U
9 B, G( x" ?; Q m; K x {; @3 C! |: G% G! Y& Y1 P7 Q3 E: E/ n
private:" m) T2 ?5 R7 _9 x. s
CUPnPImplWinServ& m_instance;
3 M' z! t0 f1 ]7 X LONG m_lRefCount;
" J( ^5 p) w8 w6 ]3 L6 e# l}; @3 U5 a, f) Z: A6 w, S9 O: G
. d7 ]5 S# T; m
6 I: u. Y% d/ o5 {; F
/////////////////////////////////////////////////6 z8 I1 \* q8 c
- U$ {* k; {' P1 ]- l9 {
- m6 k; o+ i" D使用时只需要使用抽象类的接口。
% K" ?! H9 C$ }7 r- |CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.- T! ~9 ?% s" L+ g& ^5 v
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 u+ [+ m& f9 A' L( SCUPnPImpl::StopAsyncFind停止设备查找.: A1 k2 @( s9 ]2 x
CUPnPImpl::DeletePorts删除端口映射. |
|