|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,* o0 J7 b% d2 V$ P& p l+ \
! m( g! e7 E! {5 P
) D- n6 X$ ^6 v/ `* V///////////////////////////////////////////
8 G& i) z& i) |% n5 S//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
" m- u0 D& V$ _. \9 `
5 ~# u* `$ J) y, p( p. p4 M% r \
#pragma once
6 E4 N) Q- V! i$ _5 r8 q#include <exception>
4 [& o/ s: a# D; ]3 i0 W3 j+ S+ x9 T: q& l. ^/ S; [; `) |
4 H3 u+ x( c9 K, t
enum TRISTATE{
/ [9 c* E* K; O. A/ b# S; E TRIS_FALSE,
% M8 r5 O/ R/ F% w% B TRIS_UNKNOWN,
9 l0 n z- y _ s/ Z+ t$ R, ~ TRIS_TRUE- j7 I6 v% K5 ]1 g) v# r- g
};
! t2 ` K# T. `$ J3 {: q$ L$ p
) r! M( r7 [" G |0 j$ q$ j3 a
( ^3 Z) p2 G1 _# a9 O# cenum UPNP_IMPLEMENTATION{8 g4 q* a5 t+ n4 W* i1 k* E: A$ ~
UPNP_IMPL_WINDOWSERVICE = 0,% [5 S8 g- j9 U4 m' L1 ^
UPNP_IMPL_MINIUPNPLIB,. ` R$ z; ?2 D2 A& i% V
UPNP_IMPL_NONE /*last*/
0 h! o+ i! v2 I- ]: G/ i/ L$ u};) s/ l$ }3 J# j8 S
2 \/ [8 Y1 o3 C( _0 G9 t8 p+ e
1 n" i: a1 r# Z& N2 p L) x: v- D
3 Z% ~' h4 r6 N! q: p. l
class CUPnPImpl
/ r( E$ x Q# z$ P3 l6 a{
3 W W# d" A- M, Xpublic:4 p3 D# ], p3 }: w0 m
CUPnPImpl();
) j4 G; X0 \3 Z, ^2 n; n4 G virtual ~CUPnPImpl();: s, c$ ^" x1 s5 t$ @# \
struct UPnPError : std::exception {};
( k: v& l( ^7 |/ ]8 \' V, ~ enum {$ @) v- b+ I. j. T7 I
UPNP_OK,
; {& \8 c4 S$ R UPNP_FAILED,
/ R: Q9 O3 i8 c9 ~# u% k; F UPNP_TIMEOUT+ p7 O7 h! r+ n
};- `* |' v* m' M( }
6 T( d; ]9 Y/ K
& G# a4 c, O# | virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
5 U# s( u( m. d8 n- z. o, C9 V virtual bool CheckAndRefresh() = 0;# K3 A9 v4 o9 p& X; X9 ^6 }2 E
virtual void StopAsyncFind() = 0;( k# `$ s# e- u
virtual void DeletePorts() = 0;
! _, m/ [9 G: `; m2 U4 k$ s virtual bool IsReady() = 0;0 I. j7 Z r/ ?+ J+ H/ i
virtual int GetImplementationID() = 0;. ~. g. x: b+ U) Y
3 W5 A7 H; Z" L1 O3 c. g
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" F. l+ t; I* O3 r8 e
6 L3 Q" t: e) [7 C7 U9 M
9 D/ C* ?) u& Z6 x1 M void SetMessageOnResult(HWND hWindow, UINT nMessageID);$ ~5 u/ _5 J" _* t3 ]3 X
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ I; N8 p0 i" f2 Q# G) L uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ E6 L/ f4 U' {9 c- H: L uint16 GetUsedUDPPort() { return m_nUDPPort; }
( @+ _1 v# y3 r9 q- f$ _$ I8 Y& Q( e. X$ Y, \
7 z; h5 [+ x4 ~2 o2 M& W9 x// Implementation5 J) \' {& j* A; S+ j6 g$ K5 p3 u
protected:
8 {+ d- }% T \. V% }5 d* | volatile TRISTATE m_bUPnPPortsForwarded;$ @8 z! s4 }' m+ q2 T- x
void SendResultMessage();' @: y8 }4 y- @
uint16 m_nUDPPort;- h1 _; f. t7 s% K, A8 K8 |
uint16 m_nTCPPort;
$ A9 G9 t' [; r9 ~' ^( R! a& L uint16 m_nTCPWebPort;
& k5 t1 [7 k$ r- z bool m_bCheckAndRefresh;
/ U; z# W |/ [/ I: t7 u- [/ F; o, R2 W2 e+ W! V" w" t7 w
! o0 x# D1 N2 q+ hprivate:* D9 C- g7 V3 p( c7 t
HWND m_hResultMessageWindow;6 C% ]2 b B- J$ ~
UINT m_nResultMessageID;3 B' p5 `( c, a! |, S" X+ P
( m/ }) d, m8 ?3 T2 }3 U) X5 k; r5 ~: b2 O" w \% X
};% w' w# P/ m* X: f2 B7 `
% A8 A l8 G/ j6 ?
- D" ?7 x, V3 Y9 |) O% h5 w// Dummy Implementation to be used when no other implementation is available
$ N+ v. s, L3 w& K, Pclass CUPnPImplNone: public CUPnPImpl9 R0 U/ W1 Z9 I2 H/ N# v
{9 P2 n6 ?7 J" q" r& Q
public:, t# X* ~$ i+ e) ]. M1 s& _
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
2 ?; j* }/ y* \& P5 G- L1 Q8 ] ? virtual bool CheckAndRefresh() { return false; }$ F M/ |* I/ @+ k8 q+ y
virtual void StopAsyncFind() { }
: C' L1 R+ t0 ^8 u! `/ }5 k virtual void DeletePorts() { }$ r5 C8 c6 V) b7 H! v& U9 m6 U
virtual bool IsReady() { return false; }
$ ?7 F8 P' b- X m4 X; B virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
. R0 b6 ~2 |3 b4 F1 I};7 w' n# k" f$ N, l9 O
( E6 L/ H! V" K* }
; s n" o L' `0 W: P/ O
/////////////////////////////////////! b5 w/ ~1 C! {- P1 H" E
//下面是使用windows操作系统自带的UPNP功能的子类
$ t; Z! v! U; v S$ y0 A! B2 w8 w' W) J% g8 W) w
# H) [, i$ }$ f' R6 t, H
#pragma once
; E ~, Y$ ^2 h& T#pragma warning( disable: 4355 )5 o& ]4 a9 W7 W% M1 b( X. R# I9 h
7 ]; f6 o5 G6 B: Q/ g) f+ a9 a0 m6 }3 y: z% T/ t' l, a
#include "UPnPImpl.h"& A; s6 v1 H; t5 v: D+ @
#include <upnp.h>
) c) T2 v! l4 d( B3 r7 S& y#include <iphlpapi.h>
2 E7 e. W# u8 a- G5 H4 E1 g#include <comdef.h>
7 y) k& Q- u1 J, C$ w& Z#include <winsvc.h>
$ [1 U8 X) N4 S# E
9 Q* I3 r8 P9 {2 G
6 D6 x$ }/ Z4 y& s2 }' S#include <vector>8 h$ X2 {( Y; m9 U5 ]! L
#include <exception>
9 A" z$ U6 J+ P4 H#include <functional>/ H5 e, q8 ~) z, L
2 M4 {! j6 y5 B$ {8 \3 X' A3 e: I! H# |( G: @; K/ a
4 C, u0 W/ C% l2 i4 j
" l6 Y- Q; U9 h. h# Ttypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;6 b6 U# N# p) ~' w1 A
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 o* u' D* V: ^4 s1 F% ^3 A
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
8 I: W! z& H. v% b6 V0 Htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;/ v% S( }: z; E6 D. p0 X5 b4 I. C
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 U x3 ~3 @; r# y) htypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;- w' U$ X- A6 H( l5 o' L" |
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
4 t) ^3 `% q7 D2 A6 \2 \
! J, H+ `. {, P/ z q: p8 I8 v- |6 z; Z% K( a
typedef DWORD (WINAPI* TGetBestInterface) (
1 ]- o! f2 b- a0 ~4 g7 g) B p IPAddr dwDestAddr,
* z1 M; w8 O& s$ v" m% d PDWORD pdwBestIfIndex4 U, v* p! K2 h% ?! J) |
);
$ | v* }3 b9 _# X# X
; V' ~0 I v% P7 ^ ?
) V9 a4 J. Z4 A( Atypedef DWORD (WINAPI* TGetIpAddrTable) (
; d/ \$ g7 a2 h8 }) @ PMIB_IPADDRTABLE pIpAddrTable,
7 d0 @$ T1 i' B PULONG pdwSize,
/ P6 F+ R1 u/ ^$ c+ Q# [' [ BOOL bOrder
# l" ?/ p/ C/ i' c. ~- s2 @/ ^);
$ ` w/ Y* }" _: {+ m& V ^" y' ^2 ]& m6 S1 }- f
; _; h2 l1 c3 @& Y9 D
typedef DWORD (WINAPI* TGetIfEntry) (5 s: r( f% ]6 C/ B2 h5 w& v% f
PMIB_IFROW pIfRow
3 F: }/ f) w6 F7 B);: b L8 A- u. x5 d M7 l3 B
3 z9 n% l- f# X: i. g0 {& y5 S$ A
0 @; _7 [* ]% k" m7 E% ICString translateUPnPResult(HRESULT hr);
# Y" j6 H7 U6 c/ O. U) B2 JHRESULT UPnPMessage(HRESULT hr);
6 l. d2 `3 U" A& ]: V: R- t. Q$ G! f+ @0 Q) R( f0 V3 U
( X5 b4 o' r. s8 Y9 Iclass CUPnPImplWinServ: public CUPnPImpl
' i! t( c, A8 b" ^, v{
7 h+ q' M0 C- `3 T3 R friend class CDeviceFinderCallback;
# {% [: W% K1 B7 } friend class CServiceCallback;; @ J. o6 y) g" H! m
// Construction
) m0 ]1 [, t- ~& Apublic:
9 D j5 c0 ]' L- ~, w: N6 E virtual ~CUPnPImplWinServ();% c8 q: N' J5 c d3 [5 r
CUPnPImplWinServ();
7 F' }8 q) y9 j. h/ D: O ], N4 d& ?9 v' C* Z! w6 z
% f1 i( A! v( ?/ o virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }3 ~6 n5 F7 W1 o2 M2 m/ A: ^5 h
virtual void StopAsyncFind();2 g- ]% J( P" u- Z: i7 g
virtual void DeletePorts();
7 F+ U% A5 q& f: z' t virtual bool IsReady();9 u% w! w% o* N, U5 Y4 p& k# y2 m
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( Z! v2 Z) c3 o2 g! S# U
' W, T- B0 S9 X& G" T0 Z+ j/ g- z1 h! j; n% X
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% K$ P/ m" z6 e$ I; f2 c" ]. l // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
5 \7 v! Y. }6 z: W$ c virtual bool CheckAndRefresh() { return false; };" N$ G/ g5 ?' y1 \. I5 E9 I/ _
+ b" S/ ]3 X( q2 b0 G% y" q, m) H; j0 i" ^5 Y7 y
protected:) d& k, b+ e7 b S
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
Z9 e I0 Q( X2 ]5 e" H) ]: ] void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
0 g: W! d3 u% F% `5 L+ a( B' Q' i void RemoveDevice(CComBSTR bsUDN);
1 t V$ n+ m w5 z9 Z bool OnSearchComplete();
+ G% R" H9 a1 \* u' L+ H* | void Init();) D% F' L8 w; _) z" i: x
6 u% D3 `& V3 g+ v8 L, N: K0 Z% I. o) u3 p* n
inline bool IsAsyncFindRunning()
- J# ^: U2 a/ l( E) j4 ]# V1 l {
8 R- n) X2 N: a( c if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )/ C' J( v4 }+ j7 U
{( B* C0 b/ n; }3 f
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );& w2 e2 z; ]) X3 u
m_bAsyncFindRunning = false;
; f o4 ^. H; U1 U1 p }. l# L1 g, K9 \5 K! ^ G
MSG msg;
& g/ ?6 j% w2 h( E% ~0 T0 I while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
1 y" z2 k k* [8 @+ H' U# T- R {$ U: P+ k* m& c
TranslateMessage( &msg );
9 q$ `+ U F, W/ c DispatchMessage( &msg );
, w0 |% B! }- X( [+ g* k }! @( b. @' C& x1 {& s4 S7 g
return m_bAsyncFindRunning;
. R! J* S% W# Y4 _" f; ~& T5 S. v }# g: t& ]( ~2 m7 B! w- }
6 r# m$ w9 Z# [3 c0 ~% K' U% ~
- I+ A& k# ]5 {' N. O3 s% n
TRISTATE m_bUPnPDeviceConnected;" ]0 b' N6 A& I+ q- @' I, a; W
: |9 J* v* l" M- x" I/ m6 Z1 h. A
7 `0 I" b) P, \% h// Implementation
6 }7 C! e2 O! \" Y* G // API functions
* ]6 [* s" T+ ?8 m( W SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);7 P' `0 H' E; ]; Q! ?6 o
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
1 r% A3 n; H- i3 d' ~) ` BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);0 J" ]- m x, s% ?2 g0 x# M! n5 B
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' h4 q8 n6 u3 V) X0 } BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);2 m/ W$ m% I1 }% X% G- H3 ?# z
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
: g M2 {4 N6 ^& Q; T
! w( ^. n$ Q% d- f
% b$ M+ @9 k& P/ I* U. @" d* r* b TGetBestInterface m_pfGetBestInterface;8 Z# \1 h; y* n( n% X3 x4 K
TGetIpAddrTable m_pfGetIpAddrTable;
0 o, h4 j' Z, r. _5 l TGetIfEntry m_pfGetIfEntry;
, H. P8 |( @9 C4 V
; z; ^& Q& W, ], x: {
$ R0 q+ Q# } `. J. i$ [6 l$ C; } static FinderPointer CreateFinderInstance();
4 q! j1 }+ ^ S! w# ^% ~ struct FindDevice : std::unary_function< DevicePointer, bool >7 q$ O. X# d" `7 V/ m
{8 G: U: [+ \- m6 Y1 O, P& U
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}$ V, g0 s( h: z" f1 m6 Z
result_type operator()(argument_type device) const
, }4 {9 x4 X+ c. i# M/ y3 L {
+ {. Y* D: H3 D3 S. H& t CComBSTR deviceName;6 C a4 I( S% I& h. n
HRESULT hr = device->get_UniqueDeviceName( &deviceName );8 L6 X/ r3 j* _" C; ^/ {7 w
7 M0 N. p: Y1 c- U3 G4 s9 P
6 D6 { K+ A+ W- ] if ( FAILED( hr ) )8 P5 K$ K7 j5 L
return UPnPMessage( hr ), false;+ w. v2 g( ^' L3 B: E0 Z
9 A5 l) g- F5 k& N9 M; k& }
! G# f) j6 O& {% m3 V
return wcscmp( deviceName.m_str, m_udn ) == 0;
) A+ L1 x T* \0 O" ]% v( r }2 J5 ~4 ^5 J9 U3 W
CComBSTR m_udn;
: E8 I& p6 U' }% u };
4 k* F6 }; n* u# i* S6 ?$ Y ) Q& M, P( f& ?% c7 t2 L; q9 Z
void ProcessAsyncFind(CComBSTR bsSearchType);; U/ D7 b @# k6 I6 ?
HRESULT GetDeviceServices(DevicePointer pDevice);
- i9 J/ Q5 y0 Z& k9 _& l/ D3 J6 t void StartPortMapping();: o9 v% t Y( _2 X* N4 d8 i4 J
HRESULT MapPort(const ServicePointer& service);8 E7 K8 _9 Y# T
void DeleteExistingPortMappings(ServicePointer pService);
4 X/ H1 P; [9 }' \0 N0 L" l void CreatePortMappings(ServicePointer pService);1 D1 S8 V5 Q0 S/ C0 p; j1 L
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 U+ F$ O. l z F
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
) i6 |+ z: }. k$ ~, j LPCTSTR pszInArgString, CString& strResult);
/ [. F2 |) G$ y; B void StopUPnPService();
; [% c* y( A% Y/ J4 @( F, ?. j7 n; H' ]" p- |
- v' B7 I. i8 L: S& E, B
// Utility functions
; E; ], s6 G5 x) y% Q' r+ J HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ I. t$ O* A6 `. \# r8 e9 y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. E+ n1 f4 g. @1 Z# H0 a8 Z
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# I' T3 _. v) ]2 i void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);5 Q' J( ?+ A4 J Y1 X
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound); b9 z% C) P7 _" r* A$ P# c
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
9 x& u2 V8 @$ N; m3 ]/ } CString GetLocalRoutableIP(ServicePointer pService);/ t) n; u/ Y4 f" u. Q" t
2 a- u+ E+ }4 N: U7 v# Q: I- S, i
$ ~. H) s! U5 @
// Private members
) W& i5 F6 o4 t0 ~. }private:4 R, V' s6 G6 ~! r/ l
DWORD m_tLastEvent; // When the last event was received?
- {7 E) ^5 c2 k5 E8 j1 t2 L! L std::vector< DevicePointer > m_pDevices;! S! F. {2 S. e# O: e
std::vector< ServicePointer > m_pServices;* j/ f+ e) b$ ?8 u/ T
FinderPointer m_pDeviceFinder;
7 R4 d. |" M% Z5 x8 n DeviceFinderCallback m_pDeviceFinderCallback;) m# J8 G/ }. O e
ServiceCallback m_pServiceCallback;
) `3 k% K* j' W$ K1 H3 D; U, ]/ W* i- Z/ {8 p- t: p; Q: x! I
6 u( J5 `' Z2 j
LONG m_nAsyncFindHandle;, O/ `. K: k+ G3 K9 P) r
bool m_bCOM; q" y& F2 S: [0 {/ }, W
bool m_bPortIsFree;7 o" V" ~- t3 d
CString m_sLocalIP;
8 V! M3 `% R: P/ b! B Z4 B" n( Z CString m_sExternalIP;
3 U* Y# q1 Z- F6 m n1 V bool m_bADSL; // Is the device ADSL?
j3 ?* {7 ^5 z2 | bool m_ADSLFailed; // Did port mapping failed for the ADSL device?' @1 `/ d+ S- ` B1 j) @
bool m_bInited;
/ A- H+ @. d# w" a: X e- h bool m_bAsyncFindRunning;! P8 a9 F: W0 S" b e& X0 U7 W
HMODULE m_hADVAPI32_DLL;/ f- N* s6 R/ O5 J0 y7 ?7 r
HMODULE m_hIPHLPAPI_DLL;
7 Q7 ^! E& \- k bool m_bSecondTry;7 w& Q( |6 O* I' ]6 w6 P
bool m_bServiceStartedByEmule;
! k3 {- Q. Y* @; W* L& X; k bool m_bDisableWANIPSetup;8 K- e* ~& y( Z' ~; r( s# P6 Q) l
bool m_bDisableWANPPPSetup;& T5 I/ J9 ?5 O) |. W# B
" |- t& \# x- L* N; |% D
* w7 ~" u/ X: C/ L& d' t9 n ?};. g9 C W, t( D7 n. F7 S
! u5 M: i4 y. B" }: y! U8 z- K% r1 e* M
9 l% {, {% Q9 N% F6 k// DeviceFinder Callback* `' j$ g1 n4 z0 m+ d z
class CDeviceFinderCallback4 V# t+ Z4 }% s4 E- w# P
: public IUPnPDeviceFinderCallback
H n% D. t7 ^$ ?8 m{
. Q1 N( Z/ H1 R" K0 k' Apublic:; k8 o, w9 c+ X# I
CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ r4 D! j4 P5 a' o: v, J' |" J : m_instance( instance )
' j4 t+ u% `$ _& e; B7 t2 c { m_lRefCount = 0; }0 U/ f6 ]/ I4 Z% N! l% \6 _
) m: c6 @8 k" }: ]/ C3 a9 P# n* c' x: ]3 {0 ~& G9 A0 X
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 W- Z) z7 T, k' r! e a
STDMETHODIMP_(ULONG) AddRef();
/ }& u( ?8 f6 O: p- k8 B; p STDMETHODIMP_(ULONG) Release();
) ~0 M9 ^ p- }2 x* w, ~- t$ d' t9 n% ~# O8 J6 V
2 v( l/ C& ?5 `# q* L// implementation8 B% b/ [6 Q ?/ n
private:
/ T% _- u6 l0 C7 x HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 u9 U% B4 Z% X$ o& C& B7 ~
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);* b# q7 |* I" ?: e$ n. ?
HRESULT __stdcall SearchComplete(LONG nFindData);
& y0 i* A1 V7 Y1 D% U: K* I4 L" D4 W7 ]6 E$ g! N
' q' [) K2 }# L3 ?private:/ ] {6 O& M! m9 l" N
CUPnPImplWinServ& m_instance;
% U5 S9 {& l4 M- _! d LONG m_lRefCount;' K: L& V3 ]* g: @
};) _7 D! u, [' n5 G( b
: P( c7 v) P; \, m( K
) k" e3 n% k4 Q
// Service Callback 5 u+ A1 T: @6 m
class CServiceCallback5 {0 G9 d& h7 A4 t% {
: public IUPnPServiceCallback
' x( `7 z; ?) s7 ^8 X{9 I6 T% L3 A- m
public:
4 @- p' r s6 @& \! H; \. Q CServiceCallback(CUPnPImplWinServ& instance)" u# q# j7 q& o) |& J
: m_instance( instance )
& u( f8 q: Z! m: Z! _0 f$ g- G { m_lRefCount = 0; }
6 z! f8 l$ N6 E9 U: v& F6 X6 ? ; u' g9 z# {' d
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 {# \" |2 l4 Q7 L1 f# @ STDMETHODIMP_(ULONG) AddRef();
: \3 o: O7 ^& ?. \6 e STDMETHODIMP_(ULONG) Release();
" D2 U# W N$ H7 q! u% a7 I
, r, D2 K( ^3 m" h
! s, r0 ?) B/ S) V0 g& m8 ^$ ]// implementation, g0 d* E- w- \/ ~
private:" X0 j" W1 L' L( g f# V
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);# W9 G8 E6 Y8 E4 P
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
# v+ v: k$ e" @0 V% q; ?! T
0 X& e8 N! [: n, }) r- E
: ^6 h9 E' J4 B$ W+ f% Fprivate:9 n9 @+ f+ K" T( f9 |1 c: v
CUPnPImplWinServ& m_instance;4 K) m2 T3 ^- { x# M7 N: Z9 }" o
LONG m_lRefCount;7 y! q. p& I X, m' Y9 {
};* F' ^: ~( d# l; O
1 c, e) v5 t; E) k& a( y
3 S$ t! b; t/ U- @% t- s/////////////////////////////////////////////////
& R. K! ^7 X/ V& O8 N
3 p% ` u7 I) i Z' X' x1 G4 Y) y4 K1 K& |" ]% E* O1 d; W
使用时只需要使用抽象类的接口。
' J3 j$ `! w' C$ r& M/ ECUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.# r9 g1 V5 s( H( W8 {
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
5 @+ w1 y! A7 ?CUPnPImpl::StopAsyncFind停止设备查找., q ]; Z" @3 P5 ^' |% ]. W. U
CUPnPImpl::DeletePorts删除端口映射. |
|