|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule," e5 T/ u8 d( }. h
5 b1 _3 s& w+ N; L
% t' J' P' p1 v) O6 X9 S: E///////////////////////////////////////////
4 ^7 C, R+ {3 I& J- ?# v, N//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- r4 g9 y' W6 t v) x& B8 ]7 C) I1 i+ I# J0 n3 e% s% A( g
5 O' o. S6 _ ]2 h3 e. s0 v#pragma once
3 [, z# {! [* M: R#include <exception>
% |5 ?+ h' F0 F! M8 I' {% A, o2 A, `
) I4 E+ `4 ^3 j6 }; V2 Q
enum TRISTATE{9 m. z# C w7 B$ q9 L3 F3 `
TRIS_FALSE,! X* A& X @2 c# V6 ?
TRIS_UNKNOWN,, G. I) _- u& K! v$ \ D
TRIS_TRUE
7 S9 V. ]$ Q3 H/ A7 m};4 _. l3 B" M$ k; w
4 V0 v+ b( j5 h# o8 q8 N
9 c8 G9 \; p* U5 l: @4 s/ T9 V
enum UPNP_IMPLEMENTATION{
; z% q/ ~5 A; T* u/ G UPNP_IMPL_WINDOWSERVICE = 0,7 |9 G( v U+ H$ e# y; B
UPNP_IMPL_MINIUPNPLIB,2 d% v3 y% p0 o9 }$ ^8 x
UPNP_IMPL_NONE /*last*/; [- N8 }8 a- n; s
};
# `9 p% w; B: R& d# J# p; x# h) p- |) p E
3 T5 a C: E- n: t
" y# @6 m g- u5 M* ]
0 @3 x9 X0 o* V: M9 o; A* p2 jclass CUPnPImpl
U- F% e; |; M* Q, q{& N9 j1 P+ p' i3 g d( h
public:" h r1 A! O' _% _
CUPnPImpl();
; O: w d% L* \3 q; [ virtual ~CUPnPImpl();$ P$ s8 r# l) E& T ^* h7 O
struct UPnPError : std::exception {};
) E5 O% x0 ~9 }' k9 X+ Z) d enum {
X5 ?$ m8 S+ ]7 Y$ L UPNP_OK,+ ?; y: K* k8 E! E
UPNP_FAILED,
, d/ Z. C0 _+ l6 u* J b! e UPNP_TIMEOUT
1 c9 i# M: i. K0 x1 h# `% R };$ h( C! {+ e. ?% b- C
( H3 ?+ X. P8 F7 ]1 Z8 I& Y
" N! [/ U; ], }) e* E) W2 i; S# S virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;; V6 p+ Y$ Y! ^( K6 |% }2 F
virtual bool CheckAndRefresh() = 0;
, C; U- N3 ~1 N) M) ~ virtual void StopAsyncFind() = 0;$ g0 Y- j5 v/ f0 q
virtual void DeletePorts() = 0;% U0 R L+ f* e
virtual bool IsReady() = 0;+ n( P- T( K+ z
virtual int GetImplementationID() = 0;
/ \& g H5 \1 l/ u
0 P D7 ^- x d& T3 j: H, T void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 ^9 G! {# M' S2 r, K
2 H5 f6 ~( l8 G1 R* m. C
+ H" H% ~3 M" z& j$ A, s
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
! y p/ t' }% d TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: [8 c. d& R) E5 }! u' |
uint16 GetUsedTCPPort() { return m_nTCPPort; }
6 i# q* ?# w- Q, l8 {& S7 _+ M uint16 GetUsedUDPPort() { return m_nUDPPort; }
; H( `, S. b; a" J
6 v- B& ~# L ]1 M0 X
" v: S+ ~$ x$ k: T% z4 \! e N// Implementation
! m5 u: b+ \1 P4 Mprotected:
9 O( d. g; H( ~4 _9 ^ volatile TRISTATE m_bUPnPPortsForwarded;" S! Y5 Q: ]( v0 b" }6 J0 y
void SendResultMessage();
/ X& b; j. g: B% I# r) U. z; z uint16 m_nUDPPort;5 o7 k& M5 x) T. X0 J# Y, \% m" b9 N
uint16 m_nTCPPort;# U1 d1 h, W$ y+ U9 ~
uint16 m_nTCPWebPort;! v& `! @& C% p) Y" F' Q
bool m_bCheckAndRefresh;
* T4 s, V' X, X
' @, t) W% {5 }* J
8 N) H0 \" o0 \; ^5 @+ L6 r8 mprivate:! a- k# i7 {6 e' \
HWND m_hResultMessageWindow;- h0 }5 j3 r# T s- r' ^
UINT m_nResultMessageID;
! a0 R# R2 y5 }$ z1 M0 S- s. y8 M! ~9 ^0 o! r' k/ R" [
. a# o' m8 k% ]7 u$ W4 U
};" K2 ]% T- L4 d$ r8 a+ S. l
6 {$ n. |5 R' T- O1 @
0 {' [: M1 D: M: n3 C- r: x
// Dummy Implementation to be used when no other implementation is available9 d+ B$ f: C; D/ ~6 Z/ ]$ y
class CUPnPImplNone: public CUPnPImpl
- }* Y# ~9 Z a% R: g$ C{3 L- j" Z" B: r- s9 P8 T$ Y% F
public:" H, u& O: |6 j* K: F
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
I, h( n* N+ r7 V( U% ? virtual bool CheckAndRefresh() { return false; }
4 \& L& F* j M: _# R virtual void StopAsyncFind() { }
, m+ o0 j5 g3 E/ g- ` virtual void DeletePorts() { }7 e( h& ~; _' z2 r# |+ H, n& w# ~
virtual bool IsReady() { return false; }6 q# N& b7 h) U" h6 e* ^9 P
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, B, |7 ]( m0 J% L5 P};8 r& z5 [, z7 e* z& `
J# ?/ t) Z+ U
! a) g# D5 y' v, z
/////////////////////////////////////7 d9 ~4 p: T- F8 W" @, {& [/ ~
//下面是使用windows操作系统自带的UPNP功能的子类5 D9 t! D& Z* y+ m0 E" M
! a& j& @& |" d1 y6 L& V
+ i o" N+ N1 p8 x
#pragma once; W, { m" y9 E s3 x' [
#pragma warning( disable: 4355 )
6 F7 e1 c2 F ^' V" S) L* V9 x" S. @% M* J1 T
: {1 M. f4 R5 K; |& D$ v5 k
#include "UPnPImpl.h"8 M+ ]9 ]6 o" V3 ?. u! T2 e; b
#include <upnp.h>
% b& j( F7 m0 W#include <iphlpapi.h>! A4 K* A' O$ n2 ]
#include <comdef.h>
: J4 Y3 d+ b7 G' C) d; {#include <winsvc.h>1 D, ?1 z8 ]# i% z4 |6 x; m
6 @0 i$ d# U* S; k' A4 @6 h# c
2 I K3 w6 t2 P& q#include <vector>" g6 g p& k# R, J" c/ o6 g- a, q
#include <exception>: w3 n! A; I Q1 e p
#include <functional>) h. O* N7 I2 v+ T$ {
6 w( E2 F& p! P' H
( r" D( M# l$ u9 D5 o+ V/ U' F r; [; ~- T/ N& b9 h
- Q1 r/ t: A: P9 v6 xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;& ?, s/ u, D8 w
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) F& \, N- ]0 _" o" Z& f jtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
$ L7 p# r3 i4 m, o& M& f! {' w; Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
$ I, ?2 G1 m& ctypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
& v- P: S& }8 _7 Ltypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 j0 Q$ n) q5 e( H. btypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
! p O n7 E/ W: ?5 Z* n# {
! w% I1 s/ D, K2 }; O$ Q: l M& s3 a+ {# {* a
typedef DWORD (WINAPI* TGetBestInterface) (
" T# o5 n6 L, n( N# R IPAddr dwDestAddr,+ ]& z9 y1 J3 |2 w1 V1 Z8 X* m3 _3 v
PDWORD pdwBestIfIndex9 u( ?# G2 k A
);$ h+ Q5 [$ S1 N" p' `
* `2 Z, l' x ^
$ T# l. Q5 s# C* H9 Ttypedef DWORD (WINAPI* TGetIpAddrTable) (
: ?0 o9 Q: J% _9 I0 K2 F PMIB_IPADDRTABLE pIpAddrTable,
6 q8 t- @5 v/ T. ^# U: \ PULONG pdwSize,
5 M( T5 A; h2 B6 D BOOL bOrder2 ?' h$ G* {$ I& }
);6 x8 i; V7 I9 r; K1 `0 ?0 M. C
- w) ?/ D J* N4 ?8 C' j
0 y3 N# f$ v; o% U) [. x/ M; ytypedef DWORD (WINAPI* TGetIfEntry) (
' ]# z! w" U$ q- F! b PMIB_IFROW pIfRow8 F* q- E0 q3 L" [# v
);
4 @) c& Q$ ?: r( h' Y% i
% m9 v) ?! G0 A6 G
! | L' S0 Q3 A, D+ n! v* U$ s9 fCString translateUPnPResult(HRESULT hr);
Z) r# F+ J# b; hHRESULT UPnPMessage(HRESULT hr);3 J" C& P# C; ^9 p E
' d* M- Z5 @' c! Q( b" `
! R. y/ U# e' t3 i1 S" Eclass CUPnPImplWinServ: public CUPnPImpl3 k- H; [% K+ v: p- q% \
{
, _: j( }4 S( K, A* B friend class CDeviceFinderCallback;
8 U% z5 ~, e$ S! m# @4 u friend class CServiceCallback;! R3 |1 Z# V1 {5 Y1 a
// Construction' ^, _, E/ C* R
public:
" d* r( L0 x4 W& G0 U virtual ~CUPnPImplWinServ();( J) i% _" Y; |6 b8 K
CUPnPImplWinServ();' `1 j+ H$ U/ K3 m! v; F. ]
- m9 F5 `$ r2 v, X. ~
3 m1 f: ?- ?9 p( n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }4 b' o- f9 M) F! ^2 A
virtual void StopAsyncFind();
$ a1 `8 b- o, y( C k6 X* K% B3 [4 q virtual void DeletePorts();
- Y* [' Z5 U: T2 A5 j, y1 N& f virtual bool IsReady();
8 L9 ]4 [" ?. Q6 N virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
8 ~% T2 N9 h3 k% c5 `- q+ H0 i. h9 o K8 p0 u
/ s. Q5 a. T m4 k: H: F
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
' [4 g7 F0 ^2 H' \8 V3 [1 f // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
% T b" g2 U3 i9 ` virtual bool CheckAndRefresh() { return false; };: N" J8 n+ l1 }! k2 C- Z9 j0 g
- \9 S5 S# y! T. Z& s
2 x% W( s* Z0 @2 Fprotected:
. S5 G! _* G, r! K/ ]( z1 g void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) U8 {( i( {* S5 @ u( g4 Z1 U void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);! I5 O' p* Z( K. r+ k
void RemoveDevice(CComBSTR bsUDN);+ R1 q# E$ _, K
bool OnSearchComplete();, S/ [" w( f- B# }( k: j& `! J5 t
void Init();& M# R2 k% t9 ~. o
; J1 e2 `5 @* e' y8 c N& k* }6 Q( }0 R+ H% ^- A
inline bool IsAsyncFindRunning() $ E( h6 f$ y7 k% Z# M6 b* S
{
! M+ U! c3 H# V) W: p" F& S if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
4 k% A- x: [9 \" ?% r# S: ?1 j {
3 d3 J3 n) v) d- s) W m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
' H" o3 n) B$ t( q, a% w: G m_bAsyncFindRunning = false;; c; F, f$ l9 P- C0 Z
}
6 |; h# T) j4 t0 L MSG msg;' _( F) i$ S! D+ G5 c
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ), H: |9 T" Q0 n9 N( Z1 |; }
{* J& Z, i r* u0 J$ ^ x" W
TranslateMessage( &msg );, e G. E! a$ B+ B" m5 o J0 V
DispatchMessage( &msg );
2 j. Y. K6 y7 M0 Q: \ }; g$ N* _' J$ w# ^5 I
return m_bAsyncFindRunning;
- \8 D7 ?' `% R8 a# d# p# c }
6 {0 o) b9 A$ V( g$ r) J9 A: K6 f: R# Z& N( @5 X
* Z1 l Q s6 f/ j, b- b4 H X; q1 e
TRISTATE m_bUPnPDeviceConnected;
# W7 i0 `; w* ^$ K
1 r9 d! }- w; \
1 A+ O; n9 c8 j/ x3 E+ J// Implementation
7 v2 ]0 j9 i9 i' }6 { B6 S // API functions. V6 t8 U3 E i( _" Q$ i
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);8 c: z' D B8 K: [, v
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);. T( j( c; R$ W7 L
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 s, q' l/ ~: k1 t. {3 Z! ~* K BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
8 ]( T9 v- L8 I; \/ K BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
3 g9 |; R1 d" D' p" F; k7 b) C BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);0 {' ^4 U! r# g# l0 A! X
" C$ F/ v5 n+ L: G
7 |2 d5 F8 v8 m+ t; S TGetBestInterface m_pfGetBestInterface;0 H$ p6 B! M( j
TGetIpAddrTable m_pfGetIpAddrTable;
1 C$ N% k! F" U2 W/ ~/ Z. r& F TGetIfEntry m_pfGetIfEntry;
% M6 P" U/ Z/ T3 C5 u% W. S, h+ W
: I @8 L9 u" Z( f! V* U) d$ b
static FinderPointer CreateFinderInstance();
+ D6 t9 i0 S8 }" w2 v# h struct FindDevice : std::unary_function< DevicePointer, bool >
4 d/ R/ a& q- ] {
7 W% `/ R/ ~2 j3 G FindDevice(const CComBSTR& udn) : m_udn( udn ) {}1 m0 y0 _0 f5 |7 b" n
result_type operator()(argument_type device) const( I* E4 _& s" x: {+ D% W
{
, @' i% q8 m9 H. }5 _$ s4 ^ CComBSTR deviceName;* q/ M; h% O5 h: i
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& L8 N) F, c- k) ]
5 U! F) {. g' V. ~) e8 M4 i% j
9 o8 D( o+ H4 s0 r if ( FAILED( hr ) ): C4 I$ W8 \6 H4 B/ J& e
return UPnPMessage( hr ), false;- L6 {; d: I8 @5 f
# y- z) ?' ], F) o
" t. r* Y7 Q: ^4 i2 r- l+ J+ x i; |
return wcscmp( deviceName.m_str, m_udn ) == 0;
- [& ^* w6 h& }3 n% D( r: s$ s }
: Y9 @; h& c- H7 j+ J. O% N CComBSTR m_udn;
1 a6 N6 _, R% e' I };
c3 I5 P* }" ?" Q( |* Q/ F. W* c
) }! j+ }% M' `2 [5 ~- i" t void ProcessAsyncFind(CComBSTR bsSearchType);
f" }- \( b: w- | HRESULT GetDeviceServices(DevicePointer pDevice);; E6 y+ s5 l/ ?2 ]6 O$ L/ z, b
void StartPortMapping();5 J% S! |$ M9 {: k3 j. W) \5 F, y, s
HRESULT MapPort(const ServicePointer& service);. N- y' v4 d! E3 `3 ^- S
void DeleteExistingPortMappings(ServicePointer pService);
0 U7 R% |( T# Z1 J& s |- Z void CreatePortMappings(ServicePointer pService);
# }) _! n$ K4 R2 p- ]+ {( G HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
$ H$ Q0 S1 z6 H7 d3 Y2 G: H HRESULT InvokeAction(ServicePointer pService, CComBSTR action, * L5 x1 n' \- x/ K9 S- v/ a1 T
LPCTSTR pszInArgString, CString& strResult);+ ^7 a4 w" H; { f
void StopUPnPService();
1 m( ?0 e. R+ n/ o$ Z- b3 ]' |4 z9 Z6 o% S k! ?- x
\0 v! N+ L$ ?) o) \- o // Utility functions
& V7 k7 S6 _; t! n: X HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ W; U: @4 P+ o( Q( V6 s8 m0 A* {/ u) s
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ @& v7 V2 S- j6 ^! u( I
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);1 v" r% @* ]- O6 x% T7 q
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);" C# h: o: b2 c' D- e0 N* w- k5 {
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
- E0 T& m8 t# F& I/ c HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
+ E, G9 l, Y9 }& ~# Z4 X" [9 ? CString GetLocalRoutableIP(ServicePointer pService);$ t7 T# c$ C. ]( F1 ?$ j" w* [
- [1 z- H8 w/ m/ c# M8 o
& ?5 q, _$ V' ^# E# }7 ^) y; n// Private members
% x" S5 M+ Y/ t% A0 Lprivate:
7 A p$ m; H- A$ a; F; c DWORD m_tLastEvent; // When the last event was received?
9 v. ]3 ?' L6 c } std::vector< DevicePointer > m_pDevices;
* g& W' d$ M/ Z0 E9 f" z std::vector< ServicePointer > m_pServices;" G- Z% ]% K2 p4 Q. u
FinderPointer m_pDeviceFinder;
5 y& R: V% n. s DeviceFinderCallback m_pDeviceFinderCallback;0 H* T4 T8 g/ I
ServiceCallback m_pServiceCallback;
) Y: i: |! Z# {! t) j" c4 J' ~% v8 Z6 p' e
" j( o8 m! y& L3 o: o. J G
LONG m_nAsyncFindHandle;4 x( c& D. a( l$ G; y1 t, r
bool m_bCOM;
# {9 B1 p0 y9 C' v$ F7 w bool m_bPortIsFree;) z) H% u8 y9 ?' V. ]# l2 s
CString m_sLocalIP;
$ |+ f5 g" Z) D CString m_sExternalIP;
8 d* G( i$ s8 H/ S; M bool m_bADSL; // Is the device ADSL?
) H1 E7 L/ _- ?& ~0 y bool m_ADSLFailed; // Did port mapping failed for the ADSL device?$ I7 P- g8 i i. j( [# w
bool m_bInited;/ i( f* \* X6 ^3 n
bool m_bAsyncFindRunning;- {% r. U4 C& u' C
HMODULE m_hADVAPI32_DLL;9 o, M) I2 G( @2 g" k
HMODULE m_hIPHLPAPI_DLL;4 m0 s% `# ]& s3 z4 O+ H
bool m_bSecondTry;* a; H# v$ G: k
bool m_bServiceStartedByEmule;
g1 |! X- y7 _ bool m_bDisableWANIPSetup;1 u4 k; ~6 M9 S+ s' B) ` b9 H
bool m_bDisableWANPPPSetup;) P0 O7 c9 Z6 }: z$ S: ?
) V; t& `' q, H8 T; X2 I3 i! j# c$ H
0 n% m# v: S# u- K) a" k- ]};
7 p, m1 H1 J2 c, i9 {3 e/ \4 F% G/ C8 w8 D4 ~
, }, Y- S$ o6 n6 g// DeviceFinder Callback1 c- b1 J4 _. s0 z
class CDeviceFinderCallback3 O# ?, d7 [7 k$ T
: public IUPnPDeviceFinderCallback
; B% d5 {" C$ [( h& ^# Q{
7 i% J5 L# |2 j$ \8 x, upublic:
7 U8 ?) g. |# }4 f. x( n CDeviceFinderCallback(CUPnPImplWinServ& instance)
" ^, Z5 C( f* G& I9 O* D : m_instance( instance )6 |4 c8 X# }/ B: z5 _8 Y4 K
{ m_lRefCount = 0; }1 z/ j3 T) B7 m: I( Z( @: q
( w! C: w4 ] G2 f6 V5 \- b) a9 w# N
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 ?" X2 X, C% I% z( O STDMETHODIMP_(ULONG) AddRef();- x, h6 o+ W. F1 F/ R
STDMETHODIMP_(ULONG) Release();% M6 R3 e9 K. s! ]) p
y! u4 q% ], }% k
- b, \: S2 q5 w2 f0 i+ |; M% G2 n, _// implementation2 j0 r1 s2 U8 D/ w+ N9 o2 u
private:
+ W; S5 O& @/ O2 X( t HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
9 q) R7 W: c! t/ c1 S3 O* E HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
- I9 `8 o( E0 f$ S: d8 F( d! K/ ? HRESULT __stdcall SearchComplete(LONG nFindData);2 ~; A$ q% X+ {$ f( k
: a$ G; K* e; N* a3 | T4 b- Q0 M: y6 R+ j) ?2 K
private:" X0 O P4 x$ {7 g, [0 {
CUPnPImplWinServ& m_instance;7 \ K; c. N- D2 `" k: V
LONG m_lRefCount;# E+ _7 z% \% m
};. b4 l- o( y- R$ g3 {. A. S
% V8 }( E; ^( l7 f, o
+ R1 y) g. D6 h9 {// Service Callback # D( T4 Z6 }4 i* r7 c) M
class CServiceCallback8 R/ z7 N4 [* U) X3 z( t, Z" I
: public IUPnPServiceCallback
0 B2 a3 ~2 Q6 J{% ]# b" r% r" m7 F
public:$ t1 A! U% Y! L' V
CServiceCallback(CUPnPImplWinServ& instance)
8 q F& X. [' c' [3 z : m_instance( instance )
8 H" b7 \, q' X. Y: }6 T { m_lRefCount = 0; }
+ p3 H0 ~: f. M- l
5 t1 m y# T6 i( i5 L! w( G STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 L1 b" r( F2 B
STDMETHODIMP_(ULONG) AddRef();, ]) N9 ?6 G2 c! e F
STDMETHODIMP_(ULONG) Release();
* Q* s3 }/ X& H y7 ~7 G5 y. I9 z* ~0 m* f( K) M5 n6 q! [+ E
/ I" @9 F6 F% G) I% D
// implementation( C5 b$ O2 x% X) Z1 C+ C7 v
private:* D* R0 x0 K4 |* [( w @% \
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- o# P2 t# x' Z3 ?+ i HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 G4 e; {8 d: e: T/ P8 m; J& p) Q0 S2 S/ ]* r/ s- S% z
# U0 F" Y* O" u S+ E7 F
private:! S; h/ w* S, N" t0 A
CUPnPImplWinServ& m_instance;) J7 V( {! U2 T6 c" f8 n
LONG m_lRefCount;4 o& f% @! q/ Y% i N
};$ [. z! ~$ k [* N8 x
6 v- Y+ R4 F& @8 D- {5 n, n- L4 R# ? |. d+ ~$ H: ~
/////////////////////////////////////////////////& V, U. x! j7 v4 F1 U4 g2 | C
! m% _# d' g' _* l: Y9 K! i+ U9 H
- L8 M0 z8 Q9 y; f; B- K# ^: m9 N% q8 d使用时只需要使用抽象类的接口。
$ c6 u) V' u8 b' \CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.2 y5 o* [- E( O) d. B
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! d4 d3 e- g# K @0 {, k! CCUPnPImpl::StopAsyncFind停止设备查找.
1 C) O+ M2 Z$ |% L, F: W O0 ^: wCUPnPImpl::DeletePorts删除端口映射. |
|