|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
( F' d& S6 Y! J$ o
" p4 W) {4 `% c# j$ G0 ^% ?6 ^
5 Q+ u# [6 a s: O///////////////////////////////////////////
/ A9 s+ J' x2 k9 _//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
+ N( W7 K5 [5 U: X' q" d
2 Y( @* W* m+ V: ?% U. s. v
# r; P j( D, h$ z- a: m#pragma once
' ~. k! |: ^5 o, E k#include <exception>
B2 s4 O' ]% S! I) \9 ?# @9 F- R/ A
. m! G4 S1 I8 }1 c enum TRISTATE{
' I9 X( z6 S* X" u TRIS_FALSE,# M+ { E: B/ r( L( ?# g% ]9 y
TRIS_UNKNOWN,
+ M- Y5 K1 R# \! W) D- X) K$ e3 U TRIS_TRUE
& @+ U& ?. K/ \9 x X9 ~. K};( I( \1 _' ^% d+ V
8 S" L2 L2 w- o
- }( M5 h0 p7 V) v# U0 \" z% Q5 genum UPNP_IMPLEMENTATION{" Z* |( ~* G* C! r6 S* C: D
UPNP_IMPL_WINDOWSERVICE = 0,/ K' U3 T# l% D3 Y5 V' X
UPNP_IMPL_MINIUPNPLIB,
7 ~3 Q" z, W9 f2 D, v0 O UPNP_IMPL_NONE /*last*/. ]% p/ ?5 c+ ?' B
};
( g4 \7 B2 v/ l7 S* A) @& P# a! K4 ^9 Q& N* t- L
- L' F8 q, v8 U* {$ z* O# S7 H( E [) W5 J7 |& P
! Y% D$ A1 f9 y& Bclass CUPnPImpl. E- h& c6 @" T- ]$ R
{
% Q- M! `4 O! h: Q% x# kpublic:
3 x; f; k2 s6 I8 D. Y' Z \ CUPnPImpl();
" N5 T( g/ _: P4 m, E9 O: M) Y virtual ~CUPnPImpl();* q+ Z6 {8 I( x @8 z: Y
struct UPnPError : std::exception {};. }) Q9 s* A; d4 J
enum {. s! m! V5 D$ a6 Y. H: o, p+ b
UPNP_OK,
$ F6 Y6 e5 \) q; ^# z; ~4 Z9 O UPNP_FAILED,
2 {9 X$ L2 P9 v9 i" I% Y UPNP_TIMEOUT0 R1 u5 P j1 W; t3 W
};1 O8 `! {* X E6 u1 v" u
; t' a4 y# U e2 V2 k
& q5 k0 a) C& N. l- b
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
7 D/ X4 p k/ [; b virtual bool CheckAndRefresh() = 0;
- M9 a1 d* w1 x virtual void StopAsyncFind() = 0;
' n+ V, B7 V: [! y! A( Q, M- g virtual void DeletePorts() = 0;, V3 R8 |9 Q: o! S/ V. k& G
virtual bool IsReady() = 0;
" j& a" D+ j# T& Z: _ virtual int GetImplementationID() = 0;/ n. J, k- ^: g& \" e3 [' S, H; V1 H
# r9 X1 K/ J* b. J, C/ w+ { void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping3 w+ v/ Y) t) g0 P+ x$ H
. ]' D7 Q5 C, ^+ h' w- \
/ S' T N* B* k+ \& n* j( r+ O/ a void SetMessageOnResult(HWND hWindow, UINT nMessageID);) t& y" \3 q6 Z( y& [: t, k' i8 n
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
; n) F0 r( |* `9 x$ V uint16 GetUsedTCPPort() { return m_nTCPPort; }
4 x, i5 ^( r2 V8 c o+ s uint16 GetUsedUDPPort() { return m_nUDPPort; }
\4 E6 T6 g2 k1 M9 | T' A! o+ |
4 I! o; |, {% _! D" N; ?" k! L8 H// Implementation! n4 t' T" S- A1 z) @
protected:
3 | P7 A6 G% |7 {: W volatile TRISTATE m_bUPnPPortsForwarded;! @+ g7 S! m3 ~; z8 K
void SendResultMessage();0 E' u+ I- u1 T, E: @$ Y) L9 e
uint16 m_nUDPPort;+ Q4 P8 O# t* ]) M# p* V- t
uint16 m_nTCPPort;
. I2 o7 z0 S+ o3 ~3 M3 H- o3 S2 b1 u uint16 m_nTCPWebPort;
1 Y( ?0 U/ A; D0 G! D- k9 f bool m_bCheckAndRefresh;$ D. ?& r& x* j* G" B+ y6 J
: w: M7 _0 s7 Y; b5 f7 |( {
; B' N. R9 p7 J$ B0 Jprivate:4 H! x$ Y; j/ a+ N( O9 G
HWND m_hResultMessageWindow;
' }+ U* Z# y% D' { UINT m_nResultMessageID;
" k- U0 A; v, C* T3 K7 c# q9 w! l' T% e8 j9 ~
+ S3 i2 X+ O" b- r};
8 k3 X8 h: j `6 d% Q1 \
+ z( Z4 ^& O7 Y$ I- i! }. a* @/ X7 R; q& ^# J0 |* u
// Dummy Implementation to be used when no other implementation is available/ j' M7 P" F5 H+ N- x
class CUPnPImplNone: public CUPnPImpl
" b/ J* r' q* h- Z2 O{, q* M$ ~$ ?/ `! v* G6 g
public:5 R( ^4 p) f: f2 e, l Q
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
& W4 S [* I0 o* i( D N virtual bool CheckAndRefresh() { return false; }
& D$ \( t) }1 m& W! y: m virtual void StopAsyncFind() { }- X- i" a" x2 {* ~
virtual void DeletePorts() { }
H# a+ [1 ~! }; e& q virtual bool IsReady() { return false; }- U' f: e+ g8 y' ?5 E$ K q; l8 X
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) D& Q' Z* T E( k};& e/ B3 L8 }3 f. ]
. Z& V0 B* g2 @/ k: o1 H" H& G
5 J+ ^3 b$ R G8 C5 c/////////////////////////////////////
/ ~8 Y- V$ L2 ?- X, P//下面是使用windows操作系统自带的UPNP功能的子类
6 T e2 q$ X- u; E. |8 A( q {: a+ c' L$ b/ `3 A& t$ A
3 @ M; N7 L, A#pragma once3 T" W0 U4 }! P' U, R& F
#pragma warning( disable: 4355 )
( k* }8 P$ ]( {# e3 O
& i8 [$ r- I2 d$ e& w7 g. h$ I" ~4 q" n
#include "UPnPImpl.h"
8 U( I' F$ H1 I#include <upnp.h>+ j* T! ]( b- b; ?. X) O9 E5 l# J
#include <iphlpapi.h>
# m6 K I' ^/ P, r#include <comdef.h>6 a. Q: A3 Z+ Y' T. E4 n( n
#include <winsvc.h>3 G( r8 _+ _: [+ ^- [
7 m- w$ Z5 d0 w
( G1 M! ]- `# I4 A1 H& z& @: S0 \#include <vector>
b& J1 v& y. ?; ?$ x8 v: c% {8 `#include <exception>
5 Q5 h% }7 B2 M#include <functional>2 O/ @3 ~! g: D" t' |0 k* V
6 D5 x5 Q% S2 V" `/ ~. f4 |8 h
- P8 j* V1 u6 I2 @8 F2 Q
( }1 c. } O" P- \% E# w8 b
0 {" H+ N4 Q! j! ~" I3 ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;* b k- K8 t1 \
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
- c3 C# ]; g1 ]6 O# x; qtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
; b; a5 A' r3 c Ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ Z/ ]8 p* V& q$ d2 Z* t' itypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 v0 R: ~5 `* @8 d) {3 L* Ktypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;9 U" u& i1 p; p* f
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& \4 e! ~- I( ?) x. B6 S8 A+ ~3 {+ o1 u, E6 f% W$ S( {
& O3 i. U- ]; ], L* B/ ^" r3 X' [; \typedef DWORD (WINAPI* TGetBestInterface) (
9 I6 _& z% s- ?5 _ v0 O IPAddr dwDestAddr,# s* `% K. c& Z$ ]9 i7 }* Y
PDWORD pdwBestIfIndex& d/ R0 k7 W/ w( N" K5 d* _
);4 k; y, H* L( e6 A
9 n6 ]; n# I! Y+ F2 s; [' ^' t8 C5 Q M0 P9 I2 B: S
typedef DWORD (WINAPI* TGetIpAddrTable) (4 k& j( L$ p- t4 _! x `: I
PMIB_IPADDRTABLE pIpAddrTable,. _* h; C o6 I6 `' t5 v
PULONG pdwSize,
7 q& D9 |5 I' d& d7 S0 T/ G+ X BOOL bOrder
. D, A& x7 t9 l/ I7 ?3 v( w);" b* j. s6 A+ L" ~* Z
2 C7 ?4 C n: E, V+ m, d5 p' ]$ p1 y5 n+ n
typedef DWORD (WINAPI* TGetIfEntry) (
0 p$ i. R6 R$ E9 _( R# }3 V PMIB_IFROW pIfRow
) n. F3 ]4 E6 G' l6 ]: e) I% G);" ^ o( M, N- D: l& }5 f7 B
3 d( w+ e. h9 D7 X, Q
1 W- l* y7 ]* d, u
CString translateUPnPResult(HRESULT hr);, q1 b! z8 C% K3 c3 Y& M% z
HRESULT UPnPMessage(HRESULT hr);
) X- c& E* p$ v' t V5 U! P1 W+ k: L" }/ R. ^ N# ]
8 R3 W0 D3 K2 A4 c
class CUPnPImplWinServ: public CUPnPImpl
" c6 z& ~& @8 h& {) n: F8 @2 a{! c6 A9 v6 [" ?5 R: P) V
friend class CDeviceFinderCallback;& q- j4 H2 `1 E( g& q! w# D
friend class CServiceCallback;5 v( m B; Q) F! \
// Construction* G& ~7 n8 M8 \ t; }* o: F9 I
public:
F. i4 n( H7 ~, u6 K2 Y" | virtual ~CUPnPImplWinServ();: s) d# r1 V/ A; h
CUPnPImplWinServ();/ g$ D& ^7 F/ \$ P: _
3 I( R* W/ z8 A: X+ |$ E
; S3 X0 a3 a( s6 h( ]. t# v% W) ?
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
5 M( b) H* r8 l# y8 e: X virtual void StopAsyncFind();
- z4 U+ r1 T9 b7 Q# B. v; c) \ virtual void DeletePorts();
$ ~9 R* l" @, s: S virtual bool IsReady();
: x ]7 Q$ ^! ^( F' t% k. ^& G' N virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
. V! d# ~+ O# y7 p% @( U
6 ?6 c( t- `; c% x* U! @8 G$ O$ K; t! O& R* ?! o) {
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)$ ]7 H, ~" ^' c7 l
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 G$ R w/ E) _2 Z0 w; k7 M( V virtual bool CheckAndRefresh() { return false; };
% Y5 L# R0 {: \/ M
) B& j' U+ j, _
+ N7 k$ f2 f) f& m- P6 Sprotected:
) M$ F# U/ } L+ e/ } z( j void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
+ r9 |# d" _" k) i void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);4 s( \2 f) \* R. q G) N
void RemoveDevice(CComBSTR bsUDN);$ j7 S; V3 e: X" L- n: @
bool OnSearchComplete();, M9 O: y2 n: p6 D1 F
void Init();, j, A5 v( S0 b3 F+ Z+ e% z
u( d) @) h) U t3 t
9 K( n" Y; A, [% l0 K inline bool IsAsyncFindRunning()
4 E' q9 b# \0 ] {
. e, H6 N! d1 a" B" F* M if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
1 U. [6 r# `+ [/ P! L. w! k/ t {
- t( `# p1 U3 O3 ~1 m m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 e: z) s, A, S2 @* ? m_bAsyncFindRunning = false;
5 M1 V1 R( I: s2 s( i }
/ ?9 }; r1 l* q MSG msg;
# e f- e; N F% C2 t( ~( h* V% M+ p while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
$ b* A0 k" {5 Y, L+ w {
& I/ X1 j, |6 {" {- k" p% w TranslateMessage( &msg );
; v) V$ N$ D$ _+ b9 g: t DispatchMessage( &msg );
" i9 t, y. I3 M/ h. t( M* a }
- x1 ]" K0 _. d% @ return m_bAsyncFindRunning;
( T6 W: g5 x8 Z2 B$ r5 R }- ~4 q" H* N: k, e$ i* g
# }1 L7 d2 |4 E6 ~3 R, Y) i* U- [8 F7 E0 c9 y1 @
TRISTATE m_bUPnPDeviceConnected;0 Q$ b5 V/ `# i8 [* y' r
0 |8 A. L. t$ k- ~4 _. v, X5 G: \
7 o8 U- P1 Y- T// Implementation
2 [/ m7 m0 A' r6 I( W0 E // API functions: ^1 k% {$ |; R9 `" i) s8 X2 |
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);# S. \& n2 @9 a: i( f6 U
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
9 o# `( R3 E) o, w7 O4 l+ V q BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 p& ]% N: y8 V" Z9 b$ | BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);9 `$ n. r* H+ j) F. h" ~9 @
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); Q1 `1 V7 t. x5 Y& y
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
, J; @. c8 r6 C; S: w( D& x8 g3 J. Z3 z
+ {6 _! v- M c2 i TGetBestInterface m_pfGetBestInterface;
+ R3 R7 u# q& ~) \ TGetIpAddrTable m_pfGetIpAddrTable;+ }' c7 V- z8 v/ @1 h
TGetIfEntry m_pfGetIfEntry;
" w* [2 `: O8 E* j4 O! s f( F
2 S# V' O" q- t: T
4 ^. n, u$ e0 _; P% x static FinderPointer CreateFinderInstance();/ Z: i4 E( z+ X) x2 Z
struct FindDevice : std::unary_function< DevicePointer, bool >. Q- w, Q) O1 A* k' M# c0 o
{; V7 t. a8 e8 S
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
0 D" ]3 K {. b; P0 Z: B result_type operator()(argument_type device) const
/ T! O# B: E8 X) W {
4 c2 F2 Z1 L# Z2 N CComBSTR deviceName;
' v% I' m4 T. z3 D HRESULT hr = device->get_UniqueDeviceName( &deviceName );: }% S2 D' e2 C$ H }
. h( H2 {0 c; E$ \
: s: s( k$ H! k: G+ E% D% i" H if ( FAILED( hr ) )
6 m6 D& V$ H9 e. E n' i return UPnPMessage( hr ), false; {1 O/ |" N5 v$ x
! O9 |) S( ^4 ~5 d" C/ ?& V( P" v9 b, T" c
return wcscmp( deviceName.m_str, m_udn ) == 0;6 f) L0 D4 h! E. ]0 ]" h% ]
}9 D# u( Z3 l) T1 S1 t
CComBSTR m_udn;. z% O; `! M* k7 C1 {% I
};6 q) J& A) _3 v* O3 O
6 _) }! N5 L0 Z6 X! ^
void ProcessAsyncFind(CComBSTR bsSearchType);! w5 A) N! M. [% e _% j
HRESULT GetDeviceServices(DevicePointer pDevice);
/ ]% B$ L) @) ] void StartPortMapping();- j1 u. Y* f/ _3 y
HRESULT MapPort(const ServicePointer& service);8 z; I( `8 U) G4 L
void DeleteExistingPortMappings(ServicePointer pService);
( U$ M9 k4 l- u5 ]3 `; ^3 K void CreatePortMappings(ServicePointer pService);3 g, Z. b6 R: U
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
0 n3 h# M' S) s. J d* ^- D HRESULT InvokeAction(ServicePointer pService, CComBSTR action, . w; S7 N' b8 x4 f* S7 Q
LPCTSTR pszInArgString, CString& strResult);5 s3 k0 E8 X( m/ S" v
void StopUPnPService();) u3 [; }& u! E2 U5 O- L
% k, O; ]( x) o. q2 m0 v* @' d; \( j! i: f
// Utility functions2 N' i/ Q4 o% r
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
2 K h: M' y/ S) U6 Z8 x INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);+ M8 G, v* H! Z3 J
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
6 ?- k) d7 X# o+ T void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
, N! V' O( n9 c HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 Q- z0 b# w( Q. |- p
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar); ]& }& p$ a( K+ b) d- R* o$ ^
CString GetLocalRoutableIP(ServicePointer pService);
" S9 v4 \/ d% X9 X/ O7 i' b
6 S5 B$ _1 b9 d' r4 s% Q
2 b5 \7 ~# E( ~: m# \% ~* W$ f// Private members
, h5 J- {5 R8 P; P# V: Aprivate:. Z! z. G* q) b& H
DWORD m_tLastEvent; // When the last event was received?
7 }% C: @9 o3 Y* _; Q, { std::vector< DevicePointer > m_pDevices;6 J: C( T( L) C0 k% h
std::vector< ServicePointer > m_pServices;
K+ ~- d7 n8 K( t) G1 K X; r$ ^ FinderPointer m_pDeviceFinder;
1 F3 D& ~4 e8 c DeviceFinderCallback m_pDeviceFinderCallback;
6 v- p" w; Q( z- y ServiceCallback m_pServiceCallback;/ Z4 @3 Q2 b7 L' x
+ ?$ C, I# B2 z8 K4 O d. F7 Z3 p6 _: p; `7 }. O7 V, G# [
LONG m_nAsyncFindHandle;
8 G1 O: f9 }3 V/ y, ` bool m_bCOM; T+ B& j5 g/ S% |
bool m_bPortIsFree;
( \2 I, W( D3 [' X% ]7 X CString m_sLocalIP;, E: j3 w c& M* u8 Y9 i
CString m_sExternalIP;
& S# C C- T5 {: C, z bool m_bADSL; // Is the device ADSL?1 k" s A. h- u( W* E# n' f! o
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?! D& r% d' @6 k4 M x
bool m_bInited;: m- v4 c3 N0 T0 Q. N
bool m_bAsyncFindRunning;! Q* {! }2 [& d% z, A4 U
HMODULE m_hADVAPI32_DLL;# m/ p }+ B7 X9 A: \) _" B
HMODULE m_hIPHLPAPI_DLL;
# N" m4 {1 Z, y4 n1 I bool m_bSecondTry;) w0 `5 o( g6 ^, }5 B2 ^
bool m_bServiceStartedByEmule;
6 H& F3 y' [0 P% L+ l# m" u bool m_bDisableWANIPSetup;
1 E$ P+ C( O& V+ | H4 f' t* f+ k bool m_bDisableWANPPPSetup;
. C4 _: z |2 S' K% Y5 W% m
4 [; M5 N' x# ^$ p
$ C4 D4 p/ s5 [% [8 L1 Q B7 s# f};" o6 t( `$ j4 P- Z0 e3 x% `' C
8 I% Q- a8 @$ ~6 S4 G
1 v- D3 C/ h: }6 ]2 Q( p
// DeviceFinder Callback
6 g, @" R% u; p" [) tclass CDeviceFinderCallback2 j( z5 H$ b5 Q3 m0 e
: public IUPnPDeviceFinderCallback" G0 ]5 c* ^) U# N& W( p
{
- y' M3 q' x1 @: c4 x7 O" @) dpublic:& w# m |6 r. R- D0 P8 Z
CDeviceFinderCallback(CUPnPImplWinServ& instance)+ o9 O# ]! d6 Z7 \% h7 H: d
: m_instance( instance )5 z/ T, m0 d+ g5 l1 ?4 }7 ~# j
{ m_lRefCount = 0; }
+ B: P' @8 u3 z( c! J% J5 L
* I' u: t6 |$ W3 C2 W& `# m1 ]' W) m3 i [& P, f
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 [% m5 G9 I6 T! V4 b7 g; |
STDMETHODIMP_(ULONG) AddRef();
' F) ]# B+ y" B STDMETHODIMP_(ULONG) Release();$ O6 p( Y! I; b8 F K
C# G, w' U! N: t' d" R6 S
% s7 w7 ~. L; V$ C- E; p; p// implementation" R# _& @9 k3 a+ {1 V* ]1 i
private:
. L% g& V7 w2 }/ {2 w/ R HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
2 _4 m) @4 Y( s, o! J6 C( w! a. U HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- `5 d- Y7 \1 E
HRESULT __stdcall SearchComplete(LONG nFindData);- D3 {0 t& E9 C9 U6 P
( `) `3 D- I/ G) x5 E
$ U1 c# C u$ r' _* Rprivate:* y" V) y- p# t$ Z) H0 s
CUPnPImplWinServ& m_instance;
/ w, l9 Q" Y) w7 o4 @+ g/ x0 N LONG m_lRefCount;. K4 d. o+ O- e
};: W3 \ g9 @2 _3 ^
3 _& E9 c/ _$ f. m
0 P& ~6 N' k8 g" i1 D: B& @ ?// Service Callback
: ?4 H! `; l1 r( G1 fclass CServiceCallback' H% _- t0 c. N$ K4 s
: public IUPnPServiceCallback
% k$ G) R4 x/ ~. e1 w+ G{ ]5 D4 k* k4 H6 S7 v: M W
public:% x$ v/ O9 y. D3 s' p. X
CServiceCallback(CUPnPImplWinServ& instance)
. ~5 J5 h8 g8 s4 o! o8 }' J1 a : m_instance( instance )" }$ f: O* K4 s4 a9 i# A! T
{ m_lRefCount = 0; }" y7 Y$ x0 b$ J
- i( ?! [: A" _4 P, U; k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ ^/ K6 r/ Z. s1 O' p9 y' x
STDMETHODIMP_(ULONG) AddRef();$ p4 y0 q; X# d% d
STDMETHODIMP_(ULONG) Release();$ p8 i4 H9 L7 o) ~5 y0 l' r' g
) L8 W! D2 a; G1 M* o
$ T0 L6 D+ ?# g' u// implementation
7 K) J: [# r0 o" Xprivate:5 ~+ C; S" ~% s! g& h( t0 [% l" W
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);! p" k4 k8 W5 x! g% A7 f1 L
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" q9 Q. E U, ?: Y; e
5 Q& e. t; Z5 p8 F0 l) p
G& h; f- r4 Q. ?: ]/ iprivate:& V/ Y1 R& @% u
CUPnPImplWinServ& m_instance;
7 j: O" Y8 Y' c- C LONG m_lRefCount;
- Y s1 j& U7 @0 Z8 U7 i: w};9 }( v( C/ U* Q' s4 W H
" B; }% }) U. `( z
* y% Y6 ?6 `1 `6 x8 D9 m5 @/////////////////////////////////////////////////2 g" E; o5 i0 W* o/ O: I4 h+ i) x
' [1 I W7 T2 `# ^0 c
$ Y; n0 k0 n2 V* D& p
使用时只需要使用抽象类的接口。3 T: [* v1 M* w
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
" ~; g. `! B, }2 Q7 m6 T+ LCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口., m* m/ {# u+ d0 W# B
CUPnPImpl::StopAsyncFind停止设备查找.6 f: a* T/ K3 \
CUPnPImpl::DeletePorts删除端口映射. |
|