|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,. V$ {! o9 f* F9 a( G
2 ]2 J6 I0 [, p$ Q, @; }( e
0 f: p2 _2 K$ `# i///////////////////////////////////////////# d' ?. b# A0 Z$ [) N; k6 @8 h7 E- v/ N
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
8 W& B& X3 p% c9 i& v* E: r% x
" P3 b$ _2 b8 ` g! E* w. [/ c( p# ~3 g$ n* w S
#pragma once
, {' I$ P# s. w+ F6 I#include <exception>
, Z( i; `5 z8 N% [# y/ M$ o( Q) S
$ ^7 g9 x% K7 D0 `6 J: Y' M/ D8 V( r- u1 c
enum TRISTATE{
( c" W& t5 N* F7 t* u TRIS_FALSE,
( [/ }: P6 }" @( o- b0 U TRIS_UNKNOWN,
7 }+ Q D+ D3 k& i TRIS_TRUE
$ p$ E9 ?5 A$ h; U# D' a};
8 d! r. \! S4 c {& M" X) n7 p: J, J% J0 [" X- M$ ^
$ Q' R& C5 Y$ S5 k. t1 u
enum UPNP_IMPLEMENTATION{) l: d; D( L5 V% V7 c
UPNP_IMPL_WINDOWSERVICE = 0,
" G* v. r" s4 C" J+ s% [ UPNP_IMPL_MINIUPNPLIB,; x( Z% l, V. D2 u ^/ V$ Q
UPNP_IMPL_NONE /*last*/% V9 v- ?9 X3 e3 O v3 @3 \" I4 R* I
};
3 F& O3 k+ d) l" `5 z
2 }$ J, [6 {5 K8 L w* @6 w* p- m# x4 b# l. X/ O+ z
" S4 H7 g- h+ Q C4 v& l
' } O+ v( t) I: u; K
class CUPnPImpl
8 M, \, f$ O" T( B{, u7 e: Y( [8 D' b) ?7 K
public:
! v% b2 P$ f; r9 d5 [" } CUPnPImpl();
+ `6 {9 U& D4 S& v, d virtual ~CUPnPImpl();
2 C4 C) @' B" k0 N1 ^ struct UPnPError : std::exception {};! q' L- L5 l' b. U+ j) L+ D
enum {
! q0 k; \; F+ V( \2 L c UPNP_OK,. L- a: }3 m9 A7 v. {8 u
UPNP_FAILED,5 S: I: f# U4 p8 E
UPNP_TIMEOUT
3 `* h; @4 s9 _' f5 r };# g* J& d; s: C9 Y ~; @
# Q2 f( a$ i% ~# _( x0 u+ ?9 t
% L, _. _7 e0 p' u& U virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: ~2 ^" L3 z% s& W, r$ @3 b* r0 O" v
virtual bool CheckAndRefresh() = 0;% o4 i; k: a7 s7 p6 d+ I8 {
virtual void StopAsyncFind() = 0;# M k! @/ `# A% r- a
virtual void DeletePorts() = 0;4 ~/ |; g% F! `( O" Z: [
virtual bool IsReady() = 0;
Z# c7 Z3 z: E. Y virtual int GetImplementationID() = 0;
8 Y( G7 t3 o% g8 [3 s( Q . r1 x1 r* a% F
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping+ Y/ v4 p' s, Z
/ O1 C- w6 z/ \& j+ s
" x, C. }& e" I& B0 C* W! x& D void SetMessageOnResult(HWND hWindow, UINT nMessageID);
3 `0 k$ w" [" h6 O& q5 v" ^! H2 a TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* w# a" o+ i' E6 m! ]& g: p uint16 GetUsedTCPPort() { return m_nTCPPort; }
, x# B! A+ q" }0 R uint16 GetUsedUDPPort() { return m_nUDPPort; }
" V+ \& D; W& u: [8 d: ?% m
3 ?) w9 X9 k/ w: u' z6 I& r+ A7 o6 }, ?5 P* u, d# e, C$ y
// Implementation
3 I( V p; H) X. a+ yprotected:
" D$ s9 @1 q) D; v( G volatile TRISTATE m_bUPnPPortsForwarded;0 I8 u) M* [, G! w0 ?
void SendResultMessage();
+ m, z* m2 X% k- U$ T/ U: q uint16 m_nUDPPort;
' V& }! k2 Q) P0 v- l uint16 m_nTCPPort;
/ t- C3 E- l: B% ~: U$ y, p uint16 m_nTCPWebPort;
6 M% M9 F7 }. Y' u3 J) P5 H( S0 k bool m_bCheckAndRefresh;7 ]8 i% ] J5 |8 J
% Q+ c1 S- }: b+ R. k0 T
4 N! Z, M" f5 i U9 @. Y9 Qprivate:
) z# e# k" z: }6 |% X HWND m_hResultMessageWindow;" M. l8 P: L/ o5 D' ~
UINT m_nResultMessageID;7 T7 q3 @$ p; I% O! e& a0 g+ g
# ]2 p4 s% z# N9 u6 Z) |' ~9 {& }
. d7 n+ j7 p u; B4 A: Q9 O( {};3 f6 M" t) B) O y9 C+ g1 _
6 v% \ H f# b) l) z
: e4 r: Y3 Y2 `+ d( V' _// Dummy Implementation to be used when no other implementation is available
; s/ f: H6 Q9 s+ |3 `class CUPnPImplNone: public CUPnPImpl& z1 y& w- _% ^ i8 Q# [7 k
{( v$ r) w5 x8 E/ J. J1 P8 S4 z
public:
! w$ y1 P9 o! O virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }1 m4 y+ A; `* P* U, N% }
virtual bool CheckAndRefresh() { return false; }% K' ^ @+ E# Y3 _6 {5 D6 _* f
virtual void StopAsyncFind() { }8 M+ u$ l! S P W, |( ]+ t% i" w, G
virtual void DeletePorts() { }
; @ _' J% G! c% |6 ^* A. w virtual bool IsReady() { return false; }
* H' D0 K0 i. O0 [0 U virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
4 d( r4 U: q3 l, a, R; y2 E};2 x# _/ ]. R% R; a( C: M2 h
$ c& t6 d% J( Y
7 |+ D3 |+ }, x5 U v/////////////////////////////////////
2 l+ s& ` s% B; G+ M//下面是使用windows操作系统自带的UPNP功能的子类
$ F, }7 Q' q( A! S* K2 @5 m
' a6 v" k: {' m8 n/ e9 _/ I8 N
6 q2 J/ W& R0 m#pragma once
5 i% v" Z; c& ^6 p#pragma warning( disable: 4355 )
! X/ e, S: h; m3 n" U& |8 t
- Z& q, E4 Y3 l8 D5 Z7 G& o' U' b( x. h; ]2 k$ `7 @
#include "UPnPImpl.h"* M) t9 ?: Z8 c: n. U0 o3 }3 x1 S3 p/ b
#include <upnp.h>
) S I: Q( `3 ?8 V# l% d#include <iphlpapi.h>0 X3 i1 I$ X" n: ^# A6 C* g
#include <comdef.h># i a2 Y: [) P, }: F
#include <winsvc.h>
4 S' b3 ^2 E6 W; M1 y# o
" R7 B& ]) Q. g* W% b1 U
- E# X9 C1 N& ~9 ]#include <vector>
. U* H r2 x4 m u8 V @" b R#include <exception>5 g' I( `$ \% U
#include <functional>
$ I- z3 u. h* g( _9 b6 G
2 g. R* T; Q; b4 ~1 H( `' x$ t% z- |' q: g1 x, o; z/ I
0 r" l* p$ h/ }# F! @& g; u" ^3 @7 e3 O7 u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;/ H4 A) k4 [ _& b0 T. X
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;+ j& T+ M% z: T0 Y
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
- C0 ?% F9 ?1 L3 | E" k" ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
6 ^% e2 i; u6 z+ Qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;0 i; E. |4 s F8 }9 N
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;( [+ F5 `8 ?: r# \9 O
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 u& @- s- L( N" ~; p( n$ z
# ~# z/ L) e2 v) @
- P2 l0 h6 H b) A( D7 Ctypedef DWORD (WINAPI* TGetBestInterface) (, ]+ B+ H% g" P! K1 W4 `
IPAddr dwDestAddr,
: r. z0 U( Z t# _! D$ D P& D PDWORD pdwBestIfIndex
; A" S, e+ M" ?0 X0 Y! c6 A);6 Y% h2 T% l7 B6 T/ \$ [- S. h4 }: I
+ O8 N) \5 C6 I r7 B5 c, G: T
) a0 C6 F! R$ G5 _. dtypedef DWORD (WINAPI* TGetIpAddrTable) (
# @2 C% G8 [: J6 \ PMIB_IPADDRTABLE pIpAddrTable,
L8 ?& }/ X, _: a( {# Q PULONG pdwSize,
# }! c& V8 T3 K: d+ ~$ |" L2 j9 F BOOL bOrder
2 v" m# n! U+ Q" J);; w3 z; ^; ]6 s( G3 x! B6 j8 Y
5 m8 \# ~5 D; R9 e1 U2 D! ~1 m1 w) F$ H& m7 |1 x
typedef DWORD (WINAPI* TGetIfEntry) (
6 q, h2 y0 V8 ^9 c PMIB_IFROW pIfRow
2 l) [4 L, C3 w& o3 a8 [);
% p2 g' @$ c! N9 S$ O6 e) g4 a. N2 c9 Y1 s
1 | q: q$ t* O8 G0 p$ q& L0 CCString translateUPnPResult(HRESULT hr);& e0 \% n$ P& J8 j1 E- R" O
HRESULT UPnPMessage(HRESULT hr);. l5 }' Z, r5 j
( b! X8 I" d4 V( F
1 T& R% W9 V7 w' y) Xclass CUPnPImplWinServ: public CUPnPImpl
. C5 ]& V* R/ t) w5 m! [{
* E- d- Y0 D2 ^% ] R2 n friend class CDeviceFinderCallback;
0 G( E/ O+ e2 a) j. t$ T friend class CServiceCallback;
# O+ S9 Q( {( p// Construction- H: y% d# k0 q8 D% l' P
public:
, A9 `* M: a- C; l1 a6 q virtual ~CUPnPImplWinServ();( `. h% c1 B, V7 P, |! O
CUPnPImplWinServ();
7 E) q3 \/ n7 a# S* O
: o4 K8 s+ e: n x
+ c0 Z: G, G9 c/ F8 d8 \ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
9 l3 O- G3 p3 v+ | virtual void StopAsyncFind();: U. e; F3 F/ O9 I8 {* X9 Y
virtual void DeletePorts();* @6 P1 i) ^; e" j5 H$ H8 k1 G
virtual bool IsReady();
4 z/ U7 W5 i, f, v) c2 P virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
# h7 `& G8 {, p/ R
, L+ b: [4 @. }# A5 r& C+ _# f# e, x: T
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
8 ~, X/ H4 m+ D0 O8 S) F1 j! ?7 q // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
( u- B6 \- q) P) e7 [8 f9 q virtual bool CheckAndRefresh() { return false; };
' ] b6 N% R, \- |! }+ @, V7 M. E& d% h, u8 D+ t; w/ a, W" m6 @
8 F4 D/ j/ l/ n. q) i0 |" k6 e0 @protected:- {3 h5 ~/ i# C: d
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);0 z5 o6 \2 m2 c
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);/ E7 L) }7 k7 k0 A
void RemoveDevice(CComBSTR bsUDN);- ~" U, E9 _( a/ \) u+ M
bool OnSearchComplete();5 N8 ]3 m* C1 G. _ |; n, r
void Init();2 |. _3 z+ J) e/ a( n
& E8 w* V5 r K0 P' ~
0 B/ N$ ^/ d M inline bool IsAsyncFindRunning() 3 Z. X. | s. c& A& K! m
{
5 Q$ k1 O/ G+ F# @ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
! T: i; x" E6 @6 F1 T+ o1 V {6 a8 b. A5 k+ d# @6 X# M
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );0 G4 i q+ x) y
m_bAsyncFindRunning = false;
. l# \7 \' M: R% u }
% q4 P, {% l+ _ MSG msg;2 k$ S& i7 o; `
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" z. b, }8 _2 ?' i: J) U {
0 I0 L8 z; H' X9 e& U* A TranslateMessage( &msg );# B: S2 ~( r4 h* t; l+ Y% \
DispatchMessage( &msg );
5 y) K5 ]" b; ^/ V9 R }' L7 q6 {+ Q: @( r; W0 \- A1 ?
return m_bAsyncFindRunning;& P6 l% i; F7 u
}
2 b5 X5 O( Q, J$ M% J5 ~) ^: [; u' f2 p- w, m0 R. r( r0 Z' [
# S- [7 l# w9 ^. ^6 y TRISTATE m_bUPnPDeviceConnected;" C2 x6 ?6 e8 o' @; [2 Q. S
3 ]9 j+ u# K, F% y; K" ~
0 L& Q r9 H5 \2 n- [7 _2 D// Implementation
- g) }+ R5 |! D. w$ s // API functions
' Y+ ^0 V) d) R. O" I: D SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
- K# I* H; U6 w7 j7 c9 Z; I SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
* E1 @- s$ _" \( F: a* v# \6 D3 }& d- o BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
8 |- H5 ] b' h. q BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);: k0 T# K5 z' R
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);1 y+ A( o/ g" _) I) P3 @
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 p: j+ B: K- H, x5 X* f- F! g$ W$ Q
& r1 ]' ^2 } J$ p% n' |1 v: [5 K0 w' C2 g7 S2 B
TGetBestInterface m_pfGetBestInterface;
; t/ E# C! I/ s2 }1 w& I TGetIpAddrTable m_pfGetIpAddrTable;8 c4 t1 U0 s! s5 s+ Q
TGetIfEntry m_pfGetIfEntry;
$ y1 ^0 A6 A% {$ Y: _9 C0 Y+ q: g; Z5 Y, z J, d' e3 w1 y
& M C! U3 y W* u: B; W0 F C4 x static FinderPointer CreateFinderInstance();
: W" G$ _. ]1 H$ `! B struct FindDevice : std::unary_function< DevicePointer, bool >+ N2 A f1 C. d# V
{
: L! b% L! a8 C8 \2 o3 V7 { FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 ]) r# ^" {6 S9 t; F8 R b5 [
result_type operator()(argument_type device) const b+ X( Z4 E7 ]5 N
{
- o& H0 @6 s( F# V0 j6 x CComBSTR deviceName;5 R& Q2 l5 {. f: n }( c0 C
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- r9 y! h# r4 ~% a% k' p: E m
; P' h5 I- r+ x, S# R
3 d' t& r! T- R' M2 U# O0 b if ( FAILED( hr ) )( v9 I% R7 ~- ^ ?2 t# }: G
return UPnPMessage( hr ), false;5 Q W0 J5 @' V' I% A2 ` w
. Y0 g V) T: z' q% z
9 T2 t: j" r8 F; j1 P) ~' s; z return wcscmp( deviceName.m_str, m_udn ) == 0;
( N( x, t0 B( s }
1 ^+ {2 o9 O ?5 i, M2 i CComBSTR m_udn;0 T, y$ \" S2 q+ Z& m7 i
};
4 _3 u- G; o0 X% |" p * F# B' Z# e4 Y' R( L& [
void ProcessAsyncFind(CComBSTR bsSearchType);- t% r; |7 E Y5 i$ `
HRESULT GetDeviceServices(DevicePointer pDevice);
6 [8 g* O% s G ?, b void StartPortMapping();) @2 J9 p" N0 E5 w" V3 E
HRESULT MapPort(const ServicePointer& service);
: i3 q X( o6 U% H5 D1 x void DeleteExistingPortMappings(ServicePointer pService);! f K E& z" o. l7 i$ l
void CreatePortMappings(ServicePointer pService);. W ?) c, g$ X, l1 m
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);& ~3 q t& X& i
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
Z" S2 K' @8 ` LPCTSTR pszInArgString, CString& strResult);
! o+ y2 Z( v% R) U: Z7 Y# i3 R void StopUPnPService();
) k- u4 ~$ E+ Z% n* `! ?& j) p' }- l9 z
2 O/ S8 s; k) r4 z
// Utility functions G" Z" d g: D+ M6 R4 g
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
1 f; b' p: D9 J- e0 N) ~+ s INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. M. \' |3 I( Q9 B$ d( s: M INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 W" n( S' D4 s9 `) y void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
. q9 E' @$ a" H/ s& n HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
/ q5 z- `+ V0 w- y1 y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
7 J1 h* _: H# N) O" t) Q+ W CString GetLocalRoutableIP(ServicePointer pService);
* I4 u& G+ o& k5 x0 d- T7 D C
5 x4 L+ L7 {, G- n" x- J5 W; G1 i8 T( U
// Private members
9 P# X. T1 ^4 T5 D$ Vprivate:
9 I" r+ X4 Z6 a1 g( S7 W DWORD m_tLastEvent; // When the last event was received?
/ x- E( O9 p; I6 C4 M0 g std::vector< DevicePointer > m_pDevices;
3 ?5 H, S% z5 D" L: j5 ~2 j std::vector< ServicePointer > m_pServices;6 {; o. B3 a* f/ b8 w/ ~
FinderPointer m_pDeviceFinder;4 b4 L, E+ x, B; ~; T
DeviceFinderCallback m_pDeviceFinderCallback; F. A: \5 ^+ n- {6 q6 e
ServiceCallback m_pServiceCallback;: O- K1 x/ @4 F$ y/ F
( |! q9 n. J$ Z: p! _& B4 q
9 ?6 H& |7 [/ [7 `
LONG m_nAsyncFindHandle;% m4 A) c4 H! |% I, \
bool m_bCOM;
" l/ Y6 e2 I* g6 t; j& p4 l bool m_bPortIsFree;
: u: x( t0 }8 }9 p CString m_sLocalIP;
$ I9 t5 {5 W$ V$ l CString m_sExternalIP;
1 M O5 J1 H0 { bool m_bADSL; // Is the device ADSL?
) c) G: G- H* ~ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
7 f/ {1 F9 x( {, @* c bool m_bInited;; Q- R* n+ {5 ~% v
bool m_bAsyncFindRunning;
9 p# y- d0 N5 j: G9 y! ]) U; j L HMODULE m_hADVAPI32_DLL;- u% t! e) z9 x. t( b, D
HMODULE m_hIPHLPAPI_DLL;
$ D+ Z% k" r$ O5 f) X. s) ^ bool m_bSecondTry;& t$ ]' @% r2 ?; D! @
bool m_bServiceStartedByEmule;
/ W( x2 ~$ c8 ?' E bool m_bDisableWANIPSetup;: R" u% \. E \* o! h
bool m_bDisableWANPPPSetup;
' ^) x! [: ^% O# L4 @# p( Q/ ~9 ^' y# L* r% v" w
2 \/ T0 H6 ]# L
};
# K- `9 k/ a* w4 `: y8 X0 I+ d3 P& ]- p# A( z6 |
0 A, _/ M8 y9 @
// DeviceFinder Callback
/ e1 ]+ J, @1 ?class CDeviceFinderCallback
. ~, ^: U+ [ L- Z' D& X7 H : public IUPnPDeviceFinderCallback
# G" C6 ^% r c5 n5 n+ Q{6 S, ~0 P8 T3 z$ g
public:& I9 G& S& P9 x( B1 a% Q4 Z
CDeviceFinderCallback(CUPnPImplWinServ& instance)1 V2 A- s* d! @9 C: [; g; E0 }6 a
: m_instance( instance )0 {& w/ a: N$ `1 r! O) Q# R
{ m_lRefCount = 0; }
a8 E! u/ f$ g! k0 M- Q; O$ ^. G" H7 }1 Q; O
( O3 E3 d# M4 a4 [( s& n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& d+ R4 d# U; n( J$ s W3 m STDMETHODIMP_(ULONG) AddRef();
2 ]3 s1 g, l9 V4 b, ]+ R( j STDMETHODIMP_(ULONG) Release();' j& @& v# I1 F4 E
( N* u( J* R4 e$ T2 {' h, s5 B" \! H' W# \$ k) S; q
// implementation! M7 A; C1 |* g7 ^8 d# S
private:' ]& r3 _; H5 B* t. d& {
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: @; s/ y3 V2 N5 d$ `
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);+ F4 ]8 e* D( v G, [9 }
HRESULT __stdcall SearchComplete(LONG nFindData);; J; ^0 M2 O. x: k
3 i& o/ [ D3 E/ r4 X
. r9 w$ R: N) T1 X) V: H! Zprivate:
! y; d: I: @2 y9 L! s- m CUPnPImplWinServ& m_instance;
: O- }& ]. a7 B. i& @# z LONG m_lRefCount;
# v2 j+ b) _" B- w' U};
9 ]0 ` z) a# @# C# m& o. ^4 [0 {6 d! \* D) b/ K
+ T* ~. P3 E9 }8 {9 B. ^! e7 D
// Service Callback
/ V; R) B# K" S cclass CServiceCallback
s; W0 y v$ x6 v7 S. B : public IUPnPServiceCallback) V( e9 o( i4 R' w
{, K8 \" S' _ M" U
public:' o- s6 r% R* y0 M3 W5 h3 E* E
CServiceCallback(CUPnPImplWinServ& instance)
" }( D. t* [4 ?3 n* I7 F! M% l : m_instance( instance )
7 L4 c6 o1 o9 g5 N8 `& n, n, S9 W. B { m_lRefCount = 0; }
% t5 l) W. A/ Y9 h6 A. P. l7 J # v$ Y$ ?9 Q8 L0 v* C$ P
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. D4 x1 j+ w5 }1 l5 X+ ?
STDMETHODIMP_(ULONG) AddRef();
4 W9 V" G$ N m2 ^( s* e STDMETHODIMP_(ULONG) Release();
& T7 E( v- W. Q t- }8 p. k! Q
' ^$ e* F& }( [. O5 p! e- [3 f# Q% `& M
; x0 R r2 g# E# K// implementation8 P) a+ ^8 ^* k- o: t4 z8 J* u
private:8 z5 c' | \: {3 ~ J; w \: s- V
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
7 Q5 P+ w7 X' [1 Y0 d& O HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);: p! H; ]1 y% Z2 S* x- ^; D! X
; {' c+ G0 j3 t- K
0 b% {7 e, X+ Yprivate:
5 s( v3 ]- y0 L$ C; Z CUPnPImplWinServ& m_instance;
% \6 Q- I5 F( K, a6 ^5 s5 R) S) j LONG m_lRefCount;
. V4 K! x& c d+ D3 ~/ G# O};
; `& R7 Y7 R- Y& B; t' l8 f7 M" ]3 a I" W, W
! G* E4 S/ X' q; u7 F4 C/ H3 [4 @
/////////////////////////////////////////////////
/ K# H! R3 z+ A! b% u0 D$ z
$ }+ P: W$ R. L( W2 Z' X3 i7 B* H% t- [+ t4 d# b; j
使用时只需要使用抽象类的接口。
& f$ N% s7 \! U' q9 dCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.! e' t* L+ U0 {' [( E5 y
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' r N- G% |4 h, w# F
CUPnPImpl::StopAsyncFind停止设备查找.; I. _+ B) K+ N; l, @# A
CUPnPImpl::DeletePorts删除端口映射. |
|