|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
* q* y3 J6 b" k) V9 |7 w! g
) x" B" Y+ e( E W8 A/ b U9 u& {+ F
///////////////////////////////////////////
; c' [: V+ v1 T- h8 \7 D/ R8 U//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- `) L; }4 r7 |) `7 ^& T
& K" J S7 V; e3 Y' i' y( C3 Y0 j6 E( I9 {
#pragma once1 V1 v9 m$ |) [3 x
#include <exception>1 Q0 H5 }: ]4 _" [5 I
8 V! k/ C% W2 h. n& y4 s8 |! {
4 r1 a+ _$ \9 l$ G
enum TRISTATE{
8 X( X2 |& h/ v TRIS_FALSE,
" R* a* h) |. L6 z TRIS_UNKNOWN,
# d8 _+ l6 i% @7 M9 z& y5 S6 U TRIS_TRUE
0 l" w9 U5 O, s/ p};
. ^$ ~$ M, I+ t6 ^
# l$ h! b# _6 I+ D; |6 O% k k- o1 V
enum UPNP_IMPLEMENTATION{
2 R2 b8 D. x0 R3 e6 d/ }8 o UPNP_IMPL_WINDOWSERVICE = 0,# b# c1 v* x0 L- J/ S8 x) t
UPNP_IMPL_MINIUPNPLIB,. D8 t/ \( i- g
UPNP_IMPL_NONE /*last*/5 W0 h. ?8 y0 L; k4 n! A
};. y( ~; h/ O0 \
: E; n z& `+ g
& n0 s( J$ N* z' H( i( i
/ l# B5 \0 K h% Q L! W$ C* T: v' z! N4 o) M, {* W# _
class CUPnPImpl9 r8 S9 j8 B P O c4 d! ]9 J
{
* ~0 p: d- m4 b2 Q$ @public:
* }* d8 j0 C4 p CUPnPImpl(); V( H* \/ h+ V
virtual ~CUPnPImpl();' K* C! _* G/ m" s5 d% Z0 g
struct UPnPError : std::exception {};
# w }5 j) B' x P enum {
0 N( s. X, u) i' y UPNP_OK,2 N u% i+ ?; C+ G# s$ Z
UPNP_FAILED,9 l/ [3 ?9 }" ^" G a! r
UPNP_TIMEOUT2 I B* f9 q M& e
};* |6 \6 B2 v0 _1 w. b4 \
4 S0 S/ j. v: T s2 Q$ z# ~7 k" ^" w( D0 J0 g& N6 S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;8 S" u a# ^' a( q; @
virtual bool CheckAndRefresh() = 0;" |6 F4 o; f, p S
virtual void StopAsyncFind() = 0;" L* T q" e( o" {
virtual void DeletePorts() = 0;
5 ~) k* W# |7 Z" t virtual bool IsReady() = 0;
! \% i' j2 n3 ~" x/ Y( P virtual int GetImplementationID() = 0;
* M! E9 i7 ]4 t! r
, j: O- Z; w# D/ [ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping5 {3 @# W7 Z+ E: T6 f
. @* l/ B1 e4 p& i) g
( [' A7 g6 ]( K1 U* }+ B- P2 |
void SetMessageOnResult(HWND hWindow, UINT nMessageID);, N! q. `# \. W( A* E& g. s
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* _8 A. f a' Z! g uint16 GetUsedTCPPort() { return m_nTCPPort; }
. k$ u3 x& k8 w+ C7 ?6 j uint16 GetUsedUDPPort() { return m_nUDPPort; } ; H# n8 E, T* G) Y( u/ P# Z
) J5 a: V u; L, E
+ W( a6 t( Q: U, Y# ~* x6 |// Implementation/ d) }3 @/ Q; L6 k. p
protected:2 t$ r- R' J; G, G. O- R
volatile TRISTATE m_bUPnPPortsForwarded;6 q* ]3 ]3 S7 E8 M
void SendResultMessage();
9 W% J' }. H5 e2 w! [" z uint16 m_nUDPPort;
; Y/ R$ w# Y# U; R8 C uint16 m_nTCPPort;
# @. q! ]6 d0 Y1 L4 x- x uint16 m_nTCPWebPort;5 `* `6 [8 n1 P4 L! W
bool m_bCheckAndRefresh;
8 |, s) Y( X" Q. R. a6 P3 e& E
& h# s& J. J& `+ L) Q4 J' k( F
& Q7 ~8 f4 j7 s8 iprivate:/ ^/ @3 V) w- ?' u4 K5 J9 S* e
HWND m_hResultMessageWindow;
$ u) ]/ X8 @; g9 O/ M* J6 q. O; m UINT m_nResultMessageID;
w: T( E* c6 V
! Z1 |$ x4 L. }" B
# T" ~3 Q' n( J% M1 R. I4 H- N};
) H# b/ U3 Z7 B2 S# r8 d; x' _8 t0 M$ L ?# R5 Z! r9 z4 I8 P
. b% f q3 d& f. c+ G! _0 j0 q// Dummy Implementation to be used when no other implementation is available* o/ r: _: Y. e# V: f) b' s
class CUPnPImplNone: public CUPnPImpl: v! v7 H1 h h: i6 N6 e D5 ?. T
{' T( _& _7 e8 h. ?& R: T$ O, ~
public:! k9 h9 E) c8 Z' V
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" D% k1 C3 F% Q# l
virtual bool CheckAndRefresh() { return false; }/ B; B. h' d" ~" D
virtual void StopAsyncFind() { }
* `5 Y! @: x# [& Y virtual void DeletePorts() { }
H( Z) c V. k4 Z8 u virtual bool IsReady() { return false; }
8 J9 B4 ^& B6 a9 U+ i+ ] virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
$ D- r& @# h, K! i0 \( c" y5 }};! |. l5 P2 C( `+ R
* U/ c1 Z- ~6 q9 c- a+ h: K' M
( v& o$ m% X7 \! |: @- j# z///////////////////////////////////// g6 W! _3 W% V/ h. a: ^9 Y ~
//下面是使用windows操作系统自带的UPNP功能的子类
+ \+ ~+ c- ]- I* Z
7 e1 x4 F- W3 _0 K9 ]. y8 i. m8 F/ _) L+ j, D P' }
#pragma once2 F5 z' ?3 A- [% Y
#pragma warning( disable: 4355 )1 e- a/ Q, t, n9 e7 T, g! H
9 t2 k3 W q( j: J( O4 ^. e
( h) o# s7 k" k+ t* U1 l m
#include "UPnPImpl.h"0 D9 o+ c3 {. e
#include <upnp.h>! s5 d o, l6 d3 q9 `( b
#include <iphlpapi.h>
T8 g) B2 f$ R& M$ e B3 C#include <comdef.h>
; p1 h+ E |2 F) t' e#include <winsvc.h>2 k$ h. W4 N) U$ L' {" Z
8 i" x$ C$ z9 } s) t7 d, r6 ?
) h& B; u) t# N! Q#include <vector>
3 R* C+ f/ w: h! Y8 }! ]8 P#include <exception>
- X) q4 D7 |+ y* c* \. U#include <functional>& ^* A" R; L+ n- k
/ N2 o) R) B2 ]. x7 |% k" e
1 _. F# H. w* M8 _" N3 G
1 v% t8 t. Q; R7 o2 d( x! n, k6 W: @! R4 u% ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;9 R! E' v; |. \( M
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
+ h, f8 F9 s7 p! u5 e% wtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;* J; L1 P8 M4 e/ v( k
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! \7 G1 v/ L x& H% `) f/ J$ etypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 u1 y3 N- v! D* u" ctypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;) Y" @' \( y& [/ A1 j, r
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* J& {: v0 {- Z, k: U( `0 i1 g4 h
+ P8 m6 Q4 w# }
v, z: [" f( j p- b" Ztypedef DWORD (WINAPI* TGetBestInterface) (; T# a( p N2 B9 W; t5 P+ G$ |
IPAddr dwDestAddr,% Y9 j$ a+ U7 B% \- Q5 Z0 |
PDWORD pdwBestIfIndex P$ ?6 m4 i$ N. J6 N7 B
);
: q7 Y: a" P4 [& p$ Y
: P& A8 d0 U) \1 n
* ~5 t/ H* @" D% `* B$ [* c" htypedef DWORD (WINAPI* TGetIpAddrTable) (9 P" m* H+ m3 j: p
PMIB_IPADDRTABLE pIpAddrTable,4 y, c5 i# h& A7 b {
PULONG pdwSize,
( Y# z D* `" K4 i! Q7 T BOOL bOrder
! _$ p$ d2 s% b& ~: n2 r);6 h1 S# O3 ~" m/ q
" q+ m _& {% ~ D7 }% D
- l' m& z* \/ G& R, T
typedef DWORD (WINAPI* TGetIfEntry) (
# G4 k2 h2 b. y8 t6 p PMIB_IFROW pIfRow
1 C! i* h: c( s& W# L. w1 @( Z);$ v; w" [; L! ~ ]. o$ `
1 r; K- w% U! n/ Z
W0 s7 Z6 i. o2 ~: UCString translateUPnPResult(HRESULT hr);
" i, Q9 H5 w4 k, XHRESULT UPnPMessage(HRESULT hr);
; @- j2 p4 E. N; M! `" M! Q
8 j2 Z- \. ~1 U! L9 n& l4 V( f) B& a
* G6 M( p: ], L% ?class CUPnPImplWinServ: public CUPnPImpl
$ }) v! j7 v% ^% z0 @{: E6 l- i6 f& }" S4 Y5 p+ ]* j
friend class CDeviceFinderCallback;8 u( B7 O' r8 ^ @- X: J, h- ~
friend class CServiceCallback;# A4 h8 i1 E. s% {
// Construction6 V! Z' C- h9 [- U1 J
public:
$ `& W: \/ q C* O- B" W W# t* O! ] virtual ~CUPnPImplWinServ();
% b: w( {8 j8 F CUPnPImplWinServ();
# G) a# o& C/ X5 b& v1 c; I) B1 {( U% f- V6 a6 _2 o' P! k; P' B% d
, V7 @ _* k5 D8 }1 o0 _ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }, X9 V' t, A5 w3 }
virtual void StopAsyncFind();4 V" z' A2 M6 i% l; \' T
virtual void DeletePorts();
1 q. b, p. l' ^6 s2 ^+ H3 d virtual bool IsReady();) t _' m1 ^0 G. }) ?: U
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }5 c/ h2 @( G; r b0 f, l! W, }
z# Z6 M3 f% v4 i
! ~3 o4 I$ H$ A4 U // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 \: w4 S$ U& i+ k0 B1 E: `9 ? // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
9 P6 r' K3 K0 T# F4 [; H' j virtual bool CheckAndRefresh() { return false; };
) K1 z0 d* F( n( S. a, y7 O; w3 f& ~6 A" u+ a' _: U
% H/ x1 o! i' Z
protected:. R h; `0 U9 w/ \
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);9 @5 [$ o% X% H; |
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);% ?2 y5 {! a4 c
void RemoveDevice(CComBSTR bsUDN);& ~! M5 C. [4 n* B, ~! Q: B
bool OnSearchComplete();+ ^* Y* U; x; q
void Init();
% \4 }9 f5 T9 g4 C
5 k/ N4 J0 [8 o+ |& f3 F
& _8 a7 u/ ^9 Z! h& W4 W! r, ?9 L7 f E inline bool IsAsyncFindRunning()
5 f' t4 Q9 t3 V( q {
, t3 C; [ `" m: r# e. E1 [ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ). l1 d0 m* h$ ]
{
" X* L6 f u3 l" y' G' k P m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );0 o7 { T4 }4 t
m_bAsyncFindRunning = false;; j6 ]: l2 _. v3 Z% X
}
h4 x ?% M1 `4 }& K MSG msg;
1 f* I5 H2 E* { r. c while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 z! B5 z* U" b6 {4 l1 |, v6 |; R
{
' d& [( a; ?; _. ~. y" z3 T7 j. l TranslateMessage( &msg );- k H. d' ]* a/ h
DispatchMessage( &msg );! ~; e* y, E/ V; k, ?. D
}: i, i4 x6 Y# k2 W& `+ n
return m_bAsyncFindRunning;' {' `0 ?2 k$ c' `* `1 b
}: F3 l( S' }: u( E: G, s2 w
( ~% J6 Q: Y4 { Q+ M1 g: ^1 f8 L
TRISTATE m_bUPnPDeviceConnected;
7 I, S! B0 U+ @! D C" O: y, z n: v, [/ \ `1 Q9 F' z0 X, H2 R
# A8 U8 i( e* o- F# e4 C
// Implementation
9 T0 e7 @$ c. j6 \7 w; K/ N' {2 F // API functions! e) ~5 f. Z6 c+ S+ m. p9 q) V
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);. O* V0 @. \$ X2 ~) I1 O
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
( _& ~" Z' b) a BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
* A+ ]( G+ e1 I \' L8 `$ J BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);0 t+ A# C. T7 g% k0 l& P! Z
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);6 i+ X% {: i- v- }% `) }& I0 S
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+ d2 X# L9 p- [4 _# T/ w7 t2 C/ u" {) o3 q8 O
- m; k- ]6 i( z+ |0 { TGetBestInterface m_pfGetBestInterface;6 B2 ?- M% x5 u# T! L. s, l/ L
TGetIpAddrTable m_pfGetIpAddrTable;
2 n, p/ J v; d9 q TGetIfEntry m_pfGetIfEntry;
# ?* K; T( N2 l& n2 y
6 h, j: m! z) j C4 J) [; [# e
$ v& [6 c+ c! [. p& r P static FinderPointer CreateFinderInstance();3 \! ~ t# A5 J6 d* e U
struct FindDevice : std::unary_function< DevicePointer, bool >
) h( x" G9 \' Z/ u) Q, _$ x {
2 j2 {% B4 u9 A8 F FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
; l1 p; n0 L' A( k' _! a result_type operator()(argument_type device) const
( K: }, p5 B: p3 B {
K: k: w. D/ q& T, x, M, z+ \ CComBSTR deviceName;
( T L+ O/ o& A' t- y5 n7 q! D HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ T) t' @ Z; |- w
# w% a Y2 M. G: j
' K0 \8 k9 g6 K+ s2 c, Z if ( FAILED( hr ) )
! K, p/ ?' u2 N% r/ C D$ U return UPnPMessage( hr ), false;% l. z+ H1 i6 D" ]; U
1 i" _' D! ^$ W& d E. b$ H2 P" o% W4 Y" d6 s2 D
return wcscmp( deviceName.m_str, m_udn ) == 0;
$ [- W- `* r) A( B. A0 I) a }# D7 u' M" ^) s
CComBSTR m_udn;9 E" u7 w$ {! J/ ]
};
2 x$ n9 o/ Y0 [; v0 E2 ?
; p4 C' B: z. _$ \4 y( G void ProcessAsyncFind(CComBSTR bsSearchType);! ^1 I" R6 G. B. R
HRESULT GetDeviceServices(DevicePointer pDevice);. m9 s! G9 c, c1 a( T# u
void StartPortMapping();: d G/ t' ~7 \) }
HRESULT MapPort(const ServicePointer& service);
T3 b3 x( s6 n9 s8 l void DeleteExistingPortMappings(ServicePointer pService);
% c' T: {1 f) I' _ void CreatePortMappings(ServicePointer pService); G G6 M; F0 Y2 I {
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);3 d+ v8 o ]0 s2 }
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 7 p. s% t8 Q: e6 u5 K2 H
LPCTSTR pszInArgString, CString& strResult);
$ O4 s! {# m3 |, D void StopUPnPService();5 g3 U& t2 z% T6 E4 `5 f4 `
- D; o# o6 D X# }. z3 ]
% c6 U2 b$ f! ^0 ` // Utility functions- Q" r5 C) q# F/ R- @
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);# K7 E! u5 t6 ~0 o+ b. O
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);! p' |6 P+ M% Z0 F- e$ n
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
! n) A' S# S1 H9 ~% v! R7 n void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
; m7 v9 j. T. G% [* {) D, | HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
" i+ f7 c: @+ ] HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);1 I. ]0 n& J0 w8 D. M
CString GetLocalRoutableIP(ServicePointer pService);
- X# H5 ?& T9 {) R6 m: Z" t4 G. n/ w
) q4 v+ [1 W5 _8 T1 [7 v
// Private members
8 S4 w" g1 Y* ?3 N9 ], v Kprivate:9 w6 P9 N& ~9 E: R- W9 i
DWORD m_tLastEvent; // When the last event was received?
6 h. L. |; u# P0 i std::vector< DevicePointer > m_pDevices;
- O! r* s/ m9 B2 ^ _ std::vector< ServicePointer > m_pServices;
0 q. I- a& _$ {4 p FinderPointer m_pDeviceFinder;! f# s6 F% l1 Y g' X" N7 _
DeviceFinderCallback m_pDeviceFinderCallback;" d1 t, }: }4 U. L' s
ServiceCallback m_pServiceCallback;5 S: \1 a$ y0 C# }4 `
; v- U- A- T2 x& U9 [- p1 c
# ?' ]: D; g- d' v7 ` h
LONG m_nAsyncFindHandle;, j2 r3 M7 l% v, S/ [! P
bool m_bCOM;) _7 U' s! y3 N& | V* u3 y
bool m_bPortIsFree;
. j1 ^# H3 P& |7 l+ X5 b; o# e' t k+ e CString m_sLocalIP;
# w. N" _. H' k7 k" r CString m_sExternalIP;. M# @" _! R/ ^) p
bool m_bADSL; // Is the device ADSL?! V1 t) Y- D$ P: G8 V: |8 m/ ~
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
P8 }% x1 d$ ?8 f7 m+ o4 Y6 _# R. t bool m_bInited;% c# T) r* p( B7 j6 I( r+ [7 ^/ x
bool m_bAsyncFindRunning;
& a* ^* M; \% z- Z' A HMODULE m_hADVAPI32_DLL;
5 E) l# X# R5 z# k- ^% o HMODULE m_hIPHLPAPI_DLL;+ G z$ Q$ f9 T& c5 C1 `
bool m_bSecondTry;% L6 x0 j% F& P7 f6 S7 B$ v
bool m_bServiceStartedByEmule;6 U# {* [0 y, K: X* k7 L
bool m_bDisableWANIPSetup;8 v* h4 g. h$ F4 K* \; p
bool m_bDisableWANPPPSetup;
4 p! x7 X0 m* j4 Y. u) U- L, m% L: I. G. O
$ L2 H7 D2 d- }# M- B0 R, M};( W/ t1 M# q; E U
: p3 Z$ D, I$ A& Y
* A4 A' B( \/ H: H// DeviceFinder Callback
6 M- L; v3 E. u5 s( c; E9 Q7 \class CDeviceFinderCallback0 P. q5 L: M7 T3 i( G
: public IUPnPDeviceFinderCallback5 C0 E; m: v$ v4 ?" F5 L
{7 k. j' v& k' G8 \. g9 e5 _
public:
8 h& r! S/ V: s- G: H/ \ CDeviceFinderCallback(CUPnPImplWinServ& instance)1 [/ j3 W8 e( b; n) B
: m_instance( instance )( H$ M- \$ K) E, l B6 s. [, z0 [
{ m_lRefCount = 0; }/ |. h0 X; _9 e" C M
+ [- z5 t- t3 w" q( [
/ k$ G1 ]& W6 t: _% {( a+ ? STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
( x& ^* D( {; t& p STDMETHODIMP_(ULONG) AddRef();) f h/ D0 ^8 s9 ?# b
STDMETHODIMP_(ULONG) Release();
8 i+ |! F R& h* |6 H5 ?
+ }( _4 [+ A8 n; ~9 _! k! l/ V: {. \6 f, U8 `3 y0 A
// implementation
0 u1 Z* S9 O2 c, B* E! a( Y& `/ xprivate: Q3 }& D' {9 [
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);) t# _$ \, V( w
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- a# c9 l# a8 e! i8 c; x
HRESULT __stdcall SearchComplete(LONG nFindData);7 T8 _2 g+ x6 q/ A. }: J! H
4 p' c$ N4 I5 z2 X! d
( r! D% @7 o' s/ y3 s, mprivate:
) `. p, }, v! s) K* D CUPnPImplWinServ& m_instance;; t" y) y. y' k; y6 ^1 f: p( I1 d
LONG m_lRefCount;
3 j, H6 G. v3 f6 q};! `+ R+ j* M' A- c9 I9 \2 N
: Q( X! a3 D1 D/ L1 g% q
/ w) k3 V) A) b7 i% }1 h% g// Service Callback 2 X$ ~1 H9 f3 g. |2 @
class CServiceCallback9 ?+ P7 k' E0 T, g/ Q8 v [7 g4 e; I
: public IUPnPServiceCallback2 q: W7 [5 m& O* f1 f8 x! W
{
3 O1 k! h: I# R( A3 t& o: Ypublic:5 }6 V. T K7 u
CServiceCallback(CUPnPImplWinServ& instance)
1 ~- C9 Z9 l- q* G0 }9 n3 v : m_instance( instance )
1 n1 c' J, E# H3 s) K; [1 V { m_lRefCount = 0; }
: z- v! j; w p5 J1 a
0 u/ E( I: y! [% j. l# m' c: w STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 d; S& P8 M2 {5 _+ G3 {7 d STDMETHODIMP_(ULONG) AddRef();0 t$ m M, z' I3 Q2 A9 ^$ }
STDMETHODIMP_(ULONG) Release();
2 W, @) M% v; H0 f7 X' G. k$ P7 ^: W5 y2 I
, \2 E# {. |5 r. q/ {// implementation" z/ J, R' X1 e# H- A, a
private:
- k) K: Q# {6 \# Z' J) K9 M. N HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
0 n; ]) g+ ~5 z k$ c8 y' l HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
% T5 P0 |$ i! Y
) B7 l& f h* u2 @, I. M
; s: H2 r. O& c" y0 f/ A* X' n0 Qprivate:
8 F0 z2 x8 F1 V2 k2 @ CUPnPImplWinServ& m_instance;
: t/ a( M( w+ P/ X) l% q- {$ H, h LONG m_lRefCount;+ ^: Q6 O$ ^% k f
};3 M6 X6 U4 J B! ]- E, Q
$ d4 T5 d/ @1 f
' Y5 B- X8 q& Y. k- X2 N) E ~/////////////////////////////////////////////////
2 |4 z8 q a/ K/ `* X6 G# k3 a5 `( w
5 A. i6 n" G! W+ ]. q3 U
使用时只需要使用抽象类的接口。
( J/ y. V4 o; uCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.. S1 c! s: p% r% A7 p! v
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.3 }; w0 [$ M$ W; m) P6 j! E6 E
CUPnPImpl::StopAsyncFind停止设备查找.
2 @& U/ M: o8 c1 `$ iCUPnPImpl::DeletePorts删除端口映射. |
|