|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,4 K3 F, I. ], g- [
i6 D1 Q% v- x7 B5 ?" F
- @& z0 y3 }. ], f# b( ]3 b///////////////////////////////////////////
; z3 I8 B' }' g) f' u0 @//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.8 F4 T' E% o5 k/ \
5 T4 Y$ [8 Q1 X5 n# ~ z
1 M. H9 Q, Q: r3 K3 p. W/ h
#pragma once4 i. v) y) @' N. y3 d
#include <exception>
" f5 K$ v) l3 ^4 x4 c" T3 H I1 Z: ]8 T9 f) v9 u# P" N
$ n1 C' V) ]8 ?1 Y( |4 z
enum TRISTATE{
" d# P2 }6 _. h' W TRIS_FALSE,: T" N: p+ y6 |. S/ f
TRIS_UNKNOWN,
# Y4 w0 c1 Y% i TRIS_TRUE
) H6 }4 M- |/ V' I7 A};
0 R5 @, o8 W! i. @/ v$ B9 W
& k( l$ J1 U- K0 `' i$ e! s# I0 v8 o# J' h! `/ k7 |# r
enum UPNP_IMPLEMENTATION{
* z# D" l y# K6 s: n3 u! R UPNP_IMPL_WINDOWSERVICE = 0,
% s4 [; P& |/ Z2 @0 S5 R UPNP_IMPL_MINIUPNPLIB,
_2 K4 ]! Y. S, K3 A/ a UPNP_IMPL_NONE /*last*/
3 \/ E1 O7 w5 o2 U& Q};0 V' }4 N, D: i; l3 J
: r% {3 V) v8 |; x
/ J* [: r3 }; t- u8 F9 h l& `7 ?; W, N% W2 |& @2 l
, g. U$ f0 ?2 b# p, V' xclass CUPnPImpl9 e5 h- N; r& \% v: n8 b$ m" {* s [, C
{+ T4 X" n7 f' X2 z
public:
' ~4 q% e- L0 p2 q CUPnPImpl();- N0 R% S* c6 c' S
virtual ~CUPnPImpl();( S* G( M! N/ |+ v$ a$ W6 h% v
struct UPnPError : std::exception {};
+ [# l( s8 i7 s- R) ^/ X enum {. |# i4 P( k, ^) g A
UPNP_OK,
& B+ g9 H' u0 H8 ~$ G' A UPNP_FAILED,
) t/ v, F; `1 M5 m0 }. b7 ?% ]+ x* X UPNP_TIMEOUT
) D/ N: `( G" r" B6 G };
: @% z' p( z8 u) w
/ o7 q _' n) ]% z) }
1 ?9 G* m/ T" W) O" j: {6 E virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 _9 t: J6 Q) R4 m' F& f$ P virtual bool CheckAndRefresh() = 0;* I* C6 e* N9 B5 ?+ l4 u
virtual void StopAsyncFind() = 0;
( c# t: s& Z, R& Z4 a' m; i. _) L virtual void DeletePorts() = 0;
4 ^) _% z# B! N# N6 `# q2 i t virtual bool IsReady() = 0;
2 P: J' {0 ]% {9 W; u: C virtual int GetImplementationID() = 0;: K! m+ P+ l; W$ C+ G& v/ I
& ?+ W# g0 ]& w
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 L: F9 o# g. a6 I
6 q, [- g5 A- ~3 j p; N
& J4 ~2 \* j2 ]3 m1 m
void SetMessageOnResult(HWND hWindow, UINT nMessageID);6 I$ k! D8 A& H9 i
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
I0 z( e5 _, M" t uint16 GetUsedTCPPort() { return m_nTCPPort; }" N' \7 H; i, c8 X: @2 x
uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 x# \4 i) |+ z; v. E, L
3 m7 Z' B. V4 g7 S D) v3 I1 S2 O m$ I& j* c. T* J
// Implementation# j0 Q* v8 `7 g, K7 v; u8 p0 d& n
protected:
- m/ A) O5 T5 ~1 q( ?# o volatile TRISTATE m_bUPnPPortsForwarded;" U& E# v1 x1 s" O3 x
void SendResultMessage();
4 W9 M) B4 [# t uint16 m_nUDPPort;
( k, \$ R/ d5 H, |. T& u+ ]) x8 ~" F/ K uint16 m_nTCPPort;
. o) |) K. J5 E) ^9 z uint16 m_nTCPWebPort;
0 ~/ Z- I+ y. s+ \ bool m_bCheckAndRefresh;
+ L2 f# c/ c$ x! d
2 e" \$ n' D) e4 W% ^: Z7 K9 }1 d& h; v* G5 e
private:( s/ u! i- U5 a" @2 o( o7 e
HWND m_hResultMessageWindow;
& D3 ] J+ {9 V" _ UINT m_nResultMessageID;; w, I; O/ l2 [( c0 D4 h) Z" @
# E y# \) ^" ^+ M
" j* }% m8 w" r5 G. P6 Z& v
};
! r3 U u; W4 ^
( z+ [- |4 S" ^# `9 Z) M# ^0 X9 h# A2 P3 S. ~; \' Y* B, {
// Dummy Implementation to be used when no other implementation is available% o( ]" x8 m8 X* R4 I2 {5 m
class CUPnPImplNone: public CUPnPImpl q$ ~+ }1 D4 |
{
j1 s4 w' {7 A" |$ }" epublic:* @" P; u( w7 o6 N
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }3 M* S( A' P+ z
virtual bool CheckAndRefresh() { return false; }5 B) G2 R" C# C! S' B0 ?
virtual void StopAsyncFind() { }
6 b1 Q+ y& T/ l( u! G$ h: I virtual void DeletePorts() { }( ]# N4 Y# \" N; _/ d
virtual bool IsReady() { return false; }! y% M* ?; r* \1 ]/ ^
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
4 ^/ D* i: k$ e$ c2 ^: H. g};% E0 I. j6 W$ m
4 l* h. G( W5 u4 l6 h9 D% `3 p
5 v( T) ~0 u7 u4 t$ S
/////////////////////////////////////
3 b& S* u9 s' T d( E# f//下面是使用windows操作系统自带的UPNP功能的子类
0 j" \& v2 b; q5 q* p
; C- W% t; ]) m/ P/ e9 @& j- X; y
#pragma once
6 w" g- v$ t& d7 O9 E2 M& `+ R#pragma warning( disable: 4355 )) \- Q$ c8 k* \1 M, I
& j! P5 F- A$ [2 x: T2 n' }/ m: |+ a) D' d) I. h# R* v
#include "UPnPImpl.h"
( K8 d% M# P0 M3 @; W#include <upnp.h>& f6 x; W; Y6 t# g2 O. x2 s
#include <iphlpapi.h>! U# R% C1 |& V) f5 c
#include <comdef.h>5 y7 Z/ z- K& a5 M
#include <winsvc.h>
7 N! ]" h* b9 i" r) G4 m- d7 F
% o$ k4 \$ C5 o7 g6 J% t; h Z8 F& R- q, ?- ~& \4 S2 W" w$ H
#include <vector>
7 S+ U% l2 A9 ^" `2 T, C#include <exception>
) N- Q3 l) F- o! |* D#include <functional>
9 c' p# J' x% B* r; v0 U: \* v8 _, C' b
3 u& w. V' e$ r K4 v: c
; a4 y; b4 [( E$ Z
8 \4 f8 g: L" X+ D+ F" _& N4 L
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
9 S: g0 d' N# x0 a$ b* J$ Qtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;0 R& Z0 ?* }; x
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
6 Y$ I; v1 x: y8 z% [* itypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! \- A% B/ }4 f6 G
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 w) G! b+ M1 |7 l- ytypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* K1 ~. [: \2 T) p- _9 ^typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
8 `& t1 H5 o$ o7 @; f% h7 W# }' R% l; W4 ~0 V; R' E
4 C# i# I. V6 ktypedef DWORD (WINAPI* TGetBestInterface) (
6 ?6 A! B$ Z( V' n. |5 E# C5 B1 b IPAddr dwDestAddr,5 |' d0 F& Q0 h/ u! q
PDWORD pdwBestIfIndex/ e6 B% N- T, z8 i
);, N9 A# ^+ Z E: p0 v
$ v+ M% T" c, D
% P' w( ^+ d' O9 @6 ~% {% m' W
typedef DWORD (WINAPI* TGetIpAddrTable) (, S2 B& J# q' }. K
PMIB_IPADDRTABLE pIpAddrTable,
x( R& T; F. D8 r' K, T [ PULONG pdwSize,
' P9 A* y. l3 _( F BOOL bOrder) Z7 m. ~6 h3 \7 v t5 W+ v
);
# `& v! g$ L* Q( }# K
" m0 e( E3 D4 j9 S$ H/ w
( l, e0 _2 g& b6 S- w4 ]5 s; `typedef DWORD (WINAPI* TGetIfEntry) (; Q5 a0 v( G( w6 O
PMIB_IFROW pIfRow/ {5 g! ?: u2 z* k, R& @; u" ]
);- E2 |- O) [7 \) S
- }' o3 w8 F4 s6 Z9 z2 R$ |& \
6 ^! U% U" R ?- O/ z) F
CString translateUPnPResult(HRESULT hr);
6 a7 K3 [5 j4 i! h2 o, {HRESULT UPnPMessage(HRESULT hr);( _" N! N- ^8 j' i8 u3 _+ A: ~( k
2 H3 B# i. m9 s7 @( \
. u/ Y6 H( E ?+ i8 n2 v1 p
class CUPnPImplWinServ: public CUPnPImpl
6 ]9 B8 {& d' Q4 Y- Y6 M{
9 O) W, i! H; z }/ r friend class CDeviceFinderCallback;7 x/ l8 S# G; {: C1 }3 k. N. [
friend class CServiceCallback;( `* ?8 m9 t& Q/ [
// Construction
- E; f. k. l- m7 Q& i5 K8 y- apublic:" x0 H4 g3 p, {! U9 |$ U- R
virtual ~CUPnPImplWinServ();
; A- _& P! y+ P& f; e7 u CUPnPImplWinServ();- d) H; A, k- N2 ^+ I6 p o+ d* }
8 u, L; P" o* v! C
0 h% v8 e. R9 u# |# b2 b* I" R virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }5 | j/ m5 p! s" O; e
virtual void StopAsyncFind();; D$ F. `8 [/ E
virtual void DeletePorts();5 Z! K- u4 I2 s9 f# y2 T b
virtual bool IsReady();
( J2 w t4 v% f% d: y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, n& l6 J: Q; m7 j8 t4 h# O7 C4 B8 u" N
A" z) N9 U, C+ N; g3 e
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)- F$ F/ P& a0 u$ s
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later$ @0 s; b, M8 C' r& D
virtual bool CheckAndRefresh() { return false; };
7 o6 ~6 N5 f/ H6 P3 c
& Q$ B- z- y# L7 B" {
: G5 s3 V5 A9 T* b6 m; cprotected:
( j0 W+ p! m% N1 T+ d# { void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);5 P) p3 |& N2 _0 y& F C0 |8 [
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);2 Z* j# s1 I6 ^4 o# S! @3 v; e. i) e
void RemoveDevice(CComBSTR bsUDN);
; s. z* C1 s, d4 Q1 B0 E: `4 S4 `: i bool OnSearchComplete();7 E' a/ z9 z/ H( A
void Init();
+ p7 d" l4 i1 Z
7 v: [7 ~5 d8 k2 j1 G; R
2 m; V+ |; Y% n. [ inline bool IsAsyncFindRunning()
9 {# c: w9 n5 B' G9 T- e v, h {
. j8 {# v' y# |, D" h if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )* R5 l7 i0 f, h
{
j( P- O6 ~2 G1 y1 J1 d( z. M m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
) J9 @9 g# C' ]+ L7 b m_bAsyncFindRunning = false;/ y0 m. w. G8 l
}" a: i6 _& K2 G+ P2 P$ @# N, [# q
MSG msg;
! T+ y; l$ T7 H' g/ y, { v( m while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
9 H; N" _6 D+ R+ x {
% c4 F) y; I* o8 ^; w TranslateMessage( &msg );
" H* G" }+ C$ k' x# S DispatchMessage( &msg );$ o% y1 o5 c. p1 \% ~1 z
}& y* G7 l W$ y! |3 D5 C
return m_bAsyncFindRunning;
0 g. j- O; {: l }' A) w$ M; C/ E. D \
+ L9 a, Z) |5 r. @
* U/ m8 r/ t$ I" B8 d0 K TRISTATE m_bUPnPDeviceConnected;- E- o4 ?0 ~$ u0 c& \! X
; ~$ Z/ B( t* b! P; S# P
/ F, q0 Z/ ^7 F6 K4 v, a" J// Implementation
: B2 r; R+ b; c5 i9 b; N0 v // API functions
. l2 M$ W2 X6 j6 R/ A' h6 v SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);- S6 Q& O( c* H$ ?$ l* u# k1 l
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);- j+ a. h4 U5 j6 ^
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);7 G# d) B- g- Y6 m* j! R( W
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
( w& V! [" q6 @- d4 H. s/ I9 r* v9 S! m BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
2 n" K0 d0 p" [2 H" ?# c) g# M BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
9 b9 M* f2 b1 D; t" X. O. Z; t6 H t
6 B. K5 c0 Z' E8 M, Z" B5 @7 Q0 e6 o; F, R
TGetBestInterface m_pfGetBestInterface;
; z* G/ u2 j8 N/ K TGetIpAddrTable m_pfGetIpAddrTable;, S4 c7 ?, }9 {! B, h/ P+ ~0 v* X
TGetIfEntry m_pfGetIfEntry;
" z; Y' D( i5 D% `# o+ T( h1 x2 W! r" {9 D
, @+ {: ^$ H4 P. S7 j" _8 ^! ?
static FinderPointer CreateFinderInstance();0 G/ I& t$ R7 Z9 g M0 m" y
struct FindDevice : std::unary_function< DevicePointer, bool >
: r3 f# T7 l% [, s* a {2 Y1 F/ d N9 D1 _
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}6 E" ^8 e; e& V: w
result_type operator()(argument_type device) const
" J- w) X4 o( f {7 v. e( ^. F$ [" B: ]! I+ |
CComBSTR deviceName;4 I4 }! T% i) Z4 m- d
HRESULT hr = device->get_UniqueDeviceName( &deviceName );: Y" d2 B9 ~ O+ B9 {- G
! l5 r' r# {- ^4 Z! B
. Z8 ~/ \5 b/ f0 H' U if ( FAILED( hr ) )
! c L& M1 k- c% t, K return UPnPMessage( hr ), false;
. Y0 a3 ]. z6 e. G' [$ t- n+ l. `+ A: T: r; j7 ]
$ r8 d: T9 w. \# w$ N1 S. S return wcscmp( deviceName.m_str, m_udn ) == 0;
+ R k- `2 Q# v! R' @ }
( S" {4 q; Z* N1 S# m CComBSTR m_udn;
, I/ W" S: L6 O! P };+ X9 ]0 O/ S+ s4 c* t
3 U, n% C; L" j- l
void ProcessAsyncFind(CComBSTR bsSearchType);
+ H0 [; r3 {9 R5 ~; j7 Z) a HRESULT GetDeviceServices(DevicePointer pDevice);
7 j9 ?; p. e5 S* L void StartPortMapping();
, m1 v% R+ x/ Z8 G7 H HRESULT MapPort(const ServicePointer& service); r. J, ~+ G; @# W9 f \: e, g
void DeleteExistingPortMappings(ServicePointer pService);
/ U' r$ O5 A# Z8 l {9 d; U void CreatePortMappings(ServicePointer pService);& H/ d) D8 P: s5 d# g0 R
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);1 Q! p" W" j& O. N* d5 i W& s
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
" v0 }5 B `/ k5 l LPCTSTR pszInArgString, CString& strResult);
7 _: ^) l0 N# S( K1 q' I/ I void StopUPnPService();9 G( d- r" t! p& b( R% ^; ~) Z
% h0 P5 u( S7 b% A/ ?9 O
% b. H; a, T8 \5 V" E! l // Utility functions
# l4 ?5 L; E0 Z7 b) S" i HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);% c& q1 i3 y0 |# {" Z! A
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
/ u3 ]4 J" q" o& }2 c$ L9 I INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);; S- U4 m, M( h- |# F2 a1 D4 x
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ ?4 W# M: q1 K1 ? HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; }: z7 ?- L5 k' z- H
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);1 F' ~% a- m7 ^' Z- b
CString GetLocalRoutableIP(ServicePointer pService);5 G: r' _- v* ?7 S
! P2 w8 a# ]& m6 u G- d. G2 u t9 S( o, l: I
// Private members" Y1 E) g5 d/ |+ \4 ^" e& ]: P
private:
7 M! d1 p% v: N; [/ U& x DWORD m_tLastEvent; // When the last event was received?
6 k7 e% s$ Y+ d- k& n std::vector< DevicePointer > m_pDevices;
& Z+ G) Y- ]8 s4 `! ]) n std::vector< ServicePointer > m_pServices;* w4 R9 c! v& ^2 K0 |8 G
FinderPointer m_pDeviceFinder;
9 @& q0 c; N' f1 }; z7 }! L. Y DeviceFinderCallback m_pDeviceFinderCallback;% @; p) K" i! L! Q/ a! r
ServiceCallback m_pServiceCallback;
4 L& I1 @) C9 ^! ^5 o# x
. E5 m" l) ?9 U0 q6 b8 d9 U# m' l
LONG m_nAsyncFindHandle;. J# b. W; t _6 N2 U
bool m_bCOM;0 ?/ P! {5 r; X9 }8 @* Q
bool m_bPortIsFree;
7 ]# \% }! @ v1 ^ CString m_sLocalIP;* d9 T. p8 j& f
CString m_sExternalIP;0 U4 ^, r) }8 o% Q: T" T9 L7 a7 m8 I" D1 }
bool m_bADSL; // Is the device ADSL?5 s& s1 T: ]/ g. r5 k: S
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 Q* v% f+ d; J& Z# K bool m_bInited;( @8 I0 R( o) _) B; t
bool m_bAsyncFindRunning;
% }& @- F4 B0 n$ |0 [0 g' _+ j HMODULE m_hADVAPI32_DLL;
5 ]8 }0 Z4 Y4 [+ B' N! d! c HMODULE m_hIPHLPAPI_DLL;9 |& R% ^; p% m N. }: {3 P
bool m_bSecondTry; }. T2 l s4 E. i
bool m_bServiceStartedByEmule;
0 n/ r( f7 f+ T* B bool m_bDisableWANIPSetup;
1 _3 T+ V$ _2 O9 n& u% p bool m_bDisableWANPPPSetup;
7 ~# o: R7 j/ c9 ?6 D, A* J, U4 K* J
4 O" V2 t% c6 S, U};+ J& w f/ O# k
: ~' j% S0 |* s
6 X4 m- e, s5 j$ F, z! X
// DeviceFinder Callback
; J# l$ D5 @. Y5 T; H$ Lclass CDeviceFinderCallback8 G$ e. V$ y/ p4 [; ` y4 Q
: public IUPnPDeviceFinderCallback; U5 [0 L. |" f; u2 n; i; w
{$ U2 ]9 V) ?/ L) m- C
public: e4 Q% ]6 R+ T" C% a8 s4 M
CDeviceFinderCallback(CUPnPImplWinServ& instance) R' P0 l7 q) Q* M0 A3 C) k0 a' A( r
: m_instance( instance ), f8 @- e1 S) e- }5 P2 g+ Y0 r
{ m_lRefCount = 0; }
9 m2 e, S* D9 T. r6 `4 q$ H+ ^/ y/ }5 @! `! I" l/ Y0 M6 w
7 B7 `) c* y( ^. o STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- o1 ]- K! y ]# t6 v
STDMETHODIMP_(ULONG) AddRef();; p7 F; D6 X; X+ F3 \0 z
STDMETHODIMP_(ULONG) Release();
: t7 d* Q- E2 O6 m5 f6 w
. l. f, ?8 | x& P! v( q" z
* D5 `3 a3 V! K* z& }// implementation- x+ f3 O% v6 Z' c
private:* b0 y6 A) T; ?( F. {
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
* ^$ |, ] z- }1 ?& S+ P1 p HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);: k6 B" U- C9 U4 _
HRESULT __stdcall SearchComplete(LONG nFindData);( E+ S7 D( ?4 s+ }% K) m; |4 C2 b
% [" x w3 a4 m; Q9 N; u. J2 N; F9 p- y: q( z, c
private:- E: U# U8 y& T& l
CUPnPImplWinServ& m_instance;) q) A0 d3 ]( }+ f/ a Y
LONG m_lRefCount;
6 y- f; B8 B2 l8 @6 }};
/ a! p) e% B! e! t/ D& N$ Q9 H9 Z" F6 j! {. ]
" B: [0 b, _3 x8 T' ~) m
// Service Callback
9 x' E: n4 p% ]class CServiceCallback' }% r3 w. a! W: b/ c- A y
: public IUPnPServiceCallback
) I6 `& ~3 {, V{- j9 Z6 E5 m) Q: V7 J+ k7 e, |
public:
4 e0 u H" F6 w- }3 {" ^ CServiceCallback(CUPnPImplWinServ& instance)- m& E- G7 f! p5 }6 T- m% Y
: m_instance( instance )
. o# R/ j) D0 C1 w4 H$ C { m_lRefCount = 0; }
( N1 R8 C1 _3 t R* E8 t
! |5 p. M2 _; s' b% g STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 [0 a. I' F/ L STDMETHODIMP_(ULONG) AddRef();# a4 g9 H u1 U* G- a6 ^
STDMETHODIMP_(ULONG) Release();$ o% z! `6 n$ \
7 [# j. R9 ~4 Y* r( s
0 |' t' Y N9 g0 S& P; S3 E
// implementation# @6 ?+ U* o1 C0 u' L
private:) c! H( A7 u% f( m* L" y, ?
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; X" w7 D0 _3 l5 n7 G! [ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) v/ |; e' A `6 ^6 |0 x9 B
( U% c3 L. Y, ~' Q+ S+ ^1 a: C. ^: g0 W) ^ x; u% M, h5 A) ?
private:7 Z7 d& S' H$ ?% F
CUPnPImplWinServ& m_instance;3 E' E" I4 ~" B- l9 {$ S- b
LONG m_lRefCount;6 Y+ F8 N+ P' [
};
" r) X$ }' o6 Y* w% {" ~
. Q* e: I, x! v; d
. k& }) h& U, i, J3 v/////////////////////////////////////////////////
2 H- R! g; Q" M: I% F2 W- T" r8 D1 `( n! @. `, v; I
, {9 O, r0 o- u& R5 F+ k使用时只需要使用抽象类的接口。4 | W% i; R3 J* T! c
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
1 ]# y' l0 D* q2 |; O$ SCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
9 t6 U+ C5 k, F( ^/ uCUPnPImpl::StopAsyncFind停止设备查找.
: l. U! [2 O8 M1 `) J" zCUPnPImpl::DeletePorts删除端口映射. |
|