|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ y) N; L6 b; i7 }6 G7 m4 g, ~6 F3 @( ?( \
3 y+ T6 d, \# }; ?# O" ]' v# z( k1 Y///////////////////////////////////////////
$ E9 t, @8 ~* Z. \5 E6 j6 n//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# \; k( R: m$ w: H2 Z
3 z4 X7 f0 G! {! {6 j0 f) D y7 X7 T# H
#pragma once
+ G6 c: d6 _+ e3 W- I& S2 q#include <exception>; p' S. }! z6 `8 @8 ]+ v# i% w
8 W5 @# W; O9 @5 W9 d- H& I; }
, n% U. r1 k; P enum TRISTATE{4 D; z$ B0 b, w- p% Y
TRIS_FALSE,- ]% ?% y7 h9 o- z, S" s
TRIS_UNKNOWN,! w( X# Y0 Y5 t: G. J
TRIS_TRUE# I6 O, O) `+ r; s& \
};7 z1 w; S; b+ |/ b1 {4 A- w
2 d9 K, b6 p! v
+ j" x! f. _8 s v$ s
enum UPNP_IMPLEMENTATION{
! r) Y1 W* \2 X" q* j+ a UPNP_IMPL_WINDOWSERVICE = 0,, y2 k/ Z- u5 d. b4 m: ^" T
UPNP_IMPL_MINIUPNPLIB,# r: B& R) W/ \6 l
UPNP_IMPL_NONE /*last*/$ S. @: C+ T) V; ?1 `: a
};% ^; _6 s+ e4 H3 r$ p
4 o3 J5 n* T* |8 |* ~. E% t' O4 b4 W
* H, b2 E6 F: n5 a/ Y" d) f/ L, b6 j8 u% @. n
class CUPnPImpl) D2 p/ c) u' z5 W' N
{
% }0 A! K3 v) o3 ? qpublic:$ Z* }& x* w' y2 O( b) z, |6 C
CUPnPImpl();
; j. i# g2 N1 l2 G0 P, \ virtual ~CUPnPImpl();
' o- L0 _& C; I: `) m9 P5 P struct UPnPError : std::exception {};2 C/ H: q" e; W) m! v* M+ J5 d7 _
enum {
5 y, X( S7 V0 _+ M) C) G) L- Y. S UPNP_OK,
; w3 a; f; D6 R! _ UPNP_FAILED,
; t# }6 q1 e5 Y/ H+ g: X) K UPNP_TIMEOUT
' A# a! x1 n) a8 v1 H };
' p* \3 S' M! c% q; F& }! K7 z: g# H% q4 K6 \8 o9 N. k
$ y) E5 M: T9 N1 S4 ?+ K virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
" {/ c7 \5 c$ }0 e) i3 x: I$ Q virtual bool CheckAndRefresh() = 0;: B0 U% ?" ^$ |: y6 z
virtual void StopAsyncFind() = 0;8 ]( \: Y6 g$ |* s
virtual void DeletePorts() = 0;2 V% z6 I _+ x; A8 n
virtual bool IsReady() = 0;" w- R2 [7 D9 ^9 ^
virtual int GetImplementationID() = 0;
+ U0 C" G$ h7 [) u 8 E1 P7 J+ L: C: n) u, S
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping- d- t# @. N3 _7 ~6 M M3 l
4 {* o7 l3 e9 b" F. n8 c/ Y- e. A l/ A# |% Y2 i3 E3 M
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
8 A: o1 ~. k6 |- M2 F TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) U1 I; z0 f0 i% d' M1 W5 _ uint16 GetUsedTCPPort() { return m_nTCPPort; }+ W7 M8 V- V. u. j; q# p
uint16 GetUsedUDPPort() { return m_nUDPPort; } $ M5 z$ G6 h' Y6 ~( G+ d0 m
X8 _* K; _: c' O' z! T4 o! [3 o( H+ F, D3 t
// Implementation
2 d6 l& A0 L w9 p5 s7 Iprotected:/ G$ \2 @: N0 c) a1 X& n8 q( S" |( e6 K
volatile TRISTATE m_bUPnPPortsForwarded;
$ m6 Z9 d7 B7 y3 v) m, ?* e void SendResultMessage(); P$ m( Q% C2 N+ J! v* \
uint16 m_nUDPPort;9 \" B) ^3 l5 p5 o R# U
uint16 m_nTCPPort;% x4 k- L5 l% {
uint16 m_nTCPWebPort;
$ p" w2 {4 j2 p, L5 z bool m_bCheckAndRefresh;& z7 T$ Z" R2 F# ?
6 \. t& Q1 z6 O
( _' }+ G2 \/ U! }6 U- Kprivate:4 b: H+ e) j/ ?2 Q
HWND m_hResultMessageWindow;4 P3 R3 T7 U$ e) K5 w7 p7 d
UINT m_nResultMessageID;
' i. m5 _' c4 Q$ K
8 w4 w* J# H+ [1 ]: l) H
% g9 y% U' E; q# u# W}; H8 ?, g8 ]5 ?. i% }
1 }; F" V0 {( w- ^+ b" l( q1 _" L1 x( k
// Dummy Implementation to be used when no other implementation is available! G9 u4 R: y# D9 X3 o, }
class CUPnPImplNone: public CUPnPImpl
# u8 G- O+ {5 M' Y9 c+ V{# A! X( K" p% j& q$ b5 y# [6 h
public:- c% t- w4 V) f* s6 |
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" W2 s$ E7 d3 A
virtual bool CheckAndRefresh() { return false; }
) t, O( ]$ u; ]7 K, q( | virtual void StopAsyncFind() { }, t4 o# j V0 Z: b7 o
virtual void DeletePorts() { }8 _3 w& y# y5 }
virtual bool IsReady() { return false; }
u1 w! A3 c: ~ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }* j; {. y0 J3 {( z7 |
};; z% L! y8 M- n0 e
, M. N) V2 o) }, H$ t$ a: x9 {6 Q
0 a3 E9 a5 S# S9 i; Q. r
/////////////////////////////////////
: f. t! Y- ?1 T; H: e/ m//下面是使用windows操作系统自带的UPNP功能的子类. v8 I( t) p. L8 d0 m. k
9 u$ v) P( a8 }/ W
1 E3 A8 ~8 E8 [#pragma once: V! A- X, e. \5 _8 Y
#pragma warning( disable: 4355 )" u7 U: V/ A" T; U0 s, B( }6 p1 g
3 L" E- r7 C6 U) w. x o% }9 h& m
k0 X/ M0 h) X/ `: l9 y#include "UPnPImpl.h"
: K# f( `* \) _1 n. b' W/ y) E#include <upnp.h>
. s8 b, D# _6 m9 r#include <iphlpapi.h>
9 o1 c; i1 G4 \8 z% }#include <comdef.h>) q; @% H( n& J$ G) R3 q/ e2 r
#include <winsvc.h>
' p6 T6 j* f! q6 f, c; X2 E4 e4 i! O
/ |0 s" J" p4 y; _#include <vector># ^0 l4 a0 A% p# U" H) n: X4 m. v5 {
#include <exception>" G1 ]' \) G% J9 ]1 {" B6 @, r
#include <functional>
" F4 B2 E, } |& F n+ m6 `
7 d I1 C- x2 Z* S3 `2 H( u ^: U& h
; X R7 Q; {' X9 z$ d/ M4 V" \
1 R+ F2 N* a# ^, f5 {- C# C- M/ Vtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;3 r7 H1 ?/ n5 {' m; ^
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;' e5 m1 l% x& d3 h4 ]8 q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;' Z9 W7 a H# p* X: M( o, |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;: z Y% Y4 ? _+ }* _
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 G- M) I/ p9 B9 v; a
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
. M3 H1 V z, l( [5 Y" ftypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 v9 X2 Z2 K. B
2 W. g; C! l3 Y7 o+ B8 D' A* V: X$ C
( K! _3 N8 ?9 ^# o; F; L+ Ftypedef DWORD (WINAPI* TGetBestInterface) (
* |* s$ \$ ~& C: F IPAddr dwDestAddr,
+ e+ z, X B5 C7 P+ j/ {# G3 q PDWORD pdwBestIfIndex; ~! g% ]8 e$ M, H+ V/ Z
);# |. d/ ^0 T8 W2 G$ j: I
% N- |; F! S$ l I: L) F" ^: s- \7 ~9 M
$ H; `! t3 c) V, f% J! ctypedef DWORD (WINAPI* TGetIpAddrTable) (
. H5 ^& M. }& Y) f6 c9 }$ B) X PMIB_IPADDRTABLE pIpAddrTable,
0 @5 [/ |- w0 Z9 x( i: e PULONG pdwSize,
7 E% `, @; D5 M8 d W. d/ L) L BOOL bOrder3 K/ o4 k. G- S. s8 V+ j* I3 K
);- v x3 h/ q# y/ `
1 E( w/ O' P% h( t
+ L4 X9 Z9 U' T4 o2 _9 Jtypedef DWORD (WINAPI* TGetIfEntry) (
& o) k; N# i" X6 w5 O PMIB_IFROW pIfRow
) x2 O6 ^! ]9 n- l1 r3 L2 U& c);% y9 @7 S1 g3 ~% d
% z2 p+ H+ j1 o+ C& H' S* z; [! K
3 C9 U4 l3 r) x( Q- @ t' b4 [CString translateUPnPResult(HRESULT hr);$ I, \0 ?% Q) |: q& K' L1 E0 _ T+ t
HRESULT UPnPMessage(HRESULT hr);
9 q Z( o/ O# G: }4 ?9 M* x# K5 x' }! s! }/ v# L3 W7 r# K
) X* T8 u; b' h0 z9 wclass CUPnPImplWinServ: public CUPnPImpl
" W- V, K' f7 {; J* D8 A{
: v5 s6 T y, I" m% D9 [! v0 y8 S friend class CDeviceFinderCallback;9 { E- w2 S P, [0 J% A
friend class CServiceCallback;% d" Q3 `" t0 E0 u
// Construction
1 y7 m9 v! L+ G+ x) S+ d: v. apublic:
% Q' J( ]: c' R5 } h virtual ~CUPnPImplWinServ();% o, N& N% h- v; v4 S) [. P
CUPnPImplWinServ();
. e0 e: z$ t( g
) T1 p/ Z! \+ G4 S/ w. A8 G/ \( b% }7 O5 s! o5 ^
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
1 x" N1 u- z) ]6 w8 D ` virtual void StopAsyncFind();
) t1 Q. c4 k& Z9 e9 b( r virtual void DeletePorts();
4 L/ j9 P/ b- Q% ~5 p virtual bool IsReady();) x# J7 e3 w/ q1 e
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }2 C6 r6 m+ M }& C4 S* X
( U7 P4 ]6 B' G2 t; ?
1 x1 q! V- @8 l. u // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc); P( ?% @$ G0 _! D1 z
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
# D4 L7 V; r- Z) _$ F virtual bool CheckAndRefresh() { return false; };2 r) P' {& c) p' t1 j4 [
" a$ n: R0 I) h! m) m
5 q U2 \ J B% ~
protected:
' @# M. H/ z5 W: y( ^ C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
! V6 g! n. ?1 }1 l% d, Z void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);. A1 e G6 }1 c( j2 s
void RemoveDevice(CComBSTR bsUDN);
) S* ~4 S6 @: e. n bool OnSearchComplete();
( t1 f6 O+ D6 ]; P% p% [$ I8 s% f+ P5 K void Init();+ [' k* O) i8 G- T) x% }
9 v2 y& i/ Q3 M+ B7 z# y1 |6 ?6 ~4 x2 G- f; p6 v6 O
inline bool IsAsyncFindRunning()
' I4 j: {' S1 o4 W; Y9 m {) p% V `/ Q. I6 j- P
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )2 `" J. p0 |0 \; b; q; N
{, r! L P9 E3 @! S. {
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );, c/ o P. [0 f5 _
m_bAsyncFindRunning = false;
$ D5 k6 {- z7 } }. c4 P# E8 ]# _6 |4 P# y2 c) l
MSG msg;
0 q- S3 _( V# j! w3 b while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )$ ~! l/ G4 ~7 F" q. P4 R2 O4 T1 B
{
$ @, N0 B0 k) g+ Y$ J) L5 k TranslateMessage( &msg );% i7 M9 L9 B% ^' n' Z1 _
DispatchMessage( &msg );5 r$ Q. g0 k% W, x9 l$ \( F I
}# N2 q W1 L; U6 e5 o
return m_bAsyncFindRunning;
9 O+ r: a) o7 V% S# I [ }+ d! k: _4 y( C( y' B& ^$ x
& w5 D& q# s& H5 K7 b/ t' b7 W1 h/ p- }% N) N. h" O( B
TRISTATE m_bUPnPDeviceConnected;
. p0 C- }' Q8 V" [4 C x: |5 v* D; z1 ~* X) V$ l" F! S
: |/ K2 S/ h% W6 p/ c0 g) e7 P// Implementation
) y2 S# }; _) Z5 \ // API functions" R$ k# Q' }6 ?: b
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
& U3 c2 W2 Z) F SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);4 n8 a: Y8 R( O
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);) D' }& m/ `& ?1 _# |9 k
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);0 U; J! p m+ g; _+ q5 L/ e9 J( o
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 ^- J7 a1 z6 o7 E5 d
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
/ c' Z$ {5 |6 u
% C4 X9 W$ K5 G- b3 Y8 P* m# i
' U X8 B7 Q- ~( @9 A2 n TGetBestInterface m_pfGetBestInterface;
' t5 A. {) _4 R* n' _2 l# B TGetIpAddrTable m_pfGetIpAddrTable;3 j6 G6 X# v2 ^$ N" h$ c$ M
TGetIfEntry m_pfGetIfEntry;2 Q: z/ V# n" }7 {3 m
) t7 b$ q/ S" k1 h7 \4 g6 _
. o7 g/ g [, {/ T2 q static FinderPointer CreateFinderInstance();( O) ^7 m: W( K1 I- O
struct FindDevice : std::unary_function< DevicePointer, bool >3 a# v2 h8 E% w+ q
{
* z5 K d$ ~' v+ p% _$ s) m FindDevice(const CComBSTR& udn) : m_udn( udn ) {}4 u, A& A& ~+ D* C4 Y3 ?, A
result_type operator()(argument_type device) const! m7 e0 W# U6 y
{6 @! k# q; D6 p% D: O5 Y- K
CComBSTR deviceName;8 \6 H3 ~" n+ O5 P2 U2 i9 H, s
HRESULT hr = device->get_UniqueDeviceName( &deviceName );9 B4 ~+ b' o) I; k# `! ^. D* P6 q# d1 G7 w
. ?( ^5 ]8 O+ B1 i% P% _$ C
6 I5 A: b- A- h5 B. p2 Q if ( FAILED( hr ) )$ g' W+ a( H$ J' [
return UPnPMessage( hr ), false;
5 o3 T7 `9 j; x- l% _# l* t1 y, \5 J k$ q
K0 e0 p: W. l* c return wcscmp( deviceName.m_str, m_udn ) == 0;' J$ t1 q [8 y1 \$ J7 P) r
}
8 d" s# Q1 _! l# f) ?! m9 u CComBSTR m_udn;
% Y' W& s% c- g# N };
6 |7 s' s0 T' G; y7 `4 h1 A: d 8 y5 f% t6 G* V) x! o- }) i
void ProcessAsyncFind(CComBSTR bsSearchType);
6 u; p8 `/ C" l4 ?: J4 [7 r" g2 w: Y HRESULT GetDeviceServices(DevicePointer pDevice);' k" u y; e( p& ]. a+ x$ t
void StartPortMapping();
F, s. H# F+ y. N: z( [ l HRESULT MapPort(const ServicePointer& service);
W o& \ X5 E- E* n1 n void DeleteExistingPortMappings(ServicePointer pService);
0 \+ n- d) H$ z5 {1 L/ B! E void CreatePortMappings(ServicePointer pService);- G& ]; v$ ^' g9 j) \' I
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
! V3 {- x) r. r6 q, @2 @4 P' d. Y HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
/ ?0 ~* u/ W; m6 g4 R/ N* ` LPCTSTR pszInArgString, CString& strResult);
3 V" t/ S7 r4 H, { { void StopUPnPService();
- B& n$ e# g( `4 ~" Y
" V0 i/ |! h7 l7 T3 D, v, {7 I9 \ ~ h+ e4 H
// Utility functions% g8 l( O% I% ~: U
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
6 ]5 L* t/ O$ ^: M1 @3 z# e- x INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);- Y4 r$ z2 M6 P' w$ L* x
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);. j4 C- F$ R, N6 L4 U
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ b% r' f# r4 ~# a- H
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
- I6 j! q+ {. u) l. J HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 @( f; e- i8 t4 ~8 V CString GetLocalRoutableIP(ServicePointer pService);
2 J) x; n$ W/ t& m' k
- \& o9 T1 g' @# F
( a. A8 q2 T( T* Y3 i" R% q G// Private members
3 n g2 H0 W H! o" O$ k" Aprivate: B3 o( A# n3 R {( G" e0 y% s
DWORD m_tLastEvent; // When the last event was received?
! b- m, F H% B* Y- z std::vector< DevicePointer > m_pDevices;
. x5 ]8 N0 t7 m std::vector< ServicePointer > m_pServices;! q1 i; o9 V2 d( `8 c" p
FinderPointer m_pDeviceFinder;* Z: Q9 m' V) G# t. i
DeviceFinderCallback m_pDeviceFinderCallback;8 o) b; H, ^0 l: K
ServiceCallback m_pServiceCallback;
- i* l0 k/ b! D9 `2 J8 J5 `
8 t% F0 z. o& s
, M, O6 y2 ?! A- ]! s1 m: u LONG m_nAsyncFindHandle;" w: V7 _( Z: }/ r
bool m_bCOM;8 y2 S/ y) p6 O# A; @
bool m_bPortIsFree;1 R) X2 _1 I! M* l5 x
CString m_sLocalIP;: p/ e( K" z) b* t
CString m_sExternalIP;
+ B; B% I9 g# D% z# C9 A bool m_bADSL; // Is the device ADSL?8 e8 O1 z+ m; K& \: N: v
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
K) ^; Q& C2 W: c- D bool m_bInited;6 D, p ~' w4 `" _9 T
bool m_bAsyncFindRunning;
' P5 C6 j9 _" }! G4 L% G3 F. U HMODULE m_hADVAPI32_DLL;0 w1 B4 U$ U; L+ L6 J M
HMODULE m_hIPHLPAPI_DLL;
# j z l! r+ a2 W( i2 o/ `3 C8 _ bool m_bSecondTry;
" R) T6 p; ?7 s/ K( X! z/ t bool m_bServiceStartedByEmule;
! w4 G' i8 [ t+ K" C bool m_bDisableWANIPSetup;2 R# U6 E7 U$ \
bool m_bDisableWANPPPSetup;, _ }1 ?2 ^! w7 f% e! G0 |7 }
2 G8 v/ T/ o- `$ a/ l/ O
/ v7 d0 E, ~6 v8 r* g& N d};* |0 H! ]+ B2 u {" ?- ]
+ H5 v7 ]1 X6 U; W. j( T8 F" ?
2 _& V9 ]/ k% C# n5 S L0 s// DeviceFinder Callback6 U9 d$ W/ I0 k3 x8 u5 Q! j
class CDeviceFinderCallback! J! W; g: L1 ?& h
: public IUPnPDeviceFinderCallback* i8 q3 q0 y8 K1 R1 U1 T3 U
{
2 E7 K9 O3 w" V& K# Fpublic:6 G+ q4 }6 y% K
CDeviceFinderCallback(CUPnPImplWinServ& instance)" O) {0 b! I. Z7 y+ |
: m_instance( instance )
+ I' A2 d/ \* W, ^. ~6 [ { m_lRefCount = 0; }; Z6 j9 P+ M1 C. `7 @6 f
+ s- U* B& q& U2 J5 u
) ?9 K, g1 g4 `$ s" w STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# L- x6 E3 e N7 |: M8 w STDMETHODIMP_(ULONG) AddRef();+ ?3 O) q3 K$ R2 c) P/ j. Z
STDMETHODIMP_(ULONG) Release();5 e1 A; u0 V- I2 i O( j, Q
6 C2 j' x* g2 P( K+ S! M3 G# y6 U& R7 H( M
// implementation
& G% |& ]1 g' c9 ~! {" ~private:
7 K+ F3 q8 g. u2 v HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
# M) U4 d: X( ^5 i3 i! ?5 Q HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);4 e5 R2 z8 N, s: L% w: @: q; s
HRESULT __stdcall SearchComplete(LONG nFindData);
8 r6 ^ O0 I$ `. }% q X* c" A' y5 n! J& V9 G6 J! e5 q
/ `- r. b2 o3 V1 r
private:
2 U0 H) s0 O6 [1 T CUPnPImplWinServ& m_instance;
1 f9 B! b$ S9 q5 x, i s LONG m_lRefCount;/ `! O% c8 _" _+ `# h# e
};6 Z# U( n) Q. Y) ]
. L/ g" V. w% E
4 J2 W5 z! ?" H% e, R9 ^+ ^
// Service Callback
2 @0 Z7 k$ U/ S$ m5 dclass CServiceCallback3 D9 ]6 x1 G* a! Q
: public IUPnPServiceCallback
# A* \! Z, @6 ?3 L9 h1 K8 k0 V{
t2 n: A2 o1 e8 m9 k$ n/ J+ Npublic:
9 z0 m: {3 X& [. d5 a CServiceCallback(CUPnPImplWinServ& instance)
4 l7 n7 r5 ~' b9 k! Y7 P : m_instance( instance )# l& L4 O3 i9 r
{ m_lRefCount = 0; }
+ @6 I# Y' k& ^0 x. f; c4 q' [* w . `* I8 H# M; k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 t* j/ X7 d" W* r+ ^% I! C3 z9 b STDMETHODIMP_(ULONG) AddRef();+ o5 y, y$ g* m e- X' a& T
STDMETHODIMP_(ULONG) Release();
9 k' C& s8 M9 s j1 Y; e% v6 }
. I" x* a+ y5 h! A1 c$ G// implementation
; w# {9 ^* F S3 Iprivate:
4 E% f+ w6 A, q6 B4 T8 s! P# Z HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);+ K+ a* L( M+ y! [7 |
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
1 n! v$ Z: Y+ r0 M |9 o G/ }) }
8 ]( I% p/ e( y# R
- A0 Z9 P% c6 ^. b* R5 W5 |: y( Fprivate:" N* Z, E) G4 `3 m- L/ ~7 `
CUPnPImplWinServ& m_instance;7 W i' F6 k0 i: d5 D& X6 u
LONG m_lRefCount;
0 t2 d9 m# n- x* E1 {% u};
. e+ S8 S, U6 W
' r O2 s3 O/ c
1 e7 q2 {8 }/ }3 I8 a/////////////////////////////////////////////////; F6 d6 N8 Y: U+ M( @7 v: w$ Z
* ~- `9 ^, j1 W" y; i( p, R9 ~, G) [7 g9 l
使用时只需要使用抽象类的接口。# t4 |8 j. j0 @4 z8 w
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.5 n; m% w! w) i2 Q
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.6 r$ A: S- L' w) } J& n
CUPnPImpl::StopAsyncFind停止设备查找.. u) P6 o6 \2 r0 K. i6 l$ e
CUPnPImpl::DeletePorts删除端口映射. |
|