|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
+ g% _. s' h! E
: q! E7 I' r, Q. [) g& g
; `' C, ?' a3 a$ ^* |///////////////////////////////////////////2 f+ y9 a3 F2 i v5 }* s
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.' ^& x' g* C6 _6 e3 V
) A# m0 y( [+ v4 |& c0 X
7 B5 d1 ?) D" e t: T. ]' g, J6 e! s#pragma once; G' c2 t! J$ M# X- s9 C! H" m$ f8 j
#include <exception>7 x& H0 C. W1 J; w ^
3 \* y9 t8 v! V$ A5 X5 H
; |* m/ M) e0 c+ J2 [8 y
enum TRISTATE{6 N0 A1 Z- { g
TRIS_FALSE,
4 N0 t: v( W' T. |8 E TRIS_UNKNOWN,
7 c5 m: n/ Y: [% A" d TRIS_TRUE( @5 K/ T$ y7 z1 F1 k0 M
};
7 l) c$ [* w0 E6 o N9 D v2 r6 v
) s# d: d7 b: P6 c! B j7 v
1 B+ w' y4 D( e2 j" b' renum UPNP_IMPLEMENTATION{7 s7 P3 x$ K5 ^
UPNP_IMPL_WINDOWSERVICE = 0,
% ?) X" V* a ?2 }* l UPNP_IMPL_MINIUPNPLIB,
. I% p! X9 l* K1 r5 u UPNP_IMPL_NONE /*last*/
; @5 k; A9 x8 C e$ m};
9 | P1 i* }& S4 f. |7 N. `5 t( ^( h' h- w6 R. c
5 U6 o( n8 g/ ` |+ I
4 u' T7 q9 D7 `5 v- h0 K( y% d
3 d% H+ ]: r K( @; {$ i3 T0 x" ^class CUPnPImpl8 E) v0 a" Y+ Y" j$ W: G
{
, I( C+ y. f4 dpublic:
; ^, G$ y8 A1 w: d4 |1 k2 s CUPnPImpl();; s" n2 W; t9 \7 |/ b6 R& l
virtual ~CUPnPImpl();: O, |3 Y- j x9 c T
struct UPnPError : std::exception {};
7 K8 s, S! J4 A8 a enum {6 q" e* W( A: C8 G5 w5 G
UPNP_OK,
2 |7 W; B( Q, Y UPNP_FAILED,$ v+ O2 [8 [3 q, @/ @1 L
UPNP_TIMEOUT
7 h k R2 g& c" P7 }2 S };$ G- J# D: A9 N* }- r. Q* L% `* V
+ h& j( |) { i
' w9 f" @0 Z) _ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;0 C1 R A6 a* l% {( r/ u* l
virtual bool CheckAndRefresh() = 0;! w9 n$ J9 t3 d
virtual void StopAsyncFind() = 0;
; q( q! R( C% b' ~! L( H virtual void DeletePorts() = 0;
/ q( g' U0 X" J! P- U" [- H virtual bool IsReady() = 0;
1 V8 `3 r! N) n' }9 M1 X virtual int GetImplementationID() = 0;3 B: E0 a: e K0 M9 f, c
" }5 l1 |! P2 Q. t" P: \
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
* W5 K8 C+ ^/ R3 ]: i1 V: _* X8 g) H4 j0 q% I+ j2 {3 A& J- _6 `
$ A: T5 m4 p9 V. \% c# Z void SetMessageOnResult(HWND hWindow, UINT nMessageID);
. B+ f, v3 v! @6 h( Y1 W TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }5 B5 L0 l G9 K% D0 u
uint16 GetUsedTCPPort() { return m_nTCPPort; }: D. x4 x9 X7 }0 V
uint16 GetUsedUDPPort() { return m_nUDPPort; } 6 ~0 X6 D5 K& `% l; m
N, @0 G+ t6 Q
9 M0 e& N4 }: b7 `8 L// Implementation2 Z/ R% O# X+ p/ r/ i9 u
protected:1 A E" A s2 U( B* X
volatile TRISTATE m_bUPnPPortsForwarded;3 _5 l* X+ G9 R/ E# N+ S6 ~
void SendResultMessage();. Z6 A6 e& ?3 q( ?! `# m
uint16 m_nUDPPort;
+ A# c) d, S) d0 M, `! P* u# W uint16 m_nTCPPort; J% m$ y& f! y
uint16 m_nTCPWebPort; M: \7 y3 q; \* H0 b' c
bool m_bCheckAndRefresh;
9 f D9 q* b8 G4 i( W& r" n: c4 C; E! l7 B2 b3 Y( C) B+ _
; M* O1 S; j' A: kprivate:
/ Z7 X! W) t4 S+ ?1 A HWND m_hResultMessageWindow;
+ r) i; l4 Q* x4 E" Y. d" i UINT m_nResultMessageID;+ U, c: I( }! R5 e0 i2 J# s/ k
4 n. G0 f9 J- R9 L. i% @
2 A' _; s# ^& G};
! i. W7 F+ w5 G! ~/ l) F1 B
# {' w6 ?( x+ z0 h( U7 Q
1 a n+ \6 q6 Y9 s2 G3 q$ E// Dummy Implementation to be used when no other implementation is available
7 z0 d7 N2 B( v6 Xclass CUPnPImplNone: public CUPnPImpl
8 e1 S1 J* |/ I$ l5 B2 k{
, _+ e: K0 f3 F) C, vpublic:
: I4 I: ]* c# B virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 Q& ]4 F8 U9 ^* ?/ W6 ?+ u virtual bool CheckAndRefresh() { return false; }
$ g/ t3 P) z* B! U8 O Z virtual void StopAsyncFind() { }# h; C( ?% N3 G" ?
virtual void DeletePorts() { }
0 h0 \& l) m6 {) m- z" r/ k+ H% _ virtual bool IsReady() { return false; }& U$ g. L4 y7 u: Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
; a6 G9 W: R$ S% }9 c$ d- b4 [};8 h/ k, T/ I7 {5 F
8 T7 G/ P) F2 x, Z
1 {/ l& h0 ?; {* W6 t$ u1 _* E# K/////////////////////////////////////
; z4 M8 o. q3 J( u/ i//下面是使用windows操作系统自带的UPNP功能的子类* N0 b% C$ N' S! j7 z# h, `
# Q. d3 r6 c9 f; t; X y) M- k3 H) ]8 a' D6 t
#pragma once
2 e- A' G# H$ {2 N$ X- ~#pragma warning( disable: 4355 )
4 t- ^) W5 l1 h w, L: i# Z7 [: c
7 R, V0 t* E$ e( d# F" G4 t! y1 |6 }; F- i
#include "UPnPImpl.h": r4 a( Y+ ?+ W
#include <upnp.h>
. S1 B, s d# Y* l# h) C- P' B#include <iphlpapi.h>4 h+ p( G0 s/ A$ z R( I9 Y
#include <comdef.h>
' b: i8 R( t6 H( S0 F, G! H8 y#include <winsvc.h>
, b- Q, u3 m6 Q3 s/ V8 Q5 v- ]; d7 u
, q0 g: i! y! \% s$ q( M9 o2 n4 k
#include <vector>
6 o4 o N- p1 E0 P; Z) K/ ?# Y#include <exception>1 P# L* J+ o. y9 V0 B9 B o9 k4 j: A
#include <functional>/ v. ~+ _ s: M6 f9 i: p, S V
8 b: V6 N8 O! G7 K" p! @" u k3 V) H7 b* y+ o
: J% Y( n" I6 W6 ~ a) n0 y
7 @$ G1 X* y1 w8 J/ Mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, O5 A8 s6 i7 e% `
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;9 {; S& L& L1 @% l1 o& I
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;8 K4 h9 j- r b1 [7 S
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;& i' h7 E# \& d7 z& J) P+ y" l
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
! u0 y$ e/ L0 ]* Vtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
- I: A4 M' ?0 h4 `9 qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
# y; B* e' k1 B3 y& c) q6 T& U8 l. t
- c4 R! P( I" G: d% a
typedef DWORD (WINAPI* TGetBestInterface) (, E# M' m m; {: w
IPAddr dwDestAddr,
H7 N! d p- O1 v" } PDWORD pdwBestIfIndex
& T" ` D- ]/ r2 u; q/ G; r);: x! o7 G# M( x+ I) `9 k% D& h# J
0 Q8 ]3 E* H+ v( a- ~8 \$ l
n3 W* s2 n% `6 t$ Y
typedef DWORD (WINAPI* TGetIpAddrTable) (2 y1 L* s, J0 [5 n
PMIB_IPADDRTABLE pIpAddrTable,
- b4 @# Y" ]4 `3 f" `# Q. G PULONG pdwSize,# k1 z' c& A# b7 W! z- Q( B5 r; Z
BOOL bOrder
2 C. p! V# ^; g);0 r# T9 _5 L: x' W }
! L) T0 a* O) J7 M" R
& Y% J* w+ _ c5 o9 q
typedef DWORD (WINAPI* TGetIfEntry) (
9 k+ J* [/ ?1 x" U$ o" i PMIB_IFROW pIfRow
" f5 [( D4 A, g Q, S/ t$ x);
5 w/ w9 K0 k0 M0 `8 f Y# y2 i# ?$ U. d0 |. G& @
0 R3 e# H) c8 V, D: I
CString translateUPnPResult(HRESULT hr);
* m& V* @- p" qHRESULT UPnPMessage(HRESULT hr);
& n3 s8 F) a8 U8 h& E$ [$ N7 E0 w+ m5 ]2 S% A9 A5 y
5 V- z1 z0 A2 C3 ?; S9 ]1 rclass CUPnPImplWinServ: public CUPnPImpl9 n" S% w; |9 K4 n. \% Z
{
, ^$ G0 a3 H* t7 ^% y- l friend class CDeviceFinderCallback;( ?% I/ r, B7 Y+ G4 i ]6 O& g5 A
friend class CServiceCallback;
) {! Z7 f) K1 G; O% ~// Construction+ V& q; z) \& v' J
public:
( Z% a; p! ~0 f* {3 x7 _ virtual ~CUPnPImplWinServ();0 ?1 S( S' a2 ]
CUPnPImplWinServ();
: j2 Q( m6 {. ~
) V+ @& U1 H4 r$ N5 A4 @) X
% Y$ I7 S3 e6 u2 G8 }) x# M virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }- w: z8 r! e2 Z! w* h8 t$ p2 f+ F
virtual void StopAsyncFind();( P- l1 l) s/ E& e3 z# g
virtual void DeletePorts();
+ K7 F* e9 a! M4 r( T' X7 r virtual bool IsReady();
+ j1 |; z0 V# p9 J% I9 W$ j virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ W% h/ s8 H, m( |, V2 `6 [
) ?8 n% p6 `- J" m# ?$ M. ~
7 h0 u# F6 G8 z- T F
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
$ ]' A! K) |) o1 | // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later) a; c7 v( ~: _8 p2 V9 ~* ?- q" n
virtual bool CheckAndRefresh() { return false; };
" k- Z: \/ t9 F% }
0 Q+ A" Z, Y* ` e+ v4 U- o4 w& G& s5 i+ c7 E# J+ ~9 w6 C" K Q B
protected:; w5 W2 G; m5 I3 U$ H
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);* y$ n! w0 n _( ]7 n
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0); j/ j$ J' n, k; e+ Y P ?
void RemoveDevice(CComBSTR bsUDN);
8 @: h- Q' U$ Y1 ]& Q( e' a bool OnSearchComplete();
0 ?3 a3 ]; Z$ @: c$ J! _: Q5 h void Init();
8 J" s ?, Y- @( T0 W; z* k/ n2 c* y# `6 ?' l: G
5 L9 v+ a( Q' [: F0 N inline bool IsAsyncFindRunning()
2 J' e, I2 @3 p7 Q0 E; f4 @ {
; K }8 G6 P7 | if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
+ P5 b3 O& _; H. a {
: \( |9 _" `% ^2 N! Q m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );' g; o, n1 \$ }; z. j
m_bAsyncFindRunning = false;
' g \5 n- S6 u2 l0 u }
. g4 [: I W! K# L" h& d& S MSG msg;7 ~$ v1 P( _' a9 d
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ), Q+ |, z5 l% b2 e
{
. O: M# T4 S: @$ p9 q/ L3 s TranslateMessage( &msg );
o# `0 ~7 O8 v( ]9 h- z DispatchMessage( &msg );
/ l9 p0 A* i7 Z8 L }! H7 ?! X$ E! H. ~3 V
return m_bAsyncFindRunning;
W* V6 p0 y# C1 Q8 s z( [ }. Y* M+ A) Q+ m! Q2 J3 k
+ y: i, T; T5 V7 ` u+ n3 w3 E4 ?
* n: B' g+ `5 \$ M TRISTATE m_bUPnPDeviceConnected;5 M1 V! _# v+ i! s& f) ^
" _# e' e$ k$ h
7 y* n% _* }# H) l/ f, h& E// Implementation0 R) ~& p B3 O, y- P
// API functions4 Q3 K+ C4 y1 h
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);: K6 E$ A5 T- V) u: Z0 ~
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);. T; t5 i& A; w( E
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
) M/ K: D) Q) O7 Q W+ h BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);/ _% J. M) F/ W$ }7 K$ ~
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
- y* N8 e* Z0 E9 T/ ? BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);9 C+ S d9 K# f8 b6 @
, {! Y' `; [' N( P* J( Y0 ^% L
7 q, j) b4 i$ b TGetBestInterface m_pfGetBestInterface;
+ L; Q; k% U W TGetIpAddrTable m_pfGetIpAddrTable;
l a9 A0 X( |# S( y; o+ W TGetIfEntry m_pfGetIfEntry;2 L" r; x; @6 W
$ }6 e& e: |* ]7 S& {& J/ N
5 }4 z( K* f2 @; J) ]$ Q- j- d static FinderPointer CreateFinderInstance();& e1 X# r' a* s/ [/ J5 D; ~
struct FindDevice : std::unary_function< DevicePointer, bool >- r9 M" u- h! e* C
{
2 p2 C% K3 r3 P6 f& U/ g FindDevice(const CComBSTR& udn) : m_udn( udn ) {}$ ?+ B) i9 e; M8 L4 W1 W
result_type operator()(argument_type device) const
, [" k9 C/ v! f {: P/ `/ ]8 T; P& R9 A O# C2 {
CComBSTR deviceName;
3 L. U6 g* ~. h7 _/ f5 p HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ g0 L0 k: o' E6 }
. N. S# O, v( ^# W0 e1 F& `
" V, `" q) Y6 x9 U' q- H5 Z
if ( FAILED( hr ) )5 [" m4 w9 o+ P* m8 G
return UPnPMessage( hr ), false;2 } P3 i9 X& M3 K# p3 f2 D0 G
" G) \5 X |4 E" z& p8 C# Z2 U' L3 P
return wcscmp( deviceName.m_str, m_udn ) == 0;4 O# ?; D. y! a% ]
}5 [/ n$ i) f- |( A
CComBSTR m_udn;
! J" a6 p9 U/ M, Y };. O/ C+ Z( D3 D' D
& ?/ V; c' g3 c; i8 v
void ProcessAsyncFind(CComBSTR bsSearchType);& V% a) h; S( F8 G
HRESULT GetDeviceServices(DevicePointer pDevice);7 w. E6 m3 {2 B: z* g8 s3 m; i
void StartPortMapping();
+ Q; H2 k$ h4 G6 B HRESULT MapPort(const ServicePointer& service);" }* I/ h( _- |& ~7 E8 N: p: Y
void DeleteExistingPortMappings(ServicePointer pService);/ r+ L$ @1 A* I: f
void CreatePortMappings(ServicePointer pService);
2 U. r9 s3 a- ~ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);" G. ^( {" T! M: T& F. r
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
5 ~) H3 @7 @: r$ u LPCTSTR pszInArgString, CString& strResult);4 B! ?! r" _9 P4 n1 f {
void StopUPnPService();8 z0 e$ p" @1 Q% h' Y1 p/ L' _% c
. P* j& ]# i7 A2 Z7 r
; [5 V* Q% v/ ^" c" | z // Utility functions3 A7 S2 _' L4 m: K8 j2 C6 G( Q
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);; k( J* c6 Y& J$ ^+ `$ B
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 a5 n1 n+ C0 B4 O; H INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 m* `* h+ w, h7 }$ s
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ G( Z; L: |! k7 x9 R# w8 _ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);4 F& z) |. s: ]4 e# j4 h
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
0 N6 N: Z- k" d2 k9 Z4 h CString GetLocalRoutableIP(ServicePointer pService);- Y( _/ z2 `+ E9 ]3 T/ V
) a2 Q2 F/ s: c" p; z4 k4 u. b
l2 d7 T0 ~6 a0 e% d. {5 I: F4 @// Private members1 e5 z3 k' J1 e' H: Q, [
private:7 A1 @+ |/ M- P) u; N) ?/ c Q. W( D- r
DWORD m_tLastEvent; // When the last event was received?% k2 g9 t4 k% |4 L* N: S0 x" b+ J
std::vector< DevicePointer > m_pDevices;
. V5 _. Y; S& p7 V3 ?; @ std::vector< ServicePointer > m_pServices;+ ]+ b9 x9 d0 w7 W3 N
FinderPointer m_pDeviceFinder;) s, l+ ]* [" I+ \& L3 W
DeviceFinderCallback m_pDeviceFinderCallback;
+ I3 p& Z8 ^+ B/ R' b ServiceCallback m_pServiceCallback;
6 P: i3 g$ @# u6 ~% |) Q
6 D" r" r( ^) @& k% l0 u. m( y8 k
X4 k2 j8 z% o& t/ A k LONG m_nAsyncFindHandle;( |- I7 `5 U- Q+ H T9 H
bool m_bCOM;. S1 ]6 u5 U* @" O5 e3 f
bool m_bPortIsFree;
: n: [: ^9 h1 o& { CString m_sLocalIP;
# v: I% B# b6 _. i2 c CString m_sExternalIP;
) b$ G! e$ {& I, Z- A% t, T bool m_bADSL; // Is the device ADSL?8 X3 n/ ^$ ?/ M# {! G
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?7 p- V) w% [1 n: w8 _0 D( U
bool m_bInited;( e8 N$ F. O/ X
bool m_bAsyncFindRunning;
/ a! |4 k" Q' _$ r HMODULE m_hADVAPI32_DLL;0 a8 Q& p7 z- x2 f9 A
HMODULE m_hIPHLPAPI_DLL;* e/ d/ }4 ^7 M' c3 B" I
bool m_bSecondTry;
6 @4 d$ |* V7 A# r bool m_bServiceStartedByEmule;
. z+ d& z( @$ J0 s. U bool m_bDisableWANIPSetup;/ j1 P/ [# V+ g. O& Y
bool m_bDisableWANPPPSetup;* e; i ^( }7 X0 D
+ V7 W) w: _. f( A* w7 }
- v, E7 K, t9 b! _. r};. F2 N: T# d6 m/ q6 f
& @" O8 Q- G" _ x9 w W2 d
/ F. l' `1 V( \8 J5 Z// DeviceFinder Callback% l# n/ M$ q$ Z
class CDeviceFinderCallback4 I' E$ E) \4 a4 d# a
: public IUPnPDeviceFinderCallback
. z* v, c& M Q/ W8 s{
! `) S3 W( M u% dpublic:- C* A, b# [! i: s; I
CDeviceFinderCallback(CUPnPImplWinServ& instance)
, W: d0 g0 w; I6 z& u; e : m_instance( instance ): W/ |0 S* d$ }3 `- _
{ m_lRefCount = 0; }) X1 _ ~! U& h6 G( I3 c) p
- b- D, S% T6 J1 _
2 }# R: S7 z. q( L Q" O9 U1 w
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ z+ u% p% x) t% S1 s4 d
STDMETHODIMP_(ULONG) AddRef();
2 r" q" v7 W: @ STDMETHODIMP_(ULONG) Release();
0 M3 h- x- K8 E* \) u/ I
8 A% o0 H$ X/ r; r; Z
- D0 l; e# u# p) I* A* f// implementation d+ g$ P! `! q3 ^: U3 m1 ]. @
private:0 U8 {: W( y, y" b( o4 x
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& e- \# l3 z% p& Y! v3 D* j; R; H
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, C, T" H" ^! w8 i7 Z
HRESULT __stdcall SearchComplete(LONG nFindData);$ [! [3 D, R) `! }, u, p6 x j5 Z
2 W( h' ^" U) ^( a: @! v
; s- ?1 N% @' S- B0 f
private:, X, K* I y7 H: V& `4 N# T6 m
CUPnPImplWinServ& m_instance;
* I! v* M& k, Y6 i/ i LONG m_lRefCount;9 p- Q4 I) S# b2 g1 B" N
};
4 A4 {7 z" i" c( A( r( Y+ Y* ?* L+ D: I8 F
. i. U0 \7 T6 ?& T2 v* D
// Service Callback
3 d7 e% N3 i3 m' q7 W- yclass CServiceCallback+ w+ h0 ]9 r( \- c2 P9 G4 U" u
: public IUPnPServiceCallback8 D* p' G2 f. c. [" B& H
{
" ^: u e7 w7 {( h k* ]public:
, P! G# J6 J; |, R" `/ L3 Z( ` CServiceCallback(CUPnPImplWinServ& instance)
2 ^% `# l/ j0 P : m_instance( instance )0 m6 a/ w3 R1 [" e W" P0 X
{ m_lRefCount = 0; }9 G4 }1 O! r! f$ {
0 F( H* J, w; s3 `! e+ y/ O
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' a& x. S4 X0 B4 Z
STDMETHODIMP_(ULONG) AddRef();! K8 T" ] f% t. g y# \ @0 w6 j
STDMETHODIMP_(ULONG) Release();
4 O! r* F) w- \
* q0 f3 p( m% k; Y8 h
' W5 X, g; J2 z$ X) V; S// implementation. h! R. A$ `( b& }4 P% J7 _& q
private:
5 F2 m2 g; O" P1 P& S HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);& l/ ~: V( S# g1 n) u
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);/ R8 q: E4 Y/ c3 I* S
+ U' B2 t4 v+ E
D/ P% e0 ?: U( Bprivate:* P/ }( n5 k: L( Q, o9 `4 b
CUPnPImplWinServ& m_instance;! R2 u$ d9 y: y( P
LONG m_lRefCount;
/ X* U- [4 m3 D K};
2 q; {7 R1 @1 M; ?1 r( I
0 q4 t' ~. Y) q1 u: p& ^# l k V; F0 D; \: o/ k
/////////////////////////////////////////////////! m ]) u/ D- T: |" i
( T' J* ]8 m, O. ^/ o8 J* {- h$ Y5 `# s
使用时只需要使用抽象类的接口。2 ]3 y5 I6 f( Z" @- p n8 U7 A/ u0 a1 j
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
! k4 D I: F3 V9 y2 Y$ |0 yCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
. A9 H- v1 @$ DCUPnPImpl::StopAsyncFind停止设备查找.
( K: d! B4 V) O% U$ ~9 k" o- bCUPnPImpl::DeletePorts删除端口映射. |
|