|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
- Z% P2 m3 u% b9 j: p( R' G1 t) R* P# {$ u7 E
% u0 h4 L+ {( a4 q. M) z. R! v///////////////////////////////////////////
* h5 l# \; e3 a; c, M//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 k9 `* Y- I6 Y" {9 H( r7 a6 [2 q* A! b# C- \
+ Y @$ J0 L" z& u#pragma once% M7 C9 m' z$ }$ `3 O1 j
#include <exception>8 C v1 I4 w! L' l5 D
+ t% Y0 {0 H$ ~8 d- ?
6 J; `, l+ D; R* q enum TRISTATE{% U6 z6 O6 D- h/ }
TRIS_FALSE,1 C9 Q/ L9 }4 Z1 j
TRIS_UNKNOWN,& V5 e- h1 h% V- U) T$ Y
TRIS_TRUE
3 ?" ]+ x/ ?/ h* k/ z};1 o! g' [9 K' T7 W1 m
0 W) a/ X+ I) ?1 t
' w; W* Z6 j5 W6 q' D
enum UPNP_IMPLEMENTATION{
: f( E2 S r; ] UPNP_IMPL_WINDOWSERVICE = 0,/ R; r& Q6 V8 B9 W, u$ |
UPNP_IMPL_MINIUPNPLIB,
5 a2 o4 |" W2 S# e+ f- P$ } UPNP_IMPL_NONE /*last*/" b+ q2 Z ?# m$ g) k* }
};
4 M# h* [( w- ?. Y6 }3 K5 a* O9 @1 R- e' I7 d
$ y" q1 Z* l0 r h5 |1 f; L9 b l
/ g" J$ g$ k3 J8 Q% h2 d3 e1 U' k+ l+ \3 H$ b) ?! w
class CUPnPImpl
% _) c* q( g2 g+ {6 U{9 U" Z0 s4 v) ^( X2 B
public:
$ E" X% O0 Q1 t. q6 C CUPnPImpl();
8 _ \3 b Y& |. {! L virtual ~CUPnPImpl();% C+ O' h1 ^5 u+ Z
struct UPnPError : std::exception {};9 D/ W- j. J; u/ L; A+ `, N
enum {
( z8 Z8 r; V$ c' Y UPNP_OK,. r5 _: x. k! V$ k4 B2 w# v2 l5 g% Y
UPNP_FAILED,
4 n7 J' V/ ^/ y8 Y2 K2 B UPNP_TIMEOUT
1 p h3 C% p- F };
& A( V5 }) m8 C7 b! `' `" B" K; o; D5 T {: r
9 r% T1 W9 V! W; F% K7 T
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;' R S# f3 r* v, {- [8 r( r
virtual bool CheckAndRefresh() = 0;
# s, q! L7 \6 L. K virtual void StopAsyncFind() = 0;; n1 w3 k% o O8 G0 f6 w
virtual void DeletePorts() = 0;, H" `8 M0 T# H9 |( N
virtual bool IsReady() = 0;
( ?6 j0 u) H( W* a/ ?% |( p3 T/ G virtual int GetImplementationID() = 0;
' I$ B& l- v3 a % F* J' l. L1 _& ?- h* I2 O
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping8 o+ i9 Q; ?: t; j2 u5 }. l9 h
$ W, g/ z: e! D* c6 n, D6 F+ s
' m7 i3 P/ |6 Q6 u- b+ v# }0 J
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
' i$ V/ v C9 }- n TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
: l% ]0 b4 O4 G4 x0 m6 J$ \ uint16 GetUsedTCPPort() { return m_nTCPPort; }
, E @; S9 a1 f% u& B# ` uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ `6 o; `/ T* G" O7 O1 A
1 @1 }9 J7 r1 g& E @" J% q
+ N* P' H6 l4 Y// Implementation! J0 ?( ?5 h/ ]- e
protected:3 |5 D% }3 h% w& n/ f; d, N
volatile TRISTATE m_bUPnPPortsForwarded;( h5 c, d0 }0 u, b1 }( X+ H
void SendResultMessage();% i/ ^# }5 U r+ \* t2 \: W; k$ t
uint16 m_nUDPPort;! V/ Z' y: u3 ?! x* K4 G' f
uint16 m_nTCPPort;: D3 X. L% L' }. o
uint16 m_nTCPWebPort;. x6 L3 n6 s: r& u) \
bool m_bCheckAndRefresh;1 l) Z6 k% P/ n4 M6 O: g6 A$ i
) `4 b; m4 X* u% ~2 o t9 n, v. \" n8 @. `( x, C- c; ~1 P6 u
private:
7 {8 h" g" q, N, U& C" m& R6 y, M HWND m_hResultMessageWindow;$ N: Q5 i% F* \
UINT m_nResultMessageID;
/ Z3 ]" V Y% S% c/ N/ b
( g1 Z9 a' A \
- y1 {$ S0 g- D9 B};
5 ` _4 F8 @9 A" s% g0 \5 u) Y/ ^. k0 M
. x# y2 v' _6 s1 W* N. V
// Dummy Implementation to be used when no other implementation is available
) J1 C0 t1 s2 L; q; B( d! Hclass CUPnPImplNone: public CUPnPImpl; _; F, \. z* K: \9 Z6 u
{. @1 Y2 m) E, A3 o: ?0 ~" Z
public:
! G1 U2 C" j( y" h virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: k2 M$ L2 w. C virtual bool CheckAndRefresh() { return false; }
4 h7 v7 m* z; v8 B4 q1 R$ d virtual void StopAsyncFind() { }
3 H. M- |, F) n) o M virtual void DeletePorts() { }" R; W- n" `3 Y
virtual bool IsReady() { return false; }: G! J1 a. p7 T) B
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }3 L9 i* L: I$ Q
}; a, c0 w, u, C8 W0 X
) D# N5 s8 s6 R7 T
4 {# P! K& x* | _5 I
/////////////////////////////////////
# W5 ], T0 W3 k: z* O//下面是使用windows操作系统自带的UPNP功能的子类
: _) \ [1 Q8 ]9 t& E
' M4 T; \- B/ a8 [1 g9 Y0 G `# H1 Q* ?- b% m8 V( ]1 A g8 f$ i
#pragma once/ Z- A+ U% B, ^4 }7 A- A7 A: {* g
#pragma warning( disable: 4355 )
" e L4 c! b# h& O% y
% B4 X; ?4 A0 n6 k; K# h A' I. E. G+ u7 o& x& v
#include "UPnPImpl.h"
! W3 Z0 t/ \. _4 S6 `6 J, R6 U* l, T#include <upnp.h>
5 W9 v/ c5 N/ L#include <iphlpapi.h>' C5 y. o% D$ |6 b) ]
#include <comdef.h>3 V' v* K! R$ r
#include <winsvc.h>0 F( f+ x' i2 R! M% y% ^1 e9 E
& G4 a. x4 S- C, ?: E
1 O/ V$ z. J! C L' M
#include <vector>
4 V7 e+ g/ R9 K+ Y, E#include <exception>
. R- Z7 p' L' Z$ t" J% Q#include <functional>
9 r& D- D' e$ I! Y( h6 r& X t2 `* s& Q6 V% E5 k
1 C! n2 z3 m7 I! ^4 E' O. H- Y
& J) F* |; Z! Y" m3 C
1 S/ _ a2 r* k. d4 G$ Q/ @typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;2 S; m1 J" L$ p
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
9 [6 ^, N }+ z6 B3 \* itypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;5 B5 d5 K1 b8 ]6 S0 V* ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
1 ^) Q7 a" F( mtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;- |' C3 N6 N" V! [9 H( a( g
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;5 W9 R" I% L5 X- r2 u( ?6 H, W. y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ t4 o0 w/ J t7 z& x9 r. _/ B) t
4 s" l" x) J# f4 X$ |9 x/ O2 q+ ^
. N% [: x( a% J# x9 w% S
typedef DWORD (WINAPI* TGetBestInterface) (
2 w7 o) G% M0 e! e" S( m- o. E IPAddr dwDestAddr,
4 O% o9 F; i! T+ s; L PDWORD pdwBestIfIndex
/ B; U- v0 P' e) y0 y& Q4 s% r);+ \4 K& T# j+ A ^2 x/ D8 S
$ b) G/ z0 ^' T3 y- \. P8 ?: K/ F3 `/ P
typedef DWORD (WINAPI* TGetIpAddrTable) (
& B# W8 B7 b ]6 D r; z5 O1 w PMIB_IPADDRTABLE pIpAddrTable,, j6 T& x$ i7 @$ F3 G( _
PULONG pdwSize,
1 J% s( o" ]1 c u/ M BOOL bOrder! \: ~( u# ~) i" A t4 l
);
' q& }8 x) h1 F- W6 u4 B8 {) Z& r# d* J
2 G# P' S. M8 Rtypedef DWORD (WINAPI* TGetIfEntry) (! k, d* w7 _! K, |/ O$ M
PMIB_IFROW pIfRow! J5 ^' K) y3 Z* y# _. D# y( ~5 b, j
);) b- v# ?- p0 f% U0 \9 e% w" }
r: d/ P" l7 q8 T
8 N4 V: R# O( t, A7 t+ a c
CString translateUPnPResult(HRESULT hr);
' p" I& I, j! a2 x5 u2 }HRESULT UPnPMessage(HRESULT hr);. t9 P/ e9 S% d3 G) `
7 P+ j4 k) `& N* z3 ]7 i a
9 C8 o2 Q# |( ^" h: Xclass CUPnPImplWinServ: public CUPnPImpl
% U' n: p4 O) |) V0 M, W{
4 x) i. m5 f7 g' R4 W5 S% j# j9 Q& V friend class CDeviceFinderCallback;8 X/ E& Q2 Q5 [: z: O" L' ]4 q9 o
friend class CServiceCallback;
& ^: t$ Z- J- r9 i6 x% n// Construction# ~ \' }8 z- e4 V: g
public:% q0 \7 J; I, ^) b& ?
virtual ~CUPnPImplWinServ();
P2 W( W- L }& g5 Y CUPnPImplWinServ();
' T7 R& \" x8 C1 _
# S7 R3 L) v( i1 f& X, h8 A$ i' Q# c/ {4 l8 F5 _+ g
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }* x/ j8 x1 o% {0 Y- Q
virtual void StopAsyncFind();1 Z0 |2 S% d$ M v% a0 x; H" p ?
virtual void DeletePorts();$ T2 Y0 ?5 E! X7 ?; Q
virtual bool IsReady();
1 m9 {0 v. D3 d4 X7 Q: {, l# p' | virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( ] G" P9 B* }- V% r& n; i8 [' L( Y- m, j1 k2 Q5 i
/ w7 I% M4 @: U! r1 A" U3 X* S
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc); R3 G& l, t7 ~
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
: q+ v* |3 d9 o0 R* ` virtual bool CheckAndRefresh() { return false; };. X1 k4 K+ G# R' E6 n
8 \) g6 d8 @6 L6 M8 T" V
% |' V* F7 ~0 \! a. m" sprotected:
! a J0 z& M# o" r+ w2 w" T. L1 f void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);' X7 A' }6 L1 [ z' d* D
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);) T" C! ~: v: r: [3 {2 o
void RemoveDevice(CComBSTR bsUDN);# g& c. d& v8 K ?8 N
bool OnSearchComplete();
2 z* y' r; i0 Z% E4 j7 i5 {: y void Init();: r% Z7 Y0 I0 l* i/ j! |
, F9 Q3 Q, ?; _) s1 u5 ] d
4 l$ h" W5 ?6 T; m9 ~ r/ O
inline bool IsAsyncFindRunning() 3 e& K- f- a- D9 _8 w! K5 {; ?% d
{* q1 T" N, |9 Y1 _9 l
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
! Y7 A8 K9 M1 r/ h. D: D {8 |! A. S) }" p9 W8 V
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );" V" s, @; R+ w* a5 a: ^% F
m_bAsyncFindRunning = false;
3 G0 G. [+ q- v& U }6 k7 Q4 f+ D, U8 E" f5 g; H
MSG msg;
( B% z% b' u3 v7 J7 z while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ). N# J# x" [9 G( G" ?3 h
{
; r- I' x/ Z) q5 Y5 g9 p$ q4 U% ~ TranslateMessage( &msg );
# B+ T3 Z" ^6 Y5 e DispatchMessage( &msg );; m+ A$ H I$ t; g/ S- P( ~
}
$ H9 C6 K; H% {' N; G) d. y( W, Q3 V- l return m_bAsyncFindRunning;! i/ a* L- j( M/ y$ ]) R
}
/ `5 a- Y8 e) e
1 T" x0 y |2 h0 ?. \% S
6 S; {7 p- v+ d6 i1 r3 M0 ^2 r- o8 N { TRISTATE m_bUPnPDeviceConnected;0 b( w t& Q8 D. {1 S* G
2 P+ _. E% w! f: c! X4 Z
, r% c- [7 h. C# u// Implementation$ S+ I1 p$ \7 f1 r+ P) |+ s6 M
// API functions
, q" h- q u6 M4 _3 x8 U SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);; v' U2 H& d! Q. Z
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);/ k5 J5 Y) L, A- K; Q1 y8 W; O
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
; i$ p+ N( z4 H; o/ x2 u6 O BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);9 P( L6 X! P+ Z" s1 J
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
8 ~# C4 {& X/ Q, N, r, `: g BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' q2 [/ f# W1 o! ]: S0 w
/ w! g3 f4 x3 x( p6 V) \/ ]2 e7 y! p8 k% F0 G- c1 G( l
TGetBestInterface m_pfGetBestInterface;$ A) |0 U9 _* Z S }
TGetIpAddrTable m_pfGetIpAddrTable;8 `+ j @% A) [# r2 R
TGetIfEntry m_pfGetIfEntry;
# o/ y* K7 B3 j, v" Q2 i G
9 B9 B2 I4 b# ~
2 y- Y$ d' I& ^) k9 M; k p! Z static FinderPointer CreateFinderInstance();
* N* m" F5 E* z5 J4 a% y struct FindDevice : std::unary_function< DevicePointer, bool >
) O J9 ~0 {; r; r8 u/ z, a0 } {, O( @& z: c Z% A9 l5 d
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
6 t( R6 }0 |) f5 N7 H* n result_type operator()(argument_type device) const
6 I. P! B/ Y. g9 @" Q {$ Y8 q" ~; k- [1 a" v- `* x4 l
CComBSTR deviceName;
4 Y, n v2 u/ \! D6 Q HRESULT hr = device->get_UniqueDeviceName( &deviceName );
/ u* N4 }0 Z" U6 ~5 U* ^
& O3 r$ Z' ~7 g
$ P6 p% w& n0 A5 k3 _9 R if ( FAILED( hr ) )
2 Q& }# K0 n3 A, C) P, u return UPnPMessage( hr ), false;" I% w$ O) m6 k5 \2 l
# C3 Q1 [3 w! n6 j7 m2 C5 T$ d1 j
& l5 T E/ N) h( j8 p7 w return wcscmp( deviceName.m_str, m_udn ) == 0;
$ @# \+ U: X- w0 o }$ D6 a3 o& P0 L9 o# j2 {# w% L
CComBSTR m_udn;
% }0 G& ^2 Q' c8 u) C/ N1 d };
! }" O9 ]$ [; ^8 D( Y 3 u: i' P4 g5 t7 r
void ProcessAsyncFind(CComBSTR bsSearchType);8 ^$ U3 X6 l T% B9 W( o8 l8 k
HRESULT GetDeviceServices(DevicePointer pDevice);! i, o' b# w2 w9 [2 `/ p3 s
void StartPortMapping();
) E: J, ^0 [' g* F5 L9 _0 t HRESULT MapPort(const ServicePointer& service);3 n, a* Z3 G6 i* D7 C/ M- B7 X" }
void DeleteExistingPortMappings(ServicePointer pService);/ q# J; P/ d% h3 o0 g
void CreatePortMappings(ServicePointer pService);
: l/ x, T, U' O& r HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 e0 a* N+ K' C- o# x, S
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, " L" n' f1 Q6 m3 ^
LPCTSTR pszInArgString, CString& strResult);# w! X3 n4 [9 I: h! ]
void StopUPnPService();+ h* m4 l5 Q0 l" K4 o
( E) ^, U: y$ l9 n$ [/ v$ q
9 m( T4 j+ I" F7 x4 ~
// Utility functions
1 v: N/ O8 n p% } HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
$ u- a- h* t2 K2 I, d INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ E4 f) s0 Q0 w" s6 D( n
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
& @& H* Q- k' O! W+ P3 d1 a void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
1 @, D5 Q9 i6 f3 ]6 y HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);, ^4 t- `* S+ B& x" N' o6 @
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);( a3 J; H9 Y" w0 D: R7 E+ A! H
CString GetLocalRoutableIP(ServicePointer pService);% f1 `6 P6 i/ Z! a3 S
7 |6 L. }- H1 U1 j1 G- p" }0 n" l( b/ G
// Private members: ^" r$ q) y% i. [# n
private:
5 b6 b. X4 s9 d4 ^& j7 ^) K6 Y M DWORD m_tLastEvent; // When the last event was received?8 @- }) T1 N) j$ a7 h; A
std::vector< DevicePointer > m_pDevices;
$ l/ e* P5 @* E4 a std::vector< ServicePointer > m_pServices;
6 k( Y. U4 a H/ M. f! j6 h% y( i% t FinderPointer m_pDeviceFinder;
! O* {6 ^: `. a1 Y DeviceFinderCallback m_pDeviceFinderCallback;
3 E W! \2 n! O! H0 z$ u ServiceCallback m_pServiceCallback;0 ~) t: S: l0 X6 k+ y; x" J
! W" A. k2 i7 b% k2 j! D6 Q. O; J% i
LONG m_nAsyncFindHandle;8 o& |: _3 {: p- |. v! T
bool m_bCOM;1 ^; V/ A6 |( C; u& Z7 N: i% ?
bool m_bPortIsFree;
- W1 I' n8 E+ T, F, ~ CString m_sLocalIP;
: {8 x: l$ }8 U CString m_sExternalIP;
' g1 f2 D, s& [/ X- m& K" n' G, x bool m_bADSL; // Is the device ADSL?0 s, c$ B$ x K9 D- H
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
- s# f9 l* x6 j bool m_bInited;
; V8 b4 u) y* m. t* H) s: b! A% w bool m_bAsyncFindRunning;# G) S7 e. i' Q/ s
HMODULE m_hADVAPI32_DLL;
. W: w, ~; O8 c HMODULE m_hIPHLPAPI_DLL;
0 N8 L ]: X$ w) }$ M+ R bool m_bSecondTry;
+ H0 M/ j# |6 [6 b: B7 A& | bool m_bServiceStartedByEmule;% u9 ^& H3 X& ?. M
bool m_bDisableWANIPSetup;7 g u; u) u4 N% g" n' _. u
bool m_bDisableWANPPPSetup;3 F! m+ E; Y# N, [# D9 n
$ C* [: A( r" O, r+ e; J6 P. Q P c1 }
};& r c, r5 b; J" {# ]# K
" Q& G- y& N, B' [' A3 y! ^6 O$ L% m
// DeviceFinder Callback
' [# b- K( S- F. B4 lclass CDeviceFinderCallback0 T1 E. w d: f
: public IUPnPDeviceFinderCallback
" E! o( U$ Z/ C6 k{
: z4 \; s* e; Ypublic:: Z b2 w% ~% Z- J& i' k
CDeviceFinderCallback(CUPnPImplWinServ& instance)4 {* Z2 X) g+ L9 ^- @ u ^: N' ^2 v
: m_instance( instance )- v! @0 Y1 r5 k
{ m_lRefCount = 0; }
0 j" Y/ J8 }+ E9 D
* a8 \+ h q9 m. `6 T, P1 Y E. m: y, V ^+ {( g
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 Z; a/ ?4 u+ S STDMETHODIMP_(ULONG) AddRef();
7 d7 k1 f0 a3 Z0 X& y STDMETHODIMP_(ULONG) Release();8 R/ a1 j& u$ R5 ~ y K* {
' R$ u2 T, m9 E4 k* I
* K ?* Y9 R4 @. ?0 u9 j// implementation$ n: |2 S1 I7 t. n
private:
! L" u q. x6 S; b/ m" b HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
8 d P2 g# j" I! q) { HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- S1 `, o+ G# l; W5 W9 D! W' R
HRESULT __stdcall SearchComplete(LONG nFindData);
" S4 o0 L' z4 k3 |" j
% m9 j4 H' ]! N/ u3 k! L0 u A- m3 [
! [% K6 e' p# j' d- }/ v9 A/ jprivate:
, d! A0 [2 ?' s CUPnPImplWinServ& m_instance;
" P7 T. u7 d( z0 k* b1 y5 P LONG m_lRefCount;
5 F/ [3 c3 i" S$ v6 F9 U. i};
! y. D: j, J6 D9 Y: M+ c7 t, U
1 I* l* u _: r# u& j5 s6 L0 H& o3 R/ K! z& @6 z7 }- Y% ~. ^
// Service Callback ; K1 v+ l( q9 f6 f+ L# Y" `
class CServiceCallback
4 i4 \9 I* ]3 {% Q : public IUPnPServiceCallback
1 ~0 [$ O5 |, T4 n! N{4 e5 g2 [% v4 Q3 f3 R/ u: ` B7 j
public:
! f9 p6 ?5 R; e3 ^! D7 v4 O; V CServiceCallback(CUPnPImplWinServ& instance)
! ~6 U. f w7 @+ }" F) x0 b : m_instance( instance )
- O2 R( z2 m1 d' e0 U/ _; A { m_lRefCount = 0; }
' N- D. B8 G( q/ p3 t
6 U: k. R9 ~8 |. i$ M: x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 `, ?" _- l1 P
STDMETHODIMP_(ULONG) AddRef();9 j- K: s6 p$ r7 [4 u2 U
STDMETHODIMP_(ULONG) Release();- z5 L, P3 _7 w: L" ?( w4 T
- n$ G2 Y! p, c- W* Q
: H* C4 q' p- Y2 j( a# w; d0 J// implementation2 y3 _6 Y4 h2 T. d# @3 ~: r
private:
4 C# ?. }8 D7 c& z& N1 A9 Z HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
8 ~1 L1 w: u3 Q* A. }& B6 K$ Y HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
. n# X1 G: e5 O
7 t5 z: T) H1 {. t6 |# `* s" n5 v3 j3 o
private:
1 C3 }$ R8 i; ~/ d! j CUPnPImplWinServ& m_instance;
7 C y& Y8 ]5 P9 k! Q5 K2 N LONG m_lRefCount;
. L+ F1 D0 t( k7 b$ b3 } \( \4 E* v};
' z" W& b5 M5 r2 V) \9 H9 Q
H# N! M$ F0 ?
) u. @0 N' D2 N9 @+ L/////////////////////////////////////////////////
2 r8 G. |" s' g0 l* g8 D$ y- y) o H0 P/ \1 D
7 d/ S* ~( E3 H& p& ?" c- x
使用时只需要使用抽象类的接口。% Z8 ?8 q3 R& h7 {7 ?
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.& v* ?3 k) n C2 X2 a
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.# E( q2 L/ C' C
CUPnPImpl::StopAsyncFind停止设备查找.
: e# }/ \( H: ~. O' QCUPnPImpl::DeletePorts删除端口映射. |
|