|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
9 ?" A+ l" W* \2 C+ d* g6 x4 e! `/ U! t) a" i
8 m! m8 x% W" e) @
///////////////////////////////////////////
, `- [9 h3 N3 w6 \//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
* D* B# \* `4 b8 Z% r$ c6 W. C2 E! H, a
8 Q$ y% M- ~% ~* s# n Y#pragma once
7 s% Z. ^' R# n% d8 `* @8 j#include <exception>5 d- L7 t& T0 D7 S& x I' t
. X w E! M2 Q; @5 W! G3 M, k- }1 ~$ ^( q
enum TRISTATE{
( u2 E( b J. C TRIS_FALSE,& f. T6 ]+ s' h+ z
TRIS_UNKNOWN,' d) p+ Q" n( [# i4 K5 q$ s/ `& T
TRIS_TRUE. \: X, S6 Y* r& f: @0 t) Z
};
* V, t7 f9 x/ g
" ]" F9 N) m n8 V8 t+ z1 T: r4 e. H q% \4 G* V
enum UPNP_IMPLEMENTATION{
+ B) Q$ J+ ?$ u+ @( h UPNP_IMPL_WINDOWSERVICE = 0,0 f7 e: c t" `# l6 k" X
UPNP_IMPL_MINIUPNPLIB,3 O, f0 l& M7 P2 F" H
UPNP_IMPL_NONE /*last*/" j M7 U* J6 B7 U* L8 ~: w3 q: d0 a- V
};" f) _" g0 w+ t2 S/ g, G
$ x- q$ @ |& a( j9 e% P4 ~( G y( I" c! x- Y
W8 O, |. ]- l" V3 H
% [2 m+ O* |( R9 p8 m2 s' y8 Fclass CUPnPImpl
. r" X, q0 B$ `) Y: {{
" v+ g- E- t- upublic:
( K) o: Y. r s6 x) ? CUPnPImpl();
- O) e- y( K$ r4 v virtual ~CUPnPImpl();
: R- A# w+ F$ y9 Z) P struct UPnPError : std::exception {};
6 T6 ?7 ?, q- O; a0 H) h* J enum {
. B Y) Z2 v* }: c8 L7 }$ o UPNP_OK,) D8 g( P8 q U) ?
UPNP_FAILED,. d2 B$ U/ D3 i; ^3 s
UPNP_TIMEOUT
! W u/ l& ]% D8 }& z: X) F2 e };
0 K( r" P* T5 c( _9 v( X: e5 m( {3 R f: |: b+ G5 g
% u. d" |5 `8 L8 M. n( C9 r virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;4 R2 p$ h. c' z3 p' S% [$ l! R# Q+ h3 ~
virtual bool CheckAndRefresh() = 0;. I! @7 S }. X% l4 q( B% E
virtual void StopAsyncFind() = 0;
8 t F* z. _0 |1 } virtual void DeletePorts() = 0;' Q% Y5 k9 w$ D( g7 v4 E
virtual bool IsReady() = 0;& ]! A8 b M5 Z% t
virtual int GetImplementationID() = 0;. ]) ^9 U# v- l
. t/ c- n8 z# Q! t" c0 d void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
9 R, O* L# ^6 e% r7 \, a6 M) s" L N6 s7 G# V( j; L
' ?! N7 e$ X" h4 d% N& s! S
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
& j( p; N) v# t" ^ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
7 |2 }5 b, w9 B$ q! V uint16 GetUsedTCPPort() { return m_nTCPPort; }
: h5 b% [7 P( C+ T# L- | uint16 GetUsedUDPPort() { return m_nUDPPort; } / j$ b. F+ v- v. c
! T, D5 L3 a( g5 F* Y
) M/ a! |, X- }2 h! {- S
// Implementation2 f/ h4 ?1 r2 l& Q
protected:2 y' V( C/ D l" |
volatile TRISTATE m_bUPnPPortsForwarded;' j8 y$ v3 G2 h" ?( L) X' I
void SendResultMessage();
" Q4 r3 k1 V. b* W3 w7 H8 R8 R uint16 m_nUDPPort;3 ?2 I, ~6 J2 G% L+ t; o0 h, X
uint16 m_nTCPPort;
& ^% d7 {0 X/ B$ Q; T' d" b% a) j uint16 m_nTCPWebPort;
( V6 w; p2 V7 q" K- j3 y( A7 Q' o bool m_bCheckAndRefresh;
/ ]3 O7 U7 T* [1 N/ r/ l+ w2 s
3 V: d* o1 g# l9 r9 C! q! @+ q/ l( {$ q# n* a$ s. B8 B9 w |+ ]
private:
& p j) l7 Y8 f; o" K HWND m_hResultMessageWindow;+ G5 G( g% O7 d
UINT m_nResultMessageID;
% a% ?9 x. `& j8 n- a* s
8 s/ C* [$ G( C2 |: D# k
2 u( k7 c4 w# n+ ?/ q' q2 q% Q- v& P+ F};4 c% u" p5 X: P! |0 v; s4 a
$ Q0 k, d# ?$ O7 ]( V( h; D
. v6 E( A. E' L// Dummy Implementation to be used when no other implementation is available
5 D7 ~+ R/ z) L& ]3 Wclass CUPnPImplNone: public CUPnPImpl
7 h1 {4 u3 O0 r7 B{
: {* o2 }- ]; h0 Xpublic:
: G; F$ o2 Z$ h virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 b( i" _% l5 g' O8 [( } D virtual bool CheckAndRefresh() { return false; }
1 p& B v$ g9 K6 M, r3 W virtual void StopAsyncFind() { }
& @/ } l3 O! w- C virtual void DeletePorts() { }
1 [9 O& v" f/ v5 C1 P# ]# E; p virtual bool IsReady() { return false; }9 O! T6 B' I) P% _0 }* F
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }! R. x' t: u2 s9 s
};# S4 D% k! k i9 ?+ F1 Z
' M% X9 H0 v% s; ^ g( o( ]" Y+ y0 ?6 B' Y
/////////////////////////////////////
! i; f9 k& H( Z4 A# x. `8 g& B' R//下面是使用windows操作系统自带的UPNP功能的子类
+ b" y( t1 Q4 i4 H" w4 w' q1 |* l+ n4 V3 q- g) x/ n ~
! A9 `7 s* W a+ w#pragma once0 I j0 ^( U/ q |) G' v% d
#pragma warning( disable: 4355 )$ ?1 P- C+ `# N7 R6 Y4 O
9 x' \7 Z3 {+ ]& ~4 F/ q2 v
3 v, Y0 w7 z, v4 B: T$ O, O* S#include "UPnPImpl.h"
$ l Q5 l* B" H0 _9 l' F#include <upnp.h>
% }1 q1 `+ Z9 J( [5 j; C' O#include <iphlpapi.h>, d/ K/ V, F( r7 O
#include <comdef.h>
* L( m7 i6 ~( m. \9 `. b* }2 w2 {9 N#include <winsvc.h>
: Y5 u2 }5 m- d6 B* [6 a& P# c) q9 j$ y+ K% }; E* d
$ }% M3 `0 P- P+ l- K8 m0 @$ ?1 G#include <vector>" K# s; o8 ^" B/ H7 o
#include <exception>
/ ^: N" P, O. G ~; x: E#include <functional>1 I" H" s3 C3 P" r0 M, E
% ?+ h" S8 c5 \; {1 q' Y
7 n3 s% l e- y7 g8 K- p( t: i! s+ n8 m+ ^
( \" x" L- M% F% k4 F( q. w
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, O6 p$ x9 o. I! q
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) I9 r& x. D9 O3 z. {2 C
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;# F# n9 N% o9 X$ u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;& z0 g, ?. ~4 l9 t
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
) V. B# D6 q% A- O& ^% J0 v! [typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;: I3 T& P* V, v# s
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ `4 M2 e2 S8 w! ?" s' Y% d: ~
8 z5 t. h1 U# j O! [# d
0 p0 G$ b9 w2 g& O1 r# Xtypedef DWORD (WINAPI* TGetBestInterface) (
8 N. t' W" f l M, o* u! d IPAddr dwDestAddr,& v0 y. p# @4 {$ g( ~
PDWORD pdwBestIfIndex
& M6 m& P; m, n F% `, d);* }$ o) M* }+ ~$ {
. E" b2 B3 e: N E5 I$ G/ ^
0 C+ S+ N! G! ctypedef DWORD (WINAPI* TGetIpAddrTable) (8 a8 W" I$ P# h# `/ X. E+ T% j; b
PMIB_IPADDRTABLE pIpAddrTable,' |7 K/ {9 @9 e0 D6 N0 p* ]
PULONG pdwSize,' f Z3 }0 U3 \& s1 V5 L
BOOL bOrder
" r4 p0 ]+ I2 G' S5 N);
C. u$ o, M: r$ T# K7 X {2 r. ^2 Z% B7 z- p5 m
3 {$ F! [! f+ W) `0 K$ ^typedef DWORD (WINAPI* TGetIfEntry) (- i! y3 b; `9 K( j& k) \% D# {
PMIB_IFROW pIfRow) M6 |* K% j, \/ N ]2 u' o
);
5 {& _0 C$ n+ R( G" G+ g* M, g. _6 G$ Z8 h9 I( ]
* l0 t2 j' o- {! O7 mCString translateUPnPResult(HRESULT hr);* _1 _/ L y# o) v
HRESULT UPnPMessage(HRESULT hr);
5 p' a: E) m8 w, e! r) M0 Q7 Z" v7 } G, ~
- e8 c1 c2 a7 R6 P
class CUPnPImplWinServ: public CUPnPImpl
4 X8 Q' [: p6 i+ l* r( r8 \% T; d+ ^* _{
$ H; [: a9 n( S friend class CDeviceFinderCallback;
7 x( ]$ I3 C# h, p% L friend class CServiceCallback;
% `. d. E$ i: T4 X# w// Construction; F* T# z; X0 r9 s' {. N. w
public:
' o' ]8 A5 _8 V; x0 c" t3 a( ~: I: | virtual ~CUPnPImplWinServ();
3 t9 l* z5 E. j* [1 o8 l5 y& @ CUPnPImplWinServ();8 R. c" T5 {0 E# G. S( {% f! m
0 {- h) [+ ?" R, N! T! o
5 i1 ^) d, g9 Z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. R1 l( F" C1 d6 `% N- I virtual void StopAsyncFind(); Q" E4 R7 [* a$ l4 ?3 \. [8 {
virtual void DeletePorts();3 S5 I3 A8 d' {8 n0 J' h2 _$ Z- H; B
virtual bool IsReady();
+ \* I I4 X' N# {" F. R virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 C- L+ h5 A6 ?, u+ I; f) Z+ Q# H ^& R9 I. f+ O7 l
7 h; {* ]3 |8 ?3 x# l3 @; @ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)8 ?6 Y4 Z/ e/ x( }
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
5 N& H/ Q+ K% u$ z/ P9 m virtual bool CheckAndRefresh() { return false; };, ?6 L( F+ P, V9 _$ T* R
/ Z8 K1 B' j8 n# P" x: _. v) K
2 C7 s+ I! {0 o) b& o$ {
protected:
) D6 o4 l3 a- z+ z* H void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
+ O0 ` O+ v C: {' m5 o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
+ u! a6 w$ ?$ V# b7 V void RemoveDevice(CComBSTR bsUDN);* H3 K, F# V& B3 }
bool OnSearchComplete();
4 ?! ?! N9 q% m$ O3 Z }& L% N void Init();
. I3 f% u/ ?5 j2 T& P/ ~/ c, W* z0 V
6 p8 v- q X# f9 e y9 y1 ~" k inline bool IsAsyncFindRunning()
2 \- H3 F( b3 a4 r6 O5 i- @ {/ X5 Z$ `6 W+ V$ H5 S! Z
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )* T ^' e3 \# O, z" C! |
{
) @5 W' h# | M+ ? m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 z0 Y( l, D# @$ l$ m) I m_bAsyncFindRunning = false;
& N6 H5 G0 C$ n" r7 S3 @ }7 S; A. u- P( D2 r4 a. m* D% h, p
MSG msg;
4 g5 ~2 g' M7 r: G while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )% H3 ^7 S& _4 t
{) h, [6 z6 b+ a# ]" z$ [. |
TranslateMessage( &msg ); F% T h" r/ \& n
DispatchMessage( &msg );2 m. L1 x. W+ S0 q q
}
8 a0 S: f& c. ~5 j return m_bAsyncFindRunning;6 z% d' W# T# |# N- f+ N
}
6 _: c7 d5 q* J% A4 B9 w+ R$ x3 e; j. o8 D" z8 }9 x; Z* D
1 B3 C; W. d7 |! V0 Q" I
TRISTATE m_bUPnPDeviceConnected;
Q2 J! D' n# X1 K$ V7 D
- m9 {+ }+ s5 H3 z- f( ~ q& l1 \5 O y6 _
// Implementation3 o$ ], O6 d. L: V7 I. }
// API functions
$ v8 w4 _! F8 h* [. ?( g SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);9 P# z5 U6 ]2 i$ k6 B
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);3 o/ c0 I! l& i/ c$ e7 d
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);1 K, C* K5 Y1 H0 |: O2 \$ z' r2 ?
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
6 \7 r- [% g- ~* x: \ d BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);" v! s7 _* a+ e4 h. p9 {" b
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);# y$ m* ^3 j3 d I
4 [3 ]; R8 x: ^8 O# t8 ]
3 g2 ^6 H$ l4 ~) R% k* j4 Y1 _ TGetBestInterface m_pfGetBestInterface;
7 F! D% }) W: O4 ^( b TGetIpAddrTable m_pfGetIpAddrTable;: k4 u# S0 t$ r5 I* C
TGetIfEntry m_pfGetIfEntry;
" v! x' K. W5 } P! r J& z: Q! b2 V+ ^2 u) J7 s: K5 _
) M# R5 l3 L9 t$ w
static FinderPointer CreateFinderInstance();
9 m& V6 {& {' M3 Q6 z4 o6 Z/ s struct FindDevice : std::unary_function< DevicePointer, bool > I; v/ x. L* S4 ?2 d
{
5 G5 d' K) w/ M* [* ]: ? FindDevice(const CComBSTR& udn) : m_udn( udn ) {}( J( W/ v- I; D5 U; _: ^/ F/ v
result_type operator()(argument_type device) const
+ _# i' u" t: A8 X {
$ k f! K# Z3 m$ U) Z9 `' O' E; r* [ CComBSTR deviceName;. O/ c! R/ _6 R7 I6 j# _
HRESULT hr = device->get_UniqueDeviceName( &deviceName );5 \- f4 w& i1 Z( G! S$ p
4 k( O% j1 J' B# ?* f! M/ s* D& B7 t j! M2 n
if ( FAILED( hr ) )2 _* Z) a0 T8 N' g' u
return UPnPMessage( hr ), false;
5 `) r+ m0 ^- `, y; t8 U. Z
+ D6 u% t1 k4 I, i8 h( `3 T1 O
4 D8 a% q) q$ v7 B5 Q3 G return wcscmp( deviceName.m_str, m_udn ) == 0; _6 y; F5 c1 p+ ~5 N
}
0 w. g5 d( C) Z0 C5 p4 @ CComBSTR m_udn;0 _* l# c# M0 P) r! h* ]9 h' O8 I
};
4 V; a/ m$ f( t, x( @ + I$ I" k8 H- q8 O9 x
void ProcessAsyncFind(CComBSTR bsSearchType);, N" @; E4 }+ r1 ?0 c6 W
HRESULT GetDeviceServices(DevicePointer pDevice);7 y5 g# Q. ^, ~8 G8 h* W
void StartPortMapping();* b6 O+ r# W) o* s
HRESULT MapPort(const ServicePointer& service);
) b+ a# W B& p2 z void DeleteExistingPortMappings(ServicePointer pService);; e& v) H" [. @% Q2 c& x/ a q
void CreatePortMappings(ServicePointer pService);
+ P. V/ [0 z- q# K- z) e HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 w8 P/ c% m5 x HRESULT InvokeAction(ServicePointer pService, CComBSTR action, " G v$ I$ V8 h. Y! c6 Z* o/ h
LPCTSTR pszInArgString, CString& strResult);
- d! \! D: r+ N+ a* a9 @ void StopUPnPService();; t7 f2 C" S) s6 a
- |! S! f+ a1 o8 ^0 @' `) `( |) K B; [% y; S( n! Q
// Utility functions
6 S- w. u6 H! y B- q$ ]8 U7 W HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 a! a; r( A4 V3 J" \1 i/ c INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, p! E" L1 c, `$ q INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 B9 M) S E: Q2 z, U0 H- ? void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 {% w" Y- ~* R _! K) j HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
- H* K7 s$ ^/ d0 \ p h9 ? HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 R6 W$ w. \2 M9 n4 A CString GetLocalRoutableIP(ServicePointer pService);, j& m) Y5 Z3 t! ]! b* a d: N
% o2 w* o) m' B _' L
& z$ V8 Y4 e' T* a' w// Private members" }# }2 ?; J: c, H3 X8 ~( H
private:
0 n# M5 ]. g( g# e: J% [/ c' g DWORD m_tLastEvent; // When the last event was received?& _5 _ d- X( D7 W
std::vector< DevicePointer > m_pDevices;
. A3 q# x5 f8 q) D: S/ W3 E3 I std::vector< ServicePointer > m_pServices;) v$ b) w1 D3 C& V4 b9 v
FinderPointer m_pDeviceFinder;
3 K' L# r3 Z# s) g7 B% f DeviceFinderCallback m_pDeviceFinderCallback;: Y& q. p: R# n) X+ U/ o- z; X
ServiceCallback m_pServiceCallback;; J+ J! p2 R4 z4 H* h: W
* n1 g6 x$ D9 C3 V4 M2 r# c2 O% ^ |/ O% c& L, e; a
LONG m_nAsyncFindHandle;
: S1 @$ g' E$ N! n9 W bool m_bCOM;
$ ]7 W4 i+ N4 a bool m_bPortIsFree;
0 J. R- i6 {1 [; f' i, b: p CString m_sLocalIP;
' D! q6 X; T9 ?. Z CString m_sExternalIP;; f9 F: ~, w1 A( f! B* J
bool m_bADSL; // Is the device ADSL?
" F* Z" `% F1 h! N: f5 H( n# S bool m_ADSLFailed; // Did port mapping failed for the ADSL device?" j4 N+ a% |. b% H& l# z
bool m_bInited;; R# x$ m& K* ~7 g: v0 } x2 k
bool m_bAsyncFindRunning;$ d8 ]9 v! N6 t, F" E. d% `
HMODULE m_hADVAPI32_DLL;" e/ n3 u8 `; y c$ r, x
HMODULE m_hIPHLPAPI_DLL; q! R' Q- _# @$ ^
bool m_bSecondTry;! v0 `- i, P1 A
bool m_bServiceStartedByEmule;6 n! k' c4 e2 R% Q5 R5 s8 H0 P
bool m_bDisableWANIPSetup;5 s# g2 U9 W& b& e+ K$ F @6 I! M
bool m_bDisableWANPPPSetup;: h6 D D# m& s
: C; T+ p$ d# M& ?! {' t
8 m9 q/ K/ H7 q# i7 g
};6 Y0 ?' ?( h; [$ ^1 u! n
( i& \3 ^! N. k
# ^5 o7 ^( E. O/ r/ M: Q// DeviceFinder Callback P) h# f1 q9 g' g( D6 V/ K6 ?
class CDeviceFinderCallback! ^+ N F$ c' `% J2 z" }
: public IUPnPDeviceFinderCallback
" c$ r' Z# ?0 E6 u& s{
2 ^- E9 M* H" ]) P4 y" ypublic:, d+ A5 y' z, ~% T) I
CDeviceFinderCallback(CUPnPImplWinServ& instance)
3 W4 G( m2 T# @. N" W; U" c : m_instance( instance ): B w1 x t* |) |5 H
{ m_lRefCount = 0; }
% u: n5 n- c4 F7 L: @3 i) g A8 ]8 a0 c" G
) l0 U- z# p& _ [ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 [- n! |6 c5 I Y t: ~9 ? STDMETHODIMP_(ULONG) AddRef();
9 Y- w$ v& q5 Y4 l" c: E, ^ STDMETHODIMP_(ULONG) Release();' E. g9 d, Y3 [6 y0 \: v8 i
1 x, D* L% [: S$ z3 x2 q4 w
# [" ?4 F3 y1 ^% g) ^& r5 b// implementation9 B, h7 u3 j0 [! r" f* s3 P
private:
, y8 ^3 r5 o. n( f7 W! ~ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
& {% G( M+ i% R HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);( }. a; H+ [$ |4 i! g0 h
HRESULT __stdcall SearchComplete(LONG nFindData);/ G- l' V% x2 o
+ q! n( P; @+ b8 h- S1 v
" V( A$ M. j, i& y% tprivate:; J# S, o' J( N4 U; O, w9 k
CUPnPImplWinServ& m_instance;* {6 S# f8 D# V' {: w, S- N7 }
LONG m_lRefCount;
0 R) [) ]3 }6 x0 a+ x! @};
+ k$ @& d3 z$ ^$ j& ~. L/ ?) g8 |+ o! ]. x1 ?+ ?2 P! k g
! d# n' V" Z' o* u// Service Callback , \3 _8 t" W9 J" M
class CServiceCallback
8 r6 @6 w' Y$ |/ M : public IUPnPServiceCallback
. v# G7 m+ n& F3 L, |* D) c% Y{* X/ ^! O$ g2 P' |" z( b
public:# A9 n! n; F5 w% T0 k1 B
CServiceCallback(CUPnPImplWinServ& instance)
4 A+ [7 ~5 K8 O, C$ c : m_instance( instance )
4 ?- ]. r- T2 U3 I6 i { m_lRefCount = 0; }
/ Y# ^% M; V7 D! u* \" R7 _3 j5 g $ b+ |# [: Z2 P0 M
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 l! }, j" C' p2 ^) J* |; k! r STDMETHODIMP_(ULONG) AddRef();" G5 i+ B3 j1 h9 G$ I
STDMETHODIMP_(ULONG) Release();
! J) Y ~# G, {) J- v3 _4 m
, M# ]5 c. }& }! I i& \1 r1 L) q9 Z
// implementation* L5 I- p; ?" c
private:9 x1 Q' S6 g; p& ?* h
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);2 ~6 a L* G6 e" }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' v( y/ L7 \- F ?
0 N" v" A9 B, w: J" R' q7 l& R, W
& ]9 t# o h% f- T& nprivate:
( Q* S$ g8 @2 W1 k CUPnPImplWinServ& m_instance;# S9 e3 m6 r' [8 S4 a& S& P
LONG m_lRefCount; x' x, ]9 V2 Y0 ~6 F. ` {3 E, Z
};, c! G, X/ D1 \0 q& R" d5 [" }
% R9 K3 |3 i+ u3 w/ H
( N% e# E# J2 g/ p5 f3 `
/////////////////////////////////////////////////! W9 ?) ]0 }1 }0 g7 a' U
! k; Q7 {9 h/ v
7 n6 c! M V* `3 G: I/ b0 U使用时只需要使用抽象类的接口。. M3 L6 V! }5 T# u1 ` ]
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
: f$ K7 [/ L& } F5 RCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.+ j! D$ W2 T% e% v
CUPnPImpl::StopAsyncFind停止设备查找.
8 B3 j! D' a2 n/ h- hCUPnPImpl::DeletePorts删除端口映射. |
|