|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,# `4 A2 B5 C* q8 n# E$ d. n
4 ?" c" B# C( i5 `
/ `( @3 Z, t' d3 H3 I" F9 d///////////////////////////////////////////
+ B: z! [0 P }7 c) j1 ]+ O" o( E//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
% q3 e* F a9 c+ b ~* ^
: @0 F% S6 C! [# v
, C, P" J+ _$ v) @; h1 M* @#pragma once
3 y2 \" L9 K+ |/ r0 ~& m#include <exception> o s. u$ ]6 V& s5 W q
9 x. E" q6 N) }% K; e9 x" [" e0 T: d* g& L1 E
enum TRISTATE{
/ a" G) A' Z" I( n TRIS_FALSE,1 ~! N1 K7 a, M
TRIS_UNKNOWN,; a# E3 _3 b, {
TRIS_TRUE
6 `$ ]" f+ R- _7 n0 {};) k9 e! }; Y, B* H4 \1 o
6 m8 ^$ w- ]6 ~. S$ B% b. z
# R+ N$ \& H" x: u9 benum UPNP_IMPLEMENTATION{
* s* R- p+ g7 }4 K UPNP_IMPL_WINDOWSERVICE = 0,
6 u, |. d. ^- d6 b UPNP_IMPL_MINIUPNPLIB,
6 W" P1 f' T5 a, x& _' P UPNP_IMPL_NONE /*last*/1 M* ?( p% M+ ~- b" E2 I$ |1 R! s
};
h: r& L% h" T. x' F5 P8 I( ]1 E% Z+ s5 I U8 {
% P/ I9 M" }6 S. s( I& k4 A9 _, v2 R
1 }$ E3 j" V) A
class CUPnPImpl7 R- \1 P. @" g* v+ E, g5 f
{& Q. A. o: L, U, V3 R- m3 |
public:( d- M$ I6 G4 }7 `) R \
CUPnPImpl();3 Q9 T' n8 ?" c: ~9 M8 J4 I1 J8 X; R x
virtual ~CUPnPImpl();
) ?8 \7 B# ~7 N; h+ Z struct UPnPError : std::exception {};* F" T7 b8 r: M1 N
enum {
, p, a- M+ `/ D7 ^( Z0 K1 h UPNP_OK,' t$ u' q2 F/ A9 T9 F/ `! T, j
UPNP_FAILED,
; r R$ _8 ?, l UPNP_TIMEOUT( `; e7 O9 \) ^+ n& Z: r9 H
};
. }* a( f7 }0 a. o; d; c- s0 i6 L. d! O D7 Q( S, |
8 F' y! i) E- w virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;0 f* ~2 z" d& v) y5 c
virtual bool CheckAndRefresh() = 0;7 \7 t9 h6 H# X3 @: E& g7 [1 q
virtual void StopAsyncFind() = 0;# d H- N3 w, b$ q
virtual void DeletePorts() = 0;
& Y( B, f" f# a virtual bool IsReady() = 0;$ e/ D9 a/ o# T( G9 O) e% U
virtual int GetImplementationID() = 0;
7 }( m$ b5 t$ E; N- |: N A4 C; h " \1 E. w5 _0 {; A. m; B
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
9 a/ ? i. N1 g% s; R n; z: K
7 {& H2 j U0 ], H) W
7 E0 l& q) \6 k- n! I' u void SetMessageOnResult(HWND hWindow, UINT nMessageID);; o% U6 D! y/ w* ~' S) ^$ k0 ^0 F
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* e3 @* X* m$ m uint16 GetUsedTCPPort() { return m_nTCPPort; }
8 j3 s- `6 N! E uint16 GetUsedUDPPort() { return m_nUDPPort; }
$ x, {; Q' L; o* ?! v( U# F& F
9 D0 F. C# a$ d: U0 o7 O: Q- e# K" o* h5 g7 o# Y* a
// Implementation
2 i3 Z, E' Z+ X/ J6 _: n. J1 ?protected:2 o) m$ L3 \/ @$ u3 ~ M
volatile TRISTATE m_bUPnPPortsForwarded;
1 J4 U5 ~: f, U3 }8 q; W# h2 R9 q void SendResultMessage();
& O2 Q& t# v3 u$ {9 r- @% @4 C uint16 m_nUDPPort;
q1 v5 E# h, ?! m; _; Y uint16 m_nTCPPort;
/ R: A1 u! q9 R+ z0 s: ^! Y2 q+ J uint16 m_nTCPWebPort;% L3 N% d( ^$ l% b; ?* Z9 @
bool m_bCheckAndRefresh;1 Y6 t6 ~+ K3 |' U0 q/ n
% k$ ?( {+ F( w/ Y/ E% ^
& g$ C0 F+ g3 K+ W- ~private:
* A4 N# K( h; g& u) z; D/ N# G; ] HWND m_hResultMessageWindow;+ G8 _+ t5 [4 K% \3 L
UINT m_nResultMessageID;4 r t4 Z' w t
, {3 `, m# x4 @' I% u) W# s: Y
' Q8 H3 E. g" G: p' }" V0 V
};
2 s) c( q0 ~% F: z2 [/ D! C: \% K: l+ T* c U% r# B& f# h; W
2 ? a8 D5 s' [( x// Dummy Implementation to be used when no other implementation is available# u F6 T! O$ L2 @' a* ?/ O# C
class CUPnPImplNone: public CUPnPImpl
" U$ I# G- _1 W5 ?& d8 O3 d7 @& O{
0 `0 \# Q/ r5 O* \) M W/ hpublic:
. N+ f3 J/ w. N1 i4 a virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }! }9 m4 L* u% X- r/ S
virtual bool CheckAndRefresh() { return false; }
0 R5 ?0 G' [. P/ y. ^/ O virtual void StopAsyncFind() { }, z7 v! k4 F( D* j! N; C
virtual void DeletePorts() { }
: |/ }2 W5 v$ E virtual bool IsReady() { return false; }5 d8 C6 B' u% ?+ \
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
& J2 H% }5 t6 V" \};
8 J- c! I# k8 N2 i: J! Q. g Z, \' y
- r7 ^8 y* J! E! C( o+ O
/////////////////////////////////////
* H0 Z. v1 G2 q& a//下面是使用windows操作系统自带的UPNP功能的子类
, n! S7 p( B: O! r( m9 i4 A. H9 K. E5 e- t9 S. O% t1 v. W8 X+ J
' X5 j$ @: _: R: i- K
#pragma once
% j, p6 C! E5 N( x% X#pragma warning( disable: 4355 )7 |9 |; L* j% N
, R' b- C- Q: Y, q( O) \' x1 T7 T( \! I( ` O
#include "UPnPImpl.h"6 v: `( z( |( l" P0 q q. e# ~
#include <upnp.h>
3 o& z3 E! |8 s+ }. e#include <iphlpapi.h>
& C' }; @6 f4 r3 \$ v6 N#include <comdef.h> y+ q n" P5 g% R. L( M
#include <winsvc.h>
& m: S- g& g, @( M
& b4 `, ?; |5 r. Z0 p$ h T- x6 g$ b" y4 x5 |% }
#include <vector>
$ G- c# d6 `: W' [#include <exception>
# q% j" \& A r7 I, @0 C: d#include <functional>
: n3 Z& o0 G7 b, J! b
: S) A I" j: A. G9 X; N, V+ }7 y7 a: K
7 ]8 B% c5 b# H& w, J
' I' y. c2 w3 M- x0 Ttypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
! A4 F) j/ i+ W0 W' i3 Dtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;" O$ s$ j0 y) @) b; x
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;7 r. I/ U3 L0 b+ l) e8 ~
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 E: O& k) o6 W: Q
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# @# {. V8 D( k v1 X) }# m, Y! m
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 w) p" j0 Y# z% x* Ctypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;3 T3 T& _6 P0 O7 m' U2 d f
4 `7 W6 D7 F/ k7 _+ D# S X
% H& y0 E: R# a& E8 ]& N
typedef DWORD (WINAPI* TGetBestInterface) (( G# D* s1 p$ k$ \. o* A
IPAddr dwDestAddr," A; a: y/ m5 @6 q/ d4 r0 Y
PDWORD pdwBestIfIndex g* P6 J! j: ~/ a* g
);) N- e# ]" m+ C% f3 v+ n" H- }2 J- M
. O( N2 i X3 Z% X) E* D2 j; s
( X( X7 Y1 `4 \7 }7 @! j, jtypedef DWORD (WINAPI* TGetIpAddrTable) (8 H, u) ]7 e8 R% F! S1 j7 \% i
PMIB_IPADDRTABLE pIpAddrTable,8 S1 P- l$ p/ n+ ~ ]
PULONG pdwSize,) W/ E5 G K- v/ Q! I; v7 l
BOOL bOrder# Q* e6 t6 k8 }) I5 _' e* N1 I
);5 W' k( [& ^' k& K4 V+ l7 ?+ l
! i+ `' ]* M$ `5 r- Y2 F/ U& A
0 }" B( v& u0 X* a$ dtypedef DWORD (WINAPI* TGetIfEntry) (
) P Z. Y5 n, p: |' `/ ~ PMIB_IFROW pIfRow e1 X; g0 \% f) s) R. l( z
);5 A) O. q( H; b# r8 _* g
; {% [$ J, s& S
~9 P; q2 ?4 s* ^, ?' s! YCString translateUPnPResult(HRESULT hr);6 ^; g& L1 @; f
HRESULT UPnPMessage(HRESULT hr);
2 D9 O0 V& i+ R$ n% a& ^3 N; H
) i" O) G# o" _+ L, v. @7 y
# j, c' F# }: Y* T7 iclass CUPnPImplWinServ: public CUPnPImpl
4 L2 V2 u5 u& i{
2 _) u. M7 X4 ?8 z friend class CDeviceFinderCallback;5 J1 V* ^* g, c# V: k
friend class CServiceCallback; G/ q. o S# m5 n/ k0 }$ c& C/ I
// Construction
: d8 |# W$ N( C! }2 ? cpublic:
6 k4 Y! ]' X" P2 r2 N virtual ~CUPnPImplWinServ();) f& U! Y: H2 |1 M, m6 c3 u
CUPnPImplWinServ();
, E: M# [6 N1 C) M: V' M/ i
# x% i' K( |: b2 ^% }
7 v0 R& A; {: ~. m$ L$ p9 X. @: y+ z1 e virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
0 K/ b' O- @/ m virtual void StopAsyncFind();; F/ i; V' m. K% F: Q. d
virtual void DeletePorts();: a' B4 K& R% ^! [; k2 ]
virtual bool IsReady();& x; n1 k5 J# f F1 F& Y
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; B9 B. @" o. G( b- k9 A2 {
/ n- W$ ~. k' B) X7 Z! b o: {3 Y- G+ O' o3 B: U; r5 s) d+ C
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)6 T _9 e5 z0 k+ L+ c
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 w8 G- P/ v2 }* y/ F! K9 G
virtual bool CheckAndRefresh() { return false; };6 L" X w9 r p. _
. X0 s% p( @7 {5 s& g# a' b
: x) w; l* ~( u9 _2 n; A" k' eprotected:9 P9 N* L' \2 m( A3 L" m
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& C/ ^8 P. O3 t9 j: @ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
4 z0 _1 ^. }. h4 ^, g void RemoveDevice(CComBSTR bsUDN);
, \# s- Z9 c# q3 m6 ]- ?* ^ bool OnSearchComplete();9 _5 a" W$ E9 O2 G+ t3 x
void Init();
8 s( ?' P0 Z& ~7 H' D. I$ r' U- g. j# x
- B3 T: @! e' P. |% r3 p
inline bool IsAsyncFindRunning()
# J$ F6 @+ N0 c; T, [2 ` {
: S9 n) f J) L; C if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )/ C/ W, W4 b) Q6 f7 U
{
+ \7 s1 v5 e @1 Y m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
4 e3 M) E( ]7 W; ~ m_bAsyncFindRunning = false;4 P7 w8 k# }: o9 [/ k
}+ f: @7 {5 [* J% Z
MSG msg;( W% S3 ]( H$ p- R- I k2 O
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 ~" ?2 U0 m2 A, G6 k
{
6 `9 G/ X) N0 ~+ i9 `5 U! f TranslateMessage( &msg );
5 x: f9 R( _& O* m DispatchMessage( &msg );, s) e9 s7 m9 {7 P3 J8 [- w0 f, z6 \4 y
}
3 }* y) z7 p# p5 k+ Q5 \* ~% g return m_bAsyncFindRunning; ?: N& p) Y+ P+ S& \+ o
}
% A6 i/ F( Q7 j) g0 z( C
) t: y. E7 {$ Q' n- E4 U. I: i! `; o2 v8 k$ x+ [
TRISTATE m_bUPnPDeviceConnected;
8 H8 @+ d. h& G5 }" ?9 A
3 l8 |; {: C& [
$ c( d: ?9 ?, w# B// Implementation8 ~& H: D7 z3 _8 q+ q! A
// API functions" Z; ?5 Q9 w. K' k0 m
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 F5 L @, j( v- ?: Y6 T9 V- `+ W SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, P& k8 c" T) f; b1 C
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
$ [7 Q! ]. y- C# [ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 A. ]/ ]! W) y# u
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
: k- H4 z% j8 m5 A BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
/ g+ N+ _2 ~$ z; d& k# K3 u/ v3 \+ [" j4 B1 i, b
, @2 N; w1 A/ ` d$ _ TGetBestInterface m_pfGetBestInterface;
2 N! e- f1 m! j/ _ TGetIpAddrTable m_pfGetIpAddrTable;
5 Y. U; k" D ~" z; E- _' E TGetIfEntry m_pfGetIfEntry;
& V3 `: ~8 k$ S( ?$ j( O8 n3 I& d% U$ R3 y$ z; @0 V
3 Y, \* o# _8 [$ a2 S static FinderPointer CreateFinderInstance();0 \- Q1 f* |# p- d9 \- E/ o
struct FindDevice : std::unary_function< DevicePointer, bool >5 K0 A2 g3 j9 h/ h2 I2 f! K3 e) y
{) n2 Q4 s M! W) t* ~
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}" O( N. S2 v5 ]( p
result_type operator()(argument_type device) const! z, p; ?) a# f- c
{2 U. s7 ~7 M' h5 M: k9 J, Y
CComBSTR deviceName;
' H A ~" O! n3 @# k! z+ C* Y( w6 ` HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- {. X/ O( z" I2 R8 e' J r7 Z( H2 R0 u; y
& x4 G: F7 [/ C( j" D% |- I
if ( FAILED( hr ) )/ T( _6 D( o: C# ]! f% o; n" D
return UPnPMessage( hr ), false;
' g3 p% r5 A8 O: ~" u- R0 }# p+ P5 S
- @1 E/ _ ?" S# s5 `- Q return wcscmp( deviceName.m_str, m_udn ) == 0;& w9 |. p* ^( X9 z; H8 I2 ]! w" i) R
}' k9 n5 F/ Z1 y I; K$ Z
CComBSTR m_udn;
4 y$ l5 t5 T" ? };
, \. w6 P, U8 d p) o3 E 9 p C. {* x0 S6 {
void ProcessAsyncFind(CComBSTR bsSearchType);
4 j& X0 I$ g! z( d7 Y( Y$ K+ [: t HRESULT GetDeviceServices(DevicePointer pDevice);
+ Z. @* \% ?* o void StartPortMapping();
! `; g. r( i8 l% K2 w$ R+ e HRESULT MapPort(const ServicePointer& service);
0 }7 @& B5 g5 h# t) x/ E void DeleteExistingPortMappings(ServicePointer pService);) ]: A0 ?) o6 K
void CreatePortMappings(ServicePointer pService);% l# Q7 D4 _. x6 U5 m( |0 q
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);) L- V- O1 L2 L2 ?) b/ Z! \. N
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 T9 o4 D& T+ s0 Q
LPCTSTR pszInArgString, CString& strResult);0 y, Y/ O( e9 r% N
void StopUPnPService();
; S' M7 C; H' [
5 |$ |/ q# I3 J4 _1 u
9 x0 z" `- h; Q- i+ d# l5 V! U // Utility functions
/ u+ a* k# B# M" M& o+ q HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
. ]. i: k e \! e- Y( ] INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ C8 b1 S% w4 c; d+ s& C2 ]
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);0 ^% Z0 l4 W/ Z" F
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
6 P- v) u# a$ a7 ~ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ k' Q0 w% u" B9 z/ j HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
0 R6 g: f+ |" s' a( f6 Z# j: [ CString GetLocalRoutableIP(ServicePointer pService);
% k6 \. b2 r6 |# O6 g6 ~0 ~
& H5 ?; X; k/ V. v) ], d% u' W6 z8 c+ y+ C" N& j- I# |& F& D4 [
// Private members, k6 J$ [$ |( F2 g% F7 y
private:" H1 f, h: |1 [( H
DWORD m_tLastEvent; // When the last event was received?
: z* A# P2 p* M, s std::vector< DevicePointer > m_pDevices;
: W$ U9 `# X7 Y" v- b std::vector< ServicePointer > m_pServices;
% l. w* b% s: c6 ? FinderPointer m_pDeviceFinder;' d" g7 C, X% J; y
DeviceFinderCallback m_pDeviceFinderCallback;& N8 r2 o' p: }6 E! l
ServiceCallback m_pServiceCallback;
@" }0 h8 j" n( L
6 v; p2 y# O5 B, b( n
6 K( b J6 j$ Q' K. X LONG m_nAsyncFindHandle;
5 e* ^1 l& U- ? bool m_bCOM;) v8 o* L9 v2 ?; O- N( [* ?
bool m_bPortIsFree;
8 C: L9 M/ | j* y, s# Z) |! W CString m_sLocalIP;
" K0 n. U% {. m. a0 P; Z# {; B CString m_sExternalIP;
, }9 \- d/ E$ w7 p* ^ bool m_bADSL; // Is the device ADSL?8 T, [% d+ k& O. i x6 c
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
- F8 ~+ F5 b& h0 e$ h0 k bool m_bInited;
, z9 I3 \* w1 U, U) x bool m_bAsyncFindRunning;% v) g3 j' w- E
HMODULE m_hADVAPI32_DLL;
2 O; V" d/ d7 Z3 n HMODULE m_hIPHLPAPI_DLL;
/ `, ?$ H5 [3 c8 |" f6 I bool m_bSecondTry;
/ L' z0 i w- n4 ]9 V bool m_bServiceStartedByEmule;
: E$ e4 u# r9 S; L, t bool m_bDisableWANIPSetup;: G2 T! K8 |3 C; @, H U
bool m_bDisableWANPPPSetup;
3 ~2 [$ d. _/ R d+ g x. W
" u: p2 `) P. _9 }5 n9 _& w/ b( {' t
};. @& I; J+ t" ]' G
3 l0 b8 \# ~" k! H K% ^
6 r$ o* h7 Z8 Y R) J7 G// DeviceFinder Callback6 t! ~$ Q& [" ]8 I/ W) N0 z- R7 k( V
class CDeviceFinderCallback9 W7 S# x% i U0 m8 }0 T
: public IUPnPDeviceFinderCallback1 |8 }. Q. u, n, F5 v& w" n* R
{
' f% d0 `5 W5 o, u; @5 d& }/ o; qpublic:. W/ p! x, Q& {: l
CDeviceFinderCallback(CUPnPImplWinServ& instance)4 s) Q$ T9 O$ A5 h: r3 j$ ~
: m_instance( instance )7 k) ?: Q6 t9 {
{ m_lRefCount = 0; }
7 {* P( n7 P" q9 D) d! E. M. _5 v! j" b
" F8 E2 o% w. I2 [& G: k$ `
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 Y" t5 A$ @; ~ STDMETHODIMP_(ULONG) AddRef();
; g/ d% }" q! ~% Q& e7 M/ l, @ STDMETHODIMP_(ULONG) Release();/ q+ {+ o% `' T9 G8 _
, d1 m& f& U) s; Y* A
8 V7 x! q7 u9 w0 C4 e: W// implementation
/ {. y# T# a; h& pprivate:
2 Y. J1 v' A4 l. M h- r& g' e7 J; c HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
2 e, D8 u) X* @/ p' l HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);0 @1 j4 R! C! R5 |! b, p: S! ^
HRESULT __stdcall SearchComplete(LONG nFindData);
, s# Q! f, R( ^& r
* I, m4 h( p" H) w: S$ F6 R; m, I
# N& |. U* j4 |& G% L5 zprivate:
, C* n6 F; R+ E* A4 j2 {; o0 { CUPnPImplWinServ& m_instance;9 c; j) ~2 r. }& L
LONG m_lRefCount;" o% x$ S; u5 C
};
" o8 R' K0 f5 B( d3 V
: F2 [3 B, x& i D8 C& Y; n2 X& Y
// Service Callback : i) O% m( h/ H: ?
class CServiceCallback+ @, g+ I" `, Z, ]$ P. Q' H( P
: public IUPnPServiceCallback
8 U. r9 C' t3 Y{+ J: N- \! `1 { |+ d
public:
1 D* F& ?8 E( N* \0 m5 H( w CServiceCallback(CUPnPImplWinServ& instance)8 S# {: X( x+ w* E
: m_instance( instance )# h1 U& g; k6 N7 Q# E0 r; w
{ m_lRefCount = 0; }
! `) Y+ |' }4 D/ B 6 S/ {+ p5 e, A7 H+ J- e
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% s! }/ B- G7 S) z v STDMETHODIMP_(ULONG) AddRef();1 s/ L5 ?9 U7 C7 C/ c) V9 J
STDMETHODIMP_(ULONG) Release();, `6 y0 C" o( _
4 H A4 n( ~+ e% t- J
2 Q8 c" R3 F3 P) ^8 G// implementation
, Z1 e& L# g, |: ~7 M; Vprivate:9 Y. v7 }' Q6 \! O+ W
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);; ^1 E/ O1 d" S& N5 f M
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" l: a6 {- h- m
% {: p$ U9 X% i; [
9 b+ `! T& E. A! Yprivate:
! I2 z! m* U; w. E9 z CUPnPImplWinServ& m_instance;
8 k+ y: S- |) N& e( U9 m LONG m_lRefCount;% a! N# P+ P. p& W. D H5 D
};
7 N% |* L& g) Z1 z8 Y0 \5 Y: M y8 m$ K, L
+ T1 u/ k& f6 {- @% `/////////////////////////////////////////////////8 j8 p+ m4 y6 x2 m) T
* g, T* @" w& ?( {' x E8 ]
# s9 Y5 C- A9 M1 q使用时只需要使用抽象类的接口。
, O" P' I' X$ A! I8 F1 q, OCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.7 h7 D7 j5 K& u% X
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! W- Q" \8 m* k8 U
CUPnPImpl::StopAsyncFind停止设备查找.
1 i( k3 o6 Z2 m5 P: J% jCUPnPImpl::DeletePorts删除端口映射. |
|