|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,% Q; z) w$ m* \/ A6 c. f, i
! k2 N. N2 v5 J: _, |- s1 G, n4 p* g0 b
///////////////////////////////////////////
! ~, D3 s9 `1 r//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.5 Z! _- J: E. y* r, s, M; q
+ K- p0 d$ e. |; N, z* M E
6 s" [1 T. U# N; A#pragma once
5 x/ c6 b9 H, V* M#include <exception>
) V( v# r, h+ J. ?' n* W; }4 l5 t3 ~
& n7 D/ W; z/ U6 X, T2 H
enum TRISTATE{: ?: F* Q8 v5 a) G8 b. a8 g
TRIS_FALSE,
3 h( p1 ]5 D5 G; Y8 }% T0 @ TRIS_UNKNOWN,
! l# C3 R, y7 B& o/ p/ s) ~9 r TRIS_TRUE
. X( d4 _5 [& O4 M( l2 M: j1 k* C9 F};
" M+ I) ]: D e0 f' p& X% a2 a- G. f% z3 ~% E& j4 N
& _; `2 ?3 w2 N1 Y4 xenum UPNP_IMPLEMENTATION{
0 m! z+ x( w# S8 q UPNP_IMPL_WINDOWSERVICE = 0,
8 g) {& R% t7 L" q UPNP_IMPL_MINIUPNPLIB,: x6 }( J. P W6 X5 I& W
UPNP_IMPL_NONE /*last*/3 ?+ ?6 M& j- J/ H
};3 p" i+ x( W' C5 P! n5 P3 v8 Y6 u
. m m& i7 [' L/ E4 n
- l7 d/ s0 R6 E7 u6 `5 J$ U) z% Z
& i! a, s6 X3 H, C7 C0 Qclass CUPnPImpl2 Q. t! x* T0 I7 m7 |2 P" a# ]& t
{
6 I( ~* c! j9 n' \$ A, i7 \* R8 wpublic:' G( p3 N$ F3 }
CUPnPImpl();! x) U) B. u+ S* p; U9 d
virtual ~CUPnPImpl();
! i6 J7 h! x0 _3 r7 p+ P+ i struct UPnPError : std::exception {};
5 T% ^2 S; y& S Q; L8 [# P enum {
7 h1 ~+ M: S3 K4 P$ X4 V UPNP_OK,* z0 {6 j ^& j3 B9 _* x
UPNP_FAILED,8 U; K# q( ~: u2 d1 v* ^
UPNP_TIMEOUT% U2 H# `( S& q8 L
};! ~5 g8 {/ P3 ~+ s6 y
; M: t% O; _' `, ?4 | W# ?$ d
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
. p L4 y {" n virtual bool CheckAndRefresh() = 0;5 P- l2 H6 F/ ~7 s; R8 z
virtual void StopAsyncFind() = 0;
& T6 s3 P3 D" L Q s' M$ { virtual void DeletePorts() = 0;
* u, M% Q, _% @& S$ ~ virtual bool IsReady() = 0;
1 y6 f/ Y. f# l" f7 I4 H virtual int GetImplementationID() = 0;; b/ V, O9 i k! A9 c$ ^/ q
1 H6 } f. X1 J& k5 `0 B8 ^5 ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ K9 i# Q. N* Q' P! E% U0 y/ v" m& t
0 s5 i" M$ {% p; K2 P! B( i' j
void SetMessageOnResult(HWND hWindow, UINT nMessageID);3 m$ Y/ t- |8 G. q8 V
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
5 o5 ]% T9 k: N2 M% F( T& ?! \' w uint16 GetUsedTCPPort() { return m_nTCPPort; }
- H. R p' Q" |, f uint16 GetUsedUDPPort() { return m_nUDPPort; } 6 X" I) |3 d! k4 F6 m/ X# W% ?
5 O) _6 G4 W2 W. G! P
# O. y: c' y0 X* u. E, [3 J- w R. E
// Implementation
/ o; {! K' t+ k# p! V# Bprotected:( x. ]3 G8 p/ N2 ~! M% O
volatile TRISTATE m_bUPnPPortsForwarded;
. U9 N" D5 b- E/ D& ^% x t, x void SendResultMessage();
% U6 k1 D" N* `7 Y3 ]( p uint16 m_nUDPPort;
$ w r5 u4 @7 g( r& D! L% b& C' o5 Q/ b uint16 m_nTCPPort;2 w/ n! I. Z# u: D! [; p. [5 L
uint16 m_nTCPWebPort;
. ?1 L# F# r! f bool m_bCheckAndRefresh;
1 K$ b& N7 P" q/ I6 n
. Y. p) C: _ e9 \9 ]8 l% ^# F8 J M _& @7 I
private:" Y( X9 ~- |$ ?( J( l I; c4 H
HWND m_hResultMessageWindow;
; c2 v6 c3 N# l1 j" f- B UINT m_nResultMessageID;, E" Y6 l& u* H+ b
2 D4 D, E% i8 P" H3 M" g
+ @ j- b3 p! t6 C};
) W* o& ]# ~* |! D
m6 p: @) c; _7 ]/ f* H5 s5 I: f8 I4 y6 g8 ]
// Dummy Implementation to be used when no other implementation is available
/ K7 x7 e/ [$ I: P: M }class CUPnPImplNone: public CUPnPImpl
6 ]( A5 X) e7 g& R& g) f2 R8 j$ x/ c{
$ P+ c4 ?9 s& W- Gpublic:& h' @* q7 H/ T! q: z% d8 ~
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }& i$ k1 J1 L) q7 ?
virtual bool CheckAndRefresh() { return false; }& D8 G. D/ C1 q6 Z- d, y2 A
virtual void StopAsyncFind() { }3 f: x/ q. Q0 c: H: e9 o) h1 W
virtual void DeletePorts() { }
- F" q3 m0 T6 D5 m* y virtual bool IsReady() { return false; }
' n0 i Y/ N( z I. [, ?) M virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
4 y' v- N! I5 f! r0 j};3 `1 g8 c' G7 {1 Q
5 B5 J2 |9 _" m7 C4 J7 O1 Y
3 F0 Q9 S# o4 o
/////////////////////////////////////
/ T# A- n$ T! ?2 J; p+ C//下面是使用windows操作系统自带的UPNP功能的子类' Y' [% f* w8 y$ f
$ d0 y8 b4 X2 O6 c- b* |% O
) s1 T% ? V: s4 u
#pragma once/ z# M3 K8 f; `" c2 ~* r+ q4 j
#pragma warning( disable: 4355 )
* v1 e/ q% u- T
' P/ t |3 I# V/ P: M; U( ]* d
6 l0 ]2 P$ c2 i4 s#include "UPnPImpl.h"( D& C; _+ h b0 ^
#include <upnp.h>
' o0 g& f5 j9 [. J M& m1 j#include <iphlpapi.h>9 t0 Q6 a7 J0 }; k. t
#include <comdef.h>+ X% i( c! Q0 G, R
#include <winsvc.h>
, |6 z5 v; {! y
' D- ~$ n, V) c8 `0 }" p0 G2 w) }0 d+ S4 e$ a) H: k7 [4 A
#include <vector>
% K! E+ I8 b9 _2 a9 q#include <exception>
3 D5 k3 G5 ^6 g6 i2 v$ ~# l. r6 w#include <functional>- c6 Y$ X" d5 v$ {
3 Q$ O1 T- p5 [5 n% n
4 U- e/ Y9 D3 N0 U+ X5 f" ]
- l; o0 [. R$ f4 x; ]
, z& G7 ~9 x( ~9 \typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
6 @# \( ]4 C: Gtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
/ T+ y, O' p" j2 Ntypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
! J1 }. @) {- W4 u0 p$ ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! B' i: O% a, P! t, C% ^; h0 j: S
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
1 Q2 |8 J' z3 C; f; o* l6 T- _typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
. e) L4 q& |; J- I" p5 _6 X Ktypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;5 s* O- [" A. ^: H0 A, E6 M) L
2 n. T( ^; N' J/ n0 a
( \( e8 F0 j( A: }typedef DWORD (WINAPI* TGetBestInterface) (/ n5 C/ S) y7 w- g* T7 B
IPAddr dwDestAddr,5 K2 W6 C" E$ \7 z
PDWORD pdwBestIfIndex
$ @8 X; u# U, M' K# f9 |3 \" [);
- l# B/ I# v( j* @+ C) ^% n$ ?
/ [# S: y) k( v' t
' n1 v# N) Y+ T2 a2 O& Htypedef DWORD (WINAPI* TGetIpAddrTable) (& T2 c* F; I8 [' q0 Q) A* J
PMIB_IPADDRTABLE pIpAddrTable,; p/ B0 @3 j2 V+ w
PULONG pdwSize,
/ b0 S5 w* S" C; {2 M: }* e5 Q5 o BOOL bOrder
- q2 C7 D. {! n; Y% g4 c+ F: B);
4 x1 x+ a) T6 e' m$ [" \% e$ Z
5 f2 Q$ r) B1 _. h0 z+ i$ n
. e: {/ C* |% i2 G5 I% r( [1 qtypedef DWORD (WINAPI* TGetIfEntry) (
7 E6 D, X6 m( B PMIB_IFROW pIfRow
, K; o& W. e! f# V0 H* ?8 M1 T);
+ \5 u) Y2 M q p! I
7 v8 e0 w1 P) v* L- o3 j7 G: S0 s' U* U4 E1 E
CString translateUPnPResult(HRESULT hr);9 @0 z+ `% s& {1 V: P* G
HRESULT UPnPMessage(HRESULT hr);
; n4 S7 p. E: |( G! j
5 ?( m. j3 q$ c- j; ~4 f: H% Y7 W% d& I, g% a+ c5 K! ^
class CUPnPImplWinServ: public CUPnPImpl
! Y3 L+ \ B% y! H- `, C9 b: M{1 Q- T/ q$ q( \% a& ^( Z
friend class CDeviceFinderCallback;
- v2 }& O m+ h! k* e) w' Y) ] friend class CServiceCallback;
( F' k; t* X1 w3 q, O2 W// Construction2 `# Q& q" \7 L5 z- T5 z
public:% m# s& Y! }* t6 x6 }8 V" n! X- L6 O
virtual ~CUPnPImplWinServ();( r2 n l: p1 K
CUPnPImplWinServ();
3 [* o ^) |* w! q4 {
* u h5 a/ ^# a; h5 {( x( y6 T/ Y- {* Y1 b/ @, T O3 D7 k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }& u( @6 t' z4 G8 a
virtual void StopAsyncFind();
& `* F- ?5 N$ p virtual void DeletePorts();" M5 B0 s8 F! F
virtual bool IsReady();
3 p T, S; p; a# K4 P8 d virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
6 x& T( n( _. ]; A' e f1 j, T6 m/ F; R2 P5 L ?( t
* L; p7 R' A9 u; i3 P$ ^/ l4 V // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)( C! f) w6 M( @4 i1 u
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
- W e+ K0 A! m. `( K1 d virtual bool CheckAndRefresh() { return false; };- ^( Q* c1 k6 c
0 n/ k* @- u' a4 U8 m% {
% c: ]; `/ T. j& uprotected:& z8 y5 _- a& {* F6 K
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);2 e' c3 K/ V' i
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);$ n0 \; I+ u1 ~, M% U
void RemoveDevice(CComBSTR bsUDN);
( _( U( z6 ?3 z2 P bool OnSearchComplete();; @6 t( }! L. F o) _
void Init();
2 O1 B; F7 L1 q6 T/ S, G( l
' o W" s! O* @! x3 G4 n
" T0 c' X" d/ L y# Q inline bool IsAsyncFindRunning()
9 x+ \5 N j4 l( {9 j+ `/ } {
7 J% ^2 @4 v+ I if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )8 I1 ?/ X% {& Q6 T8 c" V
{5 T8 X* b0 S( m5 d5 ^
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );$ ]5 p% o3 h; d! @6 f, H- s
m_bAsyncFindRunning = false;
6 p) s5 n7 y+ G- I( `! p. z }5 e* ^% [! B) [6 H3 l
MSG msg;% R; g; U# ^% r- h
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
# K+ N2 G* `) U {& x6 s* [3 ~0 d0 D: ?. E- h
TranslateMessage( &msg );0 G u! W7 \4 l! U8 t+ t1 C7 H
DispatchMessage( &msg );
: _4 Y6 W. i3 |1 F& d) F } o: L( B& `5 ? m2 c* h
return m_bAsyncFindRunning;, e0 _8 \% x+ s) a- u
}
) J5 u; M+ X& n9 j# w, B( R! X+ e, ~! }" X
$ e$ u1 z; d9 Z3 X2 i
TRISTATE m_bUPnPDeviceConnected;
& Z9 V! W. U" }# ~; ^& ^. m) f& A1 ]9 ^
: t5 m Q) _7 W% k& w H N1 u
// Implementation! M4 t7 |1 h2 X4 G, ]
// API functions6 v: K2 d! y8 L
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);% D8 C$ l" ?5 w5 F' a" K3 h
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
C- O+ [2 G8 t BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);/ E& ^& H- p% x0 [$ Z' `5 g9 E! c
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);$ q7 k2 c: Y+ R3 I! p1 _" }4 j; G
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);/ _4 Z) s7 ?+ a7 i# ?7 f0 x
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' f( T7 H6 H9 e" p |! P
% C6 f6 y( C) G" M( O
+ o$ y: ]6 \/ B* C0 Q9 X0 Y
TGetBestInterface m_pfGetBestInterface;6 }4 U5 j& p/ i! T9 P1 }; b6 J
TGetIpAddrTable m_pfGetIpAddrTable;
( q; C' W4 o, }4 z2 c TGetIfEntry m_pfGetIfEntry;( @$ y) d* N/ M5 R! T _
( ^3 o: u0 a% K% {$ ?! |
& L# m" y! a3 ] `8 ^
static FinderPointer CreateFinderInstance();
: u% C* J4 m5 Y9 _ struct FindDevice : std::unary_function< DevicePointer, bool >
! i' F5 @5 D3 j5 v" u6 M! Z3 B {) O3 ^" m( h) h3 p6 J
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}' `% \5 e+ R' p9 J; Z* U
result_type operator()(argument_type device) const
0 n) S( e- S. e d4 g9 D f {$ E( G: l; |, I3 V' G& s
CComBSTR deviceName;4 A' ` T2 \- L' P6 Q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
6 I/ A# F* M; ]4 d( \: S9 s3 y$ m5 C: n% {9 \
& X1 {( S1 @( i, U' R; D if ( FAILED( hr ) )" k. T( @: N: d6 l4 K r5 `
return UPnPMessage( hr ), false;2 L4 n1 A% ?, i* v. T
7 g& _9 o# |6 X5 v4 |' ?. T/ X* L
* O0 `* c S8 y+ v* ^9 T! O( H7 ~ return wcscmp( deviceName.m_str, m_udn ) == 0;1 P0 h; z# E# b3 y) ^
}
; U7 Q, ~+ ?3 Z c! Y `) j/ O* z CComBSTR m_udn;
+ u6 C( S* Q: i9 I1 `) t };! q* s8 _5 f1 Z8 I W
& K! U/ I( |( q+ v" y4 p void ProcessAsyncFind(CComBSTR bsSearchType);# y( L, m8 N6 e! U) U6 d" _ ]
HRESULT GetDeviceServices(DevicePointer pDevice);
* n' U h5 ?2 c1 k$ o& l void StartPortMapping();
# m' ?' U1 K: b/ ~ HRESULT MapPort(const ServicePointer& service);0 }2 W# ~' w$ w7 k* h' p
void DeleteExistingPortMappings(ServicePointer pService);
) ?, D' r6 V" X" V) K void CreatePortMappings(ServicePointer pService);
1 s i9 x) T& q/ L! T s0 o HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
" y) D$ c5 m- y$ T5 [2 F HRESULT InvokeAction(ServicePointer pService, CComBSTR action, % d% } z$ I- o! D# ?
LPCTSTR pszInArgString, CString& strResult);' w0 {9 z# L X1 e3 i5 I8 ?3 J
void StopUPnPService();# e& K% T2 w( Q8 C7 m9 e
3 K; M9 g7 ?# q" B1 B& I' ~
0 U/ p' f. V) P o" o // Utility functions2 {, M& s' A Y8 J' h y+ R
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
) w. I3 s* Q- {1 r INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
Q' @5 I, k; x7 \8 r INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);- I2 N1 Y$ s: U# b
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; a# k, a R0 m" P3 Q: k0 s; i
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
w8 Q) U! j/ O& b; ?" N+ ` HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
3 @+ u0 L+ {. R# p/ O" E& O' t CString GetLocalRoutableIP(ServicePointer pService);
- Z6 s' ~: z1 y" s+ \, Y( h; H+ H/ i* A3 E+ n2 H$ G& q* e
6 l5 E3 o; p* w$ c
// Private members- q; S6 A5 ~8 V z/ l6 f
private:
8 Q- a2 v/ e' \& R DWORD m_tLastEvent; // When the last event was received?
3 {& A/ u! \) }* O" V6 {9 ^; y: \5 { std::vector< DevicePointer > m_pDevices;
/ S/ M1 K$ T- w, v3 W' | std::vector< ServicePointer > m_pServices;* U* I; {. y5 s6 ~! h% V
FinderPointer m_pDeviceFinder;0 v. d$ e# w3 z; G3 h7 i
DeviceFinderCallback m_pDeviceFinderCallback;+ y; L+ W/ s9 I
ServiceCallback m_pServiceCallback;$ V8 K* K9 i1 F+ ~
3 }) j* \7 p# a% ?0 n; S2 I |6 Q' D2 t N' A
LONG m_nAsyncFindHandle;: q* ]8 r9 A. J' w, ^7 i# M6 a7 f
bool m_bCOM;
1 ~$ i/ }9 d" [. l: x: x7 G bool m_bPortIsFree;5 i) ?) A$ g4 q/ M+ w. Z
CString m_sLocalIP;
! v+ X3 g7 t' ~2 C& y W CString m_sExternalIP;
. M" O+ C9 u" H bool m_bADSL; // Is the device ADSL?
& N x) s9 V+ X3 S9 B* W bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 B2 `4 O: J9 R* ^
bool m_bInited; D5 `) Y/ _% T( z; [: L
bool m_bAsyncFindRunning;/ W Y7 C' V0 ` H: L, o* `
HMODULE m_hADVAPI32_DLL;
2 P5 Z0 y1 w8 x; G9 P HMODULE m_hIPHLPAPI_DLL;, }8 o: d6 l1 L1 I) A( S
bool m_bSecondTry;
# Q0 e, G( I) L. d( P bool m_bServiceStartedByEmule;- g5 e0 U! C, w! [& W& z) E0 D
bool m_bDisableWANIPSetup;6 c% N: Y0 g" C1 j# T" _5 k
bool m_bDisableWANPPPSetup;- y) l8 p. s/ p5 U/ p
9 h: ^' |( k/ @+ ~
0 R( S& X) o2 b- i2 d, V};
7 [& u0 p7 o6 }9 g$ _: |4 P2 f& f# d% U; x% N6 |% _/ C* `# `
) Z; L6 p' m5 G6 H' n* N5 ]// DeviceFinder Callback8 T, u2 W/ A* q( X
class CDeviceFinderCallback( N+ }. |6 K* W- T
: public IUPnPDeviceFinderCallback% f/ Z7 T; J! o5 V
{% c. j X0 o0 `' n& k( w
public:
" V! _1 a6 q r. y: T) P4 ` CDeviceFinderCallback(CUPnPImplWinServ& instance) n. M& b4 U; `5 }- {+ i3 X
: m_instance( instance )
( c: Z3 w' M. _8 Z, X { m_lRefCount = 0; }
1 O- q; v! @, c+ ^) l$ h+ t. Z; e1 C$ _5 W( U" l/ n3 M3 @# t( T( q; P5 X% P
3 `/ H5 ]6 M, v" R
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 h7 }" m3 `; T4 r
STDMETHODIMP_(ULONG) AddRef();
) b$ ]+ c/ v8 e* A9 x6 [ STDMETHODIMP_(ULONG) Release();( f8 ], g3 b! @7 y* ]7 u: F
' E7 ~4 w* u( T& Y* n6 h$ z( t0 |, ^6 J2 w* P9 z9 b
// implementation
1 R$ D+ E. d1 D z% B. xprivate:
?: g9 z" M4 V' P5 g HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);9 g, y/ k; Y7 m) [# b
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
$ Q6 `8 v- ]% q* S HRESULT __stdcall SearchComplete(LONG nFindData);. Y. |8 J- v9 f7 A% W
: V0 i' h( n: t; _+ o! ?% N
. x, |, \- i8 f3 d& C: Gprivate:
' w0 m( g. V. L; B$ k. K! v* S M* |0 O6 P CUPnPImplWinServ& m_instance;
+ ?# L1 ]- b" v3 |7 p LONG m_lRefCount;
# l+ x" T7 P o$ l4 g};
9 U& S# n8 W" i6 d$ N9 F2 r1 W1 U+ [ _
) d5 ]: J1 ^6 ~, \+ F& x% y5 _6 @5 h3 `" T" |0 @
// Service Callback 3 d# |$ W( \5 J6 x# a/ b$ @
class CServiceCallback
$ f) ~& c7 f% U* Q# f : public IUPnPServiceCallback
( o9 f) n! F3 v. A# H{" h1 d% v) N$ _, w) F8 b& [
public:
0 f8 g o9 ~. U; L( u- p7 I" H) |; [ CServiceCallback(CUPnPImplWinServ& instance)/ C D1 W2 b8 u9 U+ b" F0 c
: m_instance( instance )& I* r7 [ [! [( T2 {8 |6 H
{ m_lRefCount = 0; }% A/ D. J5 ^9 A9 b. J
# y* z9 P& {; v9 J6 s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 u- [- n% a5 |
STDMETHODIMP_(ULONG) AddRef();+ @9 K% B/ L4 T7 P% N9 \! c
STDMETHODIMP_(ULONG) Release();0 Z8 R4 q8 j8 N3 z
# k4 w8 e! {2 S C; r: t
- N0 p* n7 Q% X8 h$ I+ t* \
// implementation$ v: }9 y- p( [
private: N6 o9 M s3 M8 J6 ~7 s
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
3 p2 i2 [* Z/ S* U HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
+ n0 p- G- u1 S1 U# i+ o$ |$ K; |) |7 v( M1 C5 H
! }* Q- d' y9 I1 G$ B& l0 N
private:
( u2 c7 z1 I0 f CUPnPImplWinServ& m_instance;
- V1 v2 f+ ^1 b9 s- l LONG m_lRefCount;0 G. v/ \% j) C1 l: j: K% l3 z L) D
};
5 Q+ H% J3 }$ c* [7 `1 u
- A. s" j6 g2 E% Q$ v
- k3 B3 \& t% S* B/////////////////////////////////////////////////
R0 Z# L) K) M. h4 g5 e# v1 D! I+ i4 B
0 w- K" S; M3 x$ d8 G使用时只需要使用抽象类的接口。) U3 ^; F% z; l
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
( {) B7 h+ B/ B& R M) f$ |+ h$ xCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! p7 h X* e% K2 i# L5 q
CUPnPImpl::StopAsyncFind停止设备查找.
) e- ~7 `5 X- j; e7 \CUPnPImpl::DeletePorts删除端口映射. |
|