|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,( I9 V- U9 h2 o* }. Z6 \' n
+ r7 Y. s5 F3 ?0 v& }+ @# E; P6 g: M2 Y5 l3 A. }1 c9 ?) D
///////////////////////////////////////////! x3 @1 s. {( s9 }9 k9 W( T2 B0 U' K
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
j) \# U$ d& Q2 M7 v
6 y/ R. n3 h* e# Q8 c9 l
/ F/ Z! y) r' ^/ k- u#pragma once% C; W3 y/ D) g" k/ l1 Q7 y) S
#include <exception>
* g8 H7 A5 c" H V, a6 |% x6 P# R% n' D3 Q
" R5 g$ O, {/ D9 p2 r K
enum TRISTATE{
' C4 s7 m( }( i4 V) P8 m5 V# y TRIS_FALSE,/ z( U2 P0 ]. ^/ Z" i3 `
TRIS_UNKNOWN,3 |+ u4 v% G- O" V" ~
TRIS_TRUE/ A+ n3 L$ h) N8 L8 S0 i
};1 Z. M5 s- Y) l* d" v9 S$ O9 F
# |7 \' H2 k$ s+ F2 p
% J% C9 j! j/ r l0 P$ c) q
enum UPNP_IMPLEMENTATION{0 U3 T% h$ e7 ~. ^
UPNP_IMPL_WINDOWSERVICE = 0,
0 ^- z4 x) {6 k: u0 i7 ~ UPNP_IMPL_MINIUPNPLIB,
0 d* J p& y: P4 x UPNP_IMPL_NONE /*last*// x1 ~; G" Z' E; @
};5 _: @% G- g, z$ w+ Q: r! R, L5 X
/ Y: K% [9 _5 b# d+ Y3 m+ L5 ~7 { |- \
- ]2 F0 c# _2 R/ w5 C4 }. j
8 e: h1 b+ U$ x0 A: C1 k ~class CUPnPImpl
5 O4 D* [0 V% N5 D6 }5 W( G, T{( K2 W+ c0 t6 }* Z0 h
public:
" y: h0 V+ ^% q/ ^" x CUPnPImpl();
: {+ [5 I H& H8 e+ } virtual ~CUPnPImpl();9 l# ~& _8 I" R0 `* t
struct UPnPError : std::exception {};
& D! a9 X" O* ~# j8 [6 A* L7 H enum {$ l( ]3 \. w8 N: i1 G" Q
UPNP_OK,! r3 v* |6 a: V g
UPNP_FAILED,( ^6 u" v, `0 v P
UPNP_TIMEOUT* S5 ?' v( a7 z; L/ N
};5 J; H2 J M) L
$ [; D% C$ }9 N# c) [2 K) L I
( C; ~: f: j" {; K6 O virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
. i ^5 o+ @/ D virtual bool CheckAndRefresh() = 0;
, n, y' d$ m! [) w virtual void StopAsyncFind() = 0;& U* ~# o2 t, b2 Q- X
virtual void DeletePorts() = 0;, W# e+ `0 T! I5 w
virtual bool IsReady() = 0;
1 }. m8 H) K) c# K virtual int GetImplementationID() = 0;
7 a' C8 C# ~; i' n3 I$ s3 o
. z/ S2 P: c2 M8 X void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; }) d/ u4 E$ l
/ q3 U$ v1 j4 ^/ C9 p1 X7 f Y R( c$ h* e
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ W. \( _" Z" N) B TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
S4 s' B2 H& f. c! R# ~) ] uint16 GetUsedTCPPort() { return m_nTCPPort; }& T$ l1 W$ z6 c7 k, t% \
uint16 GetUsedUDPPort() { return m_nUDPPort; }
" ^$ }" M: s6 N
2 `2 w/ D8 ?) S, [( v7 _4 I( X7 ^& z& |5 G. c! Z9 E
// Implementation: ?# T0 J; @% b7 B, A7 u; N8 y# }
protected:, L# X( _" ]! j) |
volatile TRISTATE m_bUPnPPortsForwarded;$ j$ O; C0 e; A5 G
void SendResultMessage();
; v/ |% @2 m4 T0 w6 t% y. e7 s uint16 m_nUDPPort;
3 S. c% z- o; ^9 P( j1 Q5 C! M7 Y uint16 m_nTCPPort;
* u# V) Q) {$ p uint16 m_nTCPWebPort;6 c) L4 Z$ M) V1 J7 Y2 H: C
bool m_bCheckAndRefresh;, O1 i7 v2 r) Y) r: H, L
% T0 K" H" T. }: R! D
: @, c5 c- I9 f& t, Rprivate: F" W. e& X$ N* O5 X) C5 i
HWND m_hResultMessageWindow;6 W; Y4 {/ [# {$ z& D/ Q" w: {6 h
UINT m_nResultMessageID;' Q- u k: o* G: a
) m8 Y+ T; P5 S A4 k
- Z+ s+ w4 q. A) n& ?- ]9 C3 h
};
, G$ Z7 h5 c' D
) N5 X! D$ Y1 ~6 I0 {. G" A/ @1 Q2 ]6 M/ {! c: G8 P
// Dummy Implementation to be used when no other implementation is available5 u. H) p, n+ t1 b" _1 f
class CUPnPImplNone: public CUPnPImpl
. y" F- V0 d# p3 @9 b6 L{) V6 [3 o$ w/ {
public:
8 F/ r L9 c. _8 q2 a: D virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }) Y- n" e& ]9 g) D' S* N/ [
virtual bool CheckAndRefresh() { return false; }
5 o' S4 }* P6 N. l1 m2 L5 b virtual void StopAsyncFind() { }
; X; X1 [1 I: a3 ~$ w% [ virtual void DeletePorts() { }! z0 n) e* `. I7 ~% O
virtual bool IsReady() { return false; }% t! X3 F$ {( s7 r* x: l& v
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) n4 J, g. |% r C9 C
};
# F7 B/ m# @# u# h" S5 u3 S% p4 ]$ W/ |$ M, O5 j* V
' s) Z$ K! |. r& Q: p/////////////////////////////////////( I! i4 y6 g) I+ u
//下面是使用windows操作系统自带的UPNP功能的子类; m j7 m$ R) d' h# ^( v" Z6 p* K
3 y) L8 e, M8 e! Y$ f4 s6 A6 {. b- |( U; o; z& p
#pragma once: |3 @5 A% j" b4 U, O3 R2 c4 H
#pragma warning( disable: 4355 )
9 h; h! [2 ]9 n! @! w$ M( }
: G% j8 w3 D( @3 C5 F
3 ]8 x$ L+ H" k; N* l#include "UPnPImpl.h"
4 f5 \& o& m! A/ |#include <upnp.h>
) l2 t' C B$ `% }- ?! W7 \2 Y#include <iphlpapi.h>
2 N& Z6 j4 h& `0 R8 H* Y+ C6 G#include <comdef.h>' g# {4 ]9 x6 _8 u
#include <winsvc.h>; S# g6 }2 {+ i% d
1 v4 ?" F. u1 c& ], f: n h+ Y$ q% u: {1 x" [. o
#include <vector>
`/ |! T( H* {3 }$ f' f& I#include <exception>* g; a2 C' f( D& k G, {) f
#include <functional>
; D- P3 c9 B! p1 `' U- s/ U8 p' } n/ |9 H3 V4 \$ {
: a& P9 |! r+ a/ h
0 T8 `8 O' g/ ^! }, q
* D9 A' B! ~# Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
5 ]( ~( | `* Y2 v" a( Btypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( g$ p) Y6 i' Q* s9 n7 Z* E
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
1 i# k- O" p8 k& ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;6 }) k% b8 B2 v3 |
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 y' i `* \0 b& c; x
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
/ Q( Q' `1 }" c6 @5 w7 htypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;( @5 u5 h/ j% h
! k6 l. `- T5 t& b; N* l2 j0 I
" N: N& S: l0 `$ C6 m Ntypedef DWORD (WINAPI* TGetBestInterface) (
% E J6 h& y3 Q0 p IPAddr dwDestAddr," ]" b/ F6 `. W$ t
PDWORD pdwBestIfIndex
: s7 M4 ?& t* V& p);
8 k& x- ~* w& Y9 H) y6 J- ]/ z# R! A* W, U, k& t1 i
2 l; M/ W0 A* K& o
typedef DWORD (WINAPI* TGetIpAddrTable) (% Q9 @: C( P1 {, u, A
PMIB_IPADDRTABLE pIpAddrTable,
6 l# A' ~) F K PULONG pdwSize,
" S' \$ ^( W& u D BOOL bOrder
& T5 _. s; ~! z);3 L. u! {( a8 d, P3 B4 a+ e
% I* K, n' l6 Y' e& v5 @0 K
* k2 s2 [" t- Stypedef DWORD (WINAPI* TGetIfEntry) (+ u* b$ G( }" g$ h
PMIB_IFROW pIfRow( j3 t6 l k1 @1 v$ g$ j2 ]
);3 I* ]# e; N3 x" b6 x$ M/ _+ g! G
5 ~2 g i) }1 G6 _9 Z" }/ h$ Q+ h2 l' M
CString translateUPnPResult(HRESULT hr);
( b& N% O( n2 Y, [7 JHRESULT UPnPMessage(HRESULT hr); D( {( U, j( d: j$ r
4 _& X, S! J( ]( s% n8 U2 P. B6 b/ m. s0 P% H4 d1 P
class CUPnPImplWinServ: public CUPnPImpl+ H0 O0 B0 \( X$ M# t3 O" s9 X
{1 O3 j$ c) ]+ _, c% ]6 a0 G
friend class CDeviceFinderCallback;
) U% Q) \) S, N P# } friend class CServiceCallback;
: o4 f3 E3 \/ N( h7 S. _6 U0 ~ m s' j// Construction; A8 [/ `& _" \4 p( D6 s- s
public:! u' M9 ]+ ^7 J& c4 d1 I
virtual ~CUPnPImplWinServ();- a& A) c) Z: @- c
CUPnPImplWinServ();
8 U- a5 T, X4 ?- \ a+ U7 k& R$ f$ ?2 Y+ _6 S% j
. Z0 p3 P& e8 {' P. i0 ?5 f
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. [# v0 U7 f7 f) p' w: K) r/ U( E virtual void StopAsyncFind();
- N3 }4 r/ t* p5 d% n' U, g virtual void DeletePorts();8 ?& a# D# {% ?
virtual bool IsReady();1 T0 Q8 y4 ]9 H6 ?8 @
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
# S* ~5 [0 G- b1 o7 V* z2 z( h0 _. R6 a: u ~+ i
3 T8 j2 _2 J. w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
) p) h8 k% D; N0 P. L // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
* Z! V( v; I/ e) w7 S* r3 [5 L5 d virtual bool CheckAndRefresh() { return false; };+ s Z0 H6 V! y- J! P- b5 n# n, o
! x, u6 y* y/ B- l, u" e# L- C) D8 N- j; H% C5 c8 u; I* ]
protected:
$ L+ d# m- `0 T8 e( o void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
' [9 x( r- y+ @5 r' `$ E void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
& F6 T3 P! j0 l7 C# m; N, R6 H# W) z" Z void RemoveDevice(CComBSTR bsUDN);
0 E* z: M+ C4 ~: O bool OnSearchComplete();
8 s- t; `4 @6 d7 [: B void Init();, U4 I5 f. G& g
- X$ U X" D6 M; j2 l% A9 ]2 r4 a& S! X8 D* X$ t
inline bool IsAsyncFindRunning()
7 u5 R! ?6 |5 O( I. i6 G8 g {
4 G# ~7 Q4 I5 K4 [ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
3 a& o% \8 D* ~) L { F0 C; R/ Q+ n6 O* t, ?( B. P
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );( R# w' m/ h1 @* t
m_bAsyncFindRunning = false;
( h1 K8 y: C5 J, [ }, ?6 y: D! f( I! I8 \
MSG msg;* o' e- }. w! o8 X/ q' n4 {
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )" R; I" z0 r" E2 r" j a9 m* N
{ B" }! ^" ?: ]7 x$ K: S" q$ {) d4 G
TranslateMessage( &msg );8 ]7 Q, J# p3 A: {6 z- j1 P! ~! Z
DispatchMessage( &msg );
7 H; T0 n; D! D5 _/ t# \5 L) v }
+ z2 D0 H5 p5 n) U return m_bAsyncFindRunning;
8 ]& L7 d2 l, _2 A }
+ e) ?& |4 K: y& o9 C' \. ?; @
, |8 a( h! K" U, V4 G9 b' ]0 i! p/ C3 Z% X' [- l8 X5 q
TRISTATE m_bUPnPDeviceConnected;
! Z3 O7 B' l" K. _/ e# ?& B, W0 T/ C. C5 [* D' Z5 K+ k/ E" U
5 ? Z8 o( Z; W6 J4 D4 V
// Implementation
- w9 M: M; h: U8 P# l* \8 T! l" K // API functions' c1 z2 l0 V, ^+ R" G0 A: k
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
- P. Y! _) q0 b3 G7 _4 B# D; I, W& e SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);9 N. j& w3 J. t/ g* z( V7 C' g
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);. z$ k" h5 E) Z
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);8 S% z' `5 V3 k% g! R. j
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
1 G* z7 Y2 g( g5 H* M0 c# b2 J BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
1 v7 F% g1 N' k7 U5 ?: g/ C1 h; x& `! M* T
8 A4 | X: Y% q7 ?9 }4 A$ i8 n% x TGetBestInterface m_pfGetBestInterface;: r3 f% m. F2 k0 K
TGetIpAddrTable m_pfGetIpAddrTable;
5 l3 L* w3 M( |0 \$ u TGetIfEntry m_pfGetIfEntry;
# m" T" J- E- e4 [; y5 [/ m0 `( ]) N8 ?/ _
) A7 _1 h" }7 P/ _3 W" I static FinderPointer CreateFinderInstance();
+ v( [7 P+ w" \3 [6 w8 z struct FindDevice : std::unary_function< DevicePointer, bool >0 u3 t) a$ m' U4 u
{
- i L8 S* U3 J5 i# V FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
" J' @5 Y0 }, g6 s- b$ [5 D/ j- v3 I result_type operator()(argument_type device) const
& X8 q6 }+ D' Z# D {5 G9 q8 H( a2 g3 i
CComBSTR deviceName;" k @, @% m# e4 a( [$ C
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' j5 K' ~/ n8 z- e5 ^0 M& l! k+ M
7 F |9 T+ O: g a8 R1 V' b _# m ~- C/ G
if ( FAILED( hr ) )
. [ F5 W( k/ ~/ E( [8 a return UPnPMessage( hr ), false;
, \+ c% F. O% T$ w. ~* ]) C: m6 a" U( o2 h% T
) z3 x) p/ J; y
return wcscmp( deviceName.m_str, m_udn ) == 0;
$ P5 A4 _0 C6 ~, V }/ b' s# p1 F4 B- [# E2 U8 V
CComBSTR m_udn;
+ i5 M( [, I! C# ^3 l2 @7 ] };
% w% u; W5 x4 ?2 M
9 q4 y9 H# G* j void ProcessAsyncFind(CComBSTR bsSearchType);4 N! s" H- [1 _! g
HRESULT GetDeviceServices(DevicePointer pDevice);" ?. C- n1 a8 ?& c
void StartPortMapping();: l4 L% {; i6 F" B
HRESULT MapPort(const ServicePointer& service);! C. o3 `/ F4 h& b: B
void DeleteExistingPortMappings(ServicePointer pService);
1 r1 q+ }) s% A. i# o* X void CreatePortMappings(ServicePointer pService);1 J9 k( k6 X* {6 D0 E% _* e5 m: ?, B* Y# Y
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
3 e l5 k4 k6 ]4 k! S1 Y6 I+ R HRESULT InvokeAction(ServicePointer pService, CComBSTR action, : R% Q% d4 |, Z: E5 ?/ i" l6 Y" n x7 ^/ I
LPCTSTR pszInArgString, CString& strResult);
, V# |4 A& Y; a. G9 I void StopUPnPService();
7 I( n2 D- @3 j8 ^3 w% O2 i `% `6 _" N) d+ H4 {8 j5 a
+ E& W4 c: H# p* p+ s/ | // Utility functions' k7 o8 `% N% T/ z# o7 c5 z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
% e, h7 B8 N: e+ p7 X- l0 Z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);& v; Y) K- H" K3 {
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);+ F0 ]9 s" J f K9 D; ~
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' J, \3 `5 j. v% B4 |
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);. `3 |3 q* X7 ?; L* M% D7 {4 l9 z
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);5 u* t: c2 o E/ L( s4 m t
CString GetLocalRoutableIP(ServicePointer pService);; V3 U# D; I3 t
, l$ N p8 M# Q! \# |' r: Z& J
0 F. I% v l9 {2 q% k
// Private members
. k+ ]$ `: j7 e# s: b4 Mprivate:
4 y' b! ?$ `* X* C DWORD m_tLastEvent; // When the last event was received?
6 G& l. d i8 N7 b) B O std::vector< DevicePointer > m_pDevices;! I, k2 f& j7 e5 {6 d
std::vector< ServicePointer > m_pServices;' p5 V# R2 Q6 q( Z
FinderPointer m_pDeviceFinder;
2 J0 Z' ]! l, ^; b" o0 ` DeviceFinderCallback m_pDeviceFinderCallback; O! M* n! D% a$ H
ServiceCallback m_pServiceCallback;! z# p! L2 L1 ~2 c0 m: w
/ y, v. `. F6 O* D% b. R" I9 Z
8 ~1 t5 @, j$ X8 K( t LONG m_nAsyncFindHandle; D3 M/ W. B1 H; K/ C7 v* k
bool m_bCOM;
% ` y' H a2 C w# W( ^ f bool m_bPortIsFree;& v: n3 ]' ]1 T% [
CString m_sLocalIP;
+ T9 x& ^' U2 f( V) v/ l& ] CString m_sExternalIP;
8 D- H) |! X% ^2 v* b bool m_bADSL; // Is the device ADSL?
2 E# v2 ~' s& Y. l* ]& x bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
8 c% j( ]+ `8 s+ X3 X8 I6 K bool m_bInited;
" H# }! W+ x: K# s$ j4 { bool m_bAsyncFindRunning;
9 D7 [3 |. w- P+ _9 z8 p! f5 F HMODULE m_hADVAPI32_DLL;' t }" ]& A7 P$ d; _8 n- ~" s0 T
HMODULE m_hIPHLPAPI_DLL;
3 q1 e+ x, s" o& D7 d! b, i [ bool m_bSecondTry;
2 M- _0 W( F( A d( w, e3 h bool m_bServiceStartedByEmule;
" \' c+ r( F8 c5 `' t; Z( g: f* z bool m_bDisableWANIPSetup;
1 p& m6 @4 l8 v$ G1 [. W3 z9 z bool m_bDisableWANPPPSetup;
4 {" Z6 Y8 W+ Z L4 c# s' r+ {# I
+ K. @6 z& D" S) _/ {};4 v0 _2 n$ A9 O# J e! B6 S8 {
& X$ D, z4 D3 N; t a5 A) p
5 B& O$ C! H2 _5 O2 q9 U1 Q// DeviceFinder Callback
, a- i! }' X. H& |( Q+ L/ e5 {2 w3 Mclass CDeviceFinderCallback5 J" j4 B0 v+ r0 F- F4 P! ~5 f
: public IUPnPDeviceFinderCallback5 c0 m: n$ [* V
{; F1 S0 z4 ?- E: F; L+ X' k v
public:
. o: A" g* |6 Z- E- ^6 ~ CDeviceFinderCallback(CUPnPImplWinServ& instance)
: W4 m! f) @6 Q' _2 Y& l5 G8 N# Z : m_instance( instance )
/ ~/ |' }) l4 n { m_lRefCount = 0; }+ Z* F" q( |, U8 g" z, X
& o' Z9 a6 z* ?# w3 I8 x* E$ B
+ o: O. p' d; w4 j( x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# I9 c( F( u2 D) F6 S4 z# f9 ^1 \ STDMETHODIMP_(ULONG) AddRef();
* h4 i9 ]) q+ u4 r$ Z- k ` STDMETHODIMP_(ULONG) Release();
! d1 b7 X9 Z0 l R& D; Y" }( U q, C& Z' b; T4 o/ T
& \8 y" {! }6 r; {4 t// implementation7 W3 ]1 g; D {+ Z8 {4 H
private:+ S' O1 t/ A2 |. A: W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
* L J* C" O; Z5 e6 C+ `: x HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. V& |3 ]* q- o2 \; `
HRESULT __stdcall SearchComplete(LONG nFindData);
+ R* v3 P9 x ` F0 ^% ]1 c7 j+ U/ n* e: T- p/ P
8 k3 N* U. R$ @
private:
9 h( W) x: y" W* f: G CUPnPImplWinServ& m_instance;
8 v1 r- u6 l3 S$ y @ LONG m_lRefCount;
- Y0 K) J4 w- f. s, Q7 Q) R \- Y% x};8 S: T4 n0 a+ f, [: M2 M) V
+ M- d* W L5 l0 @& m* d
" c" x! F1 d. g
// Service Callback
- H& F9 r5 G$ ]) K3 N6 S$ k8 ~class CServiceCallback8 p3 U- S/ j. U
: public IUPnPServiceCallback+ U) |! {! Y5 Y( Q/ r i. t
{! o5 {, ?. P0 R0 p# V+ h
public:
& B. t# }5 C$ B6 s0 V/ I' a S8 [ CServiceCallback(CUPnPImplWinServ& instance)
4 U7 C+ }4 w) u3 I+ d : m_instance( instance ); [/ B/ ]' ^& G4 ]
{ m_lRefCount = 0; }. ?1 c& H- C4 u) N3 j% i
6 \" a; D4 Z ^ t/ U1 D# r; u; V: Z STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" ]; ~, p; q( m; P# T( B5 ^# R
STDMETHODIMP_(ULONG) AddRef();5 U% c& K0 p1 {' y6 x
STDMETHODIMP_(ULONG) Release();
( o6 u1 P& n& [8 x/ Z9 l- ?+ `6 N5 u% e; }* {0 I
" R$ g# l0 T4 D# t% z8 L; _# T
// implementation' W G2 _3 Z, \- }( x+ [/ C5 f& _
private:
* O. [- S3 g3 X' |1 Y% P& |9 T HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);: W- I: o0 d7 t6 N* O
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);8 _2 M7 ~ i- f. l- Z8 X0 ]' h
) f3 ^1 e1 y8 c
5 |5 B; A+ b9 U0 c7 X/ [private:7 _# a$ ~. m! m5 ~, v$ V
CUPnPImplWinServ& m_instance;8 E2 m2 \4 ?5 n
LONG m_lRefCount;0 a$ F$ L: ?5 X
};# I8 b' R; b: Q$ m, c) q" Y3 P) h* Y
( U5 G6 ^$ [4 w* J1 ]0 @0 o
# |. ~: s$ H+ S+ v% g- L/////////////////////////////////////////////////0 Y" Q' k" ]+ R( P
: C/ v' ?) {4 Q, l* }) L) K( F6 Z% M
使用时只需要使用抽象类的接口。
0 ^$ J& n. K5 O. ] M+ X8 CCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
2 o1 _3 J( j# U9 F4 JCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.: [3 P; c, i0 s0 N( s
CUPnPImpl::StopAsyncFind停止设备查找.' b4 \' `; H d& @
CUPnPImpl::DeletePorts删除端口映射. |
|