|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
9 H* P7 A- b1 r8 [ i6 A a7 P+ k& D4 e* l* @
( p6 g! k- g& f4 p* z0 t///////////////////////////////////////////1 T. X2 g+ t( P' o! I
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
( a) D$ r8 y3 s q4 f# h* x! I, J! w/ a8 E# u" m* v
6 E% ~, N, T6 A# m/ w- B7 y#pragma once
4 D" k) M( F' s: s1 w#include <exception>" D( O" h/ F9 }) I: y+ ]
8 \& L& |2 ]% [9 {$ }8 @
+ Q) a5 U5 Q7 u" r% y' H enum TRISTATE{
7 c1 ?3 h& b1 z( n& j TRIS_FALSE," G8 v* _& i1 j2 h; ^; m
TRIS_UNKNOWN, Z9 w# A% `! V/ R6 ]
TRIS_TRUE
. @6 S! [( q8 X6 i1 ]};7 X4 U w7 k/ Q' d0 R3 w- X7 m/ D, K
8 [$ Z' P1 [1 K+ j
$ j# s. T2 h1 G4 b# |enum UPNP_IMPLEMENTATION{0 j( Z. s7 j3 m
UPNP_IMPL_WINDOWSERVICE = 0,
+ T2 n6 ~: l$ q. V! U UPNP_IMPL_MINIUPNPLIB,
1 f8 z! ?2 k" \; ^% w UPNP_IMPL_NONE /*last*/& X, ~5 k u S' J, g' f" v0 e# q
};
4 w# o1 a3 A4 |$ ~
# Y# w7 S6 k1 t7 T2 h# q6 l2 H/ h+ o' ]5 b- ?% `3 ?
) c5 s2 \( L: |$ P' h
/ h7 b, z q5 D5 a) b5 n4 ^. Qclass CUPnPImpl
# F6 o+ s8 g- j- g/ l* V9 ]. ]{
+ f( g% o' Y& G$ v* E3 }- d& G9 R+ ~public: X) w" e$ f$ d7 x2 B
CUPnPImpl();
; P9 b$ ?/ M( L+ B8 \# y* L" | virtual ~CUPnPImpl();
9 |0 \& w) V2 B! Q2 h- f& K0 B struct UPnPError : std::exception {};
- n$ Z! ~& u! p$ C7 L enum {* U9 j$ q8 E3 T
UPNP_OK,. k1 W }5 V1 x: x" U I
UPNP_FAILED,! d J0 a/ e; K6 E: o! k4 j
UPNP_TIMEOUT
, U; A+ n/ y. H2 V; o( Q$ K# K };8 M1 @- k- y) w/ x: R" U; `
; n1 X& r. j S$ d9 I D1 S
- _7 X$ D7 ?* p/ `7 X
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;7 t( C* \: D& z
virtual bool CheckAndRefresh() = 0;
: \7 F: \7 ^0 R% r/ F* E. L# s3 ?4 S virtual void StopAsyncFind() = 0;
* k' B: Z" \0 n5 ^$ O% m virtual void DeletePorts() = 0;
" [$ O( V; T) l* K6 q7 |) a virtual bool IsReady() = 0;4 C1 D/ N" @% o% S3 P0 ?
virtual int GetImplementationID() = 0;+ z: i0 P( K, ~) Y/ Q
4 K; Q: a" F1 [* {& r& I
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping( n4 {8 \1 K5 F; a n; F
. ~5 I: C3 o/ B: c7 F" }& U2 o) t% I- s' @0 ^
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; I7 h4 E0 j8 \ J' {5 |
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
5 a( [3 s9 j. {9 d$ m uint16 GetUsedTCPPort() { return m_nTCPPort; }' ~( L( T0 y# q+ i2 i& X' N! {7 \
uint16 GetUsedUDPPort() { return m_nUDPPort; } / d9 ?$ S4 q) G9 J
: r9 v5 ?7 i/ j9 X5 f( k% {2 d& F9 f" V$ X$ R# v
// Implementation3 r/ L- G2 [) D+ F( G
protected:9 x8 I$ A" r/ q% B; J9 M* d8 P9 v
volatile TRISTATE m_bUPnPPortsForwarded;5 p% d+ K# R4 {' [. O6 L9 T3 h
void SendResultMessage();3 A0 o# g% c7 W4 n& w3 q
uint16 m_nUDPPort;, r, }: i# J6 ^) I. ?0 K3 A2 y$ t
uint16 m_nTCPPort;
" @9 O4 I% c, i- {8 ^% ~* ]( T uint16 m_nTCPWebPort; v5 V5 d0 c' e
bool m_bCheckAndRefresh;
8 ^/ G" f. R9 Y- P$ y& A
) h, K# F) l$ I; a
. F3 m% [1 T+ t9 `private:6 H. w. q" ?( U% W; h. V3 i0 m0 I
HWND m_hResultMessageWindow;% _7 N4 E' Y9 b' n( g
UINT m_nResultMessageID;
- O, t6 i$ j$ l4 e0 \- K
: w+ t K9 x$ L0 `) S: c: C% P/ y% V3 B
};" J6 z/ s/ B# R
6 f! a% |; }9 n
5 _0 [- z/ e4 Z7 _" x
// Dummy Implementation to be used when no other implementation is available7 l4 p2 i3 {7 Q. f4 I+ j
class CUPnPImplNone: public CUPnPImpl* x! O! {! E! D3 }" [
{
0 Q. ]- d1 Q9 z$ h+ cpublic:
& Q/ I- l/ M; S/ u% ~" }1 y virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
+ b( V$ D% T6 i8 v) }' o4 M" X virtual bool CheckAndRefresh() { return false; }3 y: A! h# [. L1 J% c# A$ r5 Y# h
virtual void StopAsyncFind() { }
& P8 h/ q- S* d+ r virtual void DeletePorts() { }/ @( t$ e8 M( T+ o" n: a, t
virtual bool IsReady() { return false; }8 G3 O/ r; ^3 y2 k% Z+ e
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }, ~9 I. U3 p# i2 N
};
" j( L4 Q x) l9 V- f( Z7 ]: ?! O% J0 X" B' h( \
: _& d/ i5 \. b3 K- [+ X) M; v
/////////////////////////////////////
% B' T) b; A( n4 s9 W6 ^4 X- e//下面是使用windows操作系统自带的UPNP功能的子类
9 k/ l+ [4 ?1 `* H" |7 p* I- c* P) v! A/ \ a7 M
6 o6 K2 n& S$ Y2 b) B9 U* y3 V#pragma once+ a! p7 l8 y* ?; S# z1 p# H
#pragma warning( disable: 4355 )2 f1 h; R6 c. P, a; T+ B
0 y% C- R3 M0 b. L; b) [3 [! D' q# X( r
/ R: C% w- ^% k; z#include "UPnPImpl.h"# N& ]# u: x! E, \$ L5 q
#include <upnp.h>, ^5 G0 N- M% A- @# N. v N, s# Z
#include <iphlpapi.h>
# p5 L8 k8 h9 @#include <comdef.h>
6 }' A) R O# @% g+ d& G4 k#include <winsvc.h>+ n. {3 R0 q1 u
, c7 T1 |9 a* x( ?# P
. L9 J" u% _% G3 C% J#include <vector>
& o8 o% y/ L: e& Y; O4 o#include <exception>1 s& y4 j: ^. _; D" e) _. q
#include <functional>; p* s/ T7 q* U* A9 }7 |7 a, u
5 X* R# c& k3 Y, N U/ U
6 S( P* k0 H. k; M* \' @% i
+ P' ~ M2 ?$ H% S9 {! c
! O9 b8 U& w2 B0 i' q
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ J) r) E( L+ Z0 Utypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;; \1 H D* r3 v5 a/ m
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
4 v7 T0 t# z5 i5 [$ p. Htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;% L- ?0 z; f1 N6 f
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
$ n6 |4 |% N1 a; x* stypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
, l! R( D+ D9 ]/ N/ xtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 R1 y6 i/ S0 a0 l ~& G0 }/ L4 Q
* P2 ?" S: l9 W" K2 H
/ F+ v+ `, X5 Q. a% H/ T
typedef DWORD (WINAPI* TGetBestInterface) (
# z1 m8 W V9 \& f& N6 V; D IPAddr dwDestAddr,
: o4 f7 \. ~ \, \0 ^0 ` PDWORD pdwBestIfIndex- ?3 w" o! m, L& Q0 n
);
% `8 q o- U2 s# N& j- P# ^
2 N* Y9 m- ]8 O& J# h3 B! @8 j T2 \. J8 P( m: Q0 y
typedef DWORD (WINAPI* TGetIpAddrTable) (
, d) x! w0 C' h( m+ c PMIB_IPADDRTABLE pIpAddrTable,
! l3 t" ^; B: w* S @$ g# q5 A PULONG pdwSize,
: y3 Q- P0 k$ o' x. v, V$ n$ z BOOL bOrder# p- U: S9 d8 R4 q
);
3 p6 T0 w8 N, |2 O+ o* H8 {* I6 j, g. h/ O+ v: a, \3 |' y) @
! Q- Q- O# O9 f0 h, C& k0 r& ^
typedef DWORD (WINAPI* TGetIfEntry) (
" H6 e9 u* t7 Y% ^, N PMIB_IFROW pIfRow
, c4 b4 l# q! O- K);3 l- A! Z5 u- D1 `+ ?4 F7 b
$ _ A3 M, x! B$ U$ ?9 N3 D8 f5 X' Z' [4 o- @! {4 P! E7 {
CString translateUPnPResult(HRESULT hr);
/ R& V2 s2 a0 ]# ]. @HRESULT UPnPMessage(HRESULT hr);
5 y; }: p/ C, p+ @( f. _1 a. x O* w! l# c
- [% ]3 Y/ Q5 t) L) ?: a! z( dclass CUPnPImplWinServ: public CUPnPImpl; C2 S5 [5 Y; k, I! ~. X/ J0 @, I
{) _; u1 m& t' x. x" M7 z
friend class CDeviceFinderCallback;
$ x* p1 A# }9 l% D5 ^3 [0 n: X friend class CServiceCallback;
8 ^* X( Q8 A# e: O2 P// Construction( W/ p2 W! g; i; z% ?
public:
6 W7 ?) d9 Q3 y+ h/ P( ]; A/ G virtual ~CUPnPImplWinServ();1 r/ A$ h! ]( }8 Z3 M7 s+ C7 G
CUPnPImplWinServ();
% ^' n p; K" J
/ N5 H. \- F/ K4 }/ e5 L+ [4 Z% ?" u) |2 `9 p
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
/ T# ?; L% Z B) R5 p* N virtual void StopAsyncFind();! |9 W* o% h X) K
virtual void DeletePorts();+ W" C- H0 r, z
virtual bool IsReady();
: D4 [0 n# m S5 x" T virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }% i! Z! a, i* m$ a, H
; U }9 X% w% `7 h: H
. ^( f! s5 ?2 S7 W // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)* r9 C8 h6 Y8 w
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 j' A0 A5 B" O3 c virtual bool CheckAndRefresh() { return false; };
3 R% g3 [& d3 m0 ]2 m
8 H8 A% ^0 i$ q2 I% r Q" ^6 t, A5 L/ F+ G4 ?: \# A8 x
protected:
7 ]: x0 B* a ^0 L: w. c C( B8 j void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( i8 g9 A9 n. h( e0 @* `, {. c9 g void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);9 `" g1 B, k; s7 R$ |) P7 i
void RemoveDevice(CComBSTR bsUDN);% E% w1 u. H8 E
bool OnSearchComplete();2 L3 Z4 [2 {/ i8 G
void Init();1 g# U+ B3 z+ l6 Q
1 m" l5 _! C: W" Y& z: f: l+ Y" M: q0 k5 m
inline bool IsAsyncFindRunning() . |, _& Q- Y0 X' F9 c" q' v5 J" c
{
) f1 z; Y* Z9 k" H7 {3 G if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 Y5 a: C- R4 F
{
7 q) C* T5 x% F2 `" Z8 K# C7 B m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
p8 |7 Q( w; j$ u& h m_bAsyncFindRunning = false;, T- L! c$ I9 t q' I! k6 N9 {
}$ u6 E( N8 [$ B5 V8 p4 G% ?
MSG msg;
/ t% r# S8 [8 R2 ^% S6 _5 N7 | while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )1 E9 E4 W! o8 A3 e3 t
{" k6 A K6 H9 `
TranslateMessage( &msg );
& |7 o% u# k: L$ y4 Z3 D/ _ DispatchMessage( &msg );
. F1 t! s5 z4 U# ?1 p) \3 z5 p }
6 M7 R7 W3 J. ~ return m_bAsyncFindRunning;) C+ x* ^2 }" O3 z, R8 L, G) K
}
: X" a% A% i& `! U, {
; C. M& R7 _* l% M" `% o ^; x/ ^: u7 k& k# N$ ~
TRISTATE m_bUPnPDeviceConnected;
T2 @0 q% v# n8 v# j1 p- Z, B9 n# {: C* G+ G. P0 G; X
- q/ ]. {' z6 p, ^3 G3 J- n! @. T// Implementation
0 c5 k; h2 C. _/ E4 o' b // API functions
7 \2 W' \( S6 E( p7 Y SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' `( g# g9 V8 [2 W& D$ i9 j
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);7 V3 J! w, M/ S4 T3 k' B
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 p2 I) ~" X! M4 i8 G) g BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
6 w) ^4 g+ `% ~/ j3 w: M3 m BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; |: ?( c3 b, c1 o+ E, Q5 E9 _! @ X) h BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);6 r! d8 o- [4 V l2 G" R
- E/ p$ }! [8 P
: {$ |3 W% h/ u4 O6 V TGetBestInterface m_pfGetBestInterface;
/ F4 {% T- G4 c3 W3 P4 i) f TGetIpAddrTable m_pfGetIpAddrTable;
# N/ J t: p) B- C TGetIfEntry m_pfGetIfEntry;
i: P" |! w$ c- v% R1 C3 w/ d8 u) G |, a% q* G" r& n6 x
7 @8 \! v. Z8 w5 `
static FinderPointer CreateFinderInstance();
& x; q' A8 r# K% B4 m, b struct FindDevice : std::unary_function< DevicePointer, bool >
0 u2 k) q$ z- ~ {
6 a# Q/ S. M* y: K FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
3 C8 a" H. W `. i8 j9 d4 H result_type operator()(argument_type device) const' g, i. u0 K" j4 l
{
0 _) U4 k# e$ n CComBSTR deviceName;
0 F* i% x/ B' F2 w/ [0 T3 n HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 g2 r/ ]6 e/ T' _, \3 D- V# g( M, I4 B6 A
) N) S6 v$ x0 [6 \5 V if ( FAILED( hr ) )
" P; p6 a' k) C0 f' m return UPnPMessage( hr ), false;
0 \5 [% V, ~# G) O% ]6 f
X4 Y# Q( x m! f" I
2 n: p# [3 o5 F& A) m/ V return wcscmp( deviceName.m_str, m_udn ) == 0;
7 k' i4 \, |$ F3 V+ P. A }8 `- o; F/ D+ R$ N" i( t3 S4 a3 d9 m
CComBSTR m_udn;
. F* s- E3 U4 A# R6 k# y };
& v4 [) K- u' F/ Z: V3 ?' R
+ @! e- s `- l0 }5 C; C void ProcessAsyncFind(CComBSTR bsSearchType);3 Y* i. \, j1 F5 Z% q& \/ Z
HRESULT GetDeviceServices(DevicePointer pDevice);- |: d# v+ p9 D1 O
void StartPortMapping();& z" p Y9 c. }( |
HRESULT MapPort(const ServicePointer& service);9 w9 z# ~+ `& D( _
void DeleteExistingPortMappings(ServicePointer pService);" N. T- N( W) p1 K% H
void CreatePortMappings(ServicePointer pService);# l+ q* G8 j3 P" c0 O% U
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
/ j) ~6 S- i, V2 t! j! | HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: u8 p, P2 C* T! H9 X, V2 ~ LPCTSTR pszInArgString, CString& strResult);
+ d. ~* x# }4 b+ @ void StopUPnPService();
; ^. L$ Y4 P" ?' X! z6 w
. }' _9 V' e. e" g* y# X& j0 m. V7 A3 i, a, I1 M. q$ }2 f
// Utility functions% Y4 K5 ?& }" m$ ]' k+ D5 c- U. p
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);( G! i6 k; U0 d4 C' n/ X
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
) G( ~$ O$ n2 P, C: D8 y. | INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
' S6 a9 p0 u9 }3 i8 H' ^* g void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);5 I4 t" T4 h" r% H+ p5 j9 ^1 z' K
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
4 H* i/ ]! {& `% L1 K& @4 a HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ P- j- `; u. O2 B- e
CString GetLocalRoutableIP(ServicePointer pService);* D. Q3 R. @* _5 a0 X. B. z; Z+ h
" j/ M& g! |- w1 W" S. A# T
: b6 W" p+ D3 T" T5 T
// Private members1 ~5 d B7 S8 q) w
private:" s7 S- g' y/ \' x, e2 w/ e
DWORD m_tLastEvent; // When the last event was received?
5 D3 r5 W2 v$ [% U9 `( u std::vector< DevicePointer > m_pDevices;; }7 b6 U& k8 o# m8 H8 e5 X, E) T
std::vector< ServicePointer > m_pServices;
4 p3 T" w" K0 c8 k9 A, k; B2 ~& j FinderPointer m_pDeviceFinder;) ` t2 i0 T6 j& r* y
DeviceFinderCallback m_pDeviceFinderCallback;
! y* M) i! B) [ [! {/ e5 g& T ServiceCallback m_pServiceCallback;& U1 k f2 u' ]; [) H) D3 T9 x" N
, {- a! t2 t4 a/ P$ [- C
j% H0 C# ^. o3 k7 p
LONG m_nAsyncFindHandle;
$ d" c( r' ]' V/ e' H) [) p- y2 L; R bool m_bCOM;
. Y' o1 }7 `2 t6 Q5 {9 N1 U5 I8 i6 O bool m_bPortIsFree;
. Q' p- B. W4 q' k# {8 s4 E) Y CString m_sLocalIP;" g9 P5 X5 v. v! ?: g
CString m_sExternalIP;
" Z8 K2 N2 _( ^) i6 _ A( P bool m_bADSL; // Is the device ADSL?; C% Y4 G0 z/ H% J% w+ C
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?; _; O1 M& B& m& R2 v$ h% ]3 Z3 S
bool m_bInited;, B$ ~& r! E, B2 f
bool m_bAsyncFindRunning;
! _0 S7 @6 T& `1 d: j( C HMODULE m_hADVAPI32_DLL;+ Z# f P3 A: ?7 U
HMODULE m_hIPHLPAPI_DLL;: H; X) W3 l; |9 Z, J3 H
bool m_bSecondTry;
3 _ J- y1 w2 j. p8 s3 x+ r bool m_bServiceStartedByEmule;7 k9 L1 S2 {: S- F& Q7 }7 G
bool m_bDisableWANIPSetup;9 d$ j+ H' s8 G& N
bool m_bDisableWANPPPSetup;3 U( Q' o: h, b e
4 J1 y2 N ^- Q8 `; p
* G- f3 L) ?. y) ^7 F% g4 l6 w) H2 g};4 t( t9 Q4 i$ s* f/ n: l! W
( K* q% J/ q; C
" y; c0 z6 b+ F- c
// DeviceFinder Callback/ N; o T3 Y% C- v) T
class CDeviceFinderCallback) ^( \' M& o4 Z0 e7 m/ i* w, n
: public IUPnPDeviceFinderCallback
* \3 f% F4 J9 a$ v( n o, N: e' }( E: ~{
8 \8 L: P5 A' A# i6 S/ Npublic:
( d! D6 f2 M4 O8 ? CDeviceFinderCallback(CUPnPImplWinServ& instance)3 ^$ }( z; R# Q; t9 u; s8 e; {! a m
: m_instance( instance )) n u! [6 ~8 ]0 W' A4 G4 m
{ m_lRefCount = 0; }9 m5 `* Z! e- o# |/ @
0 S4 N7 {; P9 H0 H& @ p' |5 u
) C, [% Z. o; I# Z8 n
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 U( o V3 o& b' W6 C9 M STDMETHODIMP_(ULONG) AddRef();/ c9 Y# T" q8 q5 J# ^* j
STDMETHODIMP_(ULONG) Release(); K: o) Y! w* c& H
: A4 {) y2 T7 ^- M C) M! z; h! [
, O0 ]+ |9 {. [) b// implementation
1 B: q2 x8 k# R' E6 D fprivate:
6 L; Q8 J* h; S; p HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);# D$ }1 U: E5 Z$ X2 O
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" N& ~7 V& N( x# H) ^8 _ HRESULT __stdcall SearchComplete(LONG nFindData);
' K+ x, R6 V x. Z3 e( U! F; q1 M5 N) t& w, F# }) N9 `* J
& v: {$ |# r {! oprivate:3 c# V$ A% \& E4 J- P
CUPnPImplWinServ& m_instance;. J0 s+ _+ m& @ j7 Y
LONG m_lRefCount;& V, K* x6 R! Z+ W* f* J. g8 q3 |
};! V+ ^+ n7 q8 R
- V9 F$ D/ H, q2 Z5 c' i
0 R( I8 n: O$ G6 P// Service Callback 8 L$ f5 R; K; ~) A6 x
class CServiceCallback
- w8 h7 j2 ^% I" k9 x9 ^6 t5 Q4 c$ I : public IUPnPServiceCallback
; i* W/ N4 z+ s+ n{
* N- R" `( g! D, Z/ y( s% r( K* npublic:& C6 e9 A# o8 @' S: L5 f+ Z- |9 E, o
CServiceCallback(CUPnPImplWinServ& instance)3 ]& U% d5 u7 l# } [
: m_instance( instance )- J" p# V/ u+ r6 w7 x+ \
{ m_lRefCount = 0; }( I- j. q8 j- V( S$ q+ @1 D* \
2 q+ q F! O' m+ T8 { STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' f5 S& u/ q8 V6 O3 v7 \9 q
STDMETHODIMP_(ULONG) AddRef();
, J: b- Z; B& Y. [8 a% { STDMETHODIMP_(ULONG) Release();# y1 {, i0 A' c1 W' w, S( Z
- d8 S: ]2 y3 }1 _
/ Q* b4 L8 f% L8 z, w// implementation
4 A* x' Q7 T- Y+ x( _private:
6 b6 Y, s5 l' R# B e) Z HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* k, l9 B2 `7 i% q* T& Y! {& a
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);1 U1 k1 D1 J" W* ^7 c; P
8 {8 i7 ~8 E2 q+ y$ }( K8 b
( r/ k) K1 F- T, P( t
private:
* G, N0 j& f! M- x CUPnPImplWinServ& m_instance;% m T5 T0 A+ l1 m5 n4 J$ O$ v
LONG m_lRefCount;# w: }" L) Y2 M; m' {# D" g6 B& `
};3 ]( C! B, u: W% t
. a+ g6 c* z: i" l& H! ]6 O* K( G
+ P/ P0 X. H* H
/////////////////////////////////////////////////! u* |( y/ @- l+ {, V8 O
( I2 ]& j' O2 n7 G1 c8 q; S
* X# O$ M! `! n. L; g) ]$ } `使用时只需要使用抽象类的接口。
6 w# x/ w2 ] G& u. lCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.7 W# e# S4 T( U
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
$ @; U7 Z' p, Q- q( a. S6 oCUPnPImpl::StopAsyncFind停止设备查找.6 J e9 a! V4 y1 B( ]0 ^
CUPnPImpl::DeletePorts删除端口映射. |
|