|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,, d, c- T M* T
6 L8 ^: R8 l; ^# Q/ I9 S; O& \% }2 j {/ K5 n1 S
///////////////////////////////////////////
& v, D ~- s' U2 j$ I: n//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
6 U; X. }6 l& N1 O3 Y+ I8 K! B: O+ q9 J+ [
; Y# c' `1 m: p+ E6 T#pragma once4 R: X, N& A6 i" Q
#include <exception>
) \* Y1 c2 |7 ~+ e" i4 T6 j8 E4 V- z# L" H/ ]
4 U! U( q1 I# u# `; m enum TRISTATE{
2 n. r+ t ~6 G( [( ?4 x9 D TRIS_FALSE,9 a" m- ~& ]4 z) ^# w' K
TRIS_UNKNOWN,
: s6 V& o, S) h3 \9 ` TRIS_TRUE
4 L! ]# |0 f1 i; j, g8 i6 z! T};/ o4 C5 H# I+ ]9 y- g
: u; {. W) Z6 B; B p4 C
* T8 W# a2 k. F& [enum UPNP_IMPLEMENTATION{
( }. A2 {7 l: u; h- k UPNP_IMPL_WINDOWSERVICE = 0,
) U" k+ c \; y2 g4 Y5 W UPNP_IMPL_MINIUPNPLIB,
" b* r& B0 B8 n5 x: c% J% M UPNP_IMPL_NONE /*last*/
5 E0 I2 O! `0 ?, q) h) l$ x};7 e+ q( k) w1 C" I8 D
4 E! ^8 Z' X V3 N. Z
2 ?$ Q, q' \) R5 n# w# r" x3 ?
) g0 T) g2 O) I3 v8 M2 ~
2 ~. D8 m2 ?. _- J; Cclass CUPnPImpl
$ I! K! w- [& y! ~6 k( M, J{
n O1 B; G, X0 I" \/ bpublic:4 g+ C) t$ G! X+ R' C
CUPnPImpl();% o, F# ^4 D% C% Q
virtual ~CUPnPImpl();# \2 b$ D5 Q! U" T
struct UPnPError : std::exception {};
! n/ _8 `9 G; _9 ^ enum {9 f) e' u! @ V5 _, V
UPNP_OK,& C7 [' D* z% O& T2 |7 l
UPNP_FAILED,
: P/ j: f. Z I3 d5 \6 w UPNP_TIMEOUT1 S7 u. ~9 e: N4 R9 x0 K: g
};
* C; i# d. M5 C) D8 _# j& q' I7 g8 H7 F* J
5 x/ F o Z2 R9 A virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: _, V# s( ]" {* S
virtual bool CheckAndRefresh() = 0;
# p; k- f$ i- t3 A% [ virtual void StopAsyncFind() = 0;, B7 D% D6 }. n9 E$ D1 ^
virtual void DeletePorts() = 0;. q& J( H8 D* Z4 T% a: a6 ~
virtual bool IsReady() = 0;/ b9 Z$ \! x# s I9 k8 `
virtual int GetImplementationID() = 0;( |6 T+ {. l) t% {$ x9 ~5 v
* R- {9 M/ g# h# G void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping% [2 p$ q" f& y
+ b* u3 C: g* z! K" L+ p, Q
! |/ K- v0 a: m5 H C; _$ A void SetMessageOnResult(HWND hWindow, UINT nMessageID);) p! F0 i7 \# n( z
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }( r! `" h. h% [
uint16 GetUsedTCPPort() { return m_nTCPPort; }7 T# y" A2 ^, A" K. b
uint16 GetUsedUDPPort() { return m_nUDPPort; } . Y0 x1 p% P6 h' n# b# n3 T w
0 C& B6 w+ e) K) |* m) v1 X
0 f4 N6 h8 R I2 o3 V; J// Implementation
: Y9 J) ^* l! Z# dprotected:
& h6 H# s2 O& y0 k/ ?: `" T5 G volatile TRISTATE m_bUPnPPortsForwarded;* ~- C5 t8 @$ k4 w1 p+ j
void SendResultMessage();
& P5 g' p% q2 t( X# u3 S uint16 m_nUDPPort;
2 e# a% K, n9 d0 n ~4 a uint16 m_nTCPPort;
& ]' p. ]' v8 F A2 N9 V9 p uint16 m_nTCPWebPort;
% O, K ` N$ l! [1 E* S6 @ bool m_bCheckAndRefresh;
9 W, B- U, V) k, B8 @8 t9 w; K! ?+ q
/ W" {& S$ n3 j5 e1 Xprivate:9 I5 R I3 F& k/ F; N7 N# X
HWND m_hResultMessageWindow;
( ], g0 e3 x D! J- \7 j; z0 F UINT m_nResultMessageID;
% C! h, @7 R% T
; ]7 K# n& r7 v9 ?
6 G# j: J3 B9 x4 k- G};! ]/ [. F7 r# b/ r! \8 [
- }& q7 j3 X# k2 I6 Z2 V
0 u( X: P& A+ W, z, p// Dummy Implementation to be used when no other implementation is available. v1 E' `/ d5 ] B5 U
class CUPnPImplNone: public CUPnPImpl, L' D$ W- A/ k9 g1 _) ]
{" A. A' G5 i }! E: C+ ~
public:
% u5 n( g- x( q* h6 V$ h virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }) @6 s' F! D* t0 M; x( s
virtual bool CheckAndRefresh() { return false; }
7 Z9 S7 Q) b1 L" I/ O3 p virtual void StopAsyncFind() { }' a7 I- D6 e5 R1 G2 y* }
virtual void DeletePorts() { }0 F# A- ^- @2 j# ^/ U3 `
virtual bool IsReady() { return false; }
1 R0 {3 k5 X# n0 i( o( A9 o8 C virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
+ C4 W, M" F" s& @};
/ L8 c7 J; n! S+ e# ^
; P$ Y Q- S: V# q
( L4 A( I2 u8 \; c- X- {/////////////////////////////////////
9 k: l' g. l } C X/ T% e//下面是使用windows操作系统自带的UPNP功能的子类5 _5 X5 y h* D" F* `* n1 [
9 a- z8 l* l+ e% o
, G: S3 J$ I8 p' w# }#pragma once
6 k4 L8 l$ P& ~0 Z6 I' W#pragma warning( disable: 4355 )# n& C; i% R+ O3 o
7 k1 Y& k9 H8 z2 }
% M+ @; |, d- p- B#include "UPnPImpl.h"
3 c( k; V9 E9 t$ o0 t, s' Y$ `#include <upnp.h># |, t! W; \- M7 _* \7 ?1 z# G5 S
#include <iphlpapi.h>
5 P' P! w$ i7 b; c9 z#include <comdef.h># W, a) [7 ^- `6 b" {" Z
#include <winsvc.h>. n4 ]* Q* @* {
+ R' S6 C/ p0 x8 |7 i
8 X4 [0 J2 Q' q, P4 l* T#include <vector>
/ U6 V; z* d2 ^#include <exception>- o* M3 X" S, x# \6 M
#include <functional>4 N# h' e1 C5 L2 p* D9 D0 E7 C, [
; p1 z8 g% l( R* W* G7 ]3 V$ y
( s( D: q! G9 ]
( Q0 Z6 g" J# {8 o& \
( w8 }* K3 u/ Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;- e( y! E8 W2 f0 _/ n) f
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
+ t7 `4 m C4 n9 g' etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
: M" U+ d: u' ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
; Z/ |5 A5 G# z$ b8 ptypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
8 \$ R% q- y+ g# W) L8 Utypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
1 y7 L( S3 S* n$ Ttypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;! {2 H0 J0 E6 o' m1 m& p3 z
% B2 X: _3 v' L7 O& _$ k" G7 `1 H: Q
typedef DWORD (WINAPI* TGetBestInterface) (
" _8 K c/ k! @8 c# t9 p IPAddr dwDestAddr,
, z/ s. x6 M; p I PDWORD pdwBestIfIndex; Z1 \- H7 b! R, L: Y- u
);. Q+ y( n. f6 U4 i# i1 A4 D; V
( o+ f5 e' B2 V+ ^& i R# O' I. r% V6 r. i% p
typedef DWORD (WINAPI* TGetIpAddrTable) (
. @- Y" ]8 d; g PMIB_IPADDRTABLE pIpAddrTable,
# [# E. m: W6 x. m- s: A" | PULONG pdwSize,
3 `0 [8 H; A: a5 ^* ^ BOOL bOrder
: w- {* C) \- _; Q2 P);- _ c1 y& @% ]2 h0 R
( |& e8 z1 j% x. H& V; v4 R" K
$ a3 R: d; ^5 Z3 C m! p
typedef DWORD (WINAPI* TGetIfEntry) (
8 T6 x2 }9 J9 e1 Q PMIB_IFROW pIfRow( w0 O8 ? ?3 v% ^ C
); w* m/ t; ~" L+ T
% `: V, H7 }1 o/ H" ^# Z
# E! s, |8 k0 @7 m1 v9 u8 h
CString translateUPnPResult(HRESULT hr);# ^3 c7 A/ i, t [7 ~" m0 {0 d6 m6 ^
HRESULT UPnPMessage(HRESULT hr);
8 x3 X" n; o6 L# o8 Z/ b
* P3 o& p2 S; ]8 z. j
: [2 f; p! _) m8 w1 i. jclass CUPnPImplWinServ: public CUPnPImpl
) p& i: C3 c1 u3 s4 Z |3 V' V( D7 x{
6 t$ G$ `/ G. z \6 |, _+ G friend class CDeviceFinderCallback;! Z/ ~0 x& E* ^3 c. I+ b* [8 k
friend class CServiceCallback;# T G9 P6 K- U/ Z$ A Z( C
// Construction6 @" t7 |$ q0 g7 }+ n: L
public:
; S" g# I+ ^: W- q virtual ~CUPnPImplWinServ();
& \$ x; b* v9 k2 d/ }$ {. d1 m& j, W w CUPnPImplWinServ();
5 L6 u& X W$ J0 c7 L9 g$ P h- `* k: }+ U
4 x/ a( e3 K! H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
- x9 u! p- c& q. F% g virtual void StopAsyncFind();
6 V# k& y+ c2 L6 K! t$ D9 ] virtual void DeletePorts();3 t9 E, S1 \% W+ n/ B
virtual bool IsReady();
' |4 Y9 v' `) o( T8 }" K& V- \3 U virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
0 y! m5 q3 }9 }6 {) }3 n$ M6 t! c* @
# N X b; G" @# y& Z, { }/ X* Z" M. V! P- M9 N8 l
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc) M) X5 @+ F# @& B
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later( F4 ]/ P/ H- H# W, e! b
virtual bool CheckAndRefresh() { return false; };! G( d. i3 y- |3 P9 L# D
) ^; l( d! I1 i+ b% S9 p1 L
1 w% {2 W! J+ g8 G0 j2 J) Jprotected:
6 Z3 s0 Q: h$ J void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);1 v5 R, D& V; e" X9 m5 z: Z, |7 G
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);% r) N' R9 ]% j8 K+ p9 H
void RemoveDevice(CComBSTR bsUDN);
7 W. i. s" H! r& C, r bool OnSearchComplete();) O7 S* ~( ], S
void Init();+ B8 w: ?& { w, f; ~
( Z8 |' `+ R$ p5 m2 \
% m5 M6 w4 M/ I4 V9 W @% ~' L inline bool IsAsyncFindRunning()
4 b1 y. [# i7 O' s% I+ V) e {- z @1 y6 h4 D; n: y
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
" u' g0 l- K( g3 [7 c {
, [. [# v x( |) t5 h- s1 v% a m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
6 T6 Q+ n1 {: F7 E7 ]- u, Y g( r" h7 Q m_bAsyncFindRunning = false;" a5 v5 L; d1 P9 \+ j
}# C4 v1 n& W1 c# Q; w c. i
MSG msg;
! a/ z9 { v; A$ m; V6 H while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )/ k" V' g f8 [4 ~2 L1 Q
{' q# |. I* `# }) u2 Z2 @0 A
TranslateMessage( &msg );, o* p: r3 I( S( c9 B8 J% w
DispatchMessage( &msg );+ J. m( o7 A, y9 j$ Q
}
* J, i* A2 h2 W8 a return m_bAsyncFindRunning;
5 Q# d) ~, t1 A2 Z* U }
5 R; A( a e+ @7 d/ `( b7 |8 a0 O! _; K- s
$ I' j5 t5 l' l8 j X+ a TRISTATE m_bUPnPDeviceConnected;
. _7 Z7 b ~( _6 w: I$ O2 P# h* x3 G
& `9 j* p7 U" I4 X8 a! F
// Implementation
( ]/ q) q9 Q, X8 Y; Q; b$ @- F // API functions# k5 @; M; Q! ]3 d
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
1 \8 @) K& Y" n9 m5 H( H SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
! M' ]+ U+ v( p4 F* x BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);( Z4 z# g' T2 z8 Q- r* i- h1 x
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);& R1 k% G3 o6 |" {
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);3 H* d5 t5 Y. V; D' b' |( G( [
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+ k6 Z7 C/ N' g Y! {- I( Z/ I, ~- ?, R; ~* n* W
! g+ p3 ^* N# ], g8 ~
TGetBestInterface m_pfGetBestInterface;/ N4 S0 @# a: O/ x( C! P
TGetIpAddrTable m_pfGetIpAddrTable;
9 k5 }) D' e/ Q; f. _# r3 \6 g TGetIfEntry m_pfGetIfEntry;3 B- V. z% m. R+ {. s/ B
" o9 A+ B$ v, s9 \
8 V+ A/ x5 c7 C/ R static FinderPointer CreateFinderInstance();1 }8 d- o& r% s K8 [* n3 \; z
struct FindDevice : std::unary_function< DevicePointer, bool >* W& ~" D! [' J5 z& O4 V$ y/ a
{1 q* J/ y4 N# f/ _5 p5 a
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ w" V0 ~) R+ H result_type operator()(argument_type device) const
0 [1 }5 j/ o+ O* O/ [1 {/ O, ` {/ A5 {' q$ W1 ?2 S; d# }, r3 Q2 ]
CComBSTR deviceName;" @3 x, g$ C% g: P$ Q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );0 G* K6 v2 ~" o0 B/ P2 p. {
- ~ ?$ w8 J: E) c9 w0 z
7 }! B1 u) g7 ?$ f1 B j; u' @% s2 X; f if ( FAILED( hr ) )7 @9 k9 J6 `& S# M
return UPnPMessage( hr ), false;
# q3 E& \) ]6 c# Z* M, { w, `. i; N/ O7 T V H {& }8 x6 `
) c. |6 ~$ y. ~% {3 v
return wcscmp( deviceName.m_str, m_udn ) == 0;
+ P: N+ l1 Z: L/ s; C }
# _; Q& X2 e+ i; x) i+ P" | CComBSTR m_udn;
! S4 H7 R1 b5 D* F8 K+ y& W4 g };- K. q5 i% [9 ]$ M4 n3 ~
+ R$ V9 S7 G$ V8 K0 w1 U
void ProcessAsyncFind(CComBSTR bsSearchType);
9 J0 S/ A7 a9 A* d/ }; W" g HRESULT GetDeviceServices(DevicePointer pDevice);
( a# I9 S, ?0 M" G# ]3 d# O void StartPortMapping();
) F: ?; Q$ _2 T4 {+ S; @* y HRESULT MapPort(const ServicePointer& service);
6 t3 L% G! c# ^* Q2 r) W& H; b void DeleteExistingPortMappings(ServicePointer pService);
6 F9 ` ~4 c2 t O1 H void CreatePortMappings(ServicePointer pService);1 j; i, V) ^9 Y2 R5 ~2 u
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 ?) q; C0 T4 P I, L7 H9 e$ N
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 2 n9 r' b& a6 e1 T0 j3 ~' L
LPCTSTR pszInArgString, CString& strResult);/ q! B5 b! I# \$ d. Q
void StopUPnPService();' N3 P+ u- O$ w* m8 y
# a. z( z$ B* x8 d
6 m% ~: T1 ~* T& g // Utility functions
4 d) K: r% w4 c( @0 [/ Q3 B% B HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);7 j; A' v/ o( D7 X
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. o# Q: `" B" v# {' l+ M
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);1 L3 D/ F; L, X! p+ O
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);/ W! K/ y* x1 l
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);& J# M" [$ [" m1 K
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);3 a2 _: M1 a2 u5 [* w- D
CString GetLocalRoutableIP(ServicePointer pService);
- c2 S0 D7 V1 V0 p9 o
6 c. y% [2 t3 z( U
' ?# w9 [8 T0 n* E5 L// Private members
$ k' k: N3 F) G7 S$ v# _private:; C @, H7 f8 I5 ]
DWORD m_tLastEvent; // When the last event was received?
, d* R- ^0 s" r% b2 o& `, ] std::vector< DevicePointer > m_pDevices;1 H0 t) C$ N4 k% E
std::vector< ServicePointer > m_pServices;1 d+ [; b6 r {/ c8 X6 c
FinderPointer m_pDeviceFinder;
. {7 y2 V: |' {$ G$ u( ^ DeviceFinderCallback m_pDeviceFinderCallback;, U7 Y( H9 y' P
ServiceCallback m_pServiceCallback;1 l0 @% }/ ]: t @4 z* k; z$ y
8 j7 M* l7 c! b0 {* Z, Q
2 _0 M% w- V4 O4 M# |
LONG m_nAsyncFindHandle;
7 v" \5 v# w9 n1 s bool m_bCOM;$ G; U" ?9 _/ G- T) ?
bool m_bPortIsFree;$ t) s" r# s* m
CString m_sLocalIP; w6 {9 M! \3 i) L( A' I$ ]
CString m_sExternalIP;, I$ b+ A, Y `- ~, @& `( ^; B
bool m_bADSL; // Is the device ADSL?# t0 z( t; V. {: D, q; V9 u
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?$ Z# w- b9 h" ?! H, @1 a! m
bool m_bInited;4 w4 o3 { i- g* I
bool m_bAsyncFindRunning;
8 k7 a0 V2 d. ^, [/ d% s8 d HMODULE m_hADVAPI32_DLL;) a. _! r$ |& l7 p
HMODULE m_hIPHLPAPI_DLL;
: v, u9 z, H. c$ P' j' Y/ V% | bool m_bSecondTry;
R/ I( a5 V7 Q* g bool m_bServiceStartedByEmule;" C8 D3 w5 w, b4 ]0 }* s( X6 K
bool m_bDisableWANIPSetup;/ ]4 ?# I: \& Z5 x
bool m_bDisableWANPPPSetup;9 p# X5 z$ W8 ?
, U# e" m* W$ _; O- c
) K8 J! e8 D' Q+ }/ K. _
};
5 D2 N! r6 h0 M1 k$ { n, B w; \! ]/ }" I4 p1 W6 k8 t* k7 ]% {! I
, `/ S2 c+ m9 G0 K" ?8 L
// DeviceFinder Callback
) e# h/ G. z! u0 ~6 n; K% C- L* ^ _class CDeviceFinderCallback
2 E% v/ [9 `$ u" ~ : public IUPnPDeviceFinderCallback
9 A* r% Z% U O/ z% P( y{7 v8 h( P, T! Z" z$ a; q& H+ s
public:
2 W# ?" E# ^ ]+ s: ^/ ^ CDeviceFinderCallback(CUPnPImplWinServ& instance), i$ X [ f L! p" t# z
: m_instance( instance )3 f, l v9 h* P; ~. s0 B
{ m_lRefCount = 0; } U" m, Q2 k1 t
# W) j, j- s. \; t% v/ l
3 y4 \, n% b, s* k. R2 l4 l STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); u2 K/ k0 Z9 g7 o/ W+ k
STDMETHODIMP_(ULONG) AddRef();
" y8 N O3 \6 f- N8 w" c STDMETHODIMP_(ULONG) Release();
2 L7 n! {. N1 j+ D$ d N+ J
% A0 b% V* a; h/ [3 E3 Y; Z" N; b+ z; x4 @! x' M! b* [1 P
// implementation
& Y% D3 @% J5 V% a- zprivate:
/ x) Q9 L- D7 Q$ r3 Q# W HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
2 g: r$ ^$ j* B' \0 N HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);" c9 B; T. F. s4 O+ i
HRESULT __stdcall SearchComplete(LONG nFindData);
R- R6 Z5 A/ o8 F0 j4 l7 a
# V* L) j; c& M5 O7 ^3 P
* |3 `, [# c/ _! R* qprivate:
& G3 x2 |" P$ G. Q9 n1 E CUPnPImplWinServ& m_instance;) @ Q" T' F5 F _" Y. x: D
LONG m_lRefCount;
1 U) r9 m D) g* Z. t; H8 D5 W& S};( F0 |/ G3 q1 ?# @% N1 O" |
+ Q# G9 G3 K5 Y F# s# [
" C4 `% ]! f% e$ Q8 k* S5 n/ E// Service Callback
3 O/ [) R0 Z0 @) q( P) K3 a- P9 Kclass CServiceCallback
0 M$ O O5 p+ }" _' E : public IUPnPServiceCallback1 {# F/ r T% `& T. ]$ E. A
{3 f, ]7 G, A/ \- `
public:
% P6 @7 k6 r/ V5 l CServiceCallback(CUPnPImplWinServ& instance)' i% ~% q+ K1 z9 L1 ^, h" A
: m_instance( instance )- N: c- ~8 d. x' @. k/ W
{ m_lRefCount = 0; }
6 u5 w# u8 S$ C) B( z% ^: W$ w
2 i2 n. T' \9 h+ q- Y, n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 m M3 _. j- h0 O
STDMETHODIMP_(ULONG) AddRef();/ M$ q4 D* j; P. w, b! _( m/ Q
STDMETHODIMP_(ULONG) Release();5 @( p: q* t7 z3 L# ?& B( |# ]
6 A% ?+ G# V; S( S5 l
& g3 o: F" n3 P* b& e; T) E
// implementation
+ z- M! Q2 T4 L$ {* S9 Fprivate:7 a; h6 v$ D: Z! u. `
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);) ~" y& v" C# [" A( K; M8 e
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);7 |& p5 @# V( K
4 S3 V$ V1 W% A' g/ y# S6 f* j* ^7 }5 H3 `; t: c# q
private:# _+ Q$ s* |7 ] d) B2 }
CUPnPImplWinServ& m_instance;
/ t5 Q8 R3 H$ e6 Z LONG m_lRefCount;8 S3 b# _- B7 E1 L1 e
};+ T8 _; j4 n# Z6 T& {2 ?
9 u! l( e7 ^& _5 {
1 }. F6 E. }, z, R! m4 d/////////////////////////////////////////////////9 A: \; J7 b6 m
# Z% I+ _8 R8 b: z/ n( Z' c2 a2 z
$ ^1 U; S$ A6 v# \使用时只需要使用抽象类的接口。
- J) J5 `: h# B. |CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
/ D: E2 m; o4 p2 hCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
" O! C/ x" X& y" M( tCUPnPImpl::StopAsyncFind停止设备查找. |3 s; b6 A* d# D% R% L' J- |8 U
CUPnPImpl::DeletePorts删除端口映射. |
|