|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) T% D6 [4 N6 [$ Q% o7 Y
* Q/ ~$ M" N6 A- l
4 v2 O) K: D* O& @3 w- e///////////////////////////////////////////
P ]2 I9 V2 Z% N( m" J//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
, @+ q* Q3 g: I7 l6 j" M
" k7 I/ m7 ]4 M' c$ l" b( p; ^3 @0 V0 e3 N- \
#pragma once/ q4 K. K6 G. Q9 e
#include <exception>
/ K& |( ` r3 q" ]5 t! l& D
2 r% b1 \/ a9 ^- {. z
: \5 z% m) t- G# ^9 G enum TRISTATE{- }; o3 u+ W" }. W) H3 ]
TRIS_FALSE,/ [2 _" |. [$ B# T# g
TRIS_UNKNOWN,
|. ]" Y. ~/ h5 a0 \% ?3 I, y TRIS_TRUE
1 n. S+ G- ]; _7 }: X+ i};$ Q$ t$ I/ K: ]5 e7 d! k
9 |% T! F {4 {% b6 U4 S, z+ H
. N/ E/ U8 p: l$ E L" D
enum UPNP_IMPLEMENTATION{* E: v1 Q O$ R f
UPNP_IMPL_WINDOWSERVICE = 0, u" j6 t9 ^( w% k/ ~2 u9 u
UPNP_IMPL_MINIUPNPLIB,8 L, ?7 ~% k+ G" ~
UPNP_IMPL_NONE /*last*/
$ M$ \: }1 j* i' w; t& z};
6 y8 o/ K! N/ E& _; ~8 Y
$ A! I2 R# m! l! E! J6 B
( j2 H& T2 @; u/ `5 \
) _. g8 f) a% Z, _5 Y8 t+ l8 b. Q5 V$ N+ G* B3 M+ q
class CUPnPImpl6 J; o- p9 G- ~: @; E
{- g) Y! b8 |1 U( j
public:
& `" p1 w1 f& O/ s% H CUPnPImpl();
4 n* m+ r Z# K: m4 z# T4 n4 U7 _ virtual ~CUPnPImpl();
* @. S- G. G. |3 V struct UPnPError : std::exception {};
- h% H9 T" r8 q; F enum {) @+ E. e5 ~6 n' F6 s4 m/ R
UPNP_OK,
, H9 u% l, @4 j# C& a' l# |2 ~0 L UPNP_FAILED,
- m+ j- S4 `* J8 e' {( e UPNP_TIMEOUT
& V' [, G9 G& \ E7 Z };: Q" k9 i; n- L$ q4 B
) n0 v' n% a% M
, U, U( r4 D! z1 ?( } virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;) j! v- \2 S" Y4 C7 M) N
virtual bool CheckAndRefresh() = 0;
! @* ?- p% M! G7 c virtual void StopAsyncFind() = 0;6 N3 B- S1 \" B
virtual void DeletePorts() = 0;* m, C5 t9 z8 U; \ I* z
virtual bool IsReady() = 0;
! _3 b! E& A) k2 i virtual int GetImplementationID() = 0;
' t: Z4 c4 y7 d3 V" V
3 Y4 p0 F" Y$ l void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ Y! ]5 f& I( X# n" A* j. q" Q9 F; z
5 ~4 t' H' e4 b% E" w: a8 e) a! g0 y0 v8 R! a8 J0 h/ S
void SetMessageOnResult(HWND hWindow, UINT nMessageID);. K/ J9 H! D' T2 e V* k+ C, \
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }; s4 n" ^3 G# [# B
uint16 GetUsedTCPPort() { return m_nTCPPort; }3 @9 S& x. I- X* n* o
uint16 GetUsedUDPPort() { return m_nUDPPort; }
: I; `2 p4 u; t4 o3 o$ C9 a$ k3 ]' K6 @3 U. R
6 o% B5 {2 c' `$ g5 H1 ?
// Implementation
1 S/ P% N# g1 Q9 ^" P6 Vprotected: ]0 |2 G0 o! a1 K
volatile TRISTATE m_bUPnPPortsForwarded;
5 q: D1 H! H% i7 N0 ^+ g void SendResultMessage();
: R4 w. \( Z5 W0 |9 d uint16 m_nUDPPort;
% M8 D6 G8 K0 s5 s# k- M2 x uint16 m_nTCPPort;
* o' P c5 W& X4 a uint16 m_nTCPWebPort; @3 @* }* o! } l
bool m_bCheckAndRefresh;2 l/ W- A( y" S$ f4 W5 |
& T* Q0 s3 v; N% T
! K* x% H' q# N2 `
private:
5 f$ s; x* V% n* W& M r, p HWND m_hResultMessageWindow;# }$ H/ R& [* N8 }: {4 c0 w
UINT m_nResultMessageID;
. [5 t( ^5 @4 t( y" J. @2 p: e- l* k' V3 J, P8 z; u) W+ D8 Y& v
% I3 w9 g: ?* }& P& p0 q};
. I9 W# u- G! u1 p" Z2 `; t, P1 C1 k) ?1 u
9 I+ @6 L4 g& O9 E& |! c. H// Dummy Implementation to be used when no other implementation is available
3 S4 l) i$ a% O6 f; L- m& v0 L Hclass CUPnPImplNone: public CUPnPImpl% o2 q1 x# A3 J' Z5 A
{
" P. T' D L2 I0 q, V# \+ l, c* Cpublic:$ a7 ]4 D# e2 ^' ~* G! i
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" _; G" O! T1 j# j( v( I7 r7 w& v
virtual bool CheckAndRefresh() { return false; }" v6 }. D5 D0 {. q$ X+ ]. h9 O
virtual void StopAsyncFind() { }% M4 F- t+ Q! k7 o
virtual void DeletePorts() { }
[. i' ^5 q+ p* a+ X( U/ C6 Z$ f virtual bool IsReady() { return false; }
+ B$ N; K& S9 `- p! c4 _ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
: N( B0 ^. L. }# e};
; ~7 l3 l, R: T3 J$ t, ~
% y0 Z% \0 a) ]" ?6 _ n6 C( I2 q+ U5 G% o& m6 m0 K; ]4 n
/////////////////////////////////////2 Z4 Q# ?& c6 W$ L
//下面是使用windows操作系统自带的UPNP功能的子类3 f. B1 `1 k: s0 b" u; l
* W3 \& V& O f- W9 ?& \7 y1 @1 p4 s/ |0 S
#pragma once5 w! o7 @ {* i. n$ c- }* O
#pragma warning( disable: 4355 )
' R/ N* t9 B* ^, f2 S1 l0 `: H5 t# @3 Y9 K# o5 Y$ d' F: v" j0 `
. v& l& X, t3 f" c9 B1 p* H
#include "UPnPImpl.h"
[% h6 ^1 U, O, S" Q#include <upnp.h>: t8 f! h+ Z4 b8 N2 `
#include <iphlpapi.h>
S. w0 @( f% q5 s- b#include <comdef.h># {; \& n: v4 n8 A
#include <winsvc.h>
( H) C. X' K8 O* X* }7 O
: U3 U* p& I- y
' q" P: ?* V& U+ m0 I/ z#include <vector>
/ x* o a0 y/ g, X* r+ F: x#include <exception>
) L+ ~9 G8 R# J* v+ e8 U; l#include <functional>) p8 o8 N2 o: v1 r- ~* ^
) g5 r; w# f4 M) |/ ~. j
; @) N9 G3 O3 J; @7 x( ~/ Y3 _
. X6 s/ Y6 `+ X
* f/ {9 g) L& P3 L# P' jtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
; h% g, u7 F1 v' utypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;+ n4 t2 L( [9 h
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 E3 P) F, z' a5 Q
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;# ^: j0 W! @2 z, u9 h
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# g# L5 k! {9 H0 {7 a* |+ p# C+ v K V
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
# C9 D( a, T! ~. I9 l: @- ^" Xtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;( i) Q1 {. e4 P- o' k$ g% K4 m
9 [3 o- t, p6 S! z2 }* w) W
- T5 {7 k. y$ o- }typedef DWORD (WINAPI* TGetBestInterface) (
/ b; o: L* s+ K% j! d: u IPAddr dwDestAddr,6 ?% G5 O$ F+ {4 O; N: D, B
PDWORD pdwBestIfIndex- P0 |: H0 v- B. t9 y( p
);' v8 K; ]5 Q( A$ x. ^, K
9 |! [! a* O0 I' ~0 c2 o0 \6 v& }) k+ R5 m( U
typedef DWORD (WINAPI* TGetIpAddrTable) (
3 k/ |: ]) J5 r0 U4 |$ l, X PMIB_IPADDRTABLE pIpAddrTable,
6 M2 _5 ^0 k+ V5 E) m' D PULONG pdwSize,. a9 Y" i8 T5 E8 r: L6 O: o
BOOL bOrder- b- |, F$ X, t; m! x
);
# o |7 [6 Y2 T# [ P3 t/ u! ^! h* |+ I2 O# W
# |% t7 c f, g" etypedef DWORD (WINAPI* TGetIfEntry) (/ r% q7 P8 \% C* w+ M
PMIB_IFROW pIfRow
. }' M( {8 C7 R1 N; G);7 H, X1 [+ x4 j8 N' i0 B
; g5 h: j& u9 u+ t. E
* f: c# R8 u( s/ t' b* I2 hCString translateUPnPResult(HRESULT hr);: [. I+ ~2 { ~( D
HRESULT UPnPMessage(HRESULT hr);6 W0 B3 \" f5 Q$ r
+ @ S5 X2 E2 l4 p, p2 n
8 s% j. A/ l+ Q1 X' O0 Tclass CUPnPImplWinServ: public CUPnPImpl; V4 I" l) f2 w: P! g8 B, S2 e; @2 q
{% U f; }: y. V4 N$ v1 |' |
friend class CDeviceFinderCallback;/ }% D# o+ Q8 G
friend class CServiceCallback;( t) q# B( \; S9 k0 O0 B
// Construction
0 T6 S) E4 b$ X) [4 l, wpublic:
8 e$ n/ ?2 @ [- E/ v U8 [ virtual ~CUPnPImplWinServ();/ ^' J) t. w7 i, X- \3 w6 j
CUPnPImplWinServ();) s! d( k- a4 B7 F
q3 j- v5 H. y9 C$ f; |% r" t, t+ o6 E
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }7 M! W) x- k0 l/ M6 j9 j
virtual void StopAsyncFind();% G! J7 u1 s# H4 N) w. Z3 O
virtual void DeletePorts();
. m" o* c5 K) h! o4 B# F virtual bool IsReady();7 s- K1 B2 H' u
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
& s9 Q& j& K9 p* d9 K
. t8 a( }+ u- g2 u3 n0 c5 r! B
: P- k3 F7 i; y0 l- \ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
: n: P8 i5 W6 q // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later( S' m f4 H& m9 d
virtual bool CheckAndRefresh() { return false; };
0 T1 R: x! j- w' n3 `3 x* B9 q! R, L7 F- T
( J4 l1 i$ c, z; O8 {
protected:; d4 E3 j3 R {# d
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( G3 G7 F- J+ s+ y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
+ L* I" J7 a& f void RemoveDevice(CComBSTR bsUDN);+ b! Y. p2 W" R+ q) t6 }% e
bool OnSearchComplete();
C/ F6 u4 r7 D+ h) P void Init();- B, U" Q9 w3 [& x/ \ s a$ [) w
- Y1 a# y/ {: X( b. d M) }6 G& c
! j1 U0 t% x7 X# u9 E4 P
inline bool IsAsyncFindRunning() . E* |# [% E6 o& t! G! g% }
{
) V9 \/ Q4 M8 u: G D8 b. U+ C5 v if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 i) I7 z% a3 l# g- w; d
{
5 l; [$ ^; H( I6 M m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );$ c" _4 |, U. U7 J
m_bAsyncFindRunning = false;
1 `2 c" k( l f$ \+ N% v9 H }: U( B6 s1 u1 j
MSG msg;/ G# ]; h+ Y* b4 h8 _, o- e5 u
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
$ u9 f0 q! f3 j5 q9 h {0 {- y" l5 P9 f3 j3 Q8 g+ h* L
TranslateMessage( &msg );) t0 j8 O- S+ o
DispatchMessage( &msg );* {4 J5 b0 N9 V, M
}8 e K) t2 U) k+ q9 L1 d
return m_bAsyncFindRunning;, _0 X, y# w E
}- @! Y K' i) C5 ]' a' n8 Y
3 Q3 A$ f- A6 {) X3 {' }
; [4 |7 ?$ r# B1 g TRISTATE m_bUPnPDeviceConnected;
. o% A: B2 w# |9 d( V. A2 j' N7 \; b5 U8 k4 h3 r0 k
; ~( ?2 N8 V2 n4 X& z
// Implementation
% l1 J. k* r' G+ b/ R& T) u // API functions, Q; n( d# B" ~0 b% I$ c- n
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
9 a) T3 y: s7 y- {( _' G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);2 B8 y4 k3 k9 W! y6 B$ U8 b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);4 ]6 o/ p, G7 E3 N
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);# b' |6 s$ Q4 w/ Y8 N% |) M9 x9 O
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 G2 f# Q3 E. H, c7 v! V5 ^4 h; ?
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) R2 b8 m w! r+ o+ Q: B( j2 ] k0 u! w; i, R
# E# b# O9 K9 b- {4 `! t( O
TGetBestInterface m_pfGetBestInterface;
) ], z7 p) F5 r) } TGetIpAddrTable m_pfGetIpAddrTable;- j. w3 h, m7 ?1 a# u- g
TGetIfEntry m_pfGetIfEntry;& t% S6 C: I) h* b! z1 R
: m% V! p: T+ S2 X, s9 C' M
+ p; I: p6 h3 m: `% k
static FinderPointer CreateFinderInstance();
2 N/ C1 y. i9 A+ F& v+ e struct FindDevice : std::unary_function< DevicePointer, bool >) t$ Z" Y4 F9 X, x" f4 G
{0 Z% e/ x, o2 l- K* H1 S3 h0 ]- B B
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
$ a' z; h( a( u8 a& T2 P result_type operator()(argument_type device) const
1 a7 g7 @( u9 y( r {/ R, j7 o7 J. v' d+ r/ F: x2 p0 o
CComBSTR deviceName;9 ^1 { h; ?. s+ i7 O1 e/ J
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- R3 V0 }! [/ G: S6 E, Q/ k, J# M8 A) m
$ _; J6 S( A- Q- e! H- Q+ E
if ( FAILED( hr ) )
( ]7 R/ F5 |. I H, Z2 {" Z, r c return UPnPMessage( hr ), false;; L" x- R' E+ w, q0 o, [ s; i; b
2 v$ j0 r K2 y0 q1 }: O
" v) g* }! ?; G, F, y5 d* [ return wcscmp( deviceName.m_str, m_udn ) == 0;) O4 C# }, S# H( X! R% ~
}
. _% |9 l) Z9 X8 o# \ CComBSTR m_udn;
. @7 A9 M0 W& u% y. O; |, c# I$ K/ m5 | };
' s# J( u5 _6 ^7 E5 \" v! j 3 F ^' _: H$ u, i- D
void ProcessAsyncFind(CComBSTR bsSearchType);
; }% @+ D+ V& O3 P# j& \ HRESULT GetDeviceServices(DevicePointer pDevice);, i7 n) M3 J: |5 i
void StartPortMapping();, F8 J* h) r* p8 R N
HRESULT MapPort(const ServicePointer& service);. D2 l0 ]/ T- d6 b
void DeleteExistingPortMappings(ServicePointer pService);
1 S7 V, T6 ]" S( P& \5 N void CreatePortMappings(ServicePointer pService);
" v& o& X9 x' P0 Y9 ^* m2 Y HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);: I: Q9 J: l, {% p# h* N' S) Z
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
2 w' a* P' O7 l9 W3 a# q$ F( t LPCTSTR pszInArgString, CString& strResult);! F8 A a% d. B
void StopUPnPService();& |8 Y+ u! i4 ]+ Y& `- N! N
1 ]% ~" c& h+ H3 A1 ^0 ?1 V y% b" y
// Utility functions# p2 ^ k$ p2 K' g; C4 }7 v; I
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
& i% ^$ E4 K# i/ N2 s INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);' o+ s1 F4 [1 G& @- E) f$ A
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);4 V( _( D4 f8 I8 s* |+ `
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);, {; p: X. h9 ^7 ^' q2 d1 W4 b1 s+ ]
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; W: K# o% }# h* e. R! ` HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
1 K! t$ }4 g* p; ]) M' ^ CString GetLocalRoutableIP(ServicePointer pService);
- N# T; J" F# ~ a6 D, `, o, h! a( f Z( }, m2 D! \! V' t+ v
8 |& V, b! U9 M( x
// Private members
0 T) Y- z$ ]5 B4 x- bprivate:3 K% ]$ F" G5 ]8 W; X' l& Q+ P" M8 D
DWORD m_tLastEvent; // When the last event was received?
2 A$ n4 C/ c+ w6 n' z$ h* G e std::vector< DevicePointer > m_pDevices;
$ G# F% Z0 }$ M0 H" M std::vector< ServicePointer > m_pServices;
0 M* S t4 H( D; j FinderPointer m_pDeviceFinder;
1 B4 f# W3 J& ]+ j0 B9 H7 N' f DeviceFinderCallback m_pDeviceFinderCallback;1 Z, _6 X7 c! b, p! {
ServiceCallback m_pServiceCallback;# Z% N& P# ^( h" l% s9 V2 [$ k
& ^" a, }4 X' N X/ A( ^" k
; `6 p, S# v t# E7 X' E( C" M2 |& d
LONG m_nAsyncFindHandle;
, W4 |/ e: F* V5 p5 W, f& D9 m bool m_bCOM;
! V+ A! G+ z. A3 s1 D bool m_bPortIsFree;
& Y/ n* z- ^) e: T! p CString m_sLocalIP;
: p3 }( h# T' g7 _; _ CString m_sExternalIP;
+ P3 t* F. Q' ?! K bool m_bADSL; // Is the device ADSL?% z1 L# G8 t% B9 ]8 F3 B
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?8 W t& a2 e0 a8 ]$ p
bool m_bInited;" C, t1 z( ^* l: M, D$ E
bool m_bAsyncFindRunning;# l4 Q% M+ z0 ]: G7 b9 V8 H H
HMODULE m_hADVAPI32_DLL;( b1 Z; G1 K$ _
HMODULE m_hIPHLPAPI_DLL;% F" U" A0 a0 m7 ?2 N
bool m_bSecondTry;
0 u. Q& E+ B( F1 y1 c bool m_bServiceStartedByEmule;
; u* v& n2 W; }( n) o bool m_bDisableWANIPSetup;! U1 C. p. L8 t" c+ t7 e
bool m_bDisableWANPPPSetup; ~* V3 `" E- X" l1 y9 K
& K) a+ }; s6 k) q2 A! @
# P+ M; ~1 v* k Q
};
) u) V9 }3 b9 Y+ Z# W0 L& e: N' U/ K" g! \& S# I& E- w. c d9 c2 O+ j
% K0 I9 Y7 ?% r// DeviceFinder Callback
: W" i$ d- |) _1 M2 w% V7 R' t# wclass CDeviceFinderCallback' ~% J) B# w+ o5 j# I4 r- Z
: public IUPnPDeviceFinderCallback) X5 D, O ?8 [6 S
{
# T4 S- |9 U( A) q5 [* Dpublic:- O" g* I2 H z( t3 x
CDeviceFinderCallback(CUPnPImplWinServ& instance)5 V' g7 U. a1 ?# }
: m_instance( instance )6 o1 R% e- M% C! B. k+ v6 Q
{ m_lRefCount = 0; }+ l! S3 |6 ~( C5 A
, c1 E" c6 d8 N: E$ t' |! y1 `: y! f$ [0 n
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! w$ O w( i! A/ s& Y8 U
STDMETHODIMP_(ULONG) AddRef();
3 ]0 P" o3 m2 k STDMETHODIMP_(ULONG) Release();
7 K/ k o# H/ Y0 Y. ? I2 o
; T* r) Q4 _! j8 G/ m, O) q9 P% e0 y1 }, i
// implementation/ M, j/ N1 W# J
private:
9 a% U5 u/ C: W* _; Y \$ C HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: s- J/ K3 {5 z5 h) {2 M
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);/ t: X# N4 M* a0 H6 @) `2 h7 N
HRESULT __stdcall SearchComplete(LONG nFindData);4 \) k* G1 o2 y8 X2 a; A$ P, {
l+ b0 J1 M* Y# J) A* w! c/ O( z& ]7 X
private:1 N5 a3 r: e- F) I! u( J
CUPnPImplWinServ& m_instance;
: Q' g* {; |8 Y: g) T( {8 r LONG m_lRefCount;- Y) ^) q7 r7 _' I
};
3 ~ q, |8 g9 z* M u1 C* V) t3 T+ P, Y' R
# T7 q; ^8 P$ x6 B' s1 U5 C. ~// Service Callback
4 S) z4 W a; X% v$ p) T. bclass CServiceCallback
( w; S! ]: N5 F( d1 N. m0 X- ] : public IUPnPServiceCallback+ ^: t" }* R/ P* v/ |- V" W
{; i+ z5 p- e& c2 w) L* e
public:
3 V, ~% m: Z) J. ^/ m CServiceCallback(CUPnPImplWinServ& instance)
% ?! J N$ _9 Y4 W0 J- W9 C6 i& t : m_instance( instance )4 E# P/ o2 e; X6 _+ m
{ m_lRefCount = 0; }
5 o+ m0 \) A& W6 {, j
& q* \5 ]$ R/ a) F) m7 G7 V7 _ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 g+ y+ v, g# ~3 W
STDMETHODIMP_(ULONG) AddRef();
5 ^, I$ _7 G# a7 Z STDMETHODIMP_(ULONG) Release();
! ?. Z4 U: y# W9 C& U
2 t% _# \9 K8 ~; d- _" i/ j& Y: ^+ d0 r
// implementation0 g3 I6 i8 Y' B2 G' G1 A0 N
private:
0 o7 f1 \1 Q# A" I4 G4 S HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
& t1 ~- w3 u5 W) `3 V HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);: m) \# W( P5 a6 E; k
- @/ Y. m: p" G f. q+ E* O) t" M" b0 ^ U5 I: i( g$ ~
private:
2 U: t& r- N: L9 |, W _ CUPnPImplWinServ& m_instance; Z9 P2 x; j. R' d! c
LONG m_lRefCount;
- `/ i# V! j( y- b: W( v};/ k1 d: w' W( s+ b$ z1 e
& }9 g5 P# x! k* d- p
) N; X5 n* K4 f% N) Z0 M% Z
/////////////////////////////////////////////////' \& [) d/ i% N) b, k: U; w3 `2 @: @
, J* B8 b+ v Z! Z
0 B8 e/ h( G. R4 Z
使用时只需要使用抽象类的接口。
* G9 | Y7 L ?2 I, ^9 VCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
0 @2 N5 e; y% y( z6 z1 YCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
7 ^9 @9 Z1 ^3 @4 t$ J; VCUPnPImpl::StopAsyncFind停止设备查找.
' m7 n! F- |' I2 K/ y9 A* S2 i6 oCUPnPImpl::DeletePorts删除端口映射. |
|