|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 ^( q, e3 J% Y$ H! u) ~
0 L4 |" M( }$ P- p3 @8 g
/ P w% A% v+ H9 h" L///////////////////////////////////////////
8 v$ Z' q% C- x# {. Z( N//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能., h& O( i( _+ f9 `
. K0 H6 X. l) J0 J) T' h
8 g$ U9 @, ^, ~) g f
#pragma once9 [+ h6 ^0 y1 _* O8 b% N; ~& R
#include <exception>9 F* W. Z, ]8 J$ J0 W1 u) H
$ t. U% b. K! W1 \; E
8 }- W: Y/ w- d4 j8 O( u1 j0 o/ W. @6 O enum TRISTATE{
8 {% [; B2 N. K TRIS_FALSE,& z2 N0 d% v( v2 K
TRIS_UNKNOWN,
! g; ]6 Z5 n- u: f; I% J' [' w2 O; ] TRIS_TRUE3 x/ O0 e5 i% ~" W
};1 n4 M5 d. \8 t5 C- F
& l; f$ s) Y3 e. i
( t+ `# Y S, S3 X$ ]
enum UPNP_IMPLEMENTATION{/ {" U# ~) E5 L! r9 E5 \
UPNP_IMPL_WINDOWSERVICE = 0,
" [3 i ?! A' G2 b/ Q, [: @ UPNP_IMPL_MINIUPNPLIB,4 y0 X. s y# Q! M+ V5 ~, `
UPNP_IMPL_NONE /*last*/+ _7 X5 e/ ]) F4 U
};
- [( L- [3 A9 L- R+ u" N, Z) b6 l' Q& c* d/ ?, ~
7 S7 e* b+ |/ E p# m. D" y! r9 b8 T3 |, v
! F. s" f, F5 B! i; y' Gclass CUPnPImpl
2 U& z* ^9 @- l( @" m{
' y7 G2 X, B0 k% g4 X- h% cpublic:% ^ s2 l" F+ ]/ D
CUPnPImpl();
9 k; R @2 T0 a4 R/ E6 t virtual ~CUPnPImpl();
! t9 ?" K& X. H struct UPnPError : std::exception {};
" [6 y$ ]# q/ }) z enum {, F& r1 Y6 V) M: d& W1 k
UPNP_OK,4 `' i) ?! G, T# J
UPNP_FAILED,
# ]5 m6 X9 D* p J2 s$ ~ UPNP_TIMEOUT# i. D" Q; F# ?1 P" W5 @$ t3 Y
};
' t3 \3 h5 c2 v: H# A) x `. m2 [1 W* D+ _; e6 `
6 s* Y3 I+ A* s _ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, c7 E; A8 y9 M4 X
virtual bool CheckAndRefresh() = 0;
! D- Y% X! E g% S3 } virtual void StopAsyncFind() = 0;
- U- B8 I6 {& e: R& X8 W) ] virtual void DeletePorts() = 0;
6 H" [! z# U' T1 D virtual bool IsReady() = 0;2 S2 @' [( d' z' n8 z( G
virtual int GetImplementationID() = 0;
7 P7 Q, J* V5 b0 y; l; S0 }7 u ! h) T+ x& ]! d$ f6 T! w9 g9 u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping( @. S: S. v; x. c0 l2 }3 _. N
1 H( m; W0 @4 [
! ~0 f! T5 h7 o6 R void SetMessageOnResult(HWND hWindow, UINT nMessageID);( y6 w' Z' a8 @8 j( q2 }# |& k
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ z3 e, s- j( A, k( H4 i
uint16 GetUsedTCPPort() { return m_nTCPPort; }
5 H6 J7 N' j3 U uint16 GetUsedUDPPort() { return m_nUDPPort; } 1 R1 Q* ^% [' l7 T& q: J; n
1 V) G0 i! l' O/ E ~! D A
. p; N* n: {! B% `
// Implementation- T0 A1 d. i4 V( \, I( }% E3 V
protected:" h+ }! E5 E$ i5 X
volatile TRISTATE m_bUPnPPortsForwarded;
* A& w# S. M6 t I& p* n( B/ K void SendResultMessage();, P; g" ]' ?: g4 s% h% Z
uint16 m_nUDPPort;+ z3 T8 k4 M' v
uint16 m_nTCPPort;. z& p; K$ |" S
uint16 m_nTCPWebPort;! r/ t- d# X# N* Q) N
bool m_bCheckAndRefresh;
0 z% M. K! W9 w9 y$ e
/ Y) E% Q4 e! N2 \
+ F5 x& r1 k* U qprivate:1 J7 ^" ^6 Q D* Y8 }' a9 h1 o
HWND m_hResultMessageWindow;
) K4 I5 D2 I) n UINT m_nResultMessageID; N( g9 N: X% o. q' K
, U0 [0 e- T0 [ \# i/ g: ?3 C$ g+ |+ ?! x. l4 N% Y' a
};
2 ~! \8 k! D7 J7 p- i* }; p
% {! y# e8 v+ g( n, L: b# d
% }/ i/ w# W2 k& }/ s% V// Dummy Implementation to be used when no other implementation is available7 R6 T9 N: M3 c& J
class CUPnPImplNone: public CUPnPImpl8 l) U! n" U% b* g2 u# j
{& \' I& O6 o* g4 x; c4 l' V" ]
public:3 v, Y9 M3 L( A$ V' u b; b
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
# r: F) _1 g6 |) r) g8 u; Y4 M9 K virtual bool CheckAndRefresh() { return false; }
) r. p7 P$ E4 G/ ^ virtual void StopAsyncFind() { }1 e& g% F6 W2 i$ e1 I
virtual void DeletePorts() { }
- s `. z, q+ \ virtual bool IsReady() { return false; }" P6 T& v4 D) G, O3 u# ^
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }. d. ]& O3 I7 Z' {
};
8 D# A: K v; O0 K9 \: r- L8 l5 \7 F. j* k6 B- e( ?2 _
9 }0 P8 |+ v# x/////////////////////////////////////6 R; o9 i* v3 v( P& _2 f+ R
//下面是使用windows操作系统自带的UPNP功能的子类, g. k7 D7 \- Z1 F; P6 Z8 E) S# W
# a7 R3 r9 a/ X' `7 U" U
5 y1 y+ B8 t6 O1 H#pragma once
; I: I) i A2 k' k+ o. H5 d#pragma warning( disable: 4355 )6 h( O% W0 [' i0 o" a! S
5 ]5 j. ?) u* q# R) ?
7 m( J( R1 } \#include "UPnPImpl.h"! z, U) x. o5 J, P8 l5 I9 m
#include <upnp.h>
' v6 q F/ k5 C. d. P#include <iphlpapi.h>
) I9 `9 N3 P B# L#include <comdef.h>
' n/ M1 [) l4 e$ v* v#include <winsvc.h>8 c6 c5 R9 h% U6 K& F
/ S9 G9 L% a" C% G; G# A1 H
$ _, W0 P- h+ v3 V0 v6 j! T- R2 P#include <vector>, S$ B1 \3 B$ Z) d9 ~
#include <exception>
2 a; _. q& ~9 D#include <functional>
# ]* C- q8 ~) d( T6 v+ F: K9 p2 }- E, t
* e0 \$ y. w. n6 ^2 @4 W) }; H
0 K7 ]- [) D3 e) k4 {
+ n9 L- A+ y" f0 ~/ R9 P' k% X1 ^
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;( ^# h2 d! w" m$ M# {$ u
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) f! V' U; N" g( K, }$ z( @typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
+ S2 v v+ S. z' g+ Btypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;5 w- ?9 D$ I X- l& c
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: \3 x; a. n1 Z3 T6 \1 T* g
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;9 g4 ]' k2 s/ M9 r, {. W( a
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
l7 P% E3 ~3 A/ M: Z
+ }! @6 A5 D* I, p! p) ~5 Y7 w% {, q- x2 w9 A4 r4 w+ ]$ z. L
typedef DWORD (WINAPI* TGetBestInterface) (
! ]. d, ~/ t& \' N* a4 w: \2 ]" \, D IPAddr dwDestAddr,
1 y% ^' a9 M( Q: r9 u5 J PDWORD pdwBestIfIndex
8 ^& O7 l' A. N7 v# m8 U);
/ ]* W3 u/ A" F G& ]' H- W# k1 U7 r* P8 m, k5 x) }; `
; p, H' j- N& D- v3 }$ v& i
typedef DWORD (WINAPI* TGetIpAddrTable) (/ ]7 a3 j" l, l t( ^! W8 W
PMIB_IPADDRTABLE pIpAddrTable,; f* `. w9 M4 O# e4 X$ V6 W
PULONG pdwSize,
6 t( a; R7 H7 \) R" Q BOOL bOrder+ w; _7 S/ [2 r2 e" A; N# z. e8 g
);9 D) T/ I( L4 p2 A3 a# @& X
1 U, }, J9 V6 j/ c1 v, h" y. I
' W& z( [0 L) k9 B4 V. Ztypedef DWORD (WINAPI* TGetIfEntry) (
4 Z1 }5 K) S! I/ W! r! I" ~0 Z PMIB_IFROW pIfRow
% f+ r$ G* r* D0 s);4 S' s0 l* x; |0 S1 w# [& \
; F8 }6 J) e4 C& M/ F7 z% C
3 d3 G) k! ~4 ]1 ZCString translateUPnPResult(HRESULT hr);
) r3 c! M% A9 x. `, M/ BHRESULT UPnPMessage(HRESULT hr);
7 {/ L- U2 y2 x4 g: A8 Y$ ^, M; m1 q; g0 y# F' ^
* f+ y( N) h, e) I. |. R: Y( z
class CUPnPImplWinServ: public CUPnPImpl
5 G7 j0 [' x' y0 {2 M, `& m{
1 c, w2 c% X. p& U$ t friend class CDeviceFinderCallback;
% R$ L, v0 @- I' b, o friend class CServiceCallback;$ P2 O5 q: Z4 L
// Construction
& n# V& M; `# kpublic:! F. l) g8 ?8 Y' d8 D
virtual ~CUPnPImplWinServ(); U1 Z" G3 d" d7 J5 W+ _
CUPnPImplWinServ();: V% b( i5 ~/ F- I- D
/ x9 s) z) q- \" ^- Y4 \7 Z" d0 g z- s5 n# t, I6 y% H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }5 S% J( @1 G! V" j. S
virtual void StopAsyncFind();" q. o4 A, `. ?! _6 j* d
virtual void DeletePorts();
* W) y+ f" n" ^4 O4 t0 V virtual bool IsReady();
6 J% B3 c9 Z) |1 ~8 x' `* U virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
: @3 K) d2 j/ S; Y& c
8 b; T$ }5 \( E
g! S5 b+ L5 r# r8 Q8 r // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)0 g j( I$ ~0 e3 y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ }- N2 H( j: j! X& M virtual bool CheckAndRefresh() { return false; };+ j; J: Y$ p& |" F7 Y; @
* v: y" q! q! W* q% i' @ s6 T2 t
a9 S% |+ I) dprotected:
; [2 L3 x4 l+ a void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
' J( K0 }+ } g8 m3 y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);% D4 t5 Z/ [6 x
void RemoveDevice(CComBSTR bsUDN);4 M3 o5 [6 X- \3 ]
bool OnSearchComplete();: M6 o7 b1 W! N7 [* d: b7 F0 `
void Init();: k9 a$ |& g3 M+ d8 x0 F! h& U( a
9 q5 g+ G5 }$ ?( ^9 Z
6 {3 V. L& s' a6 R8 b+ W inline bool IsAsyncFindRunning() 5 y9 A3 T1 f! t$ J4 v
{
7 D/ l9 {, ~3 _) U7 M8 |4 X if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 z) l% ~$ A/ u5 @5 ], l$ t
{
x6 i, z% k' }- k m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
9 q( g, ^+ q3 s# K m_bAsyncFindRunning = false;
# w, E; B5 m3 O& X2 m. @ }7 X' {; z1 G. i+ x8 @, Y
MSG msg;1 }8 q& s' \; A/ Y" z, T
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )0 z) C2 X' j" \# a4 t
{
3 M# Q& y& d7 V' C TranslateMessage( &msg );0 ^& U) @' I) }% U: @1 L
DispatchMessage( &msg );. @, h9 I# ~ j- p- S# ?. z
}
' Z7 r. s5 g0 l return m_bAsyncFindRunning;* t/ N0 N* }0 H: R
}
0 ^- V) w4 q9 p- Q, L, \! T) K3 p- x- ~+ t# s
: u1 |/ V: R5 q1 t# T
TRISTATE m_bUPnPDeviceConnected;% s, `- `8 [/ K/ o. T7 q
& O: K: T; c5 s* x- K' B7 l
1 p+ b9 V9 u# d! Q// Implementation
3 `4 g& G: \/ O( ?1 p; q // API functions
/ D/ l. h6 H, ]9 j, T SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);7 j( k; b) d& E* I
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);3 m8 U5 L! o! Z
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
/ A# b1 N% E# w BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);$ P2 b- j- ^ L- z+ S7 v, V2 l7 h
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); _- F5 ?* I" W) A
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);0 A6 W) w' W7 q' m$ B
& @9 ^8 e4 ]% B+ W
6 ?/ X) F6 Q: V, S TGetBestInterface m_pfGetBestInterface;% G- y3 d8 m$ D% J# z; m7 e+ x
TGetIpAddrTable m_pfGetIpAddrTable;
) j* {4 D1 ~: M0 N5 P; e [ TGetIfEntry m_pfGetIfEntry; Y* Z1 M; S$ g% U$ }
! ^; b2 I% v* C. I& s3 J% ]1 A% e
{2 V; C+ C* y, ~4 d8 ^% Q
static FinderPointer CreateFinderInstance();! E# S' J: d( Y( f, q5 t# i; i
struct FindDevice : std::unary_function< DevicePointer, bool >) B& ?" t" m6 x, \$ r {% L# P
{& Q4 K# \+ a/ I( w3 u% U1 G
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}7 e% G! h$ y1 i% W. b' u: @4 F
result_type operator()(argument_type device) const# L7 ?. F" [3 x T0 {( H
{
! _; e+ J% w- A* \% \ {# n- h& ? CComBSTR deviceName;
9 D6 f5 y% ?& ?' A4 C3 z; \ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( x+ m! C8 T: c! T- e
9 Q, B% R7 i; r0 [
: e0 u. D8 p+ G* W4 y6 T if ( FAILED( hr ) )
5 A8 ~8 E$ o' U. S2 [# r! K' ? return UPnPMessage( hr ), false;
, O+ k/ D7 }- H- i" M4 b# w! p+ ~& E6 I, ^6 @5 A9 {
2 [1 j' L: H4 A; C return wcscmp( deviceName.m_str, m_udn ) == 0;7 u; e; o2 b, V+ }* j- a. l
}
6 }' O% y1 m: o8 C f4 d CComBSTR m_udn;
. k0 @9 S8 }7 f; P$ N$ y };
+ ^2 h5 Q8 f0 |0 l4 q$ l
4 c7 |4 E( |! i5 Y. |% M/ v: o void ProcessAsyncFind(CComBSTR bsSearchType);" n, h$ p0 _; a+ o S
HRESULT GetDeviceServices(DevicePointer pDevice);9 W# a2 ^+ a# d' ^0 n$ ^
void StartPortMapping();
% [- z3 `9 Z+ u9 y/ u5 ? HRESULT MapPort(const ServicePointer& service);! k5 W% R. W2 K4 ~# e- {
void DeleteExistingPortMappings(ServicePointer pService);
+ q" Q# u$ l9 ~ void CreatePortMappings(ServicePointer pService);3 Q/ c3 ~2 ~' O4 L
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
' ]2 l& `. P; `. u) K HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
" F: C- k) X0 J( T$ x% @ LPCTSTR pszInArgString, CString& strResult);
$ y% {* X( [% O3 H void StopUPnPService();3 y( q7 |" ]7 L" w/ m
/ I0 C4 w8 Q$ o5 `: D8 F( |
' D. _$ R6 s* G // Utility functions
$ \6 g) e$ O0 i2 [0 ?3 K; A& Y HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; ?2 C$ x' m# ~5 k: X! \0 _6 B. l INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
) a' J( m+ d8 u9 x" ] INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
8 I" j/ u1 ]) ~3 [; T* y+ j' p void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);* g5 r! B% S9 F# A: o
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);5 A2 W& H0 M; u
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);- A' a- Q2 S$ O d* `, B, H {
CString GetLocalRoutableIP(ServicePointer pService);
& K3 T& C3 l3 h X9 K* S
, L! A: C# e# B `/ N
9 I+ d6 Y1 f. X// Private members, r. m- D: M0 O: _0 y2 d; _
private:1 F. `0 h6 X( h3 [6 u- h
DWORD m_tLastEvent; // When the last event was received?
! t4 @ h: R" ]; j8 w# `$ x# ? std::vector< DevicePointer > m_pDevices;
2 d, N1 B8 ?. Q/ q" h& _ std::vector< ServicePointer > m_pServices;! v& p1 L. J, ]! E
FinderPointer m_pDeviceFinder;
; a% u' |) f; [0 }- M DeviceFinderCallback m_pDeviceFinderCallback;& }/ ?6 k8 S$ [6 d' e3 N1 e4 e$ L% K
ServiceCallback m_pServiceCallback;( q5 T* k4 q v" s- n8 Z9 h+ W7 H
9 L5 n$ P6 b* x4 l- o d5 ~
! @0 O( _7 P* A. x- a# ]
LONG m_nAsyncFindHandle;
& [% @/ }4 [" ~. W$ c1 K bool m_bCOM;7 J0 U/ ^) ~* s- k5 f6 K
bool m_bPortIsFree;
8 u V \' g y3 d9 p1 `2 ] CString m_sLocalIP;
* O+ _/ T4 i7 d% j) |8 H% k CString m_sExternalIP;" z: r. p7 R/ G# K' H% B; r3 H" y
bool m_bADSL; // Is the device ADSL?) ~6 ?2 U0 H. i2 P# r, e4 A
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
0 M' @% X0 f1 P& u* r- s bool m_bInited;
1 u! C a. ~* I9 t' d bool m_bAsyncFindRunning;0 u" _8 ^* V# k9 K# f6 y9 E
HMODULE m_hADVAPI32_DLL;4 t+ u$ j& E* @; p( F; C2 |
HMODULE m_hIPHLPAPI_DLL;" W+ U# q0 L. R R& z4 J7 E) Q1 o* X
bool m_bSecondTry;8 v" `/ Y3 [0 S# H
bool m_bServiceStartedByEmule;0 l/ l7 k( p' g1 |6 a
bool m_bDisableWANIPSetup;5 I, }" t, M* h; w: m' D8 F/ d# x
bool m_bDisableWANPPPSetup;# O7 O8 `. y" J( t4 D( @3 N4 g
" W M4 y/ k' K6 O9 g2 G& Q' m$ \
+ \' O- n# N0 {# L};+ H" I- D" U/ J. r( {
" I+ O( {7 {3 C$ b& S2 X/ |+ {: ]$ _
$ ^$ v( i5 _, h" t
// DeviceFinder Callback
2 Q* V. `9 l2 I4 @" {, U4 b& kclass CDeviceFinderCallback: Q# ~: f7 {5 y% V- Y
: public IUPnPDeviceFinderCallback
( W6 T* } x6 c. `{
" c; ~- X$ S5 x, O6 W8 Y/ I. }! y opublic:, i4 m5 Z/ [: c1 v$ u. K
CDeviceFinderCallback(CUPnPImplWinServ& instance)
8 X1 N0 I" p/ \6 n : m_instance( instance )
1 C) V' T/ R& B+ P* l { m_lRefCount = 0; }
; r" ^4 J+ |# [3 b) V' ~# J* [9 N% b7 u7 `5 \
" \3 U$ m: @9 i, y4 `8 Q
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 d U0 S; U4 I STDMETHODIMP_(ULONG) AddRef();/ m; {# A% c& Y; ]3 B8 {
STDMETHODIMP_(ULONG) Release();
- ^3 V- B8 `8 ^. E. z2 ?; H {4 ~# S
% [/ k& t2 e! B9 ~' s# P
// implementation
6 h7 ?0 z7 y; @4 }+ k5 D3 ]# p, r0 Rprivate:5 Z0 c, y" u9 C
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
- ^9 j; B+ y0 T* q HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
6 G/ k$ e; z0 Z( S( y1 y8 d7 D HRESULT __stdcall SearchComplete(LONG nFindData);
- w9 b9 r1 U5 D; x/ ^8 ]& ?6 }: @
5 p" K/ g0 }. |5 N9 Z+ e2 i2 ^% C1 d
private:
. ]! k* X" L9 h9 ] CUPnPImplWinServ& m_instance;
5 H! O0 H2 ^* y2 A1 c: _6 ` LONG m_lRefCount;$ Q4 q6 T9 }! U, Z4 [ Q
};1 u% K& X, E7 s% m/ k8 M$ N
/ A! w- p; {% s1 g0 F
/ g4 [$ K5 a, S# `7 {. U( T// Service Callback
5 L# M' {! F8 b% P, a4 b& ?class CServiceCallback
$ |6 {1 v& M% B: t& n$ u& [ : public IUPnPServiceCallback
5 \/ x1 [0 f6 w! F, r{
; t x+ N0 T8 |public:
7 E8 A1 |5 l* e+ r CServiceCallback(CUPnPImplWinServ& instance)
- Z2 l5 Z% G& r7 M : m_instance( instance )
& l. g2 D3 ?: h* K* \: e { m_lRefCount = 0; }4 {2 c' w. i0 v+ M
7 b, z& R! x3 D STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. _+ E- ` t4 s, Z3 z: }
STDMETHODIMP_(ULONG) AddRef();
2 `9 ?2 f6 g2 S5 l' x' T STDMETHODIMP_(ULONG) Release();& k7 K' u, g1 c- N6 P; a: [# G
4 G: J) x5 p* W, R* \9 c0 u3 y i) ^; }8 K ]7 v1 K
// implementation
/ I- Z; o2 [+ o3 yprivate:$ `9 l6 C$ ~# U" [
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);* \, k/ v+ X( w# L" Q$ u3 A ~5 }+ v
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);7 {( R! l! M7 n: v
6 i$ y+ ]6 w# U9 h! i
5 P/ C* E, L1 c6 y& T6 U
private: o. L' ~( I; G+ _+ s& W7 v. U. M
CUPnPImplWinServ& m_instance;$ @& v2 o/ b; A* n1 K# e
LONG m_lRefCount;
" l# p3 l- c" O4 c};
: B& s5 [" }' N- ?% A" F: Q1 o
5 f% e$ C. j) I* C8 _! Q; b
9 a# f" J1 V( a4 J. W& x: X5 ^/////////////////////////////////////////////////
" s: f+ k& C/ k/ _8 ~ ^; d& I
3 { e5 F& d$ Q$ A" ~: ^% f3 ^
1 g0 W0 ]# q0 y& s, E( {& A% s使用时只需要使用抽象类的接口。
& o6 V6 f$ M7 FCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: o) k, B2 i( J* l, J
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
* u+ Z; f& R+ PCUPnPImpl::StopAsyncFind停止设备查找.6 a4 o3 U2 v8 \; u
CUPnPImpl::DeletePorts删除端口映射. |
|