|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
8 ~# x9 @( ^4 v0 r% a, \) g7 Z; W
: u; C# x- i6 `7 W7 Y# }///////////////////////////////////////////
# A- y. w% ~9 A9 _' K//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 M! F, [$ |* D1 v
/ y' I7 i; C; w( D
1 p. w* Q. A1 [! [8 f#pragma once. B" _; ~, M: U6 I& H
#include <exception>
5 o' z2 M9 h( g9 a) t, k( |) @+ f2 p6 l4 |# K( b8 d, {7 n
8 T' k% ~* a2 n9 ? enum TRISTATE{7 r# H, x; N* z1 H
TRIS_FALSE,
% m5 i' r# e0 l TRIS_UNKNOWN,
. H+ R) R$ N: e9 ]' ` TRIS_TRUE2 G0 S% z' K3 k' _6 ~
};1 V5 e p! f& b* G; g+ L
( E# P1 i0 `3 |, M0 b4 ^8 d
' ` \ y' S5 D; I2 ?, O& Fenum UPNP_IMPLEMENTATION{
9 @: A! \! T+ m F* p8 B4 k9 ^ UPNP_IMPL_WINDOWSERVICE = 0,* ~' ]5 q$ a* y
UPNP_IMPL_MINIUPNPLIB,
3 m8 ?0 ?7 W; {5 } UPNP_IMPL_NONE /*last*/
8 D% O3 s+ @# A4 g9 C; a ?};$ o: Q4 D8 }$ {3 A5 A
0 T" M; Y' `' \$ k0 y6 `6 X
7 F" }) w% V0 @1 D' M1 `
9 a, K. a) Y4 I( O3 z8 }7 h% a5 U+ ]' t5 G& x
class CUPnPImpl
. W% f" W$ E% B! _0 u6 }{2 E! n/ e! A% S9 e. V
public:& R" n* ^# A7 ?& U! a3 _8 G6 |
CUPnPImpl();/ r% \& R! ]1 z' h8 o5 x
virtual ~CUPnPImpl();
' Y4 v5 z$ y1 r4 [2 ] struct UPnPError : std::exception {};
4 m! r$ \% f) U3 j. p$ g; {# e enum {7 N1 J" @4 g5 p) [% o
UPNP_OK,5 v( }$ [. I' e6 B
UPNP_FAILED,* p4 l; N/ [0 Z2 I7 G
UPNP_TIMEOUT5 j' k& Z8 j/ K6 ?, I
}; u; ?# ^4 x- h5 q$ V1 r u6 ?
! K( r( J6 f1 r9 D% P1 F( H
& z6 I& n$ G2 `( B; c" \4 p
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;% A% Q, y8 N4 N+ ^7 P
virtual bool CheckAndRefresh() = 0;
, y/ g7 N9 v5 O, K virtual void StopAsyncFind() = 0;
. a/ P& p7 I7 ~ virtual void DeletePorts() = 0;
& C) G- V5 W9 a, n+ ~ virtual bool IsReady() = 0;
0 |8 l6 T( J9 n2 { virtual int GetImplementationID() = 0;0 |9 }. ^1 |( ^
/ g' b9 h/ S8 D" N3 ]
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 J# T6 O( T. h
& g; g; C' B& `7 Y& M( E/ X9 J6 i
( @5 y! ^! b' o$ X3 a& S9 l/ Y
void SetMessageOnResult(HWND hWindow, UINT nMessageID);! `7 R% |2 g# b& Q
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
4 `: h5 ~6 }) E/ [# E" M uint16 GetUsedTCPPort() { return m_nTCPPort; }
3 p) R- j# i* V8 J% T w0 Z uint16 GetUsedUDPPort() { return m_nUDPPort; }
3 P" {: O0 }8 ], u
3 m- g7 \6 ?3 b" V# u6 V
+ U: o3 U! d( T3 y5 u2 v// Implementation7 S3 b' u; L" p6 ^
protected:# A% ^( G2 H' Z- K( V. `
volatile TRISTATE m_bUPnPPortsForwarded;0 A4 ^6 k% Y0 Y/ z' e9 \7 M
void SendResultMessage();
4 [9 n( w5 X* d4 J( | uint16 m_nUDPPort;! D, I- i; {* R/ L3 T$ V# n. w
uint16 m_nTCPPort;
. J- h. q5 S9 u1 J# T, I uint16 m_nTCPWebPort;) H; ^7 M+ c3 j4 n1 G& p
bool m_bCheckAndRefresh;+ o8 j7 S i. K: o+ U
0 f9 ^) X8 n5 E" x* K# _
5 e3 V' K, T8 d, l7 S
private:
# x0 c4 z. Z8 _# @! b) M6 a' F! d' w& d HWND m_hResultMessageWindow;
" [$ |) x4 n* o" J+ C4 Y/ c UINT m_nResultMessageID;
3 P F" e7 N- O5 n$ ?. w7 h
4 U _4 |- _. R9 E/ M; ]
" f( M) U+ m) H$ V0 u};
: }0 l% A9 \+ `) ]0 L3 O( U* L F u y' A& G- L D
! C0 c) K: a, O
// Dummy Implementation to be used when no other implementation is available" Y. x8 S: }7 b1 i; O5 X
class CUPnPImplNone: public CUPnPImpl% R: ]0 b, k6 m$ I3 R
{9 n" K0 l4 v+ J; c
public:% \; E; F0 Z* z# N4 b
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 G) a; C0 O0 r: _: h" k% N virtual bool CheckAndRefresh() { return false; }" a# B/ o# u4 O
virtual void StopAsyncFind() { }/ U, G5 ~ ~: l1 k9 {3 |8 a
virtual void DeletePorts() { }4 R" Q& e3 S# N; b6 E
virtual bool IsReady() { return false; }
! {( \) M. ^% }* x0 [ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }' b7 p3 m1 i: R4 J, O
};! Q/ k/ {0 i$ ?) i+ N
; o6 v; q L0 K" |. t8 Q/ `0 a b! n1 h: b+ ]6 B
/////////////////////////////////////
% V$ m, _, q6 a1 ]: k7 \//下面是使用windows操作系统自带的UPNP功能的子类
. I7 I7 B1 v; p1 l1 Q( T5 y0 j$ P0 N
# k3 u. u! R% s$ z7 q V' b/ L* @% z2 I
#pragma once
' l! q. q; [5 g. `) g& s* ^: E#pragma warning( disable: 4355 )
Z% R d. Q' h
$ a9 l3 s+ g. o' H9 V0 y: d" z! S, D1 G# V
#include "UPnPImpl.h"
+ j' \; ?! b# W3 t$ F9 h/ {#include <upnp.h>
1 j$ M8 x5 R3 B% b# @4 k2 z- K7 V#include <iphlpapi.h>( M A$ u, `& Q
#include <comdef.h>4 U" j2 o L2 @, F
#include <winsvc.h>
; n4 ]. h( `5 s4 D* ^- t. h$ b3 r1 s$ u Q J7 u* o
! b* `5 B9 F! d#include <vector>: h( k! ~: `& U, \" u/ d" c
#include <exception>
/ M, H& I3 v8 |! z* X& D( a Q4 h#include <functional>
4 n# W2 b2 n# H8 d1 |3 D
' q7 Y7 d% \5 o+ @& U$ i8 I5 V, \, B) a; v& ]. j2 `# H2 C
$ G' R* B9 e2 C9 E) B" v
0 r# y. Y2 _* e# c5 Z9 Y, ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;! \. |$ Q, R7 O# Y
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
, v0 j- L4 s3 h9 M Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
K# Y t5 H; `- q; {! ctypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;# Q4 N! u9 M/ j$ G. H
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 y. s$ O' a3 d# y, U% Q; B
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' G7 f/ `7 F, _5 x9 n: Utypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ @+ ~! {3 d' n( l
( _+ I$ W: {2 {% r$ c$ [8 a% s. z" [/ K
typedef DWORD (WINAPI* TGetBestInterface) (% T! f! I/ |. i W2 J
IPAddr dwDestAddr,6 D8 R8 Y }. | o- y6 l8 x( L+ s+ R
PDWORD pdwBestIfIndex
3 l) E5 w5 A+ O2 ?5 Z- ]);5 S( m C$ Z: q; i
8 Y, U2 R H: a& w
5 [* e/ y' v; M: h# etypedef DWORD (WINAPI* TGetIpAddrTable) (: r! D/ F; d3 F
PMIB_IPADDRTABLE pIpAddrTable,
4 J: ^* u' _; h PULONG pdwSize,. i d5 p( v/ V- v* U7 c
BOOL bOrder
3 {& m8 m y+ H. y: O' t/ g* \);
( C! I6 h: l' O. @3 V$ p: k9 g
2 b! f2 F, f7 J
. g( C* |# D5 z8 l9 Vtypedef DWORD (WINAPI* TGetIfEntry) (" Z" Z' w& W, Y$ S
PMIB_IFROW pIfRow F8 l& b7 b! P! M
); u% m8 o! R' O+ f
% {) O; B& u* F: ~( Z* h" t# R1 _" R" K* |, h
CString translateUPnPResult(HRESULT hr);
& K" q! u+ n1 }; ZHRESULT UPnPMessage(HRESULT hr);
& t4 q) B/ J3 `# Z3 e% z, j
$ J2 A- C7 \' n; @% {* t" S* u8 {4 u( K, ~9 b! p6 U3 [
class CUPnPImplWinServ: public CUPnPImpl9 O6 x, k. Q" E* v0 P- f
{
9 D( @; _4 s1 X8 w/ r. w friend class CDeviceFinderCallback;
! p( ^" T% a- a9 F5 e. H% N+ d. [ friend class CServiceCallback; x- [/ O" X, r2 u7 l/ ~. O
// Construction
0 {. B) W5 K/ ^* ?0 r9 W% Npublic:) ~/ ^# N9 T$ r* J- z0 Z
virtual ~CUPnPImplWinServ();, h* v: Y+ H! n2 C/ ]$ m
CUPnPImplWinServ();1 I9 |1 V" ^) p2 w) h) A
: n0 E1 l+ u2 U7 u1 d0 j
" J! E! X& @! f+ l" T' [0 p) s virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
9 K/ m R7 [8 _8 F* h( g3 o/ | virtual void StopAsyncFind();
/ P+ P- l/ l% ~: o% g% A virtual void DeletePorts();
: V7 \% o( o- ^7 P% x virtual bool IsReady();) j6 b6 ?7 V/ |% r: o
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }5 l3 b8 b. s; r+ H' b( ]% j$ O
$ K% f0 ]8 {& `0 ~8 o" C, w
7 ?) p2 l, b' Q, U5 n; w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
$ Q9 D8 @" D2 r5 R$ _/ s/ l! ~2 } // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ p/ J1 q9 |$ b; I virtual bool CheckAndRefresh() { return false; };
) c( v$ T7 e. K. } _! x4 A4 {
! d3 a. _ }2 j; H
; ]( }: u" C$ a: }3 }protected:; f/ h! |7 B& ]- L3 Z; ]0 N
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
6 a& C2 ~+ ^; n void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
l; V! E# F5 l: O void RemoveDevice(CComBSTR bsUDN);" ?; ~$ f2 H. W8 G
bool OnSearchComplete();
8 ^* P) T5 s: M void Init();
; q. f0 j9 V6 w- a3 t; d/ h- p4 n6 {' Q0 ~9 R' c# P
# K* y0 K5 {/ f& D
inline bool IsAsyncFindRunning()
$ t" F# N# d0 ~" s! t9 d5 U {
: E( X& H8 Y) N6 G if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
. d! |6 ~9 G h+ N% ^7 R- S {3 L1 u% L' E- Y
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* X9 i) P; R i
m_bAsyncFindRunning = false;" o) ^, y' B- K( g0 ^4 |! ^- g1 o
}
5 C* ~( i! [5 O8 j, E% x* B MSG msg;; a/ L) j% a, R3 w& V
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )- p' a; \7 \1 b6 x8 [% j: B8 c- l
{2 ^( _! w1 M" {& x. z, f% K
TranslateMessage( &msg );
& D9 K2 n7 B1 i DispatchMessage( &msg );$ k, G/ E) @* x
}2 M7 s" \3 @- g. g' e( ~
return m_bAsyncFindRunning;
) j& \: _1 L5 O/ e, m9 f }
" `& W1 Y3 R. }( q9 U- Y
: O$ p' C$ K! P* ]" O8 k3 S0 ~# {+ d& j8 B6 P) Y
TRISTATE m_bUPnPDeviceConnected;3 P* `* L+ z! D" I: {* M' s% K! o% x
8 F0 A9 T( @% \4 A8 H
# X; b2 U* i' v1 M1 s: y" u// Implementation
a% M; J1 @6 |. T. |* Y // API functions/ x3 }& `) |) i0 E" R$ x
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);* b* u7 M9 d+ C; U* x
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);5 ?2 H4 d$ f1 c0 b( l; B
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
' A) _2 o. X5 j! b BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
" I6 B' P7 Q4 p( h7 c! T# @ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
0 _* R" G5 g1 N. Z BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);) I1 [' L0 w8 a7 n) a, W: c
6 U* b" O! A- A! ^" m( v
( Q5 c- I9 S, \- x' M; V- A TGetBestInterface m_pfGetBestInterface;' a9 c Y$ {! y q
TGetIpAddrTable m_pfGetIpAddrTable;! x2 o. U& H0 X8 H: |
TGetIfEntry m_pfGetIfEntry;
6 m/ N6 o0 D* F! i% i ]' E$ E1 g# c0 t/ p' s, `9 P/ f) _
6 r) y2 [ b6 H' B( m
static FinderPointer CreateFinderInstance();9 b$ l5 ~8 n$ D$ Q
struct FindDevice : std::unary_function< DevicePointer, bool >
Q' @5 s/ e/ o. \2 v& R/ O8 {( t {1 Q. c- ]! r" g$ M
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}- z9 G+ E' {5 d6 G' l8 R
result_type operator()(argument_type device) const8 b+ D7 p0 b8 \. R& ?3 g
{2 `4 Q! H; x1 i
CComBSTR deviceName;9 W2 i1 w* h/ }0 g
HRESULT hr = device->get_UniqueDeviceName( &deviceName );4 k2 P3 [& z% s3 E
7 ^5 f$ I0 t) G; G
4 B3 C# R- b" i* A
if ( FAILED( hr ) )$ Q, W6 P: [% c. Y" `) ]
return UPnPMessage( hr ), false;
4 d0 u0 T! e( B3 q9 L! T* C* s: g* `7 M
4 U/ o4 L0 ^( m# c return wcscmp( deviceName.m_str, m_udn ) == 0;/ D. x) b d* K4 q
}& W& s5 _) M( k- ?
CComBSTR m_udn;8 B# K* h4 p) ?9 L/ X# `
};
. c8 p0 y2 ]2 U. `( o
i& T6 D( g. M0 W' ^% m7 l o9 T7 P void ProcessAsyncFind(CComBSTR bsSearchType);% [' k- h- ?7 G5 Y% R. N7 F6 l
HRESULT GetDeviceServices(DevicePointer pDevice);% U* J& V6 ^6 D n( J
void StartPortMapping();
( t! o& J+ C; E HRESULT MapPort(const ServicePointer& service);) Z+ @! \7 F% C9 E9 d8 W8 U/ p; P
void DeleteExistingPortMappings(ServicePointer pService);3 C* k0 Y# \! t5 V- f8 u' P; h
void CreatePortMappings(ServicePointer pService);
/ I) }$ l1 f3 a6 o% p: T, O( A HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);/ C; l+ \( r+ c A* ~+ v
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
6 V7 `# J$ n3 d% G LPCTSTR pszInArgString, CString& strResult);* W& F4 {- J2 q
void StopUPnPService();
* K: p) W: o5 O4 V$ H
$ ]) T; E3 F. t9 {
- C. A. k. {8 ~& Z0 z8 n" r7 s // Utility functions
% u& h5 @! L: S9 _+ W: m V HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
j6 c% ]7 ^ {6 M; w: k4 i INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 k, j2 M. p" \: ^
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
8 c6 [8 f5 @4 l8 e8 X void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 F* Y" D* f0 f7 _) A% b HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);2 A3 a. b) O, I9 Z) k' N
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
% ]% ]# \: |7 o CString GetLocalRoutableIP(ServicePointer pService);: g; ^1 \ ?1 c% s% w7 C( L3 p
0 R% W$ F6 e) [; P2 a( w& w7 Z; F# G4 [ o) c
// Private members( T- x+ K1 j. l% Q# T5 E
private:+ x7 v# U3 K! r# Y
DWORD m_tLastEvent; // When the last event was received?' M4 e% r/ r8 o" U/ E6 y
std::vector< DevicePointer > m_pDevices;; j4 z$ p! g; @% x
std::vector< ServicePointer > m_pServices;
& s- Z, M4 r- z: g0 G( r FinderPointer m_pDeviceFinder;3 F% b6 D, o! t9 O3 `* {, K2 b
DeviceFinderCallback m_pDeviceFinderCallback;
, v9 K3 y8 @. g1 |! b ServiceCallback m_pServiceCallback;
- ?8 M! V* N6 a0 f
" v {3 a& w/ T0 V' f: a" y
; l$ b. }- p& {8 {) \0 ^9 S LONG m_nAsyncFindHandle;
# k2 s/ r, }1 B bool m_bCOM;
/ S1 o1 c: O+ G% a" d bool m_bPortIsFree;
3 S8 a! l) u7 X% N8 n/ k: ` A CString m_sLocalIP;
* a4 P/ u$ D; s4 f3 B CString m_sExternalIP;
! U/ J+ q, u# j, c# { bool m_bADSL; // Is the device ADSL?: I& `6 ?9 m1 I' z) D
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?6 x/ S( a% X4 b( R- o! z: k
bool m_bInited;
$ j) r6 ?! Z4 k5 p3 S bool m_bAsyncFindRunning;
8 \1 V6 w- ~ N: r; ^7 T HMODULE m_hADVAPI32_DLL;! o( K( A& E8 C! G. U: u
HMODULE m_hIPHLPAPI_DLL;
$ v% U% Y p) G6 \, A! d. B bool m_bSecondTry;5 T7 \+ d3 K: G# i8 I, h
bool m_bServiceStartedByEmule;* s7 `% p3 r6 J/ f! I: t
bool m_bDisableWANIPSetup;$ D9 v. ?7 Y" g
bool m_bDisableWANPPPSetup;1 O4 q* ]0 G+ e3 m! ^
9 N/ T* a: [/ Q
% j8 h O% m0 y};7 o* b4 X3 H* V: ~) r2 J4 t
2 N8 y1 e3 l9 y, r9 J5 g. N% Z5 I
3 r& T U% n1 }8 W* \. R// DeviceFinder Callback9 N& Y: t; k& Q* _7 C
class CDeviceFinderCallback+ D/ @& {) [* e5 p0 V( _
: public IUPnPDeviceFinderCallback
/ B5 a) M) x; j) U$ s{5 ^4 {' \0 J$ `
public:# U* A* U5 Z( i9 r5 _7 n
CDeviceFinderCallback(CUPnPImplWinServ& instance)
8 s) k# x; e$ g$ v : m_instance( instance )
2 s; ^& n" t9 U0 K* o7 r* G { m_lRefCount = 0; }2 I! x- {% N# S L S' ~7 ^
* y. \$ \* H* v1 V' u$ R: H
' [+ v' m6 G7 [* A STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); K1 Y% H' p. [4 K
STDMETHODIMP_(ULONG) AddRef();
, e1 G5 ]8 M9 u- J5 X+ X) G6 ? STDMETHODIMP_(ULONG) Release();" I1 L, S+ {# E7 ?4 w- k! M
" c |% `! p' m$ K
/ ~$ U9 ], B' y0 q( `) x9 E// implementation
% ^0 v( S0 `% y W" b" z& H* v6 `# `8 Fprivate:
% m+ _8 d7 T6 F" n2 q+ u, ~9 z8 d$ w HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
7 }0 X0 \/ a( g' {" | y. J1 v HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);1 V7 e# d- ?0 Q( H: g
HRESULT __stdcall SearchComplete(LONG nFindData);
/ A( @8 w$ j5 q2 N; d, V" ]8 R. o& R3 b# k" o4 z
5 q. [0 g; H2 B
private:
3 _8 {% C& Q6 n2 g CUPnPImplWinServ& m_instance;
3 W" D: B2 F' U2 {9 Z+ p% B LONG m_lRefCount;( K5 b; o. r4 A4 L, _
};
4 [$ c! Q, u, h+ C
- G) S5 x' w. h9 l% z1 Q. g* Y% N; }6 Q' ]
// Service Callback
) x9 R0 y& w) i8 M! [. y2 @class CServiceCallback1 d) S# w' G- D7 y3 R1 e
: public IUPnPServiceCallback, A- Z! O; ]. [" M9 F5 E
{; O' ]$ ?; O1 W4 m, V. S2 V; E
public:
1 B" }" h# q2 G- Y CServiceCallback(CUPnPImplWinServ& instance)' G' x" C8 [+ `. S; M
: m_instance( instance )
. J# b. }& m4 H, M" c { m_lRefCount = 0; }
7 u' [! T$ W. M7 G9 @
/ c1 j- z1 Z( S2 M5 T$ C3 M STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);9 e# J+ H/ K/ X! U
STDMETHODIMP_(ULONG) AddRef();! x( J% R$ {/ g _1 K4 b' t
STDMETHODIMP_(ULONG) Release();0 }% _% V0 a, a& ]% x- v
8 @& r4 F! d; O# P# c9 A ^% j
+ o; ?5 s* S; K h8 [0 C" T! @ W6 u// implementation
9 K" Y: S5 A2 D9 Pprivate:
: B6 z5 {3 M' E+ E7 j HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);6 C0 k' X6 O; x. v" c+ Y; g- Q
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
; K: V4 L' s" n' _* J
/ l8 a) Q8 R' d# l
2 U; y8 t1 B+ A' _private:
1 Q% y; X4 E+ m7 ~ CUPnPImplWinServ& m_instance;* G0 F, J$ K/ _2 B* N
LONG m_lRefCount;1 a9 r# g# `' h
};
, e, q. {( ^ a9 R) o( N; z" p6 V0 B' s. G$ b0 f5 \
9 M+ s9 u2 z. E- n) ]/////////////////////////////////////////////////
$ l$ m1 n3 g6 Z! M j2 J# h. B; Z) p) C N0 a4 E' M
& v5 M, V1 z* ^0 o3 N% f( J s8 S
使用时只需要使用抽象类的接口。 c1 h; Z$ N. H0 q+ A- Q
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
6 ]' S# N4 c+ |6 a' BCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' B* u' C5 o9 N; B( _: A" x
CUPnPImpl::StopAsyncFind停止设备查找.
/ Q6 e; q1 Q Y4 c: I5 a8 X7 ACUPnPImpl::DeletePorts删除端口映射. |
|