|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ J' f+ [" `" c" n/ g r2 x
# l4 h5 k. m9 R. S1 t5 U$ Q r7 w; R$ U
///////////////////////////////////////////
3 S6 J- w* | t* M& J7 \8 A; P" [//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 K& f1 M! { h/ a- ]3 d6 e% z# G+ k6 X& i, V
+ P; r2 V6 m% X5 n+ i
#pragma once
+ T, @2 |) N3 J#include <exception>' l, H. f- ~2 b. Q) T
t$ \$ U2 F- a' i7 `' ]: t
; l! ]! j% Z0 m3 d, n/ D' ] enum TRISTATE{( B. m1 |( j) [9 o8 Z. z
TRIS_FALSE,
; O( E# A0 R" Y& f TRIS_UNKNOWN,
! L" z' L9 _9 w" [4 y; I9 k" d TRIS_TRUE/ R7 [8 `# C" _. O! U+ y
};0 y' [/ s' G7 Z# s! O2 @! D
5 R. `7 z* N, S ?9 ?
* t6 ?, _. O- _- A, [( c
enum UPNP_IMPLEMENTATION{6 n9 W# h1 ~5 Y- D6 h
UPNP_IMPL_WINDOWSERVICE = 0,/ C9 A1 { ^! k2 l! |
UPNP_IMPL_MINIUPNPLIB,/ ~6 }$ X/ e$ m9 B9 Y% M. ]" ?
UPNP_IMPL_NONE /*last*/. j5 X6 u- z' q% ^
};
. }6 E; c9 X) _2 J0 E3 k
: m4 K5 s, i; C) K6 t; q
( X6 [4 X( q! k8 u
3 \3 \" h9 C' v4 h: e
9 r G' q& N$ `; d1 Hclass CUPnPImpl
: Y) x6 D' x1 @, e: C2 H{
, t% i4 G) u7 j6 Fpublic:9 Y& z3 `# ]5 d
CUPnPImpl();# g) L4 g$ l3 v) S* F+ e: w8 g4 t
virtual ~CUPnPImpl();
2 h9 n. J# N# V& P3 x n struct UPnPError : std::exception {};) B5 [4 [; C' |3 x4 o% i
enum {
- h0 b+ ?- c( N. H" V, @, q9 _ UPNP_OK,# i; l9 |3 z5 U
UPNP_FAILED,) C; p8 }8 u/ j# U2 q; ~
UPNP_TIMEOUT: w$ E, j: l" K, n6 Q9 m
};) E; [, H% s& \5 M6 U+ m, M
6 c. F. t% B, R/ e3 f; v% L6 R$ ^' G) G, C2 m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;$ W8 X) L$ U; ^) ^
virtual bool CheckAndRefresh() = 0;
- v4 l) ~5 C3 I virtual void StopAsyncFind() = 0;
9 D3 O$ u9 W+ k virtual void DeletePorts() = 0;# y5 ]) E4 Y" R
virtual bool IsReady() = 0; {1 ]- f7 F! [) V2 k
virtual int GetImplementationID() = 0;) n/ m* [+ W r& t
; y1 [- O# ?( n' `4 r void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping$ L. ]' }- Z+ Y
; o$ p( Y% \" i# Z1 A* u! A+ ]( r! W$ n0 i& l* w( p$ B7 I1 S
void SetMessageOnResult(HWND hWindow, UINT nMessageID); K/ k( Z/ n. Y+ J3 N# U2 A
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }- N7 H0 u4 W% e# B- a8 H, U
uint16 GetUsedTCPPort() { return m_nTCPPort; }
! M& S* m$ g9 |2 v5 L0 o uint16 GetUsedUDPPort() { return m_nUDPPort; } " n7 w0 Q$ x1 m. }0 \8 g
5 R7 i, k6 ^9 J; f: l' \& t
9 i6 }$ m+ M5 R# q% g/ [% P// Implementation
z% l$ D: e9 N5 \: W8 u! Zprotected:* S2 H; w6 O& b: ^
volatile TRISTATE m_bUPnPPortsForwarded;
* N5 [$ \, `2 A8 I9 j5 ~ void SendResultMessage();1 t- x" y; c- F5 k, k
uint16 m_nUDPPort;0 i% j/ {3 F' c* Y: A
uint16 m_nTCPPort;
3 ?0 R6 ]6 r) \+ j uint16 m_nTCPWebPort;
# E0 M! t! V5 t, d9 o: @! p bool m_bCheckAndRefresh;
9 V! S0 w8 r/ [1 y0 `5 ]' f0 T7 F& w5 C
5 t* v3 e4 f' x( y1 }
private:
' ^& U2 \$ | Y e HWND m_hResultMessageWindow;) M: C3 v. i# r' Y$ O( M9 @! G. D
UINT m_nResultMessageID;
2 }- w5 z+ k5 X& F! Z7 D% S6 \" c3 w& b. _9 m4 @% N0 q! N
; {( p L( h% k* [ _& d
};9 O R# }/ Q+ g5 m! ]8 z& i9 x/ j
6 G A3 [+ o( h
5 I& B8 K5 p8 F+ u# z f9 a
// Dummy Implementation to be used when no other implementation is available
( N! O4 D/ B0 D+ A- mclass CUPnPImplNone: public CUPnPImpl
7 H; r- V) Y9 |! }( D G! U{. a5 ?+ T- M6 U
public:+ a2 ?% @# u& H# l0 |) ~
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" ]2 [% b; M8 Y# I4 K
virtual bool CheckAndRefresh() { return false; }2 X! i' }( I2 B3 w
virtual void StopAsyncFind() { }
9 z' ^3 |5 s9 v9 L5 q1 p; `7 i7 {* d virtual void DeletePorts() { }
' ]9 m6 z9 V4 _ virtual bool IsReady() { return false; }
5 Q; Y2 d! g# j# I: h z- o4 r' B9 ?. F virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
+ V$ o2 f" k% n};$ T+ q' Y. m/ {1 t; A+ X
]+ g6 C% v0 B8 ~, }/ {
: F0 ?% f: r* R" m% x0 n* t/////////////////////////////////////
( Y% H- V3 n4 U6 M5 g; I u//下面是使用windows操作系统自带的UPNP功能的子类
; m* }; ^0 F, q% x1 f, S( l% I6 r. L
* f, z" ~$ e: w0 K7 E2 V$ i1 i# P' j' Q4 {7 F
#pragma once8 C% b2 N) T2 ^# ^# r
#pragma warning( disable: 4355 )
' s' P1 E/ Q* Q7 j8 w' p' Z
8 H4 \, Z- g' s& n- u' b" x
* U& \* i! H, P5 g) g#include "UPnPImpl.h"
9 Y; m* n- A3 h/ J7 c" W7 S% u#include <upnp.h>
3 i& [6 W+ ^( t& z& Q7 \#include <iphlpapi.h>
% [) M4 M" H6 P# J#include <comdef.h>
( | V: l! D: z#include <winsvc.h>. U2 ]& z/ l7 y* h
2 D V7 v0 E& e2 S2 I
3 C+ C1 y! u% i; K- C& Y! W
#include <vector>4 w$ `6 @7 B5 d5 ^ U+ e5 [
#include <exception>! a+ k* b. m$ |. T2 u! }7 r
#include <functional>
0 S" Z- ^! m; K$ [4 P; B+ c. k. _/ a
. k1 v0 i5 w. M( w, ?, w6 Y8 P4 H/ u" b4 G0 U! H8 j) d
9 V1 ]8 _8 D( E8 G0 n# h/ w" z" [% e/ h% Z) r6 H R. |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
8 I) L; V' ?1 a( D7 J, Btypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;+ s: ^* x- g1 ~* F( o; e
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
# K* T5 F( Q* z# Y8 vtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;3 b* t' x, |0 H6 G0 _ l
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 j9 f: K8 L! g) ^$ E# S2 r
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;& D+ s# l& }! s# U5 i" B. c5 e' m
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
0 ^( G# p% u& @3 g: C+ x- Y0 h# F3 S3 y0 a5 W3 O: u
$ Q1 a' o& A c- D; P
typedef DWORD (WINAPI* TGetBestInterface) (5 j- L- c: P% A+ w' U5 B
IPAddr dwDestAddr,$ x3 j" I/ l: M
PDWORD pdwBestIfIndex
3 Z3 w7 {* G7 ?9 {);
1 v6 P# t2 E4 k( J
+ H& T) l9 j9 j3 f
5 ]/ {3 M7 J0 j( j! gtypedef DWORD (WINAPI* TGetIpAddrTable) (
5 R5 e& ?: y7 \$ c. y2 f- M PMIB_IPADDRTABLE pIpAddrTable,
4 u/ `; g0 J0 r* O1 i7 e PULONG pdwSize,
2 h |9 p5 x; C BOOL bOrder+ k' N9 j/ e# Z8 V+ K
);& y, R4 W) ]7 F# g* t5 L3 t
: X2 I, q/ u% ~7 ^% {! B l& v1 ]1 x4 Y, Y! h* P) f
typedef DWORD (WINAPI* TGetIfEntry) (! U( e/ K# R9 X
PMIB_IFROW pIfRow+ h# s5 O$ x, |3 O" D* {
);
/ H( U7 R! V4 U9 U1 n/ }3 ?# N+ U# x f% R9 C, w g5 B7 V l, }# `
( B1 g; O' }: `
CString translateUPnPResult(HRESULT hr);
r5 ` C( }. l1 l j I: h. yHRESULT UPnPMessage(HRESULT hr);4 ]8 Z8 h7 b/ U6 l" l3 c: T6 `& c
& G" i& g3 E+ ]* v$ F$ A v
3 _6 A1 @7 h( o
class CUPnPImplWinServ: public CUPnPImpl3 @9 c( n+ o4 ^$ j
{
$ K8 Z1 ~0 h5 [% B/ ] friend class CDeviceFinderCallback;
$ r( t& `. n$ A. y friend class CServiceCallback;
& G* E$ I4 a2 ]' A, r// Construction1 m- Q' @5 g0 `
public:
$ e5 x# ]0 T* E c: ?6 G! y virtual ~CUPnPImplWinServ();; J- \1 U& ^& D# Q8 q6 l7 y
CUPnPImplWinServ();
7 B2 p @8 ?4 e8 Q1 j! r! p. R, n. t1 D2 A5 b) g1 f
; W$ V |- r8 e: V% P: q
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }1 D4 O; w5 [& X! x, K* N) P7 r
virtual void StopAsyncFind();/ x* w2 a* ~- i2 i
virtual void DeletePorts();3 G: C$ H ?; n! D/ s
virtual bool IsReady(); T- k/ b2 ^. B' [0 C @
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }1 B% V( M9 i! Q+ I& F0 Z3 r+ m; v! s
! i6 v+ [' m. K; Z+ F' e) I. {6 u
/ Q; R q+ D2 v9 B+ _$ v1 x
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
! W3 k3 @7 m7 x6 v; l // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later) `! \, A' y; m) B
virtual bool CheckAndRefresh() { return false; };+ Z( p5 u% |. Q2 ], g3 C) v
+ u) G4 }# Q3 R% c4 Y! S
1 ` C4 Y/ _% T/ w+ B) p& y9 T6 t$ Fprotected:
: k8 u/ o, P0 H3 C. d8 u, w void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
^- I% C( L! c, v) U3 [& J void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);8 y& e0 M: D6 V* P+ D
void RemoveDevice(CComBSTR bsUDN);4 P/ A* v# _& d" f5 A U
bool OnSearchComplete();
8 O6 d1 O9 Z* c5 s void Init();
) s# d6 s- l: X, _: d9 z$ ^- M! f
/ u) q5 T V# I! J
inline bool IsAsyncFindRunning() $ \ K6 c, D8 _
{
- ]) [" n& s- |0 ~8 a( I if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )3 Q8 ~5 Q$ h1 l/ c7 s& o( Q
{
6 z# d! U: \5 R3 b m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );/ \; f& M0 v4 `$ \3 i9 s2 A$ n/ C
m_bAsyncFindRunning = false;& y$ B# T6 c% j7 f
}
/ s0 v- H; i$ i- Q MSG msg;
9 o; J$ C' u$ G! }4 ` while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" D* O% W) O, @% J$ \2 x, ~7 D {
5 ]0 o, U( P3 F6 T1 m( _, }% ] TranslateMessage( &msg );
' P! y" S, N, ~" V1 m5 |9 t7 I DispatchMessage( &msg );
+ g1 y q7 n8 S1 j3 [" b: V$ x0 ~, J }
8 B$ d/ c) Z1 }$ y- j return m_bAsyncFindRunning;
1 F b3 [. F7 y3 a7 M }
: q+ {0 u0 }9 k! I' ?
" J# D/ \) [% e+ {' W8 A- u/ o0 K9 y- C3 \2 n
TRISTATE m_bUPnPDeviceConnected;
5 t1 b& {* J: T0 \5 O
4 f! |6 c: `6 _ @- \ v+ O z3 |+ ]; w# r0 M) [1 L( B
// Implementation& Q3 D$ p, g4 f6 q
// API functions
) D% h( C2 D b7 T SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 ~$ G, P" g7 R+ w SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, d4 t- p& D1 e3 R+ x1 [
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
: l. G+ H+ Z+ a1 w: ]1 p BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);" r$ I+ u8 E* D
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
1 _& o8 a8 w% Z) o- D: ? BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);4 A* Q( I$ y* ~8 e9 ?( U4 c
- @5 O9 s% u# U) u- p) E; G E
. l S- W' O- G: M6 L: w; x
TGetBestInterface m_pfGetBestInterface;( H. |! {% }' b7 a* u
TGetIpAddrTable m_pfGetIpAddrTable;
6 N _- _* p5 K, v TGetIfEntry m_pfGetIfEntry;
0 A1 P' ]% q, @8 _" @6 Z6 D7 N
. P! q t ]. H) z- D7 Z, _# N1 K& V% i
static FinderPointer CreateFinderInstance();
: C) c2 {5 ^9 V* V4 ]$ V struct FindDevice : std::unary_function< DevicePointer, bool >
0 f- C( {. Z+ _8 D# g! r- ` {
0 u3 I. z% n' I+ f( Q; U FindDevice(const CComBSTR& udn) : m_udn( udn ) {}( i* [# }- b! T) E
result_type operator()(argument_type device) const
& R2 `; G# R) E, ] {9 {2 @: i5 M- | C, ^7 ~# ~
CComBSTR deviceName;* i3 D+ q5 [" A0 z/ v- C
HRESULT hr = device->get_UniqueDeviceName( &deviceName );2 u- n7 r/ h4 p
% T* ~, S# ^# a) q6 \' f4 p8 I- t' {& h! H& K: i
if ( FAILED( hr ) )
# P, `2 b) O ~9 h% U% I return UPnPMessage( hr ), false;
5 F9 `% g8 g9 f3 b# F1 P& Z8 D; O
x, d% y% J3 P1 E3 ^
. c+ \& Y# b n( S% D return wcscmp( deviceName.m_str, m_udn ) == 0;
4 V; g! u) k5 ^! M5 \# k) y }9 O2 T! t+ J. F! h; `' j2 d+ v
CComBSTR m_udn;
7 k0 ]7 m# k' Y2 C$ ]8 e };0 d ?1 ~* ?! S
2 }: e( r( C8 _3 ^" f& K) |
void ProcessAsyncFind(CComBSTR bsSearchType);
9 J% a: G3 ~( j# e7 [# ?5 N HRESULT GetDeviceServices(DevicePointer pDevice);* G/ s! h. ], [
void StartPortMapping();3 ?# J6 ]) V1 U
HRESULT MapPort(const ServicePointer& service);+ B9 f$ N3 x8 V2 X0 \
void DeleteExistingPortMappings(ServicePointer pService);$ e8 D' r8 ]* ?; X: F$ Z. w# ]( k
void CreatePortMappings(ServicePointer pService);4 u2 z, n5 S, Q% x; \& ?5 Z
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);& j- k/ M2 D3 b
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ! b9 E* ^) a8 J V- f0 T
LPCTSTR pszInArgString, CString& strResult);
+ c+ Q8 `8 n' _: g% F+ f7 H3 s3 o void StopUPnPService();. a1 E3 i) c7 g6 u2 |8 u$ N3 r6 _
! K$ J) G# U C5 T
/ C. ^4 T9 [" \1 ?. I1 G; p
// Utility functions, _" l& o. f1 ^0 z7 t# S; e
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
( w3 O: n7 D/ v, Y1 S' D! w INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
( l- X, V/ t# ^ l! N, L$ C5 @ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: \9 _2 j3 v; ^- E. J2 u void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" S3 Z5 t9 P& {+ H2 P HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);% J( A" A) A* b6 D% P
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);: E* s7 y9 L& Q& ]
CString GetLocalRoutableIP(ServicePointer pService);6 l2 `( U% M) b/ S
* Q* t: M- C! R( e, F) r% }
+ a s" g5 U% s, M, R// Private members
, l5 g7 _0 Y6 y8 G, V) [! yprivate:! \& V2 o) B' L
DWORD m_tLastEvent; // When the last event was received?
) q6 v V2 H6 v5 r8 u, K7 ` std::vector< DevicePointer > m_pDevices;
6 B$ ~# E5 W, _* K7 L6 W std::vector< ServicePointer > m_pServices;
( c- ?' h8 z+ q; ?: w' Y FinderPointer m_pDeviceFinder;
: z; A O9 q; O$ x DeviceFinderCallback m_pDeviceFinderCallback;
& F: C# f v# B; A ServiceCallback m_pServiceCallback;
5 C! z9 [. T7 G; s
8 \1 a% A, a2 e, |, q( g/ T( l7 S3 ^( A: d) L" N" F
LONG m_nAsyncFindHandle;
. F |+ U! B. B& ?6 j3 s; c bool m_bCOM;
) p' C# v, d- C; O bool m_bPortIsFree;2 D6 Y$ N$ e: B/ ^( p
CString m_sLocalIP;3 z @* M3 K/ \3 s9 k) [( z
CString m_sExternalIP;! Y" J7 `- t% I& K) G* b4 S' k
bool m_bADSL; // Is the device ADSL?
@3 X# m( z' v2 U& [! k! z3 T1 N bool m_ADSLFailed; // Did port mapping failed for the ADSL device?! O; }+ b3 f Q. C. u( ]) f
bool m_bInited;
& Q @" w9 C2 M! l4 D K5 h g2 ^4 z bool m_bAsyncFindRunning;
9 B6 a8 N- W! G6 M) \ HMODULE m_hADVAPI32_DLL;. J2 J# f$ S2 e# W8 U J/ ]& H
HMODULE m_hIPHLPAPI_DLL;- Q/ s+ X! M/ `3 D2 m9 f
bool m_bSecondTry;
! u" V- u6 t6 [8 C% o1 U bool m_bServiceStartedByEmule;8 R8 J5 [6 T& U8 E, ^
bool m_bDisableWANIPSetup;
6 v7 K0 ~9 u# Q% S8 R bool m_bDisableWANPPPSetup;
* E& C5 v9 C* V5 S+ ?: c2 z3 O) w9 Y0 g: c0 ]/ K9 o# H
8 K1 f2 E1 }8 H7 H
};6 E$ b0 N6 h- _2 q
4 G' T& ]: b" \7 I% o8 J) @( w! |5 f
- A5 v% W' p8 y8 V* ]2 M ^# f( U
// DeviceFinder Callback
$ O) I/ o' g! {class CDeviceFinderCallback. r1 g. ~2 J# x* C
: public IUPnPDeviceFinderCallback! @5 l0 c1 V- [ P
{/ f; [# D a5 Z r" o) z, N. p9 Q
public: O% h2 n4 P% a
CDeviceFinderCallback(CUPnPImplWinServ& instance)
0 g N- r) G0 h' Y4 C/ z; m : m_instance( instance )9 n! o- l6 k: M( G+ V1 q
{ m_lRefCount = 0; }
0 ?/ t5 ?+ ~) E3 Y' a: q% {+ m8 C- Z: O7 J2 n; P4 m* B
, E! z9 j! \, S9 v STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; G8 ] w, Z$ Z, V8 U1 J# z: j/ a
STDMETHODIMP_(ULONG) AddRef();
. P! B0 D0 R) j/ a2 G$ t9 V$ ?$ L STDMETHODIMP_(ULONG) Release();
& ^' U0 B: O5 k' j% e* i' q4 D" [$ ^" |* ~, r
. J! w K6 P7 c+ ~/ z1 h7 r// implementation
1 P, q1 ]8 G! ~' _ Hprivate:8 M7 a% o' C) I% I
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
4 L, `* S( f7 O: w; ]. n: P: W HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% N1 d6 R3 f y, v; X' S% h2 Q
HRESULT __stdcall SearchComplete(LONG nFindData);0 H9 K' r( v' N: j) k
6 |; I$ \, B! p
0 B% @8 {7 j/ ~& }0 |% Dprivate:
+ ~+ w- ^$ p3 L# k/ \ CUPnPImplWinServ& m_instance;
1 U. \3 |, L9 |. U LONG m_lRefCount;, m. O2 s1 i5 j" O7 t [/ x
};* X: l" L+ H" \4 h
2 u: B: t& f) S2 M4 a
) @* a* t& R5 p4 \0 h8 g* E( k' v// Service Callback
; _! X6 H. h/ Q2 A$ Aclass CServiceCallback
& l$ k1 x6 u5 S( {9 y2 J: ? : public IUPnPServiceCallback
$ P6 A/ k$ v0 \. y5 o" W* J) E{
' ]+ J& q8 S6 n4 I4 v) Rpublic:" M) `- {6 X" b+ V" g7 Y
CServiceCallback(CUPnPImplWinServ& instance). k7 o& [0 f6 V
: m_instance( instance )
9 o. p* M7 |. c$ @ { m_lRefCount = 0; }
- x& W; a- Z' y- d# i
7 M J5 ]$ r1 r& f8 `- y6 r; X STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 E/ K3 Y& v. I5 {1 U STDMETHODIMP_(ULONG) AddRef();
5 _9 x* w5 s2 ~( b4 H6 x" v STDMETHODIMP_(ULONG) Release();% K& L/ @& d- ~- P0 j0 r% m
7 w; j8 x3 Y6 u
9 m& F) d) |# Z% }$ a4 h0 y// implementation$ u: g \( t) \1 W4 _
private:+ y9 C5 @9 M. Q' C+ ?) n' G
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* ?. Z. u9 w! C5 h: r
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& Q8 h: h" U/ {: [- [5 J
9 X5 l8 j# }7 f r+ p
% a% c8 U( I/ w' bprivate:
}$ |& P/ P" G! S$ B! i1 k CUPnPImplWinServ& m_instance;' u' m! x% [$ b. ~) p" u
LONG m_lRefCount;
7 C; L. G" v% y3 u) Q};
5 L1 ^# s1 o+ }6 O1 `1 F1 K( W% i9 I, X+ j9 C5 w: q
- ?% l1 O( v4 \& Y. T# N
/////////////////////////////////////////////////" {3 k j$ l3 x4 t; T9 K
- s: Y* C$ [4 M1 d; c# K6 h
5 [2 a s% ~& [$ }' Y使用时只需要使用抽象类的接口。
2 i; J# X8 K( N0 |! n7 {4 K+ TCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.) ^. t% K& |5 A* o" _
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口." \/ P* k* Z I
CUPnPImpl::StopAsyncFind停止设备查找., D" `9 D( r' I& ?; _0 ], F/ `
CUPnPImpl::DeletePorts删除端口映射. |
|