|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- x2 y9 I7 p- b7 l" G5 N6 h) O8 v
9 p8 J N4 `; { d ^; v
% Z1 A8 J0 c- n8 P///////////////////////////////////////////2 s: u/ H+ C9 U1 g; H
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
5 M4 P% j e" K$ h! D, M5 n+ i
; z1 I; d. N6 {$ O/ Q" b1 H#pragma once' Y4 M" l1 y& d9 C3 [
#include <exception>
1 |- h5 d" g4 z( x
' v( x7 @* l9 j* {: x: L. |4 Y5 o3 Q2 N
enum TRISTATE{$ x6 X2 q+ c- b6 t9 }: w
TRIS_FALSE,
2 K. \% U# q; G TRIS_UNKNOWN,
2 W% [9 Z- C e* k2 q- m TRIS_TRUE
2 W; M& C: y/ t+ y+ e$ G4 Y! h};
8 M- \4 y' Z4 \, J* w
+ f H/ ]7 K# D& O- f$ p. @
2 i! ^& I2 S" ^7 s: benum UPNP_IMPLEMENTATION{
9 l5 [9 D: ?: H' o UPNP_IMPL_WINDOWSERVICE = 0,
* d* G' J4 J5 s% z UPNP_IMPL_MINIUPNPLIB,* X3 X ?& f9 ?* c- v
UPNP_IMPL_NONE /*last*/% [( Z1 O" w- \+ f p6 |% b! e
};& z. R W7 E' L. }% J/ g) j
- b, ~ S+ n! ^' k: R
/ d3 M- q9 U1 `9 @
) ?5 X2 }7 ]6 @! k; m- t3 x) F3 v- Q8 n, R- r9 ]# H
class CUPnPImpl! m+ T" l4 S9 F& O) }
{, K! R3 j3 S6 z6 y* |" q9 [
public:
! h$ J9 k- ]( A0 E CUPnPImpl();) f& k4 @0 n3 a! g* a* h
virtual ~CUPnPImpl();
. T. x0 L e- V8 o struct UPnPError : std::exception {}; o5 T) h; f6 I! Q4 U6 i0 t
enum {
/ _* J$ m" ~8 |" J5 }( ]# H UPNP_OK, |- h( o4 n; p$ `
UPNP_FAILED,
: ~) s/ q, G4 l* }# {+ } UPNP_TIMEOUT
1 e8 P4 n7 N& ? w };; T1 Y# [8 M" S# T# @
5 j. Q0 ^6 H6 P* W: ?- Q3 e1 f+ F, `
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 x2 @+ q+ M; m6 ~4 O) _$ I) M2 |; u virtual bool CheckAndRefresh() = 0;
! j2 M- t6 L; q* Q& K+ k( v virtual void StopAsyncFind() = 0;8 a) A, C" d8 s6 M' F
virtual void DeletePorts() = 0;
, f4 E0 S1 j! h$ h virtual bool IsReady() = 0;
9 c# q5 `$ |* Y: A2 t' g virtual int GetImplementationID() = 0;3 J% \" }5 ` ? X8 k
1 d$ K3 x: J: f2 | void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
! w& M! @/ X6 k; `9 Z: z5 s* \& w5 k: h5 g! J I- i
2 b/ `! o) C* U
void SetMessageOnResult(HWND hWindow, UINT nMessageID);5 N$ C4 H6 Z% H( W
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }3 D, f1 A9 }* K l X
uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 u% t0 r( s K/ u uint16 GetUsedUDPPort() { return m_nUDPPort; }
9 _' i- ^- F: Y' m" R/ n! f& R' ?5 G" g
+ L, p4 g! k1 T8 x: k- V2 x6 R- k( G
// Implementation/ _9 c4 ]! A8 J2 ?2 V. d- I
protected:
0 s% P% L, e. X a volatile TRISTATE m_bUPnPPortsForwarded; C' B7 e- U8 M# z
void SendResultMessage();, M$ A- T% L* I* h
uint16 m_nUDPPort;
; M2 Q1 \6 i0 t% z0 x, U- q0 G uint16 m_nTCPPort;
K7 `0 M7 h5 G7 Q8 @, Q uint16 m_nTCPWebPort;
) D/ l' A! `' ^0 Y9 | bool m_bCheckAndRefresh;
- |3 r; K& K* N( O# P- P# c; J4 n Q0 b3 p
# E" {6 X% V t* U, i% C3 L% lprivate:
) ~/ ~# g& ~) B( c8 x1 A HWND m_hResultMessageWindow;
" y0 i- _2 E+ Z" `* T UINT m_nResultMessageID;! ^' ?. O# U; R6 n3 r/ A* E* Q2 ~
- N6 \6 g5 e" ^( n9 @
/ o- l# s/ Y5 W: o+ y: v};
@% I2 R, ]" O. Z+ G4 f, O
2 y- A. `$ U1 n* Q. t' U% {% M; d1 L! R6 b; u5 s Q
// Dummy Implementation to be used when no other implementation is available5 g: [6 q, L0 V6 Z/ ^) D3 [
class CUPnPImplNone: public CUPnPImpl! b: R- m7 z) ]. }. m+ f; Y- m( ~
{
0 ]6 I: w4 v; j" a; f5 t' b9 Opublic:) x0 l8 C" [- W5 P6 S* O, ~+ x# D
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 K' Q1 k/ P! ~$ c* ~0 f5 i virtual bool CheckAndRefresh() { return false; }* T {& Z- d7 J* h, J
virtual void StopAsyncFind() { }4 \9 N. X* Q" {* b" g; L
virtual void DeletePorts() { }
+ v2 ^$ \ I1 c( D. V- z2 q virtual bool IsReady() { return false; }& K# a. s( o+ N' ~/ T: B5 m
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }5 _2 e/ u( F7 b. S! k
};- t. G8 w# L+ Y9 Q* D" o: b2 Q
. T# n8 W: w. n& c$ \2 J( [' P+ Z
/ I# J4 c6 @& f% ^+ O/////////////////////////////////////
9 j# K1 v I7 J3 u S9 U0 z//下面是使用windows操作系统自带的UPNP功能的子类
# [1 _9 V" U. w- L; N [
+ A, M+ E0 Y! c7 J9 {; L
9 c! j: S f1 k#pragma once& b: W! ^# e; P+ G1 w7 r- `
#pragma warning( disable: 4355 )9 F- o( Q4 {9 s9 h8 N) s- R" L
5 C! m( V: A1 O
0 h7 ?6 m2 n$ j' Y# s& {#include "UPnPImpl.h"% R m$ w* A' K# N0 J9 _! w
#include <upnp.h> N8 J4 { x; V7 F+ G$ F
#include <iphlpapi.h>
# [; I, n$ m1 Y#include <comdef.h>* G& G, U: K8 q5 I3 P- r
#include <winsvc.h>( C+ f2 |8 H# y o) R1 W6 b
' k" B3 `, W, P2 a- Z0 i' U# k9 h0 W1 v
, T/ N* f* f1 M( S' I#include <vector>
4 b2 ?4 T& W% B8 @/ w6 g#include <exception>5 b# A }' F) _" ]7 b
#include <functional>
% b( f" M' z% O( |. N" O# x! V8 E8 G' J- l
( M/ v$ D* v! @& V3 Z* x
! M9 ~9 b+ ?! D1 ]( T& I9 ?
$ g8 q2 D/ } g6 ^* ]" t2 xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;" D, x6 ?$ p/ w) o3 |( u! a. \
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;0 h ?% Z' K& _
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
`% m. d4 m# A$ h" X. {typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
) p9 u2 {+ S' E0 F: htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; Z: k- T6 R7 g, u. a d
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
- b7 M$ n; W$ h3 M9 R; t- jtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
: B- _9 M( t, }. u1 r; p# X# i3 W" {6 `
6 V; g/ I& u' J
typedef DWORD (WINAPI* TGetBestInterface) (5 Y6 U! g5 M1 N. Q
IPAddr dwDestAddr,( ?- v6 }% \# R2 A3 W/ H6 p
PDWORD pdwBestIfIndex1 _6 A5 T3 {2 s/ h' F8 ]
);
) D4 O4 Q" h4 W# K! M& Q/ L, j1 x! S v5 u
' m' e7 E+ M( |- J& Z
typedef DWORD (WINAPI* TGetIpAddrTable) (( P: ]( H1 P- ?3 j
PMIB_IPADDRTABLE pIpAddrTable,; L' l: r2 U8 X# W
PULONG pdwSize,
5 f/ l+ \& z+ w BOOL bOrder
8 S( @" `* ~& e9 o" P);% k' b8 ]/ Q+ ^$ t p. i
% `# ~2 ~' _, [# G: x: A$ Z/ T" { y
typedef DWORD (WINAPI* TGetIfEntry) (
( P4 I6 }4 m' w4 T ] PMIB_IFROW pIfRow
7 O; I' J8 t9 ?8 [9 {( P) E0 e);, ?6 I2 u6 k+ }7 D" _ N0 E" R
2 M% J3 }- z6 @0 \, U+ b' G
6 B, G" k0 y- U1 v* c6 Z- RCString translateUPnPResult(HRESULT hr);! Z: _3 w! Q: K, Z' J0 _
HRESULT UPnPMessage(HRESULT hr);, W6 u G; T# o! V7 M4 f1 k
0 H8 W' W$ Y/ T9 @
+ [. z' h4 U4 b! [5 |" y* nclass CUPnPImplWinServ: public CUPnPImpl& i" ^1 R1 ]2 d& D6 o* O( V
{
0 D6 _) q8 y+ y0 E: m friend class CDeviceFinderCallback;/ T( W8 P% b$ }0 U3 v) K
friend class CServiceCallback;
3 n! w6 z5 m: f. J5 n7 e// Construction
, z4 l% E* q5 n. Qpublic:/ v$ Z1 ~ _+ X8 L
virtual ~CUPnPImplWinServ();0 R+ b* [7 _! }9 V. u5 Q( k! G( H
CUPnPImplWinServ();
$ O6 e8 ^% S `+ o$ ]3 c/ L! ^! s& l
' {' E8 m8 e1 O \: ]
( P3 C' T/ t% f% F( r, ^* J virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
- Y) q5 ~, N2 _9 U' } virtual void StopAsyncFind();8 ^2 L/ o" y- L& Z+ S# | l
virtual void DeletePorts();, p/ t5 u5 v. X; X: \# z
virtual bool IsReady();
* \+ D( j8 d4 U, | virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
% z0 F0 B; t5 b4 o) D- o8 r! |, i
) [3 w. p# ~2 e // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 q* F8 V. ~! p: {- ^' a // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later) r) o! J6 p8 f- j0 i
virtual bool CheckAndRefresh() { return false; };
* p- ]6 n' f- @- X4 y& G* a
& d, N* A4 y0 S; P; i; }6 H3 P9 D* _, ?. ?# G" L9 |, _8 P
protected:
& {3 ~- j* }. M4 ?# u( X4 N void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# D) N/ t. n. T void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);( ]8 K! a* S8 h8 ~* m1 j
void RemoveDevice(CComBSTR bsUDN);
! N) k0 m1 {' r: M bool OnSearchComplete();/ y- `- k5 g$ Q! F
void Init();
4 _' T. x; G8 C. B: `6 r
% J* b; h+ J. w+ k" L% x: c$ `4 p2 ]
9 \# m* X% q. Q) K& n) s" H inline bool IsAsyncFindRunning() Y8 m+ _2 Z1 q# M/ L
{& k2 T2 [; {4 u5 K3 G! C, m6 X
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ), T0 Q* }1 i0 s7 S8 n; V6 i
{
4 h% |! L8 U/ W6 g0 W m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
+ r* T- @0 I# e, F2 T7 K% U m_bAsyncFindRunning = false;1 D3 j0 g; c6 w/ a l f3 R# K
}$ a" [' d3 r) C( L; g3 m, o
MSG msg;
* V9 Q' g1 X5 d) u1 _8 a/ Q) u: O while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )) V9 g- T m! A- M2 l
{, k. y" d4 d; N* X8 s
TranslateMessage( &msg );9 S- r+ P6 k/ o+ @
DispatchMessage( &msg );/ n& L! M3 o" u8 l1 b
}
; `* r% [% s$ Z' s% w return m_bAsyncFindRunning;8 Z4 K# D/ l K
}0 k' f2 }9 x: }; F& T
: L% Q+ d+ \/ A& U
* j( w" @3 }6 m: _ TRISTATE m_bUPnPDeviceConnected;
. ~& I( z( u; L* A+ ~6 C* `8 v
6 l' c9 ~( P+ c! |
]) J F( W/ g" I9 U( Q2 j// Implementation
i3 E2 X0 z- _, A- O/ v3 @ // API functions
N! d9 u- Y' v% a SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
: p- R. ^% X9 A1 @- Q7 u SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
7 R8 R) i5 L* W/ u; Z$ S" l& p BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
" g% b, v5 u' U) ~, T* F BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% r4 q5 W, P/ K% g" c; F, X0 S
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
* I/ w7 ?: c* W6 @1 E BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);. L5 a$ n3 T0 l9 ~, T# v
9 l. L$ Q$ a3 A# V4 i- b6 ~' n; m
8 X. H9 Q# @. V0 J1 U. b
TGetBestInterface m_pfGetBestInterface;3 G c2 w: b0 i1 |: F2 M F
TGetIpAddrTable m_pfGetIpAddrTable; z# N* p& R& U
TGetIfEntry m_pfGetIfEntry;
( W. r$ ]3 R3 b$ T% h/ G' f4 B; g5 }; X4 p$ B1 S; g
0 w( K1 U# d' G0 @& }6 f3 S5 g
static FinderPointer CreateFinderInstance();' ]) _+ ? d$ p
struct FindDevice : std::unary_function< DevicePointer, bool >. g3 u" e3 u# }' ^1 O1 V0 C% E$ o9 _
{
0 d4 q; _7 F h- B6 n+ N FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
: }6 S7 U; e" I% [& l1 F result_type operator()(argument_type device) const& u: y5 v* c2 z( D
{; U* n5 X$ X4 x4 V+ {6 D3 {
CComBSTR deviceName;$ C# [& r9 C: f8 L% u2 ]
HRESULT hr = device->get_UniqueDeviceName( &deviceName );) V+ Q( ]- B; U% D
0 p D6 \& ]1 W- |4 U8 L) \0 V3 d* A& G
if ( FAILED( hr ) )
" G9 V. @2 F* f8 I- `) U return UPnPMessage( hr ), false;
6 v0 ?7 c8 M% G0 A$ d6 o7 I" V- x. G7 d: c: i& h
0 Y& w' M O6 m: A
return wcscmp( deviceName.m_str, m_udn ) == 0; R4 d3 ^* }( _0 J/ W! l* `
}2 x. L9 [. j+ h) C/ |( D7 o
CComBSTR m_udn;) r [: u/ ?( q4 }& E; Z
};( d) d: D% G% v) @& _5 u$ D) j
; q# Z; R. M0 z8 P5 Y5 p
void ProcessAsyncFind(CComBSTR bsSearchType); Q2 A) P! h7 C1 f2 Z! ]
HRESULT GetDeviceServices(DevicePointer pDevice);
1 b/ o( e: Y! k5 s void StartPortMapping();2 Y( N' U" H0 @1 C+ I
HRESULT MapPort(const ServicePointer& service);* R! Q2 `9 _6 K
void DeleteExistingPortMappings(ServicePointer pService);8 e4 R& C4 L! Q6 z4 G' A
void CreatePortMappings(ServicePointer pService);$ C( A h" ]+ k3 T( D& Z) T4 r
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
% D8 D9 _# z! r6 G' M* z7 E$ O HRESULT InvokeAction(ServicePointer pService, CComBSTR action, , ]+ |/ r/ {' D6 |
LPCTSTR pszInArgString, CString& strResult);% k; E) \4 v4 H- C
void StopUPnPService();$ s; U7 e4 p. F$ s0 ?0 E- ^
4 D- R9 l% T5 b! z2 Y& N8 r3 N
6 l: z2 x, n( v! a1 m0 w+ u# D // Utility functions
% _+ k) N: \6 ]" y& y HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa); Y7 G! T1 {( B% i( }! h# ]+ g2 J
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);- `9 Q( }* w8 v/ }& }
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
6 j' k0 s$ [4 e3 m& {6 ]. X6 c void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);- X2 D6 ]2 a; u* {8 C7 J4 `7 a
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
2 j) [/ W1 }0 u9 [ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
$ M/ B7 l! o p: O: |: ] CString GetLocalRoutableIP(ServicePointer pService);
f4 }, \9 e3 l( R# U- z7 x$ ]: }% U9 c
" a1 o9 C5 |7 s" M$ e+ y/ I// Private members6 f& o, o. j) T7 c. M& p6 i& I' B. b
private:; E9 w9 q4 G, a. U1 b, [" k$ T
DWORD m_tLastEvent; // When the last event was received?
) e. |' e( N# _9 y std::vector< DevicePointer > m_pDevices;2 j |4 w0 ~9 M* B) n
std::vector< ServicePointer > m_pServices;
, g, u% O0 j+ }: _3 G! A4 Z FinderPointer m_pDeviceFinder;0 Y- x! S4 K8 k7 T6 |- H- \4 u2 T9 U
DeviceFinderCallback m_pDeviceFinderCallback;
. @! Y: o4 Z' q6 w& Z( _# H# N! q) r ServiceCallback m_pServiceCallback;& g+ s( U C4 @
8 u) x3 d1 \' w0 d1 U
: P: r& _$ g3 ?! H LONG m_nAsyncFindHandle;! j+ J0 j4 u$ ^* ]- N- q
bool m_bCOM;, R9 }- t) p G* N
bool m_bPortIsFree;0 k7 W" W4 l1 t; l. Q8 U7 U' W
CString m_sLocalIP;4 [7 ^- y" Y8 M' G7 _" F+ l
CString m_sExternalIP;
2 n$ s9 ]' E4 y) b* [7 n bool m_bADSL; // Is the device ADSL?) k# j% X% Y8 `5 y
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 m+ R& @6 u& C, c bool m_bInited;) s( R; t; |: H- i6 E
bool m_bAsyncFindRunning;# }: r4 W3 R3 p o# ]
HMODULE m_hADVAPI32_DLL;
~* _" Z& l9 H: D3 h S1 t HMODULE m_hIPHLPAPI_DLL;
6 q. Y+ Y- @+ \8 K! c( B bool m_bSecondTry;
6 E- X9 \! n7 u) F" V E3 k bool m_bServiceStartedByEmule;
9 z5 ?) m' |5 q# c, B) _' T bool m_bDisableWANIPSetup;6 ]' f# F. r) Y# X ?' R& g& k
bool m_bDisableWANPPPSetup;
g1 k# u* U) p0 W% [
8 B9 `1 Z: a( L: }5 g
; W7 J9 j( p, O% T: _+ _};
^7 V3 }: Y; [+ Q" ^. ]0 s; ^
$ T1 P% L# }% p( Z- v( v
$ ~6 s2 A2 A# ]& Z8 b: c// DeviceFinder Callback3 r6 J; G% B& W6 n5 u' r* X
class CDeviceFinderCallback O( T' b9 J+ A
: public IUPnPDeviceFinderCallback: z0 Z! K& f+ b
{( c' v9 V; k; k- C/ }" S! P
public:( Q6 H1 o. Q& G$ |5 q: S3 E$ d
CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ R0 Q( ]- Y8 U( I/ V d a, O : m_instance( instance )
6 ~' d, f( L9 {" _8 K1 n/ ^ { m_lRefCount = 0; }4 l; z0 o3 [" }4 V# h' \, Z
% v1 t8 L" s' j; }3 g Q5 a
# A+ w, q; @7 [. ? STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);9 |( \' ]/ K; ]# g$ M$ [
STDMETHODIMP_(ULONG) AddRef();
: A- @' r! T4 d% X6 ~& i STDMETHODIMP_(ULONG) Release();& L6 z- q4 R0 a( }
) ?0 l# Y$ P5 h& Q4 \' R6 E+ s, t ?7 W7 M" v# Z* w' J8 f
// implementation
" C4 h6 S7 Q# gprivate:
4 N4 @' V9 V" }: x* N/ G+ F HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
9 c' l6 \$ Y8 k- F# [; Q. u/ Y$ y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);( T# z; A2 D) d! P6 Q* M8 K7 _
HRESULT __stdcall SearchComplete(LONG nFindData);1 V ^! F$ m3 O: b# a$ z& f$ @' V
' h$ [( s9 K5 q3 M/ l) N2 E! D
1 H" v4 V, I* E0 lprivate:8 v6 J" L. Q& b' B
CUPnPImplWinServ& m_instance;2 U1 F5 t) K" b3 v8 t
LONG m_lRefCount;! v% F) a8 N, R& g) n- p
};6 H8 H E! Y( s9 P
( s" o5 L8 T" a
' H% |+ j; v& D& _+ i* {- ^// Service Callback
" I! m1 ?: I" h" k1 Q1 x( xclass CServiceCallback( l4 @! @$ j) {. r
: public IUPnPServiceCallback e G O3 ?4 i
{
( A7 g0 F& g, p1 M9 H# i; a f7 mpublic:
) i4 R" S8 Y7 d4 G3 ^ CServiceCallback(CUPnPImplWinServ& instance)
+ n; i3 w6 R% f% C3 f: u$ b : m_instance( instance )( x4 K# M. {- [
{ m_lRefCount = 0; }
. B3 C, k- k z- W: S, V( Y" J , c! d* o- j" z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 N$ c: z8 {1 X A/ W( b
STDMETHODIMP_(ULONG) AddRef();: _1 K& w5 S) E; t$ c" }
STDMETHODIMP_(ULONG) Release();
( W( H: E6 b: U% V3 X- C! Y/ w+ \: Q' E x( E0 |
9 _8 l5 C( ]1 I2 t- x: ~* ?. Q
// implementation b$ [8 D% Y( h4 E2 p
private:) {& f: G% o& W: j0 Z# Y
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);2 m" K! J _7 n
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& d5 G. c2 p8 ~9 I9 r) @7 i
5 e( k6 N( m+ v' R7 c/ T
# q. S" y; y c* e' R6 T( [. Oprivate:
; U/ t' F5 ~5 z$ ] CUPnPImplWinServ& m_instance;5 B9 u! F7 z; @% e- F2 |( V0 y
LONG m_lRefCount;4 H9 s1 L# ^; X9 Q
};
; w F3 B" u/ h. K |; J" _6 x# ]: j- l) j
) b/ X; D& [4 l
/////////////////////////////////////////////////
# l7 P* p) V& [0 w$ }! ?, V+ p& A* i% X% q; I1 j4 j
9 ~+ j/ B7 ]% W( O z/ K) V" U使用时只需要使用抽象类的接口。
% Z, n) U- r# P9 L# t4 ?9 t/ QCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.# {5 q4 h% Z2 d# Q$ u
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.( E2 i' e& y; b$ I7 b9 A. W
CUPnPImpl::StopAsyncFind停止设备查找.$ A. j/ @8 M7 x5 \) s: g
CUPnPImpl::DeletePorts删除端口映射. |
|