|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,$ ?/ r* c/ G# V
) c& M1 D8 |/ b; s" t! E# F. {* V% U# B3 P+ r
///////////////////////////////////////////7 _, r/ s, N5 M6 y! ~$ |# W
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.7 p* o0 A4 j6 U
' c0 k) P, v- t2 P) U& v9 V6 [
3 b0 z& P, X, S9 e- R* P) V#pragma once# q/ l5 N5 e! U; S: F
#include <exception>+ z" R! ^& M" A9 _
8 h/ |7 T/ x, V7 o* N
8 l7 w3 {" T" c7 M, G! a/ O! f enum TRISTATE{+ a5 y! ]5 K6 v9 S: t, `3 j
TRIS_FALSE,$ S- @& O# b6 U. @9 t
TRIS_UNKNOWN,
' ?' |8 `7 j: P h/ h- o TRIS_TRUE
/ c3 Z3 E7 D6 v* W/ Y; U( G};
$ l" S8 c4 A2 J8 P- ?, X+ B0 x+ O( H+ X, k! a& ]! ]+ r' R0 E. L
# v9 u0 a# x3 M- q. e' m, Kenum UPNP_IMPLEMENTATION{
: c/ M2 u x3 h" m; E UPNP_IMPL_WINDOWSERVICE = 0,: ^, z/ X) x% u5 }
UPNP_IMPL_MINIUPNPLIB,1 u$ k% l& l8 Z3 K8 J
UPNP_IMPL_NONE /*last*/* I! O7 _. x2 ?8 Z, U5 o& D
};$ _6 [4 B% _* ~0 i1 G. r1 m
k4 |9 ^; ` g% M9 B
- q$ v: N0 S$ q- K( f( S3 [& J" ^) y( }( O0 _
! S" }. {3 h3 X) h% C1 \! e8 zclass CUPnPImpl5 [" [+ |9 V$ P. W: S, _) ^# }
{
+ h& N8 Z0 q& o, `1 t8 x- Hpublic:; x2 P( g6 M$ ?, i3 h
CUPnPImpl();) y) }/ I# F z. ?" |
virtual ~CUPnPImpl();( V5 _% b! r, o3 Y7 p: C$ Z
struct UPnPError : std::exception {};
. x2 A% e' g0 Z+ q* p* q enum {* P! o: X, H& ~; L% M
UPNP_OK,
" F" D$ C/ I4 u7 }+ T$ i UPNP_FAILED,
3 a% G! K [. |; ] UPNP_TIMEOUT! c8 E% ~5 ~! u, [, E# a' M
};9 ]6 O( @, E7 o! W1 d$ y4 V
" \) r* }: e" s1 o6 _
. s8 F l7 u. f; u/ K
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
. v5 U5 C6 w4 L* f. d6 d virtual bool CheckAndRefresh() = 0;
+ ~ v; m. _9 @' W( P& x, q virtual void StopAsyncFind() = 0;
$ d4 L4 a# C/ b$ s- d8 P7 v# o) F virtual void DeletePorts() = 0;2 E" M, {; h9 {- l6 @* P* u
virtual bool IsReady() = 0;0 F0 O7 |3 Q4 X$ _
virtual int GetImplementationID() = 0;
% l! b6 s# E4 y3 P* ~ " [$ W- q! O3 C- o
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping( [+ Z+ U2 Y% B9 a3 x+ s
$ V) N' r8 n9 N" Z+ C( H( a
$ f* P3 V7 }& b8 d+ l) m* W' P4 z void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 E4 x( d9 o# C* T6 [9 o# k
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
7 q6 m3 V- f6 G9 y; }0 S uint16 GetUsedTCPPort() { return m_nTCPPort; }
' S' N7 w& ~! y uint16 GetUsedUDPPort() { return m_nUDPPort; }
, X; q$ J4 i8 [' ` n' Q" c @1 }# X2 A" C6 I% Y2 C$ a0 m
- k9 f& {( s! @7 V, i// Implementation4 \3 y1 h: c( I4 i2 \7 `
protected:
. {$ R3 y; T% {6 N3 ?; M6 H3 \7 v$ k volatile TRISTATE m_bUPnPPortsForwarded;% u p# r; W$ y" t: C4 u) Y- `" Y
void SendResultMessage();
1 b. R" Z- S# F. Y/ E" y/ H uint16 m_nUDPPort; q9 S2 w1 R- I* c4 F1 D" X6 k
uint16 m_nTCPPort;
8 T( p' ]0 }3 j3 z uint16 m_nTCPWebPort;, z! z& L% b' }5 b" q; o: W4 n5 @
bool m_bCheckAndRefresh;2 `* G7 c9 t. _
7 `4 `- X: T' f+ m+ F& u( Z* }
7 `# M* d5 f' t. ^1 vprivate:
5 m* A. Y% f& ~7 A1 t* R' D HWND m_hResultMessageWindow;; ^0 }, U7 N+ L$ h0 ^# Z. q
UINT m_nResultMessageID;
& s8 M2 S' V5 _. r& O/ _; i n) E0 `- q% b2 A5 i
* O# z* V& {/ J0 y; a6 ~
};
. D7 K" p! Y( ?2 b5 s0 C5 z7 d! Z9 G; w, P3 X3 @9 G5 H4 d8 b: J
$ S1 C. H+ j# C. N. v7 m5 k% S
// Dummy Implementation to be used when no other implementation is available6 e/ P) e. I+ {
class CUPnPImplNone: public CUPnPImpl
% ?" \5 s, W) ~ |" o{
5 x" Z2 `+ u, K2 }7 h+ Y* c" M- v" wpublic:
; C+ D1 I# [) H virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }' d3 S S8 x" ?# f' y2 N8 U& c
virtual bool CheckAndRefresh() { return false; }! e# u. T$ r9 q: g( q
virtual void StopAsyncFind() { }( { P3 L6 U! l6 m% `
virtual void DeletePorts() { }: \+ J+ o1 S7 J; l/ t9 b
virtual bool IsReady() { return false; }
. x- t4 `% P+ ]% c Q virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
5 v1 W5 J( y) S};
$ b& U1 W* J" k2 O; r" a+ Y1 p
7 ~! C: L9 @3 J5 Y: K7 \
! r% N' T9 e( a2 o/ x/////////////////////////////////////
+ I) }0 d, h' _ r* G& W+ e//下面是使用windows操作系统自带的UPNP功能的子类
3 g( a. s7 R) w1 \/ h& m% v' i# b5 A' ]6 s5 b
- \5 p6 k7 e1 N' L#pragma once
! b" m! C6 m# n1 [& a7 q0 g#pragma warning( disable: 4355 ): G4 H0 E- {/ n* ?' V6 E
3 ~1 m8 v1 ]! J2 o/ J+ S: b: g
9 s+ {8 a# k) O* h8 |# Y | C; G
#include "UPnPImpl.h"! r; x. @; n w1 O2 p3 l
#include <upnp.h>
+ U+ E2 x% d; u2 x#include <iphlpapi.h>4 _2 I" \$ V9 n! r$ @" o
#include <comdef.h>
( `' ^- B+ ~9 y/ g#include <winsvc.h>
; H# R4 t/ `' V' r0 J" B8 Q2 S7 l
8 b8 Z4 b. P( G6 f$ ^9 h! O#include <vector>8 S. J2 S! f+ Q8 x3 m! ^! z
#include <exception>
: D1 h1 l K! J/ N; y#include <functional>* |" [4 e& B1 b, @4 o( ^' @
# S* K5 l# {3 d' `! X
" q* G2 W9 G9 }" m& L. p
1 e% E0 s6 W/ @' n' f" V1 ?" X- z. B
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
7 r. q! S- z5 ?% j8 f% mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
- m3 k/ d1 K8 O3 n% x7 y0 ^, Ntypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
. ` _8 ~, M( T, Z9 ^typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;. j! Q7 L5 k. h; n" O$ `
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 i$ z+ ?! D1 q3 c- ktypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;$ ~# j, T; O2 ~
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 [, a4 I7 M I9 P. G" f" x# F& d
5 j0 D: q' m7 |& I r- B; c
5 Q! P2 Y: o: C/ b) M8 l/ ]typedef DWORD (WINAPI* TGetBestInterface) (
8 N5 w: G3 b6 Z$ {- r! G IPAddr dwDestAddr,0 K/ I. Q7 s" I, V5 b
PDWORD pdwBestIfIndex
$ G) n2 d+ W2 j8 U- ]6 r4 [) z);
1 O2 d: a. t$ f: g# L3 x1 b+ ` R
8 F5 k& l/ L# @) K7 y8 s0 S
typedef DWORD (WINAPI* TGetIpAddrTable) (9 X( d4 g( y* i# W8 M( E/ c; ]
PMIB_IPADDRTABLE pIpAddrTable, L# g: n" E' C6 [) E
PULONG pdwSize,
( ], u M8 N& p BOOL bOrder7 i( p9 C/ k* z* |4 O; n3 w
);
/ \0 ]7 Q0 H8 t% X/ v" y5 h! t! f$ `% A/ E6 _# R0 W% c
1 ]/ y x3 A8 G0 h0 ztypedef DWORD (WINAPI* TGetIfEntry) (
0 q2 } N& }/ t5 V PMIB_IFROW pIfRow0 X% S2 g9 D) h9 N- G6 Z* O
);
5 Q* ?$ e% Z% K4 I" L
7 B0 n6 L+ g2 { y( `( j. n& d* B: p7 {1 I) V7 j1 r! w" e
CString translateUPnPResult(HRESULT hr);& D' d4 v% I& Y
HRESULT UPnPMessage(HRESULT hr);
+ g0 r$ c( p- T5 _: U" y* i( h, E; F9 J6 y0 D
! ^+ y% Q; C0 m5 ?! F5 @) T; J
class CUPnPImplWinServ: public CUPnPImpl$ C8 Z' N; W( L7 S7 X. a: Y; w5 |0 x
{9 m1 M% n) d7 q3 G# g! i. c8 m
friend class CDeviceFinderCallback;" p" M; f% i7 h6 m1 d/ e6 }
friend class CServiceCallback;6 p0 n( i8 r3 Y& t- M. A
// Construction- C6 J, ~3 q% K# H9 A$ \
public:4 `# k4 o4 Q" N; ?+ [: j
virtual ~CUPnPImplWinServ();
# F6 T( o+ X, d CUPnPImplWinServ();$ L2 x0 t$ J. z z7 v: u% T
: }- p" Z6 q+ s) Q2 _5 m8 d0 x: A `2 i- W
' ^. V9 j# ]4 P& b" D virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }$ x" Y0 _3 {/ E' T# n6 r4 i
virtual void StopAsyncFind();4 K: Q6 g3 {) f- C. t, N
virtual void DeletePorts();* w- z9 P6 h$ K7 x5 v' M
virtual bool IsReady();
: R6 y) _5 [0 g( z6 ^- l# ` virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }- z; B7 j4 i' n4 U9 \) A9 j
. W9 ^8 X. K O E0 ?: m
3 S2 o9 g7 O' b! G V // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
! j! Z& s: X5 Y( ~: a! _* ] // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
0 I4 x7 M; b' I- v- d3 a) c2 K9 ~ virtual bool CheckAndRefresh() { return false; };0 T6 x( L8 _ D$ B( o, \# g! t; h
" n. k3 E2 |& t! r3 E( i
M3 W. \9 |+ m) V/ W
protected:
5 E6 n7 d k' `+ E) U8 j7 o8 l void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
9 @3 L& s. V9 r2 k5 E void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
1 k. i% d2 _3 c- e# L. m$ o4 G void RemoveDevice(CComBSTR bsUDN);1 J4 b; {: z2 N E$ A( I1 C6 N, B5 s
bool OnSearchComplete();- l6 D6 c" e9 |2 j, b
void Init();
, c7 o- q1 A! X2 J5 o
4 i/ N& @; M/ q1 R+ q( H0 _" L; Q: f" s
inline bool IsAsyncFindRunning() ( N% w ~) C: r3 h+ Z7 E) z4 D
{
8 X, E5 A7 ?" p0 @ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )2 ~2 [! t5 C! e, \& ?0 A6 D/ W
{. j- r0 |2 t0 s) N" S5 f
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
. O% V$ Y' v1 q; @& h, z* j m_bAsyncFindRunning = false;
0 v( V3 d$ O& R) U }6 u+ o; E/ u$ y9 ~; ~& M/ Z
MSG msg;
' O' T s3 t9 i9 D while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ); m2 Z C7 |& ^' f
{% }# x( ]+ P/ K& E; h7 }
TranslateMessage( &msg );- S9 G# x1 j8 q1 t
DispatchMessage( &msg );
4 a6 r7 j+ X% P }3 G2 J( i+ P* @3 H, h7 b1 U
return m_bAsyncFindRunning;
+ [( Z2 z/ C2 t: S }% r2 @9 T( y+ y- B" x+ _
' R' o7 h; [7 u0 Z0 L2 ?& o& N/ G; p1 n8 K6 r
TRISTATE m_bUPnPDeviceConnected;
1 S# Q( T) H3 L4 K2 x$ J% b5 \4 O, b, I$ l! Z
4 N A) U+ z- B
// Implementation) U5 p: R% ~. g9 T' `
// API functions
- p1 z# {' {, v SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
! O* d; r3 f* `8 Q SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
3 G' F. e0 j( }* F, [ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 O- d9 e' P3 C4 ?" j1 j BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
6 s( y/ N0 F8 c5 l& t% y+ q BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
' f! S8 a, U/ \( P+ f( w( d. i BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS); H' F. |% M' b4 z4 q
" }8 c" a! j2 q+ J8 X' U! d* t
. Q6 V% y7 L3 n* M6 ^
TGetBestInterface m_pfGetBestInterface;
: y6 P- ?2 P# h! w( P; g/ g+ W TGetIpAddrTable m_pfGetIpAddrTable;# F i& S6 _6 \: c% J
TGetIfEntry m_pfGetIfEntry; u, \+ R/ E6 k
' ?" Y" z1 ]" o, |! Z' p# ?
, ~& v) p C5 ^4 ~) L3 w static FinderPointer CreateFinderInstance();
d! e0 L! X/ D% c% z# P& | struct FindDevice : std::unary_function< DevicePointer, bool >* I. i/ M, d3 y9 X; y
{
% b2 t# |" B4 x$ C( o; k) e FindDevice(const CComBSTR& udn) : m_udn( udn ) {}" I; X/ A+ Q% H* V+ r: U
result_type operator()(argument_type device) const
9 ^- @; m( p9 Z! b: z/ ] {# Y1 U' J0 G* k3 a1 m) l! y
CComBSTR deviceName;1 E9 a2 p! z$ P3 ^( M. |/ o
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
3 b7 f# z6 L3 Z
9 r: m4 |$ _1 @! A- D) X
" ^0 V- S% J/ D; B$ S- w9 e6 H if ( FAILED( hr ) )
) x; ~+ |. K0 \ return UPnPMessage( hr ), false;
0 I% M- ?" u# q e& u( N( F, u
9 @2 a5 Q9 L) B# v
# A6 ]+ ?( j. P6 x return wcscmp( deviceName.m_str, m_udn ) == 0;
% |. q6 f8 V0 [/ z% h: f7 _" x }
, N# C9 e, Y6 D CComBSTR m_udn;& j. p! {& R' `$ c
};% ^3 C% H! n" z9 N% I9 t
0 ~4 P9 }* o+ }. e$ g0 s void ProcessAsyncFind(CComBSTR bsSearchType);
) I! T" x) z3 P [1 ~ HRESULT GetDeviceServices(DevicePointer pDevice);, \" A3 l( k* z- V- @! O- N i- B: O
void StartPortMapping();
0 h, M; `4 U: ~# k HRESULT MapPort(const ServicePointer& service);2 x1 Q% ?2 C# Y. |9 Z9 D5 w( O
void DeleteExistingPortMappings(ServicePointer pService);
; T. c6 C% P+ m" Y# M/ x void CreatePortMappings(ServicePointer pService);- M$ Y- s6 n- k$ L% ^( G
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ @. ], U& Z0 L4 S+ B; S& _ HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ' q! ?% _9 `: J
LPCTSTR pszInArgString, CString& strResult);
* _+ |0 O& F" N/ F void StopUPnPService();% \' m* O; \3 v7 Q! p
+ a$ T3 P9 L, _8 f6 V+ N1 z
+ o) W( P1 C( W7 Z! H$ g
// Utility functions
" X, }- I( D& g9 |" D) |( g2 Y6 w HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ m4 ^' K7 G& u' b INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
$ h! W2 ~' v8 { INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 w* |4 v- D7 D* U) ?6 i
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 p; u& j+ w. G( s8 o! Y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);+ d$ I6 {3 J1 q7 ?1 l
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
: v6 ~, K F( A# ]; A5 { CString GetLocalRoutableIP(ServicePointer pService);: g/ J4 S2 c% K( I1 l
8 @3 w0 ]3 ^* x) j7 e( ]# j
; O4 A# E( l, Q// Private members
5 P! z5 J1 ^! V, Xprivate:
5 Q5 M* N: K8 }7 [ DWORD m_tLastEvent; // When the last event was received?
/ z, n B3 ~& v std::vector< DevicePointer > m_pDevices;
6 [# B# J, H/ t6 w3 Y std::vector< ServicePointer > m_pServices;
* i, F6 C5 F0 H# Q7 H FinderPointer m_pDeviceFinder;5 o, p8 w$ Q# y r5 B! c
DeviceFinderCallback m_pDeviceFinderCallback;" P2 o r: i4 `. V
ServiceCallback m_pServiceCallback;
. e, N2 g' p& H) N a5 F! V
+ ~9 r+ k, t& e1 j0 ]- {# r& s$ d& T+ e: v/ K2 m! k/ Q
LONG m_nAsyncFindHandle;
: y9 V, k8 \6 T( U4 l2 L0 a bool m_bCOM;- Q2 n' W0 }4 A: g
bool m_bPortIsFree;( L1 Z0 o% O' z& g% i/ ^
CString m_sLocalIP;
0 n- M% O' `$ B. M8 ? CString m_sExternalIP;
6 e% H( }+ ^) j/ l2 @# s bool m_bADSL; // Is the device ADSL?+ r5 W+ |- q5 K- {0 ?/ c1 e3 Q
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
8 B" }. K& I% W! P) I) p% e bool m_bInited; `0 I: F; l3 Z
bool m_bAsyncFindRunning;& p) O. w: t! _1 d* M% s
HMODULE m_hADVAPI32_DLL;1 W8 _4 o5 q/ _$ e3 l
HMODULE m_hIPHLPAPI_DLL;0 d( F& f7 ^" u H: U' @
bool m_bSecondTry;0 M+ u: g$ D/ _; X+ D$ ^
bool m_bServiceStartedByEmule;
8 D4 B0 r7 h% |* q5 U bool m_bDisableWANIPSetup;
& W0 C( G/ T& p* d: s3 j bool m_bDisableWANPPPSetup;
{1 ?+ ^1 v# |3 ]6 @& {! Z; f1 E0 I! `; G9 g
' F( l1 n2 M _# ?% b' |" v9 s
};
9 V' d: U/ W- E6 u' v5 V A+ M G
0 P, \/ |0 R% ^6 V
7 X5 A# B5 D. Y% K; r// DeviceFinder Callback
/ ^$ I$ X: H+ g, mclass CDeviceFinderCallback
/ Q! r1 l/ G) L/ ~ : public IUPnPDeviceFinderCallback
+ e7 h2 T! I; ^# j{
6 [" {* ]4 Z6 F" N( H5 [public:( }9 z4 m. T# r
CDeviceFinderCallback(CUPnPImplWinServ& instance)" ]6 ~4 X- q' i3 f
: m_instance( instance )
: D+ @+ m) [& i0 ] { m_lRefCount = 0; }& h& o' g$ \3 j/ j' [* c$ ^
' h1 R* Z- V* ~% }8 V
[+ u j1 _) V8 I STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. G3 E" N: T1 I8 K% J
STDMETHODIMP_(ULONG) AddRef();
9 f) g) m2 h+ Z STDMETHODIMP_(ULONG) Release();
2 g5 ?6 x0 q( f# i' n4 s" H! L2 r1 @, ^7 H8 s
& n5 ?" N! {& A! ?; O- m// implementation M/ Z& A5 j! X' s4 P
private:/ ?. n, B0 P0 r Y7 J# x
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);, E b! R, g1 _' O+ c- [" f2 D( c
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ c; z5 B& {9 D* N HRESULT __stdcall SearchComplete(LONG nFindData);% E- k; Y. P9 N$ j. L
+ b4 S- d7 i6 j1 l, [
1 D6 v1 t' A+ a$ z" P
private:
7 J3 m% j9 J6 ^7 x0 m/ L0 l CUPnPImplWinServ& m_instance;3 \+ s& k M) q1 M1 {7 m
LONG m_lRefCount;; O8 w; X' g5 d8 M
};3 [9 v5 z( R0 l9 ?8 @2 o
# T; h. A+ b" o! b6 O
2 @ H% o# u5 j5 J// Service Callback
: B+ H& r/ Q! ~! A4 {7 ]3 kclass CServiceCallback
% P1 G/ L% i9 l/ l2 Z. H! U/ s* C : public IUPnPServiceCallback
! M$ J9 ]- }/ y5 l{" `& c% [7 C, k$ T; h
public:
& {' ~, V# B- M2 Y6 q' @8 j0 A CServiceCallback(CUPnPImplWinServ& instance)
2 r, R0 B7 x Y9 t1 O, \2 d : m_instance( instance )8 u" o6 r( U" y5 ]% f4 i
{ m_lRefCount = 0; }) g0 }" P) Q+ P
- o$ H9 t. g" [% J& h
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ s ~1 i; Z& r7 S* c# r8 q
STDMETHODIMP_(ULONG) AddRef();
; H) L/ b! N; W w) t6 ~2 T1 @, I0 B& W STDMETHODIMP_(ULONG) Release();
+ P1 C n9 Z4 V- e( W' g& J! o' g" m
; v3 W+ E( P" w1 W2 {& M) w( t// implementation
+ j2 X' {& q- ^8 K) |private:
% `4 n( V" ^: Z8 | HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
+ r, K* ~/ ]3 T0 E+ ~ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);$ w$ @, O5 L' ^9 ?3 W2 `9 z
' {+ H7 R* G) e2 G. {: J" y
G8 [( h" \( O! q! X4 ^9 Lprivate:8 F* U4 @: m, q# v/ B) j$ s( J
CUPnPImplWinServ& m_instance;6 B: w! c& N+ ?
LONG m_lRefCount;
+ d% j3 | t7 Y) H0 E- h" Z7 H};
0 Y& g& Q( G% K0 I, h, l e5 L6 \) x) H7 M
# I( f9 J4 T2 Z) Z2 Z1 |- c4 `5 G/////////////////////////////////////////////////
, `; w. Y! p9 y3 _) G% x- k2 g# l9 G$ G: U( N1 }. |
1 D& Q* I" l$ m) [
使用时只需要使用抽象类的接口。
+ ?$ _; ?: V1 W) y$ Y1 W' vCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.* b9 | h% J: H6 e
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; Q1 v7 k4 k: z4 L5 j; d( B
CUPnPImpl::StopAsyncFind停止设备查找.3 X( O- T2 o% d! H$ W: P
CUPnPImpl::DeletePorts删除端口映射. |
|