|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ s5 e- j' q2 t! l
4 E7 ~) E& f: r
8 h' C; T3 [ [1 N( G///////////////////////////////////////////
, D' S2 V8 I5 \//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.( y. D: y7 j; @3 C n, l
7 g: s9 m4 F7 P8 u$ }7 k0 _
+ |; \9 N B' L8 O5 M
#pragma once$ g% R2 Y: b* F& E2 Z" s
#include <exception>' K. h9 k0 J+ \) h2 j" U8 I
) g2 f' i& d4 O- t0 O
j: }3 [+ x6 f0 }4 d enum TRISTATE{5 Y2 K; D5 {4 ~6 e
TRIS_FALSE,# L0 {+ A! E+ Q% \0 P. R" U
TRIS_UNKNOWN,- ]+ s7 B& |, c1 H7 a
TRIS_TRUE
( V$ i k. g5 Z3 ~, Z};
8 c7 K0 S- q. h$ O: I
# n4 @0 V+ i4 G( u' c' I; y# @3 P& V2 X& F6 C
enum UPNP_IMPLEMENTATION{. @0 S" _& B& e! u* D' H$ Q7 b# Q9 F
UPNP_IMPL_WINDOWSERVICE = 0,6 u+ ?6 h, C- a; a6 Y: R0 X) H
UPNP_IMPL_MINIUPNPLIB,
8 N& J0 P/ A1 h) [5 [ UPNP_IMPL_NONE /*last*/# Z/ I( c: b+ B% m% h
};
" h: L4 A" t. j* E( n& p( A& Z9 Z1 O
; O" y1 P$ z& n4 Y( b
8 y4 A1 u5 [0 e Y: P& p! }
?+ J* a3 V- k. rclass CUPnPImpl
0 U1 `) |5 v" J( |{0 W$ E8 Y3 b, q
public:
+ h! B8 D# G# R7 r CUPnPImpl();; M: A3 w, s& E p# V. a% |2 }' j
virtual ~CUPnPImpl();
V( v* ^$ K+ q% A$ o2 A struct UPnPError : std::exception {};
. L0 Q) `; e. F6 t* [$ P5 ` enum {
- t" c5 |. g* E4 h3 ] UPNP_OK,3 `; S9 k, Z! w* v- _; G/ T
UPNP_FAILED,/ F; r2 ^! ? F D; r
UPNP_TIMEOUT. k! d8 K2 }' Q: \% R, V/ i
};# \7 X5 D% c! V" [
% E* p3 x/ @5 `6 f0 c7 j* V9 I$ p
. _, X! J7 X4 t- H5 L virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;# o8 T, ~1 f5 C) S
virtual bool CheckAndRefresh() = 0;+ _# u }$ i; q
virtual void StopAsyncFind() = 0;
$ `& H+ ~8 z* W. p0 N9 v& F; _ virtual void DeletePorts() = 0;, F1 t( |4 B5 x: O% S
virtual bool IsReady() = 0;9 X/ ~% ^) f! Z+ Q9 W6 Y! f9 C
virtual int GetImplementationID() = 0;4 a* T5 b& X# a9 A
6 X7 K" h' L: ]- s
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping+ P/ t* i' b2 s; E, x5 D1 \
7 Y) Z0 a+ ]; ~2 a
. Q/ G2 d V1 i9 V void SetMessageOnResult(HWND hWindow, UINT nMessageID);
7 b' y1 I8 u' l TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }7 X$ e3 Y# N( ~3 n' l- q! X
uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ q" n) Y9 X) M* b" G( s7 J3 c uint16 GetUsedUDPPort() { return m_nUDPPort; } 9 U' s& R9 {# n0 ?4 N6 i7 C! ^, a& H
; F$ W5 \& ~4 k" A+ \! F6 ^
1 b! e# d6 F M: Q// Implementation1 o M8 z: G# r
protected:
' s# \5 a9 \( S$ ` volatile TRISTATE m_bUPnPPortsForwarded;
, d3 O* ?+ n) ~- m9 z5 q void SendResultMessage();5 g$ X! v0 x- Y5 F# [$ e
uint16 m_nUDPPort;
8 v; I7 Y$ I$ D3 n uint16 m_nTCPPort;1 D" q2 B' j5 i7 o/ y5 K4 b
uint16 m_nTCPWebPort;: T. f. K: ~. z) Z8 H6 D- s6 D
bool m_bCheckAndRefresh;
+ @, f$ \2 G; a y, ^- H& v8 |+ d! P# m5 d( _! c
* V9 c; b7 o |- t8 y4 K8 N/ k# b
private:
$ V3 N( j- X' x" Z" i; I HWND m_hResultMessageWindow;
6 b4 }0 ~. G1 o2 S7 l UINT m_nResultMessageID;& u; w' M1 g6 ]/ g, {
o+ ?* i/ y4 o0 w$ R4 Z
+ S9 h h/ g- ?};' A& }3 k2 ~ [/ _' J$ a, Y. A1 [
3 J+ ~$ [- @& [( i" F, a" K+ @9 b; R
4 p$ M4 f/ p$ ?! X// Dummy Implementation to be used when no other implementation is available2 [% ~5 c' J+ X5 J& I) p
class CUPnPImplNone: public CUPnPImpl7 D$ X8 L$ h' t6 @
{. q; ~. d) _/ ?0 R
public:6 C% J6 F+ w% w) w/ o
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: y; b: _ i% W; D7 _+ E virtual bool CheckAndRefresh() { return false; }# t6 j: q3 J8 y
virtual void StopAsyncFind() { }
3 x+ v7 e$ x) l. V- v+ S! Y8 n% B virtual void DeletePorts() { }1 K& @% h; {" s
virtual bool IsReady() { return false; }, z' t' |; Y3 W5 l; w
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
" S# H5 H! A2 o7 Y; w3 w& y6 d};2 j9 Z# P" b7 ]
8 F) F/ F# [5 x) i# {3 {
, `! m `6 E6 T* V6 w. P. ?' R
/////////////////////////////////////
: W% u3 f9 S5 \ D0 L7 G# n% f! x- Z//下面是使用windows操作系统自带的UPNP功能的子类
- F8 y6 K& P; `5 I' _- f( P2 I9 D2 t9 C
5 Q: x. B0 K& R( ~% u7 T' V/ H2 q. L+ t0 N7 W4 k
#pragma once
5 q% `% u! G" u* M$ Q! ^+ h+ e#pragma warning( disable: 4355 )6 R. w7 _) r$ g q' T
) P N4 x) q6 [' u0 y7 d4 |
/ b# h) }+ A2 P3 [* Q' ?#include "UPnPImpl.h"8 Y! X3 j; @# @# ?
#include <upnp.h>
& d4 b1 D9 w6 _1 {5 O#include <iphlpapi.h>. n) w: c+ M$ @% |+ `8 e. m
#include <comdef.h>& M( ^, o* W* b/ O N
#include <winsvc.h>
9 {) v; X6 X5 f! ~* B
% x A, @( @& t. c
! J9 Y& G: |! h$ s/ F#include <vector>
( x% [5 N; n$ W9 P. K: N#include <exception>/ q; S# N1 u, Y* ~( U
#include <functional>
1 k3 Y. n: ]/ u% H. ^& |( L7 E$ P7 X0 n7 h( `/ \/ z% {# @
& D% ]/ o6 h2 I4 ^: W" f8 q2 e
- h( X4 T$ ~ j3 V: R5 I8 W: h* |0 Z! @
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer; l) s' i6 p3 O8 f
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;. h( r. ?- z* w
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
% G" L! F# l' ~1 t! p6 q8 J; Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" d. c( G. e' B
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
8 Q9 ]! H2 G# T9 wtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;) a4 |1 D! {/ F$ i
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
! S! k. M9 o6 N6 ^# p) E$ ^
0 [9 E" h0 `4 m5 K5 V# b1 @; ^9 n+ l, b8 z6 ?( r3 o- ^
typedef DWORD (WINAPI* TGetBestInterface) (+ q. q# ]0 x/ \7 Z# q4 h
IPAddr dwDestAddr,
% H( x, e( f3 r2 [ PDWORD pdwBestIfIndex1 z* g& w; A7 }
);8 P/ M, Y6 {5 \* E
( E, m2 t3 I+ `. y7 N# S4 u5 I9 s; k+ O
typedef DWORD (WINAPI* TGetIpAddrTable) (# ^' @1 ~. k2 K) H& i
PMIB_IPADDRTABLE pIpAddrTable,
8 e8 x, j' y8 F" m! s PULONG pdwSize,/ h5 o. s& @8 ~8 t f* B" I
BOOL bOrder. A! ^+ ^2 U. h% ]" D: w$ [8 q ?
);
6 j1 L5 y6 @5 W D( r' V" [7 X
/ e9 P( L; o; b5 g% b' Q: @* k+ g' h+ K+ c2 ^9 l# N
typedef DWORD (WINAPI* TGetIfEntry) (1 h' n2 `( r# j% W
PMIB_IFROW pIfRow
& {) D2 s& L7 A);0 Q% q7 ~% R h ?
' S! D# u, P! B' S2 A/ m: s) k( f, b3 [7 n3 s
CString translateUPnPResult(HRESULT hr);
" `( g* }2 @# k5 a! b$ _HRESULT UPnPMessage(HRESULT hr);& W# \: } A) l: M- C
5 S+ Q0 ]% S) e+ o
7 |2 o r1 B$ u8 jclass CUPnPImplWinServ: public CUPnPImpl( H2 P8 G2 A7 v9 g5 ^$ J) M- o6 c
{
' r9 p" \9 W% n' [ friend class CDeviceFinderCallback;' Y' ~& G! `7 C8 q6 t- M5 G
friend class CServiceCallback;( e" G% t0 E8 t; N9 r- E" X
// Construction/ _, X% t# K1 V, u
public:
7 \# N) N: g) ~" `/ R: m9 g virtual ~CUPnPImplWinServ();% Y- E4 I. J9 L+ |- [- y. ^! D
CUPnPImplWinServ();
. n( I7 e' L7 N2 I8 k; _ j z/ h' }
; {" C2 C7 F8 J R$ I3 _! c virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
- `1 @% I* j7 G virtual void StopAsyncFind();
2 q3 A5 b3 X7 b; H0 ?2 p virtual void DeletePorts();7 x, ]) w% _3 u7 z
virtual bool IsReady();5 I9 A8 V* q" i
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
8 B! d1 V' j) f4 Z7 ]7 I/ g5 k8 J( u- v. c, W5 Q- X! B6 }
1 o: f: j! }3 {
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 ~/ J* v4 b& c/ e& I8 k# [" H // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
) p9 x7 s& f% K9 N- t; A2 C virtual bool CheckAndRefresh() { return false; };0 E) w2 c2 @6 ~# Z) A# \* p
% T: Y4 C2 d2 ^8 @4 S* s0 a5 H" p8 K+ x* [5 I# v
protected:: Q L* d2 D2 j2 e; B# l2 M( w2 D
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
5 ]1 t+ [* s$ a8 P4 q3 ^ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 D" A8 Q% V; R2 H$ Y8 G, z void RemoveDevice(CComBSTR bsUDN);
+ J! m2 G* ?; s! n& k2 e bool OnSearchComplete();: x" c$ X1 u( H" t/ H' y
void Init();' c' o% g1 t/ T
2 _. w/ q& V0 h( ]
* W1 |- Y, m3 `0 i$ k7 v o: R J inline bool IsAsyncFindRunning() 8 n4 r, ?! C a1 V c
{
" N: R3 a0 v- n9 {! Q" X0 e. d0 c if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
i& C5 U, B/ W" n {( n: w8 o- O/ d. V# ~" H4 o
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
V- S D& G/ @, t m_bAsyncFindRunning = false;
4 Z3 E3 o; P W7 Q. f" y/ ^ }
% X/ c6 ~: a9 r MSG msg;
4 k5 U6 [1 e0 Y. G while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
X" [% ~) u, W5 n7 T3 y {
2 c* Z9 d. y* O TranslateMessage( &msg );
: i' [8 p" d1 u! B% s" v! m% L: { DispatchMessage( &msg );8 G9 P$ H+ F' O9 l
}
' s- M/ J8 m- L3 K) E8 I- b return m_bAsyncFindRunning;* r5 J3 g6 m5 X2 Q: [
}: U# v8 A' _& F8 p1 W) r
0 D; x2 k: g* s) A
1 R- y" {0 m$ o* Q6 Y& ?' c# I TRISTATE m_bUPnPDeviceConnected;
" A- S+ G3 n( ?1 V8 E
7 Q8 D8 M6 n$ m; p1 H! \
; } d: @0 V. u% p+ z// Implementation
' `, S3 v5 i8 k- Y0 q9 G* t6 D% P$ J // API functions2 @ G' w5 d3 _, B
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
' v+ `& C) P4 t' M SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- z" _" ?8 Q" U) b4 z% u& M BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 S) r/ T9 U- k( ^. t6 ~/ F5 k, w+ L BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
9 x/ n: P/ b5 N* S6 Q% X" Z& p BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);$ N# C+ i+ m5 U' m
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
q" g7 _* D" E8 M& e R a
/ v0 `, j* ~# V$ e
1 {' p, J! m5 M- ^- R TGetBestInterface m_pfGetBestInterface;/ d W4 Q, p0 j$ P( q
TGetIpAddrTable m_pfGetIpAddrTable;1 O+ J) [, |: s# s
TGetIfEntry m_pfGetIfEntry;
& f( O" b- ~$ p/ w
- R9 c8 H$ h/ p
# U! ]# I2 t7 f# B( v9 f$ b; h- N* L static FinderPointer CreateFinderInstance();
2 i# q! {/ x" H6 O0 {& } struct FindDevice : std::unary_function< DevicePointer, bool >
1 \1 K! d% }/ ?5 e% k" G {
! e Z3 y! x; V* ~, A) [3 a FindDevice(const CComBSTR& udn) : m_udn( udn ) {}, g7 e' z7 n: t2 _9 ^$ R& t$ e
result_type operator()(argument_type device) const
1 X* S# J' I" E3 D+ S6 W; c8 m {, ~1 W6 R) a, a% l. Y. O( }
CComBSTR deviceName;* U* h) j X# S9 X0 r! h$ Q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );7 |6 i8 g1 |; A: @* k9 S
* d {( D& O9 O1 B
; |0 ^: z. [( h if ( FAILED( hr ) )
8 ~7 P$ k3 k& u) Q0 @. a return UPnPMessage( hr ), false;
5 B/ W- \$ Y }* x g" c* u1 ]9 i& ]+ t" y$ o8 c1 j. B
( V2 ~8 B8 h. J' D: ?& ?
return wcscmp( deviceName.m_str, m_udn ) == 0;% D7 } c# M# g6 f; @0 Z* J
}
}7 q D6 r# G# A6 g CComBSTR m_udn;
* z2 Z; {) z4 H' F" U6 }2 V1 v% a };
2 V; ^% m( V: X! ?0 V* \) Z; }7 A ! u. @3 h! H, i% S4 c0 T* {; ~6 i$ _
void ProcessAsyncFind(CComBSTR bsSearchType);6 y/ x# C6 \3 q( k9 S0 y+ C! D3 n
HRESULT GetDeviceServices(DevicePointer pDevice);
* \) _: z0 K/ H void StartPortMapping();! m6 q+ S3 D' d
HRESULT MapPort(const ServicePointer& service);
; w$ \9 c4 S3 Y6 u' o; Z! R void DeleteExistingPortMappings(ServicePointer pService); x3 i! J0 ?0 G7 L4 d5 e# y+ H
void CreatePortMappings(ServicePointer pService);
, a. f0 W; ^4 S F0 p HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( J) ~: N- m% C7 \( W, o5 ] HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 5 l: _4 H8 h5 n- p4 F
LPCTSTR pszInArgString, CString& strResult);
; b. f* Z+ H( k {5 M' U& f" l9 j void StopUPnPService();; d) r. Q! a" v
2 X+ T1 P Q/ m" t1 t( d5 j$ ?* e2 @ d* E. `2 z& c
// Utility functions+ G: l& ]: |5 J
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
" o* o, ?& u' L% E! i8 I5 l# y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
" \: L) P( Y" @( ?. e INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
3 e7 ?+ I0 w! N: i( [( [ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
1 Z1 Z, c- E0 E& p5 x) m% p HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* Y' g) p% F4 ?. x" W' N4 ^1 ? HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 h& J8 B" Y+ b! A. r7 d& L
CString GetLocalRoutableIP(ServicePointer pService);) D4 \. X. |6 M* R, ^9 ?- @
- V6 X; u$ z: j* [+ [8 e* ]' K
2 H9 j" K% \0 S) c. U+ G1 f# I// Private members+ Q$ o; j# b% {$ Z: D8 d$ P
private:2 q* U+ }$ U' d+ Y3 `6 z$ J1 [
DWORD m_tLastEvent; // When the last event was received?
& i: \8 s! \" j* a std::vector< DevicePointer > m_pDevices;3 v* ?" Q6 R3 [& L: { T
std::vector< ServicePointer > m_pServices;
+ f% V9 R/ F# q; T& t( b0 q FinderPointer m_pDeviceFinder;3 k: F! P. o+ |2 Y9 z; X' U, `" z
DeviceFinderCallback m_pDeviceFinderCallback;) @& s2 U4 N$ Y @. n R
ServiceCallback m_pServiceCallback;
5 s5 F4 y7 X) v" L/ D* q9 p. C/ Z
c( N0 A4 ?4 F) r3 o
' S2 O# x+ a0 D/ s7 y LONG m_nAsyncFindHandle;0 F) L6 N- L8 \0 G, c% Y2 _3 w
bool m_bCOM;* W3 t0 N6 M3 v9 J6 q$ o
bool m_bPortIsFree;9 Y9 T4 n }( {; @
CString m_sLocalIP;
/ T6 \9 v+ M3 w5 ^ CString m_sExternalIP;. o: f3 s: ]. j) k3 N- a
bool m_bADSL; // Is the device ADSL?
0 J7 ^6 c O9 V- [: Y bool m_ADSLFailed; // Did port mapping failed for the ADSL device?+ p2 ~( Y* g( V9 i7 G* U7 v
bool m_bInited;* n' X ?1 k9 @% N0 y7 Y
bool m_bAsyncFindRunning;
' a, ?4 e, m0 k2 ^ HMODULE m_hADVAPI32_DLL;! H% {4 a& W' O
HMODULE m_hIPHLPAPI_DLL;( w: A* g% r+ L4 @" L
bool m_bSecondTry;
* R. T- f! K2 r' w0 f bool m_bServiceStartedByEmule;5 N5 {7 T( B* B0 X: { X
bool m_bDisableWANIPSetup;
1 A3 r- f0 i# j& V4 W% u* }( ]: A bool m_bDisableWANPPPSetup;. I- l, V- J6 g- D
' L4 [+ a$ R) L: l t
8 Z: Z; i2 v; |) w; A};
L2 a. E" C) h; k; O0 q0 [" r
" x- y: L% v( ]# v. { a9 w% P+ n" G/ u2 x; R P" X7 J9 G! ?( A
// DeviceFinder Callback0 x6 @3 y/ Q) r7 D
class CDeviceFinderCallback
5 C9 g! f6 a5 |) n% j4 q( D : public IUPnPDeviceFinderCallback6 x$ ]3 h# h% Q2 ]" X" r \
{: o7 B/ c* k1 H9 M! `' i9 t
public:# \# [$ X. \& K( |9 _' @; Y
CDeviceFinderCallback(CUPnPImplWinServ& instance)
. W' c# G9 ^& X4 r : m_instance( instance )6 Q, G; f. C7 c/ Y- x
{ m_lRefCount = 0; }
) P9 g9 H& }" U1 h5 U" W& I
- G3 Y! R, b9 u& u. O3 x: |4 g
$ A6 _% W# d' e+ R+ g3 l, v STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 x. d! ], G7 a* V( r9 z0 F STDMETHODIMP_(ULONG) AddRef();
! m8 a1 _' E& y) G2 B1 `( U6 H STDMETHODIMP_(ULONG) Release();. @2 @, F+ U; K9 D# }# p) M
! }& M, v0 o: W1 A) W' t- Y
! W6 R; A* E& e1 U" Q// implementation
, O" Q+ u1 e$ F0 X) Wprivate:
2 b) |( ]* f* W/ K5 W HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
7 Z2 r" h; O) n HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 |& R/ K) F; R HRESULT __stdcall SearchComplete(LONG nFindData);
- h8 F8 J$ p; K% T7 `
4 u+ P0 r k2 t! o/ b0 |1 [" P3 f }& w( _2 B5 j6 h, l! i
private:1 C! w: L# ] Z$ k/ e! q$ f
CUPnPImplWinServ& m_instance;
- e) i( X( n. F) y+ q LONG m_lRefCount;
+ g. L: a, h6 X- J};
9 J0 ?/ `9 h& c7 o, x! o+ _% v
9 T4 ?4 p N/ i- Z8 }4 `* i, ~/ d. x
( x. g* o8 p' w// Service Callback
) h5 |! Z# c% r6 m7 Qclass CServiceCallback; [3 B% R& c. `' p' L: v, Q3 ^
: public IUPnPServiceCallback
. I+ I" [5 m+ w: O{( O. h0 r& K9 \( C! Q0 L
public:
! Z5 a1 F- b1 o CServiceCallback(CUPnPImplWinServ& instance)
* k& k: ` i5 e' V, e : m_instance( instance )* S5 R/ E7 u b6 p* a3 C
{ m_lRefCount = 0; }1 Y9 C u/ [. n
) w4 y2 g) y5 m/ I STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 B9 t( U7 [8 }: w8 {4 `; Y
STDMETHODIMP_(ULONG) AddRef();* P1 v# |! K i+ j
STDMETHODIMP_(ULONG) Release();; _8 [6 P/ T( p9 Y1 q. A
1 N/ c, z: R7 P: f/ p# O
% l. M1 E' J- o$ Z$ J4 l# b
// implementation2 N7 a2 s4 [. {4 R
private:/ K, c6 b( b7 E9 s
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);3 J; e/ d. v5 O, e" v7 K4 k7 p
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 u: b# G+ l7 q% N o3 A! x: J- ]1 g) \+ b
Y r3 ?# a a; _3 B8 M4 M& Y
private:
3 Q, I. v* U4 Y; L, P CUPnPImplWinServ& m_instance;$ U; x! p8 Q/ L- X2 b/ x. s
LONG m_lRefCount;: f4 J" n$ S8 M- _- k. Z9 M: v
};
& f+ q) b+ u: w' m6 P5 H1 `3 s" a4 j; l- x) V; J
1 f, `! c6 g' L- T2 T/////////////////////////////////////////////////9 w8 A0 Z; g+ M7 q" d* F, Z
1 R, F1 c) _* P/ q, r8 u7 j
4 z) H9 m( x: Z& A& d, K使用时只需要使用抽象类的接口。) {+ `4 e9 _- g2 Q" z" V% }4 s
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
( q9 I3 D- T+ H) S& D* L" @" ^CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.8 ]6 [2 g! N+ n" z
CUPnPImpl::StopAsyncFind停止设备查找.9 [* B4 e) C: \2 o- o
CUPnPImpl::DeletePorts删除端口映射. |
|