|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) V7 U, X* \% J
5 D% x3 P. {4 e2 K; O. o( k! y/ y0 j. h& F, O* x, k1 A ^
///////////////////////////////////////////
% {3 [- ^. i: q; L) r" @$ J//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# A. D9 ^' [$ I+ G; p, @& x* Z3 H: i9 @- ?$ K) S( V
' M' C- L$ B9 X& M6 H0 t8 y#pragma once
# l: T5 C* j8 B1 V- x4 C#include <exception>3 |; Z1 y) K: I- [" {' }' j6 A# `
9 q4 h, f0 j6 p6 @6 h% M# D" o3 r7 \: O c2 q
enum TRISTATE{
7 X) `- c! N! u! V4 ^* j* p" c TRIS_FALSE,' L) X5 w( f- c& c: v3 `
TRIS_UNKNOWN,: C" ]+ T: H+ l& x9 V S# d7 V
TRIS_TRUE
( C: ^7 T* U: M' L* G \8 g};8 i! ^ r$ y. v6 q# w
' K2 j8 ~3 e! z% n- r& A
; ^! \) v$ U" n7 h
enum UPNP_IMPLEMENTATION{/ J/ I( B" c# X
UPNP_IMPL_WINDOWSERVICE = 0,
4 u' b: G" p$ `$ F! J6 k UPNP_IMPL_MINIUPNPLIB,& V& ^ G; ]9 }
UPNP_IMPL_NONE /*last*/
' H8 k7 n+ v- O5 ]};& X) {& \, Q" D% B! \; ~7 s. \- v
5 u, F( U b6 h, D% ?- k2 }5 N& f/ p" M; l) N
% b9 ]. q; _0 r) N0 W' F: q5 i7 o$ x a: A: L
class CUPnPImpl3 k- D! e' c/ r( ^
{) O" [8 p+ P- C' ?# x
public:
% H% A9 I# x4 G3 w2 B, m CUPnPImpl();
0 l o3 K7 p. d, I$ g1 k virtual ~CUPnPImpl();
& Z6 B6 |0 C7 F; S1 q struct UPnPError : std::exception {};
9 n, H, |6 f( o enum {9 N4 U& } f3 R: n4 G' W2 a* T- m
UPNP_OK,
3 F$ g5 }$ f: j7 Y# E: J" c UPNP_FAILED,& ]9 u; Q: n" s% v p3 E& d6 V
UPNP_TIMEOUT
2 s: v8 S9 i% P2 I: ^" N& I };
8 A V7 }5 A8 ]2 D4 C2 x# U7 _& b8 o) l2 Z
: @$ H& ^" M+ u0 M* X virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" r# }( y/ x' E6 Y, l, D" Y% e, Y
virtual bool CheckAndRefresh() = 0;
! N, T3 ~6 m) Q9 y. E, X1 }$ r virtual void StopAsyncFind() = 0;
B% v5 S; K, l3 R- p! M virtual void DeletePorts() = 0; s4 m' B( N5 L5 E! w9 ~
virtual bool IsReady() = 0;; n9 _' y! h, r& P
virtual int GetImplementationID() = 0;, o5 ~7 [# ~; Y8 l. g
2 B# K6 \# t6 y3 C+ w
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 g4 h3 F) J. Y9 u% ~1 J% ~$ `, g6 Q N+ ]& V& d5 @
- v$ t( \, x. E1 I, F( L: \
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; |# Q( K9 N: H) W4 Z$ \4 _! J
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
5 g7 f2 \: `$ H/ c8 m9 _ uint16 GetUsedTCPPort() { return m_nTCPPort; }
& n$ z7 \! ?; V w4 e' ? uint16 GetUsedUDPPort() { return m_nUDPPort; }
7 B9 m u6 }8 t
3 P$ A! z: ~ H B; H, h2 L4 H5 B: [1 O: s+ r
// Implementation: L/ j4 {/ H2 g
protected:& E7 J: k8 j( R! ~- {
volatile TRISTATE m_bUPnPPortsForwarded;( Y+ w' e3 {1 ^, j9 [! Y
void SendResultMessage();3 W$ R2 O5 O; k( v' i! e6 r
uint16 m_nUDPPort;" E- b2 G* ^4 D- V7 f- T
uint16 m_nTCPPort;/ G$ `$ H; `+ p8 k g4 t3 C# v+ B
uint16 m_nTCPWebPort;
9 L0 [- D$ t4 ~1 D" _ bool m_bCheckAndRefresh;7 g5 H" m: l1 L
' \8 H* a2 D" c
( a- D, S4 C# k7 i' U3 m" q
private:4 a' e- j; ^% @. s9 F- x G
HWND m_hResultMessageWindow;
9 T: u! w3 L2 X% P5 r) ?- f$ H UINT m_nResultMessageID;
4 [6 L% C9 [2 w ^& V. u* A: _
7 o& O4 J) f. V6 a- [& B8 Z6 `. W) f" e
};! Q/ C0 I( Q2 y, T/ s9 K
7 J8 B D$ `7 @6 H) U+ ]
" K8 F. o+ c: T; h; I |// Dummy Implementation to be used when no other implementation is available3 z, R3 J( q2 ?/ e$ r: K. p1 p1 l
class CUPnPImplNone: public CUPnPImpl
( J8 D) {/ C) @, L, |{, h- |' N2 n, y5 m. o' W
public:
# J/ [/ g: x7 I virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
- \) D' ?( W/ t9 P- Q& s4 \/ d$ b virtual bool CheckAndRefresh() { return false; }! L% k: q; z& v% t
virtual void StopAsyncFind() { }
8 g7 N# o8 p9 Q/ A- H: E8 P4 T5 B virtual void DeletePorts() { }
3 a+ c1 Y8 S2 @7 a8 v virtual bool IsReady() { return false; }
! g1 E3 J( ?) q% M virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, b# N' q+ z7 e$ d# }};
2 N6 f' v8 @$ q5 R! u* M1 z; V# o9 J
( k( w. e/ {. G/////////////////////////////////////: _% t4 e- k; ~' J
//下面是使用windows操作系统自带的UPNP功能的子类
p/ k9 W" j3 W# f6 c7 A% f; q$ A( Q: _- G5 N9 b# e
0 W; i4 u( B! S
#pragma once
5 t: |" e" h! W; l#pragma warning( disable: 4355 )
2 K: K; A' u) O V( g
# O+ s5 h) S, Y4 i( z- Y) ?8 N+ }1 E
) v! s/ z7 w5 I4 J#include "UPnPImpl.h"; [/ k. i1 Q% p: _# g8 s
#include <upnp.h>+ g, e+ y$ b) Y6 F
#include <iphlpapi.h>( h1 s! x# r( E
#include <comdef.h>, |3 M( G. G- X. {; _
#include <winsvc.h>- O7 Y' {- Y: R6 R( O. y
2 H/ z, W' ~7 G q0 z! m! W' ]/ f
# p8 ?, Y* D: N5 ~: r#include <vector>
8 `" u, k5 l) H4 R9 ]+ Q4 u#include <exception>: ]: N- n+ h* Z/ X6 ]: w7 a: u
#include <functional>
4 [' [8 ~& i& P7 S# w4 N
! O! q) |0 G! v" T; S1 n* y: E2 ]9 \! B0 R7 r4 |9 d& K0 p
2 {' R$ d$ P' Y* s( S& x
& ]& X/ G0 b& q' @9 ^+ R1 }typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 H3 d9 ^( K9 A, `$ y/ ?
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( s: q% U- P2 G, f c2 e2 x
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
; s. q. a8 e) ?7 t8 h) w9 A1 }" ~typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! N* h7 {( d, f7 ^& {; ]. [& F: D$ htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;+ n0 g$ u4 T& I. T. s
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;' X( m5 n6 L- [: d/ V
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
8 J }2 Z% H$ H6 x0 X# f# W* R
: o, G1 I; i7 z! p. otypedef DWORD (WINAPI* TGetBestInterface) (% |3 }( R. U' D) Y; Q9 X- I
IPAddr dwDestAddr,
2 T0 h, I: l1 D! e: b PDWORD pdwBestIfIndex
. ~% N2 f% T! R: ?);
- Q/ k0 e" r. K' M/ \" M. q+ q9 u1 H7 v- A, m. i7 H6 R
9 `/ J3 y8 v5 F, l* t* s
typedef DWORD (WINAPI* TGetIpAddrTable) (
3 X* o- F5 X4 b* S' ` PMIB_IPADDRTABLE pIpAddrTable,/ | \. r, A' B% c ~6 _2 T: N
PULONG pdwSize,
" Z* e: [% m" B2 t3 a& A BOOL bOrder$ C* L0 U; f a" g; t3 B
);
3 I, P. _9 B: ~# |: |+ D! }' D5 v# Y: g
- E, R4 c7 B! F: Mtypedef DWORD (WINAPI* TGetIfEntry) (
1 I5 Q* S+ r4 X5 t4 _: j; ^8 W PMIB_IFROW pIfRow
2 y2 X, G6 N2 p' O);9 X- K- e* W5 A+ R3 K( T/ [
: ^0 }, p" y* q0 ` R- T
% m+ o8 [/ V, i! n% A- z
CString translateUPnPResult(HRESULT hr);$ e' j# y) ^& w# H2 J, F0 C
HRESULT UPnPMessage(HRESULT hr);; C( i5 n5 K1 x$ s* Y2 x
) R6 R% n! ?' O/ \& G+ w4 F
: C7 h+ [2 V, Tclass CUPnPImplWinServ: public CUPnPImpl7 X& d( A2 ^& P4 Z9 K
{& I. J' b: `# Z1 `. K
friend class CDeviceFinderCallback;
/ V" T8 \2 J' @! C friend class CServiceCallback;
1 u: m1 y2 ]5 h: E" E// Construction
5 i) [3 e$ i% N# A1 Qpublic:: Z8 V" D4 ]2 @: l' ]
virtual ~CUPnPImplWinServ();
0 ~$ {" Z6 ~6 c/ i( T* a' |$ j: J. D CUPnPImplWinServ();" @6 t5 b5 e2 N5 k) E
; x% R5 H" M B+ j: }! N
5 _2 R. p- r6 F$ p Q
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% a7 o+ u1 Q; z9 ]$ \9 \ virtual void StopAsyncFind();
8 k V |3 C! [% \7 W virtual void DeletePorts();
* u& S( q x0 m- i8 } virtual bool IsReady();& u6 Z+ L: O% u/ U. q* z
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
8 v5 o* E. S8 R" F" d
7 F7 i9 M+ Y# A: Y) { x2 x. q
1 d; w( Z, V& E1 I // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
$ O. f- ~8 ^0 H! e$ g6 h0 L" K // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
/ x8 E6 O7 i1 w# \8 O! a virtual bool CheckAndRefresh() { return false; };) I- K, K' N0 r* F7 r9 z* ]; p
8 | ?" A; D% @; ?/ J' I" W$ W6 T% s
/ J6 b* s$ [8 t" d M7 vprotected:6 ~# H" T& y. f
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);- {. r3 [( ~, g* P0 [% p k
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 u+ L5 q/ ~7 P& j0 N void RemoveDevice(CComBSTR bsUDN);' O" C8 h' @% H
bool OnSearchComplete();
8 e; S/ ?. n7 P2 z% b void Init();8 A2 t0 R1 k0 R* V/ \$ j' s9 c( P
( x1 g* ]& s* Q* a0 k: X* e; f4 w4 z) v' _- \( K
inline bool IsAsyncFindRunning() 5 [% P7 J6 h* `- _; L
{
* `7 ?5 ^) l, B8 b/ a! {; f if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
) o3 b) Z P! s: ~6 v- }% B9 ?8 k {
5 c8 F- h. z- {3 ?1 y( j m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* S' S6 ^( A; c( F1 }' C
m_bAsyncFindRunning = false;
3 b/ b9 M& ]4 c) x }0 @& K9 `1 ]2 V# l- X! R8 y
MSG msg;
, p/ d( |5 q: b- _' C) m while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )' O5 G8 m$ f) g: \4 y$ @$ [
{& G* X" P6 S5 Y# |2 m" B; V3 q
TranslateMessage( &msg );. p6 ?5 o" {* R: s
DispatchMessage( &msg );
% E, |: {! p6 V0 b+ x }
3 I1 K Y7 s3 l8 e: R0 F c3 k return m_bAsyncFindRunning;
6 r) D! h! z+ X" ] \3 [" C }
# @6 f3 b& P+ c9 w: p5 m% d( i3 O8 z9 d7 |/ t4 T" \" @* C; e' I
) M4 e) ` R0 v4 [) Z TRISTATE m_bUPnPDeviceConnected;- k# P6 m* X4 X, @* z* [( R, i
, G+ s: d; S4 W
8 ?8 C4 G$ a! w; l5 e% K
// Implementation0 Q$ \. J, a2 G
// API functions
6 T1 T' J/ i0 p2 z+ g SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);; w) c: Y8 Y8 s( X( S! i% P
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);+ K+ \9 u+ J4 D
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- v; P% l1 g" I" k
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);" I# M1 s, O- {4 P
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);( f' j' J! e) z0 G. s) L6 j
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);% d: ~# U8 L! C* Z% v4 W7 y
+ W- c% L. G; i3 G; ]0 [- s" e
# G& T1 f0 d0 k- T7 \: n TGetBestInterface m_pfGetBestInterface;
' {) E" b6 ^* g: W TGetIpAddrTable m_pfGetIpAddrTable;
9 s9 t1 m e0 t! Z, f TGetIfEntry m_pfGetIfEntry;
. S9 g. \% C) |' Y1 w' h+ ?7 d0 t% W+ a- I# H
}' {: x. O4 N static FinderPointer CreateFinderInstance();
/ W2 l( P0 p) p% U5 b0 o struct FindDevice : std::unary_function< DevicePointer, bool >( s! `: i# l3 z8 T# |) l: q8 v4 x3 k
{
+ M2 t/ H. ?' a G1 [ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 `2 n$ e4 \, F" V. s( [ result_type operator()(argument_type device) const4 n/ F) N9 p$ P) M& h' z Q
{$ B4 w4 b& z9 X1 C
CComBSTR deviceName;
" D9 [# I Z# L( u* g9 @8 [# p HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- N2 ^6 b* p" B. y, r" ~7 u% {3 X& P ^. r1 ?. {# q% C
7 e) X d2 @* [5 i6 z; y9 G# T
if ( FAILED( hr ) )2 J" p n2 v( j( \" n9 d7 Y
return UPnPMessage( hr ), false;9 G$ F4 O- C% C! J2 v
; }4 _( o! A7 p! U
7 F) T3 A/ i2 R9 s/ j2 F
return wcscmp( deviceName.m_str, m_udn ) == 0;
& ~# l# r" i- i( T! h7 z0 o }
) B, r/ j+ n+ S, W' X; J8 O7 O CComBSTR m_udn;
/ D6 g' S$ M/ c1 L };' j, t/ E4 Q `. {
4 U S; _( C) A& w void ProcessAsyncFind(CComBSTR bsSearchType);# W4 K. P# z, [* H( j
HRESULT GetDeviceServices(DevicePointer pDevice);
3 D0 V& B" F% ]* z void StartPortMapping();3 ?: n* [9 O8 `# C( e
HRESULT MapPort(const ServicePointer& service);
+ p- f1 T! n' g* b void DeleteExistingPortMappings(ServicePointer pService);/ Q; v, j8 c3 {* T) s! D f$ c6 l
void CreatePortMappings(ServicePointer pService);- p) M& G4 t) ~: _! D; B# s) o# ~
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);! a8 c3 o3 i, E% C# a7 z
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 0 ^" M; i7 u3 K) q
LPCTSTR pszInArgString, CString& strResult);
) n' u$ i( {4 N) b void StopUPnPService();% k/ i7 ?& C6 e3 y/ d: z3 f
0 R8 _3 P/ X" X2 A* |" Q M1 g; u: V3 V8 `( X
// Utility functions
+ M9 P9 Q& N; y+ p, W3 d7 i. U+ x HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; ?: y' L( H+ S( I5 d- h H; I INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
3 B5 j q8 c) p' I7 e INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 A% G+ A+ C7 ?* ~& K( B5 U1 c/ X0 a8 r
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) x9 S w7 U% F6 D HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);: g4 i( }9 H' @ s/ W, [
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
7 v5 t% N4 W h CString GetLocalRoutableIP(ServicePointer pService);0 \- x/ ]' ~* ?2 C6 g
/ g8 o! w; P1 R6 \6 l/ Y% P' P( p) O7 T, A6 @5 {
// Private members
# r7 k. s1 \4 _' n5 b5 v8 X! V' uprivate:/ H- i( }2 `7 u5 g/ S
DWORD m_tLastEvent; // When the last event was received?
& b( Q) a+ \6 S% m/ ` std::vector< DevicePointer > m_pDevices;: }! d7 B4 i" X- @# ], A& B, g/ e5 A
std::vector< ServicePointer > m_pServices;
$ I- Q( q$ D0 b9 F$ p4 s, P1 R FinderPointer m_pDeviceFinder;
0 @0 m; E- x2 O3 ~/ b$ m" k DeviceFinderCallback m_pDeviceFinderCallback;1 K1 _, t `6 v# ^( L3 W6 a
ServiceCallback m_pServiceCallback;8 R" D* z7 u9 `9 `$ X+ k+ {
1 y9 v# g4 q4 a' G4 D7 Y) @% S
3 |, V( y# o) @! W: h+ | LONG m_nAsyncFindHandle;
5 {& |, B4 {- B3 r bool m_bCOM;
# }$ ], i1 R4 B" J/ d bool m_bPortIsFree;/ O* ^' k5 D: R; f
CString m_sLocalIP;3 v; N6 u2 j1 s% z
CString m_sExternalIP;
, r, L8 B6 M# p1 Y- t& U; b bool m_bADSL; // Is the device ADSL?
0 x: C& J. C3 q( y- o. Y bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
- o/ r4 P. k) K* P0 s& P bool m_bInited;. C: [6 R3 n- X; w
bool m_bAsyncFindRunning; X4 z% @: Z. f+ w3 l
HMODULE m_hADVAPI32_DLL;5 }7 u j% v# l3 y! B
HMODULE m_hIPHLPAPI_DLL;
: H0 f6 `" x Y bool m_bSecondTry;
9 E' ]: \/ k! ` bool m_bServiceStartedByEmule;; S0 I6 P/ @; i
bool m_bDisableWANIPSetup;
' ^8 ^1 t* N. L bool m_bDisableWANPPPSetup;5 v2 h w! d+ b% I! x
8 G' D5 L0 _ R. n$ ]2 U
5 P1 R/ q% E4 [3 \ |% s, P};
$ C; }, p P( Y1 \6 H' H+ h6 Z
( r8 y- `7 r! B! }
4 x! m1 B0 n$ v) {+ ]& Q// DeviceFinder Callback
. `$ @; ~' I* R# t! E* j* }class CDeviceFinderCallback
0 V6 X, Y9 u U$ `) V2 T : public IUPnPDeviceFinderCallback: B" @7 F4 }& H/ T- |
{
+ D' ?; e1 Y4 S+ o$ C0 H, }5 \- bpublic:
0 ~ E& m& R" p/ x( v4 c CDeviceFinderCallback(CUPnPImplWinServ& instance)7 u1 t# k* R0 L' b+ Q) y: [
: m_instance( instance )$ l* A. Z) C/ ?" v2 O
{ m_lRefCount = 0; }* Q9 e. I( V. O9 s- e5 q
# s" H0 I. k- p# W8 d. h' S S7 Y' {! U1 y( n0 B+ S* r1 F% I
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# }$ W& K0 D; e# S( u1 { STDMETHODIMP_(ULONG) AddRef();! P, O7 Y7 x: E5 ]
STDMETHODIMP_(ULONG) Release();
6 \ M! X# R1 F/ t8 H& U
* k" O& Q4 t+ X( H% K! g( i. D' Y4 G, _! e
// implementation8 v# K: K# i& o* v
private:
3 _' A5 F" c9 q! D. D) @ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
" {4 i7 o" n' @! }5 Y2 M. n HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ Y9 |" C# _4 ?6 P5 T+ h4 ?9 ~ HRESULT __stdcall SearchComplete(LONG nFindData);
% K5 `$ r6 X9 |9 Q7 {: M% [7 _( N K& R( |
9 ^* W7 q+ @: d. G" A$ |private:
6 v: H2 n! v( g6 | CUPnPImplWinServ& m_instance;0 k. E* ~! p9 ?
LONG m_lRefCount;
, X" @1 L; q( Z9 g# r# u' Z! a};7 ?. L9 C) A3 ]; k+ U5 o; ?
8 E2 i- R/ E4 C% p
P% e( m( h" V. `+ h
// Service Callback
- l# d: E) Y, r! N( Z) Nclass CServiceCallback
& _! x- J6 k6 m+ U. W5 _/ v$ F) f : public IUPnPServiceCallback
% ]: r% m+ Y% l! W8 v v{
; Z6 W7 C6 Z7 opublic:+ I3 W6 E; f2 L) P* t
CServiceCallback(CUPnPImplWinServ& instance)
, D# U/ r7 ^* L- V) R& I : m_instance( instance )8 h; R7 D) v& e6 s4 z/ y1 y9 j% q
{ m_lRefCount = 0; }
$ B1 Q$ F, B9 `2 C9 T& F . f% M8 C7 p, K% h8 O7 G
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" y' L( z5 R: U- c STDMETHODIMP_(ULONG) AddRef();
3 ^0 p& B6 s' V( W& A. i STDMETHODIMP_(ULONG) Release();, ?' x' s. ^ Q/ d
. z- ~; ^, V$ m
3 w+ Z- q7 R2 x4 X! ^
// implementation0 ]' C* u* j4 c& `* J( V
private:* o, @3 @7 ^+ _; r( m% o2 G
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);4 i1 z7 G T# ]; W0 z0 D
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);9 u' J2 m! b& J
' L+ i7 |) L7 V: e) D! `
! C' z' J7 q7 o2 f7 c$ I, ^7 }private:% W$ j3 @4 Q7 _! g
CUPnPImplWinServ& m_instance;1 f3 Q I( O% u) n/ y# @* L
LONG m_lRefCount;; D" w- ?- J& x1 {) Q$ p# d7 i
};. x8 D: y4 Q8 d0 ~: L h
y# P+ _" [9 y" |, V. ?# {9 T
( l' M% W9 V7 l1 s6 t/////////////////////////////////////////////////
# I J& T) _+ O) G3 e; L6 g! G" h
: }. L6 W, G! Y. x, ]" Q! n使用时只需要使用抽象类的接口。
4 V/ V6 v& Q$ ]0 \) b$ ACUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.% ^, c) `6 H! {$ n9 N: j
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
3 N2 I0 |' s" w5 P& R9 s) VCUPnPImpl::StopAsyncFind停止设备查找.8 G# P7 d, Z4 v$ N$ d4 T! z
CUPnPImpl::DeletePorts删除端口映射. |
|