|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,4 W! J7 o! v: B6 F/ w- |& a
! h$ z% S3 ?8 v2 E; l
. I b1 M5 o( d, h+ D; A( ?1 g+ E
///////////////////////////////////////////3 Z% F* \) B3 }( j2 b
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- }' s- K; G8 H! G! w: T5 R3 C
4 u+ H! T6 J! E2 g: K, O
) ]2 D" L X0 E: [2 v#pragma once
5 e9 T ~& F1 G; `# K3 ^#include <exception>7 L2 o- X, s ~1 a
. n T: ?8 ~$ G6 N% _% f5 o3 D3 g; W
enum TRISTATE{
1 e9 O9 N6 i M' @% g% u TRIS_FALSE,( c/ ~; e5 ]+ F" s) @+ w; }
TRIS_UNKNOWN,7 `7 y2 m- m( q# S" `; A
TRIS_TRUE
1 A( q# I9 d, m, d! _, M};. ?- _9 V$ x0 j: z: V+ f
# f) e6 h3 C) x2 p% ^1 _ Q. G. P. ~; E
enum UPNP_IMPLEMENTATION{1 Y# [9 R. m& Y
UPNP_IMPL_WINDOWSERVICE = 0,' I+ u: b" f& b- L1 O9 r( l
UPNP_IMPL_MINIUPNPLIB,
: u6 j7 f2 t* ?: @& r, T0 x) S y+ n' f UPNP_IMPL_NONE /*last*/3 o9 s% |3 F8 ~4 G+ A
};
' h ~& g: d$ [$ R" ~$ g$ S
5 C& U+ j7 x' h, D5 S/ I
" Q5 S) @" U8 W4 r, O" ?; [5 L2 R n2 ]5 U {- W4 x
7 k2 o7 {$ C4 S$ J: M Xclass CUPnPImpl0 C! |! R" [- E) E
{ f4 _; c4 O6 j( z3 X% B! p
public:- t5 Q4 B8 ] u* }) o! y
CUPnPImpl();
4 |! R; P+ r" |9 @ virtual ~CUPnPImpl();
: s/ L6 J3 m' [; J+ B" R struct UPnPError : std::exception {};
$ P+ s/ P, ~: |+ H3 W enum {) N( {3 H+ y/ w8 [0 Y
UPNP_OK,
$ ]3 d. @2 T0 t( T+ s UPNP_FAILED,
! z. k( O; I5 M) ~2 v" A3 u UPNP_TIMEOUT, N5 t6 U1 V9 u% N4 V
};
C7 ]1 C9 ~; Y1 v( q/ x) ?$ c: h. q$ P
$ Q5 I+ z: I* w3 _4 d6 b
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" u2 E- f& y* U+ z& I# @8 Q) s9 x7 R
virtual bool CheckAndRefresh() = 0;
; Z6 \2 F4 k( p" X9 E6 g' N$ P virtual void StopAsyncFind() = 0;$ A1 ^, h" e; L
virtual void DeletePorts() = 0;0 f4 M, H3 P4 T7 u
virtual bool IsReady() = 0;6 R. ]. o2 {; S
virtual int GetImplementationID() = 0;
, Z& C. D8 e* \4 N# n5 D, y ; L8 t- v9 s* h Z; [! h
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
0 u, j. W* ^% `: ~3 [$ e' c; C5 D" m3 K9 @) ]
) k7 ?2 P" |5 E void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ W1 C; j7 |, [+ {3 U" F TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
& z! S: Z+ u) S$ a8 L/ e: b; e, x( { uint16 GetUsedTCPPort() { return m_nTCPPort; }
! r1 w. @$ n/ e6 F uint16 GetUsedUDPPort() { return m_nUDPPort; }
7 v& e; U% V$ v( h/ ?: h% d7 n7 q* n1 r _. V; J: q
7 M% _: X! m% K, z; s
// Implementation
: P* q' B: ~$ E3 jprotected:
; N' L7 z- o2 e% }, l0 G volatile TRISTATE m_bUPnPPortsForwarded;
" `) C7 A2 y# Q; W void SendResultMessage();) X A. R' b7 X$ @
uint16 m_nUDPPort;, }( R7 U. [# V+ x* y
uint16 m_nTCPPort;
* s7 d# ?. p! {1 g& ?0 `+ i uint16 m_nTCPWebPort;
, u" ^8 }! W; n$ s4 h' d bool m_bCheckAndRefresh;) o4 h4 Q' A4 D0 D0 g: Y
5 }5 N: O. p1 M: M1 f1 I: X( A3 W- `2 c, h+ z- S
private:
! b- F# x, y1 [+ J! \ HWND m_hResultMessageWindow;$ [. H" y& T5 T- s4 p8 w
UINT m_nResultMessageID;# f; s6 a3 l& _, G) R2 ^# }
) \9 ] f& @" w7 X
. T1 ?' g" e: c- z% }. z0 \7 d};
2 {- J& E+ O- ]0 C& n" G) J
3 e/ T, K; Y- F; L( [
) a6 ]5 ?' w) O$ L% W' e// Dummy Implementation to be used when no other implementation is available
1 j' \6 c8 C$ S7 s' gclass CUPnPImplNone: public CUPnPImpl
7 T6 i4 a! K5 q' X{
8 K7 n' [( N A4 `public:
; ~' k' M8 l6 c' z6 H virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }8 h- M- p+ T! w
virtual bool CheckAndRefresh() { return false; }
. U v( `/ x( d0 }5 I& l virtual void StopAsyncFind() { }2 ?; h; ]3 f% W9 P
virtual void DeletePorts() { }' w+ T ]1 {4 R" m7 I1 W6 }3 V' p
virtual bool IsReady() { return false; }2 H1 ~& ], o8 x# @
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 Q( A" P; N' B! {8 z
};: e4 x5 _5 Z2 j: t! P: k) ?+ s8 p
7 r! y# U! E& ~4 B
* F# W! R r- t; S5 k Z0 a3 {; w/////////////////////////////////////, l6 f: a* o$ ]% i: d" M! ^
//下面是使用windows操作系统自带的UPNP功能的子类5 |# g: }* W( `% U2 A3 D
4 ^5 U% V& k* ^, M( Q- |7 {8 B5 G7 P$ c, E5 j2 h4 V
#pragma once
4 @) L0 _/ c, E#pragma warning( disable: 4355 )' t7 } L4 [- g! \# p
7 ]8 j6 p' T" W1 f) a
5 {- K# q1 s9 O, o0 x7 I#include "UPnPImpl.h": r; n3 J% H W, C% b( g" V" @
#include <upnp.h>% [' {; }; r" n- k
#include <iphlpapi.h>2 ?( a) c; {5 e" h
#include <comdef.h>! P2 u! M, L# R' {* ^! y, v
#include <winsvc.h>
2 F4 F: Q( P; G* k' L3 A1 |
3 E \. l, t. v1 o' t- z# U
' V; D. _: i6 |+ }5 V#include <vector>6 v* d" C3 x3 K4 q" c6 d) ^
#include <exception>6 N; y7 j3 |/ y5 [) H: y
#include <functional>: V% C% {# U7 G8 \, [8 `& R* ?
& A% |. ?* e" Z" e# s
- p3 D6 d; D; h% B7 [3 F3 ^9 m( w$ D: A% z5 i
8 C. P: m: n8 R9 I( g+ {4 w
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
( T* l9 V1 r, _$ O* B, Ltypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;1 t: y' E" N( X3 ]5 F i
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;. q# J7 w; \+ W- T
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
q! w4 `& F# c/ ~% p1 A+ e3 Qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;& i" [) n, V- B6 \: K* u
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 P0 O* e2 v) c8 \1 W- z- `
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;6 D T0 J! p, B( b: O0 M' x
8 `% [, |, n! y1 F3 f
; [( A5 r3 m$ p. B$ W0 O
typedef DWORD (WINAPI* TGetBestInterface) (+ i) S `$ N9 B
IPAddr dwDestAddr,
- ~2 t, w9 Y7 j7 J, G( v+ r PDWORD pdwBestIfIndex1 c5 P3 L/ K# Q% J c% C3 ~( A3 p
);
" ]5 F7 y/ |. m/ G
5 w4 G- _7 s2 Q4 G' P$ q7 r/ [
" A0 Q; k2 m$ {0 O/ ~/ Etypedef DWORD (WINAPI* TGetIpAddrTable) (
, \9 v; `: J( C& {( ^3 c( Q PMIB_IPADDRTABLE pIpAddrTable,2 L5 {7 @8 D$ J
PULONG pdwSize,9 x# V9 X" I2 s4 p7 d
BOOL bOrder8 R9 k( u# m5 Y3 t6 P, v/ W
);8 @" K8 n- y4 f
. \- v$ b$ g% s+ `6 r6 T0 A7 L
typedef DWORD (WINAPI* TGetIfEntry) (
" _4 v, [, t. Q: Q, H z! r PMIB_IFROW pIfRow3 E, V0 F0 z) p, c
); P- G7 o: [# |
9 @, i0 Y8 d) D* c" A- n* D& R5 c
. I' Z: i- Y4 I* w; m7 E
CString translateUPnPResult(HRESULT hr);
- v2 z& Y ~( VHRESULT UPnPMessage(HRESULT hr);( R* p) v) w) c2 i1 [( J( S
2 X( V" C/ H9 v' s# P f
f, @( W3 ~; D$ S$ M% S1 ^
class CUPnPImplWinServ: public CUPnPImpl& Z8 q0 c: E6 W* v1 n
{4 O6 u3 n. I% Y6 G
friend class CDeviceFinderCallback;
/ g( B& g1 M. y+ F/ m friend class CServiceCallback;& @/ F! O. J G: s, A8 m. t* M
// Construction
" T; p, |. h+ G0 N* [5 fpublic:
1 Q: t( `& M0 X' m) T" p) } virtual ~CUPnPImplWinServ();, ?) Q- Q) f- k+ `! j4 ?) f
CUPnPImplWinServ();
i1 S. J* s, F/ N" ]+ @5 z7 s2 o2 e6 v( u, T" i3 a8 m
5 L X$ g4 `+ b, M' k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; E# g/ p! q h5 h) n. Q virtual void StopAsyncFind();
! H: J; ^- T- ^0 P% @6 n# M4 v virtual void DeletePorts();
! h/ ~+ J6 P; H$ ~/ S virtual bool IsReady();
. K j8 V8 {5 _' u8 J virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }# [; f! e- E1 N1 F
% E! ] |; {) ]6 O8 \8 [7 _9 P0 j1 p0 n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)* u: s1 a5 |1 j; W* g0 O$ d- ~
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later! d0 L3 S* k* A; }
virtual bool CheckAndRefresh() { return false; };: k+ F( t- u/ m+ I5 t# ?% Q, W9 _1 b
* }( ]4 {$ \9 u( d( D; O7 {1 {
2 ~3 x$ P# A1 \; ?2 c U8 O- P- nprotected:
% V2 r/ k+ L2 G( _7 \, t, Y void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- }# o7 u+ h3 B i! T void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
6 Z/ o, U+ O8 H1 L3 X3 z void RemoveDevice(CComBSTR bsUDN);
1 N$ X6 n4 Z$ m& j( \' }$ }8 |2 a bool OnSearchComplete();' {# o9 l" h. E8 e) K
void Init();, F g% I" A2 R* j+ H: @! i0 v
' K7 T" i/ q3 M+ p; E) _/ v
! C" o( [2 ^3 D% [ inline bool IsAsyncFindRunning() v) q, K' R4 O- `: }* k
{5 T* o" P; x7 G3 o) A6 M4 d
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )" T, c% V+ H% S4 y$ c& _2 n
{
4 Y4 S6 u2 K+ R- L' H: d+ d/ W# j m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
) W: Y/ W9 B; c- a m_bAsyncFindRunning = false;
9 E; M0 ]; l$ x }
/ ^. ?" C5 L! Y MSG msg;
6 w! j0 ~2 ^# G' P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
' s, {* S& i B2 a) R; h" V7 E! } {
- g Y* m4 }6 Y4 c TranslateMessage( &msg );' I3 j# U# e# j, R
DispatchMessage( &msg );$ E) P* D/ w7 @' O q& T- e& h
}
# {1 t3 |& Z7 z0 o! c return m_bAsyncFindRunning;8 }3 ~& s. |2 c+ [1 s2 C7 b, [
}
; s/ q) t c& V1 Y9 Q- u7 u* r7 d' A, r7 n
# a2 @$ p7 y8 T+ r( A- \7 N TRISTATE m_bUPnPDeviceConnected;- Q* `+ ~- _( h6 |) k; Z
0 ?4 \/ g9 a0 ~4 c+ [; i0 h' M5 A- C
// Implementation
+ n- M8 C, d! f C5 P1 [ // API functions0 \% T* M2 ^0 e4 p$ r* o
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);& D ~+ q6 H7 y0 n9 P
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);& `$ L& J% i$ l
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);; r( ~$ p6 J# n/ [; }
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 }5 \1 x/ S7 Y, m1 `- c
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
2 y+ k+ J! f; Q0 y% c. V BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
3 K9 R4 \/ l1 T/ [2 ?$ W7 i& O/ i2 C
7 R u) h. K5 c8 R& P- K- W q0 v
TGetBestInterface m_pfGetBestInterface;
1 J) ^) q$ h" A( ]: E' X TGetIpAddrTable m_pfGetIpAddrTable;* R$ \9 X/ m% U# |
TGetIfEntry m_pfGetIfEntry;
5 F$ P) J. P8 p- k
$ L! `9 I# B# F% R- ~" y) m" L: h8 o# f0 Z/ z
static FinderPointer CreateFinderInstance();/ X1 w$ W& }8 z& {+ i
struct FindDevice : std::unary_function< DevicePointer, bool >! v. f( @$ G% ]3 T
{
- G% X6 n" R0 c* X FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ V7 f3 ^3 m0 j) w3 V1 p/ H result_type operator()(argument_type device) const
! \5 Z1 w' N$ ~$ E* o {
' f, H, f4 V3 a3 U CComBSTR deviceName;
7 H7 O5 y' j+ v+ z HRESULT hr = device->get_UniqueDeviceName( &deviceName );# ]# i5 o' G- M* N5 n! l
1 E3 M4 i0 U- V8 g0 O- {7 G, O9 {: g* A4 }- c- G, ~
if ( FAILED( hr ) )+ R4 M% h- M# [# u1 a
return UPnPMessage( hr ), false;6 a8 T8 s3 x' ?. B$ \
6 z& S. {( ~, X( L7 M
) \ u& _% v* Z' \* A4 `% X8 Q return wcscmp( deviceName.m_str, m_udn ) == 0;; P0 K8 ^) r5 x- I: e7 E
}2 g0 R. P( J- P, w7 S: D
CComBSTR m_udn;. p2 K d+ i( J- p
};
. _' I' B8 S) r. F. ~. \( f 8 J X6 I, H4 @3 A
void ProcessAsyncFind(CComBSTR bsSearchType);
4 w1 t5 g* Q3 O R, G' D HRESULT GetDeviceServices(DevicePointer pDevice);1 f8 `1 {% o2 Z& ]9 q A
void StartPortMapping();4 O1 Y7 ?) m$ v
HRESULT MapPort(const ServicePointer& service);+ }+ s( L8 d" N! c1 Y, x
void DeleteExistingPortMappings(ServicePointer pService);9 Q" y3 H' @. [) M8 N9 Q8 _3 s
void CreatePortMappings(ServicePointer pService);6 H- D @" R8 C7 |' b
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
/ b/ e6 |; S% w% Q2 T% N" ^ HRESULT InvokeAction(ServicePointer pService, CComBSTR action, & |# O/ [7 L# g# C5 v3 Y
LPCTSTR pszInArgString, CString& strResult);' G( c2 {% Y! g2 h! ~3 b
void StopUPnPService();
9 Z# Q" @! u6 D4 w' q+ m" {
9 a4 t4 a5 C7 I$ ~, x! g; Y" C, T, E
// Utility functions$ K. Q( F% I/ Z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 X8 k9 r$ v4 v9 U INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
; t( f$ r4 J9 l( A5 h3 z6 L! {7 p INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);+ [* Z* O3 W, I$ k' j
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
}( H% o5 _( @4 k3 j" i- B2 F; G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 Q% \' _, P- O5 X7 A+ l
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
% r2 c; \( C/ v7 d' T CString GetLocalRoutableIP(ServicePointer pService);
* r# Z+ R0 A: O4 T) Y/ Q: L$ ~7 ?4 a; `5 t; a
6 U1 C0 v. U; A( [- `
// Private members9 |/ e/ a/ N8 z! ^: y9 W
private:- f% c5 _4 @& v3 o# S0 Q \5 Y
DWORD m_tLastEvent; // When the last event was received?
- C9 o' {, U4 P2 D6 v/ _ std::vector< DevicePointer > m_pDevices;4 ~8 `% w- c: V" U! C
std::vector< ServicePointer > m_pServices;
3 i/ \: {- Q: z FinderPointer m_pDeviceFinder;
% W- I7 C: f* f% h& \ DeviceFinderCallback m_pDeviceFinderCallback;
9 W; R Q4 K: t2 F4 W ServiceCallback m_pServiceCallback;
: y6 E. j. r5 i6 l8 y2 @# e7 Q
2 E6 R! i- Q t
4 s, E- O2 x; H LONG m_nAsyncFindHandle;) r c/ i: Z3 B( l" U0 J' E
bool m_bCOM;
, ~, R/ U; |6 M. c3 F0 \$ J* H8 d$ H bool m_bPortIsFree;; X! M9 ~2 R$ X ?
CString m_sLocalIP;
8 |$ I+ R' t9 h4 ] T( K CString m_sExternalIP;- @1 f$ ^- G! g
bool m_bADSL; // Is the device ADSL?; p1 ]: q) S! [
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
% Z& r' a- y. S% X+ l bool m_bInited;
9 o( l& G7 k* q' y3 I bool m_bAsyncFindRunning;
( C, @# V% k/ ~# L B0 N/ y HMODULE m_hADVAPI32_DLL;
" c9 x& G% u5 D0 r HMODULE m_hIPHLPAPI_DLL;, }$ S' n+ H9 s2 L+ I2 _
bool m_bSecondTry;
2 y G5 e5 l9 g2 u6 [ bool m_bServiceStartedByEmule;, l5 ^( s9 s) M
bool m_bDisableWANIPSetup;
$ A5 J) u# ^! R3 B! T bool m_bDisableWANPPPSetup;) X" V' b* y2 q8 C. u+ I
5 s* n; [5 d; Q K: |. x8 E
: ^/ M$ d" @+ q, P};
& F8 G: _+ a9 o1 ?6 [! P& u
! F7 Y4 z& u+ a' j& x2 |& W8 k3 {# G# M# F8 o9 |
// DeviceFinder Callback% w b+ _$ [: m" u4 ]5 V, O5 p4 v
class CDeviceFinderCallback% m: O8 o! o5 m
: public IUPnPDeviceFinderCallback
; g- e' \: H4 i6 i0 J/ } h{
0 p$ L* Q' H5 `7 d7 l, `) Dpublic:
+ Q( R" N) p7 G4 }+ H% l0 V CDeviceFinderCallback(CUPnPImplWinServ& instance)( d/ i6 @: u* g3 |) |
: m_instance( instance )5 @) L& S: ^" A
{ m_lRefCount = 0; }
/ G* j' z; ?# K- M/ |0 j8 @# b3 n2 E9 ?9 \% {. [9 X9 }
) t) S" X5 h \. b; ?- N5 ~* a/ H
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. M" x& V* k- `, R3 g STDMETHODIMP_(ULONG) AddRef();
- O' m% Q6 K6 u STDMETHODIMP_(ULONG) Release();
/ s$ d- x( S! ~# P2 s" [' S* l
* \- u1 v. r8 I
5 y4 M; o: z* d& Q1 |// implementation
6 G! G7 W& G8 D# L/ u2 u1 Mprivate:9 J! e# h9 i: |5 j
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);2 j9 N" U. A9 N- n- L. G# W* J
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);6 a) p/ b. E4 r; a- Q; T* G
HRESULT __stdcall SearchComplete(LONG nFindData);
. o; N0 W9 z$ [1 i+ {* D' v' m5 `/ z3 t8 P4 M, h
. x' s1 v0 ]1 D; u0 h* w4 C+ p) Cprivate:
: M) [. R$ ]9 a. X" J& n CUPnPImplWinServ& m_instance;
' s, ~5 d. P* b' q% V8 o5 ~- Y; } LONG m_lRefCount;6 P" U+ \" {, J5 g, p
};
. Z, [" g* b0 S# J! r
3 D r5 K( g7 K- h
+ n9 Q. F" {4 b% [* h2 I6 [. O: q$ N// Service Callback
* m. r1 i6 e" g0 Q qclass CServiceCallback0 e4 @: } {' b4 e9 O H
: public IUPnPServiceCallback" x( f, G( I4 q
{
( J1 J" @$ x" }public:
: l7 {+ \3 I; R+ m' i CServiceCallback(CUPnPImplWinServ& instance)
3 c2 `( D" S3 A' r : m_instance( instance ), H, m% V4 L8 n. P- N" Q/ k
{ m_lRefCount = 0; }2 i: z* _4 ]' w. @) c
4 p7 ~4 a! A4 f2 y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ A( F2 b9 d! }( X; E. r STDMETHODIMP_(ULONG) AddRef();7 c6 F Z- j+ h
STDMETHODIMP_(ULONG) Release();1 y- T, u6 @2 J# o. ^/ j a
6 E+ J% s) d) P) t9 O6 c
% O. k5 h2 V' b// implementation& ^3 J3 l: H. d4 J
private:
# C5 k1 t: i3 } HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);. r- X6 J9 \. [% B# m% N" ~6 f* Y
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" h3 W5 U7 S+ W, C2 e9 v
0 g8 n* X U( W& I1 m: J1 \, E3 f
# Y: g2 S: M9 Wprivate:
6 m. t. ~. U1 h CUPnPImplWinServ& m_instance;
! ~/ A* `8 U, O. g3 Q+ }1 ?, l LONG m_lRefCount;0 G6 {8 u: F& q4 k" V; `+ _
};9 w+ x" {8 {* I" ~
/ Y( m; n, V& `5 d* K! z
& ~' K& R+ i4 f) W+ ?, u. N* C
/////////////////////////////////////////////////
f$ B7 Q) N2 C2 ^* k6 ]2 C. Z) t9 e2 \8 n6 v2 k
, q' k3 E1 ]/ A0 s- h# a使用时只需要使用抽象类的接口。
/ I! o7 ~; b& c2 C, @CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.* `2 @1 Q; j" j; @( E; b4 \1 c
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 R8 A% A7 u8 ^; H+ j# SCUPnPImpl::StopAsyncFind停止设备查找." l& s; b3 U1 k' H7 E# p% R
CUPnPImpl::DeletePorts删除端口映射. |
|