|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! P1 g F0 \) M3 m4 u
0 d! G; [; s9 X* ]5 J* T! h
$ H7 w9 z, C/ G( x( F
///////////////////////////////////////////6 ]7 i3 l9 h& h. d0 {, e
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
$ P# q8 m M$ ^& C& ^* U! E4 U/ v/ l( S5 W, ?+ n# I- f6 \) ]( w4 ?
1 ?* W# I) r& B4 F#pragma once
6 E5 f! U* s9 i* g0 k#include <exception>
0 w# M) k! }, ~; M
; D' @" _0 m; q' p. @4 u4 ]/ D* m8 z! A6 T/ H X9 ]
enum TRISTATE{1 ^* r9 M: f+ B) K, k
TRIS_FALSE,2 o: n( y) c" u% v2 z5 }( f; k
TRIS_UNKNOWN,
; A( T6 J6 l! i- _! A) L$ U5 @ TRIS_TRUE
$ a' J! V# e- r+ k4 ?0 n};/ z) O+ A3 q" S$ F3 F
. C$ y+ i6 A" V* g4 T
1 j! s* H F$ u9 }- Menum UPNP_IMPLEMENTATION{0 A! C8 o" T3 n. z& F* c# a
UPNP_IMPL_WINDOWSERVICE = 0," c' B. j/ U' S: S+ v& [
UPNP_IMPL_MINIUPNPLIB,
4 H- V+ Q+ e0 g J, [( a- b* \ UPNP_IMPL_NONE /*last*/
0 D9 V; R' I5 I# E, O% m/ E};- @" |9 l( |; @# \* q! A$ @% [
) g9 @$ U& }" B2 t, Y' U, l) [
; L( V0 a! X. v3 [* e5 O
& H9 d! W8 e& Q( Q! x6 q9 y& }
- Q! N3 a' h! _' [( G* S0 cclass CUPnPImpl& [# ~2 J% K# D6 ~6 N+ x
{9 A) U S* v. Z- o, \
public:' d3 u+ b; H7 |$ ^; F
CUPnPImpl();$ X) v7 ]/ Z3 T( L4 ? p
virtual ~CUPnPImpl();
! V& w( f+ u+ s+ s, U6 G2 Q struct UPnPError : std::exception {};* I; c! B5 A- S6 D! Y1 n* l, a
enum {, \1 t9 L/ C: B9 z+ s2 j& T
UPNP_OK,+ m7 L' a5 d* J5 V( N6 p9 ^5 c
UPNP_FAILED,) H+ u+ b! f/ g/ W
UPNP_TIMEOUT; X" g+ O2 G6 [- u
};
* ?/ J2 d+ i' D" `2 u
" W2 s" n/ D( K: X( N
6 V! t4 c5 O5 }( ~ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" x4 G: M2 Q, K# g& {
virtual bool CheckAndRefresh() = 0;* [. ~5 ]" \, C
virtual void StopAsyncFind() = 0;& ?. Q$ {% b% j& j4 N
virtual void DeletePorts() = 0;/ q* n& X" Y4 k
virtual bool IsReady() = 0;
6 K% {2 Q2 N; `. J virtual int GetImplementationID() = 0;7 Z' z7 h- e7 Z/ u+ f8 B) v; n6 n9 ?
& D! o2 c5 t" R1 @0 I
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping* J! O5 z; Q5 c2 Z! ?
9 Q' ]0 L1 W. O* v% L) r; g+ h7 \0 a) M6 q9 t3 L/ J8 E$ q8 W
void SetMessageOnResult(HWND hWindow, UINT nMessageID);" O6 y: r5 Z/ d2 P z# S
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ a6 X/ e/ b5 e- ?
uint16 GetUsedTCPPort() { return m_nTCPPort; }2 W$ Y# L2 H6 }+ {6 r. b
uint16 GetUsedUDPPort() { return m_nUDPPort; } + J4 h9 b1 d" ?$ i
. |. q, o, i- y; k0 T$ z9 l# }: B$ \* D v
// Implementation
\: t$ B, s* Xprotected:
& D- x/ G v7 T' W volatile TRISTATE m_bUPnPPortsForwarded;
! f+ E- {( d1 `# O3 d void SendResultMessage();1 U1 U c3 k- |; s1 i2 ? Z' N% @
uint16 m_nUDPPort;
7 B) Z& p5 d2 w. i9 s; @9 ? uint16 m_nTCPPort;
) l6 S ]8 w( p, U0 K1 B uint16 m_nTCPWebPort;
8 D- x i, p7 q: W. r( X( ^# H bool m_bCheckAndRefresh;
$ L( ~3 g$ Q; R& y5 I d0 e4 {& d2 N
7 J9 ]/ q9 s$ o" m& i/ `0 S
private:" c9 X' A( c, L0 r
HWND m_hResultMessageWindow;
1 _, d* d# V) `) O, X5 z( \ UINT m_nResultMessageID;
' q% Q; n0 _6 a. W. P6 }3 v' m; i& D9 i% C! N
/ {8 Z2 W9 }; Z, d* [, E};( r& G8 ]( _) R
" w6 m* }* e5 b4 h4 g! _7 C B, K/ z6 Q% F6 K: \1 I" ~
// Dummy Implementation to be used when no other implementation is available7 U6 G4 Z4 b% F5 k# _0 d
class CUPnPImplNone: public CUPnPImpl
# t d. E! \: i" C{
: L; d Y" _6 Z3 R. s/ m6 gpublic:
1 C6 S- Z [8 i% ^0 v virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
- q+ ?8 Z& K S% c virtual bool CheckAndRefresh() { return false; }' z) {" @3 g7 f
virtual void StopAsyncFind() { }
5 U2 l$ Y3 N- |. V! W4 J u virtual void DeletePorts() { }1 E( o& y& n' H) M
virtual bool IsReady() { return false; }9 u8 j0 K' ~! x. ]
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
: J& m' T$ ^1 x};
* \; Y& S" K- p0 r9 e
- `; ^7 e* J8 p$ B
' C) i8 l- b) C1 `" r- d+ C. A- {2 y/////////////////////////////////////
1 l% Z4 F* k/ y+ p* m( Y* m$ C4 S//下面是使用windows操作系统自带的UPNP功能的子类- s0 E! c" h1 a5 u' r3 W
3 k9 \* S# E2 R. |
. r' m) Z. }; L Y4 L0 ~! Z9 h#pragma once7 D$ u1 J1 u, K+ P) R
#pragma warning( disable: 4355 )
" P+ c/ f5 I' c
5 Y4 N* ]2 ^0 q# D
- e% Z8 Q/ _2 n$ ]! z5 Y#include "UPnPImpl.h"
( W. s( ?% h+ `3 ]4 d# h#include <upnp.h>
0 o* u: ?0 R# C+ }( K r#include <iphlpapi.h> x% u& c/ M" B( J# F: ~
#include <comdef.h>
+ U$ c) Z0 t I3 J: s/ \5 k! G3 [#include <winsvc.h>
! x. U7 ~$ q4 s1 a+ b9 r
+ K2 D; J8 b. j4 Y9 M% O) D: ?
4 Z1 ~$ ]" G+ Q#include <vector>
b+ B$ [1 a$ ]2 {#include <exception>
* x" }# l/ d9 [; j. ?#include <functional> _6 g* a) c8 o0 F S+ U" V
( W" \' f5 p8 j, Q5 G
" k+ r( r5 r# ~4 @
2 w& t. N/ O8 H1 P6 i& o- A0 S, r! p, [
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;$ I6 l8 O+ ] L# P
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
% j7 q% m- \) ^6 Htypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
+ P1 A* K# g- H( Dtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;/ a: B8 q1 J6 ?; r
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 {# S; _ {) o, o0 A
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;# F& V* g& ?' a( U
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& F) ^/ G6 V( ^( e) s
. k% o, { x: t& z2 k
2 ^' h3 U' I; M( Xtypedef DWORD (WINAPI* TGetBestInterface) (
6 a6 }( ~) K) V6 A# Y- z1 Q IPAddr dwDestAddr," e+ u& S5 U: G2 P. ~
PDWORD pdwBestIfIndex6 q- D# [, X3 L, b' ^+ f
);
$ ~7 o7 ?$ ]3 o/ D6 l' M6 q; Y- b6 ^# Y( I
* t+ F' v& T) b: t! Y
typedef DWORD (WINAPI* TGetIpAddrTable) (+ I6 Z: j$ F/ i) ^
PMIB_IPADDRTABLE pIpAddrTable,+ c2 y; {4 W3 ]7 W
PULONG pdwSize,
7 J1 v0 p3 E! O( ]9 K i( p& ~* I BOOL bOrder$ N4 g# o' u* d
);7 T& A: T k1 H& Y0 ?9 c1 H4 i
4 l1 E% I( u6 J+ J; T! @! d; B5 Y ]
typedef DWORD (WINAPI* TGetIfEntry) (
+ o; ~5 p# l$ l- o) _; P PMIB_IFROW pIfRow; B( n) ^ a g8 {* i
);
* z7 z# M$ t, u ?; D0 {8 R3 @9 o; ~3 J4 l5 e, M+ k( H, \
, j6 q, e: U' r. c% J! p! H- vCString translateUPnPResult(HRESULT hr);/ g0 Q% w& V$ S. F: Y
HRESULT UPnPMessage(HRESULT hr);6 C4 b _* q) ~) V( J+ j
. ?1 r L$ z: N: A$ l
6 U8 c! B! S2 Eclass CUPnPImplWinServ: public CUPnPImpl# B1 o7 s$ E& x
{ `% }7 s; Q! i! ^
friend class CDeviceFinderCallback;$ E. q5 t& i" U
friend class CServiceCallback;, `; v& w6 F. g9 U; h4 U
// Construction: k4 ]' T0 l% j1 ]+ j
public:
5 d- V; w7 t3 ^1 _) e virtual ~CUPnPImplWinServ();
9 N/ n) A" j6 }5 v3 G" B2 N: {' t# Q$ `4 r CUPnPImplWinServ();
% @8 Z+ \8 l6 J" z$ K, P8 _& I
G: G1 r9 `! D. h
$ P# S- p ?! B2 e# H6 P virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }$ u% m2 I7 N' j/ m! h/ O. q* J, T
virtual void StopAsyncFind();& C+ }9 P( g) }0 e! d- P2 x7 ^: L
virtual void DeletePorts();
0 n0 l4 d4 D6 ~ virtual bool IsReady();) V: u& A% o9 S# E, y2 o
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }* f+ C* n& s$ o$ u% ]1 V
Y) D7 K: j) j" u# h' H
6 ~$ C3 i! _9 o( M/ u7 E- l& D
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% R$ M# f, X+ }) ` // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later$ d& b$ C% L8 `; |/ ?, }' r
virtual bool CheckAndRefresh() { return false; };
, k% n; j+ X% T4 P( R5 U1 E( o" j* I4 {3 v7 v
% s6 V% ~8 e8 J2 J+ M# x
protected:
$ O1 W/ R- U2 l4 B void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);: V c& W' c7 q
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
% k3 q2 C3 P( [& y void RemoveDevice(CComBSTR bsUDN);6 n! Z- C' q# _0 ?1 p$ w4 z/ x6 X& Z P
bool OnSearchComplete();- f" C4 k0 [. e7 _
void Init();
& ]* T( J1 B/ P4 d: c/ c/ @* ` @: C }' d& B
" y7 a0 P& p9 f/ F m& {5 e
inline bool IsAsyncFindRunning() Y: [8 X. o3 v; }0 X' x$ h- z
{
1 k0 c" Y- o- M6 C, u3 L if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 ~5 [8 ~9 x& J+ x* N- R6 M
{" O5 q- c" S; U" {" z1 b
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
L" `# `( j3 l( O m_bAsyncFindRunning = false;9 o2 W4 t/ H! W6 N5 B, M; W4 b
}
1 b3 ~9 o K. E' I1 i/ V g MSG msg;
. p3 b5 @5 e2 w6 {. r7 y while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )7 ^% y. B* h4 ]8 _% x4 i C7 Q. c
{- T2 _( M# q' K5 p3 z
TranslateMessage( &msg );
x6 |* Q. R% v' w! G/ T DispatchMessage( &msg );# J( f) u* a* Z2 ~1 a
}6 j4 E8 |4 O) C ~6 O8 D; L+ D
return m_bAsyncFindRunning;
' T* s" x' D* [8 c }- I2 x3 h9 d _+ _
/ d: _% Z% V2 U- O, Z( u& h9 R+ s, N! C! G/ ?5 j
TRISTATE m_bUPnPDeviceConnected;
u0 ~3 K/ W. z1 T; D
Q* N1 A/ c I( A; h" n: e
) f, K5 G7 G0 z// Implementation
. h- l3 T& U2 o% r2 h: j2 j! B // API functions8 P1 j1 }2 E$ K7 C% \
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);1 ~: I( {2 j6 m/ u) Z
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);$ ^3 j3 G' g& Z9 n4 U# s
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
4 N: N2 h* f% q0 G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);) i4 Y+ D. o9 w8 s) z
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);. `" k8 @) @( b2 U5 V2 F( E
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
7 W7 ?" H3 o: w$ Z: B0 U
+ l0 l; g" a# D v. c% v3 d9 F W, E6 ?4 t# Z: V5 |9 c
TGetBestInterface m_pfGetBestInterface;. K! B% s# A' f: \2 w6 L
TGetIpAddrTable m_pfGetIpAddrTable;
' \0 }6 a# N8 d. F TGetIfEntry m_pfGetIfEntry;, O3 k" q9 o q# y
9 q8 w7 e8 U* G, {
' `$ `; |8 i/ F3 r static FinderPointer CreateFinderInstance();9 B' U% C* }' N. n8 Z; ]
struct FindDevice : std::unary_function< DevicePointer, bool >$ N4 _0 V2 H0 @0 p5 K6 w8 d) D
{9 w$ d. }& i# F* g4 P$ }$ `7 _/ E4 w
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
# U' e" z4 _# V result_type operator()(argument_type device) const8 E$ T5 p9 r% [0 T: Z1 w
{7 H. C8 N4 e( p ]6 W+ f. i
CComBSTR deviceName;" ^' k& d5 a4 X% D% W
HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ x5 E6 {% K/ e3 p, m4 i
+ n+ t8 I' X# T( k
6 B" Y- I# R; r, q3 r if ( FAILED( hr ) )* A b x2 V5 _1 i
return UPnPMessage( hr ), false; ~" E8 E3 e* o7 f3 I4 f
$ Q4 Y8 v+ c- q \& A5 }
5 r- z5 ^: q. N! o/ L( j3 d
return wcscmp( deviceName.m_str, m_udn ) == 0;
; ], _2 b% o% K( N3 b) s }% m X2 g4 ~; S8 g/ O
CComBSTR m_udn;4 z; w- K# D, H- O2 k2 I- j
};
r c, q7 L1 d8 v3 m" t* j \& J& P7 s) g/ V8 l) F: h
void ProcessAsyncFind(CComBSTR bsSearchType);
2 ^" n: M3 ]# _ {5 r HRESULT GetDeviceServices(DevicePointer pDevice);8 ], r: k( V- e0 O
void StartPortMapping();+ `/ S$ `7 |: S E; G, V% T1 M) j
HRESULT MapPort(const ServicePointer& service);
( H6 [$ ^; t+ B8 @- E void DeleteExistingPortMappings(ServicePointer pService);
0 T! s8 L9 \. [0 Q void CreatePortMappings(ServicePointer pService);
6 `* S9 C: W. I) D HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* `% P/ {& Z( f! z) V+ a, h HRESULT InvokeAction(ServicePointer pService, CComBSTR action, * r) k0 b. e2 X. J$ B& C+ C0 A
LPCTSTR pszInArgString, CString& strResult);' d6 M5 \% r7 W2 o0 y- n* S& m
void StopUPnPService();
7 F* A6 U' Y* X) |* v6 B2 s# M% _$ b; I2 J
. D( z0 D$ \0 w0 B( G6 L/ o3 l* v // Utility functions
$ v9 a" U% N( s7 \; u. G HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);, ]; D7 S6 R& E% P. v" w& V
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. }2 J& E, q; N5 @6 `8 a
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);; e# B* P* I' O. f* N; z
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);0 F8 n) W9 _+ r
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
/ A. O* W( Y% x, L8 F3 X4 p HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
5 i# j6 `+ W8 E, X CString GetLocalRoutableIP(ServicePointer pService);2 N& |8 Z3 F5 ]. k# K) u
# I( b7 q, _, z6 {( Z" L
0 v6 q+ u; Z% x# M
// Private members
( Q% x+ P/ F/ O% [' z- Z% S( k+ R$ \. k# lprivate:, h( h6 l1 K7 [# ~
DWORD m_tLastEvent; // When the last event was received?8 L- B8 Y4 Q0 S0 w$ l
std::vector< DevicePointer > m_pDevices;
3 g# Y# ?; \. K$ Z! i std::vector< ServicePointer > m_pServices;2 O9 V5 D6 p5 e/ x9 `7 n: B: B
FinderPointer m_pDeviceFinder;+ {) c; u0 v3 ?: C2 b" ~
DeviceFinderCallback m_pDeviceFinderCallback;
1 f% E+ |9 f1 v7 l7 J$ w2 y8 l ServiceCallback m_pServiceCallback;; G4 W; {" l0 r) c0 \; D( S- R2 J
6 f9 ]- d% ~1 {; ]/ j' k
' N) |- n7 _4 _8 i; Y. F3 F# U% \6 j LONG m_nAsyncFindHandle;
% s% t- a, d; X bool m_bCOM;
9 J! p h. h" o- Z$ Q bool m_bPortIsFree;
% k/ u+ w+ N4 E K+ M CString m_sLocalIP;
, H4 k9 Q# O0 j+ }. q4 A& }! M% U CString m_sExternalIP;) g9 m6 J" `% ?2 t: ~* D* w
bool m_bADSL; // Is the device ADSL?
/ l1 }# `) C( G$ ?- o: P' ?# j bool m_ADSLFailed; // Did port mapping failed for the ADSL device? a Q& k1 o# ^! n! `
bool m_bInited;
% k( W0 A! @' U8 E1 ?& ~8 o bool m_bAsyncFindRunning;
# ?. M3 L: v5 B7 Z6 _+ E- v HMODULE m_hADVAPI32_DLL;
" ~* Y( Z4 i, ~8 u: F% n HMODULE m_hIPHLPAPI_DLL;, u) ^/ A1 N$ f, }9 R" d! M
bool m_bSecondTry;' F. N5 L6 I, n
bool m_bServiceStartedByEmule;6 R9 m% R( w9 j' w" P1 I5 o
bool m_bDisableWANIPSetup;7 E1 B& o3 Z1 s( ^3 W& [
bool m_bDisableWANPPPSetup;
! h3 K% D3 b8 P6 N( |' ? ^8 ]3 v5 k. r' ~$ x _
: D1 F0 z) O. C6 O5 T8 y};" V! I; Z" ]! o! e( @
5 M' C" Y5 ^4 A, M* x& K
6 X$ H: }1 A" M
// DeviceFinder Callback3 j5 P9 y8 H# j! J
class CDeviceFinderCallback& _$ N) H5 k7 ^. N7 L
: public IUPnPDeviceFinderCallback
4 ?: [. U( J$ @, A3 F8 O{
: K4 l1 A) S$ X0 U `: Xpublic:
7 O, W# k; g7 b CDeviceFinderCallback(CUPnPImplWinServ& instance)" T3 U% _2 M: C
: m_instance( instance )
$ X: I* w# X7 X% ? { m_lRefCount = 0; }6 l0 t# V5 y( J
8 E0 n' S" D, y" P8 h! X
) W% ~" L7 n- P5 R5 M/ ^2 s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);9 L7 k# }4 q) @! o4 n, X
STDMETHODIMP_(ULONG) AddRef();8 g/ G5 R+ }$ T# |
STDMETHODIMP_(ULONG) Release();9 _3 O4 r4 {7 B0 w, {
( o7 ~5 V) f2 g1 I0 F
a# J) [- Q* i6 ]& o- t* M// implementation
3 I- j; e" \3 w C0 Eprivate:4 b( \3 q1 A X, n8 }
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 P) j4 Q2 k4 [% N4 ` HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
: F7 F! z5 P5 [ s* @ HRESULT __stdcall SearchComplete(LONG nFindData); p9 G3 {7 w7 k' o9 ^ v3 [
+ r4 g* r4 T- N6 {8 F4 E
/ j) z r3 i8 X$ N" E5 s- P- aprivate:- W. r9 E5 l8 f+ [5 F7 @# P
CUPnPImplWinServ& m_instance;" W5 z# X0 x" e( a7 g$ P
LONG m_lRefCount;
# k& r$ R4 L" m/ M) C};
% F, k) J. u/ m& f" l4 X3 v# T. \6 A2 ]. ~: K1 P
9 U3 V( m" P# Q- z, N// Service Callback : F4 I9 e5 [; C8 j
class CServiceCallback9 P- I" r2 i/ J6 ^9 u3 E. }
: public IUPnPServiceCallback
0 u4 T* T5 |& ~; h- m{
/ O2 ]+ Q+ P; X9 M8 r; _, y# Rpublic:
6 v5 j% {; S# N7 [" M0 J& o7 T CServiceCallback(CUPnPImplWinServ& instance)! j1 a4 r$ g% m# I+ |
: m_instance( instance )
8 X. a% r6 i: T; ~ { m_lRefCount = 0; }
5 N$ Y, q1 x' \, l. {/ i
2 V' j# @2 F9 v( X* h1 i8 q+ r STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, l- x0 H" `' A: h- F
STDMETHODIMP_(ULONG) AddRef();
2 u( E- j1 [3 \5 o' i STDMETHODIMP_(ULONG) Release();
& \" G1 |/ x5 M1 o8 R
6 T; _/ j2 @, w5 D% v/ [2 _
7 F) v! [: X2 c2 `6 [// implementation# |+ y* c: e' [8 e
private:
" D; s6 _/ X6 R" T HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 N, Y3 v- g* b) S1 Y HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
`0 i! E6 B3 W# h" `3 j1 c
, s9 K' S+ Y$ N2 t5 }. G- O# v% |+ S6 m7 W% }
private:
+ H" e) |& ?) _* `) T' ^" w2 v CUPnPImplWinServ& m_instance;8 y4 f5 T: }: Z7 ~3 C8 G4 `5 c
LONG m_lRefCount;
" h: y3 l9 j9 q6 \4 [; b f3 n# {0 i};
+ i, D1 u n2 v) @+ f- B% |2 ?. q2 Z- |/ _
2 V/ h/ L7 M$ l9 Y6 T4 @3 i
/////////////////////////////////////////////////
2 F6 K% e: n* M' u. o2 F! `4 ?9 t4 \& ~5 Z
# L/ s9 R) D5 A3 c6 U; W
使用时只需要使用抽象类的接口。* ], x2 k* ?* \$ w* B+ Q- y
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID./ S+ {; n, d- U$ t+ t9 q. M# U: w
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
r" f4 W8 X! X) uCUPnPImpl::StopAsyncFind停止设备查找.
2 n: Q) F' R' N) u1 i( |CUPnPImpl::DeletePorts删除端口映射. |
|