|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,2 y; z+ J7 Z- {6 F* e
0 @7 p8 o: _5 `7 R- y
" a8 P. w R9 s+ j6 N4 S
///////////////////////////////////////////# N0 B/ w- _* q4 k/ q" @! I( ^
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# u( X3 l2 g: \0 N t2 j: Z; i$ a+ ?* ?' `
8 ^# t: U) ~1 \! f
#pragma once
" I5 s; W# Z- {) R#include <exception>
: s }& p: q" y; U
5 H1 B# l3 U$ h/ _/ g1 l6 S/ O6 H( _: W [' X2 k4 S3 [# N
enum TRISTATE{4 P( A7 d7 M# B3 H
TRIS_FALSE,
* o4 I( J+ b G5 J$ ^ s TRIS_UNKNOWN,; I0 C4 W" V: i0 }: M$ d
TRIS_TRUE
# w# R+ ^. u; f/ L2 a};
1 p0 Z2 }# `; M2 P' W( r& q4 a7 E0 _: W% S
: U5 u7 H+ D' [& p4 R
enum UPNP_IMPLEMENTATION{
# [6 R( t+ ?! L& A( } t( h, { UPNP_IMPL_WINDOWSERVICE = 0,
6 G# F& }+ i2 b( _% o8 `+ z P UPNP_IMPL_MINIUPNPLIB,8 o% h/ ^ y2 Y
UPNP_IMPL_NONE /*last*/
: H5 D+ T, \# E};
4 @! u- e N: i& B6 H. l( T0 J
0 K- t3 b1 Y' Y7 C" H( Z% |/ J3 r/ ~+ F1 x- ?5 T8 J
4 W+ V/ [9 E' P* D$ {
/ _! [4 c& W# r7 ~" N4 G* m
class CUPnPImpl! _; Y7 ^( ~: c$ |- d
{
4 ]& n! _) S8 ?; g. \/ ipublic:
( H1 G. Z f6 h' ^+ n9 H CUPnPImpl();$ {2 A0 N7 C1 t* s! V4 w H8 o
virtual ~CUPnPImpl();
' y! K* g& `. ]" c struct UPnPError : std::exception {};
' ?+ {% i) D- H' o U+ f enum {
* D: u" a2 ~$ q+ ^4 ? UPNP_OK,
) {) ]6 K# l o& t8 l UPNP_FAILED," R i/ |4 d, R. a2 p( \, b, Z
UPNP_TIMEOUT
' v/ }+ i6 | s. r3 b" E }; A' G/ E9 L- U# b
8 r. f: h4 q+ e, d
* j3 j4 s" L( W) Y8 K0 u. _ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;+ V E0 T$ g o+ a% S; x2 C
virtual bool CheckAndRefresh() = 0;9 Q# c% h9 A2 P: Z: j
virtual void StopAsyncFind() = 0;+ ~, M8 k! x( G7 c
virtual void DeletePorts() = 0;
( L9 N" V9 Q0 q virtual bool IsReady() = 0;; m, F5 S r) K) R( W& V
virtual int GetImplementationID() = 0;
2 H+ u, x b4 H: ]2 N5 S# o- B6 _
: T7 O. ?1 \+ G. J1 y6 H6 L void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping: l- [8 z) _, U; N$ U9 t+ }
# M+ o; Z0 z/ d e3 c
0 U1 |- m4 K* \& U* o/ l
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
3 s6 R: i* W; f TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
! q1 h% w) ~, n4 L) o uint16 GetUsedTCPPort() { return m_nTCPPort; }
9 Q6 _9 u& x+ p9 Q; F( r uint16 GetUsedUDPPort() { return m_nUDPPort; } - S# i. V/ W7 U
+ l* A5 o' E* M; E& X4 S* U+ P
3 Y( j8 n4 k7 ~ B& h# p// Implementation4 s, \9 t; m. [+ q5 f8 r5 k
protected:" u; }: `8 c6 c% q4 p7 m% M! ]
volatile TRISTATE m_bUPnPPortsForwarded;
9 c( \# }: k5 J void SendResultMessage();
2 O( n1 E/ m. p: {/ f6 e; A0 | uint16 m_nUDPPort;% ]; [- o/ ]1 P# W) W% u- M
uint16 m_nTCPPort;
" w p% V7 B% J P0 ]3 } uint16 m_nTCPWebPort;
2 z' I7 {9 M9 i- W9 `* r2 q bool m_bCheckAndRefresh;
) D% G% _& C0 p0 M
: T' \. F$ b3 D5 A# F* {- Q% B
% E; W4 P! @ W z# j4 w" }private:
5 X$ x" t7 J, z8 X HWND m_hResultMessageWindow;: X" D' K/ O5 I5 c; x7 W& U
UINT m_nResultMessageID;, S9 Z% y# d2 _7 N( o/ _- ]
3 _/ a3 _; U5 ` j
6 [) e# n3 B& g" y};
- b3 [6 w/ U6 G6 G) r0 R& J& K% R: z0 E
" v1 [( \1 s$ q% k7 J2 d// Dummy Implementation to be used when no other implementation is available, c! T2 ~# M" }* i( A: m
class CUPnPImplNone: public CUPnPImpl4 n" e7 ~+ U5 B7 S% x
{
5 M# Z, h. H8 }/ Spublic:
u9 W' Y0 d% T& O virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }5 V: g& {1 c+ }9 x+ A Y
virtual bool CheckAndRefresh() { return false; }, }1 x, J) y* o& M2 w6 R# H
virtual void StopAsyncFind() { }3 ~% [& B% q# |: I7 O) n8 [/ V
virtual void DeletePorts() { }
0 X A4 G9 u1 e; x, E* N virtual bool IsReady() { return false; }) z# V3 W$ i, v8 t, ]7 ?8 U
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }$ M4 j3 z0 z9 [9 \; A
};7 ~& ^: J3 }0 j( M
2 ?6 F0 K* I6 z3 Z
# _( n# ~. }; c9 ~6 A4 G$ C8 t3 L$ e( Q/////////////////////////////////////
0 ]8 W3 }2 n2 W: G- Z8 L% ~//下面是使用windows操作系统自带的UPNP功能的子类5 g6 M; z' L! Z7 L" E) k7 {4 o8 m
- b2 R) g! N9 g8 V* c1 d( H
' q3 }$ N3 E) p; Y% N#pragma once
" U) {# T5 }; O# F#pragma warning( disable: 4355 )
6 M) ^1 e/ K3 x* m/ g0 G% l( i6 W# m3 m1 o' C+ W& D
) i8 M$ r& B: I& c: P) P
#include "UPnPImpl.h"
# F0 j- ^2 C; ^% m& s#include <upnp.h>
2 {" m- r; `: R% x& @0 C#include <iphlpapi.h>
0 I4 e7 U/ V9 ~* ^. [1 L1 e#include <comdef.h>/ ]! f4 n, n/ } R6 U. x$ }
#include <winsvc.h>
# k( a" M+ J3 D( I/ ^# r. ]
; n+ F: G+ E4 K
2 ]4 {$ Q, j3 m3 i" q8 Y#include <vector>
; i! y2 g3 x$ A1 A4 Z#include <exception>
( P3 Z S& S4 @2 e( ^#include <functional>7 d3 f$ ]& ?+ i$ w: C
( s4 G: \) c% _- s. V0 M; {
- X- H, t8 W* Z" d' s7 k6 @' i9 a8 d& L" G
2 V' g- c6 l& P1 ^typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;0 u& G( k6 b! C' P$ Z4 @ T1 t
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) C' L" S: q6 H8 h# W' A; M6 Vtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
- C2 w9 O1 D( Q2 Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
4 }3 R0 I2 `9 f# Y+ o+ Xtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;3 D# Q% B1 I, U9 @/ H
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;' |" l- p4 w$ @. @# N& w% r. Y& G8 w
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;" i; {8 |6 O" W
{1 _) y; @" _4 z5 T4 g. p' M
* X' w5 g9 S% {% Q. {5 ]' }0 Q6 ttypedef DWORD (WINAPI* TGetBestInterface) (
: P* X5 Q. _6 i K. [/ _1 \ IPAddr dwDestAddr,
, p0 ~% k" B6 C3 x# }7 y4 ^ PDWORD pdwBestIfIndex
8 G/ L/ }3 [4 m& T);
( t6 n7 H! O# K$ h
- Q7 I! C2 ?# Q( M3 O- ?2 U6 V) @( a; Q# x/ w- g
typedef DWORD (WINAPI* TGetIpAddrTable) (
( G2 Y1 Z, n% m PMIB_IPADDRTABLE pIpAddrTable,/ d9 y4 t6 q) |' W. C
PULONG pdwSize,
" d; I" Q1 T* n BOOL bOrder6 A* L. ?# o/ A; u I6 W
);- n# x5 ]1 b6 N, ]6 {( m9 i3 D
* \& |$ x V7 ?9 F# {6 l
2 `: a% i4 O! _& U8 d1 N* b
typedef DWORD (WINAPI* TGetIfEntry) (5 Z% ^3 n# s& I1 h9 `: ?' ?
PMIB_IFROW pIfRow4 y; O, t3 G7 M. w5 `
);
! c6 h* ?. g: @% | C# C
5 B0 d7 I2 ^8 L$ P& Y# w% h
' A6 w4 \ [6 UCString translateUPnPResult(HRESULT hr);
4 a0 g* {* c1 w7 GHRESULT UPnPMessage(HRESULT hr);1 A' @* C# K4 p% |" [* [% o
8 N- m8 E" t2 |; b
; N( G/ i8 k% X- q. Xclass CUPnPImplWinServ: public CUPnPImpl2 A7 T' n1 r1 U( C. }, f
{
2 H; R m+ f& D* S friend class CDeviceFinderCallback;1 L+ [, p" h, r9 |" a$ _+ `. g) A' Q/ |
friend class CServiceCallback;
6 {) P0 F8 a& O3 p# U// Construction; z( x- r% n$ G9 S' V" ?% k
public:2 v E# t9 x3 {1 d9 I" Y+ g
virtual ~CUPnPImplWinServ();- d( S4 _% B; a! E2 E
CUPnPImplWinServ();- ~) i! w% R; |. ]1 `2 [8 \3 A
. R' \ s! _7 v5 t9 `- f, M
! u v9 K y0 k5 n$ c6 X virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }7 ^: ?; m. g. r0 h( S: ^0 S) l% h, k+ i
virtual void StopAsyncFind();
" N" f" c( ]) |" |. N virtual void DeletePorts();
/ Y1 z+ ?& D# V- e$ d4 F4 W virtual bool IsReady();7 G/ Q) U7 \% m$ u h
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }* j, `& {1 z) q* H0 o
4 w t' m" L2 z# L' t; Z
J$ G( O$ P: V/ x' c) p // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)# ~7 _$ N. F% ~- R3 X) y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
7 T1 [* _' P3 C7 [, n4 I virtual bool CheckAndRefresh() { return false; };
* {- c3 c8 a& h5 v& N1 y! h }6 O; D0 s3 ^' e
+ A3 L. X8 G. ^( u2 B- T6 ~# lprotected:
* t% `( `4 A' N7 O void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
* z0 ~% ?3 @# |% @$ ^! ]6 C) C void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0); |. r7 M2 A+ ]3 @
void RemoveDevice(CComBSTR bsUDN);8 ?+ j* F/ ~0 g3 m" m8 ?7 S
bool OnSearchComplete();
; p4 y* ~* W5 s9 w# n' r void Init();
/ f+ ~- v. g- w* c; x6 o/ K8 w, p! z7 m- S( M l @5 a/ k. R
; q+ U) H4 c) J0 x; K, u
inline bool IsAsyncFindRunning() ( c0 O- i: q* l3 ?9 z
{+ |, t, ^9 A7 n* q4 y4 _( N
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
% f, |7 b5 L$ [: ^+ y. S6 i' _ {0 P) ~3 g) j/ T# j z5 q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
" x3 V9 R4 w9 g2 m0 o m_bAsyncFindRunning = false;
m" \. v* d9 \8 l- v }
8 r* Q' P% N$ \1 a- }. \; C MSG msg;& _8 ~' j; F& O; Y+ p z/ x
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
I5 c$ V- N" w" M. N( V {7 o- O$ Z6 }# [$ F
TranslateMessage( &msg );
8 I( A, [) W. V8 ^6 ^2 s0 N DispatchMessage( &msg );
% ]7 R: i; K) V2 U* T }
( `5 u3 {. u4 q' t return m_bAsyncFindRunning;
* v i& R6 o0 {2 A7 ]* V }. v' X, x( }2 O6 J/ }: d. M
, Q# m$ i* T) G2 _- f9 ~6 {+ ~
' I/ D$ s3 y" @ TRISTATE m_bUPnPDeviceConnected;
: V* Q5 r' `/ a* p6 e# o* Q9 C/ Y3 C& [$ P. K4 o8 P
, s2 ^: y0 f6 x' A. m; Q
// Implementation% B# i, e! J6 k+ I! X
// API functions% E, n3 T1 i2 |- o
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
( L' E! A( `2 q( f3 m. X& G, M) ^ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
1 m+ p t6 ?% M6 @% l) O BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- x1 X2 o" i# a5 b4 l; K1 u: s3 R
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
- Z$ n- v/ l; w6 { BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);( l, `% F9 X4 l3 g5 q3 z s) n( V0 G
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);0 l k9 ]/ O% E" H* B8 J( _; |
# @* h8 s2 L! C8 y; p% K5 e4 a6 E' p& g! c+ K
TGetBestInterface m_pfGetBestInterface;6 d: c( P8 A/ H( k
TGetIpAddrTable m_pfGetIpAddrTable;
; w4 h9 x6 O2 z$ O TGetIfEntry m_pfGetIfEntry;
/ j, @# t- A0 f9 u) {% e- n3 g
; M! d- W) Y) T+ E2 ?$ y9 ?) P) ?. E; R
static FinderPointer CreateFinderInstance();( `4 W4 Y8 n. P! B+ X, o+ m" _
struct FindDevice : std::unary_function< DevicePointer, bool >
9 M6 ?' h* }0 p/ Z& [ {) L+ d" g2 U% i/ H% m" C
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ c( g" I: H9 j1 `) O* S+ q result_type operator()(argument_type device) const
r! F0 Z3 @& e- P {) ~ ~* X. E' L# \% d+ P
CComBSTR deviceName;
+ ?0 x% T9 p0 q HRESULT hr = device->get_UniqueDeviceName( &deviceName );
) h1 h3 K; \. }7 A$ {1 h3 u& N/ \; n- o) n9 m
8 ]6 V. j5 E' P' \ j4 |: w8 y if ( FAILED( hr ) )
$ Z3 M. Z2 k7 C6 g. J j" L return UPnPMessage( hr ), false;
- J0 @5 M; a& X3 r$ W- z
" [/ w- ], m% ]# d- @3 h* x( B& G. h1 }- T5 t N, |$ K
return wcscmp( deviceName.m_str, m_udn ) == 0;' c- N- G6 {# g0 U i+ N1 W( G
}8 y& ~# F# N- R& L
CComBSTR m_udn;
, M5 k$ q( E/ z [8 I- ?; v };
* _- j- D4 x1 ?
+ [% K8 G& ~5 e void ProcessAsyncFind(CComBSTR bsSearchType);5 f' \0 T; ~0 J ~
HRESULT GetDeviceServices(DevicePointer pDevice);# `4 M' Y' d) Q# f/ T; h& Y
void StartPortMapping();
) A. y6 q8 Y' J. i, L i3 A2 h! K HRESULT MapPort(const ServicePointer& service);
$ n& V5 ~) ]- U3 r. n void DeleteExistingPortMappings(ServicePointer pService);
z: G2 n0 s# s# H- v$ `" z void CreatePortMappings(ServicePointer pService);
$ S$ q3 e5 j/ e( L' P HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 G: ?/ ?$ D `, }. T
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 2 `, A! b1 R2 Q3 e4 @9 l% c
LPCTSTR pszInArgString, CString& strResult);
& Z% `4 p$ R ?/ {% l1 q0 [ void StopUPnPService();
7 h, c: }2 _& U
2 o2 x2 B* D3 e- E+ x- C: t5 J2 r8 K8 j8 G
// Utility functions
2 @2 x0 C: K. E HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
% a, O" E$ a$ m. a) a7 @* P4 n! L5 T INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 B: x9 s6 v- b; i5 y5 h INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);; ]' X# t8 C9 v, M! g1 N; J
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ L, w& ?, r$ q HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
: w" g, h, B, X HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ c. x5 q ~8 k" @; _
CString GetLocalRoutableIP(ServicePointer pService);* z6 O- s5 O1 n* q$ p5 Z; n: E- h* ?: S
4 p; L7 `( \" |& V4 d
/ q2 A7 ^+ ^0 o// Private members
/ \8 K( p6 v4 D8 H; H: hprivate:
- _9 f- G( c; q% H8 V5 h+ F3 A2 D" c DWORD m_tLastEvent; // When the last event was received?
) K1 M+ d4 t( @( s% M6 [8 w0 o std::vector< DevicePointer > m_pDevices;8 I7 e4 ^, a n
std::vector< ServicePointer > m_pServices;
7 Z+ @0 x1 g7 ^& p7 s8 Y& L FinderPointer m_pDeviceFinder;7 R9 |5 u& E5 B
DeviceFinderCallback m_pDeviceFinderCallback;& C6 ~6 L% q; E4 D K8 k; v' k
ServiceCallback m_pServiceCallback;
w0 U: |% N9 b: ~! B2 q; O# `3 R+ N6 P* i" ~" _7 G
) p7 b' `. s- y6 Y2 M: w
LONG m_nAsyncFindHandle;
7 t {6 } L4 B' D+ j2 I# k9 g bool m_bCOM;% t( s. O3 E! C6 F
bool m_bPortIsFree;
1 b- J4 f) I2 e2 R CString m_sLocalIP;0 h* P" O' R" O. Z' Q: n% W
CString m_sExternalIP;0 m$ A( r' Z9 D. y' P
bool m_bADSL; // Is the device ADSL?7 O: L3 g% B: M% h
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 k/ Y# N7 V/ ?. F4 N7 m
bool m_bInited;7 Q8 \8 ^ o' d/ h: K1 K% b; L8 q
bool m_bAsyncFindRunning;8 V( D) @- e8 ?, s4 z
HMODULE m_hADVAPI32_DLL;1 j& m2 y9 o7 v
HMODULE m_hIPHLPAPI_DLL;5 I/ c7 D5 M! G* D. Y' y
bool m_bSecondTry;
' L0 Q3 f0 ~' ?' Y7 z6 J1 J3 g) F0 W- D bool m_bServiceStartedByEmule;, P% f) f+ \# q$ h: E2 i7 c8 G
bool m_bDisableWANIPSetup;
( d& v- {! P# S# n bool m_bDisableWANPPPSetup;$ _4 N2 P Z3 S, j6 X
0 M8 S0 d# p3 e' J0 }( w4 M' s1 N
$ v8 o8 Y$ s* Q& }, Z! ~};
" T/ y$ J' ~" O& y
# j/ B% W, S" g: t V& J2 t0 [0 M. l7 c6 j& b0 ]+ v
// DeviceFinder Callback
1 P: O6 u# i& A8 T& u2 {class CDeviceFinderCallback
8 g! S0 N" z; C2 g+ ?* B$ N : public IUPnPDeviceFinderCallback
8 N- {. R, L' J- v5 p{
1 f8 B _; H& c8 Gpublic:7 a/ x5 K0 @% [
CDeviceFinderCallback(CUPnPImplWinServ& instance), n/ k( z7 u* e1 ~. U
: m_instance( instance )
$ b& Q: J F$ j7 }! } { m_lRefCount = 0; }
8 Y: t: {( H' E) e- T
4 `; V- |& Q {" r0 U1 `
0 K7 c! n0 x, a: B STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 Z7 i: \, @2 _) o& t3 y STDMETHODIMP_(ULONG) AddRef();' ^: Y/ S: d1 D! p o0 t
STDMETHODIMP_(ULONG) Release();
- Q* J" b) w1 w/ H% A
6 |, u9 J2 u$ {3 G0 P; |. ~9 h' K
$ D9 x, y Z: s: e6 V3 X# h// implementation
3 w' F1 m) ]3 o, Oprivate:4 Z) z; O( @9 }2 f1 P2 l: c0 u
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);. P6 O0 A; _% b! ]6 A; \
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" f, M: `, `7 K3 D" ? HRESULT __stdcall SearchComplete(LONG nFindData);0 Q& U# T* B r
% z& |! P/ |6 u/ j1 S; Z& D: n& J) w$ ?
private:
% X0 a- x4 |7 p% Z, g& @ CUPnPImplWinServ& m_instance;
' m, U; R [3 [) \; m LONG m_lRefCount;
, c) m5 q* v( a `};
6 g! ~: w' U" M: \2 q& ^3 M# k* J' H7 D
i* \4 n" Y7 q) P2 Y* o: d// Service Callback 6 f( g0 `6 k! x) y* X5 v7 U
class CServiceCallback3 f2 B! ?9 Y* D# Y
: public IUPnPServiceCallback
* b4 l6 @, h0 X& E- G{
* ~+ c4 o* Y: t- ^6 a9 npublic:( t+ N* P& s# ?! S: ?
CServiceCallback(CUPnPImplWinServ& instance)
; `* v) z V! G1 c+ J : m_instance( instance )3 W; J% j4 z1 F& r* v: j; d; H
{ m_lRefCount = 0; }
3 }- }( U! p5 `* \: e+ ~2 V% [* r5 n
0 V# k; I5 A0 u/ x4 U1 }! G, y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! |5 v1 x- T- o7 a1 t+ H
STDMETHODIMP_(ULONG) AddRef();) W! i' y3 K, ]; L7 A( B
STDMETHODIMP_(ULONG) Release();
/ [3 f8 H& Q& o' a* C" X
/ C+ W8 m& S5 a: b# ?0 ?: {% A$ q* Y: A/ Z3 ?% C, ]
// implementation
. c" c, L9 W4 Z* B% cprivate:
( a3 c0 R& ^6 o' T, u U HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);5 _ m4 b. }7 ^, b$ m. i
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' H7 r+ `- ^7 t5 H7 { x% l* u3 k
+ g9 \4 e& \6 ?( `# a
+ {, Y# E9 j3 ]' ?+ `6 q) ?private:# w* ]7 q. r- v- J
CUPnPImplWinServ& m_instance;
& @0 ^) Z+ C3 Z9 o s6 M7 C LONG m_lRefCount;
, ~' B2 c8 C3 j* N$ C: B6 B};
7 [+ E: _2 A% d9 s" p7 G) v7 o/ G/ n K$ s3 p3 g0 W& Z9 s
7 s" U( b4 h( H W3 D x
/////////////////////////////////////////////////
+ N, a- ?# G; R9 V1 H9 g# w3 p9 I% F4 ~5 X5 I0 C: b" M* g2 b
% P% U& j+ J4 |" n8 C4 Z使用时只需要使用抽象类的接口。
4 b3 k+ W; Y4 ~6 @$ \8 P8 p7 V) ICUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
) Q& g! D5 q' [5 uCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
7 T+ K8 }' _: d9 U% [5 mCUPnPImpl::StopAsyncFind停止设备查找.
& y6 h) W3 H3 Y! i. s" r* n2 dCUPnPImpl::DeletePorts删除端口映射. |
|