|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 h+ U; U5 e3 u$ ~- t
; }; F% I& [, Z) E* v9 L
+ k9 B- C( P% H, J8 B5 c) ~///////////////////////////////////////////
5 u$ y* T+ \5 _//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- Q% f i9 }: K. k
* M+ m+ ~- a5 F% g* ?0 D; x' W' @+ r) S [6 a
#pragma once
& @. ?( s1 @: w#include <exception>
% \ x" T @& e0 r2 z
( U4 o: [2 b% F- z0 t+ i1 K; `
; d) H( _, ?: }( C7 ~5 W enum TRISTATE{
) e+ ^: E$ m2 g TRIS_FALSE,2 A+ K. n' Z% g( M2 T* ~+ p
TRIS_UNKNOWN,3 I P/ ]+ D3 E X: j3 G) {( O
TRIS_TRUE
- p" N+ b, G+ ^4 g% Z# R; ]' o};
( V, X! B% j# ?- Y/ @2 {( ~$ R' v2 `# E# ^; Y5 ?3 K& u# @4 V
) ]5 e [9 Z n7 z/ ` jenum UPNP_IMPLEMENTATION{
/ |' A, g1 m$ m; ]3 ~! N& g! b UPNP_IMPL_WINDOWSERVICE = 0,8 q- H4 s$ z5 P8 Z' l
UPNP_IMPL_MINIUPNPLIB,
- m$ p. Q2 o$ P+ w# \ UPNP_IMPL_NONE /*last*/: e5 F/ J9 @+ g `8 k' Q
};) A& Q% B( e6 g& l
+ a, e) y) I0 X0 l5 r% u) u! s
! D. j/ h: N# H, g. Q: Q4 q7 |. |# s6 l& q% w. \
3 z+ ]- E a; p# j4 Oclass CUPnPImpl
& K4 R$ H! O' ~) h; ?. y& j{
1 @4 V+ W4 R/ }public:
! ~9 H9 O3 ^+ C. Q8 R+ B CUPnPImpl();: P2 A6 G+ S8 y6 i
virtual ~CUPnPImpl();
' o$ d* \+ H w struct UPnPError : std::exception {};! b0 i4 R# j: o. o1 w
enum {
; V Z. b& ]3 _1 ?5 m. w' U6 Z UPNP_OK,
4 W. F) R! b6 r6 f3 I) ^ UPNP_FAILED,
% @& N- d8 Y6 }. F/ w% e UPNP_TIMEOUT
+ J1 V. T! a% M+ i1 \# { };% F( w# U( H3 B& R. X- F: ]
% t; s" u) R5 |8 b/ m
- O& C4 i, X6 H% A5 V& @
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 O0 Y. G. b2 v- C$ f3 P A virtual bool CheckAndRefresh() = 0;7 k2 ~, X+ u: X% W. x$ C
virtual void StopAsyncFind() = 0;
% t/ Y3 Z, R# K& j" o' Y virtual void DeletePorts() = 0;
: ~0 ^/ e0 x- V' g7 W virtual bool IsReady() = 0;
9 s1 `4 m B q9 G& V e5 S virtual int GetImplementationID() = 0;
7 P* o9 X" t! X8 {6 D) |( c
7 G( \& e3 z- x/ ~% t8 j& |% H void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping m6 u) @; p& Y
7 b4 m8 s! e% Z% m0 T
3 J# w7 h1 W* O% G/ l1 ~+ W) \+ C
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
" q1 n. J* V) U, |3 r: d2 V TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
2 W& {) V/ z" M* P+ I6 V uint16 GetUsedTCPPort() { return m_nTCPPort; }
- c6 _: j1 \* h/ h3 J5 R" h uint16 GetUsedUDPPort() { return m_nUDPPort; } ) P4 d3 {& B" M, ]0 k, H/ @# P5 ~
" d. J. L8 G2 d2 L8 i
. m3 K$ b% m0 }! @2 j' L* b0 [// Implementation
5 A+ O/ V% ]( [7 O5 @3 N; iprotected:
3 f/ y) ?- n* v+ d; V volatile TRISTATE m_bUPnPPortsForwarded;
9 D5 T& m$ |# G& U' E* { void SendResultMessage();
, n* ?" M8 o/ S; d$ s uint16 m_nUDPPort;9 k. |2 f" z( F& J
uint16 m_nTCPPort;
: T r1 }: \6 f2 K' f/ A4 N uint16 m_nTCPWebPort;
7 V+ g/ v7 W9 q* p. w w0 R& _ bool m_bCheckAndRefresh;
1 O& s3 w) k1 k
$ L- c. R6 Q; x$ I; }2 p' b
8 ~/ x, [% o. I* eprivate:% t X% s4 A1 \; C9 r+ U
HWND m_hResultMessageWindow;
( ]- {- Y3 o$ g. x UINT m_nResultMessageID;: R# S2 v. M; f2 q
, [3 F }& j. A
2 Y$ y v1 {6 r# W* W};/ N0 e. m6 ?( M2 }* k3 v
" A" `/ s9 Q2 S2 ^; z
' t* w6 \! J! M9 m. @! U, H5 x// Dummy Implementation to be used when no other implementation is available
9 C' r, c7 M+ a( B! Zclass CUPnPImplNone: public CUPnPImpl
' P& W D+ I9 |% e5 g{5 V" Z2 t0 |4 C2 u
public:+ T2 j ]5 ~+ N2 ?
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }2 L$ R* b. C2 |' s- ?
virtual bool CheckAndRefresh() { return false; }
9 e. K; f. d; D/ s' G virtual void StopAsyncFind() { }
' f2 Y7 B' P O2 I" Z; P virtual void DeletePorts() { }
8 e* X2 H9 o) a* R8 { virtual bool IsReady() { return false; }
: |% z3 \- \9 I/ a- o$ Y virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) I, @/ ?( P* Z8 d0 R; z
};
+ S/ ?! R1 `: m1 X% }
9 G7 s Q5 D: x' t2 E) N
2 n( A+ `" t }4 S8 ]/////////////////////////////////////' n+ ]& O' H1 V+ a
//下面是使用windows操作系统自带的UPNP功能的子类
/ s+ s+ @7 S3 D( `5 Q: |) Q
' K2 l! k8 O! P1 J& Q' H7 z' |- i6 j, L& x
#pragma once
+ w& a' M' t$ D8 R: `- H#pragma warning( disable: 4355 )- T6 J. G# v5 ~' W% @; }
7 W" D5 J p$ q2 V. r0 @. |" Y/ k* s6 C: l$ g* u5 Q
#include "UPnPImpl.h"
" I$ p L1 F& U. d0 t! c- ~#include <upnp.h>
' S H! S4 Y" O/ a1 h#include <iphlpapi.h>
, H" T& j" f$ |! o- B& K& `#include <comdef.h>
: t' ^+ w" u- g2 G#include <winsvc.h>- P2 y( `: f* @" o; S
* q' V+ ^1 @: g+ m% O% n# Z2 I4 Z, S6 z5 W5 S8 k
#include <vector>
1 l9 E5 e, ]! V/ H5 a#include <exception>. p- n* M2 F, \- d; {5 a( j
#include <functional>
: @. |* [. k: r7 Y2 G4 v S) _3 Q& \$ H7 N! N" r9 H
$ i8 |3 A/ o" N
' i7 v+ O$ C7 m+ e
7 Y) [, [& _7 e; H$ ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;! j% U3 U9 ?* _
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
; s; p5 E9 u0 s' ltypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' r# ^% P I0 Ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! G( X3 A& l. v; b2 A8 U4 T5 S# x7 q! k
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 ?6 x6 q9 _: U1 j3 Q" F
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;; S0 c/ `! d, U- q( u0 E
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
$ }% j& _# ^/ b( `9 L& ~6 P: H; ]/ R: d5 b, f
6 O4 ^3 G2 H4 m+ s# {) d2 o: X! @9 otypedef DWORD (WINAPI* TGetBestInterface) (
( I# g9 G+ u' O% D0 h- w( | IPAddr dwDestAddr,4 z2 H8 _; j3 O Y5 q3 z% p- g i
PDWORD pdwBestIfIndex; z! [, r+ X* p5 E: Z
);3 y. w" v( T( O: d+ Y/ p
% i* q: h/ l2 D c4 I! x
, d+ L7 i, H# Y$ z9 j% } utypedef DWORD (WINAPI* TGetIpAddrTable) (
# p! D5 [5 ?- @% R% k; X PMIB_IPADDRTABLE pIpAddrTable,
. u O. ]! u6 G4 c; {% l( n PULONG pdwSize,
4 e; U/ F2 @5 o$ ?- W$ {9 e o BOOL bOrder
) u# l8 x, n4 e: r$ j: Q+ h);
1 l# j" `2 o& [0 H8 v9 x$ c/ h8 w! V5 E, w$ o) b
/ A7 N% t( W$ g7 T8 c6 J4 W6 wtypedef DWORD (WINAPI* TGetIfEntry) (6 H, L2 O4 W( M. F6 e% S
PMIB_IFROW pIfRow8 G% E# _7 I% g* F
);
% ~+ B _) j+ ?
3 J2 e! G0 p! [; x; c/ w" K2 l
$ _: e: I4 T1 O ~1 ^" \4 BCString translateUPnPResult(HRESULT hr);! V4 S; j3 E+ s( ~
HRESULT UPnPMessage(HRESULT hr);
/ p$ e$ z2 y; G3 K1 E. ~) q# f- N" G5 \& ]/ B% x3 r" ^: ^
9 [: ~* {2 J! z8 \! K% aclass CUPnPImplWinServ: public CUPnPImpl
4 B' ` w& f2 \$ k* {' Q# ]{9 e. ]1 V, O2 \
friend class CDeviceFinderCallback;
0 s3 G4 |5 f+ z* V' t, k friend class CServiceCallback;
) M7 F: V) _. }8 h% w0 M, |2 n// Construction
( M S. `* w: ^+ ?" Kpublic:: {) m: a& d+ J& _3 e
virtual ~CUPnPImplWinServ();
9 M& H7 V1 _. ^) l CUPnPImplWinServ();& E4 Q6 q Y) C$ @
. K& B- i) e" E; H
5 ?4 N2 h8 h0 z7 U. q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }- }* n* O) p7 r8 r2 v
virtual void StopAsyncFind();% u# _4 o0 P+ ?2 a
virtual void DeletePorts();
0 l/ b2 c K# W8 D$ o! T$ A virtual bool IsReady();
9 q% i7 T9 Q# N virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
' Q% a" [) p! F" b: h% w
+ L% f# [. L# p" o/ ?3 g' h; h5 h: g/ Q1 X `2 W5 Z$ B$ Y E6 _+ s5 Y
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- L7 }! x# O' G3 d, | // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; q. V) H3 i9 K8 d: q$ h5 K8 C9 g virtual bool CheckAndRefresh() { return false; };
0 J6 Q4 z/ Q* T, {2 ~- K! q- d' Z8 I$ R ?
`( D& y( A+ S$ `
protected:
4 g/ c1 E$ Q+ A) l' A void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);% k( e& Z2 i# r' v3 h$ Y0 P
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);/ G7 e6 N3 W1 [2 q' x& ?7 _4 e
void RemoveDevice(CComBSTR bsUDN);8 P4 f7 Y' F7 d; q7 F: d/ [
bool OnSearchComplete();
% V2 u% W$ d6 S+ |. S9 w) U; E void Init();& a, k& X& _ s/ Y# n
) t' t! Y; |; r6 `+ C* B! e
8 e" K' Q4 u8 q& g6 B) H$ E inline bool IsAsyncFindRunning()
! y8 H3 D" R/ x* s* K6 |6 V2 h {
. m7 o3 ` a" C7 {% j if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )& D7 Z. }. H; g
{3 _5 J c, O+ m
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );; M/ Z0 L4 o. y0 @1 B
m_bAsyncFindRunning = false;. m( e! @) x. A- X, x) Y& t& Z
}: M, S" O" x& e5 j1 ~
MSG msg;7 I5 o F8 i4 u* J6 L$ K& r
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 S& O0 ?; e* v' z: \
{
X5 Z6 G% }% n, Z& M" x' a TranslateMessage( &msg );
! V" a9 D: ^ v3 C DispatchMessage( &msg );. I5 `# S: u. U) ?, Q, B# A( c& @2 O; ^( u
}* Y( z+ R1 r N
return m_bAsyncFindRunning;
: ]' S$ Q' Y+ K+ R s9 d g }
4 ^/ V/ _- }, W. v) B/ }
* S$ x9 D. L& n. J; h5 u
9 x; r+ v7 B9 E0 b1 i TRISTATE m_bUPnPDeviceConnected;* Y6 g H0 Z0 L1 }! G2 g4 k
; x$ _$ `4 L0 a1 b
/ x* S ^5 {( \, \8 D- O* b// Implementation7 Y3 H1 p( j, x$ P0 v& p
// API functions
- y4 ^! @+ B9 V( Q SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
+ e6 Z, v1 D0 D9 s- a: ] SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
E( \$ B2 n, W7 [* l9 |2 c BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); X: A4 \1 h! }; t
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);& L% {: ~; O5 m: Z7 j/ U
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);3 Z& d/ m4 U/ h- U
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! m" S: W. L& p4 Q H( s2 k O% m8 j& X/ q% v& k0 Y
# s; ]2 v. ~' C- k: p7 {# H TGetBestInterface m_pfGetBestInterface;. h+ {/ o+ C* x. S [" H
TGetIpAddrTable m_pfGetIpAddrTable;5 x0 f7 S, K; | w" m; W8 C
TGetIfEntry m_pfGetIfEntry;
" h* {* e, u: H I3 I
4 q' W# q u( t& D* I9 u6 h! ^1 [* J% t2 q w$ Y( ?8 Y
static FinderPointer CreateFinderInstance();. x; Y n5 T) Z
struct FindDevice : std::unary_function< DevicePointer, bool >
3 @/ q9 a- J' T7 g5 d& [: k {! h: D' q4 y: J* w! k: e
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}! s3 ^6 h+ g1 i3 z5 e7 F
result_type operator()(argument_type device) const
. W8 }& q$ J5 C/ _' D9 }6 G" o* ]% b {' I9 ]* b+ L# L3 T& b2 c* Z
CComBSTR deviceName;& R0 j1 @: }( f+ m+ w! h
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
; M! x% x$ {4 D* f) A$ b+ L, q( Z' L* O0 p+ w. Z/ R/ S' M; G, I- P
( ]2 e! Y9 C# |! F6 g0 a6 { if ( FAILED( hr ) )' }! R7 b$ A, t5 P- X) d5 V9 @) Q
return UPnPMessage( hr ), false;& @) p# ?9 K/ R( U
: v3 G7 w S D/ ~" O
: x1 O3 x7 S7 k) D3 \9 k return wcscmp( deviceName.m_str, m_udn ) == 0;* ?4 W [: [! K& U6 K/ s( ?
}5 x4 C% |" n! k: `; x! \5 T4 H
CComBSTR m_udn;9 s/ A) e/ u/ v8 U- X
};
" s; d- S% t' v! B
* E1 S# e: U3 t. P0 f* [ void ProcessAsyncFind(CComBSTR bsSearchType);" J) \5 W' }* d9 ]2 G
HRESULT GetDeviceServices(DevicePointer pDevice);
. B& P4 e4 m4 x$ X$ K, u' L% Y void StartPortMapping();
, G/ y, m9 X2 k! _7 g+ D9 m5 R P* W HRESULT MapPort(const ServicePointer& service);1 |$ q V3 k5 g# L# t9 c: n
void DeleteExistingPortMappings(ServicePointer pService);/ h+ B1 a# }2 o
void CreatePortMappings(ServicePointer pService);
" t: y5 ?: p/ s! _4 b$ b! o HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);5 a* l8 B% p% u* h3 v4 N& W
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, d" N+ F: s% K' D3 y; x2 R LPCTSTR pszInArgString, CString& strResult);% i( z0 i: o% Y7 d2 i
void StopUPnPService();/ P- }1 R$ i& d# H$ W+ U
, w! w- w8 @! h2 q4 {
1 \* Z: w7 z0 W# ` ] // Utility functions
; Z8 v9 v p- C: S2 a/ z& I HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
3 B- c1 e' Y# R4 x. L3 Q+ V INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);/ ~6 `" x: m; D" q- E$ s) v& }7 v
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
& H T& E9 q7 r4 S4 S ~" e void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) v( I1 A. M9 w! R. g' P HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
" Y' d" F1 L4 B; K! v HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
0 N& R, J6 j9 D1 |7 ` CString GetLocalRoutableIP(ServicePointer pService);: Z9 C1 b, E# D; x6 g8 u0 E; u- I. b
7 w( I: z% w8 _' Y; |- K" u
6 d* U) Z0 Z- Q3 \1 V// Private members8 h- }: X7 _+ H' u ~4 R; K
private:
- R+ p, G" b: x/ M DWORD m_tLastEvent; // When the last event was received?
" d2 B7 V6 k, t std::vector< DevicePointer > m_pDevices;$ n/ C$ h1 m" K+ v1 @" C; a
std::vector< ServicePointer > m_pServices;
$ ^ n- ]: F5 ? b" f- h FinderPointer m_pDeviceFinder;
5 [6 e2 u3 {- u1 q) z0 l% e& e DeviceFinderCallback m_pDeviceFinderCallback;
/ m( y' R$ ~. Z) \ ServiceCallback m_pServiceCallback;
! x) D! `; m& A) j6 _) |7 @2 c% ]4 r* J. l" q
& `! b6 U# H. ?" u" k5 `- Q LONG m_nAsyncFindHandle;( h+ s3 L5 ^; v4 C! w1 o4 E) p s
bool m_bCOM;0 l! y6 ^, k2 `. ~: D; J
bool m_bPortIsFree;+ Q; ]; c+ w# X6 E" a6 T
CString m_sLocalIP;
' C- L: R$ I9 A( _; K3 V$ ^ CString m_sExternalIP; O2 L) e* ?6 z6 y
bool m_bADSL; // Is the device ADSL?# Z8 X9 Z9 a, q* y; D
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?6 \" }" c/ Z4 x* l+ }. q
bool m_bInited;
# P' {4 D H5 F* \; N bool m_bAsyncFindRunning;5 M o. s+ i3 s1 {0 A, w
HMODULE m_hADVAPI32_DLL;$ p9 m# r) Q ]0 h
HMODULE m_hIPHLPAPI_DLL;
( ~! B2 z; F. E1 ] bool m_bSecondTry;
- W: c# @1 d! P; D7 }/ P bool m_bServiceStartedByEmule;& h( i+ I$ P5 S! C% N- ^
bool m_bDisableWANIPSetup;
& U/ k8 L) q& B+ c c: e* H: Z% w4 K bool m_bDisableWANPPPSetup;
6 K/ `6 e v8 g3 t9 s- r% R, ` J" T8 |
# O. D x3 n ^5 N0 K( l8 A
};
+ G _3 o* s3 T0 c, e7 r
4 g+ D* z9 f7 s- Y9 C' i" k$ L( d
// DeviceFinder Callback
8 w$ z* X* B. V+ ^& Dclass CDeviceFinderCallback m/ A& ~ ?5 ?' H4 V: o$ X" a
: public IUPnPDeviceFinderCallback8 L: L, V S+ K: L2 ?+ s
{5 e' a8 h6 s, A% E$ L0 Y* P
public:) {, ]' m( F$ u1 d4 v+ j
CDeviceFinderCallback(CUPnPImplWinServ& instance)4 ^! ]8 W, ^( `& {! T; [
: m_instance( instance )
4 E4 G3 I: w6 ~1 d* S { m_lRefCount = 0; }$ H. ^& E" ~( j& f8 z) c3 G
, c6 Q! @) G4 }
1 n& `; w- Y8 `4 ^! ?! q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# F6 A9 q K; J STDMETHODIMP_(ULONG) AddRef();
) }' [' m5 B* ?; M8 E& L STDMETHODIMP_(ULONG) Release();5 ~1 b4 D& i( g u7 ]8 G
4 U4 S' D( c9 f+ W
0 H7 x8 P+ T8 N$ r, S
// implementation
$ a- Z# b! ~ k) P5 n, F+ n- u% @private:2 v$ |' q& h* C
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
0 a6 ]6 O4 b0 y3 ~& e HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
' T C% I8 j+ X$ E; e HRESULT __stdcall SearchComplete(LONG nFindData);
8 r2 P" u U2 c- ^# I3 o/ I2 V$ C
' s& w( R# }2 @1 O$ xprivate:
' F4 n1 W9 x2 e0 _- s0 O CUPnPImplWinServ& m_instance;8 b/ h2 X0 q3 W& d! H8 b* }
LONG m_lRefCount;
1 m; j, ~( l F};
% c+ Y0 a: u$ K
' N2 y+ }3 ^" }2 y t2 k: k2 s
0 a# o) H" S" e v. q& R// Service Callback v; G& z; A, ~
class CServiceCallback
3 v l# u6 C/ B! g, R# R : public IUPnPServiceCallback
: k( e8 B7 I, ^; ~{9 w! h) }: A/ _$ ~( b( o- ^& j; B
public:
6 z' z9 e8 j. R% ^6 j/ h3 k CServiceCallback(CUPnPImplWinServ& instance)% L% ~' v: U1 z# E
: m_instance( instance )
! ]) w3 b9 {. l { m_lRefCount = 0; }' c2 o& d4 Q; o2 t" t! J& P
" R$ j* [2 c0 _" [: r3 b0 [! @' e7 I
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% e5 L5 U* j- c STDMETHODIMP_(ULONG) AddRef();
1 L# C+ _& h) X8 ~: ]; n+ z STDMETHODIMP_(ULONG) Release(); [- b( P' o! h# M
& M1 E; Z' |/ }# m9 ?- b( C0 k' V) Q# n) D0 j" V
// implementation
+ ~! l, {" n2 K+ `private:
- E D5 X4 v7 g' ~9 Q7 Q HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 B) T# T* J6 E HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
& b0 l/ w: }# n3 R+ S3 W, L' @+ B5 X
+ h. n3 ?6 s" r6 ?) Z m
private:
% u7 I3 G, A" W( Q W4 ^; r CUPnPImplWinServ& m_instance;2 E0 f9 b6 W& U+ }; [/ _3 W; Q
LONG m_lRefCount;2 }) _3 M& M/ d: s/ r: B
};- p- c, p6 e1 h# f' \9 U! }' b& i
6 R# T, _* x2 b" b
3 J+ _7 I0 j' }3 m1 W! ~1 H/ }4 i/////////////////////////////////////////////////! n- ?2 q; x( w! {
$ V0 k4 E4 E5 i
6 ]2 H2 y3 G# L/ U9 P: s
使用时只需要使用抽象类的接口。
3 \! D( D; k9 I* Q, j1 t* T# {7 aCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 X3 p* [3 R w& F, H, K# H! ICUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
4 c. t/ `3 Q3 S/ {, RCUPnPImpl::StopAsyncFind停止设备查找.; a8 W' v( R! c8 s
CUPnPImpl::DeletePorts删除端口映射. |
|