|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: D9 p, J* a' J }) P
' a) W/ O! Q1 Q( ~+ o- y8 g P' L' I3 r
///////////////////////////////////////////
5 J8 ^ W3 }* O//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
& G/ f' ^' m5 Y. [: p! |" g
x3 i4 Z* \% s" h. b. q3 A8 r
#pragma once0 T7 C( O0 `% g5 c A
#include <exception>, b0 N8 m! n+ i7 m
( V/ }# T1 U7 K$ ~! i
# ]+ G# f6 @, N enum TRISTATE{5 ?# A, |* k2 R2 N' v; G1 F6 g
TRIS_FALSE,% E7 a5 A1 A5 T2 J1 s5 ~% q6 ]2 q
TRIS_UNKNOWN,
! R' p) E. ~: }: d& j$ ]/ q TRIS_TRUE
8 _8 `' S1 A5 E& i/ g2 i: @};$ M/ N, p$ [& m x/ h
) G8 w4 C: w4 M c) {
% @7 p+ r0 V3 L: ?enum UPNP_IMPLEMENTATION{
: }& \$ q% F% H UPNP_IMPL_WINDOWSERVICE = 0,
3 G; X' y& O9 N8 h' p* o% v UPNP_IMPL_MINIUPNPLIB,
' }! C$ B* P q UPNP_IMPL_NONE /*last*/5 g* D$ D, e5 X3 i1 t
};
; t. u, ~8 y+ |" j8 _( X/ g4 v1 b
4 U6 s; G: k& W, T
+ u9 e- F- Y% D; g* p) O, N8 m( o% C: z b& @7 m
class CUPnPImpl
4 x9 ~8 I2 P0 G# b! [0 X) V# {7 t5 r{& H3 _- G5 F* F& X/ p
public:
3 A1 r5 _4 s; J9 g CUPnPImpl();/ `1 r: h* w' y( m
virtual ~CUPnPImpl();
; z& e' \7 x* T struct UPnPError : std::exception {};- D0 H. K8 C: @% L8 W* g! H
enum {4 l( E1 Z! B* F' I" `
UPNP_OK,
7 v; O! @$ | Y UPNP_FAILED,
5 T6 g( H) R7 o% K+ {$ R UPNP_TIMEOUT1 a2 U. t2 u' R6 Q
};$ E, Z( ]# `) ^' E0 V N j
! V3 l: D8 r: t$ A7 P; Y
/ {( g; E) y) P' z6 f8 Y$ h
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 \. h5 X: J/ w" G virtual bool CheckAndRefresh() = 0;/ a. o; G! \% b }& g1 U
virtual void StopAsyncFind() = 0;5 s9 _: r5 U( j+ X
virtual void DeletePorts() = 0;+ u) K# t: q) d# R$ d' G- B
virtual bool IsReady() = 0;
4 @3 ], v; @' H virtual int GetImplementationID() = 0;* R1 w/ o9 }& x& ?! s4 J- K3 \
" {9 U( T! M1 |$ O# A void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
! o* D9 V( {7 ^: A' N' r3 O: g; s0 j/ ^% L1 f. t* J
( ], K6 ^! M; I1 F2 V n
void SetMessageOnResult(HWND hWindow, UINT nMessageID);' m* W9 i0 v9 I* X. y z: w
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }; i8 o8 S+ r/ C7 K
uint16 GetUsedTCPPort() { return m_nTCPPort; }. f }/ ?2 L, U/ V! q( v
uint16 GetUsedUDPPort() { return m_nUDPPort; } / _+ Q1 r$ _7 U, F7 y/ B0 a
0 @, T1 m! C0 r+ W
! J: Q- I9 Q4 @0 `1 h// Implementation* l$ T0 j Q: g; A. a
protected:6 W( Z* H. _2 l, L5 O8 b
volatile TRISTATE m_bUPnPPortsForwarded;
! U# X7 @4 ]5 i6 G void SendResultMessage();
9 A( ^# R7 _, o: _9 z8 n+ Y# Z* M4 ]6 H5 P uint16 m_nUDPPort;
0 ?+ d: j" ~( f; }9 ~ uint16 m_nTCPPort;& k: }" i' Z; C6 `4 b
uint16 m_nTCPWebPort;$ }( b; A4 k3 l; {% k
bool m_bCheckAndRefresh;
5 w' C6 f/ {2 h. u2 C
$ q# x$ j, h9 L! J, Z. w7 u' J) Z# p3 i1 d. G) Y# t* Q" C
private:
! |. d* K& x# L3 j$ V2 W HWND m_hResultMessageWindow;
( ^& o' r: ~- x/ `. N+ ^0 A4 v UINT m_nResultMessageID;
1 E# S' ^& P, o) A- L a
0 ^# H4 M6 n5 i9 N9 U
. y' h; X! E4 [0 G7 B8 @% }$ o9 w v6 P};* T$ U: b1 I8 Y# _+ Z/ `! h
) X+ c9 A# l$ P5 J( K
! F9 B" k/ j, L2 W3 H9 z// Dummy Implementation to be used when no other implementation is available
1 j# j' k) s6 f$ Eclass CUPnPImplNone: public CUPnPImpl
4 V: ?" N2 Q( C7 m) @+ f$ o2 W, E{
5 N& R) d% y- y) _( `public:6 ?- E' l7 K' u9 G7 M
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }5 S3 N" G& C5 \6 g0 K/ I- @
virtual bool CheckAndRefresh() { return false; }/ k9 n" A- H* C3 a: C* g
virtual void StopAsyncFind() { }) Y8 u% Y' x! B! L
virtual void DeletePorts() { }
' J- K6 g0 T$ O: _( ? virtual bool IsReady() { return false; }- B" i2 O3 `4 _7 v" C
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }0 V* o' j: G. z1 z$ s) T
};
6 l7 u7 l! p' d# _( ]: p0 {
7 \2 g7 W* c T7 P% c0 b4 z" `# {0 Y3 T9 g D
/////////////////////////////////////
& T; ?9 W% s/ w& `7 Q0 Q' H//下面是使用windows操作系统自带的UPNP功能的子类
8 y. S* [& p: `# S3 d2 S: c
$ R$ g9 Q l, y- K: U$ C8 ~+ K7 V$ d
#pragma once
5 y# S5 O' z$ u. o+ b, t#pragma warning( disable: 4355 )
6 c/ n& `3 P, J R5 t" U6 A% A- d' t$ ]; o% A; b% p" x( |
9 _" R4 H6 b K5 |#include "UPnPImpl.h"
- ^ _! o" j4 I P4 q5 W' w#include <upnp.h>
0 A) K- C1 q! ?% ]/ L#include <iphlpapi.h>1 @, m1 b9 c' K2 ^1 r5 C- W: ~
#include <comdef.h>6 `/ M `1 }3 O" J
#include <winsvc.h>1 C' ^4 g4 y% q8 ?6 F
! v2 h5 s- q9 ?, K( I: C' I8 c1 E' V9 J/ g# J" ]
#include <vector>, I; L" F. M& t- Q3 E1 W
#include <exception>
. b- E9 P4 b" b' b& v$ I; O#include <functional>
! D! ~& p4 j. P6 Q( n* L% d8 K- F7 _7 ^; E) L/ H4 K* b
5 y( r0 k0 ~* D1 A# D* F
1 h' }3 Z5 A3 h/ y4 ` V+ Z* a$ j7 P7 O+ f/ Y' m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
6 r- r2 T) R0 u- a$ T# h- ^/ Vtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;2 K/ d! T( \, M$ B8 Y' m* E
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
2 b" H, C" Z6 {$ h6 z2 ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 N. s1 R. v0 T9 c1 @* C4 x
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 F( V& d. N' k; b# rtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* Q2 ~5 W0 H+ g" [typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
# @ Q: W4 R. q n$ C( d7 J% u
. j9 W4 u! u; N( w. ^: ?% ^5 O: Y1 D0 C R/ \2 j9 s
typedef DWORD (WINAPI* TGetBestInterface) (9 x3 x" w2 {& H) ~% q! L; ?
IPAddr dwDestAddr,% B2 Y, s4 W/ F, s+ ~1 O2 C- F4 e
PDWORD pdwBestIfIndex
' }. {# l1 R6 E* Z' d);
& N# z2 R, }& B
/ k, |. c$ F1 g% V: X+ t: H7 }1 w1 `, ~$ ]1 F8 O
typedef DWORD (WINAPI* TGetIpAddrTable) (
. p+ ~/ d3 c1 K PMIB_IPADDRTABLE pIpAddrTable,
5 X; x- o0 |# G" r: f& I PULONG pdwSize,
4 b( W6 U. q; { BOOL bOrder
- u+ K5 v3 X3 P);9 p+ i8 u; r9 N5 T5 T* T
$ v6 b; V" ]2 G; o9 Y/ q5 i5 \% f% E
typedef DWORD (WINAPI* TGetIfEntry) (
. |, ^1 n! V0 s; u PMIB_IFROW pIfRow% p! z ?, I% P$ A- o, R
);: }* D X" h2 N6 w
; d; |+ v0 {8 L4 F5 H- y, D, |2 b: s6 y
CString translateUPnPResult(HRESULT hr);
; s' b$ b3 x# E/ h0 i/ UHRESULT UPnPMessage(HRESULT hr);& Q( u" A9 c9 Y, v! h+ o8 P( _7 X# G
5 ?' w( x. I- {. V9 o6 h
9 j4 h# Z2 C; x1 i% ]class CUPnPImplWinServ: public CUPnPImpl
, C* D" x) }, X% Z{1 h1 K0 O) K/ r& V3 i0 b9 m
friend class CDeviceFinderCallback;
! l# T4 D# _6 R b2 R friend class CServiceCallback;" J2 D( p- [$ ]4 v- u/ S
// Construction
: g! h. V9 q- h( ^public:6 F a) n' u9 {3 Q
virtual ~CUPnPImplWinServ();! E2 v- w# F; w( B! z# ~) F
CUPnPImplWinServ();% n" ]' f. E% p0 G1 U
- v# o- @6 l! Q% w, H$ S. o0 y* w; }% N' H) F
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
' t( I/ X/ E& j6 z virtual void StopAsyncFind();
6 V9 m* |9 @3 @- A( u6 H, Q virtual void DeletePorts();* F" U) L3 `0 f j0 ]; ~6 ^2 ^: Z# k
virtual bool IsReady();: V" `( P- [- B5 W+ }
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( Y2 a! t2 w) N" t1 h5 o) Y
# ~" R+ |9 H( `* v I
4 v+ v4 ?6 e- c7 a5 }( B // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)% I& C$ |. H5 K/ U* F) @; E
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 d/ L# D: M! R% ~
virtual bool CheckAndRefresh() { return false; };
! @" Y) [( m6 F# k+ T( J
1 N' s9 Q$ r; T7 K5 K6 E
/ E* k0 `. S7 J1 |protected:- e$ N0 e4 q0 ~6 J X( y' M# n! i
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);6 q- l& ^ C3 _6 ^0 `
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);8 n* P$ k% \7 }& L# K
void RemoveDevice(CComBSTR bsUDN);
8 P& s4 D; j; y" X2 V) w& \$ a" ~ bool OnSearchComplete();
0 N& m% j" I7 U7 }/ G void Init();; n$ [ ?; p( j7 A& Y
2 v& f6 h( r2 x! r' K( I# M5 r- M5 B0 J3 |
inline bool IsAsyncFindRunning()
5 h2 N" _% n* l0 b6 V( n2 c {
4 Y0 m- v. v% O4 l4 f. u0 ]! m if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); ~' \1 s2 X) T! v2 S
{
* D) w! u5 D6 @! [ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ `7 R4 s+ E* m- I, Z) q
m_bAsyncFindRunning = false;
4 [8 A" @: ~1 ^3 Y2 B. y }0 J* e, A; N1 O4 G: Q
MSG msg;3 D5 b f) c+ c, h+ W
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )/ L4 `6 q& ?+ J! l7 \
{6 Q& c$ c, E) q( r: |; t
TranslateMessage( &msg );
0 U2 H1 ?& S7 h# H* _ DispatchMessage( &msg ); o; L7 m: S) h
}, o1 E+ t7 j/ b+ F
return m_bAsyncFindRunning;
/ M. e1 B. L8 S, n1 U. i7 b2 W }
+ Q4 V' s$ `$ T4 }/ [
) Y+ H) f# i! E) H# c9 X4 |7 c/ [
TRISTATE m_bUPnPDeviceConnected;
2 @- `8 P' ]9 ^4 _5 D. s" `& F) V. F- g& E- A5 p; [' ~
9 q2 L6 G( _$ T9 k1 S: _
// Implementation
1 \1 E8 X1 a+ j6 N9 u6 w% ^3 U // API functions4 V( |- f! F2 W4 @' o
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);4 a9 w/ T% p. v& G. @6 x
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
; C* V" }' k6 x5 a# _+ Z2 L: q BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);$ z# k, W$ Q8 r& e! Z- Z1 L9 }5 a: T
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
- i8 f% H) _$ r4 T BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);5 u# u. l) g* @. w1 b# r F& c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
" U* J. x3 q7 G/ O0 \% G6 a. ]9 i% H- ^
3 _% I' W" f! j9 B8 M; I
TGetBestInterface m_pfGetBestInterface;
* k* [" q& O' ^, N: _+ ` TGetIpAddrTable m_pfGetIpAddrTable;
4 c9 u1 A8 k: J: F TGetIfEntry m_pfGetIfEntry;, c, l1 P! \. t @/ C' w
+ u4 o% d" y* Z$ g. H
' ]8 {" W; J! e7 k% h( _ static FinderPointer CreateFinderInstance();2 b; }% Q% V9 J4 O
struct FindDevice : std::unary_function< DevicePointer, bool >
c3 B) ^! Y/ h% P: V* d {' s* r; d, x8 i7 x4 l" D
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
$ w$ `! p" S2 O; g: H# p% C result_type operator()(argument_type device) const1 L# f8 q9 m. L/ Y8 K/ m6 L( X6 ^! o* K
{
: X! O2 w( Q6 Y) M5 {0 x4 A CComBSTR deviceName;
+ O( E. r- W* z: L: r HRESULT hr = device->get_UniqueDeviceName( &deviceName );
2 O( @9 B' t. Y! q3 i% R. o6 `/ N3 y( b* k. I) t6 P2 n& d& z
/ R; \8 {7 V5 q* K: [0 C
if ( FAILED( hr ) )
# Y! | Z7 a& R3 u- ?- s h return UPnPMessage( hr ), false;3 l! Z: N, Q) y: b
: {: T f% t% ^* |) }! t
, t/ \! B b' u+ [5 r9 I+ X return wcscmp( deviceName.m_str, m_udn ) == 0;
6 L% W: v, Z2 T1 s6 S2 u& D }
& `# ^# v2 y- H8 ]5 S CComBSTR m_udn;3 L* e% W1 ?2 h: t7 @$ P0 a
};
& }: [1 Y9 }3 u" o) U
# b& @$ o2 Q" Y& _: n void ProcessAsyncFind(CComBSTR bsSearchType);( ^1 M `( h" \! u4 u
HRESULT GetDeviceServices(DevicePointer pDevice);$ r7 s! g* x& ~8 x8 z
void StartPortMapping();/ u, H) D+ R) s- Z' l) l
HRESULT MapPort(const ServicePointer& service);
2 E1 v4 Y! W' V- q) I/ ~9 c void DeleteExistingPortMappings(ServicePointer pService);
3 e) \3 B9 `' v7 h# X2 T, t void CreatePortMappings(ServicePointer pService);" O A9 O' ^" y% r/ D. u: T
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);% t/ D7 M% n. B d5 B H$ ]
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
6 U$ e$ D$ F2 E7 n z LPCTSTR pszInArgString, CString& strResult);& g' @: \5 j3 s6 g$ w
void StopUPnPService(); ^4 l! \; R: @' X8 o' E
# ?, n$ s* I3 a( G
8 z. l0 R. Y4 b5 Z // Utility functions
1 V5 O" R* p$ x: Y' B HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
4 {# R" R% g# {5 [0 N2 s INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);! w' T& S5 S" c9 ~' k x
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);9 D8 d" }( m3 c& x1 U$ `' ^
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
% m" H4 e. T* }% t6 u HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
" T+ D r, I/ ?# H" E; [& l- z& Z HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
% i5 E3 k9 Y+ a$ G* A CString GetLocalRoutableIP(ServicePointer pService);4 K" S" i+ s# I! a) m% z: f
1 T+ r; D! p2 X" M; r1 X D* J. ?9 Z
/ d) p7 G$ p& }, m: n0 u
// Private members
9 W2 w& K, ]- Z& {0 M! i! ]private:
. r- V4 e) _4 O# X7 X7 @ DWORD m_tLastEvent; // When the last event was received?
* x/ N) p! S0 p; y std::vector< DevicePointer > m_pDevices;
7 \( r/ h+ j* l, d0 `& z& o5 i5 q5 e std::vector< ServicePointer > m_pServices;
' |0 f3 N/ ]( \* ]0 R FinderPointer m_pDeviceFinder;# }+ Q/ l* p5 i# S1 D' i; x* {
DeviceFinderCallback m_pDeviceFinderCallback;
6 ~6 W9 B, ]' m) `8 f ServiceCallback m_pServiceCallback;( B8 [- t" S' o, R7 K
# q) D9 }+ D( l9 t. ~0 h
, \& c+ n# Y! y; u: z! R LONG m_nAsyncFindHandle;
1 }3 _$ D7 C/ o9 N4 j, X7 S bool m_bCOM;" j6 Z; t. M2 t/ g3 H# N. V
bool m_bPortIsFree;8 O0 ~- x) Q4 h4 R& i7 k: k6 X. p
CString m_sLocalIP;/ x2 g- g C0 j4 r" {4 |' @6 G. z/ F
CString m_sExternalIP;
% S M# ~% b* J; n/ M b bool m_bADSL; // Is the device ADSL?4 p* l' f- F( j
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?& i& Q9 H V( D8 j
bool m_bInited;
# l* {2 }% Z' B4 h bool m_bAsyncFindRunning;1 N, |* p1 k. g* \, } A
HMODULE m_hADVAPI32_DLL;4 R4 R5 b! @, J, j, [7 P
HMODULE m_hIPHLPAPI_DLL; U" \( H# |/ V' [5 }+ U; y
bool m_bSecondTry;
+ ^& I' Q/ T% [, z1 Y# { bool m_bServiceStartedByEmule;, x- Y, g7 W: _$ V
bool m_bDisableWANIPSetup;& E3 S( }' W1 b7 o# i
bool m_bDisableWANPPPSetup;
; h, T1 X0 v% c5 K5 x
2 D; X; ?2 X4 V3 p/ y, i) _7 x0 a; y( D1 }. p
};3 Q- Q8 [; R5 }3 f6 _) J! x- g$ f. F
9 P+ i4 ?# {0 V
+ ^5 p2 q; p9 y! P! E
// DeviceFinder Callback
+ ]* \& |4 L3 x; Cclass CDeviceFinderCallback
, B7 |% Z, N) H: ^ : public IUPnPDeviceFinderCallback9 E) g2 }, O" y/ l: P1 x
{
2 e' s [: p! f- i9 Y9 N. Qpublic:
6 [, [4 G- m' l( f* r& F: o CDeviceFinderCallback(CUPnPImplWinServ& instance); l" t- l* o( q: w' D0 V0 ]% f
: m_instance( instance )
' z6 Q: T2 y2 Y G+ A; i { m_lRefCount = 0; }. U$ i% m# [0 A2 \ z5 R R
6 f0 w7 k* @# `0 D
, g& S% Q1 H2 y7 ~; p; F, N: y; f STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# u. H: e% U4 b' E- S' | STDMETHODIMP_(ULONG) AddRef();7 L/ z6 g* g+ `
STDMETHODIMP_(ULONG) Release();$ Z# q4 A* Y- E; G! a
1 f- N3 B8 V9 P d- V+ b
1 a0 _( ?/ ^& n7 n
// implementation3 w5 z5 T1 r$ L0 ?9 }! s
private:! o9 n8 y. T$ _1 e7 m" J/ G& q6 |
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' Y% K/ U- P3 i; n% i HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" z. C b1 ~% j5 n5 N HRESULT __stdcall SearchComplete(LONG nFindData);
2 n4 \, K7 x$ a3 V5 p1 m, Q, V. c
2 I, _" H9 o; u6 f" m* r
private:
. X: ~# C$ z: S CUPnPImplWinServ& m_instance;- g" b6 v5 Q) d3 W2 l* n! S" l+ d1 a
LONG m_lRefCount;( y1 D4 K }/ ?4 l* n& w) w
};
& m8 Z* n; D$ ^' `6 K
4 B, D) o! v; e I
+ C8 A3 T) h2 ]0 F9 k6 H# u& c, E// Service Callback , Y* t$ G7 S3 |1 f) T
class CServiceCallback
8 e- X* ?8 \5 Z! G( ^1 H : public IUPnPServiceCallback
6 `; J+ `3 `% {/ @8 w+ f{; K7 S- z! }& B+ l" b( E. B" c( ~
public:3 A$ a( x! {2 J; m
CServiceCallback(CUPnPImplWinServ& instance)4 Q' i% [. R5 @3 \
: m_instance( instance ). }8 A5 Y/ ^. n6 O7 T8 t( x
{ m_lRefCount = 0; }& c. e; B! P# s
2 j# e& M% B! z" c& P5 w, ^
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
' r: M) L! q4 x, K1 y0 N# g$ @& X STDMETHODIMP_(ULONG) AddRef();! H+ N. ]2 [3 \) R1 S
STDMETHODIMP_(ULONG) Release();
2 S: B& ^) M3 f- x; _' m
5 ^( g, g' P8 g0 @! ^/ a( y, l" l4 f( ]' Y( E
// implementation
" d/ a: c/ m. J/ Bprivate:
2 z, P7 ]! \# ]5 `6 E# R2 s+ s HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 y# p5 h' U0 `$ i( L" V HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);# s4 A: u; K. n: {
! I& w! U7 o2 U a
1 X; L1 s3 `* v1 D6 I5 u" p! Q
private:) P) f6 }; C- A
CUPnPImplWinServ& m_instance;( B9 @; R# s3 @
LONG m_lRefCount;5 b. W, g: K( G
};
* a0 k' s5 g$ i
0 _' w" ~% N8 c- P/ A4 z2 j
( ^4 O; ^- |& D/////////////////////////////////////////////////
, a6 R; z4 ^( n8 Y: |$ f9 U1 \/ u0 H0 _
' O) ]1 A( h; |
使用时只需要使用抽象类的接口。$ f+ T# `( V: ~/ k1 f* F+ @' T
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' J2 {! P" _8 Z& {CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
' \6 K$ \, U( _4 T; [' Z H, zCUPnPImpl::StopAsyncFind停止设备查找.* b3 `6 y3 O; n& K
CUPnPImpl::DeletePorts删除端口映射. |
|