|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,* q5 I" H7 z9 ?8 @# @! y3 p1 c
5 \& o% C" T; w
+ ]3 }0 o; q/ p, d
///////////////////////////////////////////
4 v2 M( n, a4 Q* w2 d//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.+ A* X; R4 ^ o9 K& v( A
0 c2 B7 t2 `2 S6 c8 g4 T1 Z/ w
( h; n! i- y$ u6 i! j#pragma once
. P" \5 d! e+ _2 u2 o) B#include <exception>. }. e; j5 k6 c8 E2 r3 B. T% M& v
$ Z/ d1 x0 r0 w/ _6 R+ x: K# B/ }- ]6 w* o( A" T6 g
enum TRISTATE{
# F/ W! e+ O4 G) N( ? TRIS_FALSE,+ [. j0 V& x2 s& ~
TRIS_UNKNOWN,4 K8 K9 A. E& ^* N
TRIS_TRUE6 ~0 n5 N: E% H- \0 L7 a" I: M
};
2 p/ H" O# M, v A: t; @
9 A! U* p* s3 V" B- ]/ S1 ]1 r+ r6 R& p. I1 J8 e) W
enum UPNP_IMPLEMENTATION{) E* J# f3 }/ o: s0 K
UPNP_IMPL_WINDOWSERVICE = 0,
8 R0 }- C2 l, x5 } UPNP_IMPL_MINIUPNPLIB,) U& X% U2 q4 c3 H6 A5 O& \6 e
UPNP_IMPL_NONE /*last*/
9 [! m, N3 O( D5 Z0 L0 p};/ ~; L+ E1 Q q; M
( J1 G7 N" i8 b
! Z" H! [: V8 M
: R" ?- W4 y, M% g2 |
$ ~7 m0 G w& o& H4 F3 M9 kclass CUPnPImpl
: T z" o/ G% h2 {- O& ^, X{% I- S) {# f. ~
public:( m+ c1 V7 {# g C5 V# ^
CUPnPImpl();6 S9 ]( T3 { m$ Z+ g5 j
virtual ~CUPnPImpl();& @( a8 l" D; T0 G& o
struct UPnPError : std::exception {};
0 e- x$ Y6 A$ Z [/ N' B8 t: U# P/ [" e enum {
5 a* [6 ]# q6 x6 n7 J0 N UPNP_OK,! {* d2 O Q& T$ ^- c
UPNP_FAILED,- p8 e8 D. f# j8 q: A3 @$ A7 M
UPNP_TIMEOUT) l, M: }7 r! y$ k6 X! ]0 M
};
- U7 f6 u- g( x, R9 a
9 c ]& T; [+ a0 w2 {9 N# Z
+ w. k, u; L8 N' `) P virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;4 S& c: V9 x* P( C# f$ @
virtual bool CheckAndRefresh() = 0;
; ]0 g: J7 L0 ?9 b& N0 g8 Y virtual void StopAsyncFind() = 0;1 J7 z0 B" E1 E6 \, u
virtual void DeletePorts() = 0;
& d; J3 s6 _+ d s) B- | virtual bool IsReady() = 0;
+ C. ^6 Q+ H4 }' P3 g virtual int GetImplementationID() = 0;" ~/ w( u, p& v; \9 o
- `9 p2 ^3 G8 T; V. E$ R void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
# `0 K: ?5 X) K2 {9 M, [7 p/ w0 I U# W$ _
0 s" F7 L/ A3 l
void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 p! `( X; L) L2 l' N
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }. ~) m: l% {4 Y
uint16 GetUsedTCPPort() { return m_nTCPPort; } Z' B% U, J L, a
uint16 GetUsedUDPPort() { return m_nUDPPort; }
. d3 A& |0 f/ i/ d5 D5 O/ l, d4 [5 a U6 N) m. _* m
4 q0 h5 k9 [/ [3 B+ I: s/ d
// Implementation( W+ E3 H ~. h- t
protected:/ ]" @& |2 s+ X0 d; e' V
volatile TRISTATE m_bUPnPPortsForwarded;
! t5 O( N9 l1 H( z# B void SendResultMessage();, P* x/ v3 B" ^1 U9 C1 k; q
uint16 m_nUDPPort;
# b" D% X# e. R+ \- w8 I uint16 m_nTCPPort;: p7 z# p/ c5 T3 j
uint16 m_nTCPWebPort;8 {. Y& O% a, n4 {! D
bool m_bCheckAndRefresh;8 i5 J/ M: N! c
7 T& U p; U7 l# q5 ~
& k$ F/ H7 N' I- r x# xprivate:2 Y* a$ f6 ?) h$ z4 Y
HWND m_hResultMessageWindow; S/ `' }" R" k5 c; W
UINT m_nResultMessageID;
. H* l; N: t( J8 A
1 I! l8 z8 ~+ d' O. s' G/ G6 N
: {. F- u8 V7 i' X8 p& j};
. a3 E% C `' h; N) d( Y9 u `' ^% M9 r0 d$ H' H7 x7 w1 k3 L: J" L
, p: A+ i/ m2 K5 w# A// Dummy Implementation to be used when no other implementation is available
1 n% D& Z$ I3 g) n- G& J+ s7 jclass CUPnPImplNone: public CUPnPImpl) o- z" l, r/ h: |" ~; n6 {
{ X+ `1 B0 J9 l8 O9 D6 m+ d- X5 n
public:
# Z' H2 T) }( H P virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); } U& B: S7 Q' r# B( N+ G6 r2 r* `
virtual bool CheckAndRefresh() { return false; }8 m, E# r2 s6 B2 M J! V2 O$ `1 j
virtual void StopAsyncFind() { }
3 c! Z7 [$ M0 P, `6 p; N virtual void DeletePorts() { }+ h- Y- x6 z k# V6 g
virtual bool IsReady() { return false; }
7 K1 @/ K: b8 G. W/ r! X virtual int GetImplementationID() { return UPNP_IMPL_NONE; }2 a# L0 c4 c* Q7 z+ w ~
};
, x, I% n2 |1 ]# n, ` r6 }
' g! A0 }% p, h
# d6 @& {6 U6 W2 O6 d) W5 [/////////////////////////////////////, V( B B( p0 G2 M- k
//下面是使用windows操作系统自带的UPNP功能的子类
5 B( t6 F5 @, u
3 [4 I" t0 S+ B z0 b$ g
& {% L2 Y! ?; ^6 \# I#pragma once' |: ^% P9 W4 S; b0 x9 f" u M
#pragma warning( disable: 4355 )
0 e0 ~8 b5 V% l; m' y) O
8 q% G d6 h7 }: Z N4 y5 J; O( |. y; T' J
#include "UPnPImpl.h"" n. H7 {. p+ u0 `
#include <upnp.h>) w/ r$ ~% m2 p, d# Z8 {
#include <iphlpapi.h>
" h; h, e7 _% K4 f# A; I#include <comdef.h>
# {% o- g/ h; `; r7 Q3 v#include <winsvc.h>
1 b K4 F& p6 R, ?/ L
( J& r. c6 V2 K$ J* g$ S4 |: b2 U* J1 f* [) w
#include <vector>4 w, L4 F4 s0 D" u' K; C) O
#include <exception>
/ w+ L W+ p. `7 o4 {8 q8 K#include <functional>
4 `5 v3 e P+ N+ Y! I! q( }2 A( w, j8 ~
9 ~& x1 \9 f3 Y4 m$ l* Z: ~1 Z: U4 q8 {
/ J% `( z! w5 Btypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
7 h6 a- C# `" J" p% _typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( P' _/ M9 c2 \. Y4 dtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer; p7 [. i7 ~ _' q: g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 t0 k" j+ y( e, Gtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
) `7 Z' `/ E1 g' t) v* F$ v3 Otypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;" @& X7 @$ z9 P; e. j
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
4 y+ ^" m0 ]" H; q
3 E9 a0 ]# b# `# A% u, l% L0 y+ }
! K2 R1 E. W, T% V+ ntypedef DWORD (WINAPI* TGetBestInterface) (/ S7 Y, E7 d* O* G) n9 O
IPAddr dwDestAddr,
( o( S q! D7 m3 {' q7 [ PDWORD pdwBestIfIndex
4 n: Z, Y. H, w' Q' \);
9 }/ b' a) G# E |. f0 b, ]0 ?; ^& W; G( _+ W; K# y- j
4 {6 `4 V. g Q2 V6 Y) A3 Y
typedef DWORD (WINAPI* TGetIpAddrTable) (
9 |6 L* y" L7 p PMIB_IPADDRTABLE pIpAddrTable,; i" \$ D; N8 Z
PULONG pdwSize,
5 Z; _) a% g# ~ BOOL bOrder
6 z& b$ C+ |! `+ z);2 U- R( E8 E8 m: t
- S/ g& i% P6 D1 p+ ~/ k0 x
# ?# Y( p6 n. p7 P' d: ctypedef DWORD (WINAPI* TGetIfEntry) (4 N" f. L5 I8 X7 z+ Z" o9 B
PMIB_IFROW pIfRow
- U0 v6 _: y6 d: j8 w8 [: U$ @);: Y3 E S" c9 e& E
# ^' O6 b$ ?5 w
% i) x; u1 Y |( _7 n9 GCString translateUPnPResult(HRESULT hr);
5 w/ S! h) O i' w7 o q' oHRESULT UPnPMessage(HRESULT hr);: f F! C' L. W1 S) {
; B4 [* v5 J0 [0 {& Z, }( q# d7 h: U1 S
class CUPnPImplWinServ: public CUPnPImpl
% ]3 v5 k2 o* k/ k1 S5 Z! k% m{
/ ]' |; J6 |2 ]- _& b } ` friend class CDeviceFinderCallback;1 R' G3 T* h: n+ M/ w7 F% Y. m5 g! @
friend class CServiceCallback;3 C$ r+ p% m k6 S) V
// Construction" R0 a+ n1 E1 W* R$ X* R
public:
+ |0 b+ a( e% j virtual ~CUPnPImplWinServ();) t: h4 j O E* i1 t, \7 n
CUPnPImplWinServ();4 ?3 {1 f+ G$ Y9 T
4 c7 V" S% G7 U
; C( [$ m$ ^) `" D$ r8 X; S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }4 x. L* D5 R0 s' X' p% `
virtual void StopAsyncFind();8 p- g+ f# O8 ]5 H. j4 Z1 W+ x
virtual void DeletePorts();! T; Q! `& L, t
virtual bool IsReady();# }( i" d4 o" e! h1 U8 |
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, q5 B5 i1 C2 b) p+ r- A% m6 ~ |
- F3 U# S- S$ v& D) b1 S) j9 U! F: h
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc); \2 c6 Z: c" _/ i/ g
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later' ?& U" z* v: G$ N1 U: N% |" G" C
virtual bool CheckAndRefresh() { return false; };
; i* C" m0 ~" ~8 X! U5 w
. T3 ]0 Y! d9 f4 ^9 y' R5 N, a r/ N. p" @% }" T
protected:
( D) K4 K3 ]7 f2 }- ~ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
: [# U# z. q9 E9 y& X. _3 ]0 r void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);) v4 x- Q+ V9 X( `9 e
void RemoveDevice(CComBSTR bsUDN);! T `9 F3 p" M0 m" W4 |# }% ?* h- X" o
bool OnSearchComplete();
$ e; ?% n* Z, m# e6 { void Init();
% u* W: D6 l; f B& m F- [3 U9 ^* \5 @$ |. `5 q
; X# U5 q- Z* c3 X9 n
inline bool IsAsyncFindRunning() 3 X2 B- Q- }. H- c6 X. E. L- p
{# ~/ L1 Q! N1 y2 w
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )/ ]7 w$ x$ T5 ^: h
{
a! e* b/ t; M5 z( N( B' z m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );! M7 E# W2 M! D5 l( R, ~
m_bAsyncFindRunning = false;
/ `% ~2 |4 X* m! b6 b$ n }
6 s+ k2 \* u; @* G( s. p. J MSG msg; e0 T/ k* u) w z; Z2 n! q
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )6 c0 @! f& L+ G, t7 j! g
{
* z% V3 Y8 a9 y. K7 L f& m/ e/ j TranslateMessage( &msg );
' d8 w2 @2 S8 O7 s" D3 A$ p DispatchMessage( &msg );/ h9 g- ^# y6 Q5 }2 ? Q
}
2 p9 f% d5 B; C w/ D4 H6 m return m_bAsyncFindRunning;* W% Z: S$ T! B. O
}8 Q. t, G$ @6 N
' H2 [. v w# S- G
" C- w, `/ ` a9 J
TRISTATE m_bUPnPDeviceConnected;
; P' h5 E# o3 J& C, s# z; ], Z/ ?2 l, `/ F5 }8 C" Q
, ~$ g4 S/ F: m$ Y
// Implementation7 P- s' ?( m2 w1 E
// API functions
$ Y% d6 b/ `' Q1 r" z/ Q; L SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( n! X7 v$ D9 H7 C" S1 I
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, H a3 i9 ~0 Y3 k
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
/ s4 i( N2 d/ {2 \$ O* v% H BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);: X" ?8 [- J% X
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% e x% j, C$ P0 z/ ^: {, Q7 E3 f) }0 u
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
3 ^( R8 e, O3 {; ^' `: {- T3 w" O7 Q1 B" ]8 j7 n2 B/ Y
6 V) O) G3 ]2 {! Q+ q
TGetBestInterface m_pfGetBestInterface;
# N+ u- c9 Y9 M. ?1 T TGetIpAddrTable m_pfGetIpAddrTable;
# s _. I; \& X# J8 [8 U8 d4 c TGetIfEntry m_pfGetIfEntry;
9 F6 C( L' H9 T( _9 T) H( T B4 t( f( z+ {- ?
/ L) C( u! W8 F# |! e
static FinderPointer CreateFinderInstance();5 z$ B: N+ C0 f" p F
struct FindDevice : std::unary_function< DevicePointer, bool >7 L4 b r2 s g# }: L
{4 Y. @- R% F/ k+ A
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
. b2 b: z4 W2 y, ?8 T5 V; U2 W- W result_type operator()(argument_type device) const
f# K" [6 b% j6 a0 g6 ^+ W {
* e, s1 O: G, w) r% Y CComBSTR deviceName;
8 J, V0 G9 A# k1 O+ x HRESULT hr = device->get_UniqueDeviceName( &deviceName );
) Y- @% k0 u0 A! c( _* \; D5 w2 W8 f3 \. r' g, ~
" \' s0 f ^2 F9 V1 {. l* L
if ( FAILED( hr ) )
: H _2 e+ t% M* K4 B return UPnPMessage( hr ), false;* z. B9 C) p z# t5 T9 z
" }# u1 _7 @( F1 v/ E. j
j, r% ]* w/ `% ~ return wcscmp( deviceName.m_str, m_udn ) == 0;
" G/ L" H$ ?) W% e3 G. F6 \2 k }% P) ]! l* E3 C( S0 }& J
CComBSTR m_udn;# p: L/ [/ K* m% S% T. ^0 c2 |
};- }9 q1 h- P( T0 x
* l9 j& g) ]: V8 w void ProcessAsyncFind(CComBSTR bsSearchType);
! d: \1 s7 k- j7 w8 J HRESULT GetDeviceServices(DevicePointer pDevice);; w% y+ Z3 @5 s6 s
void StartPortMapping();
; f% a# q% Y# o D HRESULT MapPort(const ServicePointer& service);: e: \, X) S- Q
void DeleteExistingPortMappings(ServicePointer pService);
1 X( {! i$ ]- ]" X% I void CreatePortMappings(ServicePointer pService);
1 m' t V9 {3 N8 [) d0 t HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( K0 m; { X8 X; t HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
4 \. L; C$ F0 \/ x A. a) K3 D LPCTSTR pszInArgString, CString& strResult);
& X; d E: y9 V: `. U void StopUPnPService();) w. z% b" _0 `6 o& J& |& E% t
: c) H6 r- w, d0 v+ {+ N2 i# V- x
// Utility functions% _9 v7 G9 ~% [* g6 m' B0 O
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);" ^( @+ {9 q: ^- ]
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
: r" V1 E5 x+ | INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);$ ^; A' W; B. M# z( H& m9 M
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 Q& C' d; G1 m. Q
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
5 G, a* [* ?# C G HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
% l" r7 t: x* b+ M" J; m CString GetLocalRoutableIP(ServicePointer pService);2 {& O/ R- M: k4 T( Q
6 e$ N3 p9 _8 I# Q' c; ~# `& O
, D: M8 a' R9 |* U/ E% d. f// Private members
' M. v' C, I$ tprivate:1 a/ u1 A m5 M* K% H6 g0 S) k2 J9 u
DWORD m_tLastEvent; // When the last event was received?$ N3 }: v @/ W1 n
std::vector< DevicePointer > m_pDevices;
* o" t1 v" Q5 i* f9 O std::vector< ServicePointer > m_pServices;
4 v- B( ?9 P0 {3 Y' S+ j2 C' u FinderPointer m_pDeviceFinder;
$ @: d; ?; j+ }) D DeviceFinderCallback m_pDeviceFinderCallback;
1 R5 j* S" r" I% M0 k- @" e ServiceCallback m_pServiceCallback;1 ~% }3 }. |$ ]5 q
8 C1 c$ i( z0 r7 T. [
_8 `8 G% J9 m1 @) P
LONG m_nAsyncFindHandle;- _2 j1 g2 T5 d! Z- y# t. l2 W3 o* q
bool m_bCOM;, U1 f) I/ w: V E. K
bool m_bPortIsFree;
) _1 F& E/ w0 C1 Y" b0 h CString m_sLocalIP;
5 u6 O* L& k# h, y) z, q0 p CString m_sExternalIP;
$ |7 b8 v% a$ p- X2 ] bool m_bADSL; // Is the device ADSL?
) ~( X4 K# B N bool m_ADSLFailed; // Did port mapping failed for the ADSL device?% r+ U8 U0 F; S0 s: s, S
bool m_bInited;" ]8 x) o6 y$ J8 M3 X! p8 | ~
bool m_bAsyncFindRunning;7 z4 Z% l. }$ e9 n1 h
HMODULE m_hADVAPI32_DLL;
5 N- P1 _7 G9 l l3 | HMODULE m_hIPHLPAPI_DLL;
$ J. y9 O; ~8 G9 j bool m_bSecondTry;1 c$ g$ W3 {6 ^) _, d
bool m_bServiceStartedByEmule;. |6 z2 \7 p0 A
bool m_bDisableWANIPSetup;7 ^. _, h; H% E
bool m_bDisableWANPPPSetup;
- `2 K! U' l5 G9 \" C1 ] [* z
) z. Q2 ?5 S( {; }
9 w- u0 `7 H, Q! M};. }$ i, _% N* V
5 U% j/ t+ |1 J0 m# v0 i. A
& n9 H0 {7 C6 ~0 L; D! ]( }! Q x// DeviceFinder Callback) O/ u S8 [5 A( H
class CDeviceFinderCallback& i9 k* H; h( M" Z0 q6 \7 M+ |
: public IUPnPDeviceFinderCallback# Q. d# W% e9 f5 z, l6 M9 `* p# |$ H
{5 G5 c3 \. G( m( Z! s
public:
8 V e" [3 B; K0 R+ b" [& L CDeviceFinderCallback(CUPnPImplWinServ& instance)- z; q& S6 V6 D( z4 j! ~0 h1 o, i
: m_instance( instance )0 g; z. C% C8 R# v% b, ~
{ m_lRefCount = 0; }; l7 d* P4 T; u- O& j; V# g6 @3 {$ y
5 C, R0 ^" @9 b( }% ^4 C% w3 H# T. y( s6 M% W+ A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 L$ B& Q* K+ T: U: b
STDMETHODIMP_(ULONG) AddRef();
, O: U: F9 ^+ ?0 H STDMETHODIMP_(ULONG) Release();( c. _2 c# m% h8 `
3 y ]' @! L! H) k' w, `2 i
: b( h8 _- I* T. I0 U
// implementation- `7 `# `; ~- P
private:/ i7 L' K; q. R$ Y5 ?
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);) b; X0 `+ T+ N' m8 P
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);" x$ V6 p% x: N A' O1 e, ^
HRESULT __stdcall SearchComplete(LONG nFindData);7 s9 Y4 g1 }9 ?' a: M; X7 `
7 G; e5 d& R0 r5 }. m* M q' }# A, n- q. M' u i
private:" W0 c% l, O5 A# s' k
CUPnPImplWinServ& m_instance;
* A- n O9 m, ]3 c9 a/ B: ? LONG m_lRefCount;3 |/ n* c$ l0 S6 u. N
};7 ]% _( c; r3 C
- u* K( a7 h" {: W6 ]& F! p7 w2 }" w( X; T: v4 E" O4 u6 [0 b( Y
// Service Callback / t% m; j, }& l: v
class CServiceCallback' t+ q# N8 r) v+ p& L; ^( j
: public IUPnPServiceCallback
. o4 Z; W2 u/ k3 ^) I' O3 b{7 E- ]6 o9 a5 ^
public:
f; h; n% z* v3 o CServiceCallback(CUPnPImplWinServ& instance)
* @. O# k% _ K$ m- e : m_instance( instance )1 a1 I9 D4 u% S; R7 r: q2 i
{ m_lRefCount = 0; }
/ k; M5 X5 O( ~5 [ @0 V : G% I8 ?, ?$ o: K9 i
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); H0 V+ T7 t* e% e! t" M
STDMETHODIMP_(ULONG) AddRef();' S8 P) |+ I, w: N/ ]9 L9 u+ v
STDMETHODIMP_(ULONG) Release();1 u! P) x* p+ r: I; {( L
& c2 o$ y5 e/ I7 h1 f, O6 M
5 v4 i" V& A8 b1 |0 {% r9 h3 r* Y
// implementation
4 N# H7 A% _; G7 P3 z5 Z9 Gprivate:! j! A; e# W" {% L$ k
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
% A4 i5 L" l! A, |8 Q9 k HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
& z& Z2 v0 @$ w2 e5 g! F$ s
+ W( X& g; T* a2 e& S8 s/ H
8 q2 V9 K' j( N1 pprivate:
( x0 {6 L c1 s5 m/ u( s3 I1 L CUPnPImplWinServ& m_instance;0 L2 C6 @8 g3 W; x9 y4 d; O* f
LONG m_lRefCount;
! _2 K g$ ~6 L b};8 i1 J8 Y+ X+ O5 j% d. P! ~. B
- {! d C* H+ P: Z3 F) g( x& Y0 `6 @& C" q3 I
///////////////////////////////////////////////// N: W. E' |% N3 e& t
9 z; h ]% v* b; H: r5 I
, S, L0 ]4 [, e使用时只需要使用抽象类的接口。
, |& x3 N+ L) P- s0 W8 ]CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID./ D+ p% L9 x( U& {( D" V
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
1 J* @; [0 u" x: oCUPnPImpl::StopAsyncFind停止设备查找., J( u+ Q+ q3 P: `6 `
CUPnPImpl::DeletePorts删除端口映射. |
|