|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
* ?8 t$ ?; y* O1 K
' X- D/ p: S N1 G* u% B1 Z+ o: R( O* q1 {! y
///////////////////////////////////////////
" T" f' O" P1 F- n4 k//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
! j# ~5 D/ I/ h$ A2 P5 n2 K0 o" Y5 ^& C1 O8 F1 k7 m7 c4 T, g
) a' H& L- f% F
#pragma once
( d% u. s2 B/ b" |#include <exception>
) [/ W' A! e6 K: \, \' W9 }1 V$ e* J! W; s* S1 l, X3 V7 o
! o; O n4 Z# u
enum TRISTATE{& Y7 \/ u% Y* k6 p) N5 _
TRIS_FALSE,
. K" \2 g1 v+ f/ H$ A" d- e {* b; m TRIS_UNKNOWN,
1 F7 I* g! D* N5 k+ P TRIS_TRUE* {2 h( Y+ ]1 g, Z+ b6 O* t
};( R9 s" B8 @6 Y( T, H! |9 i/ i. Z9 u2 n
+ W1 L. @& e6 u- o$ B
2 `& W7 \$ q. [2 b& T- _2 D
enum UPNP_IMPLEMENTATION{
+ F% U1 D+ C& a' v* C2 R" ] UPNP_IMPL_WINDOWSERVICE = 0,/ S; z" P, p+ G3 p8 y. c8 b0 R" N' o3 m
UPNP_IMPL_MINIUPNPLIB,
- \! d$ V3 Q( p+ V UPNP_IMPL_NONE /*last*/
: _" ?7 Z9 R% \};; m9 g4 z9 X, g
% i' S% n+ U6 X/ \! p
6 @7 v% L! l0 _( J$ s) H* ^! h3 A5 {8 x2 k+ O/ j8 j1 ]' N
) a& U. d* ]8 |3 _
class CUPnPImpl. P* G, u- n' ]1 B$ |6 \
{ o$ w+ G* f1 Y& ]! d
public:$ C* C1 y7 j; v# @; P- S# P5 c5 Q
CUPnPImpl();
8 R9 V. j- `; q- B' K I, z virtual ~CUPnPImpl();
0 v" m4 F9 l5 c5 x struct UPnPError : std::exception {};/ } b0 t1 h- b$ B/ A
enum {
" C$ O* l2 ?+ t( m9 X UPNP_OK,! c. H3 X2 Q% w( H: ]2 `
UPNP_FAILED,
1 u- x; |; f% c( B UPNP_TIMEOUT
! O% X( j& p" ^/ I7 T0 L };2 ^: R/ P& b4 e' G+ [+ {. _
; d/ ^) g7 f% [- V/ H" C
/ A1 i( L2 {, `' R7 W2 u- B/ o virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;3 ? ^$ S6 w, z
virtual bool CheckAndRefresh() = 0;' P3 G q, m* O" X* I
virtual void StopAsyncFind() = 0;
; u! H. j( C. q0 L, | virtual void DeletePorts() = 0;' T( C" C/ P" I* ^+ ~6 Q
virtual bool IsReady() = 0;* S+ ?* p1 w* y" Q
virtual int GetImplementationID() = 0;# ] v8 Z- ]/ e- P4 p
! y8 S9 X# I `5 e- |- U7 D void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" I% F, E) @0 v3 d; B
' @/ }) A# B2 v7 A( _: F0 ^% I9 s6 g% c [, J. q% R; ~
void SetMessageOnResult(HWND hWindow, UINT nMessageID);3 G! t2 S' b. Q
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
3 A6 ?2 m1 _8 S uint16 GetUsedTCPPort() { return m_nTCPPort; }
# ?; K- a# r0 e+ d uint16 GetUsedUDPPort() { return m_nUDPPort; }
/ J5 E* ]3 Z. L
' M# y- e% n4 D3 \( X9 B2 c
& {0 z5 `+ Q6 ]$ }; }5 Y// Implementation
d. c/ T0 S% S# B) h0 p+ aprotected:3 T4 y: S: R3 s3 H+ R7 E# G
volatile TRISTATE m_bUPnPPortsForwarded;6 c4 p: B7 C: ^: U, ?( B2 A6 `
void SendResultMessage();6 f/ |: i2 ]2 b* M7 D
uint16 m_nUDPPort;: }8 r3 L# g3 ?2 F( y0 |
uint16 m_nTCPPort;
# C7 L' J, u0 O5 } uint16 m_nTCPWebPort;5 J1 [& F, W2 L# v
bool m_bCheckAndRefresh;
5 {* K6 P C* F3 C6 i; r3 T2 ^) A
" Q% `# P1 u' E% k8 T4 Wprivate:
8 c n+ U2 W: \4 h7 l; [ HWND m_hResultMessageWindow;
; Y0 ^& @) i* M* V1 F' D% V4 v UINT m_nResultMessageID;7 _5 j0 \' z& P6 }" g! }( t
/ v4 B9 E( a! D* \' L6 B7 _8 @2 h$ r, P( \* f2 s8 Q3 ]
};$ z- Y/ ^* T& [
7 h6 C# w6 {8 s. x
5 s; o& _1 K8 x6 Y* [ _8 J& T// Dummy Implementation to be used when no other implementation is available7 a2 c: s. C& a: w5 U# Q# K
class CUPnPImplNone: public CUPnPImpl" w' h# W: {/ v, R8 s& u3 [
{
9 W. Y- M" M7 f+ |2 `* {+ ~, N' p1 g& lpublic:# U# n# k/ @" o7 t# O) w
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }# X8 Y: W7 H9 c8 e: a- A. T7 n
virtual bool CheckAndRefresh() { return false; }
. H8 B0 Q! H- k. R virtual void StopAsyncFind() { }
- E J/ `+ F& |5 B virtual void DeletePorts() { }6 C/ k& h! Z: U' I
virtual bool IsReady() { return false; }! ?: d' v x. }# t. j
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 y- K2 Y& z/ r0 x};
5 }* t& H5 u6 ]
7 Q# S% m3 H, q9 @& b5 C8 C6 _7 P" R7 v
/////////////////////////////////////
5 C8 t9 j. u# e& C- e2 ^; \//下面是使用windows操作系统自带的UPNP功能的子类! h+ s* q% D, f) x
" |5 f X; d8 y+ e: d2 @$ ~" R
- G# l1 g- _0 R#pragma once9 l, p$ s( C& p5 e4 y
#pragma warning( disable: 4355 ); b* p, r/ I6 u6 D* w, n5 e& Y3 V
3 v* ^, O8 _! z( N; M5 C6 Z4 b5 s. u% l2 M7 c) @
#include "UPnPImpl.h"
( P( o' d/ O( l# ], E#include <upnp.h>
% x( Z: p, Y" N: t; W#include <iphlpapi.h>
w: f$ P0 R: j% M# [+ Q* s- S/ W#include <comdef.h>
' e0 ^1 w1 a7 e8 |! E#include <winsvc.h>7 s) j- d( G3 `
' H8 D: |0 x" u
8 n/ P2 O- p0 J" O
#include <vector>) K, i; g& f) f( V
#include <exception> y2 @7 M9 r: a
#include <functional>0 G& i3 F) G6 Z- K# X# C
% z' T+ f" z/ ?. ]
. u5 p' A1 `' _ k1 o" j: X% M# }
% I% R: Y. [$ |9 l8 x0 p$ W/ f! C6 m" U
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;: Q% h* b2 F! a
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
$ ]- E$ J" r# {# Y) U, J% htypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; ?( h4 g! i7 l5 G9 p
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
( v: N- p% z* \8 S7 @typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 Z/ y; I) N! h% [) b, Rtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
" B, J( g1 k1 }+ ctypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* v- t+ x0 U( W% r/ {) _/ ~0 i0 A' O, u0 J& ^+ o# U/ I# v+ W
/ L6 C% A4 I# X2 q
typedef DWORD (WINAPI* TGetBestInterface) (; a7 h0 S4 t2 L8 @) I- {
IPAddr dwDestAddr,
. k' C7 y" G5 s0 }& R PDWORD pdwBestIfIndex) P2 a$ n( a, l: f; l* O" X
);. B: Y( Z( R0 x) [9 k& `+ w
) z6 x' m2 e7 N8 k+ U1 g
: t6 m) q, }) ctypedef DWORD (WINAPI* TGetIpAddrTable) (
2 N, N) p) m4 x* ~! @5 t6 X! k PMIB_IPADDRTABLE pIpAddrTable,
! z' T. M7 x v9 ~ PULONG pdwSize, s6 e/ ?" F4 ^; i( n
BOOL bOrder
% w( ?- P1 t; O1 _);
# K0 k6 F. p' \( q2 n
6 d: d7 q; e$ J/ c- a
/ f. W, I6 [) ]: G. A# Q2 ~' ]typedef DWORD (WINAPI* TGetIfEntry) (/ w% T: @" i7 q; B t
PMIB_IFROW pIfRow
: |9 z0 R5 p7 o1 l7 Q$ y! K);4 p( ~! ]1 D5 g. E
3 v9 i$ y5 L& v' M( R
4 X p( z( i7 V; X0 I) Z/ Y* i, FCString translateUPnPResult(HRESULT hr);
' h; j" a/ k* p! M7 e S- J) v& V2 UHRESULT UPnPMessage(HRESULT hr);( W2 i3 O) l k4 @. A8 D9 O
" h( k( W! G) P! H; D% D% p
; Y6 |! _7 j$ v, E3 T( F) R
class CUPnPImplWinServ: public CUPnPImpl
; j4 I7 l3 O3 W{
1 o9 B: T3 U* J7 D& {: Q9 Y8 z friend class CDeviceFinderCallback;
- E6 F0 L& V- z+ p friend class CServiceCallback;
0 V8 ~! T2 s; C0 @/ V// Construction9 a* S7 W) Q+ C. X
public:2 B& ]7 x8 H1 T7 Q
virtual ~CUPnPImplWinServ();$ W7 b3 _$ y5 q. `& }' k
CUPnPImplWinServ();$ g# q3 N9 T5 [8 P2 P
$ Y3 A" C4 G$ B: q, Y* u: e) n2 i2 c% f
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }4 W1 Q7 ?) d6 H& L; s/ k c0 S
virtual void StopAsyncFind();
; T- H: z8 R7 s _$ ]" @9 l. T, h# [ virtual void DeletePorts();8 K1 S$ {: T* Z2 }
virtual bool IsReady();, B' B7 f, L$ J5 q$ A& L4 J( `
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- J2 h6 A. U* v* |/ _/ c1 @/ `' Y8 H' t) ?; s
$ L% ^- X: L8 }# ^2 B) z // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)% ~; v) D, u+ m% H
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
6 G; [7 S) _. p virtual bool CheckAndRefresh() { return false; };& v k9 I3 M! M1 X" M* }. k
3 E$ I- D1 ^* z- ~: b4 \
$ V% T( d( O# g0 y
protected:( w6 l* `) V6 z9 P# ?
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);; ?, B. Y8 W& l5 B6 ]
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
) A; q# |% x; O3 U }0 J0 l- h void RemoveDevice(CComBSTR bsUDN);9 h# L: b/ l" x4 r* E0 B
bool OnSearchComplete();
+ |& L- H3 g" G: Q, y3 S* C void Init();5 I B; Q6 ?; u3 H3 B: t4 n7 t, z
, O0 T5 z: K" N- T% q
% ]1 v7 c( @' m' j+ {. Y- ]
inline bool IsAsyncFindRunning()
# j4 [7 x. a4 P/ z { r+ e% ]5 W: u, x2 r: L
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )# n! ?3 V+ u1 a# c* F9 m/ x8 q0 b, U+ Y
{
. R3 s* O: Y6 k, {. o" g: K m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
; W; g- i' a; }; B1 m. j. v9 ~% b& W0 e m_bAsyncFindRunning = false;) A+ Z& j% z) w0 y
}& }; V3 Z7 N9 @; ]/ z3 _
MSG msg;
6 U' Q/ n+ ]) i( k& h while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ). b7 F" G6 m) w! v9 @
{( ~) b& {- w; O; D& f$ B" b
TranslateMessage( &msg );4 R# `1 g5 Q2 f* l+ K* ]
DispatchMessage( &msg );
$ {4 x+ J3 t- s! M$ F$ L7 I: |/ v. v" j }
2 f+ E0 J; o4 d6 S( J2 C& L% {' j7 t return m_bAsyncFindRunning;
8 G* N# P: a2 {1 F }
: j9 t& d& J% u% N# |# @7 k) ^) `% H- }3 v0 K' \6 Q5 K" K
; [! N7 n% I1 G" W" d3 ?6 v9 Q
TRISTATE m_bUPnPDeviceConnected;# d$ S$ F" o/ i% N b$ i: r
- o( r4 M9 x& z( N- j
# j* @/ z, G; K/ e4 H// Implementation
5 n8 G( N: k; V# g2 S. _" K8 {8 P // API functions
( _% Y9 f! L6 x5 l SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
3 `$ n- N, a) k) i& J SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);7 o+ o" |* q/ n9 B1 G
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);3 r& n: A# K1 h; L' V2 Q" d
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);8 r4 j- W' {$ o X
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);, V) V3 }! n& q: r' @
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
, v6 T+ W% r/ f: S6 W& {( L" {7 h8 T2 w: K0 v* R
' c( T3 P+ D J) g6 Z
TGetBestInterface m_pfGetBestInterface;0 a6 N: m8 q" I" v: r9 `
TGetIpAddrTable m_pfGetIpAddrTable;! b+ O# X. X5 Q
TGetIfEntry m_pfGetIfEntry;9 P' F, P+ L' {( r0 ]1 ]/ Y1 r
* j0 T" `" A! ]2 X( B
% o P6 d% Y6 Y# L# P
static FinderPointer CreateFinderInstance();
; K( Q$ X u j+ z w struct FindDevice : std::unary_function< DevicePointer, bool >
4 P7 ]6 P3 R. T, M {
& ]' M- u9 q' |% f( X FindDevice(const CComBSTR& udn) : m_udn( udn ) {}- `- S' A& S2 G. \1 W5 E
result_type operator()(argument_type device) const
$ |6 ]! D- \5 m {
& t+ v o; x4 q: F9 L5 ~: c# w CComBSTR deviceName;
! R7 b: ^6 g( T) @! ?' T HRESULT hr = device->get_UniqueDeviceName( &deviceName );- N$ k2 T) h, N6 g( K
- `, I# H8 i- K+ n% y& w7 o6 J$ W
if ( FAILED( hr ) )
! R' R( l2 I* v6 {; V9 Q return UPnPMessage( hr ), false;2 m9 [: ?- h) E# ^3 ]9 c
' [6 R. W: ?9 D1 g: f9 {, `0 u& b) T, C: ?3 [4 s
return wcscmp( deviceName.m_str, m_udn ) == 0;
# K3 m6 ?9 i) w5 W0 J }3 R1 O4 q, ], i7 ~, ]) q; E
CComBSTR m_udn;
& }; k$ d! K8 w2 a* v4 Z };9 G2 j. [. L8 a/ K. X6 q$ {
* V, ?; \! N: M. F/ v9 M+ k void ProcessAsyncFind(CComBSTR bsSearchType);
; R+ ~2 t& l" [ HRESULT GetDeviceServices(DevicePointer pDevice);; h: \% M) e- \. D: X5 K
void StartPortMapping();6 g& |" X" Q7 @3 n, M: e
HRESULT MapPort(const ServicePointer& service);5 U! }) o8 H2 x# q
void DeleteExistingPortMappings(ServicePointer pService);
$ h$ [* {" l, R void CreatePortMappings(ServicePointer pService);. u& a0 J! ?8 }
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
4 o7 C G; O5 ?5 w3 k5 s HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
( l, A0 f1 u2 T& X4 S LPCTSTR pszInArgString, CString& strResult);8 O, H0 H% E/ a9 _
void StopUPnPService();
' I5 i& l" c* r3 i; N5 x1 ]( z- K: v: y9 o& d
& o& s/ [3 z$ m2 O# A2 A8 u // Utility functions1 W6 _. m$ r6 V) J7 y: d; R, O: p
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);8 d( k9 x6 A {% Y: j( S
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 c. U' T1 q7 Y
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);! H2 F8 r; W0 n+ W3 f1 ~
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);, ^2 g( L3 r1 Y3 l- @
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 Z$ Z. P' q# ]
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);% f( ?- R! I1 b" d
CString GetLocalRoutableIP(ServicePointer pService);& }& u- k6 M" ]2 _, N
% _9 y& r, H _- _
: c& \3 H6 x9 H" G! V
// Private members9 w. }2 v+ s" Z# R; }8 B( N
private:
; b- n# `) f- t4 c Z DWORD m_tLastEvent; // When the last event was received?" G4 h F* S2 R/ S& T4 Q
std::vector< DevicePointer > m_pDevices;, J) L5 H) a3 R! n
std::vector< ServicePointer > m_pServices;
: B5 W' y8 Z6 A FinderPointer m_pDeviceFinder;3 [3 |. ]) V# a5 K3 w, L0 e
DeviceFinderCallback m_pDeviceFinderCallback;# P% U7 P& U4 t( w+ F
ServiceCallback m_pServiceCallback;
. {) A# B( k9 | f# U# m1 z- }2 i8 a& Q# E" P: A+ n L- [
, a1 t" U! E, ]7 g* h* h; a
LONG m_nAsyncFindHandle;
3 J) P" K1 D* y* [/ c) E* O bool m_bCOM;
+ h3 I0 u" e1 P' s7 e bool m_bPortIsFree;+ e' O* V! a! Q( a g
CString m_sLocalIP;
* S* l* B/ N" ^8 Z+ V, x4 k) H, U CString m_sExternalIP;; d+ P" M% L( p& Z
bool m_bADSL; // Is the device ADSL?" v8 J ^) ?" c: u
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?& @! }6 O) L7 l' h
bool m_bInited;" Q! Y! c# V8 a2 A: @
bool m_bAsyncFindRunning;9 P4 Y+ H1 f& X2 ?; l* _' S* P; b
HMODULE m_hADVAPI32_DLL;4 K. O L, m3 [" \( A/ f
HMODULE m_hIPHLPAPI_DLL;
- a2 R$ x6 a. e' }0 I bool m_bSecondTry;
; H; J2 ~9 s% h0 I- n bool m_bServiceStartedByEmule;
. ]% q$ S/ S2 Z; V bool m_bDisableWANIPSetup;
6 _3 W L3 V3 ^, w+ \1 o bool m_bDisableWANPPPSetup;" P. q6 H4 M2 ?! w, V
) {( `; A# ?* H
# Q4 T; [3 [- c9 [; }: G};
+ b- i+ Y! ^* L1 ?, ]( t
8 Z% d; |( y. m
+ r6 ]% H/ g3 ]# k- G' {) _( f6 z// DeviceFinder Callback" P- u+ ^/ u, H; v! T$ D0 ~
class CDeviceFinderCallback7 p* Y+ u. u1 p& d/ q
: public IUPnPDeviceFinderCallback- y" n! `4 R6 V" y1 Z1 g
{
8 Z5 a! i& u! C6 wpublic:
/ j9 a$ [; V& `. J R# @% {" m. } CDeviceFinderCallback(CUPnPImplWinServ& instance)
* ^3 G" V7 U6 K3 ^8 e : m_instance( instance )6 `* E8 [: d, A1 ~
{ m_lRefCount = 0; }
' \1 ]7 n6 N4 H& g' i& Q* ]/ Z d7 Q2 T/ v
$ N" v( _ v( T
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# K) S9 V" C) J& V8 m& ^
STDMETHODIMP_(ULONG) AddRef();
7 x& V9 Z: _+ Z0 ] STDMETHODIMP_(ULONG) Release();
& H K& _9 ^* {, D$ C& @; U3 \5 o3 ~' y. [) K, D
7 N, }* m0 F+ Z1 w// implementation
, k! {& z! w) S( g' d* u+ `private:
, k- ?2 @0 T5 F HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);! r$ o1 X0 R* s; Y) b6 c' C' [ g
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
0 T1 T' R' S5 k8 m5 G. ?" @ HRESULT __stdcall SearchComplete(LONG nFindData);" h4 S* h& y) n, r( m2 A$ N
% `2 e8 j- Z$ V4 ?5 R1 e& f
( V `$ P$ @& [& E5 a" Fprivate:# O5 a+ q# f ^7 ^6 ]* @2 P
CUPnPImplWinServ& m_instance;
. u6 W" o8 [6 E4 I$ U6 k$ H LONG m_lRefCount; a0 ~6 Y' ^! n1 h( a; Q2 g
};
' H+ N& ^: z* R& Q8 v4 g# r
/ Y$ d/ s! R7 {+ b; }1 T/ a I$ A* y8 w: q+ U D6 P
// Service Callback
6 _/ R1 | D$ a0 h2 f8 V$ P. Qclass CServiceCallback
& g; S$ y/ `" X P : public IUPnPServiceCallback7 v2 j' j9 W) o- ~) @& j
{
% R6 q) B2 [( Jpublic:
. }/ }, J4 r0 ` CServiceCallback(CUPnPImplWinServ& instance)
' [5 n' O) e, ^2 j* o : m_instance( instance )
/ e( ^% w$ I" r$ S% C/ _ { m_lRefCount = 0; }
: j' t5 q1 D/ F! D
9 F8 T- N8 p& z+ q3 ]2 c; }- ~5 Y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ ] I) t$ c. N
STDMETHODIMP_(ULONG) AddRef();
$ K/ ]* T n' N6 @$ m STDMETHODIMP_(ULONG) Release();
, D# `0 G" K2 b8 Y3 L- \% L2 b5 @2 s |, T
& I! C5 a& m, G: h! I. y2 `: O// implementation& z' j8 r/ y6 M* D3 S
private:
9 A& A8 [: R9 z" y, w2 F HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
" r) I3 H; n% L- m+ G/ t) e HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
' k0 Q# e- [: k$ Q' ]+ ?$ I; t% j1 B/ k' G. w) ?$ I) z: n" u
+ w* I4 N% ^- t/ F6 Z2 ~private:
" k' {& [8 A4 G4 s CUPnPImplWinServ& m_instance;
% S1 f5 f. S5 t0 l3 _% D- q LONG m_lRefCount;
8 d, Q2 F& H* Q/ F$ w5 ?};" V% }& N/ T" V' Z5 ^3 M' `
\, v4 m9 D7 S$ ]/ ?, ~) b: l* ` Z( }6 _/ ]5 B8 A6 [; h
///////////////////////////////////////////////// T% f) Y+ ?" a
, ^. W0 D$ k. A) _+ r9 B7 X6 c0 `
) j7 `. q8 Q! T: f' c$ [使用时只需要使用抽象类的接口。% E3 w% e$ i' C; ^2 D
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.! F2 x# J- C0 W# I# {, J
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! w5 ^$ s/ N" \3 B
CUPnPImpl::StopAsyncFind停止设备查找.1 G) z+ r' Y, O: l7 [8 }8 f; M
CUPnPImpl::DeletePorts删除端口映射. |
|