|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
# g# C" `+ ]+ A" T" ] I1 I% O" P
- N/ \; [6 O8 J" K///////////////////////////////////////////% `' _+ D. u( l7 D u: P& J
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# F( g2 Y6 r: m& ~7 v: o' t0 A; v. c- R7 r. U+ p4 l) D
! R( H" |4 T' r#pragma once
6 |* m$ F* z5 |) Q3 e+ g#include <exception>
: P+ ?8 L# N D, ?, x3 ^) b& \4 [, m+ I( ]3 Q) T* t/ a
6 f8 m X0 r R) p$ u
enum TRISTATE{3 _# F' U% p/ L; k% R- C
TRIS_FALSE,
; P/ R+ _& W. q. [, V! I9 o9 n TRIS_UNKNOWN,
$ Y- o9 p4 |6 r2 G8 D: P TRIS_TRUE" G& h/ M/ M1 X# m- X4 n
};
' z/ r6 O2 i. e9 C
( w" n% {. S) c8 p8 u& ]3 n2 c% n2 Z. L/ K2 W F! s- k/ ?2 Y
enum UPNP_IMPLEMENTATION{9 T* F. o: P/ w. K# L, d Q, b. w$ s
UPNP_IMPL_WINDOWSERVICE = 0,
T& @6 w" l+ \, w8 {- o7 [5 a UPNP_IMPL_MINIUPNPLIB,0 g: b* E* b5 V, V; P3 ~
UPNP_IMPL_NONE /*last*/+ N% R, k2 d; i3 |; H! s
};
J* d- M4 B+ Q+ x h% V" G: c J! Y+ d: j. N3 C6 ?
- j' t/ x8 D7 X) T8 p
8 I' R9 g. ?6 u" e" ?: F! F
$ D) H/ D4 U: I7 \$ h. `
class CUPnPImpl; R$ S7 ~0 Y9 A v" K$ e! h
{
* x5 A- S% b7 A9 V: u" ~ z9 }% fpublic:: O( n) A1 r9 M
CUPnPImpl();
1 Z- r0 q3 _: f$ {6 K- `# P virtual ~CUPnPImpl();& }. i, d( z x% K, F8 m. Q
struct UPnPError : std::exception {};3 M% e8 r/ u1 y! c' z
enum { {2 y+ a) u* Y0 q" H3 D
UPNP_OK,
+ s" r. t4 ]) }- d) Z3 Y* m* r UPNP_FAILED,
! t+ O) i" I+ m4 x+ K+ i* P UPNP_TIMEOUT
b" k# b4 A! } j0 n: @& ^ };' u$ q! D+ M- W7 D- I
$ z9 ~6 }& Q# C( u' m9 R, Y2 {4 t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
/ X3 d" k0 |* ]5 b virtual bool CheckAndRefresh() = 0;9 U u. f% e$ t; G
virtual void StopAsyncFind() = 0;
# Q/ V5 q0 Q( ]4 v: M virtual void DeletePorts() = 0;
$ U) R: W0 y" `9 {5 Z3 w9 k, H) o1 @ virtual bool IsReady() = 0;
/ H- I8 h3 Y8 |2 p. ~% s4 F virtual int GetImplementationID() = 0;
: O$ S( z/ z3 @2 u0 j6 }
$ s3 {* T, E7 T3 \# Q9 }( L5 l6 m void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping3 ?( O$ D# b. ^" C' I
0 ], M. l8 d8 T) E. \5 j o" w6 Y0 ^- d
void SetMessageOnResult(HWND hWindow, UINT nMessageID);" G* i5 g0 @* @- F
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 J: E7 m7 ^* P uint16 GetUsedTCPPort() { return m_nTCPPort; }
8 I" y+ g7 D, b3 h uint16 GetUsedUDPPort() { return m_nUDPPort; }
) Q+ D, W. v: n2 Y% j; Y2 d2 q" s9 t
( ^, c5 M& D5 U: j: ?
// Implementation; t9 f" B# c4 x9 [" T0 ?
protected:
/ E* p- f) B& W8 J. s9 k" x volatile TRISTATE m_bUPnPPortsForwarded;
8 ?9 F3 B1 L5 w. Z0 R void SendResultMessage(); J+ S; d' _8 u
uint16 m_nUDPPort;& r3 _+ B/ a% [1 T+ Q
uint16 m_nTCPPort;$ Y8 u/ F/ V( z+ g3 l) {* Z
uint16 m_nTCPWebPort;0 b; O. Q* K" t( K# Q; B3 n1 l: g
bool m_bCheckAndRefresh;
/ ]# n6 ]3 ~1 h) C$ ~
, X; s7 v' b* d/ m, O5 v4 J4 O R" a! p% L) a- D- k* K
private:
1 l; H: o% L/ q# ` D; I HWND m_hResultMessageWindow;
9 B3 V7 k( T$ k( Y, s UINT m_nResultMessageID;
( [5 X u+ B. T
# ~( V3 ~+ N+ T0 Y1 T( {9 [4 l) h& Q- ~
};5 Z8 |% }3 g) V
' S2 M: Z; F* K) q, H3 h7 F# T! \7 V4 T: J5 N- Y# n* I
// Dummy Implementation to be used when no other implementation is available* _* ^8 H! {$ E4 u
class CUPnPImplNone: public CUPnPImpl
- x) d: T7 Y# u+ ?{8 Z- T" M, T9 w2 B8 M
public:
- ?) r/ E: b- w y$ c: c4 S virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
" A. f4 G6 w9 u+ E virtual bool CheckAndRefresh() { return false; }) a5 J7 B- S2 p, j6 s+ d7 e
virtual void StopAsyncFind() { }* S( f0 u' q" ?! m
virtual void DeletePorts() { }$ H/ j1 q$ T( S6 h) O- y
virtual bool IsReady() { return false; }( _& X* U! i/ s$ g m
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }( c8 T R, B$ L7 y' G8 z8 H; B
};
~. E- c, M" w# P0 X& e2 b2 p' S4 N9 f) n" t+ [
' M) s% W; b2 g5 S3 N
/////////////////////////////////////
/ \$ i: Y/ L! y//下面是使用windows操作系统自带的UPNP功能的子类% S, f, ]' Q( c8 B
! j0 Q% \& O! z8 u. P4 b0 L4 c- e
7 l/ x# w2 L' U8 g, A& s* }' V, g#pragma once
3 j9 j9 R/ @9 y. q+ P#pragma warning( disable: 4355 )
5 S6 A/ w: M/ O; o9 s- k7 f
$ p! J$ W1 b; z5 ~& I- C& j9 p |! |% J) l* _
#include "UPnPImpl.h"8 I2 _3 i6 }& j4 t" \
#include <upnp.h>
! G$ s9 A9 p' M/ l0 _2 ^( B8 K9 Z#include <iphlpapi.h>
`1 s7 C* K$ ?0 i+ U" M#include <comdef.h>
4 g6 ]$ m l; q/ \2 K: A( D v#include <winsvc.h>
4 ~5 J! j! K" O9 H" s! p; G ~
2 N: W( [8 a }
) t0 y: ?6 {& {( f7 L$ F#include <vector>. C3 z% ^8 O/ c) e1 p$ V" _3 P& s1 @
#include <exception>
' e- q/ H( z5 _$ t4 R#include <functional>! Y* [: s4 Z9 H; r" K0 k/ l0 W8 r
. l$ K* j4 j, y! u# C5 w, ?
, G; b7 M2 @: G
& g i' T# g# I, W( w& @! M/ W
" W+ v6 \" v; O7 ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;# n5 c& B4 q' `& K* m
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
6 c% |7 q- l; X9 v0 X. Ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" D4 d; l& }3 p3 h1 ?% N6 K L0 d
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;4 p& z) C/ T; f- j* A. S
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;8 {( b7 ?3 o7 K! K9 d
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
3 F6 \- x0 R/ i) p- ]0 Ttypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
+ U" l2 ]% _/ }
" N3 u/ P5 N" c4 E4 n9 J( L2 A; M- f& j' |6 _7 P
typedef DWORD (WINAPI* TGetBestInterface) (0 @% I* p- m8 B! k/ z& P7 f6 f2 i
IPAddr dwDestAddr,, D6 n" G8 |" Q6 U9 h( z2 D8 ^7 z
PDWORD pdwBestIfIndex8 r6 O$ C. ]: o
);
' h( i7 o; N& B0 V' c
7 K f* X, _$ }2 O; n# R) N H0 p3 A1 Y! f2 }" D5 y
typedef DWORD (WINAPI* TGetIpAddrTable) (
/ P x$ X+ v2 g" W9 z% K PMIB_IPADDRTABLE pIpAddrTable,
' |. i) \( U1 `9 D: ` PULONG pdwSize,
- {! K8 U/ L0 `. c/ W- \ `) l BOOL bOrder
& O( M$ N! w$ H);8 U3 ]& z$ a6 i) E! @5 \7 Z
# ^! W1 D7 X8 U; ?! f
: i5 S$ a& ]% a# ^* Ttypedef DWORD (WINAPI* TGetIfEntry) (
0 O3 B. v0 o7 A( F4 b PMIB_IFROW pIfRow
9 x S4 A. D8 E. V);$ w- C- B$ K, H: ? Y
# p6 e) m; C3 g2 f F
+ d) K3 y2 C. J$ _/ g2 l; p# U6 h, j, W, h
CString translateUPnPResult(HRESULT hr);
: Q0 U/ j% w4 s; A$ U! {6 ~5 @HRESULT UPnPMessage(HRESULT hr);
* h; V7 m9 t; o3 O# H" Q) y1 K, j8 L8 D) y2 B# _
) t3 [8 G# r' v; i5 S: |class CUPnPImplWinServ: public CUPnPImpl7 O! l' j8 M6 h' e- l& R. x1 }! T
{( {* u4 y7 Y9 l8 @" ~: l; U
friend class CDeviceFinderCallback;
! @" i. l( ]' ` p+ w# r% C friend class CServiceCallback;1 c" ?( W8 ?. q$ m. I
// Construction) v' @3 \( I+ d; Y
public:
2 ?2 b) o& N: g, m+ q5 `( D/ X0 i virtual ~CUPnPImplWinServ();
% i& B5 M- g0 v6 V: ^ CUPnPImplWinServ();0 [( g% L4 O% H% P( D
; H V& a: R) O- E1 u9 z2 B: C: e- O; Z# D3 w
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }9 n% \3 A2 C; E3 O
virtual void StopAsyncFind();- p$ k q8 `$ i% G
virtual void DeletePorts();
# q: n9 |- E+ j" D- v: B virtual bool IsReady();# H/ _2 ?; ?7 A. s
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
* K: c$ c( Q7 R3 k( _7 J1 L
6 W+ Y% Y8 x( B I( f( |' [5 o5 x' y( f; {% C
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
; K& P5 f& p$ r& d6 f6 a" o2 Z, { // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
4 h# |, ]* j+ @2 R# ] virtual bool CheckAndRefresh() { return false; };
7 I$ A5 c; U% e4 ^8 e K( R! R! A+ H# h7 k$ L4 }/ @0 ?- z( l' r3 J
! p' L* w$ C+ ]: g3 {' v0 {protected: r6 Z+ C3 J f5 K S4 r( c
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) ~! ~1 i5 p) l- i) K, x0 a( d, V' J void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);" T U' n% W, q/ G8 T: _
void RemoveDevice(CComBSTR bsUDN);% Y6 }/ _" F4 d5 t O& n
bool OnSearchComplete();: p6 ?% j; U! R; c. V6 l! V" H0 C
void Init(); C4 y c( m, U6 }' T7 J. @# R
, O5 E2 N S+ H* z& Z
: ^9 O4 l# t1 p4 A inline bool IsAsyncFindRunning() " r# @$ j+ p7 B( r
{
* e! W4 R b, Y if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )& w" Z9 B0 f* \( I/ O+ ^( v
{
; E6 H; y3 p, ^' e3 W! z; j m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
* p$ E' u4 s0 d& F m_bAsyncFindRunning = false;: j2 f, K1 W' P
}
& K6 y9 V) d z/ R, B$ X, T MSG msg;
0 I W+ z5 p1 R: e' u; Z. L% W while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
8 X! l6 M+ O9 {4 p {( W6 N; t# o x. c+ t- V% a
TranslateMessage( &msg );* l1 v- x( q+ n- e$ |7 U% x
DispatchMessage( &msg );$ I& G% A4 f6 x' ?4 z. e
}
2 M& H) p8 N" G- v& C5 D5 l return m_bAsyncFindRunning;
* Z) R: c8 D5 s' ~# y/ G: R }' E7 T2 r" c5 W+ Y/ l( k0 M; w6 T
$ ~' ]* v a. |+ c/ B1 W* b- W x1 n. r* V. ]4 h
TRISTATE m_bUPnPDeviceConnected;
1 ?( N6 }* l ^0 \
+ a) z. v& Y4 M$ g2 [9 C6 c2 N" G) {& }" B# s
// Implementation
9 d. t5 S! C( e& C& D // API functions5 ~; |$ I7 ]- Q0 @3 O
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);: Y5 D5 `# [/ {* i+ e$ Q
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
0 {5 X! t' ?) J- m! e3 M8 a BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
" c& R7 O! ~! b BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
; U- {3 }9 F) T7 E+ x BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);+ j* Y* e5 @' {1 Y" M; s ?
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);& J0 f& q. e D9 x; O* U
3 b- L% B5 J# \$ D; r
' U- r" |/ ^& i4 G TGetBestInterface m_pfGetBestInterface;. k3 N4 D& w* c9 W l$ _3 Q1 r0 D
TGetIpAddrTable m_pfGetIpAddrTable;
- T# y; A1 y- @ TGetIfEntry m_pfGetIfEntry;
4 W! ^( i. I1 }& V8 L
& G# J3 c; |6 S2 p3 a- V* y$ W- u7 R! Z4 o2 x0 z5 M d
static FinderPointer CreateFinderInstance();
# w: B/ u0 i* R% o4 [/ l6 y5 \ struct FindDevice : std::unary_function< DevicePointer, bool >% w6 ?) X/ v( j$ N/ q
{
' h) w3 |$ g6 P8 k FindDevice(const CComBSTR& udn) : m_udn( udn ) {}1 a, y( p0 w4 y
result_type operator()(argument_type device) const( G5 v% c4 H5 F8 k: e" }: J5 C
{! M$ a) K( |) v2 G: l8 ~
CComBSTR deviceName;' @$ N- L0 l% k7 c- ]! W# e, l9 n4 e3 t
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
! K- H% K- F3 d- P6 `
; v% L9 `9 L2 }4 J9 `4 d6 g: C( u$ l# v/ j0 {. k
if ( FAILED( hr ) ); J4 ] H: j" L; f
return UPnPMessage( hr ), false;
+ Y6 {& p. I4 u% \. h! D9 M0 U( `: ^" P* [) C: d
. P# |4 S" K, D% Q* t- @4 G
return wcscmp( deviceName.m_str, m_udn ) == 0;+ | V% a4 U+ O, v# J, P6 O! I- P
}
5 ]9 b0 ~* u* _9 c% O* t; U- G* U% a CComBSTR m_udn;7 s1 S5 [0 n: g( W! a) z
};
) d" J0 v$ S7 i+ ?' q/ T: e # l% \% H' K! v6 a% W
void ProcessAsyncFind(CComBSTR bsSearchType);" M; P& Z% y7 V5 v4 C
HRESULT GetDeviceServices(DevicePointer pDevice);
2 N5 \1 y* F' x; z# P( y void StartPortMapping();
8 W' W1 {3 S0 v V- W+ T- w4 ]- G, [- M HRESULT MapPort(const ServicePointer& service);: A7 n9 W. l4 r8 p+ h
void DeleteExistingPortMappings(ServicePointer pService);' [) [( ]( h2 i) C6 I6 l8 {
void CreatePortMappings(ServicePointer pService);+ n* k5 b% l. T8 @5 a
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);6 Z; U% X1 t; N6 s) k
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; o$ I' ?5 R- ?2 u0 L! h& S w& w LPCTSTR pszInArgString, CString& strResult);! ~- H' H! H! i' j; b5 z/ @+ i8 K- ?
void StopUPnPService();
* e ]5 M; o5 y7 e" u7 p: r2 U/ d5 X. G7 {% `. [/ O
$ u+ F& w1 |' c7 w // Utility functions
: J' _+ q/ h! N; q4 g HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);- ^5 V5 w" F4 g. @# O% l4 O
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
i7 M! }) Z# e% ?. Q INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);( ?3 s+ ?- |2 ^( g; g
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
6 I0 E! z, I3 U- W: b6 w1 A HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
1 F- `7 T& l- I- D( N HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
3 U* T% o( w$ r" ~* \ CString GetLocalRoutableIP(ServicePointer pService);
! \: e! n: F: R& Q! N+ d# i
* f5 Q7 L3 y* y( D! ~
, X- e4 T) }. B! X( K/ D8 l// Private members
: r3 I1 ~& C) e" I4 |private:8 p: o5 g2 {6 Q) |7 c N
DWORD m_tLastEvent; // When the last event was received?0 s: J+ S h- P
std::vector< DevicePointer > m_pDevices;* e; j' M9 w# t( X( v$ ?& j2 x
std::vector< ServicePointer > m_pServices;
$ R7 H& q0 s& Z* Z! m FinderPointer m_pDeviceFinder;: t: b0 H& V! A f4 ~1 y
DeviceFinderCallback m_pDeviceFinderCallback;* j- M0 E8 Z% y# r7 r; y; D" c8 ]
ServiceCallback m_pServiceCallback;
) e! T5 @, d h6 e+ b3 W8 o" n2 y5 ^. ^* Z+ H
! I2 G" ~1 {, s4 o* J% Y/ L LONG m_nAsyncFindHandle;
; Y1 K' S( o l) @ bool m_bCOM;) D. ?) M6 l% R/ q7 K7 C0 O
bool m_bPortIsFree;
- u5 A) d" }' o$ Q1 Q4 B6 N( T CString m_sLocalIP;
, I3 ?4 W V- o& e9 \7 P CString m_sExternalIP;& v" P4 W' M2 Y4 s0 I4 P% @
bool m_bADSL; // Is the device ADSL?8 D1 S% t. S: |4 @
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ j" T& }. [, [+ B8 ^8 K bool m_bInited;
?4 d: R* M% ~$ Q. }6 Z bool m_bAsyncFindRunning;
1 Z, x9 ]. @# Y7 Y! [5 \ HMODULE m_hADVAPI32_DLL;/ o5 `5 g+ L1 K6 P. D0 X9 T
HMODULE m_hIPHLPAPI_DLL;
4 [6 R9 k$ |9 _ bool m_bSecondTry;
6 h0 E" b& L" ~( F0 q' k7 }; K- d; n bool m_bServiceStartedByEmule;
( A: v- E( \) E+ I+ o bool m_bDisableWANIPSetup;
' |: R2 s4 R3 N Y: z$ G) V; V) b bool m_bDisableWANPPPSetup;7 c4 W7 K7 I5 U% F$ h6 h
% d1 t, G) `9 r: K9 X' @! h4 |4 U2 B
};; R: ?$ @3 k% K" d
/ C% D8 q$ U6 J# v1 `6 c
$ H/ \0 U3 ~) g
// DeviceFinder Callback
" \0 ^6 r4 y0 Jclass CDeviceFinderCallback2 d$ C+ A. N' g
: public IUPnPDeviceFinderCallback m- A, \3 Z7 ~% R" f( i5 v+ i
{ J5 ~, P, w, ~7 H6 F4 N( t
public:
& N' k p, O w7 d# N CDeviceFinderCallback(CUPnPImplWinServ& instance)
+ D5 P, c% i( T3 K6 {( s# W+ M# x : m_instance( instance )- Y+ a6 [2 b" O# ^ {
{ m_lRefCount = 0; }
/ ?% L: e c b7 J- _ y
0 u A) J* t# J! X5 D
9 j8 O6 |" v2 O& }# V. W9 Y( ] STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- _6 \3 Y1 G3 \% c* J4 K! ~& C STDMETHODIMP_(ULONG) AddRef();
# @+ A# A1 k$ n, D% Z! } STDMETHODIMP_(ULONG) Release();
$ g4 l8 }3 O% z' L5 j! M4 r7 u# `9 P8 l
7 o9 T' D. @* e! I6 Z// implementation
6 F( M h$ K, r* |$ n) i. a$ Qprivate:
3 u+ u) U: b5 \9 @4 V HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);$ _+ s' e3 F7 U
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
. T' _1 Z: r- c* e HRESULT __stdcall SearchComplete(LONG nFindData);
( V$ c1 O0 A) s0 S O& X; ^3 o. T4 f: f7 D
: q0 t2 [! J1 w M' Y/ x4 Q
private:; l8 {' A# C5 b- V+ Q( ^$ {5 o
CUPnPImplWinServ& m_instance;
; V# i5 h$ n* U- ^$ ^ LONG m_lRefCount;5 e$ l; q/ \/ Q0 C* `; k
};- j1 F" A% }' Z9 k
2 |2 b6 y5 G$ y- A
2 a- w: S, s7 T* R% }) i" J' [
// Service Callback
0 H3 E( ~( M( jclass CServiceCallback
+ d+ Y& J4 l% n" j : public IUPnPServiceCallback; x: |; z# Q) v9 B
{
4 Y; @2 S1 ~- X# A8 d5 I' Wpublic:' z( ^9 r" ^' P% ]! ^0 A$ L0 w
CServiceCallback(CUPnPImplWinServ& instance)
+ {( s: {: ~! K9 T8 v : m_instance( instance ). `4 N: B' V7 M5 a7 }
{ m_lRefCount = 0; }
) W: s: E5 U- T- W; P& [" K: l. F
" q: v: |. V% ^, E' [+ z/ @ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ v( q- [) T0 T! [ STDMETHODIMP_(ULONG) AddRef();& H2 B7 N& Y, {; W" p: V: l6 E
STDMETHODIMP_(ULONG) Release();
# e: b% T7 k! \0 f
+ W& |4 A1 b' a' O
5 f3 l& D% b' ~8 D// implementation
4 \" A8 F, ^8 {" Q* f B7 rprivate:6 N3 Z) d- d- C
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 m2 Y w8 K. N% d8 M: H3 z7 E
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
6 b" K2 n% }( N9 Y' V; Q- d: `8 b+ F$ K+ ^, o
1 B! g$ U2 B8 m7 |$ q+ w/ `; M
private:- \" i, f, q* a1 A( | h+ E
CUPnPImplWinServ& m_instance;6 j2 Y2 b. W+ [- D3 c/ z
LONG m_lRefCount;
`, g5 r* B) f" u};. j! b: J/ ?6 b- |- s
) c; T" g) [: y( C" |
6 M: s- B% Z- D n0 E- ?: ]
/////////////////////////////////////////////////
0 g+ q0 N# J9 a3 U. ^" P7 d/ h$ I: P/ S3 f4 R- T! A9 q
3 c) b# G( v: R% t8 k8 _使用时只需要使用抽象类的接口。
( S; k7 j# I1 p& `! X4 t+ aCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' _& D/ d( ?# e+ L8 h; f& WCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
9 [1 _4 R5 S, F8 r3 n! tCUPnPImpl::StopAsyncFind停止设备查找.
! P' Y3 r0 L0 D2 u6 Q0 ZCUPnPImpl::DeletePorts删除端口映射. |
|