|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,, R( o+ h; P) f7 W( b
p0 t. O e8 s
( s1 \1 R4 t4 h8 x( x- X$ B' u///////////////////////////////////////////
/ P/ k/ n" r8 n& b2 s7 L- p//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.3 x' q0 l" A; E' ~
! l k# u ~" {* V6 H
' Y3 \0 ~- N7 v" `& f0 O#pragma once
9 K6 Q9 R# y7 C; D: Q8 C' x#include <exception>
/ H9 `% R' t1 K) Y# c4 h4 ?
, v* S5 t( d" U) P. K6 j* g; F
8 i! B) Q) ] R! Y! `" k enum TRISTATE{
; O! j" d& z1 ]! _: f) }7 Y TRIS_FALSE,
6 f. ]/ L; s, \3 v6 A1 M! f TRIS_UNKNOWN,
# w% L/ ~. z; Z% [; r TRIS_TRUE3 k4 E. K6 ^( f8 L. o4 x( m
};9 [7 B% ~! @7 F- R# j! u
% \% J9 k% Q# {) o# x3 E9 E% n( ]# ?8 y* E* q* |- ?, q
enum UPNP_IMPLEMENTATION{( j( t) a7 p8 V4 i* a+ o& I
UPNP_IMPL_WINDOWSERVICE = 0,
6 k7 H+ \& k% k" N D( u UPNP_IMPL_MINIUPNPLIB,
5 K7 y! q% p- H) b) B, i3 |' T UPNP_IMPL_NONE /*last*/# {1 Q* Z: c7 ~: ?7 g4 {
};" Q5 s" x8 a/ g; A: J/ X( ]8 I
/ C! g; I9 \5 l3 x$ c- f/ A
. M5 h; J3 V) c! y5 i' J i- A
- O d n8 T6 T( L* T
5 r l" C4 v9 q5 [. {8 F$ E
class CUPnPImpl
- s8 j* O0 F, s% h, Y' P* m. `1 B, p. W{3 v, t' l! L4 d# L5 r4 I! g
public:
. N$ z* `6 c& F$ g3 b. G% W3 t) [- q CUPnPImpl();
% D- m# h# i: c4 j; m virtual ~CUPnPImpl();
% D# S- w( O( ]( N: d& s struct UPnPError : std::exception {};* T- u7 G }8 i6 c! Y" L
enum {
) Y2 }4 @- {' a: Q UPNP_OK,
! D, P6 D. x( C+ h UPNP_FAILED,
% F: W* x' G8 s w UPNP_TIMEOUT
# h) X; ^- `3 q/ Y };
3 a, z) d Z% E# \6 M& ^" R; o1 \ h2 [: J" ]2 W" F& Z4 |
. z) C8 `# }( T
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
( U# c6 x3 G! ]/ M8 |: O virtual bool CheckAndRefresh() = 0;
+ u( p: ~ ~) e) v* L( j* z virtual void StopAsyncFind() = 0;- e6 z# a8 l: {# _! ^0 v0 Z
virtual void DeletePorts() = 0;8 N# _ f7 I, R$ T1 O
virtual bool IsReady() = 0;
, l: q6 q/ W1 d, {- s virtual int GetImplementationID() = 0;# w+ {% K. ?. U& e% }' s
6 u8 f( {) ^5 V' S0 L% t) {( a
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 W9 T+ o' E- [! x
; s4 }; N' s, x8 j! ]/ t
& p, y' G* k3 B- a. k0 ] void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 h: N0 H+ E. i: D" H! l
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
8 m4 ]5 A6 }) o& Y# J uint16 GetUsedTCPPort() { return m_nTCPPort; }: Y3 `9 f7 x, F
uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 Z f! ^# a# D: z3 I/ B5 C* R/ F
- R+ D! K4 s/ a. i0 j3 W
5 ?/ F# X4 q; j4 t5 F* p5 q8 o// Implementation; p; S& w% u! n9 T; ~. q/ F
protected:
k1 \. a2 |! F9 r1 \# Z+ s volatile TRISTATE m_bUPnPPortsForwarded;
: Z- F6 S7 u0 b void SendResultMessage();
% A C n) B2 j$ j uint16 m_nUDPPort;
6 Z p% l4 W! R- v6 A' i1 ^ s uint16 m_nTCPPort;, E x9 l% @" _
uint16 m_nTCPWebPort;
- a, O0 [/ @+ V& {, V bool m_bCheckAndRefresh;
1 I, g8 e0 |- u# \. } i) t* K% p( p
3 H$ ?! h/ {/ v- k+ R! s1 ]) `$ ]: ]- l, C
private:
& k7 }* l- I R. p9 m& M% u; R$ L HWND m_hResultMessageWindow;* Y. A$ U7 j( m h) s( ]% S
UINT m_nResultMessageID;
" O4 j# ^) v4 W+ f: O% L6 V: H
9 Q- w/ [/ h/ h1 X/ j& [) m/ z Z+ q2 e7 |" s
};5 z; Y- L( g8 M! g% u1 e1 Q; G
# U, d1 _$ y1 b8 p: @% @) E# G+ g' M1 A9 ^
// Dummy Implementation to be used when no other implementation is available
7 z+ P. U7 j$ M$ ]& Aclass CUPnPImplNone: public CUPnPImpl' X+ [0 \$ W5 g$ v7 }
{
+ o6 x" e! y9 {$ _) ppublic:# ^9 Y$ o+ ]& H2 |: _# w
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 S: J, K3 S/ ?/ E
virtual bool CheckAndRefresh() { return false; }
0 ~/ I3 U( x; X3 z$ m virtual void StopAsyncFind() { }9 t' l2 C' S- [" r3 \
virtual void DeletePorts() { }
& H! V m$ M/ ^2 n# u0 g6 e& z: | virtual bool IsReady() { return false; }
/ H6 j# H* L- [, b$ f k/ G* J virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
n3 H( [. M4 B |7 ~};$ e. c0 q) s, e D1 j: A- R
$ P7 |- B' R* k+ k3 ]( A/ C @" M. F8 l& Y. q" R
/////////////////////////////////////
/ `5 @; w& o- X; t- h//下面是使用windows操作系统自带的UPNP功能的子类9 e; [3 [; M$ u& Z- X0 p
6 d$ p6 S/ h6 v! B3 M4 t" Y
3 p( j; ~' T' E$ K J#pragma once
# T: H* V% k5 v#pragma warning( disable: 4355 )/ t# N( Q! b+ y( ]# I" q
' L8 ?; y3 P; |' x7 M& F* ~7 y& u. O0 G/ e! G6 w
#include "UPnPImpl.h"
2 s! J: v4 E. p- K6 W. ^4 G#include <upnp.h>
% F2 T; a# G/ ?+ c0 Q \7 T% }% x#include <iphlpapi.h>
( J4 \: C3 l# H4 p% U9 H#include <comdef.h>
5 e1 Z8 q7 D0 I5 R# Y: A#include <winsvc.h>& `1 g7 f9 l8 M% J# F+ ^
6 k" T' A3 C2 L1 s! [5 h \0 R
5 y* B2 A+ M( c0 j- W#include <vector>
& w# C: S' s& Y8 ^7 \#include <exception>! o1 J0 {# n. E0 I
#include <functional>/ g0 r" s- p+ s. K
( H' a6 H+ e" S" N
2 d6 ?5 s1 I) w
% l) C8 r& c6 y5 a& P- [3 e5 r. y1 z
8 k# g3 ` t. ?3 f" ^- b7 k7 utypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. L% K3 H2 r) W& g: u+ ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;" [: U3 \8 X' x- e B" v7 c
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' p4 Y+ P/ T& ^- i$ L: q( `2 q; Ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
- S' u" X( m$ j, T% ]! d0 f3 itypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;3 d' Z W" z8 {- N4 f) G9 c
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr; ~" n9 P% i" `! s" I( E9 f
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
2 j* F* ?7 b( U9 B% j1 g2 H
: c+ J& U: o% b0 l# y, T( d6 X9 s+ H v
typedef DWORD (WINAPI* TGetBestInterface) (+ F3 I" k4 E# N% _6 M
IPAddr dwDestAddr,5 w ]9 b8 \* r5 @1 p/ x
PDWORD pdwBestIfIndex2 y$ c: ^7 S/ @# U9 C" i
);
2 S {/ r- b: I" l0 x: `8 J, u( V- W0 k$ v4 t) n7 q
7 L3 s4 T: I. D0 |5 u
typedef DWORD (WINAPI* TGetIpAddrTable) (# z+ `5 Y b; B
PMIB_IPADDRTABLE pIpAddrTable,9 [$ _- P: T- e. q
PULONG pdwSize,
3 }/ F! U5 |" M2 c BOOL bOrder+ q$ g2 w j1 Q3 M
);
% y: e4 x9 B) h4 I0 {/ `& e
, |$ x- }0 H! X& H4 b: I8 U; \0 c, s& c
typedef DWORD (WINAPI* TGetIfEntry) (
6 m% N" _/ A; F0 L PMIB_IFROW pIfRow* ?* z ^ A0 h5 n6 h
);
0 Q+ O$ L, P( s( L; B/ G# a- @# s: ^0 I, @/ D, I' j
( P/ `% s; |: ~
CString translateUPnPResult(HRESULT hr);
7 s( ~- t5 u( Y$ m+ M! DHRESULT UPnPMessage(HRESULT hr);
f& g5 H7 q% r
: P# s9 s+ w+ R3 Y2 t! ]9 `5 ~; X' V" f! R/ H# ^8 {
class CUPnPImplWinServ: public CUPnPImpl
2 Z1 N0 y4 S& G7 T1 R{% g. F4 ~/ ~8 w3 d; W
friend class CDeviceFinderCallback;$ x, b- P. |; } ]3 h
friend class CServiceCallback;6 i G. g. X; }
// Construction3 D+ r* K( p6 N6 X7 |; W+ [
public: }; R& X; Y3 ]* l b. v$ |
virtual ~CUPnPImplWinServ();( ?9 J/ X3 }4 g! L5 K
CUPnPImplWinServ();
1 C2 w' Y4 U* _2 s/ N9 t; S4 z: M! @4 b% \! d2 U" x
% o, [" Q6 w. i. u
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
4 K/ Z. v% ~, e, ] virtual void StopAsyncFind();
4 t: V5 N& s/ d1 H0 D6 k+ y virtual void DeletePorts();. L9 I" y8 N# P, n |0 Z6 N
virtual bool IsReady();$ C2 q4 R. L# q; J
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 h8 S- B4 Q, d/ R: f% n
! n, u3 K! e! K* _4 O
1 }$ }+ V/ d4 r7 n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
d' F+ ]. G& { k. R# Q4 R* } w // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
% B# v8 u6 B4 X3 k4 i, b- I virtual bool CheckAndRefresh() { return false; };
: x0 r' m7 A6 g9 B, R3 H/ D8 _
7 }7 u' u/ ] Z f+ s
9 Q/ M9 w) G0 C% _, w+ ?) oprotected:
* j- g2 ?4 z; x, b void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; m6 f9 h0 P( t' Q void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
2 C3 u; n% W6 K7 e0 A void RemoveDevice(CComBSTR bsUDN);3 A& z5 F- l; i
bool OnSearchComplete();* y! p& k! b& |* l0 i4 U6 x
void Init();
! W0 |3 H/ _+ e+ J: D
. L- p3 @( T, K) P7 G7 f
2 m7 @1 J$ r+ S. L5 R; \: \ inline bool IsAsyncFindRunning()
- x* V. ? ^4 F# N% v B {- _: G" ~( I- j
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )! e- H$ t7 ]( |2 X/ R3 O
{
7 p* _& O6 q, z% ]* y# h m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( ]$ v! H" d5 N k9 v m_bAsyncFindRunning = false;
# U. L1 ~( Y& C0 Z2 M }
! Y# q9 c# s4 J5 y1 a4 R! c ^1 P MSG msg;
. D [. e- {4 H+ A4 S" ^6 r$ G9 q | ?. b while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
) u+ d# s% ] @5 D# X% Q {
/ m( |: |( B0 ~/ J, Q: y' ^ TranslateMessage( &msg );$ x% q9 i% m1 h: P" Q
DispatchMessage( &msg );* F1 W- } a% z
}
. d% s* ]2 ?. E+ e) y! A! k8 ~" \ return m_bAsyncFindRunning;9 e7 f9 y3 m6 b9 m
}) D8 _ C8 M( ~9 L9 C
. d( `9 g7 O; ]$ ^% ]. ^- D( \ a1 G: P
TRISTATE m_bUPnPDeviceConnected;( B5 }. `" S0 O
) _9 f b7 p4 c$ t' T9 h. v. j8 v
// Implementation
( X* z) r1 k9 H1 l' b" B // API functions
/ q) s" G P) X- l i B$ t SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);6 H0 `& s- @& `1 A+ ?' @' x
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
. H# B0 N" y, V+ g BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);$ _# ?- H) ?0 ~5 u) J
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' n9 E* m0 n% H4 X3 G& A( t BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
: C- C- `$ k& i9 T8 i( ` BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
( E2 y. d. ?6 \8 d3 t& P0 t6 g/ ?9 v( `9 S5 {7 O1 ^
: o3 m) }3 k' H: J) T, C' e TGetBestInterface m_pfGetBestInterface;* W) D$ b' |" x1 P
TGetIpAddrTable m_pfGetIpAddrTable;" X: o/ Q2 D5 C- I" N- {
TGetIfEntry m_pfGetIfEntry;
$ ?/ B2 Q7 \3 g) f# B& g$ ~% J- @, [* \. Y0 m# K& H
! [* M/ f+ Z9 |/ D4 R9 q- i
static FinderPointer CreateFinderInstance();
; ~8 b: W4 b E struct FindDevice : std::unary_function< DevicePointer, bool >
6 P# Z( T8 h" v9 o5 E {% S- Q5 q2 Q) W% ^( L, Z
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
1 \: ^5 c+ o I7 b$ n result_type operator()(argument_type device) const t' |, A7 J6 g1 `5 I3 C
{% D) ^0 c: {) J. R2 f& b
CComBSTR deviceName;
7 N0 _) @6 D; `& Z1 \# G: l2 N HRESULT hr = device->get_UniqueDeviceName( &deviceName );, f: C5 k" |) d/ r
}2 M, j8 f! }, G
2 a9 n1 r8 M9 I' {5 q
if ( FAILED( hr ) )- d% t' H7 T% k' P
return UPnPMessage( hr ), false;$ }) U( T3 @" W# C
2 z( q" S% Z6 |
4 x* `2 d+ w. ^, Z6 E- D. u7 c+ @ return wcscmp( deviceName.m_str, m_udn ) == 0;/ c) b$ o2 K" R& v0 r1 h/ M" W4 S
}. F% s( b) I+ O8 S0 O
CComBSTR m_udn;
8 x8 Z0 f6 I7 n };
Q3 }7 }% F2 `+ J6 ]% u ! B+ w/ k+ K" ?. Q7 u- a0 p
void ProcessAsyncFind(CComBSTR bsSearchType);
, J% w, H( W9 w8 X1 s3 _+ H HRESULT GetDeviceServices(DevicePointer pDevice);
- E2 ]8 T* M! R7 M/ u' f void StartPortMapping();" F3 q/ E1 I: B+ c% J& l
HRESULT MapPort(const ServicePointer& service);
8 w& J6 _% F) [9 R void DeleteExistingPortMappings(ServicePointer pService);
# c9 T' z0 _1 n& A% f3 k2 Y# H void CreatePortMappings(ServicePointer pService);
, N# m: l4 k$ d3 A HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
; N, k7 I$ M, F7 Q HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
2 l5 M. s3 j& |( i$ k" g8 b LPCTSTR pszInArgString, CString& strResult);
! m% _% P* p, G8 j2 t) B( _ void StopUPnPService();
; ~3 r8 N5 N4 C, S* H+ m
5 m+ U4 @; P' u" l6 j6 w( x
l" \1 `3 a( N: q // Utility functions
0 }. }; ~/ I7 V6 N! b HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
/ p2 d; N0 g0 O/ U2 z. V' r7 x# a4 `, v INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
! Y/ f, e7 m% y. U: G7 _ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 {9 b: I) J: E
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
; V$ P0 q+ r; u5 c- G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
, U3 l6 J( z3 y' {, I4 x HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
|/ J) r* k# v3 q7 h. T CString GetLocalRoutableIP(ServicePointer pService);
L0 ]6 v1 L& ~1 Q+ ?: J. h; W1 V, E7 F. y
' Y0 d: O: Q4 n: p$ Q% f
// Private members8 p! J4 t% M/ n! H4 K7 U4 e! B
private:
, {# ?4 i( ?% M# P* R DWORD m_tLastEvent; // When the last event was received?$ {1 `4 z O7 O! ]8 _
std::vector< DevicePointer > m_pDevices;: Q" w! o5 E6 i( I8 u& e
std::vector< ServicePointer > m_pServices;! W7 j6 `6 Y) Q0 m
FinderPointer m_pDeviceFinder;: b8 i& d& J2 P- U/ }+ O) c
DeviceFinderCallback m_pDeviceFinderCallback;5 Y# T' o# \9 N0 R" R2 `
ServiceCallback m_pServiceCallback;
/ l- V# l# e4 A3 K* X4 N8 a1 t
# q2 R1 P# b. R: u& z3 e; a, G% x9 J" }! p, b$ m1 e
LONG m_nAsyncFindHandle;! b) o* B3 q( m2 P$ O+ P
bool m_bCOM;$ T. C$ w9 R0 S+ o& b& h) J; E
bool m_bPortIsFree;
' Z, R! O; p- U CString m_sLocalIP;% q p$ d0 x- E4 z* [) `
CString m_sExternalIP;
Y9 _2 R9 @; K bool m_bADSL; // Is the device ADSL?
6 Q3 C8 _) o; E o9 ?+ ~5 N# O bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
5 J' d6 W" n: }3 B, J bool m_bInited;! I+ i/ F% c* G. ^, Z# t. R
bool m_bAsyncFindRunning;+ o$ T" @- G. C! e! j0 Y/ G
HMODULE m_hADVAPI32_DLL;
; g/ k: L8 w* a) X' c2 P HMODULE m_hIPHLPAPI_DLL;
! C- [" K% M! }3 T4 G3 d bool m_bSecondTry;, S( F" n9 H- _ t
bool m_bServiceStartedByEmule;
/ |9 L% f+ g$ _: @ bool m_bDisableWANIPSetup;
0 @; u) R* ]7 o& Y bool m_bDisableWANPPPSetup;
6 D" z; O0 H9 {/ o. k2 F) `) T, x
5 n& @$ c/ M# V; q. _5 B* Q6 m3 r6 I
}; r& u p$ v2 s
! u# m# _+ b/ A; L2 V
, |" T% i5 N4 e
// DeviceFinder Callback
& W0 c& [6 `# {' c5 H3 f; `class CDeviceFinderCallback
. X4 k& u6 x# R0 t0 C : public IUPnPDeviceFinderCallback
3 `: W4 G* x0 t! G5 P{
% t7 I! E8 J5 \# ~$ Npublic:6 l$ u, d5 }3 k! K& I& J& ^
CDeviceFinderCallback(CUPnPImplWinServ& instance)% D9 j1 C) G1 ]# ^( ]6 u
: m_instance( instance )
+ Z! O; Z3 Y8 J2 | { m_lRefCount = 0; }
" p7 W5 b; X% Y3 A3 ]
7 b' C! s( N1 z9 h8 K8 b9 p( C) {' y% A5 z# ?. b0 _
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ }% A. }7 S; g6 Q% o
STDMETHODIMP_(ULONG) AddRef();
7 N3 w0 L E; p9 T# K3 X# n! W STDMETHODIMP_(ULONG) Release(); v! p2 E0 C) `& ^+ ^
4 L1 L& C$ n3 R$ W: a( r$ [! d4 ^1 M( f, ^* n1 d% w7 Q
// implementation
( a/ l- v4 }. M' I0 u! q5 G9 {, Q. zprivate:7 l0 t* }' H- @$ D
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
! @# g$ \8 [6 f' k( c HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% V# C/ `) m1 W$ [ ]4 W! \
HRESULT __stdcall SearchComplete(LONG nFindData);. s8 ]; g$ d- K% Q
8 G4 v( q1 L1 E2 v" }0 ~7 c0 ^; c) F, ]
private:9 U* {* C5 L0 V3 T; w3 G
CUPnPImplWinServ& m_instance;- u+ H5 Q& v) W0 h: B8 K
LONG m_lRefCount;) C9 q( z7 U+ r
};
^0 H3 l+ k# s% ^$ n. N! W( P; S* C5 R- B$ I- Q
) O# ~$ n7 H Y; S// Service Callback
1 l# g! F. i& E! B3 rclass CServiceCallback- H( }: d6 `1 v4 V$ m/ X8 }* R% u/ O
: public IUPnPServiceCallback
$ u! c. g" `0 ~ E' N' I9 |1 K{
7 O/ `4 k5 _: ]; G4 ] Ipublic:7 {) F/ l. M: a6 C
CServiceCallback(CUPnPImplWinServ& instance)+ V6 g/ D( R3 A3 {5 F \
: m_instance( instance )
8 L" l* c! e `# _; u: p { m_lRefCount = 0; }
6 b4 R, x3 I$ o- ~/ Y% u . H/ ~/ {6 j# z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- g" W. s8 d1 M1 p$ S4 L" G
STDMETHODIMP_(ULONG) AddRef();
$ T. L3 E: y! X1 A1 \2 D STDMETHODIMP_(ULONG) Release();
$ l5 u4 j7 |& x% Z2 i2 m! W
' O" k; ~0 q" w6 {
4 T/ s7 e/ {) n" O6 @// implementation+ z) a0 s( @) J3 J0 X
private:
- P. }% j! T R) Q9 U3 o HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);; P2 ~5 O8 l" W* L+ ]0 N
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);. W( u' x. @: \
4 n7 q) a/ m P: J% L. c9 D
7 n; O- @# s2 _( Zprivate:
1 f% G' u% y9 x) D CUPnPImplWinServ& m_instance;% s' c' L% D0 a; x# I
LONG m_lRefCount;
6 I3 ~+ t) c) K$ Z; b* m};0 e/ c4 L6 r: p8 ?. n/ d$ A" U
3 m5 ^1 X# A& O/ ]
) I! v& `9 I4 o- Y. A/////////////////////////////////////////////////
' H9 m, U5 W- p ~
; e4 z% } y# W" K
* l% i8 z3 c; H `9 ` A0 J* s使用时只需要使用抽象类的接口。
' G& Y: @2 |. l. XCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
* T, B% F; Y7 L h4 z4 m, DCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.4 J$ s1 t2 Z) {, |# r
CUPnPImpl::StopAsyncFind停止设备查找.
% O- M: p; z' L9 {( _% gCUPnPImpl::DeletePorts删除端口映射. |
|