|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- X' F5 Q: ^: A9 k: B1 m
" V9 D5 L3 e7 z& A/ H3 [6 I
1 d9 e) }5 Q, F5 H$ `3 t7 z) V///////////////////////////////////////////8 Y3 s2 W. d0 c+ l
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
% z2 [- I. i3 ^/ {5 U1 B
7 z6 l: @, w2 p: s- J/ o
2 ^0 g$ d7 D m8 y# o2 O#pragma once
0 E0 C7 N3 C" f- l; @( n4 \#include <exception>1 X$ x+ j! \8 M+ O. ~) w
" h" s& M4 g& W% D
9 D& u0 E4 F. A/ e! r P
enum TRISTATE{$ K0 h4 C7 }0 P' p7 B- V
TRIS_FALSE,
" W0 k5 K, X( f0 L TRIS_UNKNOWN,
! Q( s+ c" {$ f) O4 Y" J" D4 J TRIS_TRUE- Z% M6 }2 m0 Z! f0 W* k+ \
};
- O& f$ }- ?( U% W: G a* F
. P: f8 e0 y; K k; q0 T5 |
$ g+ }( [0 t2 ~3 f) [5 Cenum UPNP_IMPLEMENTATION{& z0 C. O6 ? D8 H5 g
UPNP_IMPL_WINDOWSERVICE = 0,& Q h9 }( |; g9 f% Q5 ]
UPNP_IMPL_MINIUPNPLIB,# A. u3 f6 K0 a3 `
UPNP_IMPL_NONE /*last*/" [: n6 E) M4 u! i
};
2 i/ [* U2 Z9 ~$ U o: \! Z9 S% o" B. D
$ S1 j5 o9 f; H, U0 \6 b
2 P- l0 G7 F6 Y; p
' @7 E2 P5 s" \6 _class CUPnPImpl
# @- s% h4 U7 z4 L' K8 Y{
6 b5 p) [4 J, |( Q! l+ Q6 ipublic:
z, G* i5 G/ u8 [/ a# P1 I" Z CUPnPImpl();& w3 S& ]; z, l- a m
virtual ~CUPnPImpl();
) k7 [& R6 z2 {% Y# o/ f5 Z, T. m: j struct UPnPError : std::exception {};* |- ?2 E/ `2 E. P: h! M- p" U
enum {
- K& ]( q4 y" T# X) u5 q UPNP_OK,
% C! | V0 |1 |- H$ x( C UPNP_FAILED,1 a* s5 k) T; ]
UPNP_TIMEOUT/ B: P; ^+ { M" D, Y' z
};# a8 d2 W6 s+ o1 v) z
% e. G/ V+ Q. J
* d, s! W* }/ _& F& c
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
! v! P% y) W2 _2 S) w: s virtual bool CheckAndRefresh() = 0;
% j1 [ S% Y1 p4 v' L. k5 t& S virtual void StopAsyncFind() = 0;
" N3 A' S% \2 z! B/ a2 b! ~ virtual void DeletePorts() = 0;
! [( l3 U# f+ P/ f+ q, j& n virtual bool IsReady() = 0;. K" ?( `7 s. g/ @" P; l( f
virtual int GetImplementationID() = 0;
- p1 j+ B8 Z5 ^. H
% c4 w$ e% Y5 A0 x( G, i: v( G! \, ` void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
, A2 I' _5 F0 z; v8 v" A' a# @2 V
: n" H$ S( {* U8 t0 ?( f
9 }) w' K/ V, y+ p" U void SetMessageOnResult(HWND hWindow, UINT nMessageID);) d# R# v) ~: h% f; J
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
1 u1 N/ }$ S. y6 g! T. S, j uint16 GetUsedTCPPort() { return m_nTCPPort; }
% g4 w! Z1 R+ w$ { uint16 GetUsedUDPPort() { return m_nUDPPort; }
# f2 l! [% Q% A* q5 T3 T: y
( H6 N0 S5 N) C/ _0 Q, Q( i) n3 y* j1 N
// Implementation, ^! ^4 b1 p. Q" s
protected:4 @- Q: ^% P. a2 [1 M. O4 G8 k
volatile TRISTATE m_bUPnPPortsForwarded;8 E) J0 {; b( Q
void SendResultMessage();: ^1 U; j) n% |0 t5 }7 T/ q) E
uint16 m_nUDPPort; b+ j# ]6 a) G% |8 H
uint16 m_nTCPPort;
/ P' K m* ?0 q9 }$ V$ b: [/ L uint16 m_nTCPWebPort;( D( K+ y+ d0 J% I8 C
bool m_bCheckAndRefresh;
6 [& _7 k4 |% G" M. @! g
P" v. S: d0 U& ^2 e
7 Y1 n# t) a) X0 G- z- ?private:5 t$ }8 Z9 R& V" o% N' t! n
HWND m_hResultMessageWindow;
+ X) c" X$ {2 M3 a0 H" N UINT m_nResultMessageID;
% I/ E; t$ G0 |' q1 w# A% |1 ~- r3 H. U' l
7 W0 D: `& }& ]9 g* H. H" k; O};
# V; |! v' }' ?( v% Y3 t! u: }# R
' ]$ r# o9 D# M+ e* j) b7 i
% c- w* n* O- B( o/ }// Dummy Implementation to be used when no other implementation is available
6 s1 \$ O( _2 S( S. R* n& C. tclass CUPnPImplNone: public CUPnPImpl
# }8 a0 f8 R, Z0 |# [3 s{$ |+ Z0 ^8 x+ A) H) [ o
public:! F6 X) Y4 z* v4 u
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }, a# x- S" [! a3 e1 m! m f# l0 m
virtual bool CheckAndRefresh() { return false; }6 `0 F0 P: z8 x. y( `9 H
virtual void StopAsyncFind() { }8 z& _+ X& `9 S! F/ @; {
virtual void DeletePorts() { }
- O, T! W( j. @' o. h7 @. d virtual bool IsReady() { return false; }5 h! |: L. b: n5 y
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
' |3 @" R# K) W};
5 E! Q* J% s5 v* \- F, i7 A6 l% l0 s9 N8 T1 b3 \* B
5 s* h- F+ N* l5 m* w0 ~7 q
/////////////////////////////////////- z3 ^$ }) [$ o! t' x' Z! x) g
//下面是使用windows操作系统自带的UPNP功能的子类
- _. W% I( `) q9 V! E& y6 |6 a, Y( q7 W. ^ {' z' ?% l
5 |1 T# n) a0 Z: \& n* |
#pragma once
% Y0 Z3 ^, k* y' c% u9 B: x#pragma warning( disable: 4355 )8 p6 X N' U! h2 |5 z& }2 V
( f! u6 i7 c& S3 l, C4 F6 g
3 I/ A8 D/ q& d$ J# O \' [% D#include "UPnPImpl.h"$ z: E# ]2 C; M1 x; l2 ^5 \) \
#include <upnp.h>4 j9 }3 M# f6 x% N" ]
#include <iphlpapi.h>& h' P! q2 y9 b0 m
#include <comdef.h>% v! [$ k" H( |/ r+ r* E) g
#include <winsvc.h>
0 D, u0 H& c3 q. c8 F1 u: |* m+ N' L2 k* a7 Y% q6 U2 J
8 c/ J+ \: `7 |$ `3 q#include <vector>( E1 x: d' N2 U& K+ G) S q
#include <exception>6 t( g; N$ o' \6 B' L: e
#include <functional>$ `2 F; A9 @0 R- \ P
1 l; F w, y, r* Q
3 y9 d) _& P0 g% p, C9 e" J. Y0 c H/ @' C4 v' p( I
, k' W" U- v0 }* \( U% x& Ztypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
; b9 V) `4 s: o9 Ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
+ ]- I% K9 q+ J# ]/ ~2 G+ Jtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;* z1 T+ x/ y; y" N- T* Y: u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;- g1 H# [" I0 y" k# X! }
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
7 a& \$ Y9 W8 G8 H' Mtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;6 Z0 s$ a4 c0 G C9 J
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;+ ~6 h0 D4 n% ^/ ?$ p7 N$ U! l
- B, E8 I0 y9 Q. E
$ X7 ]& w& {( a; L2 vtypedef DWORD (WINAPI* TGetBestInterface) (9 X7 C; h6 h/ x m
IPAddr dwDestAddr,
2 L* t* _: S; r* U PDWORD pdwBestIfIndex: `' x! @1 Q7 v! F9 r/ n
);$ o7 ?; g. Q, x" l! n) P
! M5 h, s$ r$ H4 p$ H
/ c$ h# g o2 K' |4 l3 M5 vtypedef DWORD (WINAPI* TGetIpAddrTable) (1 k) ]& l# M/ W& r
PMIB_IPADDRTABLE pIpAddrTable,$ w2 p% I' b! P
PULONG pdwSize,
+ v4 i, M9 J9 [2 s) w0 a+ n% l BOOL bOrder* H1 b, \, W+ P
);8 v2 c% O$ J. b/ q2 f+ |
* W7 y/ T1 F4 c* G* O9 l8 m5 j& B% H3 F5 Y
typedef DWORD (WINAPI* TGetIfEntry) (
2 f% g y# U# C+ P8 f2 ^; f7 T5 i PMIB_IFROW pIfRow
6 F# \! m/ C% r! q$ {);. N1 Z `; u" @0 t7 V3 @- D
8 T1 s8 w" [- g, n* z. A
6 x/ b) o& q9 \% b3 \0 S* h
CString translateUPnPResult(HRESULT hr);
4 R# i; R, K$ q$ l; p. L7 E2 D% JHRESULT UPnPMessage(HRESULT hr);. d% }. J) |3 b% W+ e
$ Q$ m( X0 Y" b; C% |1 l& @ d6 S2 i- X0 Z3 w% C, ?% V1 y" L
class CUPnPImplWinServ: public CUPnPImpl# I, ^2 C6 |/ A( K3 V
{8 i+ f, Z3 j9 j3 l3 ~- j
friend class CDeviceFinderCallback;
0 H5 Q& R# i: s+ Y# p4 N% s& Y friend class CServiceCallback;/ u; ?$ ~. j6 K3 i: H `
// Construction" G3 T# T. _2 }7 a& R2 d
public:
1 Z, W& p+ [1 t G7 @& V9 V virtual ~CUPnPImplWinServ();: l0 Y$ T. B) e+ h7 F
CUPnPImplWinServ();
0 }3 }( G3 T5 H! W' X" K( g; P* b/ z6 l( d5 l, @% l1 J2 q1 j
6 Q5 \ {. y6 v& i6 ]9 N! l7 g
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. | J& y' c! M: S, o virtual void StopAsyncFind();3 h/ w9 B) f$ u( l
virtual void DeletePorts();
5 t& R* ?, Q M& g$ @ virtual bool IsReady();1 ]( C- r- U$ U0 X2 c
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
& h t, G( W% K0 F+ J! r5 L
Y& v, v' Q a% A) O$ v
0 v) }: ~$ f# x: j- t8 u // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
; E, s1 z0 P6 k) m // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 B/ J* \* o2 M; f. |$ a. y
virtual bool CheckAndRefresh() { return false; };
' w3 B# {3 q6 Y. R
. H) {' X& `& p6 y* n5 u5 ?, C& j( M# ^& {" q
protected:8 f5 @0 x+ ^1 x0 @) Q
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);. S/ q% m9 ?3 X* b
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
- `/ J/ w! g- B( i, [! I void RemoveDevice(CComBSTR bsUDN);
; p( R1 g# L- c2 f; x& F bool OnSearchComplete();
5 {5 P, ^3 ]! C; P0 ]% J+ H void Init();
! n! Z9 \1 e7 v& y4 O; K7 P* D, S$ U. G# m. }* C! z5 e
$ G8 B/ i. ], T6 W B7 H inline bool IsAsyncFindRunning()
# n& ]- w5 l; Y9 W {9 J% y% a+ n! l$ o) W
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
6 C4 c1 G) S) }1 z6 x, { {
5 m ~( Z3 J. _) o7 N# `% L m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
5 H) V/ o# K5 s: x, V2 N m_bAsyncFindRunning = false;
' Y' p. F( T2 F# t$ c }; O6 ]3 r) c& p- \: D% E5 e- A
MSG msg;
, P2 b, H0 O5 t0 ^) W while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
3 h2 w7 a' Q" ~! V1 k6 r {& Z+ `- K J( g+ b0 N8 ?
TranslateMessage( &msg ); c; l: e6 \4 b
DispatchMessage( &msg );9 u b+ p7 @: |8 _. ?0 ~& V
}
6 d" V: V0 @$ I7 Q return m_bAsyncFindRunning;
9 p, ?' J# D) i. f }2 |$ D" H: u( J: M
+ K: g- A J4 u5 m/ o5 J+ c8 z( ?8 w4 r. F! _* ]4 o: h$ Z
TRISTATE m_bUPnPDeviceConnected;$ J9 \. y0 l6 y( Y, ?; Z) ^
! ]1 N/ z5 T- T& c1 h. }
( c# g8 F8 Q; ^& k3 @7 U8 b// Implementation$ C6 [# c g$ v, X& ^0 M; l
// API functions
+ R, E- b! r1 s9 Q, I SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);; x/ {& N/ {6 n- O
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
8 z. J' Z, s+ w' O( k/ Y BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
0 H( A* C( S; A BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
8 S4 V5 V R1 ~) { BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); I3 b# [' R! x2 i
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);) |) M9 e! W9 F, E5 T5 D+ r0 D- T
5 o: H; K: h2 m1 R0 r
# J+ j* Y5 {5 g
TGetBestInterface m_pfGetBestInterface;
5 F% A5 U7 H ]/ t9 G2 { TGetIpAddrTable m_pfGetIpAddrTable;
( K& i: a# @& I. _' c3 C6 Z2 u TGetIfEntry m_pfGetIfEntry;
% x+ h* p, \, p# k- c
" K! F/ x: a0 B$ p3 A5 T0 l( o
. S0 L1 e; R7 G. _$ V( `8 K static FinderPointer CreateFinderInstance();
" e& ]2 l' E0 X4 n+ x struct FindDevice : std::unary_function< DevicePointer, bool >; ?% I$ j& z0 X3 D D. y/ U2 _
{
7 T- c9 C$ ?9 ] FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
, q, l0 M. ^$ l/ v" _ result_type operator()(argument_type device) const
- F5 ~/ a" K3 n4 |# _2 b b1 \ {+ `0 d) {! ~1 d, W
CComBSTR deviceName;
, ]( c* i. f2 m HRESULT hr = device->get_UniqueDeviceName( &deviceName );' ?1 a* V2 D. v
6 v+ D* Y# W4 @2 c
; f- _' {9 A# U( ?- z6 Q) K
if ( FAILED( hr ) )
8 y* f+ M; \; W5 v return UPnPMessage( hr ), false;* R& Y, o v/ g# A; r3 x
, O. Y* r' ~( K0 t% C* r
& c1 A1 p! i, @5 i return wcscmp( deviceName.m_str, m_udn ) == 0;1 A; m9 @+ z, w+ B( ~
}
1 {* D% K2 e+ x" X CComBSTR m_udn;
$ V) @ j6 I# u2 E' a };$ \# ]1 a$ k6 \6 h* k- c5 b ^
; ?9 t4 M: h7 p+ Q# L$ J, u" J
void ProcessAsyncFind(CComBSTR bsSearchType);, L0 I }/ C3 c" h+ A* h) }
HRESULT GetDeviceServices(DevicePointer pDevice);
% M* @/ y0 |; p$ H) b' s void StartPortMapping();8 R, [* z: O4 ^& n
HRESULT MapPort(const ServicePointer& service);5 r+ g7 u1 D7 U
void DeleteExistingPortMappings(ServicePointer pService);
& p) d+ S F0 X1 m5 M$ X void CreatePortMappings(ServicePointer pService);
* c' u b. c+ C) M' |$ E HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
) I: e) q: E1 C0 N9 Z3 } HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; Q: d# Q ^) ]- w' e! A. y" a LPCTSTR pszInArgString, CString& strResult);
) D7 \9 ]3 E0 [9 A. ^' G3 Y- d void StopUPnPService();( E4 J O4 E9 i0 P7 a
4 O$ T8 P( R8 F
$ Y6 d7 {8 r5 u; r2 V; ^* F! u
// Utility functions6 ?- K* Z; ?; C3 q
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
' y ?" T+ F. T) z3 h INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* [, x7 }+ k% L: `9 W" ]" F; W INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
9 V. V' A0 _1 g4 T7 c void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 Z2 |% y" _; o# B# k2 Z$ H
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
9 ?) L, y# I) B! N2 |7 ?5 ~ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);# P/ X3 L7 K4 J' U/ }4 {
CString GetLocalRoutableIP(ServicePointer pService);
6 C0 a9 u z l9 | e5 g- F/ g" [% c; T. a, P' z
5 o3 ]/ @; K; \, |; f, Y// Private members
/ K0 y! N* }4 E/ g0 a7 g0 ~" _private:) A9 L: Q% _3 D8 E; Q. U5 v+ B* U
DWORD m_tLastEvent; // When the last event was received?4 b- Z( C- q p: U+ E" @" s* L
std::vector< DevicePointer > m_pDevices;
" y* u& p2 S, f' S5 m std::vector< ServicePointer > m_pServices;3 E3 ~# `/ m I. [* U
FinderPointer m_pDeviceFinder;
9 A# O% `- [0 j DeviceFinderCallback m_pDeviceFinderCallback;
6 J8 [! f/ k$ S) W8 |! V ServiceCallback m_pServiceCallback;
& _" t4 \ \7 j# ~$ G* y9 s9 A" h3 \( P* ^
- [2 ]8 e( m. v1 w) l* } LONG m_nAsyncFindHandle;+ F/ m; Y- A1 u6 k; C5 ^0 C2 B
bool m_bCOM;
& t( u ?' p% x; ?' I- i bool m_bPortIsFree;! I5 {: P' r% V) @
CString m_sLocalIP;
1 d* V$ u5 ~2 j; t2 ~4 a CString m_sExternalIP;0 g$ c% V1 e7 Z& @) `
bool m_bADSL; // Is the device ADSL?
! S* f& _% m' H( ~, C1 K! K bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
8 f7 O4 D# d1 v7 S$ d+ ] bool m_bInited;: _) u* Y: e- A+ c4 W
bool m_bAsyncFindRunning;
' e; E4 r8 c0 r/ S5 A HMODULE m_hADVAPI32_DLL;# E# T2 i7 D' [4 q/ `; y
HMODULE m_hIPHLPAPI_DLL;, S: o( S4 n( s
bool m_bSecondTry;( G: }7 Q8 c" |% g1 b: w
bool m_bServiceStartedByEmule;
+ E" K3 i3 s, y$ L, Y0 Y bool m_bDisableWANIPSetup;, z2 p9 |0 R% A' C
bool m_bDisableWANPPPSetup;
; c K% k- P8 g: s* ?; ? Y. l2 X( X
/ z* r' ]4 x; ^" w6 _1 u
};, f% j1 ]' W- | k( a+ X
& x1 ]- E x, J4 K+ O. ?# p
( x3 {4 ~( G4 n0 J$ y* R! S
// DeviceFinder Callback
8 f' t6 P3 i a( m* @, s* Dclass CDeviceFinderCallback, }3 E5 B# j/ A+ ^" Y) Q# Q
: public IUPnPDeviceFinderCallback
+ \5 D1 w1 o0 N- o# \/ T" C{
) |' \1 O$ J w& W' Y& u2 |+ opublic:5 f/ z$ h% U/ M: z0 d7 L; x+ }
CDeviceFinderCallback(CUPnPImplWinServ& instance)
$ {7 g% e. J/ m9 e/ J$ a+ H : m_instance( instance )
. [+ { _2 x. ~. @/ Q2 f% D9 Y { m_lRefCount = 0; }. I( S/ J/ j3 B4 n
8 F: q. o& K0 `" a
1 W, W8 o8 S0 b% K$ G# T3 j STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- [" M5 }3 W& T- B STDMETHODIMP_(ULONG) AddRef();
6 W, W7 N( ?* [9 E' `4 _5 f STDMETHODIMP_(ULONG) Release();
) q. V0 G" K1 G) s/ ^5 P5 D
4 D! C/ E q# x+ b0 W- n
" G' g; j8 i0 {7 W" G& L// implementation
5 i* B2 b& ]- H0 A1 Pprivate:+ P$ m5 u2 A7 x( W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 x4 ]6 `, a: b HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 R% o! b1 O0 C3 N$ n5 F: m. C HRESULT __stdcall SearchComplete(LONG nFindData);' Q6 `) y% Z, A# y7 U# M [ R
" \5 [. P, d2 _5 c! t# ` n
$ d# S& m* W0 |# ] Y; H4 Lprivate:5 `6 J2 ^2 ~, _; i/ Y
CUPnPImplWinServ& m_instance;
6 z: d7 x4 V4 d, b LONG m_lRefCount;! x$ _3 U" k! `3 f& m: p6 T% ?; ~
};4 L: ` t9 @' i" ?# M- k4 u
7 `' L* P2 ~) G1 q; i" ^; f8 Y2 a
% b7 K6 w, k5 o+ e4 M8 Q* T8 X// Service Callback . j |# N5 [: q" N& s: \
class CServiceCallback% U9 h, E/ H5 Q3 e# s
: public IUPnPServiceCallback# m' p5 a( W+ M, e- V/ d
{
6 l. R# z) J `+ U8 vpublic:
- j- ^" j8 `/ P/ k+ l% c' m CServiceCallback(CUPnPImplWinServ& instance)
1 z, U; X9 m. m# w% X : m_instance( instance )
; o$ K+ {: U# U4 Z) I S: ~/ F { m_lRefCount = 0; }
. I6 D) b" ^: I A, V' r; A
7 k2 c9 u6 m' e2 B5 f STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 Y* y! b0 N( }, S Q STDMETHODIMP_(ULONG) AddRef();
% _; e( _# D7 u- S, Q z" F STDMETHODIMP_(ULONG) Release();
- n+ P1 D- X2 T1 x
, E& g4 c2 U/ `. B6 {' a2 z8 U, X; s& _! O% @' T. s5 ]
// implementation
* h- n2 k) j7 R x# \private:
7 |# u$ r4 J; E HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 y0 g3 X/ Q( c7 Z- }; f/ z
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
; Z& h* _3 v& a1 w3 J7 h, d W; ?/ l# s6 C1 J7 \
`, l/ f. b4 e" t
private:
2 `' j/ P) ~+ g% j CUPnPImplWinServ& m_instance;
$ J! {3 k" V) r5 q LONG m_lRefCount;
% J/ W0 \) T+ @: s2 P/ [) w};
5 z0 U# l1 {3 z- J& Y" F" T6 s( \+ O" g' V! T
5 N0 r. W- r" E/////////////////////////////////////////////////1 @4 N5 ~( A9 S% O! ]& J/ I8 N
) x) K+ \9 S) V" \: R4 ?2 o; T
. F# h p% T r) \- ?使用时只需要使用抽象类的接口。* C) \* u6 ?% l
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
9 G5 Q9 h( Q0 n. pCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口./ m. \5 \2 e- v3 E' _+ t4 q% s
CUPnPImpl::StopAsyncFind停止设备查找.
# b! _. j" L$ U! f! jCUPnPImpl::DeletePorts删除端口映射. |
|