|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 T1 W4 R/ B S( y+ B) o6 d
4 T9 d7 T: }- }; ^
/ G; H8 r! @( _4 M" f///////////////////////////////////////////
* k- p. s- t u6 g4 L. _$ k& D//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
" @3 u0 e( V" H- J8 D0 f, \- m( z( f+ v3 ^( p, U: F# e1 a
M! M, K O9 M" h M#pragma once. S0 x" \4 ^, G& ^
#include <exception>7 P9 P' _! j/ V
4 J0 }; `1 S% r& ~
4 |7 |+ C7 u2 c. z$ I
enum TRISTATE{1 t( }" r4 U/ _$ R5 ]# }, l
TRIS_FALSE,& G2 t: O* @% S1 E. [! j+ s
TRIS_UNKNOWN,$ E4 ^8 z8 U9 m" ^0 C0 o, i8 S' n
TRIS_TRUE
% @- L6 D3 n& k};
; B+ D* W1 G) e$ x! |7 B& @) u1 p3 y! E1 W9 i
2 Y. g9 K/ T% J4 z
enum UPNP_IMPLEMENTATION{
2 m$ T1 U; L/ U& K1 ` UPNP_IMPL_WINDOWSERVICE = 0,' B1 o+ n' {) j I" K
UPNP_IMPL_MINIUPNPLIB,
; C( C+ u! F. C UPNP_IMPL_NONE /*last*/
" `' P0 Z k0 J& H; K* Q};
: o9 n) p% l- Z
: I) w0 i3 p0 i1 U/ g
; H' x3 _7 n% T; O5 ^
" c4 H, I) u; e: ?
, T# w8 s1 T. u5 w+ l) yclass CUPnPImpl
( [( z I( e" v+ A6 K7 ^0 P. i{
% ]) Z2 r. K) d* P8 M% N9 Rpublic:
+ u* r7 ?: Q2 }2 X3 { CUPnPImpl();
8 F$ D ~, H2 B. ^, g9 ? virtual ~CUPnPImpl();1 b' C7 V4 D' c4 _7 W& z7 {4 Y
struct UPnPError : std::exception {};
8 k# h( T+ \& a/ M& {' i1 f# S enum {
2 |. i" H$ F5 p' f z UPNP_OK,, \: e( Y* F: I7 ?2 {4 }8 q* P+ @: Y
UPNP_FAILED,8 O) e- u4 X! E D& A9 n" _
UPNP_TIMEOUT+ A/ D7 u) D8 c
};6 d( D' M6 D. p
2 D% d1 o4 L6 J2 Q% g9 \. A
8 v; z! e5 c# Q8 i$ g
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
+ ^, X. w/ L9 G4 ?+ y virtual bool CheckAndRefresh() = 0;! u' X) P# ?6 Q; V
virtual void StopAsyncFind() = 0;" {! }+ z! v' B; }; F
virtual void DeletePorts() = 0;' J; Q$ F& n3 v7 l, U. p. g3 j
virtual bool IsReady() = 0;
7 [/ @3 d5 ~* Y9 i8 U1 W) f virtual int GetImplementationID() = 0;
1 ^# v! }" M8 W9 M& Q- S $ N7 ^# I) v6 L6 Y" G; s- |# c
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping( V9 K6 R( F+ Z
9 c0 Y- W4 V+ Z) W1 v+ ]+ Y
) z% V, w, D' b. G( H% H4 E$ j void SetMessageOnResult(HWND hWindow, UINT nMessageID);. F! y7 }9 W) o! S! I$ \
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: I8 U- C- b6 ^- _( I
uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 \! ~' n3 E5 O( W$ Y" K0 | uint16 GetUsedUDPPort() { return m_nUDPPort; } / G( R) V' ]7 z5 ]& [& [
+ u0 b2 B$ t4 z, S
& K3 I$ m/ r( p9 M7 _+ ^! Y
// Implementation
1 Z4 y j1 V- I# L Xprotected:' i$ C. O" y' L; z! s0 q& V
volatile TRISTATE m_bUPnPPortsForwarded;+ ~! w& a* W5 M2 I# Q" k
void SendResultMessage();
( U* a5 a9 C( v uint16 m_nUDPPort;
3 X6 G6 E# C: Q2 q1 B, a g7 g' H uint16 m_nTCPPort;
: y1 t2 H. ]# S, ?- _ uint16 m_nTCPWebPort;
8 ]0 W2 l" G" F5 C4 c& a. F6 n L" b bool m_bCheckAndRefresh; [: M: T/ z0 }. i: s6 v4 ^
4 d L. T+ I+ U/ g4 E8 `! J+ `; o4 \1 x
private:
: P" j* P& ^. p2 i% X @ HWND m_hResultMessageWindow;
/ ]! u( K, Z' ^ UINT m_nResultMessageID;# Q/ S& p3 m I* S$ G
) x1 G8 B1 f4 F( i9 ^0 n. n5 X) _1 F6 L- j4 x0 O
};
0 V& H) U+ W7 w B+ N5 {3 t0 L
# N3 \; ^' | M8 F, ^+ H/ u2 X4 n3 _# u; I& f
// Dummy Implementation to be used when no other implementation is available
6 U# W* n. W6 \& L4 b" Uclass CUPnPImplNone: public CUPnPImpl
0 z, U0 D( l9 Z* \, g$ ^{4 P2 }# Q0 k% _* [3 _; `
public:0 d% k8 j/ v% c) t
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ L0 F9 R; A: V% \ virtual bool CheckAndRefresh() { return false; }+ k3 a' S7 [9 c% Y
virtual void StopAsyncFind() { }
7 @' Z3 P0 O* X! D. n( P virtual void DeletePorts() { }8 ?7 v, _. E* b, r9 J
virtual bool IsReady() { return false; }
6 x2 X+ G5 S; u7 E$ O virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
- ]: w2 M( q* Z2 u1 c3 q# Z8 O};1 Q: w# ?3 g0 {
7 w; W, n8 f$ u3 u' O& ^
( b' _! g( q; }$ w, h5 m% o" c6 c
/////////////////////////////////////
- E6 h2 T, z1 I, g# S! |& J//下面是使用windows操作系统自带的UPNP功能的子类4 g6 z/ }' k# _- u$ B2 I! B
1 n% c% ~1 E8 ~! ]3 P
; B( E; {& S8 D- f1 x
#pragma once
- Z) o; A# l: f#pragma warning( disable: 4355 )
! r1 Z! \) D% n* n) l& O! }
/ ~% m8 b+ S, u2 A1 E" O
8 |3 C3 A. R) ~, J3 D$ a; Q#include "UPnPImpl.h"
! ]0 \& `8 i4 `' V* U#include <upnp.h>* a8 y2 T0 N& }0 n) R. [
#include <iphlpapi.h>
. K6 ~; D y9 [" O- q- e% e; m#include <comdef.h>) f; k- T! [- b" z
#include <winsvc.h>
, _2 n9 C6 C0 |0 t! f2 X1 w8 e7 ~( U# i! U2 E; g$ p: M8 i" `+ B
6 `" @4 |& {! M+ D3 d#include <vector>
: A0 h1 y- `* j0 H% F#include <exception>
6 }* P, N! [, [#include <functional># w. D6 c) j$ P$ G+ a
5 e' R4 j6 T2 |5 z% S% Q
1 @. }8 @* Z& w& m
8 L& }% ]' b3 R& E+ h! P2 }- I0 P, N
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;5 m8 h5 t( d" z8 s$ O+ {7 N; n
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" C. `5 U) d9 E$ Xtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;4 s2 H) O1 z. o0 i3 E
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;* O, F' M8 x# }; {- F' B" Q
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
. @. M: R! E t. ztypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
8 p- l; l+ s' z4 Ztypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* ]8 j7 m4 |1 s# Z H2 f
) Q- e9 u5 a) F# t, W. A) a
# ?, ?% i G! o$ etypedef DWORD (WINAPI* TGetBestInterface) (
5 l. k5 z6 h# M3 L IPAddr dwDestAddr,
0 [" E2 ?. z% Y* D+ t) } PDWORD pdwBestIfIndex
1 G: C* y# e, x3 c+ U);# F0 V: m# n( J7 Y. _3 K
; I( a ], E6 J* {$ I; g9 T
6 o0 b- S4 u+ }+ m+ J% dtypedef DWORD (WINAPI* TGetIpAddrTable) (7 R; X4 o: t; b
PMIB_IPADDRTABLE pIpAddrTable,
# {6 m2 o1 K* b7 \) _6 g PULONG pdwSize,
9 l/ G7 Q- B, g! Z. Q, ~ G2 p BOOL bOrder y; x h5 }8 o9 h2 J% X5 v
);
- X7 @6 [; f6 q; i
2 L8 M7 N# ^9 w p2 o; K8 f7 n6 M* X) P0 q6 v& {& A) r
typedef DWORD (WINAPI* TGetIfEntry) (
8 ]' s+ @' L- y% F. j! L' O PMIB_IFROW pIfRow
- G& H& R7 w+ R7 \& w);
* _- v% z9 d" u" J, Q2 @+ t! B R3 i' s, L
, U8 ?, a/ I0 z/ w0 u: g+ p
CString translateUPnPResult(HRESULT hr);
& A$ f: A0 D Y$ z" BHRESULT UPnPMessage(HRESULT hr);% j! F- r" \1 Z1 V
( ]4 R6 Z) ~3 o" Z1 U$ J/ w9 W( y2 B* _& ?
class CUPnPImplWinServ: public CUPnPImpl
/ R) A8 n8 d) U$ f# p6 c- u{
9 l3 w7 [; F8 w8 n0 h; F friend class CDeviceFinderCallback;
& b, i( n8 G9 D' c* | friend class CServiceCallback;
+ l5 ]" v; d+ s1 J// Construction
) }: A2 L" P; @" Q# gpublic:$ ?9 D. _. _+ d4 W, X: `
virtual ~CUPnPImplWinServ();, d" Q8 v6 d7 f% \" r+ f3 `
CUPnPImplWinServ();
, f0 u+ P9 r3 s: a3 |/ g6 U( i! A
$ U6 k8 U h6 }% g2 h. o" d6 u( H+ G
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }, U# L5 V& a! S; b& ^+ E t& r
virtual void StopAsyncFind();$ r4 a1 t* t7 g8 f, u# b
virtual void DeletePorts();
: }) B6 n7 X% j- j) j$ p4 C- I virtual bool IsReady();8 z |. o( n4 V8 {
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 S+ l! M# M+ Z4 Y
2 s8 B' {- n) D+ j
5 K8 }! D2 D& a/ A# H1 w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 U! f: w- N5 _- Y- b' M // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 U$ Y7 O. S5 D" I
virtual bool CheckAndRefresh() { return false; };
6 P$ v$ f* g7 ]9 T: |3 x4 |# e3 p
4 u! ?/ H/ m8 l, ^ F
protected:
8 }( x; `: U9 w: H. {! L1 b* [ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
. d% m* ]( d& E4 [ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);+ a P' {$ `* Z
void RemoveDevice(CComBSTR bsUDN);
; X! m! j2 j, N3 E bool OnSearchComplete();3 A7 C; ~) C6 S0 j: M* F
void Init();3 D$ C2 r- k: J( i4 A D b, D% U2 r
6 d# R6 V* {- D* @/ C% X
% u% d4 {* S0 } T+ z' [; E inline bool IsAsyncFindRunning()
# G0 a0 ?: \! c T {
/ n& w. b+ Q* x: N if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )( a+ x N. I8 @+ e$ u7 o& U
{9 B$ _0 Y4 r+ C, _6 S6 Y* N. h
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
' [7 q6 u& u+ {2 S m_bAsyncFindRunning = false;
9 D1 b( y2 Q6 @( h( @! d }
; F s; b4 O1 ]2 r: N3 F7 G. ]3 w0 Z MSG msg;& j7 X, J5 [$ |7 v6 C
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 k3 ~* Y, i9 G9 a {4 }4 Y) W+ ^" @1 R$ u" J/ N
TranslateMessage( &msg );
- {! c8 _+ m( ?6 Z$ q DispatchMessage( &msg );
- G% C% P8 Q. W; L9 q }
, l) u, x# O ]4 Q8 X4 Z. h return m_bAsyncFindRunning;
; \" G+ R$ x& J. W( l# d }
' r3 A/ v2 [' t k+ \5 W- f' R! h( v% g; h: K* D" H) H
" b7 {8 v! d# E! Q% E TRISTATE m_bUPnPDeviceConnected;
+ J% f/ N5 O) K" e7 Y' z9 a/ W
# B" Y, a6 ?; |0 N }8 H4 j; _$ ]+ ^* a/ `* M# z" Q( c
// Implementation+ k) [3 K& V5 [$ \8 `
// API functions: {" b% x, J" C) |' ^. }" n
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);6 X) ]5 G4 c. P
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
) C7 p# R/ e/ t8 P BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 V1 N. `9 b6 X9 P: F BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
2 a8 Q" N, D" n BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* e# R' k. N0 C+ Z+ J0 a, U
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 F. @. w5 r% J4 `+ M
( K" U! C7 O. I% C/ E6 F: t
3 y3 [: O$ Z) R; u TGetBestInterface m_pfGetBestInterface;0 C& o) m' b& D, [4 m3 g
TGetIpAddrTable m_pfGetIpAddrTable;
% }( G5 ^- Y# a TGetIfEntry m_pfGetIfEntry;
4 X6 ^/ {9 \+ A& c2 v( P$ x3 a+ g
% H: j; {% v# S" x! @$ Q& l
static FinderPointer CreateFinderInstance();8 L5 T* Y' J$ m3 k2 E: q* x% L7 z7 O
struct FindDevice : std::unary_function< DevicePointer, bool >
/ m0 r7 G$ u g$ B" ~# o {3 b1 P1 [" g( W5 @: e N c5 a
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
) N& y$ z. w5 P result_type operator()(argument_type device) const, ^2 O" n6 }8 x0 {4 `* S/ Y$ V& F
{6 p( j7 b. f! I, m/ j
CComBSTR deviceName;
/ V8 d3 K8 d/ h( \9 s$ ?3 H HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& t0 Y9 X+ ^( m* w+ h! d2 B4 v3 J
8 F1 ?0 e1 Z8 y7 ^+ ?: E
5 r% f1 y1 d( @7 y4 z& U% A" \ if ( FAILED( hr ) )
6 t, B5 S' r( [% a( ^5 }. R return UPnPMessage( hr ), false;- i0 z9 L0 m8 ]/ `
$ y" ?8 L2 O1 T- K4 R6 b4 p" {7 `- i' R
return wcscmp( deviceName.m_str, m_udn ) == 0;
, s. `4 G, @' E# c. s& J8 O }
. G, v' k6 f: e- A% b7 N, \$ K CComBSTR m_udn;. o/ T# \. T( t! K+ s- z7 G, x+ Z
};+ ?+ o' g% u" w9 p' B
) U( ^+ ] x# t; q. u8 f void ProcessAsyncFind(CComBSTR bsSearchType);
2 Z: m1 ~# r2 b6 Z$ U( F HRESULT GetDeviceServices(DevicePointer pDevice);
9 O' A* ^6 Y9 s+ r void StartPortMapping();. D$ Z- A# i- d* v. l
HRESULT MapPort(const ServicePointer& service);
5 M; }1 m7 r4 T2 E- s2 E# J' v+ i void DeleteExistingPortMappings(ServicePointer pService);$ B- I* F% M2 r- n5 {7 U3 K
void CreatePortMappings(ServicePointer pService);* h. X4 q' U. F6 S( I
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);0 g' v! }6 R B
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, + Y" Z, P& Z- M" Q
LPCTSTR pszInArgString, CString& strResult);
' k. W9 r3 W8 D$ M. [8 \1 L void StopUPnPService();
0 g% f/ B' J% W+ T7 n2 ?3 {$ @+ y8 o6 ^2 i6 }! h( M& s
O% {- K* e) b; ]) m' ~" H8 L# P& u
// Utility functions8 e4 d$ R, j6 b
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 U u6 l( k; l# k7 ? INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);4 M# I( B. D5 e6 A0 [" a/ v3 J: T
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 d1 |8 e% S" r6 v x( F
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; i" h: M4 v2 a; Y/ D
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);9 P' K s8 ]! i& _
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ E" h: ?3 t5 t: L6 P8 ?& g CString GetLocalRoutableIP(ServicePointer pService);
1 ]5 a( R! d! q; V* e- ]" E/ ]! \+ ?: o$ R8 T2 q
1 y \) a. L, {
// Private members& j/ c' `6 k% Y; z4 K8 O$ y
private:
/ G7 J" M& H9 Z( T3 @ DWORD m_tLastEvent; // When the last event was received?
9 g) j# ?: Q+ r, N) X/ n- o% y std::vector< DevicePointer > m_pDevices;
% W& d! i$ z s/ r std::vector< ServicePointer > m_pServices;/ p& y" o, ^$ r9 ~( |
FinderPointer m_pDeviceFinder;
3 }/ q: X4 p0 g8 g: \; v DeviceFinderCallback m_pDeviceFinderCallback;, x* I) B5 d9 M/ ^! T
ServiceCallback m_pServiceCallback;
8 f/ J* u0 ^- w& [) i
. {5 Y& K R2 i: h& O) O) Q) F9 W- |' w& ]3 m% R
LONG m_nAsyncFindHandle;2 j, O! e) J. w2 k+ ~0 Z0 V% q
bool m_bCOM;$ Q7 e( R7 G: R. c
bool m_bPortIsFree;" f* {$ T# |: A6 I Z2 F
CString m_sLocalIP;
) ~7 v: w5 k+ Q/ w8 B3 T6 n CString m_sExternalIP;$ c* N4 P) d: [7 \% m: a- C* `
bool m_bADSL; // Is the device ADSL?
' f- ?8 y9 t6 x7 V' q; v bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
" D) O7 v) X, r+ u. U+ e bool m_bInited;
3 b! q% S' i5 c7 p. w bool m_bAsyncFindRunning;
9 p9 `4 P1 ^' I( d+ D HMODULE m_hADVAPI32_DLL;
% e7 y% H( t% W HMODULE m_hIPHLPAPI_DLL;& T: ~$ [( |% f+ Q6 a9 V" S
bool m_bSecondTry;& d( @* {3 Q8 V5 Y
bool m_bServiceStartedByEmule; k4 L1 }6 Z( \, u9 \
bool m_bDisableWANIPSetup;
. u$ e3 F7 \- U7 `( O' j8 b- ?# _ bool m_bDisableWANPPPSetup;
! P; ]; V. w& E4 a# P
8 V" }# d! |$ e) T+ D$ h0 E, L
- h9 M4 y2 O$ s7 j1 |% [ m' T};
" a4 l |* o3 X/ i% J7 q9 T# g1 R" E0 z/ J% J
: ]/ M$ l6 X' ]+ T3 T' y+ w8 r* M6 q
// DeviceFinder Callback' B }3 t5 P. w6 U2 B0 L
class CDeviceFinderCallback
% G5 U0 y. G7 L3 C1 ~8 }7 w : public IUPnPDeviceFinderCallback
/ C$ r: T7 m2 ]$ R' P{
: ?7 d; I/ g, t$ c; A$ c& R1 mpublic:
9 `# q9 w# M; k' M) q CDeviceFinderCallback(CUPnPImplWinServ& instance), x! u% g1 W# ~( \
: m_instance( instance )/ K" J/ t6 q8 `% n- ~- x
{ m_lRefCount = 0; }
: r4 u- _6 P) A$ M7 L" c7 j/ `6 o
- b. V/ ?' p1 S8 V% l6 E5 q6 ?$ `& c- `, K
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ t/ i' k* h+ j8 J* c STDMETHODIMP_(ULONG) AddRef(); g: M' y5 L9 O
STDMETHODIMP_(ULONG) Release();8 B! _ w( b" o3 a# L4 j% K
8 k! z' M ^0 e, f- C
* d8 W& G& Y( R// implementation$ d& Z6 ]6 ?% p6 T' B8 o. |
private:! v3 S5 ^( M9 ]6 Z- ]7 m
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);. }% p1 O% ~$ E$ _/ X+ C! G
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);4 G4 w+ C$ Q1 P5 A
HRESULT __stdcall SearchComplete(LONG nFindData);$ F1 [5 q- m" L5 \
}6 m3 |5 V3 Z# S$ `
0 B( n# P0 ^ {* j( b( F _; S6 t- {( qprivate:7 d6 q+ G) c/ e
CUPnPImplWinServ& m_instance;* E1 `$ X% h" A
LONG m_lRefCount;0 E3 H+ ]" w$ r2 w, }* G% I( G" q
};
, k4 M' A) F- _
2 s5 `' h1 z/ X e. M0 r
( N9 c# H$ u7 Y// Service Callback
$ f; C1 W0 q; [class CServiceCallback1 B( k: Q" r5 ?9 j0 c/ z5 H! W
: public IUPnPServiceCallback, g3 m3 Y+ O# E, [
{
6 P o( n t3 Ipublic:
+ o" t; @' D W% a7 m. h CServiceCallback(CUPnPImplWinServ& instance)
% Z- k5 Z3 c0 l: l! U; S( Z : m_instance( instance )- _* W8 l, \- m: @/ |& N
{ m_lRefCount = 0; }4 o$ O* d$ o7 D7 [4 X2 i
! B5 s1 U+ g" c! i; j
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ V8 n V# }% O, [6 E STDMETHODIMP_(ULONG) AddRef();5 m. U! i9 l m5 j* q$ _
STDMETHODIMP_(ULONG) Release();/ S g. m. k# X* Z2 } Q
" G+ D7 m' u4 l& W2 j4 X
# U q2 x) y# \* Y5 m6 s// implementation
! E% D3 N! l. K/ Mprivate:+ b& c* I7 H( V! M% V# d M
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
+ x& e( I' m2 `7 |) i0 Q! A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);5 { i: m+ A" U$ x+ g# Y+ h
7 S3 Y7 k' y% A1 n) B
! I/ \4 X( x! q: {, T/ uprivate:9 O. ^7 n6 u: A/ z% x' M: j
CUPnPImplWinServ& m_instance;
# R+ \( o% K" \ z, l) Y LONG m_lRefCount;) Y H; R- m! u% O6 c) |. h% U
};5 [ j& i6 M+ u8 {
7 r; x$ \5 H( Y( `
1 V$ K3 y& k( p* U/////////////////////////////////////////////////, E( f' L! c5 h: T
7 j0 U1 ]0 a+ O9 `
, B) V2 F4 I* n. i) {5 k1 v& t. r6 U使用时只需要使用抽象类的接口。
" B2 f: k) U5 U* OCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. C, Y; a5 U3 y
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; H8 i6 e1 V/ ]6 f* G9 |
CUPnPImpl::StopAsyncFind停止设备查找.4 u8 F, y* T5 ]& \( C
CUPnPImpl::DeletePorts删除端口映射. |
|