|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
) l) g6 F+ V1 O) b+ H1 L
& v: c# N1 K; B" H. c t2 e+ J, _3 m# T9 L% {4 X, }* z
///////////////////////////////////////////8 a( z# i4 b8 q Y8 _( g$ ~) {
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.* S7 n- ^( \8 h3 }8 L
' P/ Z; o7 L: w3 ~2 k5 p
5 K# w9 O0 k, C#pragma once4 h4 k- R5 j! _
#include <exception>- `$ P- X" x3 P) w
4 M7 D0 s4 [+ l4 Q$ m* y
5 a/ f4 ?7 ]% c% S enum TRISTATE{
" ~% J$ m$ L2 A; u2 r! M3 \/ C TRIS_FALSE,+ Q: J/ p3 |7 v. i9 r
TRIS_UNKNOWN," t& R8 t+ e6 [& ]: c. u4 Y9 t
TRIS_TRUE' J4 o' R, ^" `# I
};7 \' p, A: W7 U: y& s! T
! c. d3 c2 a( s
) O( ]% V0 q5 g6 kenum UPNP_IMPLEMENTATION{$ b t$ ?% C! t& T/ Q
UPNP_IMPL_WINDOWSERVICE = 0,
8 |" X4 p0 v& F4 L( t8 }4 x4 z1 C; C* s UPNP_IMPL_MINIUPNPLIB,( ~) U5 @5 U# L( W& c' ]
UPNP_IMPL_NONE /*last*/
* W [6 e% o9 X- I" ]};: ]( [- r, L$ C& Z! T; W8 q
3 R# o9 j1 z% U: r
/ J& G- F, u1 W2 B8 Q* k
2 }# z/ X* S% j. [/ K8 e; `0 A! n8 |- ?/ `- K7 U5 a% O( M4 u' c
class CUPnPImpl
& e# G' S* y$ v, w. V, D{7 J7 n" F, \3 O5 S
public:
" h+ o* Y: `0 o3 M# J+ z CUPnPImpl();6 i8 H' V( o f7 C
virtual ~CUPnPImpl();% m5 x n7 b- a8 G/ l
struct UPnPError : std::exception {};5 f. n& W, Q; x: ?/ k4 K
enum {
% E0 ^( p! D* a3 Z UPNP_OK,: T: J7 O8 N4 m" v$ h
UPNP_FAILED,, w# p0 u/ \4 v: S" ^
UPNP_TIMEOUT
* I! ^( q+ I1 f8 {( r };
1 d% Q" n8 u* c6 l3 d$ V6 ~
! m8 ~, c4 W$ |, O7 Q) E3 i9 M
; I6 p/ f/ L+ ?! |9 {2 b virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" j1 ~! d% G$ y% ^6 R% j
virtual bool CheckAndRefresh() = 0;& z- l) z* k* m! f# {# \$ N
virtual void StopAsyncFind() = 0;6 F' Z) T- g4 ^9 @0 r
virtual void DeletePorts() = 0;
/ a6 P+ ]% E3 k' T2 p virtual bool IsReady() = 0;, V) Q3 s( |/ b- z! l! z
virtual int GetImplementationID() = 0;
' O5 F: r% u( _7 ]0 v
& m$ f& `' P2 ^+ M/ O9 H* d3 ]! e. T void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
7 z' _) X3 ^4 _' o
- C8 b+ S9 I# W B7 S x$ J, Z. m
) s6 I- Y; J; g2 A void SetMessageOnResult(HWND hWindow, UINT nMessageID);
5 E( p) Q# z# v2 | TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }% U6 F) O8 H' \4 u k! C
uint16 GetUsedTCPPort() { return m_nTCPPort; }
8 W+ Q" s2 x$ h2 K uint16 GetUsedUDPPort() { return m_nUDPPort; } $ u+ N. ~# A# A6 s% }
# Z7 l- c6 u. y. K5 f$ b
! N8 m. p1 q1 e& Q// Implementation- |1 P h( B1 P p9 [3 N
protected:! ~0 G" ]7 u4 q) T! w& s
volatile TRISTATE m_bUPnPPortsForwarded;
! p7 r: V$ z: |6 u$ X. M: O* x# c void SendResultMessage();
/ }2 Z; x5 ]5 \4 d+ j/ O. N uint16 m_nUDPPort;$ L5 D& }% H: z; c, E$ H
uint16 m_nTCPPort;
& U7 j: M( @+ G4 {6 R+ k( \0 u+ \ uint16 m_nTCPWebPort;6 g* I8 c# Q. m( ^" y
bool m_bCheckAndRefresh;
" W3 t: p6 h# C* T
6 F5 v$ g& s$ G3 U
+ b" Z" W- T( H& n* ]* |& R$ Iprivate:" _( a* l6 X$ c( J% J
HWND m_hResultMessageWindow;
! u. t" \& M1 c _! _2 [ UINT m_nResultMessageID;
" f* a6 f1 b5 a! r$ F# l- u, m6 V# w# |9 C6 |
3 U0 O( r! R9 }8 C* w};' [+ W5 U, U6 \6 R9 P' g
! }6 s# _. U0 B& D- f- S* w1 R% V! J
5 `( _' {5 b/ d7 ~( N) t// Dummy Implementation to be used when no other implementation is available
~- M6 T7 i& B, qclass CUPnPImplNone: public CUPnPImpl% ~: ~3 Q. e$ H% [3 }7 x, S
{0 h; a! D1 ]$ l: ?( n7 N% z+ l
public:
* Z' H0 A( A Z A- n* ? virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
- i( E+ L+ k' ]' Q0 R% ]8 @$ t. M virtual bool CheckAndRefresh() { return false; }& l( q, o: y G
virtual void StopAsyncFind() { }
2 F4 r* S, {! L1 Z7 X4 S3 r virtual void DeletePorts() { }
. ]! A* [% J: r3 b) S, B virtual bool IsReady() { return false; }
+ ^" P; O# I2 I. {: A& G. j' g virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
+ |& ]4 \9 C6 d2 V0 F! d# H};3 }4 M3 K( h" Y! g
! r, F( T+ V& w. G
; @0 N: x, w, _% x, z0 ? }) K/////////////////////////////////////
0 {# D1 Y. Q* N7 G2 S//下面是使用windows操作系统自带的UPNP功能的子类
( K+ f2 k6 r2 ~# a) M; R8 {0 l
" e* l/ j- x# g( z; D#pragma once4 C o' V! z+ G& g
#pragma warning( disable: 4355 ) ?1 e, H/ e3 i% b3 _4 q
( U* w+ }/ j7 p$ v" E) E4 J, e. O$ f2 T
#include "UPnPImpl.h"
7 n! p0 R' Q; w0 V L* t |3 b#include <upnp.h>
6 |* Q S) `8 \#include <iphlpapi.h>
0 |; e( k; u# Y9 j; T#include <comdef.h>& }' u3 |4 z) e+ ?5 o$ y
#include <winsvc.h>
- O! l& I9 y3 T3 H: L P5 v
; v8 M: A! t; V# I7 k0 Z# |1 P# g. C; r
#include <vector>
4 v; D T7 o D) v#include <exception>( K5 A* x9 Y0 d0 [9 F
#include <functional>
?) Y* E8 ]' x8 x6 d
1 _5 @" w- h/ m1 W0 G
$ o) K; u3 n. Z4 n+ S1 s- a$ L9 n! x9 m- m3 `( ?" c
( \: ~/ ?7 z' P. S0 N) j; _typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
/ o+ Q8 a9 G6 \: F+ ltypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" X2 `1 K+ B6 k5 jtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;+ K4 e+ x [2 Y
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;4 q1 ^' w2 T+ V5 s& D
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;3 z2 N2 J8 ~( S* k! q3 j: K& y
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;" Z, P R o, c" {" N
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ Z# P1 k) c; a
4 c+ e: B w+ M2 I- V# f& w: K8 g8 ^& D' g0 m6 @
typedef DWORD (WINAPI* TGetBestInterface) (6 j$ L3 ]9 T8 S" M7 [" m
IPAddr dwDestAddr,8 \9 ^( W/ B/ X/ S# e
PDWORD pdwBestIfIndex) J* W+ q0 b/ m+ x
);9 F" b0 V) `9 I, \1 P- U' J b
$ f7 w8 H. \9 k3 a/ L! {
0 Z9 ^8 k& I2 G& H/ ]( o* o ? Ytypedef DWORD (WINAPI* TGetIpAddrTable) (
b5 o# ^8 P. Z* z6 C PMIB_IPADDRTABLE pIpAddrTable,$ I) Z. r1 G/ t% J. [: U4 \, o
PULONG pdwSize,
6 W' a" C/ L8 x- V8 Z: J% t+ a' J BOOL bOrder
9 C0 o& h1 v( p0 J0 |);
- C/ ~+ j, p9 G+ Y6 W }) S5 R+ Z5 j) P( g5 O" c
+ w! K! v# Q4 s, {/ {5 W
typedef DWORD (WINAPI* TGetIfEntry) (
/ N0 ^5 h D) v5 a2 X PMIB_IFROW pIfRow( X* f! d* e; M8 Q9 }
);
( q7 K3 o) W' _0 }* a4 g% s7 Z8 k+ ^1 Y+ T* A: J+ O
( ?8 d m( U" wCString translateUPnPResult(HRESULT hr);
" p" Z" d$ Q' n' @HRESULT UPnPMessage(HRESULT hr);
" b l9 E R: h, d' Z0 ~+ t8 { O) }2 n
3 D0 o( V1 r0 o0 fclass CUPnPImplWinServ: public CUPnPImpl
! `1 c3 [: I9 y{$ r0 u o5 r" _3 H. r
friend class CDeviceFinderCallback;" I- R- j' D5 H
friend class CServiceCallback;
) E8 q( q! }* M. i// Construction
* P# [" E2 p0 b( P- `- Upublic:
$ s7 U. n4 v) I! e( D virtual ~CUPnPImplWinServ();5 T: M2 B7 I! m
CUPnPImplWinServ();
# C. w- f7 I- n! \4 T) {: o4 M* w
) I" f) J3 i! v5 p* k0 @) p
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. a, B& p4 y: }' r6 X& V( c virtual void StopAsyncFind();4 s, L) o1 k: p+ K
virtual void DeletePorts();: K4 s' _, u, P9 o/ _4 ^% L
virtual bool IsReady();
3 q1 t. [0 Y0 q$ P1 Q+ O virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }* I1 T5 Z) y+ o) A( m' x# G
: N P; {8 ^# p& ^" i9 M
0 Z2 a3 t4 E. ^" @9 Q( R // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)+ E' z. x N2 v+ d1 h
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later: o* A; x, A. w6 l" o
virtual bool CheckAndRefresh() { return false; };* F5 R+ d: g% E- @8 {9 h
7 F3 |( t3 ~7 L
( n) b: ^9 R7 lprotected:1 }( L" Q k4 K( K
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 q% d8 B% i7 a+ G& y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
6 S- t+ ~' @2 j- C void RemoveDevice(CComBSTR bsUDN);/ L/ j' Y, n# q& J
bool OnSearchComplete();0 E% F: O( N0 H/ O" H
void Init();
, ?0 g$ {% m- P4 r0 I: F) D3 x8 n* X7 u3 l: q4 w e
( W3 G2 d/ v; W7 x/ `/ k
inline bool IsAsyncFindRunning()
' ]7 R3 k) Z% e1 P" |* V {
% C3 `7 [2 V1 J! T2 q if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ): e2 N" f8 [( M( T7 V
{
) K# {. Q8 v, C$ d/ [$ e m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );' s. R3 O# @0 A# C1 E% N. P' z
m_bAsyncFindRunning = false;
: v I6 W. ]. T8 p' F- M4 q& `2 K }: f7 `" C6 _9 x# V( K K* d
MSG msg;
; U' L$ I; r$ _ while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
, a" r* _3 k: G; i {
4 ~: y+ k$ ], q# Q y( w TranslateMessage( &msg );
% i" Y0 H. Y+ f( q( i" I- x DispatchMessage( &msg );
' I+ q# F/ ^6 k4 L) P }
' [3 _" S8 Z; ] return m_bAsyncFindRunning;% N9 V! U- q: M7 v0 j
}
+ K8 v9 g9 X; v4 @7 n$ o+ D7 { \* I8 c5 Z
6 S" D' J/ l/ l7 |
TRISTATE m_bUPnPDeviceConnected;
3 z N: M( J2 a* v$ @' a+ b6 W7 ? `0 y
! _1 Y$ E8 p; Q$ G% j. u/ X8 q) X// Implementation" V1 Z9 p# K! c$ I0 |0 h
// API functions5 O* F! |+ u# j$ A( r- i& h
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 x1 A' g- f" U, Q SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
0 n' J- h; }3 Y' h9 A BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
" ~- ~& B7 V5 o' m BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
& N4 Y, S e) l BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
9 ^( m+ P0 V% M; \2 n( Y# X BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);! Q9 W! a6 l# N' O! S
0 i7 b8 n% C+ ?4 p; L: |3 `
* J$ o" [7 a; u/ S% F/ y* G
TGetBestInterface m_pfGetBestInterface;5 p9 s5 y$ d8 O
TGetIpAddrTable m_pfGetIpAddrTable;
/ h E' |$ z' r% I% R: i/ D5 R TGetIfEntry m_pfGetIfEntry;
1 y9 e' z A9 K4 K4 {6 Y: L4 C- w" e
1 H0 r% [) e3 b static FinderPointer CreateFinderInstance();
& x3 t1 j+ c3 }/ P! @' e struct FindDevice : std::unary_function< DevicePointer, bool >' u# ]% [2 @$ z6 W( T
{1 z: w$ |6 q3 L1 k0 P, f3 A* t7 c s( u
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
# v" ~& g I3 n2 \! c& \: ~ result_type operator()(argument_type device) const* j9 Q& _, ]' C
{
3 }4 M+ t K8 E; P5 e* v CComBSTR deviceName;
, g* `' ~9 Z* } HRESULT hr = device->get_UniqueDeviceName( &deviceName );
1 u& `1 f1 Q' G/ }- h$ ~, c1 [, B) h. w% X7 f3 S, J2 c& m
- V; D' g# J6 e7 {! U8 b- y" F if ( FAILED( hr ) )
3 [( Q% a9 m6 p3 B$ m l return UPnPMessage( hr ), false;
, C! H# g0 ^ o, V3 m, b0 q: a# g
# i; a) r0 {' r6 E! M' F( g! ?7 Z8 h5 |# W0 R) ^
return wcscmp( deviceName.m_str, m_udn ) == 0;
- \. y3 H7 p; K3 _( r }
% g& K1 ~( f* f7 T7 ^5 u3 s! P# A6 v CComBSTR m_udn;% W n1 G3 d8 {+ ~0 N+ `9 B
};, l! z2 y1 u* g
`3 P; V: l3 B g
void ProcessAsyncFind(CComBSTR bsSearchType);
" \% D6 r7 Y. d0 |9 l7 a+ f4 V* t HRESULT GetDeviceServices(DevicePointer pDevice);
7 B, I- R' g7 O$ ~ void StartPortMapping();) ] v# o' M0 V4 N+ ~9 ]1 q5 t
HRESULT MapPort(const ServicePointer& service);
3 |( Q W9 L1 S3 N: h8 o9 ^ void DeleteExistingPortMappings(ServicePointer pService);: U C/ S- Y9 P# x5 }
void CreatePortMappings(ServicePointer pService);
9 W* V6 V" o) c# a( ? HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);- b' S3 e; U4 H9 r" u% j c) J
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
/ s V1 i8 ]& g3 a& f. c0 `4 o7 o2 n) U LPCTSTR pszInArgString, CString& strResult);
! G/ b" G8 O6 ?6 V! A void StopUPnPService();
! N% f/ u/ b4 o) F9 m" W2 X2 `/ j/ Q* Y! ~4 C/ h$ N: K
4 t1 V ~& ~5 q6 v8 K# g8 a
// Utility functions
( X5 K/ U7 x& J8 A8 G; W HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 j" q2 y$ [3 T; a3 w* R( k3 ? INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);) P. `& H' t* \* a* ]
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
. Q" B n0 X; j5 L0 K3 g/ N void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; V2 q0 J W: H) M, j
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);& d/ K/ m3 g* W
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
9 {; ?' r. O' ^0 o- E2 K! u CString GetLocalRoutableIP(ServicePointer pService);
# o3 l5 z& O. a/ [2 L( C: J$ S" ~4 x% w' L2 k# n
: Q$ B+ _' e I. H' A8 e: L// Private members
( Y6 i) r: \0 z; {( Aprivate:
/ L W% i4 w& I( N' H7 ^9 u DWORD m_tLastEvent; // When the last event was received?5 Z& t. y/ E/ t# F
std::vector< DevicePointer > m_pDevices;9 g; O! J8 b1 U. U! C4 D
std::vector< ServicePointer > m_pServices;
% d# U7 {, _9 Z$ C8 a FinderPointer m_pDeviceFinder;
/ T7 l4 j' S5 y- E* c8 Z DeviceFinderCallback m_pDeviceFinderCallback;5 ^* H$ }/ b% N" C9 c' L) ]7 ]% [
ServiceCallback m_pServiceCallback;
, A+ q! u2 S% A6 [& S( Y+ y- X8 K& M( x
! U$ \) [0 L) E9 x3 F. B' k LONG m_nAsyncFindHandle;
p/ r0 L( y" f) r. h- l4 B) e! b3 c bool m_bCOM;
$ \1 T4 v9 o& h5 |# p I* a bool m_bPortIsFree;
9 U+ r! b% j' r; I4 Q' P$ Y CString m_sLocalIP;
- c3 g! g# R1 {# w CString m_sExternalIP;. f+ P2 N2 g9 \; g3 O
bool m_bADSL; // Is the device ADSL?
! Y0 x; k( M4 [4 V% g' p bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
3 \1 O0 K0 _5 n( `) p bool m_bInited;
4 U. q, j1 g7 E- t& X( i1 I bool m_bAsyncFindRunning;
$ h; c2 ], }2 J% m5 K2 l HMODULE m_hADVAPI32_DLL;
" H5 N8 r1 R: ]6 c HMODULE m_hIPHLPAPI_DLL;; s% @2 Y: l7 ~* B! h$ y# K$ X3 A
bool m_bSecondTry;
/ ^3 K9 Y4 @8 Y# | bool m_bServiceStartedByEmule;* _! h s2 s0 S" W
bool m_bDisableWANIPSetup;+ w% Y( f9 Y2 w
bool m_bDisableWANPPPSetup; @1 h& T6 V1 q8 w j
! T. v' q1 \0 M7 H
/ ~1 _5 ?' y9 I0 F+ g! [
};
- S. }$ K5 T/ l7 S. C, x% l4 B6 ^/ i7 U5 Q; @: h5 t
]* T! w, w& p8 g" t- w. s
// DeviceFinder Callback
& W0 w6 |6 A( Z0 ^1 hclass CDeviceFinderCallback
! o+ M0 j( W7 K : public IUPnPDeviceFinderCallback
1 f4 F/ U! r" g{* V9 P7 u7 t; ?2 Z
public:
9 i4 G! o3 t9 ?! n( d3 M CDeviceFinderCallback(CUPnPImplWinServ& instance)
: B# ] `5 a* t" W a : m_instance( instance )1 x- o# `2 }+ b* Q# o4 R
{ m_lRefCount = 0; }
+ P1 j, t- E; Y% q' \7 Y X, u. \7 L3 _0 B+ G
3 |! h: z1 F7 M7 Z q, a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! r' i7 R1 N- j# h p4 @ STDMETHODIMP_(ULONG) AddRef();, p0 C F9 A) V- w: S' e' h
STDMETHODIMP_(ULONG) Release();
4 }$ k: V* Q% b
$ f4 J9 F) [' j3 W3 o8 s8 y4 H! \7 [, \$ j5 ~
// implementation$ ]( t w! A* y
private:! z. Z0 M. N; ?, B. Z5 k" p' T, R
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);5 W) ^" e6 W8 i A# D
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
6 T: j8 k2 g/ X. X0 i" V, I HRESULT __stdcall SearchComplete(LONG nFindData);
2 A( ]; |+ }, w. L/ }0 l, O0 _, v! o& A6 r* v4 B, Q- x& r
4 V' X; P3 U) k
private:) j- O! L; Q2 r" f
CUPnPImplWinServ& m_instance;" t/ C6 X, c S8 \0 z* V v
LONG m_lRefCount;( s d8 X- B# d$ k+ q: S
};
$ t* `+ O I; e
$ T- P! q1 @. V7 _! q9 ]* c/ H' c! Z ]# _
// Service Callback 1 t( |+ @$ n6 y7 E3 H
class CServiceCallback
% N# `/ O1 V0 W b8 s : public IUPnPServiceCallback7 x' s; B O9 k- K7 J
{/ f! H% c+ h5 s: o
public:- ?" N% F& i$ ^- X( L/ H( S
CServiceCallback(CUPnPImplWinServ& instance) k | f( j% ?6 y, [& {+ j2 W/ c
: m_instance( instance )1 _# i9 l0 u9 G3 H
{ m_lRefCount = 0; }# g& }- p- @* B+ |# @
5 I s3 \' k4 G( f4 K STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# C6 d' O2 h, Q1 W0 y/ D
STDMETHODIMP_(ULONG) AddRef();
9 C8 X# o% _% v STDMETHODIMP_(ULONG) Release();$ e2 o8 m; i) m, ~8 \6 I* j+ S
" H& i. T/ ~; @# t
- c, J) i# d: Y// implementation, s& [5 P0 i9 e$ f. y
private:, D/ H# ?5 o( ?% J
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
) R" x" b8 m7 l HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' a6 `' N4 H* G
m: N+ |2 q' D0 s
( q7 V. e3 k/ u" [5 Aprivate:( e. K( K# L+ u. ]/ A
CUPnPImplWinServ& m_instance;
+ S$ J( C0 R. Z" I2 Q LONG m_lRefCount;
" q+ B; l' z( n! o. {};
$ u/ Y, \7 j+ H. Z' E& H. O: `3 z. e4 t
( h# @/ @) U8 M9 r
////////////////////////////////////////////////// A& R9 V, {' U$ u( M
9 D% K" _* d7 @+ ]# u- N K& N! J9 |" [
使用时只需要使用抽象类的接口。
2 x7 ^1 ~% A' f3 \3 p5 y5 hCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
5 Q+ C9 y9 u/ b! J4 L: x! oCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
; g8 B/ K9 e9 p6 U7 B# cCUPnPImpl::StopAsyncFind停止设备查找.6 I' q( \; B z( i: f. r3 y% |3 d% N
CUPnPImpl::DeletePorts删除端口映射. |
|