|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,1 O' V" |: u/ C
$ x( a% G/ C$ I( [# P& y5 _
+ H# Y* W3 Z* |7 b, P: f///////////////////////////////////////////
% O, w; ?# ?: D8 f! r//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
6 ^' p& e1 |2 O( |; V. y4 ]( R. D$ b: h' d
- |" j* y- Y& w5 B3 N7 `+ w% U#pragma once0 \6 L3 X2 z, E S/ s
#include <exception>
; p& @8 R- K3 [. `6 U
( q4 m F8 v* V: f# x& t* B3 c
. ~) L3 v/ A4 b9 j/ K6 _! q @/ V enum TRISTATE{
i1 C1 f0 x, n! `; G TRIS_FALSE,$ B9 `6 m+ w" r# F9 U
TRIS_UNKNOWN,
9 u& _- F9 v: Z/ m2 h6 u& c TRIS_TRUE
" S8 ]9 d2 I0 q F};2 L, ^+ N# ~2 G4 ?! o
5 H7 c6 C0 E# T) {) O8 n% n! y8 j7 F
" S; I) c5 Z4 @$ I7 U9 h8 I6 R, Henum UPNP_IMPLEMENTATION{
4 j3 q& Z4 G- J' u* P5 X4 r UPNP_IMPL_WINDOWSERVICE = 0,
" s' y0 e& P( l F UPNP_IMPL_MINIUPNPLIB,
5 z) D5 i% h! H" B& r; ~ UPNP_IMPL_NONE /*last*/5 d5 t) e% F% J9 ]
};! J* Y8 m# E; k0 S' ]
4 V4 |5 i% X, a# w! G7 h( `+ @5 b8 _ C' N
/ C. b/ r/ o+ ]0 @
* G+ L5 J% J' N! J5 N% ?class CUPnPImpl
# d( P. ]. q" `. _8 e$ Q$ g{$ M0 K, k6 Z' I; }( W( f
public:
; k# d6 L1 P# i0 K* o! K6 i CUPnPImpl();7 Z& @% t5 k/ J D
virtual ~CUPnPImpl();
, ^( d2 J- c/ }8 d/ m5 S struct UPnPError : std::exception {};8 g: j% K$ i/ }: m
enum {5 N$ w3 G) W. |6 W6 \0 {
UPNP_OK,& x W& q' ?. f3 b3 h0 W/ v) M
UPNP_FAILED,
' v0 a: p+ B" q3 h( |: ~ UPNP_TIMEOUT
1 f' ~% ^, `* K0 d$ ` };
0 b1 x8 @1 u) M1 W2 @. D" k# D8 N3 n* z, s2 r& k& @1 g
5 t0 j# z& F* L w virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
) X/ B% ?6 f+ G! l& J8 s virtual bool CheckAndRefresh() = 0;
3 W+ o8 q3 T5 Q" ^ virtual void StopAsyncFind() = 0;
0 Y: v7 q. d5 a2 {( L' A virtual void DeletePorts() = 0;
( i1 h: ]' n! i% l- q virtual bool IsReady() = 0;
5 D4 ^$ U4 [8 i* y/ W& U7 Y virtual int GetImplementationID() = 0;
* ~1 [! ~/ n4 `. E# w: D# J* ~ 0 i( `4 C- p: i- h8 J6 x8 \
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) e- K l" p+ H
- i: R9 k, ?4 `
" b9 k0 E/ F9 P! c void SetMessageOnResult(HWND hWindow, UINT nMessageID);
; N1 p; O2 J/ ^ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 Y4 ~3 @* ]6 @1 i$ ` uint16 GetUsedTCPPort() { return m_nTCPPort; }
4 [1 k7 ~6 G! L& N uint16 GetUsedUDPPort() { return m_nUDPPort; } 8 w; R& W, k% z* k
, ~" \ o- ?2 Q! t# `
' Q, O, T7 H0 ~- h// Implementation' x! }" y% W% y4 {' o/ `7 K
protected:# j# J; i7 _& [* R
volatile TRISTATE m_bUPnPPortsForwarded;& c' g f* ]8 N, Y) t$ c
void SendResultMessage();
; W" r/ C4 U; X# [: d$ F uint16 m_nUDPPort;3 ?/ q( w# ~% w% {4 Y! d/ C8 ?& t
uint16 m_nTCPPort;
7 }- {3 W; G- O* @+ r uint16 m_nTCPWebPort;2 j! t0 X2 n) W# M# g* w; [
bool m_bCheckAndRefresh;0 z2 d5 p; p9 m: t3 y, a+ R
6 f9 _3 |: w8 g6 V* R$ l* N
. F1 N, d6 l) m" r5 gprivate:
$ q' M2 S9 x' L- n2 A5 | HWND m_hResultMessageWindow;
6 f* W1 N5 E* W ]) A8 v! U UINT m_nResultMessageID;: C# ?6 a; [8 z/ \( I% I, O% A% L
d0 ?- ?7 f& V+ S8 @
0 C) @+ o3 ~, @+ j};
* i- \# E9 G( r. X2 Q @6 g: f2 o- `# M
. ]5 W. \. a" Z. U- O# F$ q; `
// Dummy Implementation to be used when no other implementation is available8 q/ M8 B3 z" h" _# f/ T; b
class CUPnPImplNone: public CUPnPImpl0 N% |( E% v- F9 Q b
{
H4 l3 U. U& I, p# ^8 r! ~& Bpublic:
% Q0 Q( E; c( ?6 V( U. m virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" |9 A$ T: Q8 N: S+ \4 u! O2 |
virtual bool CheckAndRefresh() { return false; }
; O8 ?0 F8 _! O2 \4 f- K virtual void StopAsyncFind() { }
0 q" \! f+ R9 i/ l virtual void DeletePorts() { }" |) e! }* s' M& A
virtual bool IsReady() { return false; }
% h9 O6 o( Y1 D8 r: Z0 N virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 W$ m4 k& A* Q/ K0 K
};! v1 k( X$ k' d
# u* k1 r* T1 M7 }1 I. ?6 a; C) r6 g
/////////////////////////////////////
) [6 |) S; S1 }* I2 X U//下面是使用windows操作系统自带的UPNP功能的子类
; d4 A/ k7 b* I2 D5 e
- M# ^& j# G( ^: r( n* h9 ]4 a0 {( W9 n9 B5 O9 o
#pragma once
. K# r6 ~/ a9 Z8 a& h#pragma warning( disable: 4355 )
s4 w6 s' w) j- g- m
8 c+ k0 `4 H" m9 N" x1 o5 `8 o
; w7 e) C8 V3 U0 ]2 Y% b#include "UPnPImpl.h"
: `0 o' q% ]9 a# Q# G7 ]- R1 m#include <upnp.h>
" o: P1 L+ |$ H3 W. Z+ U& X3 E3 z#include <iphlpapi.h>
- ~3 D* `* s0 m+ N3 Q#include <comdef.h>$ r8 H0 `: z* [8 i4 `6 N V
#include <winsvc.h>
+ H: L, }. f, ?* N- e0 p/ p3 k" E% m- A* X6 I
: S5 j% u; i p1 P
#include <vector>( w3 l" j+ F0 H. ~7 ~9 S$ |' V
#include <exception> ]7 g( V' b) P4 N7 f& C% G2 z
#include <functional>+ j. U% s/ k+ l8 n+ ~
$ y; ?& s! ?& H0 b. V' n( {( `, S" A. ~( N
% r4 t9 q+ d0 w
# d0 U8 i5 V& A8 k5 P. X: itypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
6 d$ ^: v6 C: d V d B9 itypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;. W; |; _/ z' C5 m6 c# a9 E
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;5 u) I# ^! h5 H3 O1 H' z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) ^( b; y$ w. G5 k) ]6 i
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
5 n( u3 ]& h! Itypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
6 q% a) S8 d' [$ A5 Etypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' ^ Z' g4 |5 x; O
. X6 M2 c1 k3 o$ i' C' J: R& e% b8 {% ]! J0 L& ^
typedef DWORD (WINAPI* TGetBestInterface) (, p" n6 Q, ^; g
IPAddr dwDestAddr,! Z# u8 l7 \% a2 L6 N$ _+ r" E
PDWORD pdwBestIfIndex
" \! D' H* }" n: [: U; h);9 C4 S; u0 b6 h
- G* F6 U+ D5 A: F* Y
! J1 L4 a. M+ ?
typedef DWORD (WINAPI* TGetIpAddrTable) (
' i- `3 z+ C( A$ E2 J PMIB_IPADDRTABLE pIpAddrTable,
0 e) T. _. @1 ]4 c p# g" m, h PULONG pdwSize,0 M7 B& T: {) j7 m$ W0 n6 a( I* w
BOOL bOrder n" B6 m1 E+ H7 d6 x" K& S1 f
);- B8 g( T' E" K+ t/ C
1 G' i' v( b U: a ?" N8 V `
7 v3 e7 ]0 c$ g% Ctypedef DWORD (WINAPI* TGetIfEntry) (
* t1 A: v; Y9 @0 F PMIB_IFROW pIfRow# D0 k4 ~' [* D ]# @ d
);
5 [& O; v6 ?% W3 m) b$ ^* L; O" M0 D1 T) e/ L: |
* p1 Q$ ~7 b6 G% z& }# f) Y
CString translateUPnPResult(HRESULT hr);2 W0 M: Q/ }6 x5 o( r
HRESULT UPnPMessage(HRESULT hr);- X4 u5 } Y' {) ]) }6 r4 {0 T0 b
8 u- r# K6 m7 H
& k* r# @4 g$ t2 gclass CUPnPImplWinServ: public CUPnPImpl3 |* n! ^4 }* z& y! o* r! s
{
# b& X- K; y5 u# D+ k friend class CDeviceFinderCallback;
1 N' z5 p* e8 u! `& t# Z2 P friend class CServiceCallback;
. j: }$ B% R/ Q% M// Construction" m; e& p2 Y, d$ j
public:4 J- I- a2 P8 Q
virtual ~CUPnPImplWinServ();0 @& [8 M; h1 ?9 s3 k
CUPnPImplWinServ();5 B4 W) h+ s( K& u: d* Z7 k9 j
/ m5 H. k4 ]% N% D2 E
& Y4 G: @1 w( H1 u5 j4 t virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }# |* |7 K% q* V+ N5 \% `( L$ I1 H" h
virtual void StopAsyncFind();- E# }0 u4 S& l z1 @9 }1 N* l. @
virtual void DeletePorts();
: i" C, i7 x- T- ]% L4 f. k# D' a virtual bool IsReady();# z2 S& s" l; h$ a+ d- J( B4 {
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
" i7 C) o, a' c/ F1 J% f# h. d2 q0 c* n G
# M- t m, L: m/ {5 n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)# A0 Y5 `8 `% c# ~; K6 N! n' Z; r
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 t2 S& f# j9 S: o3 S
virtual bool CheckAndRefresh() { return false; };
7 k8 E2 g! t/ t* y( `
0 D* s9 g( d" W; s2 N; B% o! s3 h' }/ D; Q
protected:7 o3 w( y5 D, `' I9 W! @
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
2 i+ O- P7 P( v& c) m, z void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
) {2 O9 y" Z& C; _ void RemoveDevice(CComBSTR bsUDN);9 j9 f5 A5 C. ~7 ^
bool OnSearchComplete();
9 Y( S/ h1 d, A& b K void Init();
0 s* {, j, V$ O+ \) k" U) c, x; @! W/ ~$ [
+ ^% T% N1 Q! z$ {9 P
inline bool IsAsyncFindRunning() 9 \$ O2 A! z: P: k
{
. O" V- `4 Y' Z- I: n; K if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )2 O+ c$ }2 t. q# l2 o6 O
{
# l0 m, G# x5 l) Z m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
$ L6 j' |0 f: P9 I( \& E+ S m_bAsyncFindRunning = false;+ K6 i. \5 i; ^5 H0 e" Q( K U
}; _9 e% `; o n2 P
MSG msg;
, o1 P+ y4 _" c* [* r while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
; `5 _" l; d& ]" ~ {
$ V0 Z4 @/ p% A TranslateMessage( &msg );
" B& `: a4 M G& m# N" V! T DispatchMessage( &msg );
; g1 b8 k7 `3 E" d1 L, l3 B! L$ T( q }
8 A! O3 h2 M& X/ U return m_bAsyncFindRunning;
4 E6 D! A& [, X. s% Z: R6 `( z }
1 a- [ y) k$ I( d& N
) U& o& u. @. x0 ?
$ M* [! ?! t# j. H. V TRISTATE m_bUPnPDeviceConnected;
) c& M( s& ]; D5 X( U4 ?' h# w+ b' o& {9 b: J/ p, G. j
1 H8 C |! q9 H" Z- [& z
// Implementation
# |6 d4 e0 y& m, E // API functions
; N s9 R) B6 a& J SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
3 J* S" h& s+ f4 p, ]6 I SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- t2 X6 H# y1 Z G BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
9 r, h1 x% M3 Z BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
: c5 l( j4 v' l( Z0 h6 z6 ] BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
' B( G0 B: V. ^/ h- m% [ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);, d) p; H3 c6 k( |$ {
1 M. y3 e% n. `+ r1 V
7 }( t. ~4 G3 w9 R1 r+ B/ n# j
TGetBestInterface m_pfGetBestInterface;
- Q" r* G* A; E7 q TGetIpAddrTable m_pfGetIpAddrTable;
9 p3 G: u2 H" g6 p' [ TGetIfEntry m_pfGetIfEntry;
1 l* Y: D% U# n6 H, B2 s
( V( u. b; Y# a$ w8 ]& b( J) x
U# R' S4 ]" |; |/ b2 p) p9 R static FinderPointer CreateFinderInstance();
6 {$ e z6 }( @ [ struct FindDevice : std::unary_function< DevicePointer, bool >! M8 F' o; t' G+ ?/ X+ Z
{
* r* ]% E$ W; f# u: I- N! {" x- {- X FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
, O) ^8 ?0 E8 Y# j/ Q- M3 w result_type operator()(argument_type device) const
, l+ B* o- b6 [4 Y3 L8 O {5 {7 D) `1 ~9 W" G' |" L" ]5 H& ^
CComBSTR deviceName;
, Q9 i4 X: ?8 \( x! O( S0 u HRESULT hr = device->get_UniqueDeviceName( &deviceName );
; {- O M1 g1 w( ~% d
0 m0 D& f3 ?8 X# H; L/ _# r
& c. H5 i; v1 K- A0 } if ( FAILED( hr ) )2 L" x- v( Y7 N: I! g" q
return UPnPMessage( hr ), false;
# h; t& K2 V7 ~1 R
3 ^3 u: e# O( [# H
. a( W: f6 {5 Q k' ?5 F$ [) A; \ return wcscmp( deviceName.m_str, m_udn ) == 0;
5 K7 m( N1 |8 T7 _' y }3 x5 f, f6 }0 q& R2 x$ ?0 q5 Y3 J
CComBSTR m_udn;8 ~: E- e# i5 p$ k/ k0 w
};
1 ?) J) K& `+ T- l# \% l3 X # p' G; Q8 a3 C( d. g$ e
void ProcessAsyncFind(CComBSTR bsSearchType);
; v. J- ?$ ^% y3 U; D$ ]% t& F9 p# e1 b HRESULT GetDeviceServices(DevicePointer pDevice);* F) {& q1 Z7 @5 b0 U& }- G% I
void StartPortMapping(); ^& B" v) n. X
HRESULT MapPort(const ServicePointer& service);$ e* R t; S4 w7 M+ j, c
void DeleteExistingPortMappings(ServicePointer pService);1 o, W# o: s" C- _. p" U
void CreatePortMappings(ServicePointer pService);+ f3 U5 w0 g" _+ b8 p
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); h% p* B9 `; z+ C+ c
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 0 x6 r7 Q/ ]4 H" `4 T1 Z
LPCTSTR pszInArgString, CString& strResult);7 A Y( l& J9 c. a3 i
void StopUPnPService();
% E- p% f* B1 G6 w7 ~. c7 w
, @# x7 W3 M' G; P9 f, D0 I- ]
2 e4 J+ m5 H. K' Q) Z+ F8 Z% B // Utility functions$ b* h* |5 b |3 \
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
9 i7 q6 A% s: n1 B INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);0 \( z* u+ U( U8 Q6 Y
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);- b5 \' ?$ E6 H
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ |0 e; \+ ^3 K V4 Q
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
% Y/ A9 v- B1 y! O HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);1 ~2 K* w; ]. T; v* K5 k! I
CString GetLocalRoutableIP(ServicePointer pService);& B$ @8 X8 y# A' z; F2 h1 V+ |
/ `- U# n5 ]5 D7 B3 r2 o" V R. M# o4 \
// Private members
f6 y1 [2 P$ C' I0 [' Q8 lprivate:
3 q: a' J. }4 Z8 E+ G, m" W9 B DWORD m_tLastEvent; // When the last event was received?1 n9 P7 q; f+ |; X3 D& E
std::vector< DevicePointer > m_pDevices;1 y' E7 {. t s" o0 _, Q7 }
std::vector< ServicePointer > m_pServices;
3 S' T8 k$ D. f; q% x" V" X FinderPointer m_pDeviceFinder;0 g7 i2 L0 s8 `
DeviceFinderCallback m_pDeviceFinderCallback;& ~# U6 C6 o- p2 N) w* D! D
ServiceCallback m_pServiceCallback;
# H( u" @9 S2 o h' v" P) `% O( _" H' V6 O- c5 J
& {7 n0 R$ y" h6 B5 r$ v$ B1 b! B
LONG m_nAsyncFindHandle;
; r% O7 d5 I8 p6 d0 f1 x# k bool m_bCOM;& t/ K( t, Z4 V. g( r( t
bool m_bPortIsFree;; \; g, ?9 m9 ]# a0 u
CString m_sLocalIP;
6 @& M' w. F! U; v$ `5 \7 a CString m_sExternalIP;. U" b1 t7 j/ \
bool m_bADSL; // Is the device ADSL?
( |- C3 D9 A& N0 s/ T% n8 X bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
% \+ p1 D1 x0 u; n# a1 Y" k } bool m_bInited;/ w/ z. @2 l6 Q% c
bool m_bAsyncFindRunning;' R8 a) l7 S/ Y% n9 C
HMODULE m_hADVAPI32_DLL;& Z( l! `2 |4 ^5 q
HMODULE m_hIPHLPAPI_DLL;
8 q& q! a) U7 x% {) Q; y. g( j bool m_bSecondTry;
1 g6 W' ^& J* y: I7 k, S bool m_bServiceStartedByEmule;: C% F# l6 |- c- L7 {0 J9 O- r
bool m_bDisableWANIPSetup;; r" L& o( k, G
bool m_bDisableWANPPPSetup;
# `- M4 U- Q6 _3 Y2 H/ o% ?& p0 p' I
3 h: ^3 U7 ~6 l: Q, M1 a
};
4 _+ [* w, `7 x) ?- Z% O% @* @' a
3 b5 L8 c6 M7 q+ @ _1 X0 B+ `- g( w- Y* `% [% i2 j& W& V, Y
// DeviceFinder Callback
L9 r" G- b+ p: ]4 T2 ^class CDeviceFinderCallback
. R4 p/ I6 Q$ z- P7 U : public IUPnPDeviceFinderCallback$ J, ?* t+ F7 d8 S- @+ A6 `) r
{+ T4 e* a- B" [( r+ d% f; I
public:# g8 ^7 O/ ]6 A. M7 h% Y
CDeviceFinderCallback(CUPnPImplWinServ& instance)
& z* R5 c$ C% M* M7 R ^- g : m_instance( instance )! w5 R x* k: J- H6 S
{ m_lRefCount = 0; }
0 {& {+ a1 y1 S/ i0 u
- R5 g9 d- u. c
4 p) m! y/ }- b" v q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
]+ \; M i! C' c STDMETHODIMP_(ULONG) AddRef();
8 _# ]; i9 d$ l2 ~! `/ Q- M6 Y6 t STDMETHODIMP_(ULONG) Release();
3 ~1 \! ?0 {( n! c
4 @8 r. s8 P, D/ t
& {; E9 g$ {$ }( z// implementation
1 f8 @, H: O1 V3 Lprivate:
( P, h7 {/ u2 a9 p8 F0 ] HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: A( B9 d9 M5 S2 L# F
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 T. C) T, N6 {8 q HRESULT __stdcall SearchComplete(LONG nFindData);0 U+ M3 e4 V& |2 s% d, }
: H* i$ x, c/ _" N- @
" f3 l& A) P3 v0 Tprivate:
% A$ J }2 n$ F) J0 h6 F CUPnPImplWinServ& m_instance;& ^" y* p: v0 V8 c( S/ A
LONG m_lRefCount;! S% X- t- ~0 |" I
};
4 @- C- a1 S0 B' P2 q7 n* r$ m
( f$ p$ J5 f3 h6 D7 z0 W// Service Callback
r2 B6 ]9 U: p& o; P/ m5 c0 Mclass CServiceCallback
8 {1 G! l. Y9 h8 D' I; u3 A! l : public IUPnPServiceCallback
4 D) X& p1 R0 l6 J9 O8 S. Q{1 c B! G' I6 i; \4 u R" Q* g5 @/ M
public:
& z6 {$ F- p" {/ w7 D CServiceCallback(CUPnPImplWinServ& instance)# z6 H3 Q- ?9 }$ e5 @+ ?* h; c
: m_instance( instance )5 U/ g2 w0 X) J6 T' K: ]6 p3 J% q
{ m_lRefCount = 0; }
9 k' o- b9 D* X% n) e' e
# v, x2 F' s4 Z' i STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ t! N8 {7 z- ^' Z) H
STDMETHODIMP_(ULONG) AddRef();% M, T0 G, C+ F+ g+ I5 H1 V
STDMETHODIMP_(ULONG) Release();! x1 N) E# X0 [# p
6 Z3 t: k# T) f( X* } |' {, _# ~ h0 F I
// implementation9 C( y) L& u, W: s/ k; H
private:( Y6 i# \0 l: k( E \/ z: Q; o
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);5 A0 G% [( X6 {' N1 \
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);: R2 x6 _/ m: O5 W L6 M3 G
$ w( Q& `+ x2 h# @3 i) U
& D: ^/ e6 g% Xprivate:7 j/ Q( j7 Y. F- h& [& k5 \
CUPnPImplWinServ& m_instance;
" F9 s& r- R- A7 }+ u1 U! v LONG m_lRefCount;
; W [, d! f6 }1 \8 R};
% u4 h2 i r% H6 |! L0 _6 i* X& t' J- q+ q2 O' N
9 Y' j& z( B8 `+ ]; X# [/////////////////////////////////////////////////
. C& D0 ]6 a4 I+ t' Q& ?9 F
, A: {9 q$ x1 f/ r1 v4 k" _; \" y( X& g4 D
使用时只需要使用抽象类的接口。6 `3 Q, o2 ~# W# U3 z
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.0 @4 m7 N( E; h3 T3 J1 }8 L
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
- q9 N# C8 |3 wCUPnPImpl::StopAsyncFind停止设备查找.
# g) f M' ]( z! g* XCUPnPImpl::DeletePorts删除端口映射. |
|