|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
`5 p$ b0 G; }4 ~+ Q" b, g% U/ u- b2 ~
( r4 h8 z: N. U8 M9 `: \, @# s
///////////////////////////////////////////
8 U" C( @" Z: ~: Z//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.; |/ I; t4 h o: `
" I) G4 ~4 y9 F* ?
( ]+ F3 [/ J; X" E6 p- V- L#pragma once' b- u- Z R2 h* i4 B
#include <exception>
* Q, n& x% D7 d/ f, u
. G) w( v4 x# ~& B3 u7 `# p. v3 M z) l
enum TRISTATE{
, k, T, k% a* u6 S: x! _! M) ~2 K TRIS_FALSE,
$ {6 I4 ?! ^% d) X3 f; h5 y2 f# Z- h TRIS_UNKNOWN,
% h" U3 ]! g( C J; `6 N TRIS_TRUE
" _: a" u) V) c$ r- O* q% F/ _/ B};
4 Y e, M D! K) ], k8 v7 V7 L8 j" S
. y7 {; z9 v1 J! @enum UPNP_IMPLEMENTATION{, m9 L: P0 H: H# W6 `' z
UPNP_IMPL_WINDOWSERVICE = 0,1 c1 Y% y* N4 q* K! L
UPNP_IMPL_MINIUPNPLIB,5 q2 n1 ?9 i; L2 z8 g7 I- _
UPNP_IMPL_NONE /*last*/
0 n9 x7 j+ R5 J9 Y) j. T3 {) M};
5 V# W/ g" Y! u0 ^+ X9 y4 b; h$ H9 H
- W6 y+ `$ ?1 }+ r
) T( [; W+ \) Z4 T: s( y4 L2 k3 \8 C L% L" f! m1 A9 q
4 n- v2 Y$ [2 K2 O9 Wclass CUPnPImpl5 U0 [: D, S% P, p1 G* r
{
: ?# x5 b c: Upublic:
, W% K: s+ C; o' _4 t CUPnPImpl();
0 s( i- g/ a! O$ w virtual ~CUPnPImpl();: k" x2 [ T7 u+ R: g$ q
struct UPnPError : std::exception {};
4 L% ]1 q+ K$ a% K& B6 | enum {( [+ I8 E! T2 K# T2 ~( P
UPNP_OK,; N1 o2 A6 N6 h9 d X3 w! J7 [: |
UPNP_FAILED,% X( r; Q0 h( I% Y9 d8 h }
UPNP_TIMEOUT2 q& L' M5 m% ]9 a! _. q
};$ \. E6 _0 X @. K B: e3 U( Z
3 T7 w5 S( D1 L( v, h# e0 z5 v( b: o) _" \
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;9 ?& a5 R( R. s; _0 o. V: A5 k
virtual bool CheckAndRefresh() = 0;0 J; f9 d/ ~+ w9 ~4 l! Z8 w
virtual void StopAsyncFind() = 0;
( C' m2 k6 K$ w! F. l- }4 a N' } virtual void DeletePorts() = 0;
. f' R K( \% {7 l2 S: l9 a# I virtual bool IsReady() = 0;
% u2 X/ g/ n, I' M. x) R virtual int GetImplementationID() = 0;. Q) q. J7 G$ b/ a" X
5 F- ?0 I+ A' V$ C; }5 q8 n void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping* a" N& U+ I, Y1 X( z
6 a1 a( V$ P: D# m$ a; \
- N' p& ?: \ I9 l$ G
void SetMessageOnResult(HWND hWindow, UINT nMessageID);% G0 G# _6 }3 t/ X
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }( d8 h- ^: S! C% h l* l' o2 X
uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 C( j! E2 V7 _ uint16 GetUsedUDPPort() { return m_nUDPPort; } . C; c0 @9 G5 L( r
# P$ D( A% \- L, l7 V/ W* e) Q1 |
3 w7 ?3 Y u5 u5 a/ V, x& G// Implementation0 E: M2 O* E4 e8 l
protected:
L8 `1 f. ]+ s" ?1 |3 S volatile TRISTATE m_bUPnPPortsForwarded;
2 Z. t r5 p% S. V) U5 b void SendResultMessage();! s& Y0 T$ @- U5 E
uint16 m_nUDPPort;) j# y5 v& d8 L! U. d0 {5 X/ ]
uint16 m_nTCPPort;
9 ]3 Y, s$ B! A/ `, f2 E! ]" {9 | uint16 m_nTCPWebPort;! M+ B) j, j9 {, _: b' R% l
bool m_bCheckAndRefresh;
) k* M8 Q6 p! y4 D; U9 }8 ? _! S1 n6 {5 ` J% J
: P3 H, |- k8 m4 k8 O$ f; X, f8 wprivate:# P. D0 g5 D5 u" [$ w" A
HWND m_hResultMessageWindow;7 X, U& G7 y9 A0 t$ ~
UINT m_nResultMessageID;
& |; @4 u$ W4 H$ \# o9 o
0 ~- T, C8 F: i$ h6 x- ^
( Q* J+ x3 r% t9 L, Y};9 b4 v% L0 q u" ~3 W6 c
' z; _. M' v; C- k, u% b9 }5 T+ B- x9 m2 E
// Dummy Implementation to be used when no other implementation is available0 U8 d7 ?% U8 t) b( n6 M% \
class CUPnPImplNone: public CUPnPImpl
) n. C* d# b( p/ x% M{
, N& u2 F/ Y c8 C/ p Rpublic:; @& q8 K7 g( k- Z$ L
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }0 |8 x9 G/ t$ L, m C" G
virtual bool CheckAndRefresh() { return false; }
& l. d: X+ t5 H* f& v2 M. c virtual void StopAsyncFind() { }
1 n% E% b- \/ h F virtual void DeletePorts() { }
1 @# `8 k3 Q, ?0 H, F- U4 g$ f virtual bool IsReady() { return false; }
& v2 X4 g5 r: n: ~! ]" H; r virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, ~) F5 u W$ e' [+ j1 D};) n: i3 K% l: u: x3 I/ Q
" B) Q' {* I3 y" Y3 X. }
( V' _3 g% c7 X e- x
/////////////////////////////////////- a* t( c6 y# `: E+ D3 u/ B' P
//下面是使用windows操作系统自带的UPNP功能的子类
* Y2 D1 Q: V- N, k; z1 w) B
2 C5 g: `. H# }' M
' v/ Z& f8 J& J#pragma once" m: D" p1 G1 r$ y
#pragma warning( disable: 4355 )
0 r7 S, U1 d' V! V5 g8 L
" @0 f; g6 X. [; [
* l' d I: O* a. |#include "UPnPImpl.h"
# X. B: a3 \0 }& y2 U#include <upnp.h>
! |% W/ y+ I: p; t( n" @ {#include <iphlpapi.h>
" A& n5 o9 N, m6 h3 V8 }+ g#include <comdef.h>7 ^8 w) b5 m9 A/ a) R, v
#include <winsvc.h>
; F, D2 ] A0 o! `: j% j! d; a* a, b+ Z9 {: w2 ?0 l
5 ]9 @. N$ }, u5 B4 a1 T
#include <vector>- k( O4 X" h- M; h' {1 Z* O/ N
#include <exception>4 w) l T3 B6 {: n& H9 e T1 d
#include <functional>3 h( i1 i/ _5 @9 J7 S; K6 a" i! _* n$ S& ]
" z% O. B3 \3 F
% b2 b9 G! G5 ]2 @( K
/ Z: T# g5 x! I3 M
+ s. W/ x w" mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
: X: N6 v [( b3 t# y% T4 }9 Rtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: r* s* _1 Y: J+ N. u, l7 e0 D
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;$ R3 g( E; L0 t$ V. j
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 E3 c6 O* ~8 x+ J5 z7 B' |" J5 w' Ytypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# ?1 _* w+ p" e
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;$ M/ o- C1 v# o
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;. C' Y+ \, ]6 K$ m( Y$ P
6 ? a. r6 }" T0 _) S5 O) z* O; `/ h# Q% A6 [/ q
typedef DWORD (WINAPI* TGetBestInterface) (
: |8 d- N( M& d, U. ?- q' O. ~# O IPAddr dwDestAddr,4 Z6 F' _7 O" y5 o& r
PDWORD pdwBestIfIndex
7 o. H: I% T2 f; v" J);* [) S% o# b6 o t
7 V+ A( t' y" a& o4 ?/ m
$ H( g: k2 ~, T2 n O5 A* y+ Htypedef DWORD (WINAPI* TGetIpAddrTable) (1 V9 b6 |2 |8 Z* v0 A
PMIB_IPADDRTABLE pIpAddrTable,
/ S. A ]2 U% D7 m: w3 C1 }( v1 v2 p PULONG pdwSize,
* n& _- _3 ]" k2 w* ~8 [3 h BOOL bOrder$ ^. k- t! r# T2 X
);
* y" f# |) z% ?( P+ `) b7 w+ O. ^+ h9 D. H% Z- f- L9 [0 v9 b( L t0 q p6 y
( F. N0 C( {) o- p, c6 ttypedef DWORD (WINAPI* TGetIfEntry) (0 o# _1 y& D" ?/ g% C
PMIB_IFROW pIfRow
, ?2 h5 g9 ]% M6 l);5 p, X8 b8 `1 m6 L3 h1 H
7 f7 @% d( n" r1 i- V, J6 V3 x
3 t; U; ?; U! v8 @+ \7 O+ N! kCString translateUPnPResult(HRESULT hr);# C. U2 F$ D) C2 B( T: X2 x% {
HRESULT UPnPMessage(HRESULT hr);0 g$ C# x2 Y1 a, O Z9 w
. l, O- y; G7 p1 R9 r7 |/ b" L' ~
8 i0 b0 W! O3 M9 `! M: e+ K6 a) |class CUPnPImplWinServ: public CUPnPImpl
7 f/ n" |0 J3 _; B! M I{2 T5 Z8 q" _9 m2 O0 m- t
friend class CDeviceFinderCallback;$ @7 {! r- K! F, Y3 K
friend class CServiceCallback;
4 p, {" y: s3 `4 J/ L: e// Construction7 U# _% E; z, u& l
public:
) P' ~! Q( E2 n/ E# C virtual ~CUPnPImplWinServ();
' |- T9 d+ y& e, H CUPnPImplWinServ();
/ n5 b! z% N0 I, ?4 }3 n% L6 y
3 t; i3 C3 p& q- @6 U, o4 j
* F1 @! ?4 \& ^$ C virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& o8 J! j4 y) j# F& j c" e, Q virtual void StopAsyncFind();
! f& Q& E1 |; p, E virtual void DeletePorts();
1 X" j$ }0 O- v3 v) c* D s7 S virtual bool IsReady();
0 a# E M: p7 z3 L q( \4 u" m; i3 K virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
" x5 }0 v S$ j
: X& K% s$ E+ ]) b% h
H5 j- p- a4 V // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)' o6 K7 |* z8 v- S( R" A
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 P6 U/ ]2 j' E/ i& {0 w' f virtual bool CheckAndRefresh() { return false; };
+ i( w9 }+ Y3 w U' I1 G4 }. t# x/ @: H: E
" F( X1 C# z$ m1 c0 m' y* O6 _5 X$ r
protected:
$ T! U ]) c! q' c8 i$ | void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
% x, p* H! N4 ^1 [1 Q void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
4 o1 ~0 N( f" V4 z void RemoveDevice(CComBSTR bsUDN);4 |: h1 ?' H" v* J- c O
bool OnSearchComplete();0 \! \5 m$ ?) ` A- ~7 R' v8 w
void Init();! R* x% y; _- L6 j) I0 W5 n1 P
5 j: s9 m. }/ T9 q/ e
/ p* I! a9 b7 h+ I, t) I inline bool IsAsyncFindRunning() 6 s$ P) u; p( \8 a/ E
{" E) h5 w9 l: l9 c
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )( Y3 T; N2 }) X2 b0 h9 A" ]
{
, a$ t+ }4 E: ^) O8 | m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- G; ~4 J* r- T4 _0 j; p+ U
m_bAsyncFindRunning = false;
& }9 W( i9 G0 r1 r/ F8 Y }
, I5 r% M+ d9 F0 T MSG msg;
$ N8 b2 G# B; V3 B while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
/ z& \; G8 }1 ~$ `6 t2 I) d0 P { B: M3 Y1 n$ c3 d5 U# ?& t
TranslateMessage( &msg );
2 E6 S' A1 l3 F DispatchMessage( &msg );
2 G, y2 J. X6 C0 w/ i$ ~ ~# W+ `* F }
' \6 T9 c" E( }' v" A. K return m_bAsyncFindRunning;- v4 w/ R9 C3 ?- B- v
}4 G+ Q1 |* ^8 C( L3 |
6 h8 S6 @( u3 A9 \ l0 s6 J3 D
* S1 j% |; Q7 v TRISTATE m_bUPnPDeviceConnected;
" A" b+ }% F9 p3 {; U: w4 Y- h/ o) } e2 j
0 h8 `6 o) d6 R2 N0 z// Implementation
4 S e% a( o8 t1 h3 K5 _$ N // API functions% T1 O- @+ J6 v. x1 _0 D0 q. a, [
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
3 L4 N0 W3 z0 F SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
3 {5 E7 e7 [3 k6 \ a/ I' |: k BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 t/ d: k+ W+ N; r/ ]: W9 }; W BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
* _! W0 X3 J7 p- \( \) u BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
, T) ]& H7 ~ i4 I, p$ m) Y' u BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);! V: `$ s& y, T7 O" n7 N5 ^$ E$ M# w
& ]5 H% D7 Y6 Q2 S# Q5 ^* P: B
* C8 L, y% ~1 a/ `
TGetBestInterface m_pfGetBestInterface;
( L: a: x8 N: h. y r TGetIpAddrTable m_pfGetIpAddrTable;
4 E i9 d% _5 I9 \9 f) f3 ` TGetIfEntry m_pfGetIfEntry;
6 a2 U8 z2 B" z, u, n- M% f5 ]! `3 m. g. z3 j, z
0 e, s. V7 ~8 G( h1 O
static FinderPointer CreateFinderInstance();
( d( ^4 t4 L1 }$ W6 F- ]1 J struct FindDevice : std::unary_function< DevicePointer, bool >& B- s$ |6 x5 [9 ]) ^
{, v, j' e& E9 T/ `" n+ t) ^2 {
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& A, b! `( h9 c7 Y8 C0 Q
result_type operator()(argument_type device) const
0 U8 G9 L& m2 x2 x8 k. ?7 N {
% x2 R! [* ^( b4 g+ G3 F CComBSTR deviceName;1 d' ^ w$ F6 P0 Y4 \; u+ y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );8 K) H+ F% [ }. x# V; P
# a- w) U( P2 G* B8 S
, V# d$ M, E, ?5 \3 L8 r if ( FAILED( hr ) )
3 Q7 ^( l: ]+ |: j return UPnPMessage( hr ), false;
' ?1 q8 W' C6 \) m# _, P* S- U+ N) F
$ A+ `" Z8 r+ V
return wcscmp( deviceName.m_str, m_udn ) == 0;: w) W# C2 _+ s* h
}
# \: `; n& k; u; n4 g CComBSTR m_udn;
# X% w/ i, B) R4 C };, R( b/ C! K9 ~# U6 J0 U
6 R7 r7 x0 k) f" ?7 c/ m
void ProcessAsyncFind(CComBSTR bsSearchType);: {) e1 D& C" s. C) j4 @8 L
HRESULT GetDeviceServices(DevicePointer pDevice);% h6 U3 n! U" r- Q4 n$ c% y
void StartPortMapping();% Q' N: k3 \0 y" X/ u0 t) P4 j
HRESULT MapPort(const ServicePointer& service);) U* T9 A7 D# Z6 i
void DeleteExistingPortMappings(ServicePointer pService);
( O b& W$ t& e: U/ b/ I+ k void CreatePortMappings(ServicePointer pService);
3 y( T8 q1 B2 j6 q- l' O HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; m) |) ]" Q' N$ N
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, & T0 C, t( G+ n$ D7 p0 E; _
LPCTSTR pszInArgString, CString& strResult);' ]5 E* P1 h2 k& C: |9 a/ J
void StopUPnPService();
+ n' \ F, V: @" M y; E% `; |1 l0 B% z2 n6 t D+ O l
0 ]$ y2 H7 e8 C7 M( q, l6 L9 {8 I" p // Utility functions! i' P! y1 C7 r! z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
) n$ _0 [. e5 v9 r" E" X INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);+ X/ b/ x5 J n6 Z4 I: @' g
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);/ W) W+ }& w/ I9 f
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
$ o* r0 z/ W" k4 _: T$ W7 f x HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);" a" C9 k. w, V3 T. M' S0 w. ?
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
; d: b5 r( V8 M4 V) D3 H CString GetLocalRoutableIP(ServicePointer pService);
# l0 e7 o' x: X2 v" i; y! G5 h, i' O& R/ `3 u4 {# ~3 [! W# ?$ W* L
1 @6 G, S4 P& v// Private members
- G- q7 Z8 h" p+ Oprivate:6 P% }6 M$ M& s; t: k P5 t m9 n
DWORD m_tLastEvent; // When the last event was received?
* C3 }+ @8 D, x( T- C3 s std::vector< DevicePointer > m_pDevices;* y! V7 b( ?, r- l: p
std::vector< ServicePointer > m_pServices;1 ?+ q5 `$ F4 z& a3 A* ]! N+ e; L
FinderPointer m_pDeviceFinder;6 e1 S# M; u) h# h
DeviceFinderCallback m_pDeviceFinderCallback;
" Y. [( J0 d2 |# G/ p3 u& A ServiceCallback m_pServiceCallback;9 E/ o$ Z: t! B) u9 @6 W, u$ `1 ?
; D8 o2 r: z w- I/ Q9 T4 V% P( h, v1 } {) l0 P
LONG m_nAsyncFindHandle;) q) o; Q& Y5 _
bool m_bCOM;
7 I3 l8 R" ]% }" | bool m_bPortIsFree;
' S+ a8 E& M8 `5 d CString m_sLocalIP;
* @0 V3 D- D6 \. U6 ^5 L9 R CString m_sExternalIP;- t0 |3 ~' }9 n8 R$ u T
bool m_bADSL; // Is the device ADSL?$ y# N2 j) E1 f- S
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?$ t5 y* |, g7 v4 p
bool m_bInited; L; p( u7 p- Q' M4 R3 b
bool m_bAsyncFindRunning;, v; t0 T9 k8 T# m6 J% V+ r
HMODULE m_hADVAPI32_DLL;
3 k* D! m T1 I" _7 ^4 v/ E% O, Z HMODULE m_hIPHLPAPI_DLL;4 H: _ h" R& @% f# g5 T4 }" e" v
bool m_bSecondTry;
, a6 H) F M; o. H% v bool m_bServiceStartedByEmule;
~! }2 |1 O. k) x" b5 E' X/ u. } bool m_bDisableWANIPSetup;
" Q- P& t- K- D bool m_bDisableWANPPPSetup;# w, f3 C% E' F# L2 c% z$ @
5 I& @- I0 e3 }3 C7 b
- D4 @8 A+ v! l! r. Q# c1 |};' |8 k2 M; d, m4 W
8 v* y0 I: J4 Y; W
: ^1 x$ w$ ]4 n4 _ k// DeviceFinder Callback6 S& F2 s# \+ i5 h
class CDeviceFinderCallback
% M4 w( B. D1 G/ N, A$ X : public IUPnPDeviceFinderCallback
* ?' A. r* ^6 k z9 z1 F+ `# D8 d{& T; g5 G3 M6 f3 ]; Q; D/ D! h
public:
/ c' v9 j/ T# g, m+ z& ]* g5 m% ~ CDeviceFinderCallback(CUPnPImplWinServ& instance); _ n/ y4 v/ r& z$ K
: m_instance( instance )
3 S) ]+ Z1 H" Z$ W7 C( M! c { m_lRefCount = 0; }
+ W# q- Y, q' }$ t) Y; k9 k2 P
0 y9 F' z- E1 u$ @
5 X/ y* \7 P+ [0 [, @6 J STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); L' S6 V/ o4 y
STDMETHODIMP_(ULONG) AddRef();6 [( ]: E$ z9 w" |
STDMETHODIMP_(ULONG) Release();( z+ x) `# T( r6 ^* r/ B% i" F
! m0 C! n9 ~6 V- d' {4 f
: K" H$ I: m3 b5 Y
// implementation. V* {+ l" ? u% b! H/ n
private:/ h f! @, P( M
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
3 y, U# n! H2 X HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" C2 {* t0 s( I1 J# O1 C/ B1 |/ D HRESULT __stdcall SearchComplete(LONG nFindData);) ?! \3 @/ Q2 e+ q1 O5 a
4 t, }2 J6 w, V' m6 Y
9 P, l6 s3 ^; R' `: Q
private:' l4 T y" @9 |: p" \
CUPnPImplWinServ& m_instance;
9 }7 o' ~8 I% d, ]; b- N) F H+ e LONG m_lRefCount;
6 J- ]; S7 c. ?4 D5 D0 P1 ~- Y/ T};; {6 ^; V9 d6 E! ~' g
: h- I/ g! ]; F: ?8 Q! L& Q/ Q# Y; M/ _+ j- J9 B
// Service Callback
, x/ N% F$ ^) X0 A$ N6 I; H# zclass CServiceCallback
7 u% K/ f) P- f% a2 t1 ?. E : public IUPnPServiceCallback5 f, G: T$ k( Y L9 c5 w
{
; I i# U! X& o5 a' `; i+ ?: Upublic:) u* j- y5 Q8 w5 c# K9 m" j
CServiceCallback(CUPnPImplWinServ& instance)
4 r% A) R# M6 d4 q : m_instance( instance )& M& a' s: T. _: B
{ m_lRefCount = 0; }% G4 {1 A5 p5 z7 t4 T' w- w4 v
7 g# F" g1 B9 p4 h# G. D% @6 {
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. a, ^: I+ |8 C( w
STDMETHODIMP_(ULONG) AddRef();
- V6 n( f0 l4 h STDMETHODIMP_(ULONG) Release();/ ^4 A3 I4 W0 Z& E& a
0 |* z/ U1 k' x6 t9 S8 |; {& H" J! @
/ O# [1 |) P7 i8 E9 O, B; ^// implementation
- \3 Q8 L, q4 w: q/ L: L/ Dprivate:% o, |5 D; }- V! a. e
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- R: X0 R- n0 A3 w: ?" W: u+ r HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
+ g7 {2 [, ^9 E6 y m2 Y" e" a! O# t$ Z' f5 _, w0 q3 Y
* u: W; S; q) d
private:
, N- {0 M6 A5 _$ w3 f2 j8 P, R CUPnPImplWinServ& m_instance; `) t4 o+ n$ R( M
LONG m_lRefCount;
7 D' h9 V9 m! ~/ i4 D: |};
& Y$ L& J: ^; E% j
' F. z; j( I9 b0 o( @
% @# c$ c$ c3 ?; t/////////////////////////////////////////////////. ^+ B' a/ L5 v& W2 o* E
8 d) I5 A# E" l+ Q
% d: S2 j" ~# _3 o. M {' Y使用时只需要使用抽象类的接口。4 E# W8 S' W6 O0 d, L; ^& B
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
f! n$ [5 Q* G2 M4 M& d6 d8 HCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
4 P/ K( \8 W( B* T5 JCUPnPImpl::StopAsyncFind停止设备查找.
! g% `9 M4 h; }. Y P; ^CUPnPImpl::DeletePorts删除端口映射. |
|