|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,/ W |5 ?0 @+ J3 W6 T6 E
8 T: [+ B' _6 Q; b# t5 j% E" x
- W1 c6 I& `- @/ U- B2 @
///////////////////////////////////////////! D. t8 s7 w. r
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
& M7 ^' J% [1 @
' D2 |( o# s$ k$ H7 N( l3 H6 \) ?0 K( b7 ^9 f: D Z/ c
#pragma once0 g$ g$ p& M5 e& u3 R9 V; F" i
#include <exception>
/ X' G6 v) `$ X7 R1 N5 D- N7 ?/ A( G4 w" A& B: E
) M0 e' g( q+ m
enum TRISTATE{, Q- d o6 F: f
TRIS_FALSE,
: O2 j) A! f+ t! k9 ]" ]1 u TRIS_UNKNOWN,
2 j1 N! w7 f; Z TRIS_TRUE
. l8 x( g2 C0 K7 ?};
' [3 I5 g) v6 e: O8 i" E7 S& t) ~
1 B! |: t& v" w! J: Q1 ~% c6 ?% Xenum UPNP_IMPLEMENTATION{
1 v% `5 p" s/ _4 N4 U9 ], h, s UPNP_IMPL_WINDOWSERVICE = 0,2 l" ^/ F+ ]8 @
UPNP_IMPL_MINIUPNPLIB,9 b7 D ?6 r2 p" m* r- o
UPNP_IMPL_NONE /*last*/
9 ~' W; O5 A& B$ [* |};
8 {1 w% H, _8 @
4 ]2 w2 ~4 E5 I+ |/ d0 {" D
* S9 Z. B5 M6 d* J: Y ~5 v$ ^. G! z. k; `5 ^6 o7 V1 j
# z: B9 m2 ?) H0 e7 D
class CUPnPImpl0 {, D) |0 ?8 c5 ?; k
{/ w+ `2 `: j9 u* J! \
public:; L! K6 k5 U$ W8 l
CUPnPImpl();( g# w: [! D7 O& F# `
virtual ~CUPnPImpl();3 b7 j8 u% l7 m7 N0 N- g' J
struct UPnPError : std::exception {};" M3 u, d# l, ]3 L, g7 b
enum {) h: |; \- \: ]" z' U
UPNP_OK," a" z7 v7 m$ _7 P2 w6 t
UPNP_FAILED,& X% ^5 Q% C1 J" {$ a/ B
UPNP_TIMEOUT5 Z) ~) q. G! `9 t q$ B
};# @ ]. ^- Y6 H6 E( m3 h( _& f) j
& Y: b+ V5 Y( l8 B8 r6 b1 J' l# d8 |" H! U- J) E" v
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;% r' D% g8 L, K( `9 I
virtual bool CheckAndRefresh() = 0;
7 d+ Y! L( f8 c8 K* i! u3 b3 I# @* W virtual void StopAsyncFind() = 0;
* a# P) `/ @* c- O I$ z virtual void DeletePorts() = 0;
# S" a! R9 J. Q1 F) _. z1 J virtual bool IsReady() = 0;
0 M0 Z2 Y7 Z/ p/ w$ k virtual int GetImplementationID() = 0;4 @" D5 U% o1 a! X
, z P9 u& A' ]7 x8 ~$ o
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
$ b f. E7 Q, T+ w# w
2 t$ a) ~( q* ?; R
, T3 z# N# `/ s0 |3 |4 ?* k* ? void SetMessageOnResult(HWND hWindow, UINT nMessageID);, G' z$ Z7 ] k5 d8 a. g( `# P0 v; Q. R
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 f3 \1 {9 q$ ?5 J- g$ F- k
uint16 GetUsedTCPPort() { return m_nTCPPort; }
' T0 `# c" b( F5 Y3 n ?; k uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 J; {* K# a" X) ] }) n6 ^* i! L
7 C# G0 e* j8 m
9 W3 W, g1 f* t# c// Implementation
$ t% A! |% K" s. Xprotected:" v( A1 P* S8 U
volatile TRISTATE m_bUPnPPortsForwarded;
% b- d6 ]& u9 }9 { X. y void SendResultMessage();( A# t2 G, O( M* w4 a/ q
uint16 m_nUDPPort;6 r( r/ f& P' P K, |
uint16 m_nTCPPort;$ }+ I+ z7 U( B& G
uint16 m_nTCPWebPort;) b4 ]0 h7 V7 l. U) }. K
bool m_bCheckAndRefresh;
5 j( L. c6 r( ^! \( m: {; W( m, {/ w7 H, o* n9 P
1 _# {- z6 u9 W( S* `4 J6 Xprivate:# v4 i/ S( Y- X6 V6 {; |% u1 q
HWND m_hResultMessageWindow;, E3 G; W2 u: M8 K
UINT m_nResultMessageID;) T0 X" @0 ^* \/ ~ ~4 V8 S9 p* h& G
/ M: }/ n1 Y1 L3 @% h" ?! q- N. W, O2 E$ Y @0 R# [. \- u
};
& g' Z7 l/ L1 B. k9 ?# I2 H! H0 f( e) ]) h: H" F% e( C+ q
' Y* h+ [# U* r- l+ S// Dummy Implementation to be used when no other implementation is available7 [: E; X7 u' N1 b
class CUPnPImplNone: public CUPnPImpl
% c2 F. K& L" r5 W, v* G% \{
" T) i# x3 W6 ]& t S6 D9 cpublic:9 z% U" p" [" u w2 k, M
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: W( Z7 \; `, M9 b2 H* h virtual bool CheckAndRefresh() { return false; }: m1 _! s3 x: l$ Z7 v1 \0 K+ i
virtual void StopAsyncFind() { }) l. B9 z2 t5 w
virtual void DeletePorts() { }
+ Q% _! N- g* C! W virtual bool IsReady() { return false; }
! j- W h: r E% `! a) y virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 w% e$ q3 `) ?) J};
% Q* i$ s6 E2 L' z7 Q& S, A9 \1 [; k$ C2 k4 A& l5 M8 D
9 A; n' D$ H, t- V: B( Y0 Z6 g# `/////////////////////////////////////
\4 ~" s# l ~0 } M9 W//下面是使用windows操作系统自带的UPNP功能的子类2 m3 N6 q" R7 @- i, l* F
- b$ H# \, e" w2 y# j6 J6 w7 x6 {) b
1 O# X% ~- T% Y, y#pragma once
* K3 Q, q5 ]% ^#pragma warning( disable: 4355 )
. D# D- i3 { H4 n2 ~$ c+ P4 Z' R3 S7 t/ E+ [
$ J+ T+ S/ v5 |. f. _, M i
#include "UPnPImpl.h"# d9 ^( W( a3 M! J! ~, [
#include <upnp.h>5 L, B0 d1 I8 ]4 r2 i1 M4 t
#include <iphlpapi.h>
! K, z S9 `( s2 Z- n; i% ]7 a#include <comdef.h>
/ o% o/ j! K# D#include <winsvc.h> e5 r# e) O+ @: Y3 h3 ~7 ?5 U
2 g* K& `; n1 G ~4 k- V( H1 F% q) y) W5 i7 v8 R( l: q4 J' j
#include <vector>4 o4 m( |' J; w, |+ |/ P
#include <exception>( x. `2 m) T* N( {2 A/ U+ u& O
#include <functional>
9 m0 D: z; c" x! Z1 e/ }* L! C+ R( j2 _1 t+ _
3 l* V' n- S7 ]& D8 U
9 d% d& m! `; r$ E# v7 O; W
& H: D5 s* N. i, \
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
- j! l4 Z+ _4 s0 a" \" y9 l( m0 d$ P7 etypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
3 O- Z. a- I& C7 dtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
! ^& Z; T3 R* B- ?9 p& g8 Q/ ?typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
% f I- `! i; Jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# z; B+ t. m; X: T, X1 c" J
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;# @+ {: R; W; ?' q9 ]# [
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 Z4 r5 } h# L! z' V2 x9 } u
E+ p5 F5 V# H# F9 w4 |
1 {4 Y# L% u6 P$ gtypedef DWORD (WINAPI* TGetBestInterface) (
% c4 a6 c; D8 {% C! \ IPAddr dwDestAddr,' a: S% f( B4 G. v' C) F
PDWORD pdwBestIfIndex
8 K. R V. b8 {0 c( j" q);0 {, v, b6 T9 r2 X9 U! w+ a, E, k4 J3 y
/ c! A, v2 Y+ r2 C# h9 z4 M* a! @2 F( B7 F9 Z
typedef DWORD (WINAPI* TGetIpAddrTable) (
, T4 V; p' a; D6 s& L) v PMIB_IPADDRTABLE pIpAddrTable,; R' O& ~3 L7 x
PULONG pdwSize,$ L% W4 w# E$ [1 I* d7 N" J$ t8 g$ K
BOOL bOrder% C2 U# {: e5 w: F; m3 Z3 J
);
" |' Z, t9 F( S4 Y( K/ K, ]. ?4 t' ]: l5 d
( g' T; B7 _1 ?6 ?# E
typedef DWORD (WINAPI* TGetIfEntry) (, U# P s+ A# u+ W& y1 I4 C
PMIB_IFROW pIfRow
. P% v7 `* q$ ]' B$ t( `2 Q);& d$ G6 B( M3 G
% ?8 H9 w9 H- u! ~3 s; V5 N) \7 c, D9 ~3 w; c
CString translateUPnPResult(HRESULT hr);5 e) ~0 i# y& g* q( v) L, {
HRESULT UPnPMessage(HRESULT hr);' w0 n3 B0 a0 i) ]0 q
9 Z( [% g2 `; o
) B2 s% r2 ?4 s- A# p9 P1 Rclass CUPnPImplWinServ: public CUPnPImpl ?3 G6 S. A) i' f7 i
{
8 q# [! k& t! p: [5 M/ O+ V; z% b3 P+ s friend class CDeviceFinderCallback;5 ?/ S9 a n: Z% Z) R
friend class CServiceCallback;
% J. F2 F/ w# @" l; }// Construction
# t" Y5 s/ @8 |& mpublic:4 d U" T% D/ A% ^! b1 l# V
virtual ~CUPnPImplWinServ();
9 A! S+ {$ X3 F4 j0 c7 S CUPnPImplWinServ();- {! A( S, K: K- X8 d- {
5 f1 `7 o& Y% P% V! v% A% a* \7 b
2 [# ] }( _* V, D
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }% t, r: A# S( o- D; i9 `& X' r ~
virtual void StopAsyncFind();6 h3 ?; k, E, B/ _9 V$ m9 }- p
virtual void DeletePorts();$ k, \% ^! R" R2 ^- S. o
virtual bool IsReady();. ^& R0 M" r0 c1 n' H1 ]0 M
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( s! M3 n d# h- i* {' @4 r/ p
3 _' w4 q/ m( _+ F: [8 O% X) }" Y
! {8 E! U& }% w$ i+ \ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc) i I$ z$ Q. T4 {9 K, L
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later" H( }" d( r9 n: k1 T% Z2 C8 W
virtual bool CheckAndRefresh() { return false; };
B/ c9 Y. i7 t, @( C$ _. G
$ ]1 b, {& G5 Q6 N& C1 ^1 j8 A
# w. h4 E+ z2 ~. Q* Y* E# Y" Uprotected:, w9 l' Q' M6 H3 B# y: J; d
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry); L) Z3 b3 Z$ N) r$ r
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 u ?) [& i# W: @ void RemoveDevice(CComBSTR bsUDN);
9 x# F' z g2 N- v# @( u bool OnSearchComplete();
' B: B" r1 M9 M; h9 ] void Init();& {: o3 \) f; p Q0 P- v5 h$ s0 {
! z2 K8 o9 U5 i! }1 ^4 a
/ Y* t) ]+ @5 t) s% B. J inline bool IsAsyncFindRunning()
. U% ?' A0 B1 \& N& P" A {& j0 ~" H) U2 Z
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )$ P3 A5 L9 `4 u; e) h1 \) N2 h
{
! f' ?3 i8 i& t! Y, _& K" l- P' w m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
/ L6 y5 x8 b* E m_bAsyncFindRunning = false;
5 d" v* ~6 a! Q. X; b }
1 a# G. q9 t4 @ MSG msg;" j0 ~. K0 y$ k
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ): }8 s9 _3 v8 C; z @
{
; r+ A% q& S% f& s& Q/ H; w' G TranslateMessage( &msg );
; n3 J! O9 [% g3 k& B+ J/ H DispatchMessage( &msg );9 r) S7 c& z4 M& n* G) a9 k7 [
}
% u: Y8 O$ M' }- M3 j return m_bAsyncFindRunning;
0 I7 }5 V* n/ {, |# ^ }2 a' P( B+ C$ {/ U3 B
A1 f! H/ G* F# v) |+ d7 G; x, h8 v& B$ o) K
TRISTATE m_bUPnPDeviceConnected;' ]0 ], A' g9 q7 l, e
5 f3 q: L3 t/ r
, f, a) l# H1 }- f6 h// Implementation
. Q1 @/ @9 d$ Z9 a7 h1 ~% ` // API functions
8 q4 Q9 V+ B% o) g, j* f SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 W+ L& ~ B. b# ~: ~, B SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
6 [+ ?; t4 @" B! [9 u6 N BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
% [2 ]0 |; X; l2 ~- t8 d: z- A. B BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( G& [$ y) \; z& L' [
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);6 J8 y1 X, @4 s+ ^' ]. b; Y
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
& Y- T: }8 V- [" ~% d& _0 X
% R' e- }( A% x9 V$ v6 ] H P( R$ U! A1 c
TGetBestInterface m_pfGetBestInterface;
; _& L" I- S- t5 G/ W TGetIpAddrTable m_pfGetIpAddrTable;
& z$ j( d: U" H. b6 D- _1 L TGetIfEntry m_pfGetIfEntry;7 W9 `6 N' Q2 g2 w; i
, K7 M' [) i+ a8 m9 I |4 b. S( r- F7 J: i% c
static FinderPointer CreateFinderInstance();
0 y* }& v R: C' X& v* Y6 \) R struct FindDevice : std::unary_function< DevicePointer, bool >1 d4 g9 _4 g/ E1 y
{( ]0 b- K. K Y A/ n$ k* z
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
: G8 F8 X4 _8 q- T8 ^% E, B result_type operator()(argument_type device) const
7 R! U. D+ m3 }! @+ T. H {- J+ g; D6 g1 A$ m7 [' H* U
CComBSTR deviceName;
) \( {' Y! q8 ?6 P" c, @% B0 D) C HRESULT hr = device->get_UniqueDeviceName( &deviceName );
1 t f; x5 c! ^
2 m0 u C8 l* u% p
, ]5 ~- a1 E6 l2 Y& J if ( FAILED( hr ) )
+ K: B5 }: ]( a2 M/ ?4 o% W1 R return UPnPMessage( hr ), false;- v% H! y, m. v0 l# h
: F% K1 g0 x! b$ L$ m
) f% t7 g0 S9 C R/ o7 @ return wcscmp( deviceName.m_str, m_udn ) == 0;
) X/ p8 l' s2 C) _* T }
$ U" I* j" \) \$ J2 J4 F CComBSTR m_udn;
) i0 E$ K/ g5 S% z8 z9 c' N- X7 _5 q };
: t9 x' X$ ~6 ^% Y; z1 J ' p* D4 }- _9 j+ k& p
void ProcessAsyncFind(CComBSTR bsSearchType);# e# E; x: o5 S( [- X7 B. d
HRESULT GetDeviceServices(DevicePointer pDevice);
1 i$ j+ v2 o9 D. i) o void StartPortMapping();4 J M% m2 F; m$ \
HRESULT MapPort(const ServicePointer& service);
5 S4 I0 q+ q$ ~/ p- ` void DeleteExistingPortMappings(ServicePointer pService);
7 Q5 C- y. Y3 B% H3 C void CreatePortMappings(ServicePointer pService);
! i7 i& Y6 X+ E, C" ] HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 B; q. q3 X0 J' B( c0 c, p. |
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* |0 G1 {2 x G# J$ v$ a1 Q- A/ [ LPCTSTR pszInArgString, CString& strResult); x7 I+ p1 ^3 d$ A) h
void StopUPnPService();: n H7 s9 X: K: J1 K
) V+ H, g# b: |( ~. d/ x$ Q
; C9 n# l) U$ A // Utility functions! I1 E* ~8 _& h8 N
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa); @, e' n+ @0 Q" g. u% ?
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);! S1 |' o# T2 q2 G! s8 P2 A
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);3 x. z" U6 H! j; ]1 A' f1 |
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);9 }" [8 f% N# v& \: o$ Y( ~: P
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);5 Q, t E1 S& i$ r8 k
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);9 |3 ?+ @- s, L6 r" A
CString GetLocalRoutableIP(ServicePointer pService);
4 c: t* c8 M# S; L* |* ]4 |) D# d: r' F& G. l! G8 ?) C, R& n2 R) N
1 @0 Q* P5 F$ O
// Private members/ j) R# U8 g4 U) i5 T$ e) c9 o$ b$ g
private:
4 B0 q8 b+ Y# c DWORD m_tLastEvent; // When the last event was received?
3 v) u5 w/ ]* ?3 j( ~% H5 {4 E& T std::vector< DevicePointer > m_pDevices;
0 p/ ^- j5 X: m3 u std::vector< ServicePointer > m_pServices;
+ k$ e$ L/ C4 P: a$ v FinderPointer m_pDeviceFinder;
5 j5 {4 Z& Y4 J DeviceFinderCallback m_pDeviceFinderCallback;9 k% O9 {) G: ?) g
ServiceCallback m_pServiceCallback;$ f3 e; \9 W _
' [9 H2 k/ R9 } O9 I
- t2 \& S5 X% l2 r* w8 I; y8 K LONG m_nAsyncFindHandle;; i1 x, M( ]4 o9 V" S
bool m_bCOM;8 y$ P' N1 j, }& ?: P
bool m_bPortIsFree;
0 e, |/ r' }" Q/ q CString m_sLocalIP;' J( ?/ w ~; ], W( h2 [" P
CString m_sExternalIP;
" I. o. v* u, ?7 B& P5 j9 h bool m_bADSL; // Is the device ADSL?
1 { n3 f& |6 x7 X$ D bool m_ADSLFailed; // Did port mapping failed for the ADSL device?3 A1 y5 y# U6 n% m: s
bool m_bInited;
5 `2 S+ V! x, q, `3 b: F3 a! ~ bool m_bAsyncFindRunning;5 C( b/ A4 b' F$ N0 c* y9 b8 F$ c
HMODULE m_hADVAPI32_DLL;
, m* s. [, e5 G1 w; u HMODULE m_hIPHLPAPI_DLL;, t: R2 s# N8 Y. v
bool m_bSecondTry;+ k) F" {6 g' X% d! i( j# L" f% I6 Z
bool m_bServiceStartedByEmule;
* G- J: A% W% @+ ]* h bool m_bDisableWANIPSetup;" ~: {. U8 ~5 B) T3 n$ X; v
bool m_bDisableWANPPPSetup;' A3 S' E' o3 b
- \- G T; P# L6 ~$ y+ `8 U; U9 O) C/ c# i
};: E; i* K' n5 K
+ n1 X- a" |" V# b2 \2 ~+ R
% P+ @% T( j5 v% Y- y// DeviceFinder Callback* ^) v, Y' {% D: z Q5 F) m
class CDeviceFinderCallback, i3 @5 w( O0 n, K% \' q8 k: N
: public IUPnPDeviceFinderCallback
1 l0 K5 j7 ]& U* S{1 o% U. ^. y! E! w+ ]$ K7 I4 M5 P1 b
public:
7 R4 o" R$ C; x! G% A CDeviceFinderCallback(CUPnPImplWinServ& instance)
. O* P) q8 J8 j0 E' Z T : m_instance( instance )
7 a) c5 b7 x5 J) P0 n- ]. ~) [: h { m_lRefCount = 0; }
1 m. Z# Z9 z v& Q% F: I: K: Y$ j5 Q! U1 }# L4 @0 u
3 B9 U! P `/ ?4 {# s Z( @
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
6 b+ p& }3 X# t, n5 q STDMETHODIMP_(ULONG) AddRef(); y: ~% a; r/ B0 H2 Z
STDMETHODIMP_(ULONG) Release();% I5 d# [0 n2 q! [5 E
; @- w, C% [8 Y2 U2 j* o
$ \# y1 u$ f6 {6 i$ j// implementation
5 `) \ c8 [( Q( r. {2 I# @private:* j5 e: n9 }9 }. i
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);9 I( V) I. z, E1 B; K5 W3 i
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
0 C% J3 P' d( \5 `: G) @3 T6 \/ Z& @ HRESULT __stdcall SearchComplete(LONG nFindData);
# ]% f, }" _0 r0 I5 X0 C# W* D5 N2 m; A6 Z) |! u5 w; N
: ]1 Y+ @5 U) J8 Hprivate:
% ~ b" u7 \$ y. P; ^6 p: b CUPnPImplWinServ& m_instance;$ |: T( g$ W! \% x1 M# r
LONG m_lRefCount;
5 \) X; s4 `" b$ G' i* T. y3 A5 O};
1 ~8 ^" U0 C% t( L
" J+ H, t6 h5 U. ?& N* ]; ?* z. h0 D1 _2 I) n9 ^% @- I
// Service Callback
$ N: U: {: o$ Y# qclass CServiceCallback9 z+ G% C3 A" @4 G. f9 m
: public IUPnPServiceCallback
! ^* P7 h3 H! R$ V{- O! V0 @+ U9 W
public:" K+ ^& D0 X8 } t2 f# y
CServiceCallback(CUPnPImplWinServ& instance)- K) C( S" @: s
: m_instance( instance ); [7 O! B9 h( P8 s; r+ I
{ m_lRefCount = 0; }
; p- }- M* d. X! B
7 I4 L2 p2 D! R5 `. y1 b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ Y. \: ? ?( z
STDMETHODIMP_(ULONG) AddRef();
1 j. j9 R. l1 ~: F STDMETHODIMP_(ULONG) Release();
/ Z1 N) }# z! U
* O' }: Z* G; ~8 K9 M1 E/ c: J! m& I) e
// implementation
* Y9 ] x7 }! Xprivate:
' }1 r2 l5 C' D" d/ [! H9 r& a- D HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);, e! A: @) P9 _4 r; y' p* |
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
+ k8 [1 K& J* ]- ~9 n2 B) b- F1 A& f6 o* U3 ]
1 q, S3 {+ t: Q
private:
7 o' `5 @6 p6 \+ a u2 I# ~ y CUPnPImplWinServ& m_instance;
$ _& V( v3 \$ s2 G" {: n LONG m_lRefCount; W' t! K! m8 }4 M5 |0 P) D
};0 I5 R$ [1 l7 Y: ?$ t/ {
8 S; o4 F% A; Z8 }. U
1 G0 F5 M# v: c' V; t8 J) a/////////////////////////////////////////////////3 h8 n% l5 V" ? ~/ |
. j& |, b) P* S) ^0 K
9 X9 e+ }( V# a4 t5 p7 Y; | X使用时只需要使用抽象类的接口。# _6 H9 q& v* Q/ y n7 T. v( Q
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
: A% d2 x# c0 W3 z' M9 eCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
& ^ d& u8 r1 p3 mCUPnPImpl::StopAsyncFind停止设备查找.
& G) K `) N! c, w% D% v: R- H8 y! lCUPnPImpl::DeletePorts删除端口映射. |
|