|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
( R3 G# S& R/ p" A. x; x$ P+ J& Y9 a% J
7 }6 V' r$ M* k% C$ w
///////////////////////////////////////////9 r- u0 v" M* z7 ^6 _- L1 R6 E" V
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.* G' `; ?+ x4 k8 Q8 F
3 z7 O$ j0 k; \. u: `# O ~* w" S
) n" a" Z0 [9 V" a9 T: v#pragma once% A% w- z/ I# R4 @) z, [* N0 r* J) {
#include <exception>$ g2 X3 P0 @/ V: e$ S
/ h3 b9 {) u) k$ ]. f7 C0 R% o
" y% o- B1 M f
enum TRISTATE{. @! p2 a/ I( N* Z* Z
TRIS_FALSE,6 X" o, p$ A2 ?) W. \( K
TRIS_UNKNOWN,1 ^8 A: Y% L l n
TRIS_TRUE
' D/ b" }' U S: g6 I# L5 h5 u};
/ @8 N2 m3 M* p u
! q4 H! d0 X# L9 L, R
3 \( D) M9 P* J/ |enum UPNP_IMPLEMENTATION{- K. r' P5 F/ d" h# `
UPNP_IMPL_WINDOWSERVICE = 0,0 ^& H0 M4 n9 c. @
UPNP_IMPL_MINIUPNPLIB,# W7 y) i5 D% L# p' V
UPNP_IMPL_NONE /*last*/( y" a- k3 l) I5 Q. t# [$ p1 ^
};
# B8 `' r& W3 p$ {9 }6 A: E8 M+ [3 S
( M6 \# m5 g ?( V& l' M" `
4 {, ]9 S- j, D, ^0 p h" U+ w5 w e9 t# _* p
class CUPnPImpl
; R% K; }' E- [. H; {{5 e6 L' Q' l+ Q. r5 C
public:; s# }8 l# c% Q9 T/ Q! i
CUPnPImpl();
4 ^8 E, ^* i0 j. f) J virtual ~CUPnPImpl();
8 {% ?' k3 W% B, R struct UPnPError : std::exception {};" c' y7 E4 T' ^- \7 A& C7 f$ j1 R
enum {: u! G5 Q4 ?8 N: x, @
UPNP_OK,3 Z/ b2 S& K& c& Z; n0 e/ y. I
UPNP_FAILED,0 w7 |6 n! V( J: S
UPNP_TIMEOUT
f' `: G; X0 h5 F7 C* N: X& J/ x) s };
. W* Z, X k0 [) D
7 ?3 p* o6 Q, W( }
0 b7 n' I: k4 x1 K- u+ H( b virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
+ m& r' z+ n9 F/ P virtual bool CheckAndRefresh() = 0;
0 v, K( _) n! h2 m: P5 j9 r virtual void StopAsyncFind() = 0;
- ]$ Z2 e- P+ z7 \ virtual void DeletePorts() = 0;9 Z& i& }2 c9 Y! a$ d
virtual bool IsReady() = 0;
0 h( g! h+ \, r' T) ]9 ^ virtual int GetImplementationID() = 0;
/ ^7 c" i8 m# e3 f2 h! f' Y v5 u* W* d3 v. ?1 o
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
|0 M( e) T0 a0 e3 P' @0 e$ O2 Y$ Q
* A6 j) F5 @* K void SetMessageOnResult(HWND hWindow, UINT nMessageID);5 c% \ \5 ]7 M, t/ s/ o B
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: z; Q5 D4 {- ?: |* I8 ~$ j
uint16 GetUsedTCPPort() { return m_nTCPPort; }) m! p: | d; i
uint16 GetUsedUDPPort() { return m_nUDPPort; } ( U6 A0 C! \' p# f: i4 M
~: u! F7 g' M, @ G, x
8 I+ h. z, G; a+ I; [% f, \8 t
// Implementation' F& J. C2 C; n$ r
protected:
0 C! R; d1 M9 ^+ O3 f- U- s volatile TRISTATE m_bUPnPPortsForwarded;
5 z0 V3 D0 z: G7 A/ L+ U void SendResultMessage();# g7 Y3 V; p6 G4 c# w8 B
uint16 m_nUDPPort;6 M- B/ w0 d- e7 v
uint16 m_nTCPPort;! V* v& \, N& |/ O! V0 C& ^; B ^
uint16 m_nTCPWebPort;8 k2 B) V" l& c2 q2 q( l4 H
bool m_bCheckAndRefresh;% B! ~. r! A! ~" A. Z+ l& N7 b
: `3 Q: C& v8 x' ]7 O9 ^
! \% ], M% W) O6 Q7 W+ i
private:
7 T/ L% M5 J% U0 p9 k# i HWND m_hResultMessageWindow;
5 T* ^. B+ Q+ [$ x: R" P UINT m_nResultMessageID;- _' y& @! m& v- Q. F: e
% G! c4 k/ \4 @' C
( C* n7 E$ X9 A3 B1 I! i7 M( q
}; f. t: Z$ D2 P- s0 Q
) f# `2 f& l6 ]- T y
* K: G- r; M4 @, S% ?
// Dummy Implementation to be used when no other implementation is available
' P6 Y5 B) g, v; F( x( Qclass CUPnPImplNone: public CUPnPImpl
. v7 a% @# j! ~, [# t0 A{
" d6 P' K" O# g8 n% z; p/ ^, n8 Fpublic:
( G) b+ s% U$ D+ |# B7 Q' S virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }' O5 j" {: N8 b* d e8 d
virtual bool CheckAndRefresh() { return false; }
: b( L4 V5 {) T7 j" v virtual void StopAsyncFind() { }" p2 _8 ^, X1 h
virtual void DeletePorts() { }
; [8 F* z. t& h5 | virtual bool IsReady() { return false; }
1 F9 U- L9 c% I virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
$ a; G) x- G. B; p9 T};) n$ s0 \1 C# ?6 g# u6 }
" Y5 J0 q( |; t+ O8 g' d* R7 }$ h9 _- q, b8 {/ `& ]
/////////////////////////////////////7 ^. Y) x( h- P" v G. u+ a
//下面是使用windows操作系统自带的UPNP功能的子类7 O5 c, M% g; z( A
5 T/ B0 w3 B Q/ g3 g
5 z- `2 q* V$ T
#pragma once' u. n$ h' V6 W4 K9 a& f
#pragma warning( disable: 4355 )4 R7 y. Y( D: G" M
4 K+ }1 S3 Y; L* G m3 m0 B' T9 ? u; d( t
#include "UPnPImpl.h"- m+ E3 D1 Q& r J F
#include <upnp.h>, C' x1 [* |$ p/ m* j
#include <iphlpapi.h>9 C# Q4 ]" `$ u( q8 ^
#include <comdef.h>$ d$ ^, Y' _$ P9 i0 k! s
#include <winsvc.h>7 t* s2 n) t M" h2 Y. S
' s4 F9 K# f2 f+ X
0 |9 O9 T( m3 y( ]7 S# `9 v
#include <vector> {- j( R2 ]' E! @' Z! Q _% a0 d
#include <exception>
8 z+ I9 V) ^' k6 F9 J#include <functional>
0 ?( n( t; U# N% B* N+ v; `0 j2 w0 Z& ?# q: [. c1 w. @
- p+ u0 e$ v8 H$ L% W9 K
# X; S/ R0 e( @6 Y) k6 H; A9 H$ ^0 r0 T7 Y% x+ D' b5 x
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;; F" e' u) c W6 q+ A* W
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;9 o7 ?7 g$ }; n+ l: C
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" ~5 f; b9 I' T0 z6 f
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;; g8 |/ \2 I7 L) c; @( e4 j3 I, h
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
1 @" Y( t' I0 B& d0 E8 _typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
7 v% L% j4 d2 `" k/ Gtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;. p! R+ h5 V* ^% Y& T5 [% A
& F" t4 F* J. g% k& w- E
7 Y" q1 r$ K# |+ F1 V3 c- c# stypedef DWORD (WINAPI* TGetBestInterface) ( A( f2 ^! U& S# g
IPAddr dwDestAddr,+ o; r+ c" {$ a/ S4 R
PDWORD pdwBestIfIndex5 J/ s& q3 V" I; n8 ~
);
$ l( u& k! f* _
5 f% e+ O7 l) u7 {! ^# [& L* G
6 A- [( Q; p4 O ctypedef DWORD (WINAPI* TGetIpAddrTable) (6 m: S. m+ S2 M1 p6 ^4 [
PMIB_IPADDRTABLE pIpAddrTable,/ E$ K8 z! [$ u( w& Y: ~* A
PULONG pdwSize,; H: ]% D1 E% I% b3 \
BOOL bOrder
+ @0 y1 `$ n; R( f+ [) R);
% P* H* Q. J7 |# a$ O! i1 T6 _& ~+ V$ F7 O1 \
( Y8 `/ X3 F0 ]0 m( {typedef DWORD (WINAPI* TGetIfEntry) (
. D& z" T* q* y& L, C PMIB_IFROW pIfRow' W* }, @5 f7 c# P; s
);$ u$ A" ?3 S9 S5 F% g \
& K- G+ _ r V
# Q/ M* h* H& Y6 n
CString translateUPnPResult(HRESULT hr);' z- q$ {. ]# z' _% A0 }$ \
HRESULT UPnPMessage(HRESULT hr);
. j1 `( F, p# [ ?% w9 K/ d$ Z% T4 L8 o
- e8 n8 S$ o* _/ r2 G- N, H
class CUPnPImplWinServ: public CUPnPImpl- K" z" t, y+ {! E* s2 @$ \' ~9 {$ |
{
0 w1 h, L6 H9 c5 [: T8 u$ l: N3 X' h2 S friend class CDeviceFinderCallback;
& y7 u2 l+ V* \; x( F2 u friend class CServiceCallback;
* H7 \# I7 R* D" j' r// Construction% D/ @9 X/ u$ z; M3 X3 k
public:
. O6 }1 z1 o* K; k$ }% w# \4 Z virtual ~CUPnPImplWinServ();) J! m8 x6 {- X: a' I3 W2 e
CUPnPImplWinServ();
* U, |/ P* e5 @9 K+ z, I; @5 y: i% }8 L- E! g- B D2 y
W; K ` m( J: A. A- z
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }* Y: B; |) Q |5 L/ d5 y* N; J) }
virtual void StopAsyncFind();
) [' ~' j8 O, Q/ E* i; w virtual void DeletePorts();0 @9 ~. f% K4 v! f( v
virtual bool IsReady();
7 E, A+ P; S6 t1 r) C" o" | virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
+ A! T0 A7 @' U3 C2 C# m7 {8 m! \+ b5 }+ D
3 ]/ Y6 @2 r# Y" O8 U) Q
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 @4 K, |7 g, \9 V. r // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
( O1 d: b+ F% t( S8 r1 A virtual bool CheckAndRefresh() { return false; };
7 f$ x1 i( t/ }- |8 ?: l, M7 n8 E# ~& y1 o7 }; C; j0 N, d# L9 L k
" Y8 ]( g5 O1 n
protected:
/ i& H" b+ o- @" z/ L void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);: o) Q3 p; [3 j0 s6 P; O! K, T
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);9 x) k" Q& ~$ }
void RemoveDevice(CComBSTR bsUDN);
7 y2 r* r; S9 w8 ?, S7 q bool OnSearchComplete();/ R4 f$ D R) ?! P; E: e
void Init();
& U3 h3 O/ ?& g- H* R+ S
( z9 [( C8 |9 _( W
; r/ M# D( C8 h5 W l: | inline bool IsAsyncFindRunning()
H Z4 x' f Y9 w3 R {( c0 ~7 d4 `2 l2 p
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )' E- g y# n( F) O% i
{
# n: W9 ^/ s, d6 ]6 O# |1 \* D# i m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( Y$ n I7 c/ p- Y$ z" j- U& X m_bAsyncFindRunning = false;
$ w5 u, Z; {! H& _: z }5 h; n8 B- q; @1 K+ ~, x
MSG msg;) N. B& F" s3 N" n k3 N, H$ r
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )" {3 [! _4 ?! a! l
{0 j6 o- i9 Y% {/ `. [
TranslateMessage( &msg );
. q' N( E' o, f1 d DispatchMessage( &msg );0 L4 w$ _0 I0 ~5 g; p1 D
}
- `- C8 e; v) d+ K3 I return m_bAsyncFindRunning;' x, R# C/ d" ]+ C/ \- W
}
8 }$ Q% |) S6 T' M
0 P6 |/ }/ E0 P) S
* C& T2 I: X9 \: L' y; _ TRISTATE m_bUPnPDeviceConnected;
! s# e% w5 ~! s1 c: }! E7 k1 K2 _' E3 {: ?6 C
8 h4 T1 Z+ o. T# g// Implementation
' S4 R; `& y( l6 @( [& ~! S6 | // API functions. V' E) k. p: `- ~7 L2 J; u
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
. ?( G0 L* S% @5 ?& F9 y" o SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);$ b& e. A5 K' s. b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);. U- u9 k' x# {5 c
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);- O2 J9 O8 K& `
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);; _3 ^4 q6 s& F. s+ {
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
- @% i& G7 I8 Q2 `( S( V5 Z
0 T4 d _8 S. [. P& {0 c
7 X% ]9 U; \1 m4 r; L TGetBestInterface m_pfGetBestInterface;! }' \/ |. Y& r) e% h$ N: |' [8 ^
TGetIpAddrTable m_pfGetIpAddrTable;: L6 [8 n: ^" u
TGetIfEntry m_pfGetIfEntry;
1 I+ ?! C7 ^' g* x
8 ~! T9 q e7 q8 j* O
2 V9 j* p7 Q8 S7 \+ r& }! ? Z static FinderPointer CreateFinderInstance();
/ i% p4 ]$ [3 I( A+ ]5 [* _ struct FindDevice : std::unary_function< DevicePointer, bool >
. O9 S8 _2 K9 {, Q/ W4 S {" o& b, W: N9 t w
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}; {$ H1 ], K- {" y N' o, p
result_type operator()(argument_type device) const/ |0 g. `% k3 R) y4 h
{
: f& f8 _/ Z6 r: v8 C* [- |! Q& R CComBSTR deviceName;
. @* C+ r+ s8 E4 @& N HRESULT hr = device->get_UniqueDeviceName( &deviceName );3 E2 t; J7 G. y
5 n/ f9 \) w7 X1 G: F8 z5 l
: l6 v+ Q) F; ]$ m0 Y* O2 b0 d8 Q
if ( FAILED( hr ) )- ]) w# j) O; J6 x7 e- ^5 h4 {+ l! H
return UPnPMessage( hr ), false;
) ~$ O1 r' N( g+ V. O/ i
/ d7 b9 F7 F: ?# K! w9 G: u+ K& z, ?6 u
return wcscmp( deviceName.m_str, m_udn ) == 0;
g8 A3 k0 v* R7 G7 j }* h: d" X$ F0 O5 d% u
CComBSTR m_udn;. j+ ~1 S1 Z. @) C5 q9 a
};% x4 y/ m1 M- j1 a+ V- C% `4 c
9 I A2 F0 o8 T% v9 i$ k- O5 s
void ProcessAsyncFind(CComBSTR bsSearchType);2 ^; z; e6 H- n8 @; H4 B
HRESULT GetDeviceServices(DevicePointer pDevice); V$ d8 U( w# [2 `0 S
void StartPortMapping();
- d. a5 ]; V8 a, |1 \( r7 K HRESULT MapPort(const ServicePointer& service);& a3 p5 P' m# a. c% a
void DeleteExistingPortMappings(ServicePointer pService);, a: }2 J. r r+ |; C9 a( ?& O
void CreatePortMappings(ServicePointer pService);
2 `+ |$ p# d3 \5 m7 a8 @ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);* q; q A; V) c2 X: ]
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
- p9 j& |3 c3 Z4 y1 e LPCTSTR pszInArgString, CString& strResult);7 F& h0 v! }# z6 K3 e
void StopUPnPService();2 @# D& L5 p1 G7 U) Y
% z6 K6 ?7 l. Y9 s V) u
- _: J/ I; \) q
// Utility functions
7 y; z1 b q5 Q( t# c+ P HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
, ^, Y0 `2 H3 ?, u6 n INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
8 ^) W, K( J6 g6 a+ ?7 m INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);4 D y; y' i2 `' B |
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ b( g7 M% c& E' i- \
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound); D7 n! f" Z; }, Y' u4 @' A) ^( [
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);2 {7 O8 [ S8 B% q; W9 b
CString GetLocalRoutableIP(ServicePointer pService);
* K* `; z! b( x6 a1 X
$ ]! I) X( g) [ j) f
5 \) ^5 W. p% \6 Q5 D- f9 R+ q// Private members3 b. e& F: J- j1 \; H& j
private:
, }% }8 r& `: U# M! R5 c* H+ G DWORD m_tLastEvent; // When the last event was received?
& z0 E! _' C6 V8 o" B8 W std::vector< DevicePointer > m_pDevices;2 S6 J+ i; n/ W5 r) w: d7 ]4 T
std::vector< ServicePointer > m_pServices;+ x; \% }/ G7 L1 A; U2 ?- f
FinderPointer m_pDeviceFinder;+ ^: ^8 ?/ k ]; ?0 N
DeviceFinderCallback m_pDeviceFinderCallback;
6 m9 y) o) U: j9 k2 P7 J ServiceCallback m_pServiceCallback;0 T* J' A t/ Y9 R: p2 }
. m+ q/ m$ i7 a# l% U7 k& Q! O/ c7 g/ f& Z. O% @* m
LONG m_nAsyncFindHandle;
" R( c; D! w2 U bool m_bCOM;1 L$ C$ w6 R3 t) P
bool m_bPortIsFree;
4 |1 \; |" ?* S CString m_sLocalIP; w& o% X3 X4 n3 ^! r; k
CString m_sExternalIP;
5 D# K) t1 O, t: u! q+ f+ @ bool m_bADSL; // Is the device ADSL?, B! h0 y- B8 A8 _6 A- u' m& h
bool m_ADSLFailed; // Did port mapping failed for the ADSL device? X1 v( l5 [% E2 _5 ]4 H
bool m_bInited;5 L% z% t& |: L
bool m_bAsyncFindRunning;! w% }2 h+ X6 l1 Y
HMODULE m_hADVAPI32_DLL;, d* |5 p, G8 n9 A) l' r7 ~
HMODULE m_hIPHLPAPI_DLL;- Z7 n! a, s+ g% D5 G; ~
bool m_bSecondTry; P2 P5 s, ?* d3 ^* z
bool m_bServiceStartedByEmule;
8 F. Q; n {5 y6 h# V' u" @ bool m_bDisableWANIPSetup;
3 q4 D$ F2 h. q* s bool m_bDisableWANPPPSetup;
7 \; Y$ d: n0 b# ~; l/ K3 c) L4 r: X3 v
2 l& t# C4 _. N" J/ [+ K};
' z( Y4 `6 y3 |! ^' N }( I' p5 ?9 S6 n0 y5 K
, Z0 |. q$ u6 S8 U5 ]9 k, @// DeviceFinder Callback y, Z, h j& q, N
class CDeviceFinderCallback2 @* K1 G6 Y, m6 V, S; t
: public IUPnPDeviceFinderCallback: w! [- E; l8 ?' Z; C c0 h
{; P/ @3 n& m6 H2 u, ?
public:( f( s; V. W- V
CDeviceFinderCallback(CUPnPImplWinServ& instance). h7 U7 T4 n7 B
: m_instance( instance )
; C' |$ d5 d8 C& W: l7 @$ E { m_lRefCount = 0; }
5 w: R7 A W8 f! s5 [% h: B' S% x4 \, i" I7 }' W
, n$ A! a) J9 d% {
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ j+ X; m" @, w3 E6 C! @
STDMETHODIMP_(ULONG) AddRef();
8 W! P) y7 j) a+ H STDMETHODIMP_(ULONG) Release();% o+ _5 K5 ?3 V/ ?$ n& Z. s8 s
6 g0 H! P/ F2 B7 w0 ^) l
/ m4 w, M3 A9 U* @! t
// implementation" f: q0 _0 c; j( P
private:
* z. D9 k% B0 l# W, F0 ? HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);- L& e0 J8 C& }& G
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 `2 ~; i% x( i' Y+ F, r; ] HRESULT __stdcall SearchComplete(LONG nFindData);
8 d! i* N0 i$ L; J; S. B6 X: x
( ~) x4 g% r6 v) i$ k% S1 U: [5 |
, o; B% j/ C& ^( H8 }( i Cprivate:$ q1 q# o0 w+ ^) Z3 V1 [
CUPnPImplWinServ& m_instance;
% F7 b* a9 ]* i" }% o LONG m_lRefCount;
+ A) e, b. t) w- o5 C, ? K2 c};
, l) m2 T# o- L% g3 \
( d+ o B; C! F- [( x
0 O2 `/ n4 m4 r% F// Service Callback 5 e ]0 Z. o+ a' j" R/ y1 y
class CServiceCallback0 k% u5 m a' n6 p) G$ F
: public IUPnPServiceCallback
) }3 N- S# v! ^0 N) m. a{8 h% Q4 Q4 i9 |
public:+ V7 ]* }9 a3 q# H& M7 }
CServiceCallback(CUPnPImplWinServ& instance)" y( p- y2 \/ z+ k( @8 ^
: m_instance( instance )
& V3 p( Z% `7 }6 U$ ]* J { m_lRefCount = 0; }2 Y9 F s/ `4 G2 l
& y4 o3 N( k' W9 @* h; x0 r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# T" b0 Z2 i8 Z1 r STDMETHODIMP_(ULONG) AddRef();+ i5 N p; h, U' L0 k0 B+ r
STDMETHODIMP_(ULONG) Release();
" Y5 e) T- k1 p: I
D" _1 |4 _6 v t) `
" e9 ^9 n3 R5 s- J- e) v// implementation) |- W! I+ c4 m6 G+ y! `
private:
* F( J R2 r/ o: J* T HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- @$ H! v) H' @0 y- k HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
, T. A5 m$ T, Z& \: f: n e* w+ c
% w0 U! a1 c _3 E8 u
; ^& [" f1 Y7 }# v1 l" `0 Tprivate:1 D ^" V# c6 i! @0 n y7 S; a9 [
CUPnPImplWinServ& m_instance;/ a7 U! {# h2 l
LONG m_lRefCount;6 m4 L3 V4 N9 u1 I" j2 i
};
! l1 k& P k6 E2 G9 |/ a$ @/ `; O7 u4 N
( `- C8 `7 v7 y; V; c) {4 ~/////////////////////////////////////////////////
% O* w/ W- w. H8 R, }6 m% }' h! r" u- D- S6 o5 R0 }6 s
) E0 X. o5 X- e$ C0 O0 P: [
使用时只需要使用抽象类的接口。5 F# S9 l6 r# Z* O
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
- h1 P% R1 _' zCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
9 s2 o0 o6 Z9 CCUPnPImpl::StopAsyncFind停止设备查找.
3 G) u7 l2 g+ c& W+ l- SCUPnPImpl::DeletePorts删除端口映射. |
|