|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,# Z/ |5 b. q1 ]" _$ G- c! a
i e+ c! f0 U0 B; ~4 w: S( C! b0 j: s p
///////////////////////////////////////////
* w; J, r% M( _/ c. x% z//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
. o# r' J' o* O3 u
9 N5 B* Q6 A" F( N! V' Y5 W
4 b, G0 o7 a; P6 D8 v& E#pragma once0 L4 J+ I, I: O( b4 L6 G( i* i
#include <exception>$ \8 }& c* v3 ~9 R3 ~5 a
: t7 m/ C v. z2 d7 N; I$ J8 W
) E# U5 B& i, l& M, Q# B
enum TRISTATE{" l$ c8 h" j# \$ [# }9 } S
TRIS_FALSE,
+ |( r) A! @- Z' j2 @& z4 c5 h TRIS_UNKNOWN,; {" I4 A# [. G7 U0 z% |% i- b
TRIS_TRUE
3 S( V$ }" Z# o* O/ H};
& S% x/ g7 b& z) W
+ C' T; j" U- \/ t K: W5 |8 o9 N" i0 m( y
enum UPNP_IMPLEMENTATION{" `8 J# G$ D0 X; L2 l0 J
UPNP_IMPL_WINDOWSERVICE = 0,
3 Q H* L& [) W, F% {$ v$ s UPNP_IMPL_MINIUPNPLIB,
# F8 j- y b: g. g UPNP_IMPL_NONE /*last*/
M7 a e- G& G& N0 Q; v+ Q};
0 F7 _9 ~7 l5 A7 b. j; K8 i( e- p6 d( S$ C. ~& z! ~
# N( _, B2 W8 \) u& Y6 R( {* {
! Y$ K$ s* u2 P% F
+ ?* d; e, o. B4 Dclass CUPnPImpl
- U9 {4 Q4 c& y8 A( R+ V( B: E0 ^{3 O/ X& y% T, m, z2 _
public:: m6 e( W$ |# ?( K
CUPnPImpl();
2 a o( D; n, r5 c- Z/ B virtual ~CUPnPImpl();* h" i' w2 u" z/ F2 {; G
struct UPnPError : std::exception {};$ o1 ^2 e5 u: A
enum {' B/ {8 z& h3 {9 n, K) a0 ^
UPNP_OK,
$ |0 ]# a! h) ?9 U* g! e/ T UPNP_FAILED,
6 E1 l# }6 E+ s: ^0 B UPNP_TIMEOUT S9 }5 O8 ^4 m# x4 D! H) k$ c% c8 w
};
! {# z* B) }, [& D! }& O( {( _0 x
- j# @' s: ?! _. R9 I) F
f5 [7 Z' O( S% s/ u" k7 Q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
0 _* w) f1 L; P, S0 q3 c, r virtual bool CheckAndRefresh() = 0;+ C+ Q1 S) L' f |
virtual void StopAsyncFind() = 0;
/ @4 o+ G7 B: O+ C2 F virtual void DeletePorts() = 0;
4 b4 q4 g( Y2 y$ H g) d$ g% B virtual bool IsReady() = 0;
7 U* E" [, t0 y5 q virtual int GetImplementationID() = 0;
7 A- q6 P" j. u5 ~' _+ Y# {6 W ( M$ }8 q3 G) E- j/ F" s8 K3 Y0 x; O
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
$ X; D0 e. H% O9 R& s( s( f! K) D5 g
/ e9 L( L5 A2 m6 n# P' C% P6 Y void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 T8 U; |7 W2 Q: }" W5 q! e TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }2 f: g7 O# s: H: A# K
uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ W/ [+ K# X$ @ uint16 GetUsedUDPPort() { return m_nUDPPort; } 7 S; D# N8 v! U4 V1 T
7 _, s% y, W2 v' m( d
2 q- o4 f( @7 h* Z
// Implementation
! J/ |' x+ k, [5 i- x2 @4 J% j5 wprotected:" c J4 C* ] M
volatile TRISTATE m_bUPnPPortsForwarded;
- p. {1 _- j6 g. k7 p/ A- O void SendResultMessage();7 o' K; F w1 q0 m# Q" q0 Q
uint16 m_nUDPPort;6 J1 S. |# t6 B& q& }
uint16 m_nTCPPort;
5 ^, P5 R$ s' i; `- E uint16 m_nTCPWebPort;
& q8 p) r3 q# [1 W) I: i8 ] bool m_bCheckAndRefresh;$ E- j7 _9 }+ D; W
9 P, U6 m" |$ q% Z# x' R f! U. C4 x8 @. T! Y1 o
private:2 @2 p8 h; Z, C) @; C2 }4 O+ X
HWND m_hResultMessageWindow;/ d- R1 ~$ _, v
UINT m_nResultMessageID;
% z N! T( ^3 c6 F1 b
+ K. I# w! l9 a! p3 n+ P1 G
& j# v, k+ Y. ~/ Y. [};
! Q! ~" Y7 X! Q" Y$ n9 K
8 l q- X2 |7 ~% ~$ H" C' }1 o% Z5 d2 f, L! B$ m" m8 `# ^
// Dummy Implementation to be used when no other implementation is available' i7 c, w* C/ p/ T1 S' G
class CUPnPImplNone: public CUPnPImpl& T6 d% Q: p% [$ j# D
{- Y. b" h ]6 I: j) }
public:" W6 H3 W) H7 H% k, ~3 c2 c. t
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
6 l! a5 m; u$ l/ h virtual bool CheckAndRefresh() { return false; }
w( C" s9 n& O {$ n3 F virtual void StopAsyncFind() { }/ E+ C: T) }% H- H0 b1 j2 q7 Q
virtual void DeletePorts() { }
. V- b! d9 ?" D5 a/ U3 } virtual bool IsReady() { return false; }
2 ]3 b6 g& y7 ?0 [ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
- m" K5 |. G! I$ s( O1 |};) V+ I0 H" A6 B- a% d
' Z2 V. o, ]4 ~( Y8 w& v( A* s% w9 `6 J1 ]2 f# T9 G6 z' h
/////////////////////////////////////1 _! R6 S! N0 E6 P
//下面是使用windows操作系统自带的UPNP功能的子类
2 t6 H( i* i$ }5 u; A6 |; S, r6 m5 d3 l, W" ]: }0 C3 v& h' O
. p7 Z: E+ a3 H! e7 R3 A#pragma once
8 @! ?5 \5 _6 v3 l4 P2 R! K1 }; h& n#pragma warning( disable: 4355 )) ], j# T& E) X9 c2 Q* U
a4 T N9 _" G. J2 \
6 x6 I3 i ], _: X
#include "UPnPImpl.h"
. Z5 M e0 _/ u% [#include <upnp.h>0 r( y+ k& X6 H/ I7 d _: e0 e
#include <iphlpapi.h>
0 o/ @9 h+ X; k#include <comdef.h>
7 u! J* I! O8 c3 b K' T3 H: J" a6 B" ^#include <winsvc.h>; Y# t( ]) A% h8 [! m
; a4 u( ~# q4 f' ~1 s# \
( D0 Q7 ^; s% n6 H& h& U( K: @#include <vector>
8 e8 y0 `5 S8 {$ |9 g; {; E#include <exception> x# R: w9 O& |9 ^' V! N. q
#include <functional>
& y; D+ b* _+ }" \8 h C+ }& N9 c" c
2 X) v m u% w% W; w4 e8 t; q9 Q/ O4 F
; L, [7 J# K4 h. O5 j* f& a
8 ^$ o5 [/ |, W) L9 G; {- k! h3 ]9 Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
! x( b9 F+ a) W1 [" Mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
* w# t6 B! `9 Q7 ctypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;. l% H" Q7 W% u( f$ P1 o% F8 D Y
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;7 M( U2 W% ^8 I) E5 N2 k
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 G. {+ [5 A; o0 y6 U$ X! `typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;- m% [5 J0 g# S+ P7 f8 Q% f
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
" o9 a. p0 j9 n7 n4 F& P. r4 t' J8 _2 h G$ c' [: X$ G
! W0 b1 n. @% Etypedef DWORD (WINAPI* TGetBestInterface) (
5 k* P8 f, [1 _3 e IPAddr dwDestAddr,
; e; K2 c r; f. [ PDWORD pdwBestIfIndex
) A2 R6 M2 M. q9 n( }5 a);( E# \7 `2 x7 e3 w' i/ s+ ]
- Z+ E+ o, H- J/ @0 p/ [
1 C( o5 a& U$ w- S. Gtypedef DWORD (WINAPI* TGetIpAddrTable) (
0 o ~, b# m0 w7 R1 ^. q PMIB_IPADDRTABLE pIpAddrTable,
5 P) F3 {( G) y) v! | PULONG pdwSize,
4 R# v$ p+ D2 B ?, v, E3 m7 K BOOL bOrder
& L4 \" \) K: n4 d7 _/ t);0 D7 j! [- y5 ~& v7 F ?5 T! P" d
; l) R" \" m) v, M
9 w2 u0 X" P. }8 a# ftypedef DWORD (WINAPI* TGetIfEntry) (0 g% a! O* D! n1 d2 \
PMIB_IFROW pIfRow7 u& ?, L- u, h( n5 H3 J
);% X- S7 ]) s" G8 W* A7 g
l+ y. S& }' A1 S$ w: C! m6 V$ E; H$ n& B
CString translateUPnPResult(HRESULT hr); T* a1 ^0 Q. }0 O( `
HRESULT UPnPMessage(HRESULT hr);
, `' y* F( z) P$ y5 s3 h2 E/ y5 o0 L1 K" ?/ k1 e4 v$ M
+ `+ S/ D8 i/ `2 c3 d) i
class CUPnPImplWinServ: public CUPnPImpl
9 h* _2 X6 a4 l, ^2 w6 H{
6 S) ~ g1 e4 L; z! Y8 H0 ] friend class CDeviceFinderCallback;5 y5 [6 u+ l0 _' U2 M
friend class CServiceCallback;
( B" c* h1 ~6 W4 x% j// Construction/ x% a1 ]7 H W! l5 Y% @: J w* I
public:
# ^2 V! ^' z( j1 w/ B# D virtual ~CUPnPImplWinServ();
* ?4 r" {6 m1 a* K+ _/ W( ~: O CUPnPImplWinServ();
: ~/ [8 e M, X$ N( M1 Q
: n# V4 B- m' A D. H
& k) S) Y! e$ E% h% p# P& M) v virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
4 q5 S( ^( {# u( v* Z/ R4 Q virtual void StopAsyncFind();
) \. B1 v$ @* }0 X8 X4 F. Y virtual void DeletePorts();
5 t0 z) L: ~3 P virtual bool IsReady();
' D* `8 P' E @ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 w( \* G5 B4 y8 K
1 M6 u6 ?( z7 Y6 a% {6 B
9 w9 B: v% z: m0 _: C$ m5 T // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
+ ]) j+ ~9 P5 J. z. f2 e, q // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
: @" \3 H$ d7 h2 _ u9 I virtual bool CheckAndRefresh() { return false; };+ A& a5 [1 _2 O0 @$ f& X
) L3 @- s; |3 N1 |# ^1 `
5 r3 _& U% G1 q0 m- j( mprotected:, e# h/ b* i( T; U9 j! Z+ V
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
, v k' n1 n7 q3 o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
$ K' L1 N' Q3 y" i' E# y% o void RemoveDevice(CComBSTR bsUDN);$ _( o {' b# p5 z9 ~% Y& q
bool OnSearchComplete();
4 m+ G" Y& `. q# v# l. o- N& z+ P+ c void Init();# H3 k/ r! d" _* i O/ O4 M# w
- @. N3 z. f5 x( ~6 R& L/ J$ i- ` E' L3 }9 E% g
inline bool IsAsyncFindRunning()
4 Y Z* x" y; k+ w {
( f( [: P2 M3 x' s if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
7 Y% s- ^6 { L! r9 J$ T$ A' ` {9 ]# I" W' u4 V" H
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );) ^4 J: T/ L7 l
m_bAsyncFindRunning = false;
! d8 C+ R+ w& ?: ?# `9 K& g- a }& k( c: Y5 v L4 p7 X
MSG msg;
! ^' ^5 O3 f; e4 ^ while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )) v6 C, L9 N1 E6 j3 m
{
3 \7 m, |0 X9 _+ [4 F& i TranslateMessage( &msg );4 i7 q, G% g# d# ]4 R( s7 u% `
DispatchMessage( &msg );. X$ y9 T# I! ^. {8 j
}9 l ~2 u/ V# m e6 s6 m
return m_bAsyncFindRunning;7 U* U2 H9 D0 D% p) o
}% V1 ?4 j% s4 I: g$ _' d) Y; |+ Y/ o
+ e! b$ Z0 w! s7 h' _1 Q! N
# J: f& }& b% _ TRISTATE m_bUPnPDeviceConnected;3 Z1 C ~0 e6 F
. ]. I. |& [" d. U# q5 v
( ^" \4 k7 t; X% z
// Implementation
3 h- m1 ?$ V7 j Y // API functions1 N) t# l% }, H6 J; y @
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' z" T* P/ A. u5 O
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
+ V9 J/ x. m+ ~7 Q' J( [2 j BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);3 x7 o. F6 `$ D e) h/ e5 D
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
2 ~$ A5 L( c! r BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 i+ l8 p) @/ t6 s) F
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);: |# I& d, U* Y _7 w$ j' }
8 L1 n1 k* W' V# W6 K$ o9 L# ^5 ^: [. a9 `
TGetBestInterface m_pfGetBestInterface;
; P- q( }7 W5 X' a& A! w' p TGetIpAddrTable m_pfGetIpAddrTable;
, z* |* s4 ?' K0 J TGetIfEntry m_pfGetIfEntry;
( H2 o0 S5 h9 w( ?- Z$ Q4 L' z( q6 m/ x3 f
* I6 @: @7 M' P static FinderPointer CreateFinderInstance();6 @0 \1 f' C0 k, z! K
struct FindDevice : std::unary_function< DevicePointer, bool >
! y! i2 ?8 r. \% H9 R2 p {
# h' _+ _9 P* I9 ]: z; c0 e FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 V/ ~4 [/ l# u. A0 z( u: a" y result_type operator()(argument_type device) const" d, H/ U1 z0 q
{# A% Y4 S" x7 t. _9 A
CComBSTR deviceName;
; a2 T: t1 p! e+ @9 G% j) ] HRESULT hr = device->get_UniqueDeviceName( &deviceName );3 o$ x' V% @5 O* j7 I/ {( u/ T( `
0 l: N+ }6 _3 W) |) L
. q$ ]/ I5 M8 R if ( FAILED( hr ) ), Y9 J. q: E _. H. h& H
return UPnPMessage( hr ), false;
1 w( U& s/ X0 Q1 \. ?0 n! r" ^/ P3 P, [
+ ^8 J0 R6 m6 e# W4 S& q return wcscmp( deviceName.m_str, m_udn ) == 0;. f2 {% g+ _4 X2 G' Z
}
+ m& Z0 G& B+ e2 p CComBSTR m_udn;
% k6 i8 z6 E; D. I };; i1 y4 i% q' H8 b) f: j
; `& T+ Z$ T" q0 P$ g0 `5 {% b7 q
void ProcessAsyncFind(CComBSTR bsSearchType);
. E6 E. a1 f9 n& F- ]4 M5 n HRESULT GetDeviceServices(DevicePointer pDevice);
" U) e3 ?9 o! X% p4 A, ?: X5 x! T void StartPortMapping();
9 B' d, k* u" D# O HRESULT MapPort(const ServicePointer& service);
" ]1 ]/ D* J. L+ { \' g9 s4 ] void DeleteExistingPortMappings(ServicePointer pService);( _7 ~# I- ~3 H, h2 M! t3 [# V
void CreatePortMappings(ServicePointer pService);- s, }3 |- m% _: q0 a* V4 {1 I
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
- q1 x0 h& _0 m HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
5 @) B! G2 m9 ~7 K/ x LPCTSTR pszInArgString, CString& strResult);. ?5 M# n- W$ W" K1 \
void StopUPnPService();
3 n ~5 Y, i- B/ Q7 J' p+ N. _
" W( h1 Y' l4 c }! c* u5 H6 K1 b! B0 U3 e2 p
// Utility functions7 `, t, s2 k" ~6 N5 D
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);+ @' ]3 h% @$ H" u. k# P0 g
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
7 x6 z h8 ~0 B+ s8 N1 z% }" l1 t INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 P( v/ D K; |
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ Z, N6 |0 y6 w0 Y# x
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
$ d- q" U/ w2 U& x! L/ W HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);0 j6 w3 c0 l1 w. o2 y" o
CString GetLocalRoutableIP(ServicePointer pService);( L* p7 a9 m1 [; Q3 g/ s
: g& W; Y7 x1 Y& Y+ |3 O# J: \" E& J& @3 [& @/ j0 P) I" U; P
// Private members
" p, q+ u- @) R2 n; eprivate:
& Y$ ]6 Q1 Z. @" H DWORD m_tLastEvent; // When the last event was received?
3 k/ v. h- d" b* d4 L- x' q* E std::vector< DevicePointer > m_pDevices;/ a! N# ~( l$ p, J: @5 |
std::vector< ServicePointer > m_pServices;
, r4 L5 w# G/ s# {& D% b" h FinderPointer m_pDeviceFinder;- o% }; [9 M3 a) }' X: I. t
DeviceFinderCallback m_pDeviceFinderCallback;
1 r% T% x5 t- g5 G ServiceCallback m_pServiceCallback;
7 h. x8 f; P: s! \* c' ?0 t' c& l1 i
, j- C! W$ s3 r* r9 y' [
LONG m_nAsyncFindHandle;
6 O9 w0 p h/ N6 ?. i1 R bool m_bCOM;& B, [, m% A! l* v& d( m/ Z. _/ s
bool m_bPortIsFree;
) ?5 ?! f u0 M* f2 @6 ~ CString m_sLocalIP;. h1 ~- ^9 Q( b/ P
CString m_sExternalIP;
0 g7 m0 O; \: L bool m_bADSL; // Is the device ADSL?
* p% l! _/ [8 a: u# E$ _; |* ~ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?3 i5 n8 i7 @ p: t' w, y6 C
bool m_bInited;3 H% d; k e9 q( B; }
bool m_bAsyncFindRunning;; Y: @6 M% i* m5 K* L; e
HMODULE m_hADVAPI32_DLL;9 A" D7 z5 o1 ?5 m, O- [
HMODULE m_hIPHLPAPI_DLL;5 i, S" d z' ^" A( S" P" ?
bool m_bSecondTry;
" e; Z3 q% @, E. e1 G bool m_bServiceStartedByEmule;$ z" N& C- y' K& W2 S
bool m_bDisableWANIPSetup;: h$ Y) h+ @7 n) r+ E
bool m_bDisableWANPPPSetup;0 A8 R: U/ o9 z' R0 v$ M, w
+ H/ i% {; N3 [) K0 m' E! c( C
2 }% M( k7 Y3 A* N. E* b
};
! ^$ x" Q3 ?3 a+ g
2 P3 j$ z2 u% d. [( a! s- u. U% V1 g. S7 y' B; c. |
// DeviceFinder Callback
& z5 K1 l8 Q( \4 A* b4 d7 o' k" kclass CDeviceFinderCallback
& y# r* F& H7 S" I' N( f : public IUPnPDeviceFinderCallback
# I o: C6 ]7 Q! f0 q5 e, `, K{
8 r% a4 Y% j+ H2 S+ s. D Rpublic:
8 |7 n0 u5 y7 h) ]$ x: w" a, e CDeviceFinderCallback(CUPnPImplWinServ& instance)' |. r, T0 K9 V. Y- q
: m_instance( instance ); p/ c5 n# h, y2 a
{ m_lRefCount = 0; }) ^- J, O) R' U. I- N$ ?
7 x8 s* D& j! V9 Q# E6 M
/ [0 K% }- w- T+ A: A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; ?9 i% Q, i" ~9 U
STDMETHODIMP_(ULONG) AddRef();
& \; h& j6 v* l1 B9 {* c: k STDMETHODIMP_(ULONG) Release();
, C" h+ c$ D: M. f( R: E& ^& w* K5 }
. _& i; l" r: o) V
// implementation9 ^) l* J& c" j! X, |# b
private:
* [1 J0 ^) ^: f! u7 V# Y1 B! J/ [/ D HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 i0 t' G: r- ?3 o& A! y" W HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" j9 p) A+ d* X( c B HRESULT __stdcall SearchComplete(LONG nFindData);
~+ j! N- M' n/ d' [0 V1 A) t( G7 s
8 `! K; b/ ~$ L$ Q# r _" Z! Wprivate:/ O k0 u1 G' v, q7 g: w5 \
CUPnPImplWinServ& m_instance;: N# y; k, Y" h! q+ Z2 j6 Z! s8 j# S
LONG m_lRefCount;/ A8 Z0 y, V9 y* O5 ~+ S# V) {
};$ |5 B; c! b+ n E
% ]# ^" F% s1 P
* F8 l0 d7 p2 g// Service Callback
2 j; o! @4 r; F" D) \! l, Jclass CServiceCallback
, c* M( l* j% C; y; z- v$ F : public IUPnPServiceCallback2 V r8 G* v/ z
{
" ~( W" M* I7 L: M$ epublic:( N [" J3 R+ w; R; V
CServiceCallback(CUPnPImplWinServ& instance)
- f8 q) v1 _* j : m_instance( instance )% j' J4 [( F& B1 I; T
{ m_lRefCount = 0; }0 F7 e- r& W+ F; f7 J: }- x' W
/ N- J! W- a8 [
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' E2 a5 N6 ~0 w o: `
STDMETHODIMP_(ULONG) AddRef();) X* a t5 d2 E- \
STDMETHODIMP_(ULONG) Release();! i* X J( b M# l
3 g: P& l6 g9 l& P
, L% t( d& p2 V// implementation( B2 d' S+ ?7 u; a6 T- M
private:
4 b) `. V; f v' t3 m HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
( J: O+ v% [9 A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);- V! P; U# {, ^; \/ [7 l
( E# R; `: M2 \5 _$ Y+ p2 ]$ V: b+ h" ]+ H+ {
private:
& K) U1 Z/ X" g( s8 x2 g CUPnPImplWinServ& m_instance;! S& v6 z+ o0 I# a$ U$ D1 t+ t
LONG m_lRefCount;
" b$ X+ J% Q3 h2 d% |. y, d};. {. @$ d# J6 ?
* m. I- `4 d1 o. v+ f! i8 e
1 P: ^' }" R+ [1 Q* p N- B+ z7 c/////////////////////////////////////////////////
4 ?( i- Z& W7 `4 s8 t! }9 o0 m5 m/ t0 \, m' D
p* k! g8 h0 L5 c
使用时只需要使用抽象类的接口。
" @! ~9 s* e3 f% Z' e- M# J$ JCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
- f6 o: x" u) I2 ECUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.5 ~1 |% O: h2 C
CUPnPImpl::StopAsyncFind停止设备查找.- L! }, @$ W6 p
CUPnPImpl::DeletePorts删除端口映射. |
|