|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
0 g) K3 _( B; f) l; ~0 Q" i- T B/ V6 `8 b6 T! S# z. F3 x
# c8 Q x: {3 |( {- E5 P///////////////////////////////////////////
5 D4 t& C1 y2 m( q+ E//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
1 H. U8 {! C6 u7 x# B9 |
; T$ R2 X+ S; Y8 O3 D8 h% _' c7 v5 C4 s. A& i8 [
#pragma once8 F) u3 R2 V# w& \
#include <exception>
2 g6 u3 V( X* f6 x) p8 v w# c" b9 y4 H2 i5 m. g
9 g9 Q4 W; G9 C b. s
enum TRISTATE{( ?, w: E1 f/ z+ G- X: C1 A
TRIS_FALSE,
# j6 D2 B+ u; W: N TRIS_UNKNOWN,1 J9 }! [% p% T' K
TRIS_TRUE
% y3 R& m. M. D};+ r& C7 p' ]9 d2 u3 H6 i
6 r) {5 x1 x& G/ [6 G
, \/ u# {7 ?# w( \* m
enum UPNP_IMPLEMENTATION{( H" N2 \: b' a+ F5 \' l
UPNP_IMPL_WINDOWSERVICE = 0,
; o. A/ t5 c% H# I' m4 T0 t UPNP_IMPL_MINIUPNPLIB,
, [# \3 w) \+ Q( O: P0 u5 n UPNP_IMPL_NONE /*last*/5 t+ Y8 y8 g9 {; ~
};! z9 N' T, A% j( t# K
8 d) c. b# f9 N1 ?* h' o' Z
4 _0 Q/ e$ K; c! c8 w ~
9 B7 r* m. T; Y5 ?9 R* d
- v3 }) p0 b% [# j7 [% Q; R
class CUPnPImpl
* V% }! h( A0 q/ t, m0 J1 `{
( e8 v6 `3 l7 L; W$ wpublic:
( C: h3 d9 F3 U CUPnPImpl();
% ?% t4 _5 k3 t+ V6 t& E virtual ~CUPnPImpl();0 s2 N+ O1 t$ Q. k7 G
struct UPnPError : std::exception {};' j2 x; g$ d1 z2 ]2 [. w
enum {
8 | |4 e1 p! q; d7 Q UPNP_OK,* {9 ]2 I3 N! s" j
UPNP_FAILED,
! V' Y" q8 L; K$ o4 s& F0 n$ D UPNP_TIMEOUT0 r1 L3 H3 l2 }" u3 |1 T5 P/ }
};
+ F/ g, A6 `* o4 H. Y' P6 B% M5 P& X
1 x5 K8 p4 J9 @' }" I% g( B virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
. j& [, D! |* m# o# L% h" ^# Q virtual bool CheckAndRefresh() = 0;: A3 q1 \ E" j H" w2 S
virtual void StopAsyncFind() = 0;5 c+ X, @3 I# K! l& }. e6 V
virtual void DeletePorts() = 0;
: x, f. `& F v9 ^. A$ E+ } virtual bool IsReady() = 0;0 h$ ?- K7 a# x. s. M
virtual int GetImplementationID() = 0;, @ A, N l2 P2 s/ \/ j2 k5 U
0 w7 g @; Z1 W& `, M0 u void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
, S/ p- x" A/ |( ^3 R* r9 Q) P% V: C" ` ~7 h+ Q% p
6 p5 {* g* a( A$ B
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
4 Z) w$ O7 g7 R7 B; `3 C TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
! G! O N& k" \; j/ }7 x3 S0 B uint16 GetUsedTCPPort() { return m_nTCPPort; }
! ^5 {5 r# [# E( d2 M uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 s% E. J; i' o2 _6 a" q
! L1 u+ u2 t5 \
5 S& ~' l6 @# P7 B: R" q# R, Z& X
// Implementation
- u* G1 }1 y$ Aprotected:( |5 B; ~5 P. X4 T8 q a G
volatile TRISTATE m_bUPnPPortsForwarded;7 D& Y# b1 | h; {$ Y8 P- ?
void SendResultMessage();8 `5 _( t7 R% H
uint16 m_nUDPPort;
9 e9 s- u1 D* P2 d3 |6 k uint16 m_nTCPPort;: `- U2 N3 s3 v1 S2 o" A7 [
uint16 m_nTCPWebPort;3 L' \% u3 |- T/ M* ?
bool m_bCheckAndRefresh;
/ ?1 b: Q$ D; W7 S
6 \4 l. k9 Y* j7 F! F
5 g# \+ z6 Y7 I' k* xprivate:
) L p6 j* N% j I k HWND m_hResultMessageWindow;
9 S; Y4 w& P& X$ k UINT m_nResultMessageID;. n3 P, d2 P/ \( P- {7 ~' u
4 {9 D- ~' a& D/ D: d+ d7 ^& ~5 c* l0 b
};( C0 ?; D0 t( x4 X
3 `# q/ y \5 x6 c
# Z* T, F U8 f/ R8 v: X; b1 y9 X3 Y// Dummy Implementation to be used when no other implementation is available3 c4 R, D7 n& I8 z: d4 v+ I
class CUPnPImplNone: public CUPnPImpl0 ~: e( m B1 s6 u6 N
{/ X; I2 I# p( \3 H! r0 {* d4 N
public:
2 x6 C$ i" M! `. j% Z6 q) \ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: ~3 F8 ~1 l0 O/ Z virtual bool CheckAndRefresh() { return false; }# z }* S9 \8 r: ?6 X, |! s4 M+ I( ^
virtual void StopAsyncFind() { }
8 h: E. `( C. ~) D2 s/ q [ virtual void DeletePorts() { }) o: a$ ]6 K$ p- J( d- Y5 z
virtual bool IsReady() { return false; }2 k1 r$ F( X: k1 I% Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }( h% r3 [! s% P9 R/ K# L" Y( b4 y' A
};
7 r+ w9 P1 m1 _% O! X4 \
8 l: e3 S8 y! G) p Y0 J! y* ?# u, L5 P* P
/////////////////////////////////////4 {7 n; s+ U b
//下面是使用windows操作系统自带的UPNP功能的子类
1 m4 d6 g* z5 O5 J
. ^& T! S& k, U! Q( e5 z3 x6 m6 e, H- E
#pragma once
5 t8 N; M% p3 W: `" A( x1 W#pragma warning( disable: 4355 )
* C7 ]% u0 Q; i/ a" s) ?
. s0 p# _; p: i. x' o3 n- ?9 }9 Q
/ e% Y3 X q2 l3 B3 i! h. z; O#include "UPnPImpl.h"0 E0 O8 d6 M! j, A7 Z- y
#include <upnp.h>
$ q2 K ]5 F+ p. s6 a/ d6 c1 @+ u#include <iphlpapi.h>* y# O* R* P; Q3 B) m$ I% f8 W
#include <comdef.h>7 M- Z; i, g1 |/ g5 Q4 y
#include <winsvc.h>
5 l' u5 \* d; F' r, r9 |* G H- ?1 p
! P! }& x+ a5 ?, y% h
5 _+ Q l2 q! i9 T. P#include <vector>
, Q) T9 o- }/ U- H# r+ S }6 r q#include <exception>
" g: V& m! V9 w9 g7 r& I#include <functional># p/ w& V1 k% z" Y( F, d( ?
6 @0 u c" ^* f8 H" X, }' b+ G9 n
" q0 n& r) |- B/ c1 `5 o
* I5 }8 y# i2 E0 F
6 b' e+ z+ G/ x: h! N7 R$ b& Stypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;; n2 o Z) u% w* M x( I# f
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;, d+ Y: V1 M! F( z. I! Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;! y3 X# v- Z. U3 z9 S) ~5 J- F- X' @
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;+ Q, V3 l+ e1 b, ]- T
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
' p/ d& o1 \ ?& n. i9 b! \6 utypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;3 p: `9 \' @ U
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;5 I4 Y6 `$ X2 [4 P C
$ ]$ N9 ], x, ~5 w8 h
" l Y6 Q+ _: E* u& [$ Stypedef DWORD (WINAPI* TGetBestInterface) (' ~6 D& {) a w7 q
IPAddr dwDestAddr,1 u: b d0 |' n: O2 u0 u ]1 W
PDWORD pdwBestIfIndex4 @) w, j) ?- y o% {- ` C
);0 `' b( f# y* M$ C9 b2 ^
4 W, r$ k8 o' s' m Y6 d. d3 ~8 `; c! G6 T, q3 W7 O& x; B, H
typedef DWORD (WINAPI* TGetIpAddrTable) (, ~$ F) s; u( Z h: F/ [
PMIB_IPADDRTABLE pIpAddrTable,! |7 @) H. y* E$ V
PULONG pdwSize,& `/ f* j; o! t' i% {# ^
BOOL bOrder. |) }6 @ S, {. y, V1 M2 F: K
);
& P: r( g) H$ W7 x! j$ P( l5 a" ^- y% f" H6 A
8 n0 c8 S. i$ Y3 x( t. Y5 Z6 ]8 qtypedef DWORD (WINAPI* TGetIfEntry) (
$ a$ ~# h: n E, h/ C' [ PMIB_IFROW pIfRow
; C) [) E: e: j8 p7 V9 m);
. n2 p! \. m, L/ }, c( e) E$ A# U5 u$ v7 H
& \& q* V& j( e. O$ `, qCString translateUPnPResult(HRESULT hr);0 s. G: V. t9 c1 N
HRESULT UPnPMessage(HRESULT hr);
' Y2 ^$ n: g9 i: Q/ \# F- G' o5 X4 R6 a9 \- s# @4 m& c( P5 L
$ f) c/ G* J5 ~5 K# X2 aclass CUPnPImplWinServ: public CUPnPImpl
4 D }* a1 I# ` [. N- K0 ?0 {; M{
' p, _& ~6 t& [6 z c friend class CDeviceFinderCallback;$ D/ Q. g6 N1 I) w& ~/ H1 l9 o/ d
friend class CServiceCallback;& }1 G- C% T. T5 c& n# ?
// Construction0 E( f. Q0 R7 i! Q$ K
public:
6 M# x2 _) j" M$ D. f% ~5 E4 C virtual ~CUPnPImplWinServ();$ k+ i; D' B4 r# ^/ R) I
CUPnPImplWinServ();- ]/ V+ e1 B$ b9 A d
+ O: j% R1 ?2 B! g3 t. k0 r8 v/ H/ f8 A5 N; E
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
$ p) z$ j# E( N0 I. W8 ^: E virtual void StopAsyncFind();) ^2 T, z# k! T- L9 k/ h7 n
virtual void DeletePorts();4 e2 d' s8 M( v& K
virtual bool IsReady();
8 V! p; t! b$ G, M$ e# _7 q# M virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
/ m3 [4 q. L3 i1 e# j9 ~) C3 b
8 ?* C& M7 e& C4 X. \1 a3 E4 s3 g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
2 g4 {5 T" [& L( l; Q // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later/ n- t7 z; p, ~4 P6 L5 O& f) x) J
virtual bool CheckAndRefresh() { return false; };
, Y1 l! m7 v' O- J
9 L) `' x6 M& ]0 \* Y! T0 r8 U9 n& D& h
protected:- e3 _& p7 Y/ o' ?3 t
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 o9 p8 C# R$ g void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);) P% r& A. s a c& e" S7 O8 A- Y; F
void RemoveDevice(CComBSTR bsUDN);+ R0 U" l8 a3 ^+ {. h/ x4 Y
bool OnSearchComplete();
" W& v+ f2 _4 Q% W C# h void Init();
' J$ H% Y: q+ o+ z
$ F! o& B% M3 H( S0 p
" f9 N# M- H: Z- q inline bool IsAsyncFindRunning() $ J$ y' f# R+ F; _
{
1 P- g+ m( V+ n4 V/ A/ O- @ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
5 y' u3 Q) n3 w; v# n {
( w8 J$ J; C Z+ c1 F/ B; K. k m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 ~% r0 f J4 ?1 `! o
m_bAsyncFindRunning = false;
) w) a% L; v0 t4 A }
6 ~; r& y* j% s+ V MSG msg;
) t e! z6 ~3 l: s0 k while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )9 }4 i, X2 W& f
{
+ I- W' h: D' ^+ o+ |% N TranslateMessage( &msg );; i0 ^5 ?$ e5 E0 A
DispatchMessage( &msg );
+ d3 r( p: P4 D( W, i, Q0 ` }
$ X0 L. E* Y( l return m_bAsyncFindRunning;1 X% L8 j0 s" m: N+ ?. m2 }# a9 Y
}: s: K" T) N; o. I9 R, v. H9 ]
+ o( t' b! g5 p5 b; b- W3 X' R n3 O. z% T' J6 r- ?
TRISTATE m_bUPnPDeviceConnected;
# N/ z2 p5 R$ p) l& a5 f, E4 F( A5 K9 I! |" _! e; i1 r
& A1 n$ T8 ~4 f5 [// Implementation
( `8 N$ G$ k7 {0 ~% ? // API functions) m+ T# X1 y9 s$ i* X. p
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
, O" E6 |+ K* |2 O5 T$ g SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);$ S* I- S) H- G, h9 B
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);% G0 S/ v6 j, b( X% B# C
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
) x1 A$ ?7 b7 z. h$ b! V BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
! ^6 T; v% z' H9 x BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);# \7 {, h& ?+ _) \5 ?7 v1 D
: m/ i0 q$ u7 W) W- U( P m) j f' b C( z$ S1 c& N- s
TGetBestInterface m_pfGetBestInterface;
0 Y. r! Z/ E/ a8 Z. X TGetIpAddrTable m_pfGetIpAddrTable;
0 g9 M: k) K" o+ {- p1 z- l TGetIfEntry m_pfGetIfEntry;
+ s: E8 ~, E/ g, i
1 s7 q6 {, |, h/ k. K0 q
2 A: C, X$ ~) p w9 O' G8 w static FinderPointer CreateFinderInstance();
}! \3 G# J2 J3 x- a struct FindDevice : std::unary_function< DevicePointer, bool >
* M) K: q# d4 c# {% u" i* b {
( u. a+ f- |( Z* y7 O, M: u9 m6 m3 r FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
; p% p+ _9 V9 a/ r; ]5 D2 ^7 G' V result_type operator()(argument_type device) const+ H& L+ S' d8 [( o) T
{
4 \, H* M) M& g, h2 D& J CComBSTR deviceName;
* a. n5 N" P2 K+ \' u% t HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' B- g8 E$ ^7 ]; j% D& }
2 {: O- x! O% U
0 E7 [. ]& X7 M3 F6 {$ \/ h5 C1 J if ( FAILED( hr ) ); U! N; `/ N9 G) |) [3 [/ Z& C+ o
return UPnPMessage( hr ), false;/ M6 O4 j5 d' O( P% u- w, q
6 P% o' S, V( p/ m) \' b% c% F1 {$ [2 z" t7 _5 N
return wcscmp( deviceName.m_str, m_udn ) == 0;
' |$ Z& F4 e x6 w7 u8 t7 _ }
8 ?# w" E" T' @+ ^+ w" x CComBSTR m_udn;
$ T y- Z: R. C! D' V d };
; j; C& }( z% O) [( }* l
V s+ G6 m5 t3 K void ProcessAsyncFind(CComBSTR bsSearchType);
7 ?- ^4 z6 ^; }3 J# C HRESULT GetDeviceServices(DevicePointer pDevice);
* \ Y5 C1 L. q6 N! o: `! O void StartPortMapping();6 F! M7 N9 u; ?0 D
HRESULT MapPort(const ServicePointer& service);$ n# |2 c8 T, x( W7 Y/ z2 K4 R
void DeleteExistingPortMappings(ServicePointer pService);
- Q& E2 l. g! B/ V void CreatePortMappings(ServicePointer pService);
8 S0 Z. Z3 F/ b$ z$ P) l HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
0 \7 }. A0 E$ t" H7 K( C HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
$ d; S* v0 U! f& V LPCTSTR pszInArgString, CString& strResult);
5 N, D) N! s# K/ Z void StopUPnPService();
7 N3 [* J! d( y" ^
1 U% T' `" s8 j4 g% L. m1 D1 b% h2 a8 n6 k8 E
// Utility functions
4 }. n3 d' D% a: e2 z3 B0 ? HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
3 P6 ]9 _% a' y9 A# Z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
9 |+ K, p' j$ i. ^! m8 S2 c& c INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);9 x* c1 J! t* G7 Z/ t; y* P
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
4 F% u+ {5 _/ U1 ?' V HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);# _* z1 ?2 K" }1 l$ C
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
& Q3 s( j- i7 p+ {3 Y CString GetLocalRoutableIP(ServicePointer pService);- k! z- A) q' \
; r5 s+ o, {) t3 a. |2 e
! F( l" [6 {! g// Private members
- B: @1 `8 W% L2 y% Qprivate:: V: N# ]* s; ~8 U9 Q4 X4 f' s) T
DWORD m_tLastEvent; // When the last event was received?
1 Y4 ]3 E( ^2 W9 m! Q/ Z8 \ std::vector< DevicePointer > m_pDevices;
, A' P8 I: [/ \8 t' L+ N7 |2 \ std::vector< ServicePointer > m_pServices;
2 `/ v! L) ^. l& i& w4 Y5 v5 D4 I- t FinderPointer m_pDeviceFinder;. i/ @+ c/ q0 O5 R3 l- H e* m
DeviceFinderCallback m_pDeviceFinderCallback;
/ p& A8 s" f. i$ q" U c1 P ServiceCallback m_pServiceCallback;7 j% D7 r* V3 |( u# r8 X+ T) i
7 s3 [) ~" T) P% a$ y% @5 a/ |: ]9 ]/ V3 ^3 c, D4 y/ N$ }
LONG m_nAsyncFindHandle;
$ l" N" B* Y% ^- L0 |% m/ m bool m_bCOM;
& h! Y# s/ B' Q* |1 s bool m_bPortIsFree;
8 a7 t- Z' U/ T0 K1 M: p CString m_sLocalIP;
3 q* Q9 E, y4 V! ^$ ~3 d9 q CString m_sExternalIP;' C. ~5 j* d. ?2 Q$ n
bool m_bADSL; // Is the device ADSL?
4 d5 E0 p) S, s bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
/ s) W# U; b5 E) V8 b5 R8 x+ T, w bool m_bInited;
+ V7 b- r0 p; G( s3 r9 p# t bool m_bAsyncFindRunning;
; o& f# `5 ^) U2 e, L HMODULE m_hADVAPI32_DLL;
9 [* j$ N# S. \1 q; g HMODULE m_hIPHLPAPI_DLL;4 U- |) O7 o. f
bool m_bSecondTry;( B# b U6 ^7 f& ~
bool m_bServiceStartedByEmule;2 R2 P A; D% p- \7 b8 K. a
bool m_bDisableWANIPSetup;
; C7 t" R2 {9 s" o" Q! v9 S bool m_bDisableWANPPPSetup;' E4 F$ i0 [- ^* O8 u( z
2 X- @$ M+ M8 \7 _/ y- ^2 L: P- P% B. U9 X- ^
};4 n; ]4 v7 |7 [& d& K) `0 U! m
4 i0 U7 I% G7 t4 [+ t
9 _2 Z$ x! n6 ~" E
// DeviceFinder Callback" p5 x2 Y0 ]* w( ^/ \0 U
class CDeviceFinderCallback
- I$ e- ]6 j( o8 ^. l; T; o : public IUPnPDeviceFinderCallback0 n6 g( Y) t0 l' _/ C) P, `
{, b- }) `" C) S* `4 Z- l4 \
public:' C' l: h. \1 x0 {% b
CDeviceFinderCallback(CUPnPImplWinServ& instance)8 c7 @ C! }4 A) M: u: N" Z
: m_instance( instance )
1 H" G6 v! H- w1 r8 z& E; m$ g" G: ` { m_lRefCount = 0; }
' ~# K. q0 F3 |, V& `: `+ ]
$ o0 K C9 a5 ]6 j3 c8 J/ J* f. d' l- E: E: p
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- s8 K6 Q3 }& `6 W7 Y& E+ q7 H+ p STDMETHODIMP_(ULONG) AddRef(); v9 d, P. H$ t& B
STDMETHODIMP_(ULONG) Release();) C/ E4 p& j3 l2 n5 r" O
7 T6 s# p. a" l1 J8 D* ]0 o% U J$ v+ b
// implementation
0 ?. w; y- b! ]0 Q" W% K+ N7 q, l0 ?private:3 r/ S8 ^6 Y( {( b: p8 n
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' L( j/ ?8 U# ^' G! R) {6 p HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
# K8 g, D: ^& c1 Q9 R HRESULT __stdcall SearchComplete(LONG nFindData);
/ @8 e3 C" b1 O' O4 _9 A/ {: V. F2 [8 i4 H
4 w: h5 x% e0 mprivate:% y C8 N6 G; P! B4 ~# x
CUPnPImplWinServ& m_instance;6 G8 Y% U+ o, Z
LONG m_lRefCount;) [' ?& S! b$ o: V) N0 i' q# l
};
9 c' [& e# n/ b0 ?! ? C
. L6 l5 L& a, V9 x( {7 I! }1 R) i% I
// Service Callback . a6 h, k! |# `* I7 n9 m0 P. D
class CServiceCallback
7 ]5 @, q4 j+ u1 `% V" k* j& Y9 ? : public IUPnPServiceCallback
2 A& b, X8 K z; T. b0 v: p; ?{
3 _7 k8 r3 V, e2 Q( _/ m S9 B# xpublic:
( x* X3 Y! E! X: e. Y; I CServiceCallback(CUPnPImplWinServ& instance) Y Y" W/ O: l9 U) b! s4 N0 r
: m_instance( instance )$ Y2 ?$ P$ q' x3 ?! Y
{ m_lRefCount = 0; }
+ g# ]0 c) e& m8 ?9 ]4 U
5 [9 V8 y" s7 I5 Z: C* q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% q' Q0 |+ N$ j& W2 f, y STDMETHODIMP_(ULONG) AddRef();: i, ]4 r0 l R2 ?# H8 C
STDMETHODIMP_(ULONG) Release();5 U4 f. I+ ~8 Q4 {' ~* w# k! ]
8 A! d s& g3 U# A6 x! X
M. f, G3 } R3 z) ?2 c// implementation
2 _: K5 |% ?! K- `2 A0 q1 y- W9 Eprivate:( C& H4 g/ I7 h- A- ~( f
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* ~- E% u( [" z0 P# @" w7 O
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);% H9 Z) r- N" f- r# d/ I) U% I
n/ H$ ]- x0 s4 a) Y0 |. \8 M+ F, o9 ]- B; G3 h D
private:* c# H5 g" Y1 e; J$ ~- H
CUPnPImplWinServ& m_instance;; ^# i* | U% `: M! o" b
LONG m_lRefCount;
# n& u! N5 Q, [ A! z( i2 R};8 @2 U. W4 ^+ i8 a; B
) g3 O! q, H0 u2 h$ t' D
! l0 h' {2 f6 T) i, x+ _/////////////////////////////////////////////////2 D2 T. y$ X8 ]% f& U/ o
- F& w$ T$ @1 j q
5 U% l0 [& z5 u6 ~使用时只需要使用抽象类的接口。) M X; Z9 ]3 G, q! @1 F& V$ G
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ s; J% C4 c0 s: F$ N% u1 k5 L. m; XCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
5 K. \3 y- B4 {! d. ICUPnPImpl::StopAsyncFind停止设备查找.
1 d% I: }* ?$ I5 O( |6 A# U" hCUPnPImpl::DeletePorts删除端口映射. |
|