|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,1 \4 l/ S5 }$ C6 X0 j1 x$ P6 O
- f9 {: j3 H; t/ A! C. t/ K) e; L8 ]3 a
///////////////////////////////////////////% b+ u6 Q8 H9 P! ` C( y5 u
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.) L; S7 ]/ w0 t5 Q/ [1 e1 }+ b3 m
' N* ^+ i f$ s8 D1 p( k
% E) d4 ?. ]' c; \, G- }8 h
#pragma once& [( n/ ~1 |9 u L4 g C2 X1 n1 F
#include <exception>6 M. v* B: M% D( x8 h
# G- n C0 z/ h. p8 d" i# _
4 F! C2 ?1 i9 k/ W9 O enum TRISTATE{5 S% v6 a# i3 G4 P
TRIS_FALSE,
% t' I- f* F0 C3 t TRIS_UNKNOWN,; z, O+ C4 C6 I& t
TRIS_TRUE4 O6 ~0 S/ s( p0 Y
};" m8 |/ e" a8 p7 d/ |
- R! [3 h2 E/ ?1 a2 Z$ O# V: i
; K( c% I" S! ?( S tenum UPNP_IMPLEMENTATION{
$ |; H; p7 d. m+ U4 H; k+ J N UPNP_IMPL_WINDOWSERVICE = 0,5 Y* s6 Y( U0 W% L
UPNP_IMPL_MINIUPNPLIB,
1 t3 p% a0 L* H UPNP_IMPL_NONE /*last*/
3 r$ K# Y4 o2 Q" B0 E* n};
4 V8 L y1 O! ?* @& s0 w5 G- h) b2 j( ~1 r& ^! p3 e# `
- \ E7 J$ |: u( c9 [; _* I2 Y0 P0 F0 m& g5 B
1 i6 i* C' h( U2 bclass CUPnPImpl- D+ f# }$ J7 S4 i+ }0 V
{1 u: f9 ?$ v: Y s8 `; t
public:$ O( b5 h4 t: x& W# v' w
CUPnPImpl();
# y! [- V/ Z* b' [9 c virtual ~CUPnPImpl();
: X3 V3 r8 q1 g( ^4 p struct UPnPError : std::exception {};
' \" }/ o" X4 u" M enum {8 b7 A' h) H& R1 _* F
UPNP_OK,' m+ O3 W; l- Y s. ^$ k, s5 Z r5 _
UPNP_FAILED,9 E1 Y/ ~' S1 K3 V: o# r
UPNP_TIMEOUT
' O, x% \& M- f& v };
7 i* O6 b1 g" n6 N8 [& I: D' [1 g/ X+ d2 I. ?. Z9 s1 m. J
7 t, X: W7 K. M) @$ f' I virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
' b9 p/ U) ?+ {! \ virtual bool CheckAndRefresh() = 0;
" F7 |, E4 m v, a9 H1 h; E virtual void StopAsyncFind() = 0;
2 E1 d, j$ `7 Z5 u) s2 |) ?, W virtual void DeletePorts() = 0;
4 i6 o, D* s+ H5 i/ \: O* U virtual bool IsReady() = 0;
7 R) n2 B/ w8 |: Q: B8 W virtual int GetImplementationID() = 0;
* B3 K0 Z3 \, Q$ x
$ M- {) g# w+ x void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping- U2 k: D7 ~* n
$ Y$ V0 L3 o9 r {7 z
6 F* v% c( G9 A# {, g3 I6 p
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
6 Y* [ k) f9 h$ C: M- ^ Z TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 q9 Z6 e# @$ {+ ?$ {" b0 n$ i uint16 GetUsedTCPPort() { return m_nTCPPort; }
. o6 a- w% f8 A& X( m7 l/ C uint16 GetUsedUDPPort() { return m_nUDPPort; }
2 e3 E0 [$ D* x! C# d* U
. d- |3 N! z7 K# }; f$ H/ p! p& I2 c8 x
// Implementation
" t* C0 p% Z5 e" m/ S: n) xprotected:) u6 S1 }3 i- K) `# M: T; I
volatile TRISTATE m_bUPnPPortsForwarded;- H) a$ H; }% m* [; Y1 C
void SendResultMessage();
, W3 U1 q/ \4 h, u, x uint16 m_nUDPPort;
4 x0 t+ D) V5 @# F' Y* L* p uint16 m_nTCPPort;, G2 ~$ F. w9 p: v, T
uint16 m_nTCPWebPort;
) _0 X& n1 r. J3 o1 R- D bool m_bCheckAndRefresh;
% z( h6 a$ Z- w
- l. ~4 g7 ~4 N. k! s1 L
( a0 O/ x" q3 O7 l5 tprivate:
/ [2 D! r" f% \7 x+ b; V d HWND m_hResultMessageWindow;6 \, C/ v: J2 g8 j
UINT m_nResultMessageID;
& ^; e' t4 R5 `5 X/ [) _8 u" M( h2 @
% R+ G' K6 B' z. d- z};
! | _8 z7 [9 Y: O8 [5 O0 X
, F. U/ e- n- p+ z: R5 D7 \5 w; E3 F: b) H' c
// Dummy Implementation to be used when no other implementation is available
% u1 X4 F. F* r7 o; P! Iclass CUPnPImplNone: public CUPnPImpl
$ K$ O7 c; X' T3 j' R' { i0 {{7 t. m l _: {7 D: |
public:
3 n1 t4 w( F8 l& W! m ^( y virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }) N1 Q/ o- f3 ]; v8 \1 |/ x9 I
virtual bool CheckAndRefresh() { return false; }: p( L' U8 s5 J% J/ B6 p o
virtual void StopAsyncFind() { }: K+ i3 y2 i, q6 ]! Y, ]8 t
virtual void DeletePorts() { }
% d' N/ l' N0 ? virtual bool IsReady() { return false; }
% i f$ T$ S( e virtual int GetImplementationID() { return UPNP_IMPL_NONE; }: D' F2 s, \! S/ k$ c* [
};. P- c9 F; g, A; Y
" \! F7 C0 x( b$ @8 H
4 v' @* O& S! W. h: y; w/////////////////////////////////////- r- U1 Q$ `2 [# h/ d- ?
//下面是使用windows操作系统自带的UPNP功能的子类
, g& ^; r M) H; f7 x( k- P6 A* e V, O' S# {: j
' o. `$ j( i" q' Z9 C' z& D, M
#pragma once- z5 t% Y5 R* ?# b' K% @
#pragma warning( disable: 4355 )- {& h) p" W$ x: w! j% T7 o: B- M5 k
0 {* y7 t2 C4 Y1 w+ B8 z
: j9 U4 Z6 r9 M
#include "UPnPImpl.h") ~! T0 e2 g/ ]
#include <upnp.h>. ]$ o0 s8 e W, P. }. w# @! _
#include <iphlpapi.h># E+ \! _- j7 |& G' C
#include <comdef.h>
: f5 [: E/ T; q% s+ z#include <winsvc.h># v" M9 C1 t9 M; F3 U
/ J# s, H4 U8 ^& h
: X& n8 r# G2 |* ^# J8 }+ }0 Z#include <vector>" ?8 V% [3 I$ W! f4 X/ R0 v( R' E Y
#include <exception>/ I: d5 I, u b/ q2 Q- Q3 F
#include <functional>7 I% z S- }$ I* r9 \
4 H. N5 c4 F& T( p
$ O& w- W+ K% r5 m9 }. F. W4 f0 ?4 _+ m3 [$ _' T
/ j, S# I% W# m7 ?) w
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
' L2 f- m+ p5 C6 Etypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;* ]9 p* |2 n' g3 T) Q3 _
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
7 B* i6 {6 P& r; xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;( M% M% r' F9 l4 N7 a: B* I
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; Z, S( T1 m4 a4 ]& S
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 C3 h( B+ x6 `# @5 B3 R) dtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ E' t/ C- Q! p6 @8 k9 Y; q
7 c7 G0 _+ W8 ~7 ?1 s, j7 H& a) |/ c" A# X+ P
typedef DWORD (WINAPI* TGetBestInterface) (% u2 I! B# f( z7 L. `
IPAddr dwDestAddr,8 {9 X: i# c$ ~3 c1 j" v) D* i3 y7 `
PDWORD pdwBestIfIndex) T! p8 t% r7 k" d2 J
);
, [$ p( Y. p4 J2 G+ P# M6 ?* q1 e- A; N+ B: h
- p' U- G- E: ^+ y" M! i# _
typedef DWORD (WINAPI* TGetIpAddrTable) (
+ l5 N: S: E e" F0 E! G! ?3 k& A PMIB_IPADDRTABLE pIpAddrTable,; E. } n' O6 y- `+ T' ]8 |
PULONG pdwSize,8 \2 z1 l+ n, u( @) | v, x' c
BOOL bOrder ]4 R& y6 k$ j+ o& |
);
, a# U# j* G5 S) e- q
* b7 n/ @( n3 { V# c/ X0 u7 e8 V( T
typedef DWORD (WINAPI* TGetIfEntry) (! @9 b+ x0 f/ ?: K6 n
PMIB_IFROW pIfRow
1 e S* g% ?' Q. Y. N);
9 n+ @# _8 ~! W" `8 c; v1 x6 D8 m+ e' T) b
1 V( N- \( t" m/ n3 aCString translateUPnPResult(HRESULT hr);
- Y& ^( N# U6 a) T' aHRESULT UPnPMessage(HRESULT hr);7 l$ V. N: e" a+ h8 W
- j+ ?. }; W x w; m
# N g6 k W2 c% y) w7 P o0 U3 Tclass CUPnPImplWinServ: public CUPnPImpl% O' q/ A' K( x
{
* v( t+ m$ d! q- a; s friend class CDeviceFinderCallback;
* u' |6 R: \7 d4 R! w6 j) V friend class CServiceCallback;! H; {2 X2 G _! {7 X' G/ h: _5 T
// Construction
: I3 g6 B! Z. Hpublic:
* |" d& s& u- B" {7 ?1 \ virtual ~CUPnPImplWinServ();3 ?8 O. X) |: [, I; D
CUPnPImplWinServ();
! R* @' B! R, a
: |! w6 s8 V) s+ v) [3 ^* ?4 d1 i- m2 \6 Q+ O; [$ g3 B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }/ s% O- b/ O5 l# V
virtual void StopAsyncFind();8 K$ {9 | T6 A9 ]4 f6 r
virtual void DeletePorts();$ s) ^: B/ E& z0 s
virtual bool IsReady();) b% z2 S3 l b
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
+ ?! j$ F* o: Y) o
9 @2 u7 f& K7 K8 @$ b
6 L. p# _& @8 p1 X3 Q5 _7 e // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)9 e* H" E: P1 h m9 y$ e
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 E$ ]( r4 P' J. o% W. t' e
virtual bool CheckAndRefresh() { return false; };
1 r- n/ W' X7 g3 v8 I
9 r% D) l$ n: H8 @& m/ g) g/ E5 e7 ~( q& J
protected:" h$ s' b" [7 Y. \0 r* ~3 X
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);, }" m! I; c H/ i" `
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);' M% L/ j" @: r J) f6 q n5 M
void RemoveDevice(CComBSTR bsUDN);
: s [2 ]) d& l2 H* e& M bool OnSearchComplete();! n1 N/ o( C0 K/ l( }8 i9 x
void Init();. r5 u! G. P$ v
. y0 T& `8 Q% h4 n2 V3 [
: Y8 y, w: e9 i4 _, \. A inline bool IsAsyncFindRunning()
/ y0 `6 p3 I" {- X) n1 w {
8 Z& Z% P! ?1 s. R if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )4 L% ^; Z2 I: a, j) w
{) \& k% N1 p. O/ c" Z+ i
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
+ ]5 S* B/ ^& v+ H; N m_bAsyncFindRunning = false;3 j) z3 l3 l$ L2 i+ e. @0 K% ?
}- A3 V- [ k: d
MSG msg;
) C, c' \. l# X! a3 b8 Z( M- ? while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )5 S- ~7 y" a* D6 C. ~" W+ L
{
+ B% G) ^3 O: G4 ^! E/ G TranslateMessage( &msg );; z# Q5 S$ o h/ m: R# r! T
DispatchMessage( &msg );. n4 N: t! F' ]) o( k0 z# m
}, ^9 K2 d4 ^( h0 Z
return m_bAsyncFindRunning;# x! |; p; ?8 w+ O0 l
}$ h, o/ C$ W9 V3 y4 _+ Z' ~
7 |* r& O5 [2 U d" y
8 M% ?! h9 K$ Y! d+ \ TRISTATE m_bUPnPDeviceConnected;
! [% ~& [. c1 f4 k0 H: l: m- j, H: y
. C7 k$ Z! ~9 d% j' F// Implementation( P/ \7 |3 X" }6 C# @8 e2 p
// API functions. Z. \+ G% T& d; F, t% m, q
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);. g4 v# m0 U7 h
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);9 O+ y8 ~4 h+ O3 y2 V0 U
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);/ t; C0 J0 Q; `8 J% b" _
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
7 Q0 {$ B+ t' t% v d4 P BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);; l; I# l$ K6 [9 w
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
# {; D P$ ]: J3 t/ N$ k, [8 @% y; g7 V0 j+ b( w
$ ?8 x* b8 g. k
TGetBestInterface m_pfGetBestInterface;6 _2 Z3 m4 I2 ]* a$ C, S
TGetIpAddrTable m_pfGetIpAddrTable;; q$ ?4 G: `8 R _, N
TGetIfEntry m_pfGetIfEntry;
' ]: g, x3 ]& q
. ~+ X: N& O4 y+ s: z* l; L( ^2 |0 ]) ^7 K
static FinderPointer CreateFinderInstance();; \8 f' \! a- j) e9 O- j% c
struct FindDevice : std::unary_function< DevicePointer, bool >
% n5 ]. @; c' R$ w$ ] {! @5 L, i; B" O& J! C/ _ S+ ]
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
2 S y( s' P" D8 P result_type operator()(argument_type device) const
+ ^: R L) ^/ N n {
3 t ]2 k; J5 g6 `" b CComBSTR deviceName;( J9 U6 `2 Y4 {4 B9 i
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
" E* L( Z2 i6 U8 h, R5 w$ X- z1 v! a! S) F2 V; H( T/ m
1 r4 S. D; u- l: ~5 k" @ if ( FAILED( hr ) )
5 y. } M3 |8 V; u M$ j. [ return UPnPMessage( hr ), false;
# D) n. J$ L* B! |* ?$ `$ U0 \5 x4 c$ L# v/ n( N
/ ~$ s3 b A- g# f W return wcscmp( deviceName.m_str, m_udn ) == 0;% y6 G6 V; b) ]. ]2 b" F
}
, l6 N3 ?0 h; C/ p! J" d% j CComBSTR m_udn;
4 z G3 O- J) T+ r3 v. F };6 F t, |; X- o
# V: p1 ]/ @& W void ProcessAsyncFind(CComBSTR bsSearchType);
Y+ H+ j+ v9 a( ] HRESULT GetDeviceServices(DevicePointer pDevice);
0 R5 @) `% d9 u/ i) M' Z- L* ` void StartPortMapping();
! o' G8 @9 i8 M6 h2 x" W- w HRESULT MapPort(const ServicePointer& service);
# A8 c; [# A% L void DeleteExistingPortMappings(ServicePointer pService);2 H+ N3 D& P- x* q5 p) v3 o6 d+ t
void CreatePortMappings(ServicePointer pService);
g7 B4 h) ?" i8 N HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ p6 Z: F0 x- j' U+ K3 [: x" J
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 V( H1 \" {. @3 s% }4 i% s( D. F. U LPCTSTR pszInArgString, CString& strResult);
( u3 F( G1 }; k& |7 d/ d void StopUPnPService();" l3 C7 B6 \: z3 P3 f
; C5 a- V; [' y: y
+ i* w6 a; A8 B9 o // Utility functions
3 h+ C! c$ W7 F. B HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 G- y l3 j* \! B7 S+ |3 R# z* M INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);1 h% P t! r2 W; d# r' c
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: f! w M/ W4 [0 C |6 U: M void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);1 ?- A3 m" q) U6 |) C
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
5 x, h) Q3 o$ e3 f( }7 m HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
b) ^3 u7 x1 O& Z CString GetLocalRoutableIP(ServicePointer pService);; s5 z/ W# h; C4 e% [% b1 a
( M5 `, U, t# s
; O/ e2 e8 N" y; x( b- i
// Private members5 G# ` x) ~2 H5 E4 n; K7 K; _$ b, U
private:
3 X8 B6 e9 b7 j5 t( @ DWORD m_tLastEvent; // When the last event was received?
! f) P$ N9 {2 q: j std::vector< DevicePointer > m_pDevices;" W% w* j$ T$ c3 v# K9 w
std::vector< ServicePointer > m_pServices;
8 g& l1 C( R% g FinderPointer m_pDeviceFinder;
6 R& u; J" ~0 G4 C! H DeviceFinderCallback m_pDeviceFinderCallback;3 r" S; o/ n1 g% k) c
ServiceCallback m_pServiceCallback;
$ I2 s8 q6 L3 X
% w5 I. ^. }5 p* h) j5 z- q- J H" g9 k9 R! V8 a
LONG m_nAsyncFindHandle;
9 J% j4 ~5 ?6 u, B& w bool m_bCOM; ]$ h# E S! W" d! K- M
bool m_bPortIsFree;
( M1 l& U+ f) d% O CString m_sLocalIP;! B8 V% U' O( b" P% m
CString m_sExternalIP;
3 s3 w, K+ ^+ w$ d0 U/ U: j' F/ K bool m_bADSL; // Is the device ADSL?
: h: j3 O( L+ U: Q1 U5 W9 [; m4 r bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
* c" A0 ]* h k, o" U# H bool m_bInited;# s' \) D7 Z5 d' E5 U: F
bool m_bAsyncFindRunning;# J4 V7 o2 F' u$ E
HMODULE m_hADVAPI32_DLL;
) h3 D; `* E% G' P3 T HMODULE m_hIPHLPAPI_DLL;
$ j# M; K: }$ U/ F9 c( b4 h# }7 X* Q bool m_bSecondTry;& e2 W( }* f0 x, F
bool m_bServiceStartedByEmule;
Y# x5 U8 q0 I& ?# _% z$ `) N bool m_bDisableWANIPSetup;
W7 x t* P7 A9 b% ]- F, y" N bool m_bDisableWANPPPSetup; K7 Y" b6 {+ }9 N& `& _1 K7 A3 G
2 u. Z& U! O6 A. U( Z
9 a9 }% `7 M, N4 h% C0 T" G$ j
};- v% G. k- e! T2 |8 D& b1 j6 O
; H% u4 {- t: X: K5 d) A) d
4 E X* S0 M7 g5 j# i7 I/ u; m' O// DeviceFinder Callback1 u6 m9 V! _1 H" o' J3 F
class CDeviceFinderCallback( O6 T6 }: r/ d6 ^- V
: public IUPnPDeviceFinderCallback
7 Q# z: H: X- k d0 V; g/ b{
; O# |$ K: [- t: j5 i/ gpublic:' [/ l4 Z! a, y5 p
CDeviceFinderCallback(CUPnPImplWinServ& instance)
7 U% w- V; }0 z; A' [, o% z : m_instance( instance )7 C; b; K" ~# H, u0 x& C* G+ U2 |: K
{ m_lRefCount = 0; }. o( V( ^3 S3 l% \8 G
$ K9 m3 N y* y) y; O
" r! H% W' d( F6 ? STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ a+ l' p) a. ^1 B: q STDMETHODIMP_(ULONG) AddRef();
* b2 l$ ?5 z( y7 p( p' a2 ~ STDMETHODIMP_(ULONG) Release();
7 L. x4 g4 s; ~) m+ V* Q, E3 n; F: J# [
i" O0 B" E/ C0 J) p# G- H3 p; _// implementation
+ U! L) X8 r0 i9 C! `6 Y* k5 K8 U! o3 r% Aprivate:
y/ |9 Z2 ~, O' ^ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
( B1 O3 Y$ k1 b" z! b* k: Z HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);6 v8 P" ]+ \7 E$ Q6 n
HRESULT __stdcall SearchComplete(LONG nFindData);
' n) c5 C6 G3 c% f( i9 y# i+ J3 e! I# ]) j1 a5 c
L+ @% A4 A c) _- r9 F
private:$ q+ l& I; A: G6 ^9 z
CUPnPImplWinServ& m_instance;+ B, w: L4 [5 n( B% o% @* v- X1 J
LONG m_lRefCount;
2 T# E& N$ c: u};
5 |) e3 T3 M j
, J5 V; |6 H7 I
. G4 Z: B1 q; h" j+ c n// Service Callback
% P( d* Z% @9 r' ]class CServiceCallback
8 |1 Q' }- h3 W h : public IUPnPServiceCallback3 q0 [. v& i/ n7 n" |, r
{
: T- Q& N1 \- S% B' opublic:
+ Z1 {+ Q2 S; j' p" s0 S( w CServiceCallback(CUPnPImplWinServ& instance)
6 f3 A4 d. M' A% ~ : m_instance( instance )
( s9 F0 v4 B* U3 R { m_lRefCount = 0; }( K4 R9 p! b. k& Z6 g
. e" i( b- R6 l% a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 l2 @6 c4 T5 }5 @. D# j8 \
STDMETHODIMP_(ULONG) AddRef();0 O' P: k! x" ^+ k, Q5 [
STDMETHODIMP_(ULONG) Release();
0 y+ B4 P+ ^" q* E0 d3 h* ~8 d, {% w& [: Z% x) E
" V j( }* k T. b9 s// implementation
2 R- g, u( \& Uprivate:
- ^) w0 k" ~7 s HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);$ _$ w- D$ Q8 z1 B
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& U0 H8 V5 k$ J4 l9 s; k3 @( @
* Y+ ~1 M0 R9 D( B+ s
0 q2 Y: o* O2 z4 n" M0 g" X
private:
& ?* u& ~: X Y6 M* S0 M5 A CUPnPImplWinServ& m_instance;& u7 t. U C! R; R$ D9 A8 |1 s. G$ g
LONG m_lRefCount;
T. H' {5 D4 V4 L- J/ |: w% F};
$ Z: _8 d$ n# m5 `# |
0 V7 u0 f" u% J4 q
% C1 T- c/ `8 D& `: |4 ~3 ^/////////////////////////////////////////////////
! s- { x) i6 ?$ s+ u! y
: O+ }: x5 y( F. J$ O. a" t! A' x- w
使用时只需要使用抽象类的接口。7 V8 H+ G. P) A! \; S1 w1 J8 b
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.# g0 {! P/ b% X, r- [8 T% E
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口. G, o* p8 Q; F& b0 b
CUPnPImpl::StopAsyncFind停止设备查找.; A& j) U! v* l) D
CUPnPImpl::DeletePorts删除端口映射. |
|