|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
2 i7 {; D/ w2 H8 n( Y$ d
, l" {0 \3 l0 m: W, P8 D+ V7 E% @& Y& j8 X7 b' S
///////////////////////////////////////////3 ]5 ?5 I7 k- k3 L8 |' u
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 ?# ]* ^5 d$ j3 M+ p, b0 O
- O+ w' M8 S' q+ u
9 T, q4 W& ~9 ?& d* c; |* f( V#pragma once
4 J: ]4 G7 J8 b" H& q#include <exception>, x; F: | @$ f+ C" p# x
1 X8 R- T. P( d8 d2 P2 `
# P, t5 R# E. Z$ v4 N3 b/ c U# o; T enum TRISTATE{+ f& T" m. c& u, z7 f# C8 `! c5 I
TRIS_FALSE,
/ k' R) z$ G K* z o TRIS_UNKNOWN,( }6 I+ _8 e' d7 ?* [# \
TRIS_TRUE
1 ^0 ]0 ^# u# J# x* ?0 {6 E};
+ Z( I2 ]0 [* @
! i) Y' _ a) _% b2 ?1 w5 G/ ~% e3 |! w9 k* l& [- c* q
enum UPNP_IMPLEMENTATION{
6 p" l( f$ w! s7 i UPNP_IMPL_WINDOWSERVICE = 0,- S5 ^& W9 C9 i2 ~ J/ B; n/ D, Q
UPNP_IMPL_MINIUPNPLIB,
* Q/ l/ B7 C3 s; Z UPNP_IMPL_NONE /*last*/
/ V- G' M' V8 Z* H9 i1 |0 D I# s! Z5 V};" F3 q7 T- y& s+ z
& g0 c; j3 j$ Z
4 f2 v& a% Y+ p) N% K1 l
! x, H3 U. }& @2 f C9 T/ _" C6 v& \( m6 W
class CUPnPImpl
+ h$ T }: \, `2 P{
& L1 `$ |/ I* P/ A0 x* `: xpublic:
, ?1 ~/ e" w7 v: j, h* s& T CUPnPImpl();
, ~$ J3 i7 C, n6 u$ g virtual ~CUPnPImpl();- M2 a* s* u8 I- Q% i, ^
struct UPnPError : std::exception {};, ]) W: u l9 a/ o$ ^
enum {
7 a# ]. q; l/ |( ?' v, D7 k% W UPNP_OK,6 a0 F- ?. p+ O, S: x/ M
UPNP_FAILED,* E; D) {& F& ^. u y3 A
UPNP_TIMEOUT+ o3 a, b9 K; B. u- D K
};5 i+ H& X& `( J6 A8 y
" N& D ?9 }- ~3 d1 `: l( R6 b c. e* ?/ p: _1 j9 k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;) Q) V# h# ]- a$ t# m Y
virtual bool CheckAndRefresh() = 0;
! I2 Q, b& d4 j5 L% @ virtual void StopAsyncFind() = 0;$ h3 R- Y+ b! K. q" {. A s6 D& ?0 {9 O
virtual void DeletePorts() = 0;) j3 p3 t! x$ z+ S8 Q' l# s
virtual bool IsReady() = 0;
: C9 U7 L+ Y( P1 A: ] virtual int GetImplementationID() = 0;
4 r: `3 j) Z6 x, q8 I* x0 k/ K 1 h, H/ [. P3 Q# F9 _, V) q
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; s9 O% @9 b5 Q; H* W p
1 v ?% S# ]" S4 j4 P+ U
1 _% a9 r( b+ L8 A5 V) X
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; k6 P5 R G$ ]6 f4 U( U
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
4 n/ ^! c- ?6 R% T uint16 GetUsedTCPPort() { return m_nTCPPort; }2 E0 ]) p5 a- b7 K9 l* _
uint16 GetUsedUDPPort() { return m_nUDPPort; }
) e/ _3 F1 T8 m6 {/ c6 ~( N- I/ _5 e
! p" R& J2 ]6 w$ U. V! V. g
// Implementation
8 m( o3 G2 o* G# ^' c) C$ [' `protected:
& o2 K* N/ f& x( K7 S volatile TRISTATE m_bUPnPPortsForwarded;# U4 f& k2 p. c0 A9 y, C: b
void SendResultMessage();4 Y8 ]& n/ L' Q( |9 q4 ~' @
uint16 m_nUDPPort;4 I, _9 X# p7 Z4 i
uint16 m_nTCPPort;
. `6 q$ x+ H: \# i ]7 E uint16 m_nTCPWebPort;
7 o" G8 ~2 J4 S, {% K bool m_bCheckAndRefresh;
$ C7 v! [5 K2 |8 X- \+ R* u* B2 z2 I( E& D! y0 o
5 D' D7 i( m, n3 D8 X
private:* T2 [2 m( R% L2 p+ i7 G
HWND m_hResultMessageWindow;- G7 T1 b a( s/ a9 ?' u
UINT m_nResultMessageID;7 h1 i5 K# B; D( C/ `5 c
. P S" r7 i6 |% Q7 q) |/ J) v, U; D, ]
};8 l; f" g" ^$ ]" ]% R, `) o6 ~
5 l4 @6 r* w ~! ]: n( R( @' b- p8 e
D4 C1 X$ A3 y
// Dummy Implementation to be used when no other implementation is available6 e: N% A1 _+ @* T9 w
class CUPnPImplNone: public CUPnPImpl% S/ x$ o1 U9 R" }7 s
{
3 f$ t: p9 P! T; \1 G- epublic:
, {' t* L2 k& F( L virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }' O/ `: K! @% H4 i
virtual bool CheckAndRefresh() { return false; }
+ G, ?' F0 A3 M7 |" Q, l* t# h, ~ virtual void StopAsyncFind() { }& u# N- \: r2 r5 k0 x
virtual void DeletePorts() { }4 n3 q+ q6 @: `1 W9 O2 P
virtual bool IsReady() { return false; }
% c% `- ?# w4 ^- g. `: \7 V virtual int GetImplementationID() { return UPNP_IMPL_NONE; }- ~; Q3 q! }4 i' ~
};% M+ s- ?, z( ], x3 d& M7 i
- o' N4 d1 b0 @+ x4 h/ Y9 M
* b' A) d7 N: t8 f, i* x1 @- v/////////////////////////////////////1 L. ]( e) w. B% V- m; W! M% h1 {
//下面是使用windows操作系统自带的UPNP功能的子类5 K/ n- U$ ]7 L
# d% ?, K3 W6 t+ K5 o# { @" `+ l
5 {. m( \0 I; W, R$ Q, J2 ]
#pragma once. q3 h: t- o( a4 v2 t) C5 W
#pragma warning( disable: 4355 )% N) X' N% @( }
`& C0 h! R d8 _" L8 R5 R& B5 H
/ t1 q8 \6 i0 ` z/ G( Y#include "UPnPImpl.h"! J& B) B8 l) w$ H, a; W
#include <upnp.h>
. k, M7 p9 Z/ {5 q% o5 A#include <iphlpapi.h>8 U8 Y% V4 l6 J1 h9 B6 }
#include <comdef.h>
! b6 {% Z' ~' U#include <winsvc.h> j1 z- ^, v4 V6 }/ l
7 V8 W& _( j$ l7 K J( c
$ g3 Q5 w/ S9 j% u0 }( N#include <vector>
( O5 X: c" |' S, Z" m% y M#include <exception>
' k9 N% x( r4 n#include <functional>* Z* n9 \- @& M
: d- F% F) W& l% Z/ H) _
8 g" h1 L( [/ v
( d0 M7 ^8 L1 N$ `, K; I* N& L R, o% r. T" ]6 [9 L9 g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;) n" U! t6 ]$ a
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 f. D; ?5 n9 c g! U6 F
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
; i" F; j0 F7 y4 a6 f( Vtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ o2 K5 r$ N6 Y# rtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" q" C$ E' D2 \% t" t' p/ k `typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
. _! V8 e: }6 o2 b4 ^! ltypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* Z) g' G; l' Z/ q) Z4 E$ D
% @1 G" D. O. y0 t' B# ]5 V- i0 p% p* z- U3 D* O1 I. Q6 P
typedef DWORD (WINAPI* TGetBestInterface) (/ Y6 O2 w: A2 d0 x
IPAddr dwDestAddr,
- r9 M; B$ K: v; A$ Z3 y4 [ PDWORD pdwBestIfIndex; u" b# X0 V) J* {( A' `
);
- f9 V8 }* n+ e0 ?
0 q" X% i5 j. M& |% L: a. z, S0 b9 a+ S+ c* L2 l: z
typedef DWORD (WINAPI* TGetIpAddrTable) (
" K8 @ I( m/ a4 Z' L" m; Q/ m PMIB_IPADDRTABLE pIpAddrTable,: C+ t, S+ V D5 S! d
PULONG pdwSize,
* d% p. g, W4 W7 E8 n4 U3 F6 Y BOOL bOrder
% W, _0 ]9 l; D$ X& k) i0 Q);
@6 A# f' W; W+ @' W' z9 w) {# Z6 Q9 j, @- U
0 E: }2 k3 \+ w5 }3 O) p% `typedef DWORD (WINAPI* TGetIfEntry) (6 Q. K8 Y$ H. i
PMIB_IFROW pIfRow
) @! k/ h+ o k, y" |6 i. i);
# T1 K% ~* R, |
' L- t7 q; I6 c0 i1 r$ U6 B' @/ \) z" c- I. b
CString translateUPnPResult(HRESULT hr);. q$ i4 }1 j: U2 x: J6 z: z
HRESULT UPnPMessage(HRESULT hr);
s9 C q7 }) Q" I2 e" u# F! P1 u! j+ u
/ Y. r! @# n( vclass CUPnPImplWinServ: public CUPnPImpl
5 _, d, t/ }. L2 U/ @, I4 q- m{* Z# q9 G4 G( R# @2 E: d
friend class CDeviceFinderCallback;
( J7 Y! Q5 k; [. C$ v friend class CServiceCallback;7 \, T3 `% g& a& G- J8 K
// Construction
2 o3 I* S5 m2 l$ |public:: k6 D" _$ E9 X) x1 e! d' W
virtual ~CUPnPImplWinServ();' C3 s1 Y4 s+ v1 ~
CUPnPImplWinServ();3 R. [. h5 B- t: w7 s
/ }$ m& ?: M8 e ^: Z6 j0 R2 V% N, \; w- ]4 ~1 Q) h1 U
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
) z, F+ j/ z. y5 j2 A4 c virtual void StopAsyncFind();
5 y' `1 A; l5 p5 T9 E virtual void DeletePorts();
5 X. w4 [' S |9 p* P virtual bool IsReady();
1 c/ A4 e/ X- V# i4 }2 ? virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
6 O' z8 h8 } c9 K
( R* q. P* H. j' [( Q& |+ [4 A: e7 d* S8 e7 s* Q
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)$ z t K- m! U& N9 `) y4 w
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later& w6 I( l( R* O7 |$ ?9 P' a
virtual bool CheckAndRefresh() { return false; };. k# z/ n6 U9 o# U; @5 \
% _7 V! ]0 A+ H4 ], ?0 Y0 ~1 u1 L) r. i* z: F$ ~" l
protected:
3 d5 f# X% x3 q; `# M6 d* J void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
* T' }8 Y' L# A% e* u0 L; H1 t. v* j void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
9 h0 e9 ?, D, ~# U1 _* Y5 w void RemoveDevice(CComBSTR bsUDN);
" x6 ]! i* e( w- b' d bool OnSearchComplete();: Z( j7 n) Y s
void Init();
3 C3 r: g6 V! l; B" |2 r+ C& M5 t' P# o# U6 h3 p3 `5 x& Q9 D
) K. |5 N; v/ Z" O
inline bool IsAsyncFindRunning() 7 i$ s8 s6 f. ~$ L4 z! W
{
; B: V; {$ U! \9 j. r if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
U4 ~# K9 D+ e9 s( R3 X& i( Y2 \3 w {
$ |% k0 E7 d/ M! Y m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
, N) Q; g8 f, I6 F m_bAsyncFindRunning = false;
7 ]4 t V+ I" g+ x- [ }3 i9 t( h8 G8 Q4 B1 D/ R9 O
MSG msg;
8 M1 D6 ?6 j8 ~0 t5 |% \& Q while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )5 F S$ \9 ~8 _! j9 S" p* ?
{5 L7 u) _ l% C& n9 |
TranslateMessage( &msg );9 I, N( F2 Z* K6 u& ]. e, _" R
DispatchMessage( &msg );
[, Y' x! s1 y }( Y8 n9 X6 }* i/ C
return m_bAsyncFindRunning;
* I8 q: ]5 ]" [2 q }
+ ^" i. j* W) i0 w* }1 l# C- ~, u) {3 a# W
# u- _8 T4 c6 Z
TRISTATE m_bUPnPDeviceConnected;4 a' F6 q& l$ h& v( t8 A
* b7 n3 m/ _- X/ F
! X& g8 p! `1 [; E0 c. S' ^; l) Z' r// Implementation8 l, X3 X/ Y& k8 C
// API functions- o1 L/ X9 ?/ b
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
h0 v! Y( n# r8 |* y# _7 }6 y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);/ }) `3 G3 t6 U/ }7 d2 B
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);2 S) _6 N: t" S6 t9 B& s% A
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);/ i$ a- K2 }. a$ I) _8 e7 i
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 h, A- K% n& d& @3 t
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);5 D/ a" R9 r# _( {+ U3 a
- F. B# ~$ k, z+ n% t& c9 ?
/ E$ U+ A: W: y9 \) G" p
TGetBestInterface m_pfGetBestInterface;' c/ E) y! K0 j% B. T& `
TGetIpAddrTable m_pfGetIpAddrTable;, U3 b7 f6 ?$ h: `5 |9 G
TGetIfEntry m_pfGetIfEntry;
6 Y" H4 I( t5 X" ?' ^
: q. x" g; G: a, W- e6 M6 n
. q2 |# d) F! P, a- k" L4 f static FinderPointer CreateFinderInstance();! S2 R+ c" A9 }/ S0 I w
struct FindDevice : std::unary_function< DevicePointer, bool >
2 ?8 u3 r( A) _$ K, G$ { {
6 n/ s$ G( J" p+ C FindDevice(const CComBSTR& udn) : m_udn( udn ) {}" }6 U _5 d4 O; H! N
result_type operator()(argument_type device) const: t A$ z, l: p* I' S, j8 \1 s7 x
{
; [; ]. z, @& p, Y CComBSTR deviceName;0 B1 R7 W3 P$ O) q2 [. a& e% m, f5 K
HRESULT hr = device->get_UniqueDeviceName( &deviceName );: i$ L0 y9 N2 m \
. M3 j: S4 w. z! w' a
! ~+ Z# f5 g, t$ n& ^ ?& e if ( FAILED( hr ) )6 m6 }+ o' D! r2 |6 B* s
return UPnPMessage( hr ), false;0 J1 D! h4 F9 u2 T5 m
5 X/ y1 X9 ]* W7 t0 W: F4 G/ g3 N* z8 m a
return wcscmp( deviceName.m_str, m_udn ) == 0;
% G" J8 M) Z5 n- D }& Y0 s6 c1 S" I
CComBSTR m_udn;- ]0 q- ?! V$ |- e& @* J
};# Z* L1 F. b8 J3 C) S1 S7 g
" X0 p& R( |' J/ r void ProcessAsyncFind(CComBSTR bsSearchType);* C- S( Q( M7 z6 L
HRESULT GetDeviceServices(DevicePointer pDevice);
5 B0 _4 r7 [% z- q void StartPortMapping();5 w9 o' u' x4 z% b ]) i
HRESULT MapPort(const ServicePointer& service);. C- i4 ^# p& V; v. G
void DeleteExistingPortMappings(ServicePointer pService);/ d8 I- u& _' D" g' f" @
void CreatePortMappings(ServicePointer pService);
# `8 R; D& w% U6 Z; k/ `. s HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
6 W- Q4 n" L0 Q( ~ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; h9 f1 Q3 A2 Z7 {! } LPCTSTR pszInArgString, CString& strResult);
! E# M- O7 g# } n9 d$ T void StopUPnPService();. ?$ [! Z9 j& g7 a
6 m1 U. ?9 F+ M- n2 R7 P' I: I9 ?1 D6 X* R7 B4 V3 A
// Utility functions
- {0 {+ g# j9 C7 ` HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);3 H! G. h4 v) a( z( M
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
0 N: D: r+ X* Z INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, c& M. B) {; g0 L
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ u# o; {. S0 ]
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; [) H5 H4 N% C. o HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);4 B0 G# y$ O! o
CString GetLocalRoutableIP(ServicePointer pService);5 Y g$ o1 e4 B n! N; G
1 h x4 ]# i2 u; M4 ^5 |" J2 K( m* {/ H
0 J, ~& X9 w& }7 Z1 _// Private members
5 L( d8 K* {0 {9 J# sprivate:' x/ D) g6 p" V* Z9 [& ]
DWORD m_tLastEvent; // When the last event was received?
" X( o) g2 |7 K. x/ F1 O+ B2 l std::vector< DevicePointer > m_pDevices;
* N J7 D- |' ?! e2 Y3 x3 @0 b- _% _ std::vector< ServicePointer > m_pServices;
7 [9 K3 ^1 V9 k" H* \, y! Q FinderPointer m_pDeviceFinder;
. s6 \0 M6 ` |, Y* }' ?1 k& h1 O0 ] DeviceFinderCallback m_pDeviceFinderCallback;
* j3 }% s6 Z4 P9 [8 B8 W# ] ServiceCallback m_pServiceCallback;0 g1 h5 `# F4 a% ?% u& k
, m. ]! A+ y1 N! g( g' }! A4 m
& K; y9 N7 L) W LONG m_nAsyncFindHandle;1 N: S& S! o4 ~5 o6 @- N# ~
bool m_bCOM;
% \! \7 v y6 [& ~9 }( ^ bool m_bPortIsFree;
& s- L2 _7 F0 U! @0 D! B: R! q CString m_sLocalIP;
) ^* P0 O" D5 u3 T; q CString m_sExternalIP;5 I) F1 j! ?. `) d
bool m_bADSL; // Is the device ADSL?4 @: _% p3 ~7 @( B3 {3 k, V
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
# r1 d5 ^4 M, A, u# R" x bool m_bInited;. p$ w g1 N( m1 P' J
bool m_bAsyncFindRunning;9 j/ z* t5 J, A) {" G# Z
HMODULE m_hADVAPI32_DLL;' K. t7 t) U7 _* [
HMODULE m_hIPHLPAPI_DLL;
5 o" p3 c3 Z; |6 k! _ bool m_bSecondTry;
, s# Q# u, E5 X2 T# S, N bool m_bServiceStartedByEmule;* D* [& }+ V" R1 I4 A
bool m_bDisableWANIPSetup;
' I* R; I! o) `: Z' \) B bool m_bDisableWANPPPSetup;
- f5 p! G2 D) L" A1 u7 |+ V+ U! c" r: G" t, `
v1 d9 x7 Y1 H; {};
* x/ c" B) g8 D' G5 R4 O% ]
5 o( q4 |1 o: M+ R8 _- M
- f- Q7 ~7 |, ^9 v$ X( c; f// DeviceFinder Callback
3 m3 g2 {. {. N0 {% M& Vclass CDeviceFinderCallback" j. C! T' G0 M! {: H2 w8 d
: public IUPnPDeviceFinderCallback( w; ]; i- I, k' o9 D" j4 w: G
{) c8 ` t- U% {3 q- u8 M; P3 M
public:( z- V$ i( Y) y# W+ a$ N
CDeviceFinderCallback(CUPnPImplWinServ& instance)" I! ]7 ~. Z. q1 ~% h7 Q
: m_instance( instance )
o Y1 z& S7 h { m_lRefCount = 0; }9 O6 W K& \( {9 _2 a3 ^. a; l
t3 I! r5 U* O ?6 @& ^. H+ \! H) F1 { B8 R: t# ~ Y
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);+ \& D' O2 e4 h2 i$ D2 J; H. [( u
STDMETHODIMP_(ULONG) AddRef();9 ^/ p, M. t" y
STDMETHODIMP_(ULONG) Release();3 M4 p# c/ ?8 j+ D! \" \ `
0 G$ O, `$ @5 q+ S) ~! \
+ x# t1 E+ m; c! l% M( ^4 ^// implementation
* H( B( D n3 m2 d, @& ?, a: C; zprivate:
! e+ I5 ?1 I5 n HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
: V% f. |4 {2 B$ u HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);0 a( A* E1 T0 j
HRESULT __stdcall SearchComplete(LONG nFindData);! f0 M0 d" l0 V0 T6 H' @ u
4 m4 _4 B1 f# D1 X- b3 e' X' k" @4 p3 k+ q6 H
private:8 x; M! E3 Z4 d. U, \
CUPnPImplWinServ& m_instance;: k' O7 G4 j9 Y/ y* D7 X) W
LONG m_lRefCount;
9 b. x" Y6 t9 I8 T- i};2 h! @8 \. S9 N% H+ w
0 P% h) S1 I; t2 e6 `$ _; v
3 [ p, Q( e$ N% s1 E$ S// Service Callback
! E$ }3 ]4 D) H1 Cclass CServiceCallback$ q8 M# g0 V/ O+ T1 ]. m; s
: public IUPnPServiceCallback
( {; E4 }& \0 K6 @: S{* M0 N- X- x, x: c' I4 U: n$ f( i
public:
0 T L& O) @% ]7 r" D/ g% h0 }7 Y CServiceCallback(CUPnPImplWinServ& instance)
' n7 A' O1 V2 _0 _ : m_instance( instance )
7 `6 O# A* o0 d* G5 f { m_lRefCount = 0; }# Y6 u7 \& G) O0 g0 D8 f
# z! |7 |7 f0 i& J( v# v9 b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% i5 W8 k- y+ Q, ]! C6 y
STDMETHODIMP_(ULONG) AddRef();' E! @- k( k' }: Y1 b. g7 {
STDMETHODIMP_(ULONG) Release();
# Z) y. `1 Z1 F% B6 u
% A( c; T/ ?. I3 |. q; z: }+ U; m0 E8 q- Q$ t# ~
// implementation0 a3 a% }$ G# |0 T
private:
$ H& p9 w$ w# c8 _6 z3 X' ` HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
1 s3 K) J6 ~% K# l0 D HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
, g3 S; d( a7 O' }( d( X" h1 `2 m; h( h' O+ L b
" I1 V* R0 O8 ]* l+ r6 i! Z
private:
/ i' d& i7 S9 E' @7 L CUPnPImplWinServ& m_instance;
$ @' e: m/ e& N$ _2 K# Q LONG m_lRefCount;6 B0 N1 n; X0 l4 x8 V+ W
};
. g, [1 m% ^5 k9 f; ]
/ r6 n$ [) I$ C0 k% D7 F! g+ ^
) }0 s3 y9 d) a1 p0 ?' h i) w/////////////////////////////////////////////////
+ z x2 I/ W w- `( V: w
6 e5 k, {+ q( S2 @+ K0 E. s2 d
. u4 R$ w" @/ l2 D! T+ m使用时只需要使用抽象类的接口。" d# L4 k/ c, l7 }; n9 Q5 n+ l
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
( U6 L5 V& x2 I8 t* r! H" qCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' m, y1 j a& U8 l4 `% ?
CUPnPImpl::StopAsyncFind停止设备查找.; {" q$ Z! z5 W4 d) Y# J7 m
CUPnPImpl::DeletePorts删除端口映射. |
|