|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,% s z/ e, a9 B, M- a. ^. v
' m: u: G# A2 B7 p" z8 S7 M+ B4 r
* J( ~% O* M. F" B///////////////////////////////////////////0 e4 I! t9 S( s6 K9 u; ], E
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能., F5 ?3 Q* h( u; ^; ]% X5 P2 l9 B
: q( Y* i6 W: w C
5 p5 |- C8 K7 j- K#pragma once
' v$ S6 Q( V! f5 L#include <exception>
! c4 e% u: n2 L1 O' ?9 W. v
6 y& l3 H* {4 b0 {% d w+ A e" U ^8 o
enum TRISTATE{ s7 l# l: o J5 i; W
TRIS_FALSE,8 x% O; \" U- W
TRIS_UNKNOWN,
7 n4 ~- k5 z" U2 A) G& D TRIS_TRUE
- i+ x+ S% T; w# V. i};
9 z( B* x2 T3 @5 l* T& j" B
; h, Y" D. @0 A3 s( H0 _5 L3 o9 N0 o; H- \! X2 A/ N: }
enum UPNP_IMPLEMENTATION{
. k( x7 @! N2 j# m9 v UPNP_IMPL_WINDOWSERVICE = 0,% ]0 D( d8 h+ c: Q3 m9 w
UPNP_IMPL_MINIUPNPLIB,
/ q- f5 S+ H l4 } UPNP_IMPL_NONE /*last*/
& L& F. k5 i2 V8 n0 x0 {! e+ Q# ?};
g, O k; ]& q0 B) {' \
4 p! K1 [% D; c" d
+ E7 ?' w3 N) `5 i' B9 d! z+ U6 S: b' @, n
! V& l2 s# f1 ^5 a# h$ Mclass CUPnPImpl9 `6 x" o0 B @5 w$ n* t9 [
{: ]: L4 |3 C R
public:$ @' S. J- @$ c$ h: b. ?* G( g8 B
CUPnPImpl();" [' a# d9 K. |. P
virtual ~CUPnPImpl();. F2 G9 [* X# f0 |
struct UPnPError : std::exception {};
# i ]0 C8 b3 U+ F1 }, Y( [. I enum {, l, d: y+ _$ a1 b1 t( \
UPNP_OK,4 i8 a7 }3 f7 K
UPNP_FAILED,
" ~/ x2 M7 k8 [1 P* n# G UPNP_TIMEOUT: z" k, f5 Y( W4 k
};
8 H( |" E0 X1 o- V% y) H; c* e: i9 ^& m$ E
. B+ }+ i6 P3 a# @! J7 ]" X# ~: G virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
) R7 i% X' ?! [4 r& H1 z virtual bool CheckAndRefresh() = 0;
) a; F2 b5 q: q8 A( M! U( g3 V virtual void StopAsyncFind() = 0;
+ E+ g- f& ?( Q5 L/ c8 a3 W virtual void DeletePorts() = 0;
2 D, W I) i$ }: a# g6 A: ?" W virtual bool IsReady() = 0;
8 Z4 k, B5 C+ H. P2 t% h/ w/ \ virtual int GetImplementationID() = 0;7 Q5 f' Q) ^" X: o- e5 g2 B
' u' {/ c4 z" E* F9 Y# ^& O' e2 I
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 A, S- X6 o) m& o/ r C; t
! S. V1 L% H0 l7 X$ s& Q3 Y8 g Q. S# J
void SetMessageOnResult(HWND hWindow, UINT nMessageID);0 Y. q5 y( M( }2 i1 A' S
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
! b+ p0 E, Y* h+ O+ {* p uint16 GetUsedTCPPort() { return m_nTCPPort; }
# D: l8 e1 x4 R! U3 s uint16 GetUsedUDPPort() { return m_nUDPPort; }
( x z) X! Q) [: G/ b. q3 y# w; }( ^( L* Z' d. T
3 l' F* f0 y6 X( H
// Implementation/ x; d2 q- F: m2 P( s5 s
protected:8 c; K3 c9 U4 q/ L
volatile TRISTATE m_bUPnPPortsForwarded;
9 ~2 Y* D. C' i: V2 Y; g, M void SendResultMessage();
. A% n3 x, Y# I: A1 @' [( x' Y uint16 m_nUDPPort;/ |0 ?& a+ J3 U
uint16 m_nTCPPort;
4 l( O* o: \) l4 d ~ uint16 m_nTCPWebPort;0 W/ b9 ?0 \- ~3 }* b
bool m_bCheckAndRefresh;
% P8 x2 Z, G; ^7 k! F. X
- [2 a1 q9 m2 z+ U+ T
b, A+ e3 O& k6 sprivate:- p1 l C0 G* s7 x0 \
HWND m_hResultMessageWindow;
" @; O8 x5 j* r5 T( o$ ] UINT m_nResultMessageID;1 t4 Y& N3 t1 A, {+ b, n5 i: G
- A% e2 Z( m0 x% V. B
2 s' l' I) ~ U* J c
};
. y+ I q4 w# A5 z7 w/ B
' _# C5 P9 p1 s; F8 G: F7 h& Q$ H9 ~1 ?" p/ U" {
// Dummy Implementation to be used when no other implementation is available
, I3 T u& U9 M% c# Z) qclass CUPnPImplNone: public CUPnPImpl
1 C( v' Z0 A: g: n$ V6 L{8 N+ F3 [" |" k3 ~
public:: [: |* j8 T, Y- ^( W# y+ d3 \/ } p
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }$ S2 f" o% G% y, a* }: Z# a
virtual bool CheckAndRefresh() { return false; }' U5 u: q! ~0 P: T) S
virtual void StopAsyncFind() { }0 R0 o" q3 M: b1 u% E. m! Z! ~; [
virtual void DeletePorts() { }
' V1 S! I9 s* \6 Q1 N( [1 { virtual bool IsReady() { return false; }1 J% h5 C) ?! L' o0 |, P
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
7 i9 c( [; H! u/ ~, {) i};
) N) q P& h& }$ T7 }
0 b1 b0 r8 j, U9 p
# {6 q' C7 m4 m- b8 W. x/////////////////////////////////////
7 J. p+ q' Z& N+ Z) |: a L//下面是使用windows操作系统自带的UPNP功能的子类
5 U+ i8 Z# M4 @3 ]: T9 A# k' p$ {
7 A. V6 N1 L1 w! n- e1 s/ f#pragma once" j9 t7 D \+ F4 `9 T1 L$ H
#pragma warning( disable: 4355 )
. j( o- x4 z7 N7 W* M: e( t) c
( z2 L! Y. t+ U6 ~- x$ Q9 Q) g D ^) w
#include "UPnPImpl.h"
/ b( g: X d6 }4 H$ r$ d#include <upnp.h>
9 x9 X8 H0 \, }% G- q" r' ^; K t3 d#include <iphlpapi.h>
/ Y$ x. h5 V( g; }8 ]* `. H: D#include <comdef.h>
0 Q7 q4 ~( i a) f4 C2 b# \#include <winsvc.h>
+ r: P2 X! v7 `+ m- F# E" T# J% f" i' O4 E6 j$ O4 W7 m) S
+ o+ a3 g. E& X# k* }. x0 v' b#include <vector>
- W8 ~( C, v2 u' L- R#include <exception>( V5 q) x' H; C0 A# R' O
#include <functional>
3 V9 i* F( I, S$ g# V/ }- \3 X- P' Q5 O
% w X6 {' f; w$ e/ t% o3 N, D$ z
' h) h# M' [6 V+ e# X
# q P+ K+ G3 h: h1 g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;8 p9 U. X- O* Z# i* \
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;0 C2 q% i; z/ O# S3 J% Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
$ n3 K8 D- _( ^, L- ~4 `typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;5 v. ~; u8 l, c! b
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 x* B/ s- s/ U) |2 Rtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
; W' {5 @, w9 m" {# `/ c: w8 qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& X2 ]& Z( U& R' ]$ r" E$ Q) a% h: x' [" w+ c
9 V: l2 N4 c3 C Ftypedef DWORD (WINAPI* TGetBestInterface) (2 j: _% X$ c$ V. ^' h6 n; Z
IPAddr dwDestAddr,
8 v! Y8 k% }- r; I0 Z5 z PDWORD pdwBestIfIndex& V9 r- O: `5 e& x
);; x6 h! S W8 P' F$ r1 K9 W
. I! R8 o( K+ n7 z3 E9 V; B# U* P3 |% }
typedef DWORD (WINAPI* TGetIpAddrTable) (
) E5 U7 W! Q8 D PMIB_IPADDRTABLE pIpAddrTable,- c' g- X7 }- i |: @; K
PULONG pdwSize,
6 i1 \3 A& i$ V% m+ G% @5 Q% j BOOL bOrder
* V* d9 ]( O% r0 r! s3 ^);4 u& ^: C2 |4 P( h4 K7 N' u# ~( a$ _
! J: ]6 N& V' h3 _
. l7 T& v" e& x; T) K
typedef DWORD (WINAPI* TGetIfEntry) (
% u9 j$ Q8 _7 F: u PMIB_IFROW pIfRow" E t( z7 Q0 o+ ^6 [3 Q
);
5 ?$ |4 j; _8 t7 k# O' }# y, N) E
2 a6 H; ~1 {; x" }
' K2 ~$ B8 T* G+ GCString translateUPnPResult(HRESULT hr);
" ]& b9 C9 e2 S- A& ]/ k6 l, M( cHRESULT UPnPMessage(HRESULT hr);, W4 v2 I: _6 Q
0 c" D1 O5 v' Y2 j* U: J- M4 C; M
9 D% _- l7 b) U8 N& ^' j9 rclass CUPnPImplWinServ: public CUPnPImpl
8 i1 |' g6 S; d$ Y9 ]{% l" f* G; s+ `
friend class CDeviceFinderCallback;
! e, g8 \+ X- q/ J9 h/ ~ friend class CServiceCallback;
8 G0 N) h# D5 |// Construction" [) Z9 m1 b, D
public:
" U5 }2 r. K( O# A6 H9 e% o virtual ~CUPnPImplWinServ();
5 y- E/ z# j0 o/ a1 o CUPnPImplWinServ();
8 F8 D: ~- x% x
# |7 R, v5 V! @
& ^: q0 J9 l. `% L" o& X7 k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }2 z1 N+ J/ o2 R- s/ O* o
virtual void StopAsyncFind();
% J' G! P/ o- q virtual void DeletePorts();2 F5 x2 C2 b: ^+ Y" p* ], d3 L: ^3 o
virtual bool IsReady();9 U* y; b" v# r U/ j: H. A
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }) C, ]$ n V* q4 T2 |
! u- K; s: p, P$ j
0 d5 f+ q$ B' a8 q+ C/ X0 P // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
7 K$ N* t: |/ `. n. p* E // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later! I T9 f6 ~( r8 m/ }
virtual bool CheckAndRefresh() { return false; };
* z$ }# g* Q- O" N8 x7 \' ?; h3 F- O* j% r) d% G
+ T# Z+ g8 r( s' g; K
protected:
- }, [! r- N1 v void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry); w0 N4 p. l/ {. L% \; ]5 t
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
; J- e$ u# S& q void RemoveDevice(CComBSTR bsUDN);
$ ~( _0 `. d% j" d Q bool OnSearchComplete();
0 [# t% K2 k `+ Z: I void Init();" o$ Y1 V F% p3 C# L- O
0 b; N7 p& v2 ^) P2 A! h1 E7 h# o- `* C$ ~3 x N7 u8 a
inline bool IsAsyncFindRunning()
: `: T# p0 Y' w- m& |; U {0 J/ ?& O4 Z L) k _8 \6 ]
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
& T, O$ z6 m7 x) b {& @4 Y$ X0 b" M# S' {% C
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
5 ]! F9 k8 j% ^6 ^* z$ g# k7 z m_bAsyncFindRunning = false;
2 i; Q! q( j, W6 M& R }
0 r; V% u. F/ \ MSG msg;
- _! J2 N& S1 n: t8 w while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
: J' L7 T' R; z) j0 k$ z* j- X; S( u5 [ {
( _8 G+ k; L m( A/ h2 D TranslateMessage( &msg );
# W' Q; F& H) J; ], ?1 F DispatchMessage( &msg );1 w; L4 h8 ?' c6 a' V R
}
r" m; ^' d8 A( H return m_bAsyncFindRunning;9 V. n8 o1 M! A9 B! K$ d9 x4 [
}
/ s$ R' G, S# L$ W& n( F8 ]
0 ` c* f5 P) b0 G
) j* @. ?. d" M; g. Y$ G TRISTATE m_bUPnPDeviceConnected;3 p: K* o* r& V5 F: @5 ?
' I5 d' Y, a' V6 r; F* |( E5 ~
1 [7 h% T% n4 [% T5 O- M( Z9 }
// Implementation
6 i0 S+ x# t- e: w // API functions
2 [0 W7 } x* V SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
" T% j7 T# v* o1 ] SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);! z/ T2 W ~4 ]" A
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);7 Y& t$ s6 N2 y% E8 Z: e
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' x1 T5 b- W5 k" o2 j BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
0 N1 q4 X* H9 q. z" S1 j BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
4 _; j/ i# e2 Z$ g+ o# |' Q; L& C* Z! N
, d/ |9 L* m! Y% d" D+ r8 l1 b2 S* r$ l4 o- R0 K
TGetBestInterface m_pfGetBestInterface;
) n& f8 \( Y, u8 o) ^ TGetIpAddrTable m_pfGetIpAddrTable;$ X; H+ l9 A/ L4 y" { I
TGetIfEntry m_pfGetIfEntry;* X3 f& ~- F) H, n" B
: k, G9 D: Y* ^0 L8 J" O% j) |' B$ Y' d2 N8 W6 \
static FinderPointer CreateFinderInstance();3 ?5 j6 p/ K# N& j" l
struct FindDevice : std::unary_function< DevicePointer, bool ># h3 L2 } l+ {3 |, [' L
{3 J1 Z2 j+ n ?$ Z7 b
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}* f/ K; ?( o1 k5 h9 p
result_type operator()(argument_type device) const# Y% l2 T6 I8 y' T. l( D6 ?* p3 P
{6 y0 ]% N1 m/ C! c4 J! i
CComBSTR deviceName;
3 q5 n. ]( b( a, |# k* I# n) Y HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 U9 V# G: z* p( w
1 W6 x6 Q: j* s& I$ s4 N0 D8 `% w
! a# s G& S4 R8 d* t if ( FAILED( hr ) )
* T# f6 s& I$ u5 |8 M return UPnPMessage( hr ), false;
% N/ I! v, I3 L9 r/ r' W$ T, Y
/ T- }" O. ]0 p. T- l( ^2 ?+ I" }& `8 o
return wcscmp( deviceName.m_str, m_udn ) == 0;1 F' g7 l% w7 v4 p
}
0 X3 E( [4 s1 t/ u$ L: E' f" h CComBSTR m_udn;. }0 j, w' |& H* B! l' i
};
* }* H: m- i9 g& Q( j$ _ , a' m( g s8 a$ l. A9 B
void ProcessAsyncFind(CComBSTR bsSearchType);, v! T( g% E6 ? H; D
HRESULT GetDeviceServices(DevicePointer pDevice);
- r9 X" R I8 _ void StartPortMapping();7 ~/ Z, I# L; a
HRESULT MapPort(const ServicePointer& service);* O I B4 L& h
void DeleteExistingPortMappings(ServicePointer pService);2 v. O; J5 ]3 P& L
void CreatePortMappings(ServicePointer pService);3 ^, i9 d7 A' Z2 V+ s2 g
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
8 ~- w7 o, |* O- H HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 }7 L/ b2 W7 P; g8 q3 b LPCTSTR pszInArgString, CString& strResult);
6 T8 g q+ n3 Q% ~- m( X# K5 E& P void StopUPnPService();
& v" m0 n# Q7 ]! S9 c" m; e# K
) a- \: }) A: n( \ B1 K l) Q, I: R9 i$ C7 |2 `3 ^" `
// Utility functions/ c( k9 n! ]6 |8 s' U
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa); ?9 D7 I; I+ ]
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
# p0 r% c) @' f: b INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: S: S) l r5 p. V+ T0 B6 I void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);6 v0 |4 J1 D1 c4 H G
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; e0 t2 B, @4 A2 r1 L: ]( M' ^ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);1 N4 o' A; J* m' }
CString GetLocalRoutableIP(ServicePointer pService);
- K7 d2 }9 \2 Z, Z6 H2 S, i0 G ^* n; Y' y. x
8 l3 B6 b8 a. p: F# l// Private members( P, l* M2 b" E9 X: G7 Y
private:, R6 a5 j) b; s6 H8 O" H
DWORD m_tLastEvent; // When the last event was received?
9 f" h7 x5 r5 {$ ? std::vector< DevicePointer > m_pDevices;
% j# C8 H; y9 n, r$ F std::vector< ServicePointer > m_pServices;
! o1 W- u6 Z" k: U FinderPointer m_pDeviceFinder;
$ _7 t8 M& m f: g4 m) W DeviceFinderCallback m_pDeviceFinderCallback;
2 k0 q- R% {, a/ L/ l( Y- {, ^4 Q ServiceCallback m_pServiceCallback;
5 k* ~$ X1 M) s) y N/ \7 r% t( s& E
' k' @0 ^7 {3 Y( f6 Q7 T2 v$ B& z I# l8 q2 V
LONG m_nAsyncFindHandle;
( V6 K$ C* P- T2 m! C9 K$ P1 J bool m_bCOM;
Z8 k* y" Y- J8 L bool m_bPortIsFree;' b3 v2 @5 G6 o) k% `: w3 h$ `/ a. d
CString m_sLocalIP;
3 d* ]+ z# l4 T& |/ J CString m_sExternalIP;
9 O1 Y; y; g3 }, G7 e0 @( J! p" O3 S bool m_bADSL; // Is the device ADSL?
% O6 I# g/ Y! V& P& H8 X bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
2 t( j) \# P _5 l7 T bool m_bInited;
6 u. `4 X6 U `3 q" F( v bool m_bAsyncFindRunning;+ p5 p6 h& m% V3 e
HMODULE m_hADVAPI32_DLL;/ {# W7 K2 s( B3 c% f3 q
HMODULE m_hIPHLPAPI_DLL;8 Q& X& w6 ~7 T. }
bool m_bSecondTry;: U E* t6 m1 x t E; l
bool m_bServiceStartedByEmule;
- ?4 \% A G) ^- c bool m_bDisableWANIPSetup;
, y3 C! a- @) w0 k. t' c/ l bool m_bDisableWANPPPSetup;
" r8 o _; `& E1 i% F$ f: q! [ k$ c; a5 b0 l7 H
. z1 J: |. F- |3 J/ r$ l4 {( b
};
4 |% X8 v4 Z( W9 c
b) R ~) N' V' g/ J. p! O: Z9 z) e
// DeviceFinder Callback" `) z& O% l/ Q/ L* J* T4 x
class CDeviceFinderCallback/ g5 F4 s+ v' I( d0 l7 v9 u9 t/ R
: public IUPnPDeviceFinderCallback
5 q1 e/ S; p0 R' c7 D5 v" _" l{
# U6 I$ ?+ M, q+ m4 \( Kpublic:
: q/ f1 F+ J. I) w CDeviceFinderCallback(CUPnPImplWinServ& instance)) {. I4 O' w! I6 B+ b
: m_instance( instance )0 t- T2 A% M3 H+ C6 V6 y& E
{ m_lRefCount = 0; }
3 I) q9 m2 I9 Z% I
) w7 M( ^# S7 h0 v. T# c
7 U" ]- ~+ T7 { STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);* m2 O7 ^9 f& l: ?6 P. l- \
STDMETHODIMP_(ULONG) AddRef();8 ~* X( m% t( E
STDMETHODIMP_(ULONG) Release();
9 E) b+ X/ U1 [- A7 K
6 a/ [8 y1 f% \- O4 _& \' x6 F- g$ K+ L. I! g5 |. W
// implementation: Z3 p) v6 j& N! U, P& s
private:
8 F: ]7 K7 I d* [4 I HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);# O+ A) H F6 @# G+ n
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
$ [# I, }. _2 T8 x HRESULT __stdcall SearchComplete(LONG nFindData);- V z+ s4 b( J& z/ g* {
8 c' A8 U5 c8 N, _" S- ]5 y) z& b
1 G2 J1 [$ `3 p3 N& D, c2 \private:4 J5 e* G, Q+ x7 r) `* z% l9 x S
CUPnPImplWinServ& m_instance;/ ^' J! n L& g3 N F7 Q
LONG m_lRefCount;
7 o. C6 }7 g- s. ]8 y6 R% K& F! J};
% J' O3 f1 S6 \. ~ @1 N# j T5 w5 f8 A* d; h8 c/ S1 H
3 T" i7 @7 E* c y
// Service Callback
. Y' ^. U$ ~- S5 O) V' ?class CServiceCallback
) W8 f# n3 A$ |/ f3 d. O : public IUPnPServiceCallback! K r6 m% d& [+ X" @8 e3 g. k
{2 o, l; Z0 y- y, ]) ~$ R0 S
public:% G2 m# P1 z5 V
CServiceCallback(CUPnPImplWinServ& instance)
g& K3 z) m$ f8 g : m_instance( instance )
7 Z. U- ^- z: k4 Z { m_lRefCount = 0; }, V, {" m4 I/ f" ?% c `7 T& s
2 \, X- @& W2 L% X( \ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) C3 R* w" X" p; m5 _# j/ o: W' O( U STDMETHODIMP_(ULONG) AddRef();/ b; f/ d8 W. X- ~/ K% h7 E; G
STDMETHODIMP_(ULONG) Release();) }+ j( n$ D$ r0 ^, S$ j
$ X; Y8 l a+ l7 Z) l" r5 T* ]
) h7 _* O) u! S/ W. M
// implementation
9 }* d: b8 ~# g, B& J" k7 o Aprivate:8 x+ q( T; D- P0 i5 h
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
: S9 U: o% j; N* a, b F HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
* w4 ?2 F6 ~7 ^9 M' G7 h* M
0 h3 G$ ^( ^3 x+ o
: G0 X: B( h: r, b7 [9 b% N: p( Hprivate:
9 f$ ~/ D, k5 K CUPnPImplWinServ& m_instance;
8 T! x7 s5 W; E- W5 ? LONG m_lRefCount;
# G: J7 T- x+ d+ X, P9 O};, S6 K# J( z; q8 m
! q9 w6 B @+ L% B; c, A1 E% L
: ~/ u% \( F7 q/////////////////////////////////////////////////
7 v& E, C, \0 J
6 S7 t$ C2 Y [" i; \# w# j( w) D' t. V3 v( o8 b
使用时只需要使用抽象类的接口。) t' w$ _9 r! j, Q, ~; S4 l! @4 d
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. H2 y: O# \( }
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口., p; p- W$ u e
CUPnPImpl::StopAsyncFind停止设备查找.
! h9 p8 e' S: W3 K# x9 P" r+ GCUPnPImpl::DeletePorts删除端口映射. |
|