|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,6 _0 x. r! y, Q& f/ |7 p. ^; o
1 s; j: T3 x3 {
c' X! v) M4 z0 `' K+ c' m
///////////////////////////////////////////
7 h+ [5 c6 G# x$ Q( S5 d* ]5 @9 S, `: W8 I//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
& e' ]% S, f$ O! b8 u4 O
- e4 S- P1 p- M% F! b" G4 u) G, z$ I0 C% X' ~+ Q9 w9 P
#pragma once8 E% o; P) C/ y; J1 L
#include <exception>
5 O( u" S* \4 O5 _; f0 z) e; e/ S1 v
2 X* _6 X2 L3 V" Y6 Y) i+ T enum TRISTATE{' h; W7 B0 F1 ?
TRIS_FALSE,
( S* Z+ N h6 Y8 G+ \- L, L, x8 W' J TRIS_UNKNOWN,1 g3 P3 s, I5 O; s; K! e/ g
TRIS_TRUE
) @9 Y- S8 X/ Z) i# I8 w b2 r s};
5 g5 W, |$ ?+ M$ Q4 n" J" j2 v1 {% v' |0 e& O6 C k5 V
# e7 f$ }" c7 i' V) Z9 Z
enum UPNP_IMPLEMENTATION{
& e$ C5 s) R( @% R4 B UPNP_IMPL_WINDOWSERVICE = 0,/ T% @: v: [- l g3 F. R
UPNP_IMPL_MINIUPNPLIB,2 ~: d6 V1 u# R) ^
UPNP_IMPL_NONE /*last*// J. N$ p& M' \/ A. S9 m" M" b
};
# ]: T1 b8 Q% r7 ^2 z% V1 p8 Z6 f v1 A/ U$ k' Y
4 B# r& c& H! E; p
/ D+ B, h& \6 k% E6 i6 r4 G7 J
, m& l8 D" l* K# tclass CUPnPImpl( X( ?4 c' J; n/ N
{0 O$ m a9 w/ ]8 U6 }
public:4 `$ [) w8 u9 h- k3 A+ G
CUPnPImpl();
# T" B) S0 ]' d6 w/ }$ f/ W! A, { virtual ~CUPnPImpl();3 e9 s& h# }% Z* q$ }" d
struct UPnPError : std::exception {};
u9 ]* T- E$ V# R+ q enum {& q/ [/ q9 k- A% T3 c
UPNP_OK,( _: N1 z# [9 S! d1 }1 H8 f4 t0 A
UPNP_FAILED,( [% D. a/ V* l
UPNP_TIMEOUT8 U: _3 T/ m6 J4 G
};
3 v: R& E3 Z, S/ Q
# I7 V6 n/ i6 p6 c# i$ s! I% b" c9 l+ {( A1 P5 g' l0 s
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;3 Q U1 p) ~: C
virtual bool CheckAndRefresh() = 0;
. ]9 Y) d' g% |- |, }( k* x# e! L- o I virtual void StopAsyncFind() = 0;
/ p) N: C8 y) I virtual void DeletePorts() = 0;) ]7 w$ s0 ]4 W0 Q4 S+ ^& W
virtual bool IsReady() = 0;7 i6 b5 ?1 v) q: b5 ?( G7 e2 M! b
virtual int GetImplementationID() = 0;
, ?* b8 p5 E: |0 Z% s
/ F$ t6 Z5 o/ f e; P$ Y void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ G; L6 M6 O E2 g; u( [, F0 R
; G$ l# s9 K( x0 ^/ K* {" n- A! c7 Y2 ]& b. T
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
$ B$ J, x' F4 t0 b* c/ T TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }' S$ G* u# B6 c1 z# {/ C
uint16 GetUsedTCPPort() { return m_nTCPPort; }
& x+ h) g% P5 i8 d uint16 GetUsedUDPPort() { return m_nUDPPort; }
' W) |$ u1 G' @4 ~' n! x( L7 J7 m) g# i9 v7 }9 Z7 q
( E# g$ S) c+ P, I' u// Implementation
4 w5 D2 u" g% Y2 Eprotected:
* L. `0 ~% N+ k. l( O2 [( U( y. C volatile TRISTATE m_bUPnPPortsForwarded;
* u# A% y5 f! z void SendResultMessage();
' d% [/ t/ e5 h. c uint16 m_nUDPPort;. I+ \$ n! J% ?1 Q* K3 X( s: j$ ]
uint16 m_nTCPPort;
1 }( d4 Q6 {0 C$ r uint16 m_nTCPWebPort;; T8 H0 i& `0 W: t2 V. c9 S( _
bool m_bCheckAndRefresh;
( ~; K* s: _% R; z$ O# q/ i$ _8 E8 T9 R+ o+ F
9 J8 V1 N( R5 e7 d4 E
private:( a5 ]& z; A# \1 D1 [
HWND m_hResultMessageWindow;
" t+ p; \2 [0 u7 [, @5 P UINT m_nResultMessageID;
3 Z9 m- G6 ?+ H% a/ t5 r
& ~8 E8 i3 q- A) X9 L8 b. u- k" C) @) `0 E3 `9 a
};
' D( j& y! c# w! i( X' Z7 {1 m/ p5 u% c7 {9 ^% x% f& R- A0 x+ t
& J4 |7 l5 x# n3 q+ ~. g3 c2 }4 [
// Dummy Implementation to be used when no other implementation is available' l* {/ L5 A+ D) g
class CUPnPImplNone: public CUPnPImpl9 a4 L& e# A1 ?" B4 q& I
{* f M$ L2 P) @0 B; x4 h
public:3 R m+ e; h! K* @$ n
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }- U( E; g0 ^ e) k: W( p! P, B
virtual bool CheckAndRefresh() { return false; }
* f+ d* x* Y( ] virtual void StopAsyncFind() { }
, `# L9 o' f+ { virtual void DeletePorts() { }. e% z# B. d* ^* s2 l" O
virtual bool IsReady() { return false; }3 J& r+ u- Z/ ^
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
. O$ z1 [6 k3 o1 }};0 c, {. [1 s6 C# U4 n
& L) R+ u, a0 v6 {
# ^. r7 t# I$ A/////////////////////////////////////2 b1 {6 | o; Y3 E& K
//下面是使用windows操作系统自带的UPNP功能的子类1 t6 A/ E h% A- |
6 B) Q+ m; }2 o9 [. Q! `% g& B0 \
7 R5 }! @7 W8 E e# g, V+ x- O
#pragma once4 @4 z, W& |/ Y% x2 k
#pragma warning( disable: 4355 )8 ^9 F. n* T0 H: U4 |4 ?
: e4 S$ x0 U3 {" T) j2 x# N& w
/ A& ~" j/ Q* V _( t1 b0 I
#include "UPnPImpl.h"
5 Y/ s+ J) S+ e! r% I! }- E: b9 r#include <upnp.h>
9 z/ T1 C2 r! @7 E3 s$ S. k# n7 ?#include <iphlpapi.h>
! W' V% ~' [5 V' Y' I; m#include <comdef.h>
; c% p- ]- I* A8 L) O#include <winsvc.h>
* |) v& g: A3 ^! l) T, Z+ ~- S2 ?) c( ?, d) L# s/ C7 x% f/ e% C/ @
; Y% Y. q' q" Y#include <vector>8 N2 A8 K+ g" M; w n- b
#include <exception>
' ?$ A# R" I; a! y4 p) i0 x#include <functional>0 `5 Y3 l1 V7 U4 X5 l8 I0 O' [
$ a$ |' q4 T6 p/ Q6 T& H& o! k1 C# c, m/ Y( R* R
8 c: `- u0 W$ s* Y' J
6 x5 s ^ s+ f1 H5 dtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 N/ I# ]) h# ?8 b6 y9 X1 @) \' M, ?9 Wtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;- P- }# i- O0 r+ x, r
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
, X' O: c$ F. j9 f9 K/ I/ h2 atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;' [' K: G/ h% H, X
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
8 u2 m3 U, D: \ L: u" ztypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;% R% g( g, D7 B/ q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 S% [( f' T! A# M4 a# U
+ d, R/ x. `5 E$ ]6 P' b! n; J$ ~& ? u( ?; Q1 e8 `8 @: p' i
typedef DWORD (WINAPI* TGetBestInterface) (
. w, |: I/ G6 A d7 }' E IPAddr dwDestAddr,
" f7 R/ s& b% ] PDWORD pdwBestIfIndex
( E) p1 y, m5 J);" @+ V- o `' T8 @
0 r [$ Z0 X" t2 {, @1 U7 y( w$ o3 [7 A6 F! M7 `7 M; _
typedef DWORD (WINAPI* TGetIpAddrTable) (
( a% @8 O% ?$ _% j3 b# w1 i PMIB_IPADDRTABLE pIpAddrTable,
% U$ z& ]6 y& d PULONG pdwSize,
1 Z% N' j* I! R1 F! Z1 ]+ i: X BOOL bOrder" A9 q |" `/ }, G4 B
);+ N) A' i. N, K! v; f
: B/ n% g: o, m# p. \4 w9 X; t, g; a) E; h. X
typedef DWORD (WINAPI* TGetIfEntry) (5 Z w9 a- T3 H, H, g
PMIB_IFROW pIfRow) R8 c5 j6 w7 K4 L
);
! v/ {5 F/ E( @! ] y7 g) y* R0 {. Y
! c3 ?5 ^- c: r& }1 g/ _! |
CString translateUPnPResult(HRESULT hr);- k' p: z7 }) `+ T1 W- H4 k
HRESULT UPnPMessage(HRESULT hr);
( {) e j" J9 S6 K& ?2 Y1 J, X w
7 ?( c) a4 C1 b; y0 i0 J1 l; ^2 S3 j
class CUPnPImplWinServ: public CUPnPImpl6 V4 p4 j3 N# V7 d3 W
{# t) Z4 o. U: z0 v5 |% V$ G0 x! c
friend class CDeviceFinderCallback;
7 T- ^; t) G) o, b6 Y% p& t friend class CServiceCallback;
8 `% Q; q5 i! }( H+ P! d6 N/ v/ T// Construction
; Z$ M3 K; I- }1 |public:, m% b$ |% O4 |, j- s6 G
virtual ~CUPnPImplWinServ();
6 X+ E+ V, m. ~ CUPnPImplWinServ();1 e5 X2 ^0 Y/ g- {% A: c
; b+ u$ a' Z0 R5 g5 K! Y5 ` A$ |3 m4 E* b+ m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }; C4 \7 O6 ~5 e$ V* t: s8 a7 J# H
virtual void StopAsyncFind();
$ K' }* G( E; m3 B% C: u virtual void DeletePorts();. a- {# u0 `+ B7 o" {; {" Z8 P
virtual bool IsReady();6 Q! g, x5 ~8 J" `
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; } @4 X" ]" w* h7 C1 Z) {8 Q
; w! q+ e& J+ |7 l# A
& f$ {: s% C6 f8 D3 l4 @" |
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. Q% G1 y9 y5 F$ ^: q' K: m6 c // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
' H# u. ^) b% Z/ e/ R4 _' D$ v virtual bool CheckAndRefresh() { return false; };
" w+ O @! v; R# V1 m: p9 ?) m* @7 P. j( D- ?
. A; R' y/ L4 |% l k
protected:' s4 _1 |8 ^5 {8 ~- u0 s/ d$ S4 Y
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
$ [, u, s2 d I6 q' ?, s X# o+ _ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
. s. }9 Z4 _ h void RemoveDevice(CComBSTR bsUDN);
" s6 Y( |! _& W( f4 a% ?" F bool OnSearchComplete();
& ?8 F4 T9 W4 G1 a; k0 Z void Init();
+ w7 y0 J) `# D& |% ?: t
& [# j' m% ?! P7 e) y8 V- u
9 V+ l# \4 [, B5 @2 {) A inline bool IsAsyncFindRunning() * q0 ]7 h v/ r
{" w {% ^3 D! W, F5 w9 s- E; W0 [
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ). {9 e4 X+ w* i0 P4 v4 I
{. ]2 q' o; q* a* r5 m7 A( {5 P
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- q& R9 Q3 D. Z. q m_bAsyncFindRunning = false;( X8 w) C. [, O1 o$ J
}) B: e1 }% z" u4 W
MSG msg;
* k$ J0 K7 Q& V P1 }, M" o3 M' q while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 \. i8 G- z7 q _5 T0 C
{
+ |2 {, q5 u9 N. @; Z TranslateMessage( &msg );
' W& x5 {8 S( }8 V DispatchMessage( &msg );
% a H+ N( M7 } }
( p, U! k9 L1 z5 } return m_bAsyncFindRunning; g7 w0 \ O9 u0 X
}6 j. W) n9 B, W& ]$ }0 K1 y
4 x {1 y- ?; u7 q& A# n, F4 P3 k
3 T* C; ?, b0 H2 l& e
TRISTATE m_bUPnPDeviceConnected;/ Z& c/ O5 I, G5 k8 L& }
6 T% R+ S0 S( D) c6 g+ ?; [5 \7 k; z1 z& v
// Implementation
' M8 k7 ]$ @/ Q( F6 N3 s // API functions9 n2 b# _+ e( X, b, b
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
+ R. l8 P- U- {2 p2 z& v: F d SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: D: U7 A/ ^0 i$ Y BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);" Y) K; V2 r" d$ ~; y1 G8 i/ G2 j
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);' q* V1 \6 v; H7 \, Q& D ^; C
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
) V$ O$ s: u' K9 t- [: O BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);% S* x2 y E) a# }+ U
0 r/ \) l, Z& p7 ?8 b. H& x+ |+ W6 l+ B
TGetBestInterface m_pfGetBestInterface;
% a0 \$ z% g) Q8 A% M TGetIpAddrTable m_pfGetIpAddrTable;# w3 a3 t; j# e% ^& k5 t
TGetIfEntry m_pfGetIfEntry;! v- f1 p3 X! X/ g' L4 \
- u* w2 Q# B( _' x# Z8 ?' r% L7 d: r
static FinderPointer CreateFinderInstance();
! {- R5 C! s% N( L struct FindDevice : std::unary_function< DevicePointer, bool >: _/ y/ \ o3 Z) T. D9 @1 {
{
) U( b$ I1 X. d9 }9 Y; f FindDevice(const CComBSTR& udn) : m_udn( udn ) {}: [$ n# ^( f4 s5 J* _$ \7 X1 x
result_type operator()(argument_type device) const
4 ?, } j$ Y7 x9 U {) ^3 U7 k3 x- I6 E. C! l+ M
CComBSTR deviceName;9 @7 }1 |6 {! e( i' f
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
% k/ Q ?6 q' Z. H1 Z% }# q1 |- a: m/ T$ S* ~( a0 K% w9 C" r
5 C1 U( I/ Q+ w5 ]: L" b4 a* s2 |
if ( FAILED( hr ) )
, Z) d6 h4 W! {; {1 O9 |! ` return UPnPMessage( hr ), false;. y' b- l2 {; m" W, I2 Q- a8 L
# R" E5 p6 y) Q' i1 n* N* k
1 C B8 U3 ~! v/ [ return wcscmp( deviceName.m_str, m_udn ) == 0;
: [7 l6 b3 g4 g4 L6 z4 V. e }
- v2 d; h% x6 H& e% E& X; s9 u CComBSTR m_udn; W" {+ {) c: w' E) ?6 S6 w M; s/ |! \8 y
};
! V$ G# Y# \( T$ f3 w2 @) Y
) |+ a$ ~+ V* q' \5 D void ProcessAsyncFind(CComBSTR bsSearchType);+ c# j( N1 }7 h$ Y8 U" l
HRESULT GetDeviceServices(DevicePointer pDevice);: q( v, Q7 k" o7 T& P4 S4 F. B
void StartPortMapping();
' a8 `+ ^: w9 K& E9 R HRESULT MapPort(const ServicePointer& service);
* e0 u4 D! A4 k8 P5 `, Q6 U, R void DeleteExistingPortMappings(ServicePointer pService);
, Q. A- ?( C! Q& P void CreatePortMappings(ServicePointer pService);
4 ]0 L; K. ~: @, ] HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* Q5 p J" S& z- M HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
" R% @0 g4 F# r$ o. W ]3 S LPCTSTR pszInArgString, CString& strResult);
+ I T* X1 `; g$ | void StopUPnPService();
- N! w7 X* B, b, |) G/ q+ `) R
/ t5 O* E9 f% g3 Y4 t
& C8 J' O% ~+ F6 _ // Utility functions
, Y( ?3 m2 t) ?# V: m: p' K HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
, w/ ?' G/ ]5 v+ B, o" _9 m INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, h- w( u2 D: R9 D. V7 f INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* z- s, ~. |; x( h0 E+ y1 e void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
% M. q" O8 Z5 y% i0 A3 W5 m5 b HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
8 b1 d, L J) P! s1 E X HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);3 S* N+ t" U9 d* p
CString GetLocalRoutableIP(ServicePointer pService);" Q* k$ O$ T/ u$ W4 m) l, f
9 N2 i2 | n- b: Z& W" O
" I9 l/ K' {+ B$ Y2 r
// Private members3 E, G' ~3 Q% j2 E J1 l p
private:: k6 _* Q* ^2 z- e Q1 ^* [
DWORD m_tLastEvent; // When the last event was received?
7 e- f# \1 M& t/ m std::vector< DevicePointer > m_pDevices;& \6 D9 J# t4 \
std::vector< ServicePointer > m_pServices;
' o/ ]. E. l: J5 X6 f. m3 b+ j) i( R FinderPointer m_pDeviceFinder;
0 f8 |2 V( V. M e DeviceFinderCallback m_pDeviceFinderCallback;5 a$ M$ B, q! z6 ?. n: B
ServiceCallback m_pServiceCallback;
" v3 e7 G% J- |, y8 O
% o5 T9 B3 v( p
0 z+ V) f- f& W LONG m_nAsyncFindHandle;
( A2 ~' z1 Q: L" c bool m_bCOM;! O/ K( l* w1 r3 _* P
bool m_bPortIsFree;
! S8 M5 C$ T* M1 f4 { {$ D CString m_sLocalIP;
. @3 m5 t6 |2 @9 a CString m_sExternalIP;7 ]" A% }# q* S' V- }
bool m_bADSL; // Is the device ADSL?
S" x% _1 P; D. B9 b% g5 n E" }/ m bool m_ADSLFailed; // Did port mapping failed for the ADSL device?8 T: ]1 S9 w1 \$ A8 V( r3 ^4 y
bool m_bInited;9 J7 J( D1 C" L4 w! ]- O, Y
bool m_bAsyncFindRunning;) B4 B1 A4 ^5 y5 W; G, }( o
HMODULE m_hADVAPI32_DLL;4 t0 o$ I$ f |- Q6 i$ {/ u+ X* b6 {
HMODULE m_hIPHLPAPI_DLL;- @7 L6 S$ _, ~, k
bool m_bSecondTry;
" m7 U, F' q* P, Y bool m_bServiceStartedByEmule;
, l% w/ ]0 n: K- ` bool m_bDisableWANIPSetup;
4 i! r0 \2 v# @ i2 ~& h$ ]# E" T bool m_bDisableWANPPPSetup;0 b( {9 m# d/ P* o
* e( R( {! i9 v6 i( @4 b( w) r7 }1 H8 @" m& k
};
. {/ g6 [1 Z! c9 N: {7 T' E6 J# V8 |; G' J5 w5 @% C) F
' D6 f) @5 M7 C# ^4 F// DeviceFinder Callback/ C: v0 L4 Z8 S$ J* N. N
class CDeviceFinderCallback
0 L- [; L& M" j! H : public IUPnPDeviceFinderCallback; V2 h/ b7 `$ o
{0 g H/ m; U5 {0 P- N% V
public:- Y8 p( K1 B4 J( G4 D' J- Z. h5 g
CDeviceFinderCallback(CUPnPImplWinServ& instance)$ c% m# `4 N" R8 x3 E- g9 ~5 _! h
: m_instance( instance )
' ?( d0 n9 s1 t { m_lRefCount = 0; }
4 Q( W" ^9 r( I5 l) t" p6 W
- ]$ G/ x; I2 @$ _% n8 O
! E7 j1 Y" c1 B1 @ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 k' x- E6 Q/ f STDMETHODIMP_(ULONG) AddRef();; O1 [) J- M; ]* Q
STDMETHODIMP_(ULONG) Release();
7 e! J0 M3 M: J2 L0 ^7 l! `3 S6 M* |% x' [1 }
% s8 M/ J! h" l" o$ N9 k* v
// implementation% d0 [1 ~9 n! g- W. d/ g A
private:
# K" N4 t$ _3 \% j HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
% V7 Z" Z8 T% ~1 _+ O# ] HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
0 Z; t* P! I* o- k8 ?- e HRESULT __stdcall SearchComplete(LONG nFindData);
: m( Q8 a v* v" Q$ Z1 l/ i0 i- E% C8 q5 ?# S/ s
3 t7 G. _1 M- b1 |
private:2 ?- N' `0 Y k
CUPnPImplWinServ& m_instance;
! U, ^3 g0 c4 B$ W& q+ G LONG m_lRefCount;
! j# ]) t# n7 ]% x/ }, |};0 T% L; {1 T) C0 E4 i; z
" i; y0 A3 }2 A9 W$ |, L6 e0 A7 `' J0 K. X9 M8 i0 v y1 P8 B8 |
// Service Callback : X! s& Z) c' P$ _: X
class CServiceCallback
* f( w; S/ N+ H. c : public IUPnPServiceCallback
; a9 k o. S2 c{
9 a; O" k0 J8 \: opublic:3 @4 v# l9 m0 Z7 [: N8 B
CServiceCallback(CUPnPImplWinServ& instance)7 f5 v8 |" N' j4 U$ ^
: m_instance( instance ): W9 R" e6 ^9 L6 G4 |! T
{ m_lRefCount = 0; }' U* ~# ?2 d% `+ b( {2 W" J+ ~( j" V
4 F) [$ w) Q$ f7 X# ], C9 o STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" C8 X: W) C6 y# S' f! o0 Q* l
STDMETHODIMP_(ULONG) AddRef();
$ l3 B3 y) I0 l) Z STDMETHODIMP_(ULONG) Release();
H1 M. N5 w6 G8 A& H8 B* }. O6 \ t8 U# ]" r' z4 Z4 X
0 C" J3 j0 p- e r7 ]/ p0 w5 ]' q// implementation
* a3 [! b3 r. d# s% w$ m, U( Mprivate: I+ P; a5 `$ v$ q, T6 t( A9 W
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);- E/ ^# g! y4 p4 V
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ o, k6 F# V: v) B& E( r5 c% z4 i! }: g
6 d7 U5 Z; b; T9 z8 z
private:+ i5 }/ H9 p: t
CUPnPImplWinServ& m_instance;& E- d; U! t: M( W) ~* ~) U6 y7 m
LONG m_lRefCount;; d1 m3 J, a1 S/ q2 `* o
};
9 l, T" F; N7 ]2 o6 r; D
/ y, v+ h1 h0 ?0 T$ M4 r% t
. b4 B. `2 d; @4 Q8 [- V) w/////////////////////////////////////////////////8 V H' T0 U" v
! E, a8 `6 d3 d4 d" Q
" M+ f8 `! k; h; d6 f R; V5 N
使用时只需要使用抽象类的接口。, Y: Z* h" m0 C( k4 s* o, }
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.9 H1 T* f2 }% h9 |* e0 {9 s
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; ~& i d. H. a3 v: a
CUPnPImpl::StopAsyncFind停止设备查找.# Z5 o" _% I8 c8 ~1 \! t" [
CUPnPImpl::DeletePorts删除端口映射. |
|