|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- y! F$ I4 q! C' Q
2 {# [# V9 ]0 O, e" D* H; t, Q
* T1 V* [, H. a5 C; g6 n% W8 o: t
///////////////////////////////////////////; ~1 _7 B9 n; T+ H% _& g+ D
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- R3 V# s. t* r% a: w. |
5 K! C( v& C( ]/ I
& }8 q- A2 n3 w#pragma once# y1 [( L! W0 X
#include <exception>$ g% j, @# o9 Y, A( I
& {; V# Q7 m4 w8 q4 L! Q: c s, B0 L3 N0 F9 |6 q
enum TRISTATE{" h9 W7 s; h/ `5 G% O
TRIS_FALSE,
- T6 P+ L5 ?3 `* _ TRIS_UNKNOWN,
8 r, A4 O* w9 R5 I+ B; s9 }. } TRIS_TRUE2 Q- V* _- J" J7 C" w& E# B
}; L% y$ @/ s d/ V
. N' H0 X% U7 r3 L$ E
8 w7 T. T, T0 L2 I/ h2 O; y5 Henum UPNP_IMPLEMENTATION{
! W, Z& r6 U1 t: L9 o$ `6 G* [& R UPNP_IMPL_WINDOWSERVICE = 0," e0 X0 O% l4 P- v, h8 G
UPNP_IMPL_MINIUPNPLIB,
* {4 H% d; t& @7 v4 W UPNP_IMPL_NONE /*last*/
4 z6 ]* A! ]! G' o z6 x};
* t4 K- x* w) M: |9 F0 l) P0 b
, ^8 y2 @1 Q1 l U8 Y
" d9 }8 z% w1 [9 h; s, s. S( T
! O; \ E) ?, t9 n+ n
* i+ R' D1 l' V( k5 S: iclass CUPnPImpl& g4 M5 C! \7 T. B/ l" y ?
{
! T0 p" H& a) vpublic:
/ u3 ], J3 A) s CUPnPImpl(); Y. l7 a& {$ ~
virtual ~CUPnPImpl();
& F$ f! h+ V# v! Y struct UPnPError : std::exception {};: d8 V' P, M: Y# {
enum {( [" C9 W5 d0 `5 e" O7 ?7 A' N
UPNP_OK,
9 c7 b5 |! d. u; h. i$ P UPNP_FAILED,' y; m( L) C# x4 B8 R. Y* u
UPNP_TIMEOUT4 L2 H2 S# I$ B1 s
};( Y1 S& W: `$ i6 Y/ v' b
w* x: ]/ ~. _) s
4 ^: K1 x% M, L' B' i' e virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;2 e2 g8 }3 ? k3 u8 [
virtual bool CheckAndRefresh() = 0;
9 p$ K) ?2 k! O8 ^& W# } N virtual void StopAsyncFind() = 0;
0 _4 e% p! E" ^& H virtual void DeletePorts() = 0;8 _: i3 t2 ]1 A' @! N
virtual bool IsReady() = 0;
! M7 v |. {' F) v& Y. S% c virtual int GetImplementationID() = 0;0 _$ I% l: b7 V) J. ?6 x
5 ^3 x$ N/ q' T) F2 o* o. E4 n void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping+ j" g4 E6 ?+ _
. t m) n8 i* C/ Q) V5 o \
4 }4 Z0 ~# Q8 j void SetMessageOnResult(HWND hWindow, UINT nMessageID);
6 c7 o3 M. {8 t" g) g) q4 G' d3 n4 [ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }+ u7 m9 C2 D& B' @9 X% f" x1 H
uint16 GetUsedTCPPort() { return m_nTCPPort; }" P+ _; Q3 d" X
uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 l* Q. N7 x% |8 J1 i4 \
/ D% v& e+ i9 D1 `& N: D4 P7 S3 r' f( Y" p; { }
// Implementation0 D; M+ h: [* @0 z3 a* ]
protected:2 A0 |. H8 R' [0 R, b" U* @
volatile TRISTATE m_bUPnPPortsForwarded;
3 e: o) f( m+ I" d void SendResultMessage();
5 x- U. _; |5 T& `/ I uint16 m_nUDPPort;
+ s, `4 t$ a* {4 D& H uint16 m_nTCPPort;8 r. f% u" K( z" z# E
uint16 m_nTCPWebPort;6 W f1 N4 e5 e" S8 A. j' m
bool m_bCheckAndRefresh;
; e0 G' B" E( a3 x+ a2 Y' f+ O+ S1 u/ D B' E
& g& F/ n4 g- X3 e
private:$ ?4 p: F) ]4 w
HWND m_hResultMessageWindow;4 r" o* M, H: U6 w% L6 v8 g
UINT m_nResultMessageID;
9 N% K; Z9 e& u4 [
$ ^8 Y [! H. E3 y9 m6 f% R. L5 _( D( y s, h; k3 n
};
, p. _* R* b" R( q
! v1 \; H, O& a5 {/ A8 ~0 u' G* j) n: M* S5 o# @9 X! a
// Dummy Implementation to be used when no other implementation is available
/ ~+ \3 `, ?+ O# i: Gclass CUPnPImplNone: public CUPnPImpl
L A* j0 e& f6 L0 Z! y: J0 L{
0 f( s0 ^7 v) ^public:
7 Q6 @ L! F3 t1 Z. j$ O8 _% m virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }* _3 t3 }, d' M8 ~; {
virtual bool CheckAndRefresh() { return false; }
& e1 ^) V" K0 A$ L& k: |. t6 U7 n virtual void StopAsyncFind() { }
9 W* W$ X0 S# v virtual void DeletePorts() { }
, o, e4 |7 Q3 k6 j6 @5 k- R: R) F virtual bool IsReady() { return false; }9 H u+ p+ a; n* r
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
3 R; f$ e( l I1 C& I G};
: V+ M6 n: Q& }+ F: P W6 t0 M% P! |6 @2 r7 @. `
; _8 I6 _, Y$ r; e) s/////////////////////////////////////) H5 @7 }' O0 H; Y! e
//下面是使用windows操作系统自带的UPNP功能的子类, Y, J& m, ~3 x$ Q6 I( [
: @9 p/ ]# P1 Z/ z# |
2 ]7 K: d2 y9 U6 p) g#pragma once2 I. m. ]; P6 b9 E
#pragma warning( disable: 4355 )7 s5 K+ M2 E1 m$ q1 y% S
* x$ S# N. b. E5 v+ E
. R6 `. @3 X4 W2 I) N
#include "UPnPImpl.h"" o q: S. { B' P, O
#include <upnp.h>
$ {' p" W' l4 r6 C6 H#include <iphlpapi.h>
6 B6 R8 @* Y/ |+ n5 T# V: S#include <comdef.h>9 Z9 A; r( U6 ~9 o. n0 z1 ]6 _
#include <winsvc.h>: y8 P3 f; z, V# p
( G; O/ I+ n8 O: Q I/ m$ F b( k8 U0 H! ?( ?) k) y
#include <vector>4 O9 G. z8 v {# G) R) o0 X. {( G: ]
#include <exception>
/ `, Q0 l" F6 [7 q e# i; G#include <functional>* l z, |8 W5 Y' c( l
+ h, D9 t, [9 m, m' V
, L D; H& `( s% q
/ X3 B1 G. h4 s- u% c8 z" E7 ]2 P$ }2 ?8 }
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
& U+ K. Y' I* p; Ytypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
, C: A" H7 C1 v8 v! e' x4 w8 etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" Q. Q2 r& M: R9 d; ~9 e
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;8 i" j3 N) i2 L7 ^& w' t
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; Y ?; g% Z/ E! S6 i; l
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' c8 l1 ^- f; d- Z8 Q+ z ktypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;" V, E: P' w- o& u/ l+ V) C6 R3 V3 W
% {1 Q- ]' b* t* S- h7 W6 L) X$ ]7 J" e1 g+ A
typedef DWORD (WINAPI* TGetBestInterface) (7 q( ^& M% }. q! J/ n
IPAddr dwDestAddr,
; C( ?+ y" s5 v2 o* }9 T% h b2 x: e PDWORD pdwBestIfIndex: Y# K/ n- y- J4 J
);3 x2 |- Q" w! A% m7 M( h; P
+ J' k* x1 ^# N1 L y" e! f* U
/ q9 P" t; |" l3 J9 ^8 ?/ Ytypedef DWORD (WINAPI* TGetIpAddrTable) (
c% X- T; O2 U C- Z PMIB_IPADDRTABLE pIpAddrTable,
9 m T$ |& l- C& c. b PULONG pdwSize,
0 Q; [! {/ H: x2 h BOOL bOrder& \! a* ^# c: P( Z; B6 O8 b8 o
);; b3 D9 o) J7 x1 P4 m
1 j! r: N& |" _! ^/ ~8 Y3 l! X4 T1 D$ b% j& F
typedef DWORD (WINAPI* TGetIfEntry) (, P% X$ Z4 O( {+ B4 e Q) Y" p8 k$ N
PMIB_IFROW pIfRow( p* N5 V- l8 Y5 q6 Q& |. ^
);2 E! P: P& g1 z0 d5 W" z+ M4 ?4 A5 Q
+ Y: q! M7 B7 t C- S7 k9 r0 c" {/ O) ?
CString translateUPnPResult(HRESULT hr);
7 ~* R3 t, n$ \8 y' T3 dHRESULT UPnPMessage(HRESULT hr);) f+ V0 i6 w( i* ^4 B9 s
1 M3 J: x% E- z, g1 g4 G1 Q
$ C! R: U! h C8 K6 h
class CUPnPImplWinServ: public CUPnPImpl
0 z* r* o; k E n+ ~' w: o{
+ ~2 v: \% }2 K friend class CDeviceFinderCallback;
0 N9 }+ P* Z; i1 Y/ R friend class CServiceCallback;
; h7 `. |5 O. z, O7 o' \// Construction
* R# M! m' R/ l: A7 ]public:
1 J, M. |; H4 c9 l0 D virtual ~CUPnPImplWinServ();/ f. S2 Y9 f. v1 z- s
CUPnPImplWinServ();5 R: a1 z% x1 l9 d" \1 v; F& x% P
2 D, \" \- r1 X
5 o/ n4 \& C: R9 } virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% ^+ K7 j. o+ f; l" c virtual void StopAsyncFind();
; F% G* P7 y) N( L8 T( \. s virtual void DeletePorts();- L/ H' A/ i" x* _5 f
virtual bool IsReady();
* t r7 y# e6 K% F4 C s4 I- D3 y. _7 E% n virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }% G. M8 @" v+ c& z' ] `" w# b+ d
4 s. d2 x- d% h# w$ W& g/ p7 M: m0 x2 n% Y* b, _- @
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 @) R9 w: ^6 C, ] // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
# Y3 ^9 B6 \9 S- w6 E virtual bool CheckAndRefresh() { return false; };# R# b2 ~! e+ k5 h, V* G) X
! P" y/ P, V8 b, Z& R
: v) d" d4 F2 Y' V# c$ i+ Bprotected:
" S. }4 X/ }' M8 A3 K void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
" ~! G2 t7 E3 L4 g* R void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);1 y; ?- N% v& V( I* c
void RemoveDevice(CComBSTR bsUDN);
7 Y ` ~, p+ K' b6 L bool OnSearchComplete();7 |/ r4 I0 H+ U
void Init();7 K5 [! ]6 u8 \4 z5 f( X
. n4 E- \6 i: B+ ~0 A C
+ {, X1 n& h+ g+ u' h inline bool IsAsyncFindRunning()
$ l6 o' B4 Z4 I. n {9 U- O/ E! ]8 _
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
( E* K. }: A' h8 j# g S8 Z {& e& I q) Q7 G4 o, i6 z }$ \6 S
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );! P3 q! N# E0 k0 `3 T
m_bAsyncFindRunning = false;
3 V5 i% p- \2 O1 q/ ]; G }
! ~' z+ O) [6 m" K0 P9 v MSG msg;! P3 L# X$ u! `/ v5 z; ^+ i6 Y
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
; ^( u( P% O/ A& _. `5 G {% X7 ]3 ^1 B# ~0 l$ h+ O$ e
TranslateMessage( &msg );
& g2 G, v1 N- c6 @. }- w DispatchMessage( &msg );5 \ |4 t0 h. i4 Q# W6 b* f% _
}' v6 l- K3 e8 \3 x3 e5 s6 `
return m_bAsyncFindRunning;
! q4 E1 E8 V! g) N2 O: ~5 l }
" C7 ?+ M" E$ U9 F5 b" F5 J2 u& S' e* o. o
" L" e( x3 I; i
TRISTATE m_bUPnPDeviceConnected;. M' z- _+ g; \- _; f
! [: c2 E" J" M% `& S+ }; D' m3 J# l, y; {1 r9 m( t$ s {. y# j4 {
// Implementation& s8 e- c' v6 F8 w* @
// API functions
& k2 s4 c: V a3 e! ~+ u SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);# i% s, l! I8 ~. k/ O
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
) ~& T, b" W( V# G% I* @8 i BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
. H3 J' E- t$ T5 X: X8 r1 Y; Q BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 h; K6 a% `5 u! ]8 ]0 |/ C% R, g# q
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
% }0 }# v- @: _! T BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);& R0 n" Q# a5 l2 Q8 v! r
2 U) V6 \% i9 v S3 v! Y" r
+ L( `- j7 F4 P' y9 t' h TGetBestInterface m_pfGetBestInterface;' f7 h. l2 ^4 P0 i0 E. s
TGetIpAddrTable m_pfGetIpAddrTable;
2 Q& o# W# o( k( }1 Y TGetIfEntry m_pfGetIfEntry;5 z' F9 d0 O. F$ p7 j
; |2 q& f2 X0 ~6 R# F) e$ `" `
! f& q/ H# ?/ z
static FinderPointer CreateFinderInstance();# F! M! `( h+ g4 V! x4 s3 y# H$ T
struct FindDevice : std::unary_function< DevicePointer, bool >
7 z8 I0 d4 a" b' D5 m {5 b8 n d0 K' r. M! B
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}- a( E0 c( X' F" Z: a- Z
result_type operator()(argument_type device) const
! s" B e2 B) ]+ [5 ^ {
1 s5 | U$ w, x CComBSTR deviceName;
+ N" h+ V$ D, f+ w! w$ w( L HRESULT hr = device->get_UniqueDeviceName( &deviceName );. c# s6 A; C3 ]9 N0 @+ R: d
`! ?5 [8 e9 R' e8 g
! T' A a0 b& i4 n$ R: Z: { if ( FAILED( hr ) )4 {8 b( x* F+ s9 O! _: r$ X' [
return UPnPMessage( hr ), false;# R3 H' S* _6 ^$ l
8 f' q( P: A9 o( X$ ?6 y `
Z) E# D8 {8 z4 ` L4 p
return wcscmp( deviceName.m_str, m_udn ) == 0;
& h# \/ c! \: A8 L8 R: M* _) f* q D }# X9 p/ j9 r3 w. ~! I5 m, L: h
CComBSTR m_udn;2 x2 S6 I/ k0 Z' x9 n
};6 N( f# }# n, U0 m) o; q
( u1 D9 S* V9 M% {# @+ K
void ProcessAsyncFind(CComBSTR bsSearchType);' k3 I3 [1 N3 j+ p
HRESULT GetDeviceServices(DevicePointer pDevice);
3 x1 Q5 q1 [; G: X8 I void StartPortMapping();6 W8 ~! t% |* B* j) X- g
HRESULT MapPort(const ServicePointer& service);
9 F3 N. ?, r" V void DeleteExistingPortMappings(ServicePointer pService);
- G: H! s7 [3 B4 F, W& I# C8 F void CreatePortMappings(ServicePointer pService);7 B0 D0 [* ^1 p2 ^' \! g# a! d
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);% x% H! f% W1 u, l2 X2 j( Z" m
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 3 W) s w. t# [ }7 b! c
LPCTSTR pszInArgString, CString& strResult);
; S8 W2 L# H$ k/ B void StopUPnPService(); F8 {, E3 ^% s# Z8 p
! V) a# N$ x! q. S( }# h
: m+ _: o3 Y) A; E
// Utility functions' I4 O9 I* U2 b: z/ y% m
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
, l; }* i$ z: A& @ } INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 q( m+ w6 a% F( k) S
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);' r7 v* |; `8 G. B5 w3 _% i
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 X( O& L8 C% v# M, Q- \& U8 E HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
' w/ ?. p% d! e5 q( I3 P HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
. U6 j0 l4 H9 O: s# a, V CString GetLocalRoutableIP(ServicePointer pService);' [; t& ?6 F+ x/ y! Q+ _7 w
0 y8 C5 C: w$ a
/ _0 l+ S7 ]* v% A# a
// Private members
2 w0 M- D% C9 w8 xprivate:
) \) X9 x& ~& j4 K" { DWORD m_tLastEvent; // When the last event was received?
E: Z/ u. G. _ G& u2 L std::vector< DevicePointer > m_pDevices;2 S) ~1 Y: u1 \! ` `) {/ Z7 ?0 j t
std::vector< ServicePointer > m_pServices;
* L0 X* y1 V3 X! }0 D# L FinderPointer m_pDeviceFinder;; R( Q- q* W4 O& c; o2 {1 h
DeviceFinderCallback m_pDeviceFinderCallback;4 ]# Q8 j% @& t6 M) G0 A1 S9 X
ServiceCallback m_pServiceCallback;+ J& M# v: w! M% i1 l
; J$ T* D: @& _, a* k0 x! @2 D; z, g' T% @: U, M
LONG m_nAsyncFindHandle;1 E6 Z9 [+ }6 w: y1 D# i- p9 g: m
bool m_bCOM;; v% d# P4 Q0 z+ H5 N! |9 l! |
bool m_bPortIsFree;
& } W. F0 G2 b+ w" T* | CString m_sLocalIP;2 x( { m; i A5 s4 G6 W
CString m_sExternalIP;9 q) y2 g- I" N! E
bool m_bADSL; // Is the device ADSL?
/ l+ j. Q1 S' v2 @1 a bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
) c0 c3 {+ v2 @$ u3 b0 c# u3 o% T# z2 M8 C bool m_bInited;' ^- o. {" ] E# F- A; n K; x1 o
bool m_bAsyncFindRunning;
3 V5 f" Q5 I8 N" U HMODULE m_hADVAPI32_DLL;
8 p0 c1 |' j7 E& [& \+ m HMODULE m_hIPHLPAPI_DLL;
3 O! K) u1 k9 I$ o bool m_bSecondTry;
% T$ c# W; U" s9 u8 v4 R! v bool m_bServiceStartedByEmule;
6 U# m |5 @1 L+ }6 |& J# ~ bool m_bDisableWANIPSetup;
, X2 p: T/ A" p: `8 P; @% \ bool m_bDisableWANPPPSetup;
2 k% {/ {, u5 j3 l. v: i( m4 g# t: W
9 j5 q- L% ]: G4 K) M$ V0 M& J6 h
};/ C$ ^ C; c. ~; k4 @* E9 Q
8 _8 v) c4 w# V/ V6 [7 G/ z& Y' F8 }- Z$ g) C" E, J: [7 P" }
// DeviceFinder Callback6 b# U& o6 L/ F+ f2 q3 n4 k7 `2 i- E
class CDeviceFinderCallback: Y, A+ `# A; ?( W+ G6 r: K
: public IUPnPDeviceFinderCallback! T0 A2 ?& ~8 v) z {
{1 A1 Y% i) i: a
public:; O! c8 V- L+ R W. W4 ~- R
CDeviceFinderCallback(CUPnPImplWinServ& instance)
& I+ Z1 `3 {8 t& o1 D/ o4 e : m_instance( instance )
4 l' U N) N k. T( X3 \/ B { m_lRefCount = 0; }
) `% J( c4 X7 _& G" |3 w- R+ Y# J
# @1 ?& h1 |4 D j8 W9 ]4 f
# w. y1 L9 L7 w2 z4 N' r STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ ]6 x, v, I3 }8 g u8 ^6 ~" E: r
STDMETHODIMP_(ULONG) AddRef();
1 G' y; r, r: j* n STDMETHODIMP_(ULONG) Release();% A, A/ g, U/ M+ ~$ L2 M R$ n
. a3 |$ q- ]6 k( }+ H) c/ U0 W
$ u0 @. ?$ w' |+ o// implementation! [( r9 I+ |4 T, r3 \
private:8 f4 x2 ^; N" p: ~% q
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 U( Z. T" T& @- x. |
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);: f$ C9 L, D2 K% V, {( u
HRESULT __stdcall SearchComplete(LONG nFindData);! z8 c/ s4 Y5 P
* @/ q8 b: r( t/ i* a* m. A& |7 N$ @% F- p" u" ]9 \
private:5 H' a) z# w! A) `' a- W
CUPnPImplWinServ& m_instance;* l* e m) @2 h) D- l, {' Z: j# P
LONG m_lRefCount;9 j7 R3 T& S& I/ G+ J
};, b1 j) |, E; L v# w/ R
' e7 C" q- m& F/ @ I
|7 i, o6 y* L5 i2 A" {// Service Callback
; ^$ _4 t! l/ P. E, xclass CServiceCallback
' C7 T& f/ J! b' L. Q0 l : public IUPnPServiceCallback
7 s" @) c) Z* \, q{4 d7 @9 B9 S+ ]7 Q
public:5 U: `1 J. v* f6 I* M- v& K7 l2 r8 e
CServiceCallback(CUPnPImplWinServ& instance)0 g/ u z: y+ b1 l5 I |
: m_instance( instance )
- ?4 }( [# A$ G ^8 \9 n# [ { m_lRefCount = 0; }: o+ n! a0 x9 c& g; b B, z
[! v# U0 F" m% E STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ d: t, y. U# ?
STDMETHODIMP_(ULONG) AddRef();3 c+ z; Y. ?2 N x+ [0 x( f
STDMETHODIMP_(ULONG) Release();+ Y0 |% b0 K: v! d% [3 F% n2 B* q
5 B D6 o+ W9 L0 f, G5 j q3 M( U4 Y0 @* _8 o# Y- t2 i
// implementation
3 w) o: \5 a* W% E: |) Q2 W: z7 j: Vprivate:
( b5 D. ]& m8 k1 q# y8 e0 s HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
3 t6 l6 P8 k; E4 [2 C HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
2 f( X9 f' j, i& u6 o
, l0 U1 ^) G p; ?) f
5 s/ C* G$ x) }0 o* ]* N' Xprivate:, t# O4 H" J# S! e4 M% V# r' D5 J+ I
CUPnPImplWinServ& m_instance;
$ N0 g; o% C9 `3 b: W LONG m_lRefCount;
$ \4 j) G* ^) p6 c};% |3 X3 c3 d$ b' M8 u
B# n; b8 r0 Y' e' P2 W& M
8 |! A+ f6 `$ o t/////////////////////////////////////////////////. s" V8 V9 U8 x! w& q% G
8 V) B3 l8 h1 P- `
0 ~: _$ @" b4 f! o! n& F5 S. }
使用时只需要使用抽象类的接口。% R2 V g. J( J& h% q; j
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.) G4 A% U, z* Q4 d4 V5 N
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.* [; S$ z$ I2 b9 c3 Q
CUPnPImpl::StopAsyncFind停止设备查找.( F( v! c X- ~" ]+ y
CUPnPImpl::DeletePorts删除端口映射. |
|