|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
, `' B0 g( }! N3 ^: J% l+ l# B6 h1 f8 J% U: E+ Q
# Q. R+ N# Y7 M" @3 g6 P: k# {9 m
///////////////////////////////////////////; j2 e* t' D( o& l: f5 v3 @) Y
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 `: O/ W# L/ }( Z4 X3 Z
. m3 z/ h U6 K) f. ^! m! D, D [8 w" J* U% K
#pragma once, j4 X+ m7 r; H( p, M7 g* V
#include <exception>
! D- M! r( I; j% c v* w5 e O9 L L) N& H0 Q. O8 h J. I4 i$ O
7 B; ^7 M+ B# m enum TRISTATE{6 H& y( g. [; r/ t0 b
TRIS_FALSE,
9 B/ D* y) M5 ~9 U0 b" v' d TRIS_UNKNOWN,% ~, D+ s( q1 Z& [2 C3 v
TRIS_TRUE" Z$ J% j7 A) `+ B& I9 \
};8 U& b; o# a: |8 e' ~# W0 t
( a0 L6 Q7 X! ?# `4 p2 I" D
# C4 J4 h6 Y* ~4 O% A* T% aenum UPNP_IMPLEMENTATION{
7 c" y* _; q' p3 K0 N( \' ~ UPNP_IMPL_WINDOWSERVICE = 0,. \/ V Z& T% V! M
UPNP_IMPL_MINIUPNPLIB,$ h) | @& w, d& n
UPNP_IMPL_NONE /*last*/+ b6 L: A. K7 W W# w5 \
};6 W( g2 _; A* F! X4 s
( {) Q' P+ z1 k. j
: _: r* v) w W$ X* q: v$ \, J) g9 B6 ^8 l
: y4 e) k& W# Z7 Wclass CUPnPImpl+ T) {3 |4 d% \9 ~
{; S- A% a2 E3 V8 W& ^- R! ]6 ]
public:; U+ d$ X1 A8 ^8 a% O/ H } S
CUPnPImpl();2 N, R; s3 l$ U) a
virtual ~CUPnPImpl();
8 v& ~$ f) o5 t5 d4 T struct UPnPError : std::exception {};3 U; ~/ Z2 y& T+ k# ~; A
enum {- t4 `8 U& Q: q3 j
UPNP_OK,
# h! v" q% B" n. n UPNP_FAILED,
6 L! N2 `& K0 F1 ]8 q UPNP_TIMEOUT
& m8 v2 f. u. G! \ };
- t3 h$ I# f! V8 K5 N5 ~: F7 Z/ I6 V" }* o* L j; H
2 L0 O% I/ }9 R/ X' v* ^ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: A8 c% K7 U# v9 v( t3 r
virtual bool CheckAndRefresh() = 0;5 e- ^8 P$ _+ z0 s" s
virtual void StopAsyncFind() = 0;, c' {- W, ^; k: a. L
virtual void DeletePorts() = 0;) h" I7 h/ b% f0 t |
virtual bool IsReady() = 0;
* b% P0 ?/ _( \: J, M" N virtual int GetImplementationID() = 0;
- M% l' d' o3 B3 c$ y" T2 N$ T
+ `; J( m: t7 l0 w; p$ W void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 ?* |; I+ Q9 u- k3 B# I! G
& \- x5 {6 n9 ]* U) r* b b! G% M/ z. G3 \ }. u" g' ^0 E" _
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 ]2 O1 I u' c0 j TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
1 C# V' D1 J# z/ _+ U5 x7 h4 C- y uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ l' V3 R0 S+ J3 q0 [ uint16 GetUsedUDPPort() { return m_nUDPPort; }
; C9 x5 V7 d. v( C6 {
* ^) W( L) @- d+ A; l: N' \
5 Y* W5 H: I0 O' `1 W( Z// Implementation# V* v [9 o' M/ U5 s( D r7 A5 Z
protected:
, b: R E7 K. m volatile TRISTATE m_bUPnPPortsForwarded;8 }0 j: h( ?5 a H5 v+ S* y6 W9 v
void SendResultMessage();
% y7 U# c* v2 T* z uint16 m_nUDPPort;! F. t. C6 a. y' J1 Z' W9 Y9 Z4 g
uint16 m_nTCPPort;. P; Z" J. I3 r6 x# `0 u. X; r4 N
uint16 m_nTCPWebPort;" n/ q, u- M5 L
bool m_bCheckAndRefresh;! x' j6 r% W. S
, j1 \6 m7 H$ V, v+ J0 y6 P" w
1 Q% ~& h. m. m( { o F
private:
: g& u) y u# K& p6 B' x HWND m_hResultMessageWindow;7 S( U" p1 m7 {/ U
UINT m_nResultMessageID;
" ]/ h; J0 ~4 J. E& x& C( k( k7 y. K+ r5 r& v. L) e4 S5 O3 A- a g
% S: x% @0 c4 v* w( ~* ?* [7 w
};
* B; Y) G* k' n0 \$ o% k
# h$ s z0 {4 i* m$ A( E4 ^1 @
2 a/ f& Y9 Y* X' f% I: H- V" T7 @- g// Dummy Implementation to be used when no other implementation is available
8 G2 f, R& O; R( i* ^5 }- N: ?7 Fclass CUPnPImplNone: public CUPnPImpl
) ^; A5 w: V1 J4 b, J{
: H2 H0 p. v% C1 _3 jpublic:
" x' C# j! ^! k7 a/ d( @ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
! H2 }+ r$ C% Y1 Z& n X* s virtual bool CheckAndRefresh() { return false; }# a$ D+ z( J, |, G, F- z
virtual void StopAsyncFind() { }: c7 @+ R; C: ~! \9 P
virtual void DeletePorts() { }
5 d4 u9 Q# Q* s$ S. V, G: p virtual bool IsReady() { return false; }
# @2 D( s3 U$ A2 d- o- L virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
* k: f8 Z' e) `$ U8 Y7 W9 R" f};
- B! o# {2 r: G8 c
$ H9 f' q- ]5 F- ], [/ q3 @- b6 A
% ~4 Q' p8 {' s4 H) W6 Z2 A/////////////////////////////////////
) n0 Y# y( Q8 U9 _//下面是使用windows操作系统自带的UPNP功能的子类
0 J I3 R* e( t7 y6 W- N [& n
; Y1 [& n5 c+ z( F
$ n$ G% g5 B. f5 z#pragma once
' `& i1 a0 x1 B8 i+ S#pragma warning( disable: 4355 )1 ]0 [2 ?& S( @) }
2 Y4 c$ g$ z2 d! E7 q* d) I; x) y0 c% g, o2 s& c; Y
#include "UPnPImpl.h"+ \1 ]5 V. H8 P5 F5 }4 Y
#include <upnp.h>$ I/ _' M+ T8 }1 g% a @
#include <iphlpapi.h>2 H& x# ]8 h- D$ W
#include <comdef.h>. {9 M- y. Q; y+ m& h% E
#include <winsvc.h>5 p2 |$ U- O$ ?3 E
/ t( _% ?" N8 r, l& g+ C5 E
' b. g" n) _- S#include <vector>: y: Q' O4 h" ~/ P: \
#include <exception>
: e* w- N) \! D* H" X+ i0 d0 T#include <functional> X2 Z ^7 T9 z- S9 N/ C6 M
! ?' _' M8 L U. p. R @8 g+ b/ w; Z" W3 v- Q6 ?. u- R9 T
9 j0 Z0 w' u. C6 I+ C! Q' \( i; W( {. R; M9 d* w9 h
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;0 B; }5 M- L4 f/ ^
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
' |, H# y+ @5 e5 _typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;) C: v4 O7 o7 z B) M g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ }0 L+ x+ Q/ X$ w$ }: D
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
) V) Y+ l+ X" L5 Q7 Qtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr; ]4 G* E( \/ c- q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;9 k/ t) i8 [ Z( j9 R" u5 t
2 x z1 h9 ?1 B' t7 u: o9 _
+ V; `2 ^. l+ q* b$ ?% Mtypedef DWORD (WINAPI* TGetBestInterface) () v% y) \8 `) P4 b4 W% w
IPAddr dwDestAddr,
* c) J7 E' \2 G2 i5 O) @/ o PDWORD pdwBestIfIndex" d& \6 Z l9 K/ D9 o
);# [' `0 {* _6 L4 L
- @9 A; [( j. b3 d" W, T* V& q# w+ n
typedef DWORD (WINAPI* TGetIpAddrTable) (+ x9 N9 j) g+ n- r4 r
PMIB_IPADDRTABLE pIpAddrTable,
# v- F( Y4 l- A5 d+ O PULONG pdwSize,
+ t9 |9 u3 R6 R8 R* x0 | BOOL bOrder5 S# [! O* y9 B3 E& Q. y* }. n
);0 k. C4 p' c- [
' Q) x; j- z, A- g
& [" D% n$ ^7 ctypedef DWORD (WINAPI* TGetIfEntry) (5 m- P% X3 P% c+ C0 f9 u
PMIB_IFROW pIfRow
5 w/ X% }: y K7 I) \);
- ] `8 K; i0 o' |4 m( m0 G6 E) Z2 I+ [7 a% P; W, g
; c, a {; l. |) ?9 P& U
CString translateUPnPResult(HRESULT hr);' N) O8 u/ M& y- T2 a2 y
HRESULT UPnPMessage(HRESULT hr);3 @1 \, p; M& F$ s& O+ S' n" U
% _: S5 a4 B7 b+ ` P" ~
6 U4 R! w* w' p! }/ {class CUPnPImplWinServ: public CUPnPImpl) L5 k) W2 P& f' d* B5 p; I
{& A M6 {. K: K) c
friend class CDeviceFinderCallback;/ r9 v/ E/ V i1 w9 X
friend class CServiceCallback;+ w4 @/ S! K4 I' U
// Construction
" f3 C" t7 s1 a3 V+ G3 r# Apublic:
8 I1 K6 ~# {, e* S9 t virtual ~CUPnPImplWinServ();
. j: |' e6 o. B( p CUPnPImplWinServ();
1 k4 X4 n' N( y/ \9 m. W8 Y6 R3 b* H8 s: G7 l2 ?
' _& q- y4 U; |) l7 _
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }0 Q% x# P! n$ y7 V! d7 F
virtual void StopAsyncFind();/ }- c8 Y2 W% k% w. w
virtual void DeletePorts();# q9 O3 W) l8 H
virtual bool IsReady();
6 o; f3 p* ~+ i/ f4 X2 @ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
' t; O/ b8 L% u1 J9 I; y
, B d! \7 t4 Z' h: c; J' x2 I; d5 {1 `8 D" n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
+ Q! e0 k1 ?/ |! r // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later- O$ t: [; d' O' N" \( u/ u
virtual bool CheckAndRefresh() { return false; };2 H% ^& ^6 n" e8 g3 O6 A2 A/ B
! E( c* _- u) T
" V! O5 K9 o( h9 _& V
protected:
0 Z p) G% e2 c* T- v void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 X: A9 \/ L: t void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
8 D& T/ ?6 C( Z4 V- t* D1 R void RemoveDevice(CComBSTR bsUDN);! b _" a3 k* f0 d
bool OnSearchComplete(); h+ Y7 ?1 t! ~5 v5 U# x* k
void Init(); @5 t& G& F- S- z
6 {2 }8 }" {6 ]; @9 i* `
' y; d* Y2 f9 t9 r& m7 f' l7 b inline bool IsAsyncFindRunning() , v0 k2 i! L; _! H# N; s) M/ |/ L4 g3 \
{' O" v/ D' ]- `, Y" Q
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )' E* B" U U V4 l
{' t; d k5 q. ~
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- a) \' ?; l# ?9 q4 Z% X. x
m_bAsyncFindRunning = false;; p$ K; m u# E
}/ v# T' B' W$ l6 C- D& ^
MSG msg;, y8 k0 |" V+ }3 J
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
7 V: J/ n+ f [* R {
# v$ M* g m4 V0 f* b TranslateMessage( &msg );& g: w- y* Z! f- U
DispatchMessage( &msg );9 Z' n! _: E, m! J
}
% f- q4 m' O0 F/ W: ]3 |5 c7 I2 C2 S return m_bAsyncFindRunning;0 F# i2 V6 `9 {
}* A9 k4 Q2 [& X3 t6 }' n9 i9 p
1 k* q% h+ d7 F# u' W0 b- I, E. ^4 T" v* I- m; s! o
TRISTATE m_bUPnPDeviceConnected;4 Q! K8 [: d+ F1 H, p
7 n" H+ G; @8 B2 d( }# I
8 y/ q* O8 ~# a7 n8 H3 N8 ~! [
// Implementation
3 D9 V5 n( }& X5 i! x // API functions
, e# \1 f+ `9 @ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
3 `5 Z9 g! V7 y5 B# V5 _2 }2 h SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);) [3 }3 S1 T, }
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);: J. d" D4 Y' i W
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);' T# F/ C6 G8 `7 D' \
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
% i2 R9 K0 A* [( a( y' L" Q9 M BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);: s" B" O! j$ F& x n- q
$ H* ]) i5 _$ b( e
* Q$ E0 ?$ v: T5 T$ e5 M TGetBestInterface m_pfGetBestInterface;/ e. p% L! R1 Y& Z3 T3 A
TGetIpAddrTable m_pfGetIpAddrTable;, R1 v% j6 t' T# R, e
TGetIfEntry m_pfGetIfEntry;
$ w- t; s/ \2 \2 B, Z# T+ f" B$ ?1 T8 K1 k ]
! n2 G0 L: ~' B: W( _8 p: r( }
static FinderPointer CreateFinderInstance();/ V- N' u/ M9 X6 L6 f" P
struct FindDevice : std::unary_function< DevicePointer, bool >
* e8 ?) P2 S7 ~0 K0 G2 W {
7 L6 z# b- [0 D5 Y7 {7 q5 n" R FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 T7 v0 L0 `6 Q1 q% @
result_type operator()(argument_type device) const: E" t; ?1 ?9 g
{
9 ?% Q. J: S/ D; W9 I CComBSTR deviceName;
5 L& G4 y" }& J& B( O S HRESULT hr = device->get_UniqueDeviceName( &deviceName );
9 X' |% T/ ^; V4 `( z1 q5 t# D/ ]) @1 v" G/ i
% x- P& R }- D' J if ( FAILED( hr ) ); ~) Z6 G8 B7 K: K! R8 n% T3 ~
return UPnPMessage( hr ), false;
5 f4 `6 f- A! w* W" P& b/ i% X) c5 j' G" D
7 u- P/ {: X7 t" i
return wcscmp( deviceName.m_str, m_udn ) == 0;
/ S5 @% x% F G! N }
, d5 u! T* `2 s! K CComBSTR m_udn;; t! @ f( g/ A; g. y
};! L7 p" L& `5 c! N4 {- d) ~9 [
$ i# g+ X: r1 F8 Y/ p3 v2 M
void ProcessAsyncFind(CComBSTR bsSearchType);
1 ~0 c7 C: O, R7 b3 D) i HRESULT GetDeviceServices(DevicePointer pDevice);& T8 B0 q1 Z) O; w: }
void StartPortMapping();* n1 ]. h4 T, O$ u) N( e' w
HRESULT MapPort(const ServicePointer& service);
1 u9 z" a" }) J! } void DeleteExistingPortMappings(ServicePointer pService);- @: f- u2 x& x) u" @7 P' J
void CreatePortMappings(ServicePointer pService);- V4 M/ R" V" a( t( y8 F2 x/ W. o" K
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; R4 a7 P" o$ o0 M7 t% Q! [4 }
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
5 v+ L; r: o' Y/ C, X4 k/ h) p; x LPCTSTR pszInArgString, CString& strResult);
: x5 b+ t; ^/ l j' ` void StopUPnPService();
* p( d: w8 @7 I8 U! f0 P3 J9 Q" N% l' u0 s; W# f5 D3 Y2 V
+ Z$ z, N1 X& p# k // Utility functions0 x) D; s9 m" _
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);) ?# l3 V7 J- W* b. h
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);+ ]' | Y0 H1 w% d
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
, Y `+ {" m0 {/ v void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! l" k% A. o: |+ R
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);, D2 j) L; i# _( w% Z
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);3 M2 o3 V l, T) M
CString GetLocalRoutableIP(ServicePointer pService);& o. N) Y- s+ f. W4 K
$ P3 W( d7 U( l$ m0 Y- Q! H& G2 d
// Private members# [! `, w9 |6 ^2 \
private:
" ]% F5 X4 [/ n9 ? DWORD m_tLastEvent; // When the last event was received?
' b4 K$ E- E% C! Y std::vector< DevicePointer > m_pDevices;
# [! L/ \ J+ U4 |4 s9 ~! x std::vector< ServicePointer > m_pServices;
2 z0 |* S+ [' r) E# j FinderPointer m_pDeviceFinder;9 O) y6 n+ C5 `2 x
DeviceFinderCallback m_pDeviceFinderCallback;6 C) z8 K, @ E' g5 X/ b
ServiceCallback m_pServiceCallback;
$ y: j$ J- G4 p' k# B N0 P
% a1 y8 n0 D I, H5 G, ^/ s8 w. r# s: ^8 g% |1 c7 E+ |( ~* N
LONG m_nAsyncFindHandle;
( o: P3 b/ W7 k$ E5 ~3 a D bool m_bCOM;7 ?. }* Z6 I& r! ^$ T+ C4 c
bool m_bPortIsFree;
% n& |5 v( Q3 n3 f) ^5 ` CString m_sLocalIP;
# {3 H& P0 b- I1 d `" F CString m_sExternalIP;
. K) j- W$ y; ~( R" R G bool m_bADSL; // Is the device ADSL? _6 p, s6 H# M
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
) }) W8 c# t* _2 l+ G. ~% c5 H; Y; ? bool m_bInited;
& T# }; @9 J" [ }2 i' ^, R bool m_bAsyncFindRunning;1 H2 B) Y, L$ ]& ?
HMODULE m_hADVAPI32_DLL;( S0 v! @3 ^1 @) M
HMODULE m_hIPHLPAPI_DLL;
# N' a- y% ~ y4 b$ Z. z+ q bool m_bSecondTry;* O8 X" J9 s; m w7 H
bool m_bServiceStartedByEmule;
2 }+ v6 p6 w+ L& E3 [# g bool m_bDisableWANIPSetup; K. {7 z* |4 `) I0 D0 J1 L" Y
bool m_bDisableWANPPPSetup;
6 v) A) z0 _7 f% t0 {& Z' `0 y7 N" O
. G/ z( e C8 ]2 E8 P; X
};5 z% j3 y+ i; F4 J$ a
. A5 w9 L4 x( k0 @
9 C( k+ v- S$ y; v ]// DeviceFinder Callback
, G: s7 E4 v6 T3 q# eclass CDeviceFinderCallback
, ]9 @, k/ c" ]2 p% A1 L7 ~ : public IUPnPDeviceFinderCallback6 Q9 W2 L7 d9 u) ?( b# p; e. j
{! S: t7 o' W8 z& T; J
public:
k1 W. M, e' H CDeviceFinderCallback(CUPnPImplWinServ& instance)1 o. l. e) _( Y- [
: m_instance( instance )+ g8 C0 l' T0 L) e
{ m_lRefCount = 0; }
5 r; G9 H5 F+ l- E }6 o! F! y" w/ d
( U w/ F- M9 L8 n! V STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 z Q! v4 C9 J. p& q [' u5 { STDMETHODIMP_(ULONG) AddRef();
8 x$ B; \0 \2 h* }1 p STDMETHODIMP_(ULONG) Release();' X G& @% C/ {. p% y) \$ U6 [
7 { z5 x3 N2 U! q" S
6 x0 K% e, {$ p8 l% t5 {7 h9 H5 o3 P
// implementation( d, V! I7 n% \; L1 W+ C
private:
' F, A& l1 \# V; w* v HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
$ H" n* @+ M. m HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
`8 S8 o, P( ?" _' x+ |# W HRESULT __stdcall SearchComplete(LONG nFindData);
5 }- q+ z# E5 B6 V2 [9 q. a. ?" W1 c$ h; T4 |: m4 |- ?
5 ^: }8 N6 y( h# z2 ?6 `6 F1 ]& v
private:
! e& W1 W% J" V" Z' y. ~7 [3 x4 W2 b CUPnPImplWinServ& m_instance;. B) D. O/ z! C
LONG m_lRefCount;) u# C* c& ]0 O2 X. J
};6 [, S* e8 E$ {0 t8 G, m N
' V( v* }$ X: t+ H. `# s
5 w! Q0 j5 x$ \- x// Service Callback 5 Z2 K# _% V7 Y0 D! F e
class CServiceCallback+ t+ R- ]3 V2 f; ?. f& X/ w8 W
: public IUPnPServiceCallback
+ \ N4 s: ?& v% N( w{& `5 c) Q+ D" \: J& o" S8 @' h7 L; |
public:
$ {2 D+ Q* s- b) I% f8 k+ b; s4 Z$ r6 [ CServiceCallback(CUPnPImplWinServ& instance)
7 N" t2 J0 S b : m_instance( instance )
* D2 @2 ^% {* ]4 q. v; A5 J { m_lRefCount = 0; } c2 k2 s% u1 g" _$ l h1 A0 K8 _
" `& @1 O9 N) L; \; ?9 ]6 q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
* \& a8 l; _* d+ z8 E STDMETHODIMP_(ULONG) AddRef();" ?: _2 U/ ~& g- B/ p
STDMETHODIMP_(ULONG) Release();
* Y u: z! j4 [
. y8 k/ @' W8 Q! g e. q$ v( ?% A* b, o
// implementation
( n! [ H9 d1 p* f, B. \( t4 A( Lprivate:% D& W. `* \& ~. B& q
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% Z0 ~! ]* Y& h+ b- `! \0 ~7 f, Z
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);5 k9 t! H A5 q; ]2 Z
" c6 R' g2 {! {. v$ `
) `. T- m' S7 s5 K8 ?; ?2 L9 xprivate:: H2 b* M, W" X3 E/ p# \
CUPnPImplWinServ& m_instance; e, C; W2 f' i4 I( |! h
LONG m_lRefCount;
& l8 \4 d. K; E" t6 _};2 q5 f/ E& s8 j9 |4 C) z6 @# I: t
1 I( ]* e3 V( S2 f: w( v
+ L% O- Y6 l" ]- Z9 b/////////////////////////////////////////////////% r, `0 H3 u# q
' m6 b' I) a: P0 v4 _$ n0 E' W) p: g* _# E( @
使用时只需要使用抽象类的接口。
, E1 \" D3 R3 v: \. H7 oCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
) G# z$ y5 C! v0 U5 q6 R0 `/ JCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
X w2 V" p: w/ s+ GCUPnPImpl::StopAsyncFind停止设备查找.
" |/ S4 j2 @# q$ q4 UCUPnPImpl::DeletePorts删除端口映射. |
|