|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,6 l3 h: B& [; s3 C
. e# @9 B6 ?, V; [$ t/ h
0 ?6 q0 ~( d* r; R
///////////////////////////////////////////) D: I! w( t# T8 p# }
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.# Q' h! D3 d a) F9 K* v
/ z& w9 U3 b+ w) H0 Q& O+ `' T% Y+ _& Q
#pragma once
. {' l% t, H4 c; ~" J#include <exception>1 ^6 |) j6 ?$ C$ w0 d a# u& ^
8 `' g! o% c& S
" Y) A( I# S3 r4 C
enum TRISTATE{
* z, m' {! ?2 d TRIS_FALSE,& b0 Y+ G2 `, X8 D
TRIS_UNKNOWN,
0 P# V. h5 G6 o7 W6 \. P( ` TRIS_TRUE; b/ _7 u3 Z3 z2 u" H/ @
};
* [9 X4 A, r8 v" ~1 j+ a4 i. |5 n4 |& o3 p! O
) l2 e& J# @4 p1 y! Nenum UPNP_IMPLEMENTATION{
" s+ `3 z4 i1 O- Y$ t6 y$ @2 r! U3 x UPNP_IMPL_WINDOWSERVICE = 0,' V2 ~2 \7 T+ Z4 A
UPNP_IMPL_MINIUPNPLIB,, Q4 }5 l. l2 ^% \5 Q5 q# ]3 H+ i
UPNP_IMPL_NONE /*last*/
& i9 g/ {& e9 n3 O |};3 V; Q- M J1 f x0 B
, {" V0 z, H/ l) M& h1 `; H
: [# ?% L) s, ^
3 i: x9 L2 V# m9 [$ z9 X, q
& j& c* n$ d& W: x; pclass CUPnPImpl3 I9 [" h/ F# {/ h. X
{, Y: N: \: H6 U" w/ L9 t
public:( {- B" K! f3 H6 n
CUPnPImpl();4 u6 R# T. L8 h% h2 V& q+ k
virtual ~CUPnPImpl();9 d: d/ i: v2 W/ }8 p( g
struct UPnPError : std::exception {};
" m& B Q# h p$ d9 g enum {2 c+ @3 q$ F5 ^# n5 `) g4 h
UPNP_OK,
6 s' K3 N! z% R" b) D UPNP_FAILED,
5 ~$ r1 }% P3 ?0 i! k7 J3 ] UPNP_TIMEOUT" G# _% t- q0 Z5 p
};
* w o( J% Y: A! w2 p" m* E$ ^ D' C* @! }+ B# ~
* K# K. j6 I" @9 b, \3 k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;7 F' E/ ^5 J( [
virtual bool CheckAndRefresh() = 0;. i3 R8 a+ o& ~! v; [
virtual void StopAsyncFind() = 0;
9 h& p- B0 `) K4 n8 v4 y5 ~) | virtual void DeletePorts() = 0;. g& @. }5 j7 f
virtual bool IsReady() = 0;- B2 a S1 l1 l' u& \" k9 p5 x2 g6 y
virtual int GetImplementationID() = 0;
8 Y. Y, q+ f/ }# |
{- t* J, Z7 ?+ g void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping V9 b( i3 L9 W) ?* @
! L/ y+ ^3 t, i t) _8 G2 S% I1 O' v" q2 Q- l- A
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
% J: S2 [4 T7 {6 Y) F TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } A7 ^ G: ~$ A8 R% E5 g. [2 {
uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ i# n2 y$ I5 S( ? uint16 GetUsedUDPPort() { return m_nUDPPort; }
) z5 c t3 O0 e3 m
1 {: m8 D5 a: J0 h& _# @9 b! m/ S6 C( b! E1 V+ H
// Implementation
( A; l3 \, {' v: s( Gprotected:
3 D0 b+ Z3 m' ]( l* V. ` volatile TRISTATE m_bUPnPPortsForwarded;+ X" e4 V0 d, s8 q! u
void SendResultMessage();
+ ~0 K5 `! i/ q; M uint16 m_nUDPPort;
# B7 V- h; f! A- z0 M7 D( @ uint16 m_nTCPPort;
9 L1 w; E3 g; e/ M- g& [ uint16 m_nTCPWebPort;6 X* n$ u0 s8 n; _
bool m_bCheckAndRefresh;
& w" ~8 U8 D6 x" g6 p6 \" b
% H) H$ ~% j5 }! i2 D" l; C# Q' d- {/ O6 e
private:6 F, C7 N; @! h7 {
HWND m_hResultMessageWindow;- T4 {, Y: d! b) K4 R* \" U8 O
UINT m_nResultMessageID;
! e' q( V7 v% [3 J7 U7 v# S
$ j/ H, H5 W7 ?0 E9 K1 `
& F: w! i2 X% `6 z+ o6 l! n5 l};
# L, w1 ?: [: R0 _
7 E+ Q( x2 _! ~- y/ I6 j' e: Z. _: J, n) }3 q* {* K0 {
// Dummy Implementation to be used when no other implementation is available
: E) C/ C- t( d% @( u) kclass CUPnPImplNone: public CUPnPImpl% U' ]3 j6 B2 @; ?% W
{$ I3 Y. j, i5 K- i4 D: K
public:$ ]- X5 E1 I( t1 u
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
! A% \8 t6 o( |% F% U: F. a6 O virtual bool CheckAndRefresh() { return false; }
; R: _* e" R% ~. G6 s [" `# F+ _ virtual void StopAsyncFind() { }$ ^. f; N% b+ {: `) O
virtual void DeletePorts() { }( o5 f4 y9 D9 K; L# o' q) f3 k2 [$ O
virtual bool IsReady() { return false; }. i4 u% f' y0 P6 f" `2 G
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) z6 c; x1 z1 ~8 {! S! b) d
};, W2 Q) L6 V" C) _. F8 h ]) v# ~+ I
9 W* k. ]' C+ ~# [2 z) @* s
% q1 Z8 O' o2 Q0 U3 ]- v/////////////////////////////////////
* f& w6 W% ^6 F' Y0 w* @* N- d//下面是使用windows操作系统自带的UPNP功能的子类
8 P: h3 S& d! f/ ~3 K$ H1 C: F2 O/ D0 ]0 v
/ }3 @; p2 P* t! E" e+ l$ ~: |+ Z) g
#pragma once
. a0 r1 E7 T8 e8 ~7 u#pragma warning( disable: 4355 )" R) N* i; I6 {# _" W
; y+ p$ d' R& G* e2 ^; ^: |1 m
! k4 }: R m( {2 S$ M" n
#include "UPnPImpl.h"! Q; |! l# T! p) h; a$ U& g" o
#include <upnp.h>
) D6 O; x+ U9 w" J3 ]9 q! b% l" @#include <iphlpapi.h>1 W7 ~; j" d0 ^! `& Y6 b: [# G
#include <comdef.h>" ^8 e* M: _. D* n
#include <winsvc.h>; W3 R8 O7 s4 p
8 j' G7 Y' J" X/ r! L# w5 |! d
- R7 g' u; c3 H% b& A
#include <vector>
9 o' O! o( X$ v# f7 `0 I#include <exception>4 z1 p: g9 G, K! Q/ ]1 J
#include <functional>
3 v: |# T2 n; l, z0 p: j; p0 Q$ ~; Y% a. \; F) J- Q2 Q7 }
! f" Z' i$ t! w" H+ A* l
# n% g8 L# K0 b- h( B/ A- T
0 B2 o+ {' E+ d9 |: Rtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;/ Q, f2 I$ w2 Q! D
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;! z# L, @2 ]& N- o4 C2 W9 w
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
0 Q) T1 X w# D5 C* m7 F! Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ f% r8 a) h2 s) ?4 w5 q( ^2 V
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 N+ o) Q+ V( \" e2 \- ?8 a9 p
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( b9 n8 }( m/ r, U: ~$ jtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 N, p {% u* T6 d7 ^ }
0 m9 y: K1 Q4 h
( J5 Q) d4 ?* |! p! k& ]. [* ]2 Ltypedef DWORD (WINAPI* TGetBestInterface) (1 e1 M- [; J1 L# m7 P# c
IPAddr dwDestAddr,# Z- i P: t, D0 O( V# f+ [
PDWORD pdwBestIfIndex; e1 @/ k1 ?) F4 a+ f" e
);6 j7 X5 N4 e6 f
. H- A2 A! \9 h% S! X5 s* K! D
- B0 S! X0 y3 w( l
typedef DWORD (WINAPI* TGetIpAddrTable) (
9 c" n0 o5 c) p% G: m PMIB_IPADDRTABLE pIpAddrTable,
) T) k7 n3 @/ D$ [7 b9 h3 P PULONG pdwSize,3 a! [7 @. t; P3 x. ~
BOOL bOrder4 d0 g# O; j6 V
);1 C2 |! m7 B" a# ]; F
" r0 q( P" Y& Y# @, I
6 T6 C5 z+ s, j% N; T: {' Itypedef DWORD (WINAPI* TGetIfEntry) (
/ _4 O- V0 @0 W c3 n1 p' b6 V7 Y PMIB_IFROW pIfRow7 x9 v6 {- n. t6 _% H
);
! X- ]' s- D% S
- X) ]+ R" ?) d3 Y# v- e1 V3 u, @$ I6 {3 J6 S: @
CString translateUPnPResult(HRESULT hr);
8 O7 O' Z$ {# i( h |& \( I: _HRESULT UPnPMessage(HRESULT hr);: h" q9 m' Z5 e
0 }* ~" j# ]- D$ f7 g8 ^" X
* u/ \3 L8 @! N) o! ]6 v8 h
class CUPnPImplWinServ: public CUPnPImpl3 a3 \) l, e1 i: H6 x9 `/ \7 ]
{
! s1 l' K9 y, \2 ^ friend class CDeviceFinderCallback;+ i* X2 s5 \5 g& f0 o% X
friend class CServiceCallback;
* c" v7 M' M v/ [5 i// Construction& V+ n& \8 [! y& E
public: M P) s* k1 z6 J8 |4 {
virtual ~CUPnPImplWinServ();
* x H+ Z3 f8 K z" y CUPnPImplWinServ();6 g0 H+ X" d6 J# h
9 r& e- g/ V, [6 h. t
; T( M$ ^6 C+ ~; Z5 ^ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
( ^: H- G' ~3 w1 V, O virtual void StopAsyncFind();
( y6 B2 V; B& A# T9 H/ ^( x virtual void DeletePorts();
1 _. [) N, z+ X, u0 X virtual bool IsReady(); a+ U4 K1 |1 ]3 O$ ?( b" |
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( O0 w" k3 ? ]1 }5 `% b
5 ~' l+ J2 |: l) S: T) b. l$ j6 U5 l4 J1 E6 _4 p
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. u. E3 ]* k5 r: o2 G/ K // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 s( y; | ^3 B- L3 P& `& `/ }
virtual bool CheckAndRefresh() { return false; };0 C4 ^4 W4 R& }& N
0 Y3 v' I7 V$ u5 V2 y
+ O2 N/ Z* _ uprotected:
, S+ ?4 O1 ?: {7 B* I! o void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);$ A8 O4 ]* o1 Y7 c
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& G" f* a% P2 q; e" R5 r
void RemoveDevice(CComBSTR bsUDN);
) o0 e; B3 }7 z' w) ^% z' S: o0 G bool OnSearchComplete();
. m4 d3 F8 L* H$ u4 d/ a void Init();
3 |' \$ j1 `. y$ y* M, k! s: U: L8 p4 T! n5 M
4 ]& M* t- I2 j& E: o0 O- W
inline bool IsAsyncFindRunning()
1 e$ w+ X% G: n9 l$ c# ` {8 K+ U& t, L& P# F2 P1 D
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ) \3 M/ ^; q* a6 }
{
' |" b2 V' s; X; n/ p1 ? f; ^ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
6 o Q- L+ s4 h8 O3 i m_bAsyncFindRunning = false;# e: ~4 s4 k+ \$ G
}0 P7 C) e% p4 y/ j A- v
MSG msg;. X6 M! ~" t( Z: m+ K9 G- D
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )1 o: J" i! _/ {( c: Y
{" l% ?/ z7 R& N2 ]) h, W; V3 K
TranslateMessage( &msg );
' P+ e* q+ q% V; z/ Q9 i8 o DispatchMessage( &msg );
# a- ]' g: ]* j6 M- S1 Z8 E }
" O) N' F8 N* J return m_bAsyncFindRunning;0 F7 x! F. p @4 U0 s+ r
}; ^& Q3 F$ b( G0 z6 z e) i+ O% Q
4 d, H) O5 I0 e; o4 H
; T/ V+ n: ^) i' ^, [
TRISTATE m_bUPnPDeviceConnected;7 G' [8 n. `3 p
4 o! G% B- s7 B3 Z1 c9 [* Z1 J
! w& U7 m. L" A( u; B- ?
// Implementation
3 r' B0 L- R% q/ ^$ _2 Q8 K // API functions& D5 \- F! c0 {; A/ I
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' R/ `: y6 n' K/ Y1 }* c5 N; N, t
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
4 \# J% \- ^" D* M! I$ D BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
5 l4 ]6 b k G% H8 T BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
0 J- g" a5 L- M9 G BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);/ X5 Y* {3 Z0 s
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
# _7 h5 A6 u8 S N$ [* {
' k4 h( G3 ^6 i5 o8 ~
2 `' S8 W6 T) o4 I. I' n5 _ TGetBestInterface m_pfGetBestInterface;
( v( }3 x( ~7 j2 }0 x) S3 H TGetIpAddrTable m_pfGetIpAddrTable;
# x3 p' a$ \7 U TGetIfEntry m_pfGetIfEntry;
. |( g8 r0 l0 z5 ^
* U' k2 c0 Y# L6 w
& O. r* h6 G% q% x0 ` static FinderPointer CreateFinderInstance();
8 H% l! `0 Q! I9 P1 I" q1 [ struct FindDevice : std::unary_function< DevicePointer, bool ># }5 D7 @0 m: C% x
{ H# X4 W% J% O' L( x* A
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
1 V+ q, I; |2 i7 C J) z result_type operator()(argument_type device) const
0 P9 {2 n: u/ G {6 G m) c- O& T
CComBSTR deviceName;/ m- V* t9 h1 {- C+ N& W! a
HRESULT hr = device->get_UniqueDeviceName( &deviceName );9 T" R: s4 I# ~/ A; ^0 z* R0 q
- W& j7 w9 v# v# {+ |( n
, }7 y. t) \2 t- B3 G6 A/ ~
if ( FAILED( hr ) )
8 \: k5 n9 s2 n0 v return UPnPMessage( hr ), false;0 s3 I& c6 l* j* h$ d% F6 s6 m( q
; B& z/ h- T1 C0 }# D% Q& z
3 ^* J- v; e( ]3 u5 O1 q9 q return wcscmp( deviceName.m_str, m_udn ) == 0;. \% O3 u! \! G( L
}
( @* z! i: y1 h; a6 X, D5 c* P% ] CComBSTR m_udn;; e' Y) w e* j' N% h& G
};2 \/ C2 l, m- V3 i% W5 V2 Y* N
# ~ R& @3 o @8 R) p void ProcessAsyncFind(CComBSTR bsSearchType);
3 K% a6 b- W8 J HRESULT GetDeviceServices(DevicePointer pDevice);1 R3 `" z! {8 q9 D7 X
void StartPortMapping();2 n a$ {; f% ~$ W( i7 N
HRESULT MapPort(const ServicePointer& service);
9 _$ C, E E% e. w; y( g6 q void DeleteExistingPortMappings(ServicePointer pService);
, `3 C0 s7 x7 u9 k! M+ A" h6 i void CreatePortMappings(ServicePointer pService);3 I) ?7 e8 [3 q- V
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* j# X1 E9 Z: N% J G% O7 h HRESULT InvokeAction(ServicePointer pService, CComBSTR action, , Z; ^5 A, W# [) _* T. i
LPCTSTR pszInArgString, CString& strResult);8 }# k8 d" t9 P4 z8 q/ m9 c
void StopUPnPService();
4 a5 e f. M7 g/ r6 ~ L6 A5 d* @, A7 h' H
9 s/ j: B1 {6 E+ F' W, |$ G b# ?) s
// Utility functions4 {3 {1 v1 i1 T$ }' ]0 r
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);& @" a$ H* X$ D1 o; e
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
0 p6 q. Q! m/ w3 d INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
6 L3 y# b7 x& y( |4 { void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars); a$ y8 \) c% [& r. Q; Y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
k$ Z: q! `* R5 a( p8 @0 f7 T HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);% s5 f4 {* }& Q: h. v" R* K: J7 k
CString GetLocalRoutableIP(ServicePointer pService);
, Q$ ?% P" [; V9 _( Y6 g9 z2 l* f; b) B7 v ~1 w" [! ?
, G. Q9 u' G% Q y% e/ z// Private members* p! c- J2 U& K
private:
, l6 C/ Y2 q) P1 z: a DWORD m_tLastEvent; // When the last event was received?) X& O. T6 E9 T% R# F$ j
std::vector< DevicePointer > m_pDevices;0 {: l, V; o2 i: z* R
std::vector< ServicePointer > m_pServices;2 G) N9 K/ Z' b1 W9 Z0 P/ _: I
FinderPointer m_pDeviceFinder;# R% }, {8 n7 U# c1 r, t$ r* m
DeviceFinderCallback m_pDeviceFinderCallback;$ E- X2 V7 G v; w# {+ _7 |2 n
ServiceCallback m_pServiceCallback;
6 n9 q: m2 J. D2 | D" D$ A
/ k, j, a" M( v: K' g, i; r* ^
( G [; V( ~- B# S- H/ k9 b LONG m_nAsyncFindHandle;
- P3 c& ]( A; H+ r bool m_bCOM;
: F& x# u( t: {6 e) p' E' y bool m_bPortIsFree;
7 r: H! k6 z6 ~. r2 J CString m_sLocalIP;& D3 c9 l& t( _5 Y* r) X
CString m_sExternalIP;
T1 S* l ^6 i bool m_bADSL; // Is the device ADSL?
5 k1 E! i. {& d# t$ ~ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?1 ]8 M2 }8 Q* P" N1 B
bool m_bInited;
& B) c" p" N8 L. k$ g( { bool m_bAsyncFindRunning;
) z. D% @2 R6 B1 U$ C9 ` HMODULE m_hADVAPI32_DLL;
2 T3 c, ^0 b: U( X% z HMODULE m_hIPHLPAPI_DLL;
( C/ w! g* j1 [' a bool m_bSecondTry;/ Z' A4 m/ v" F, I0 I( n
bool m_bServiceStartedByEmule;. M. D; b4 |( G" \7 e" Z. k; X" t
bool m_bDisableWANIPSetup;" v' k* f d( Q3 x/ X
bool m_bDisableWANPPPSetup;$ r$ M4 t2 z0 x
5 n: R& v1 Q% v) Y" i
) ?" c, @) w3 k" S8 w9 `
};
9 T$ `; Y6 J c8 m, \6 L
# G5 {) n) v3 [. n9 C. d! _/ N1 u
9 R) X. N3 N" P+ e. ` G" W( x// DeviceFinder Callback
1 W, Q6 z2 P N- l! {* fclass CDeviceFinderCallback
+ {7 L+ X& y; B# a2 R* S : public IUPnPDeviceFinderCallback
2 _+ j- m9 N3 p' q; F5 v7 e{2 }$ X8 H+ z7 U; o6 d2 ^
public:' g9 |. s+ u+ T8 s$ R
CDeviceFinderCallback(CUPnPImplWinServ& instance)3 ^% q9 M. L4 x/ \4 D
: m_instance( instance )
0 _- i; W/ b2 @$ T/ m1 y { m_lRefCount = 0; }
# ^4 ] S1 s! y# b; k1 d1 @% k% C# e8 Z
* w" X, n0 ~+ T u$ L# N STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; x# z# y' Z- R5 M1 X( g! N( u/ @- A. K/ D
STDMETHODIMP_(ULONG) AddRef();
9 O5 J% M5 N; x STDMETHODIMP_(ULONG) Release();
: C. K$ F) n) ~
1 e& f7 d, v) H# ~# Y- s2 _$ `' g5 ?6 _" J* ?
// implementation6 p* V- h* U. g% r# n1 N, O) r0 N
private:: S5 O& I }7 V' |
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);) L' M1 T* q) D% E
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);7 B" Q( x* w: _3 S1 _
HRESULT __stdcall SearchComplete(LONG nFindData);
6 M7 x( r; M2 N, ^! @0 n Q K0 X' F+ O5 m7 z. X& P2 u8 V
9 R3 W* ]( ~( ^* D D0 [5 e, [
private:* s3 _* I7 i0 e0 z9 t; J0 K! i
CUPnPImplWinServ& m_instance;' {* N1 l% L9 p" i2 i K: y- j _
LONG m_lRefCount;
; t5 O# n( o. N F6 |! S2 J7 U' ?9 M};
8 q' u! k' O) f7 A# ^, x9 s$ |
+ k0 k8 H5 L/ a" V8 U2 F) D$ u$ G( ^2 [3 D7 K; `
// Service Callback 0 B0 O7 `/ z# b6 I: j* r. H. ^
class CServiceCallback
3 M3 R0 N4 l2 S0 M0 \3 H : public IUPnPServiceCallback
5 j, }$ c- k# S% R, U& l% m! N{
. B6 \5 H+ i I1 o0 @" O0 `public:
4 e2 j' f9 T+ t3 f) c7 F CServiceCallback(CUPnPImplWinServ& instance)
" \/ j& ?7 R3 c : m_instance( instance )" _1 t. p1 Q1 T9 w Q! U
{ m_lRefCount = 0; }
7 z* W8 g1 ?4 L2 W. c/ \* \% s
0 E* L" _4 ~9 D6 {8 o& b. u' Q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
6 Z4 }- G+ c1 E* \; N9 m STDMETHODIMP_(ULONG) AddRef();# a, q' ^5 n) S# ?8 P; S8 u
STDMETHODIMP_(ULONG) Release();
4 v4 R6 e' r# N$ T
$ s% C7 ^( g) K* J5 G
1 U1 [- w | }6 ^% G// implementation
! k, @1 j& p& F! gprivate:
6 t, c! ~& B, m, f8 \ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);, g' r+ T% G6 ~0 S
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);% t. C; q4 Z$ v9 [# e: _
M* i, ?) J+ ~6 O5 Z/ S
# K% x, l( V+ _5 |. v0 w( t1 Cprivate:$ q# k) ~; l* I4 ?1 T9 e8 b
CUPnPImplWinServ& m_instance; m- Q9 x- w& e/ d3 Q
LONG m_lRefCount;. ?% h; S# n7 j" V5 u8 m0 _
};: a, `" F' D. _9 E
7 Q2 h. f5 y: p6 ` s* Q2 d; a* L1 E6 x( [
/////////////////////////////////////////////////
" s& ?+ _; {; w4 ?+ C4 Z( K/ u% p4 w8 J+ E
! `2 E( ]- i& D使用时只需要使用抽象类的接口。
' f' ^1 U& ^- v4 ~CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
4 a/ S( Y% e( a, J0 s# k$ g: h/ jCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.* W' E# G) t0 {( O$ F4 J
CUPnPImpl::StopAsyncFind停止设备查找.
( t- j# A8 A, s% I: p6 eCUPnPImpl::DeletePorts删除端口映射. |
|