|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
# q' p+ T$ o- {. _5 i: p- u* K
- s" g3 W8 y" I5 s5 a: `: m1 y
* r3 Z5 j* Y* A0 j# f3 n///////////////////////////////////////////, g4 @. ^. v' Z5 I
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
! v, U3 N- f' y0 J2 |$ h9 M- _9 g; ] C( _. f$ }& H! X. }/ f
3 @+ K2 ]7 \ E8 |#pragma once
% p0 }& V7 D0 h; p0 x#include <exception>2 O+ Y2 f9 ~# s9 x- W% T
2 h9 C( f) f. |# i3 ^- a
7 q( V1 V+ }8 t& |3 E! E. q: ` enum TRISTATE{* {4 @: Q' Z+ i$ o
TRIS_FALSE,7 Q% k5 W n6 |3 c
TRIS_UNKNOWN,
1 s, N# k2 W, i- k0 M% F4 u5 U TRIS_TRUE
9 j2 R& b' N( G2 H};
- p3 c' f6 \/ U: x$ N& a( H; s; W& s$ A3 U. s$ b4 ~5 Q, X* i
: F9 G: _- L5 N% m) P: ?enum UPNP_IMPLEMENTATION{" d# I$ D+ M c. V0 M5 W* n
UPNP_IMPL_WINDOWSERVICE = 0,) M5 S, p* J/ c. ^
UPNP_IMPL_MINIUPNPLIB,
: `+ \3 E v5 g, S) `) q UPNP_IMPL_NONE /*last*/5 h- F3 A; E. X8 X! y8 b
};
: t' a" h' p( Z" G+ s/ t* s9 T8 G, g: z9 Z0 W7 z8 f( f
" `5 i2 ~, w$ K( p: B3 q9 ^; m! D/ b7 i
7 U2 U" ~! j, I( R6 |class CUPnPImpl
* `, ?2 t \6 i: ^{
3 I+ g0 g' V, C7 A+ F9 j- x! wpublic:
& m4 G. Q3 P( m! d# l CUPnPImpl();
# p" A- Y3 e# k3 J% m9 y virtual ~CUPnPImpl();. W' b5 F+ ^) W/ c
struct UPnPError : std::exception {};
' h' {. a0 k6 c" b0 [0 R8 E; U enum {3 ^; J( S8 E( l9 T# V" O [
UPNP_OK,
* {$ C0 e& D) h' _1 c/ ~% ] UPNP_FAILED,
$ d, ^4 t; D ^4 j% E0 m UPNP_TIMEOUT
& F- ^* A& ~. Y2 r( e' ^4 V, R };4 C ~" k; N/ D+ Q
. X7 u3 f. j9 W& t* g) |6 ~+ {% `5 Q" s, u5 ?2 \5 Q/ Z B* F, L/ y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, t" v( W5 K) b# Y/ E9 P
virtual bool CheckAndRefresh() = 0;
. s0 t6 \4 o" v5 E% @2 f. S virtual void StopAsyncFind() = 0;+ Q; e6 i+ G" r) q* S3 R1 Q$ g$ X
virtual void DeletePorts() = 0;8 Y h' A! s0 A2 G% _* b$ Z8 [. \( c
virtual bool IsReady() = 0;, S- W4 J9 Y3 o8 H c
virtual int GetImplementationID() = 0;# o+ G( k4 q3 y8 _! Z6 F8 `
" T R1 r& }/ n$ m
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping: N# }! q( k/ P5 E% P7 i6 }
- r$ c& o4 S) v$ {2 w+ x( `* O
& x: x6 o% M* Q+ ]& E void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ }) |: Y. V6 }$ U! A* R TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, v" W L/ x7 h1 w& D
uint16 GetUsedTCPPort() { return m_nTCPPort; }* j, E: r' ~# c; u
uint16 GetUsedUDPPort() { return m_nUDPPort; }
: I' T) |0 Y9 Y; e6 D3 u' K/ X, ]4 A+ k
+ V, I; x$ {; B" p// Implementation
* w( L! Y5 R, B! M! n/ kprotected:0 @# Q# {( _1 \, K
volatile TRISTATE m_bUPnPPortsForwarded;
- p, U" X* V3 l; [1 O! ` void SendResultMessage();( h: w( k; N# n
uint16 m_nUDPPort;
! h3 g8 S$ |1 E uint16 m_nTCPPort;
" S1 Y% E8 ?, Q$ z* z uint16 m_nTCPWebPort;( k5 |( i# B2 Q' C
bool m_bCheckAndRefresh;
% `: H! K; |4 `8 g) \& ~# l( c! ^/ o
; i+ I) O4 {. ^! R3 D
private:, ? d0 m; C9 h5 ?3 E5 _6 x
HWND m_hResultMessageWindow;' h& v! [+ c- l; g. ?
UINT m_nResultMessageID;3 u5 w$ s4 j. c# W! p
0 h( {- ]) V7 x) A& ~ ]& g9 Q
+ B7 o# k, l7 [8 K: ?' f3 H' Y};6 l. u; B; L7 ?! S1 ~7 W
1 r/ _7 D+ A; b- }5 x. A& Q, x: X
; k2 \% G }/ X% o X// Dummy Implementation to be used when no other implementation is available, a3 g3 W- }; e& P0 }1 x
class CUPnPImplNone: public CUPnPImpl; D% w7 J% k6 P }: j ]. D7 x
{
@' d( w4 d3 s( P8 @" Kpublic:
& k: b6 k m" H- f1 r f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 V7 G+ d5 K9 a. L+ v: [ virtual bool CheckAndRefresh() { return false; }
" Y, b4 V. z7 ]/ e4 ]4 v6 ^ virtual void StopAsyncFind() { }5 m3 u# ?; d d4 L1 C/ U
virtual void DeletePorts() { }0 }+ t2 m% v/ T9 A) O" Z
virtual bool IsReady() { return false; }
+ q2 P0 Q' y) l4 l! p8 e virtual int GetImplementationID() { return UPNP_IMPL_NONE; }& M; l1 Z1 { C- t4 m. o$ m3 P
};
$ K; g' g2 x% G5 e( |- D7 P% j1 b: S/ a& z6 z! g6 X
2 _+ z- X. |0 a2 {. S/////////////////////////////////////
, |9 J( |5 m( D, u; S; H2 [2 W//下面是使用windows操作系统自带的UPNP功能的子类1 y& s" w3 N8 Z8 i* _$ h; Z' U
. S; S/ n7 u/ t/ K; [
9 A r/ y8 @. @9 g0 j( p8 Q#pragma once
L$ I# i w8 ?% I#pragma warning( disable: 4355 )$ U* V, k$ O1 j; S3 t$ W5 Z: P
/ q/ y8 n7 g8 J; x$ J, N3 o; E
) o& m) @2 f% c$ V2 H7 E: @/ q7 m#include "UPnPImpl.h"$ j% w8 q9 O4 P- u% d
#include <upnp.h>
$ n7 |$ v+ n6 c' N7 s, y3 E#include <iphlpapi.h>
: X% `% U4 P: F#include <comdef.h>
9 K/ j9 o' i3 A! M/ U: {# w( ^3 y* a#include <winsvc.h>! ]- Q- t% e7 ~- S" M( [
4 g3 }4 J% ]7 {% N; F; B* K! ^' \$ F* |2 y; U9 x( N1 y
#include <vector>7 g' I/ n! ~: ^: q3 r
#include <exception>
/ }) R) m, P# \' s4 E+ D#include <functional>5 ~+ s' K F6 Y8 {. J: G3 B5 N# O# `
2 \! v6 L. ^* G3 `. W* E2 z# m1 L
) Q+ ~8 K7 V2 B' w9 [. ~* g! B. N8 G1 | u, n; F; W, `
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
% k; P: V$ X3 m4 [( @typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;% \3 H* n: m2 L3 [( Y
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
- g- ]; K8 q# ^& i* Htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! O. |9 `/ ~" T: x- @) wtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' f( W2 ]0 N1 q6 g" X
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
, u' e8 i+ O# ^) t& ^+ ?typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;; M* x) w& N o
$ |8 R5 x6 s+ C: _; c' q- L- Z' L; `4 \6 U' o% N t+ l. T9 E
typedef DWORD (WINAPI* TGetBestInterface) (
! Y! [* i1 J$ T. _6 g6 V L6 ~4 P7 V IPAddr dwDestAddr,
9 W5 b; F* f7 W: B' k* W O; b. @ PDWORD pdwBestIfIndex
' E; V- f3 K9 q2 {& ~( ~( R. L);
7 c& l. Q* q6 p i" @ Q) `7 i8 K: n5 X6 o
6 J% P( e5 `( C$ m9 y; _
typedef DWORD (WINAPI* TGetIpAddrTable) (
( I. [9 S5 F; f; |* K9 |' m PMIB_IPADDRTABLE pIpAddrTable,* l' b+ F) Y; W, V2 K) h" w O
PULONG pdwSize," W% ]5 h( B9 }# h& c
BOOL bOrder
s3 ^0 `8 \% D: S* M" k9 j. X);) z& N/ p- F- z
5 U6 d8 n* ]: X1 J/ w' N0 K
; s9 w5 D1 x7 h0 y; |% V) B7 o
typedef DWORD (WINAPI* TGetIfEntry) (
4 a1 k( z- M9 u) ^9 m PMIB_IFROW pIfRow
# s u- J7 {' L);
& \0 Q. _6 R+ y8 I: ?4 ?2 b6 B: n
4 M( u) R1 ~0 Z7 t8 w- KCString translateUPnPResult(HRESULT hr);8 _9 x) i1 v& H! |% \$ t
HRESULT UPnPMessage(HRESULT hr);
4 b+ N5 M: h% L, ^$ E; w5 b% s3 W: V+ O: q$ O
7 s* n$ P" I4 M
class CUPnPImplWinServ: public CUPnPImpl
* x! e0 z/ `2 X' u* _1 K{0 v7 }4 M, ?4 D+ b5 ^6 k7 Z; t
friend class CDeviceFinderCallback;
8 W& l. Y8 @( Z' K( W" K( D friend class CServiceCallback; U8 S/ p" D* C
// Construction
* ^1 {& o) P. Z/ xpublic:6 c1 K$ N5 T% ^2 t. U( _
virtual ~CUPnPImplWinServ();1 f, C+ K3 ~: m+ _9 ^: ]$ ]# x6 d
CUPnPImplWinServ();! o3 D) h* N7 q# m+ w9 K
8 @$ @ Q; U$ G! a3 E# H" ~$ z O# T2 D1 g: G# X2 V( W
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }+ E; f1 i( a5 F4 h) {8 j
virtual void StopAsyncFind();" H6 d* I' V( a4 a% l H2 \7 V: A
virtual void DeletePorts();0 V0 l& j3 f8 `: B [
virtual bool IsReady();: d$ d: r6 U& }1 n: u
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
! D. D, d6 t* ~
# X" d6 \( F; R% h* U- F; v* D# Q2 H: W9 M7 ]6 n3 J& |% g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
* V9 }7 I, G8 F // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
( M* a- i3 b! m, M0 h$ x* Z virtual bool CheckAndRefresh() { return false; };+ j4 y: X4 W" { D& F$ W( X
4 C2 \8 ~( e3 p3 f6 @9 v! Z
6 j. Z/ M) X0 ]4 iprotected:
; T0 j( @& O9 Q0 U8 T+ S void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);% `, J/ d, r: p
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);, f; d5 s3 }' b$ C1 b v
void RemoveDevice(CComBSTR bsUDN);0 Y! J% h3 l9 |1 _1 v! k
bool OnSearchComplete();
9 P. _ c; l3 l3 n2 G void Init();
; M) S' H0 B% \3 T/ l' Q: {1 i) A7 W) i" t
3 d$ N, X, H- J" }! S5 |3 b inline bool IsAsyncFindRunning() % O4 u) S3 J6 [3 ]& c9 j
{ b( h" v- y+ v# [ L. G" ^/ |
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )# E' W: N9 G; g. y) E) O
{
8 u0 i( ]8 s, I m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- H; Z( L+ ^( W9 A. Z7 U% q" [ m_bAsyncFindRunning = false;' G! v q/ q1 c! ~( M; B
}
8 i( }( q0 ~: b! }4 q0 K* Q! ]8 D MSG msg;$ x* e q/ A; g/ |1 t1 l- }- E( l% P
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )* a o. |$ \" c" R% A5 K5 X
{
+ {# U6 l2 z& m7 [7 [0 {- i TranslateMessage( &msg );' J* ^' N# X: J0 Q [- L
DispatchMessage( &msg );4 k0 v$ N" E3 ~
}& z8 }, T4 ?9 c
return m_bAsyncFindRunning;3 ~: Z) P* h* x7 s5 h D9 o0 O
}
6 Z3 M5 M% M6 ]
* O, a8 B! \+ w2 e5 t3 B! d
$ l: k5 u- W8 b" O, y. u; D8 D# i TRISTATE m_bUPnPDeviceConnected;/ z T5 ]7 q8 Z7 \9 ~$ ]1 u
) i. I t q/ a) z! }" z" v$ L% q) J5 K
// Implementation) B+ N7 z9 v5 R$ W
// API functions
9 [" I) [% x3 l) I SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);. C! r b$ z1 B5 I
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);$ R" v) ^2 v$ o
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);# }% l/ a! g6 e: h
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);* h! A6 h- G& y i# R* T2 Z
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 M/ [1 s; v- e( d+ T2 R- `
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);; `9 X+ ? `$ @+ a9 b* }
: k9 z1 N$ B' u3 R
) c4 Z( t, O" B7 u( v3 u TGetBestInterface m_pfGetBestInterface;
& c0 W* A2 Z; e; V2 |5 A4 h TGetIpAddrTable m_pfGetIpAddrTable;
9 P/ ]* |9 o% q$ x3 ?6 M6 {! ]/ g TGetIfEntry m_pfGetIfEntry;* w: t0 d2 C% B) G0 b9 k4 G
/ f1 L# v9 f* V u8 I! |1 I
8 V* Z$ C" Q) Z static FinderPointer CreateFinderInstance();
% v: i! K0 G' j0 b) M: R struct FindDevice : std::unary_function< DevicePointer, bool >
1 |4 d. l& }+ x# `* N {
1 u( Z% |5 \. f! w; f5 Y5 d% } FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
* S& T2 a# ?( D- } T0 M1 i result_type operator()(argument_type device) const
1 o: C8 I8 q v8 O$ I {
- H- u4 i- A; \ CComBSTR deviceName;
. `: d R2 W# q0 A/ ~+ q, C HRESULT hr = device->get_UniqueDeviceName( &deviceName );
: N8 t8 E/ G1 w1 ?, p5 q0 \4 l7 s) s0 J0 \. {/ }
! K; C9 K0 F; O2 c5 `! b
if ( FAILED( hr ) )
! |- ]' q& r" f: b) e% G* H5 o return UPnPMessage( hr ), false;
3 V& r: s: Y0 I$ z2 j( f. p {$ m3 S; P$ n; q, D6 F s' S
- p3 N( Z" C( D- q return wcscmp( deviceName.m_str, m_udn ) == 0;
1 k/ ]. g6 F) Z+ k6 S }& W* Z' W* q6 w. U) I
CComBSTR m_udn;- p* I$ e V! T; T9 \% q
};
3 a! h( R9 X9 X( o3 l8 l1 f
$ O: {( B8 R/ z2 u void ProcessAsyncFind(CComBSTR bsSearchType);. [5 r7 t9 E& P1 G' e
HRESULT GetDeviceServices(DevicePointer pDevice);
' ?8 ?% W) D3 B& ~5 w6 L9 z void StartPortMapping();) N/ r+ l3 N* |9 O' k5 @
HRESULT MapPort(const ServicePointer& service);: o$ c0 ]. { G3 s/ @
void DeleteExistingPortMappings(ServicePointer pService);
9 g1 y# A& u/ B0 o) a+ r7 l void CreatePortMappings(ServicePointer pService);
& k1 s5 M8 `3 |8 X& u, b- O7 E, n HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
) V% P0 t1 P7 _) i- C HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
+ } z6 T7 R6 n* O9 X2 M2 S LPCTSTR pszInArgString, CString& strResult);
5 s4 W9 l7 I& e s$ M- C void StopUPnPService();6 Q1 u, s9 u' u. C3 r3 N
( c0 N; I2 [! Q( n
7 |! v. k J. d+ K% r // Utility functions9 g+ S+ n- F+ B- p8 U
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);. `( s" T( Z" N* W7 q
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* j8 ^1 ]3 l1 ~* d INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 \; m# X6 B/ |* g: h void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
# K# E3 s$ g, i" B* J9 m/ U HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* Y) w h$ I- y2 v HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);7 ]2 X: D7 C9 N
CString GetLocalRoutableIP(ServicePointer pService);
7 s( _( a! e f% g; t. R9 @) Z) B* W
6 g5 i/ k3 E4 |9 w" n8 o
6 r# S5 C$ f- ?4 i// Private members
, \1 d0 D8 m8 R* T2 w. Cprivate:" B9 M' ^) l4 E) q0 J% R) y% p: }
DWORD m_tLastEvent; // When the last event was received?
$ X4 g4 l- t* X9 a" U std::vector< DevicePointer > m_pDevices;
: w% \& \! U5 g2 [! G, h& Z- S7 K1 P std::vector< ServicePointer > m_pServices;* Y7 s v0 b# @+ \. b2 s
FinderPointer m_pDeviceFinder;
1 u1 B4 n1 ~# E0 P DeviceFinderCallback m_pDeviceFinderCallback;
/ Q1 `+ W( b) ?& H& ?/ b+ K* b ServiceCallback m_pServiceCallback;# l1 N% H$ V" W% \
& T& T% D0 X6 g: X& Z+ K9 x. n" U5 r0 r
LONG m_nAsyncFindHandle;
" N4 w6 L+ z: d$ ]0 d& A8 @ bool m_bCOM;7 d. L% o4 d; X5 ?8 s/ V
bool m_bPortIsFree;
% S5 G: T# L! ?7 P& @5 H CString m_sLocalIP;/ c) u" a6 r& p6 H- r/ {
CString m_sExternalIP;
# j" i6 v# H- l0 R bool m_bADSL; // Is the device ADSL?
+ H1 p4 C- D: b4 f bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 f# ]1 `4 ?; t+ E* g4 M
bool m_bInited;. |$ W: y: O2 g! _- T) s
bool m_bAsyncFindRunning;2 `. d; I2 k. a
HMODULE m_hADVAPI32_DLL;: k) k7 v7 L( N5 G; s
HMODULE m_hIPHLPAPI_DLL;
9 `# b3 o; X2 N" i+ p bool m_bSecondTry;7 r6 E6 G( B- m4 l1 l3 [
bool m_bServiceStartedByEmule;
$ a* t& h0 i) B( H" ? bool m_bDisableWANIPSetup;+ Y0 X( A- U) e( v. N
bool m_bDisableWANPPPSetup;$ [5 X7 C8 G) }9 [; }% C% B8 g7 ~6 s
+ d- ?# I/ K1 {* ]2 r |
7 f( C1 L6 `2 ~9 p2 ?& b, ?7 s7 y
};% R+ e* [8 ]; q u; _ ^
% a/ H' x% T5 b$ K
1 \/ w1 \( e- Z// DeviceFinder Callback
* ^: y0 d6 g6 \' S' A+ q& gclass CDeviceFinderCallback
) H1 o) W6 R7 A8 l* X' _ }: b4 S& L : public IUPnPDeviceFinderCallback" I( g3 |& C; T2 p1 |7 z$ \# g
{
: M( v4 \: Z$ p; q" b- Q3 kpublic:3 x7 M2 K3 u* [
CDeviceFinderCallback(CUPnPImplWinServ& instance)
, K6 O" F& X/ V+ B! d+ e: G. x0 l" ~ : m_instance( instance )" z: z* J2 l+ l! T/ t
{ m_lRefCount = 0; }" |, n. O( \. s) v8 N1 g( o8 m! n
7 H& I; ?+ m0 \( z' {3 t7 r
/ o: S K' P4 ~+ c
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);6 a1 s/ d- }9 h5 m. l9 O! N
STDMETHODIMP_(ULONG) AddRef();
+ G9 j C; E! o7 {( r STDMETHODIMP_(ULONG) Release();
) X+ }( z: a1 f9 M' } \) I+ V, R; |
7 p s- l2 ?( n
* o8 M1 U1 M% [+ i5 o9 G// implementation
' {: |9 `2 K6 a. B* A0 |private:4 a! q/ i) {7 W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
k& C* ^( ?1 Q HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);5 y0 Z1 s5 [+ K* E
HRESULT __stdcall SearchComplete(LONG nFindData);
8 u& w0 \; e: j6 m% p0 C3 i1 ?) h3 N( n. H( }3 n
, U# C( A# a* Y# }% Y/ @2 `
private:
5 j- g" u3 I. F/ H CUPnPImplWinServ& m_instance;
9 l p; u, Z2 S- ~; A8 _ LONG m_lRefCount;
~( ?* Z. ^1 \* N};) g* j! c: K* K
[6 p. N1 X; K- g
3 i: C* Z/ }3 J f/ h
// Service Callback
# G& V: n! P" { [1 mclass CServiceCallback
7 i% X) P, Z- L : public IUPnPServiceCallback
" D% w/ P; p/ ^' X: ^ Z. r J{
6 b6 R' L5 D/ [( I* j% i6 Z- xpublic:
5 H/ l$ a3 K2 h% A* ]9 M3 `' P CServiceCallback(CUPnPImplWinServ& instance)% Q/ @0 s' o" i& e
: m_instance( instance )6 `4 ]# e; R( }; ^
{ m_lRefCount = 0; }
1 s) ]( @! c+ t% \ 4 P; Y3 e8 K- c% f1 A/ W- f7 a: z5 |
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 E, P) b7 }% @5 T% a2 h7 r
STDMETHODIMP_(ULONG) AddRef();
, W% \1 w' X4 s( R STDMETHODIMP_(ULONG) Release();
7 R+ t: j9 J) I" B
0 l$ ?" {% d) C( G2 z2 p: j' n1 n0 W2 R) z6 h
// implementation' d" C6 w3 }- P7 ]) H
private:( k: O. P$ `* h5 ?& F
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* M3 N y/ L1 L$ @( n d
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);( N' K! g- H" z2 B; C* b7 @* w
3 y* i% r* V) z4 {6 o2 i. f; S6 T1 {( ~2 |, _
private:( e" H, e, u8 e' p: E
CUPnPImplWinServ& m_instance;. I2 {3 z; M: j! i
LONG m_lRefCount;6 d) X0 i! N, F% `6 k/ Q
};
0 [. J" N; E( s8 E$ O" }& ]5 i9 J e* \* C) S, [
/ j3 L1 i& U) W) x& L/////////////////////////////////////////////////0 y- T t' Y5 v
2 e: k- H v* a9 o( h4 ~7 I0 O. p! D+ f$ ]
使用时只需要使用抽象类的接口。/ s4 D7 T# J; l4 G5 `6 X4 m
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
9 N1 q5 [/ D! x& wCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' \6 r, f- ~$ @: u4 I: W% F
CUPnPImpl::StopAsyncFind停止设备查找.4 S7 Q+ B# \8 `/ f# f9 n: J+ o7 [- G
CUPnPImpl::DeletePorts删除端口映射. |
|