|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
, U k* Z$ p; `8 i
0 I5 v" u7 _" }9 n- Q. G) h$ t! l% |( ^% S& Z: F
///////////////////////////////////////////
2 L" Z( n3 @5 K8 |) v//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." R7 p& h+ T+ U/ A3 S/ B3 F. m! G
9 I, p" c" e- k$ h6 x* V
5 @. |7 P5 I6 ]3 W
#pragma once
" B* s1 @4 o/ B) {, w: t. r#include <exception>, o6 Z- x% M+ [4 M! g/ }
5 k9 \% ?9 c) j8 d ~& v. |' D0 B0 U( g4 c# _/ {1 [" l
enum TRISTATE{
" E, Y% x* n6 r6 M z) Q9 N( u TRIS_FALSE,' u: Y+ e! S& _% j+ r, b, v$ `) u
TRIS_UNKNOWN,
! W% f5 O4 h' y( j TRIS_TRUE
% Y7 X/ e! |+ z9 u1 Q6 i};% C- x; u. c V7 Y7 s" N
- U1 A, G+ y! e6 B' s* b, S& ~& `
" l$ d( m2 ]: oenum UPNP_IMPLEMENTATION{
0 l$ Y6 e& {3 u4 T9 S2 C# k UPNP_IMPL_WINDOWSERVICE = 0,! q9 k; y% k- q, c5 A3 Q# \. L: G
UPNP_IMPL_MINIUPNPLIB,
, ]) _) r ]0 n+ M UPNP_IMPL_NONE /*last*/
$ A) y7 _( A, R};) c5 D" w/ [$ U/ y5 k! {$ c
; U1 k# \% g. l6 m
$ B1 U1 }+ i$ O* |" W1 }3 m% e
( B% [5 E+ t) U/ R, y7 l7 u
class CUPnPImpl
& ?& w. f$ U- J3 o7 {{' r" A" R/ V7 o1 f) S( W! S) {
public:9 b* _" T! X" X! J
CUPnPImpl();$ E* _4 c( p$ O H6 I
virtual ~CUPnPImpl();
! n4 S$ J- b1 o2 R& q( [8 Q- W struct UPnPError : std::exception {};
0 s6 D) m# O3 V- `# h enum {7 @* P0 d, g* \0 U% i4 U
UPNP_OK,
' z% m8 y- ]6 [! ~4 X, U# D* O UPNP_FAILED,
) L, \7 l# ~* C5 x' M+ `3 G8 Q0 a6 L UPNP_TIMEOUT% @/ s) A; Z) `9 o
};1 _# F* W5 L4 q: S0 Z/ ?
! N: a& E2 l+ P0 o5 p" B
. v5 W7 g! f9 N! T0 H4 d; g* K virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. J0 c/ c! c4 L* S u+ m
virtual bool CheckAndRefresh() = 0;
7 F0 s6 e; S! O. ]! w5 x7 Y virtual void StopAsyncFind() = 0;7 S2 ^# J( M" r3 n& E; H
virtual void DeletePorts() = 0;& C$ @- I: p6 U I
virtual bool IsReady() = 0;
$ x( @# D) c4 y* W4 T virtual int GetImplementationID() = 0;
( v, S, K! Z' \5 ]
! V$ p n/ T$ V0 [ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 c6 @; N4 A! T! p+ C1 @% f
9 l8 ^- j! G/ m& G# c
- D/ E0 k5 {( n5 z; U; n) ~1 _ void SetMessageOnResult(HWND hWindow, UINT nMessageID);, {: {2 Z0 H' t/ l ^* {, Q: m( A9 T
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } m' r, R" B I# P5 E4 I5 x# u9 W
uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 r' o# o) k' r# M& w. C. w6 o$ U uint16 GetUsedUDPPort() { return m_nUDPPort; }
2 h5 u: Q% y" ?3 L E' e' ^- d0 m" `- L/ x! G5 ^
% b- H- P$ J2 s
// Implementation. g4 j9 m3 w7 Y% ]
protected:
" G0 d1 q! M4 e# L/ j/ t e volatile TRISTATE m_bUPnPPortsForwarded;% j1 K3 r7 P/ X0 X& E* ~( G K
void SendResultMessage();6 o4 F$ d F8 {& W+ Z- m
uint16 m_nUDPPort;: L6 C" z8 Y6 y$ ]. t% f/ q
uint16 m_nTCPPort;
; ~: ^3 o/ v. \1 F Q uint16 m_nTCPWebPort;5 h: P/ f; i+ |2 k% [5 l) R
bool m_bCheckAndRefresh;
# }1 i+ W! J. z" n4 e5 w
" @, ?4 ?+ \9 H. d! Q. d) p8 u9 F2 ~2 N, `6 C
private:' a, d" s- G; Y" G j, k+ }2 f) ~8 o
HWND m_hResultMessageWindow;( w- p, }, K. V1 `2 h6 l6 ~. O
UINT m_nResultMessageID;
7 Y6 g$ ~7 W0 w5 ?* E! _2 L& R
l! ]+ L+ ~7 w0 x% M$ P' V};0 R$ u& |* c- Q# d! M3 y" B: _) c
, [( b8 C: z8 f& t
% d' v8 J) T6 W1 X
// Dummy Implementation to be used when no other implementation is available& T9 O. m6 J* g8 ~
class CUPnPImplNone: public CUPnPImpl
0 W/ t2 e- c5 \) K" a' t D{
8 q& N! X/ Q& t$ n' H. l" i& L" Epublic:6 c9 {/ V5 \. t* P+ Z' T" G
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 r0 Y Y; r* T, H
virtual bool CheckAndRefresh() { return false; }4 D/ [$ T% A- |
virtual void StopAsyncFind() { }
" H& P; d- W0 v" r) f1 ] virtual void DeletePorts() { }
& q1 I5 r9 ?6 s% U8 C. z2 g virtual bool IsReady() { return false; }
' o" X! |7 F5 W! u7 { virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
& b% S! y E7 e% c+ l7 A+ l};
5 A; k$ _) m" B& W( W: o7 E; T: O
/ P# Q9 w. _. Z3 q% h3 o" A' V2 V" Q
/////////////////////////////////////
1 ~" j1 V$ j# ?+ l X8 ]9 @//下面是使用windows操作系统自带的UPNP功能的子类
! a- n: |- E* u" a4 w# ^! A
( c) u, Z$ b4 K' }, C3 p& [: |6 H; G- W- N
#pragma once
% i- E( n, P& r6 K#pragma warning( disable: 4355 )
4 S- b; f+ T$ T t) D, G! M ]7 j" c. `) M4 o: n6 o! Z
1 O/ @7 M( P+ q2 C% f0 b+ F) c
#include "UPnPImpl.h"& k! ~! \8 k1 _6 |- P5 t+ n2 O
#include <upnp.h>, o# e; m& k" h9 j: f
#include <iphlpapi.h>
- j9 m$ O0 c' A/ U8 N#include <comdef.h>. l( ~0 s' b I* H s4 x
#include <winsvc.h>0 F2 u C9 Z2 c2 S
8 a" |2 i* |8 Y, n) e c3 D
7 y; T/ T4 }( e1 e) j#include <vector> `4 B- @0 n4 e V
#include <exception>
" \2 g5 S b5 `2 G3 m/ ~#include <functional>
- S3 U% m( H4 G5 n( `% k% y& }7 P: v9 X/ c/ [
9 [/ }" A+ P5 Q! F2 o6 p+ B6 g
- h% Z/ O* U6 ^- `0 @2 l, S( t B9 k, o, l$ M
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
; M# D+ X6 \6 Q! }4 l# d* Qtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) f) P" I8 i, s- o& Q, o- e# z
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;( n; V0 X4 N' K7 p* U! N. ~ @: s" |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 p+ i5 ^) m- V: R2 f+ \* btypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;. D0 ?( X9 A! m& r6 O
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;3 ]+ j# {# G+ n* F
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;9 i* i1 S& \4 {5 ]7 m, o3 a7 E. ]! \
, z! `! Z1 w: ?; H# w+ ^
/ n. T% J, Q# G! [$ O. S; wtypedef DWORD (WINAPI* TGetBestInterface) (
7 l$ i$ I t, X' \% Q+ k5 E$ b V IPAddr dwDestAddr,
- ? c% B( U& F) d# b PDWORD pdwBestIfIndex- z( l3 j1 D0 B- r4 K
);
$ L6 } c3 B2 X( I0 U( o7 `% Q2 S) y" ?* D2 x5 \
. o: J2 F. I: d; q8 o
typedef DWORD (WINAPI* TGetIpAddrTable) (
@6 t8 C; v% D! c. V PMIB_IPADDRTABLE pIpAddrTable,
8 ?8 A3 T* m- z m PULONG pdwSize,
7 x* Y% G" d" X t: v1 ~( [3 L" m BOOL bOrder
! J/ e6 q8 x2 Z0 ]( Q8 @( P);2 x( V( e! N* j( R& s. l
% G2 I1 d4 ]7 m! [. b) k& D; E: ^+ z k' O, z* R6 W1 f) Y* |, V
typedef DWORD (WINAPI* TGetIfEntry) (" T' d- n2 m; Q9 ~; R* ~: E1 t
PMIB_IFROW pIfRow G: F; h, X4 @" D9 O( E0 r; m
);
5 m# X7 o) p& G; d$ y* F& @
: k) g* J( m# _$ A6 Q, m% C* m- P( O. p- b, ^
CString translateUPnPResult(HRESULT hr);( ?8 C5 K" n- _6 j( _0 V% c
HRESULT UPnPMessage(HRESULT hr);
5 S. e% a# n+ s4 c, Z" V3 P( P: {% z$ N: G
' `3 j9 }* f5 K7 [' Q* L" `" Vclass CUPnPImplWinServ: public CUPnPImpl6 v, v; u( u4 G2 a" x4 i0 O% K+ s
{* R5 B0 i' a: O" T9 w/ ?7 x9 ~ s
friend class CDeviceFinderCallback;
9 ?$ ]3 [0 ~% F* L, j friend class CServiceCallback;
$ x; S2 l! N1 N. t0 A) x/ h1 M$ [// Construction
( x: r" v' A& `' ]" b8 I! Npublic:
3 a0 Z4 i' o6 d* b virtual ~CUPnPImplWinServ();( D- [+ M. a% P6 C T
CUPnPImplWinServ();
8 a1 x9 q! V2 W) r4 N# m8 S0 ]; ~' \3 n5 o
, T! g$ |/ }7 r3 V1 L( P
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }3 C2 P* P" u* h4 j; p! b
virtual void StopAsyncFind();
) T( t6 V: S2 [& n) M' w$ F virtual void DeletePorts();
# y9 O. ~* ~) b' d8 c% T# I virtual bool IsReady();0 c; W: c2 d8 z- l' T& D
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 b+ I8 [+ S+ f) f$ J
( l0 B7 d0 v' Q; ^+ [5 e0 b
# y$ T& X! v3 h( }! u' \: C
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)2 n/ a! F/ x) ?/ S1 ]$ `+ y( y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later9 ?* o$ r3 I3 `6 V0 J4 s
virtual bool CheckAndRefresh() { return false; };$ K& V" s3 i. P
3 z) f6 @2 i; V# K' _' D7 n
- G1 K- k) z; n) X3 ]3 n6 ]protected:. h# {1 I H/ u+ _1 Y0 V- c% B
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
1 A2 C) P2 }# y4 R' o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
2 Q2 _0 h* F$ I$ a void RemoveDevice(CComBSTR bsUDN);
( H! O0 O2 n; N0 n bool OnSearchComplete();$ ~9 \' `9 B |5 e# |' g
void Init();
, l% m+ h4 A1 r |
# e* S$ d. C; Q8 ?; r) E: ?0 M% H. s g& v
inline bool IsAsyncFindRunning()
2 Z+ h% |" ^* E1 H% k7 M7 G {& {' V7 G/ p' l
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
) J S, A e0 w5 t3 \ {! J( x" I! Y% p' A' O: n
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
]0 P, l) ]& G! f1 ]0 [& S m_bAsyncFindRunning = false;
0 l$ Q2 S/ Z* k& S2 c; m }% ^0 m# ?! B7 h, X/ V
MSG msg;
! h$ q! S: r z/ _! V0 }& P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )) Z) Y# H& _+ s6 N: T$ s
{
3 E0 [% E6 A; l G7 C TranslateMessage( &msg );
8 q! S$ q' w1 Y* T! C( M+ a# t DispatchMessage( &msg );
- h3 A$ S, ], B+ m, X) ]8 g( o }
" C% p3 p) d7 X return m_bAsyncFindRunning;
2 \6 x, \( k# P1 Y7 f }* @; y2 |/ s& k6 A/ A0 ]' `
( }$ Z& O8 E% b
& z, `2 l& K) L k' R" b TRISTATE m_bUPnPDeviceConnected;
( p) e. o+ B. t+ `# S7 N& B
" |4 _/ t0 @1 g, M# m$ Y$ M4 @0 f: ?% {8 h: B( y2 F
// Implementation
) Q7 B% L w$ ?4 ? W( t: H Y7 @2 p // API functions2 {) y5 I- n @2 m# f
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
( P0 v8 b$ [) X6 q SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);) ^- j; R7 k2 s- m7 p e! [/ a
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);& V+ h: v4 K6 g9 s& d5 H
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);3 Z- O, t+ ?; S% R) L
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& F/ @4 L# O- }# Z2 Y& j
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
0 n. z) s6 O1 s+ e- |' U4 l- \/ A$ p. G8 u
* K$ @$ `+ B5 S" M- W Z6 I4 Q8 m TGetBestInterface m_pfGetBestInterface;
& g# |& P# K2 r$ B TGetIpAddrTable m_pfGetIpAddrTable;, v* {8 W% {( P. G6 M! v y; ?% p: G
TGetIfEntry m_pfGetIfEntry;
) G" n) J* t3 g* @6 s' L# X0 c1 l/ O$ ^3 G, }, [
* M; `! I8 J# b o7 w9 u static FinderPointer CreateFinderInstance();; \& J. \ T' E4 I1 o2 } _
struct FindDevice : std::unary_function< DevicePointer, bool >4 u7 G, h( F7 L+ F0 S& _9 ^
{2 B6 k9 |$ R" S
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}# Z' Z! H4 S! `
result_type operator()(argument_type device) const, q1 A3 D" d1 ]7 _) E) F2 H
{/ U Y6 x+ N: W! P& W9 r
CComBSTR deviceName;7 }, E' f! y8 i4 `. x6 E6 l
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
4 D8 n+ C9 J% F' _; l4 A! b* {
8 T0 z% O) Y. H2 }
$ J, q" G; O7 D8 m D7 a* Q d if ( FAILED( hr ) )% A" l! g+ a' h9 u
return UPnPMessage( hr ), false;, ]8 {: e b. v# M/ w g
! ?2 b Q8 R3 C8 Q/ `* J& G8 t. n; G. N* g2 [; K$ G; K+ ?
return wcscmp( deviceName.m_str, m_udn ) == 0;
6 W1 z9 n* _, r+ F8 d$ z" n }
$ z, \- l% y' G1 @4 Q4 U- ?- ^ CComBSTR m_udn;
5 Q, j3 b+ i. X5 r };% G3 U: C9 T+ [
" r5 R& M) a% L1 W M5 n7 c5 w6 t
void ProcessAsyncFind(CComBSTR bsSearchType);
3 M- m2 b: j" o) }. J ?! R HRESULT GetDeviceServices(DevicePointer pDevice);
! x7 Q: E' Q2 W& D' Z, [" T void StartPortMapping();
2 B5 l5 y6 }( j0 O" p2 P8 e- m HRESULT MapPort(const ServicePointer& service);
4 ~" A5 T, Q. ^$ X& i void DeleteExistingPortMappings(ServicePointer pService);" m7 i% }2 T: k- a0 C
void CreatePortMappings(ServicePointer pService);
4 E0 E3 i1 K1 b& d& O v3 D HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 @1 H" h1 T# C% \, R
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
) {2 K1 N# `4 m6 B* s LPCTSTR pszInArgString, CString& strResult);% v0 r3 w- q) I; o" _4 s/ d
void StopUPnPService();9 x( I* n. f" M7 H& @5 ?: _9 d" q
X3 S0 e+ z# X
% x, l& z j2 }6 q( Y& J. \
// Utility functions
( Z# L0 @+ h* [& _# h6 i0 P HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
$ K( ]; y0 L+ h2 g4 q INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);) Q# ]$ a- G4 V. k$ z% h
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 A2 P+ q7 ~! p7 J a7 U+ k
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
, I/ ^8 T+ {1 y0 p% N' I HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
9 I3 j. x( y' ?8 K HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
2 u" ?7 _* N8 i- U' } CString GetLocalRoutableIP(ServicePointer pService);
6 K ?5 `; F5 a9 a& |4 x. N+ C
# ^; a/ R6 y. q' v* k
/ a$ D0 {3 ^" T7 }/ v// Private members
' ?7 r& L6 k# i; m0 a$ vprivate:
5 g8 f8 N+ w! B/ x: | DWORD m_tLastEvent; // When the last event was received?
. K4 Z0 \4 v+ K std::vector< DevicePointer > m_pDevices;
" u6 h# E- `* p std::vector< ServicePointer > m_pServices;* ?. E' R9 p7 p9 Z0 y8 j6 m: K
FinderPointer m_pDeviceFinder;
X$ B8 h5 J, Q8 J2 E+ C DeviceFinderCallback m_pDeviceFinderCallback;
9 x. N8 A' r! O" z3 O ServiceCallback m_pServiceCallback;
% D; g- u! [! a: m& s7 u7 ` `: B7 ?, a+ _2 H
# o; E5 M u/ G& W LONG m_nAsyncFindHandle;
! S$ A: w2 t8 i5 I- c5 n/ ` bool m_bCOM;
+ I4 x# b: T2 ^ W/ H9 ^) Z' Z bool m_bPortIsFree;
' U% y' Z- `+ w/ e' J6 L' ] CString m_sLocalIP;8 G. ?& S3 v" s8 o- Q7 v
CString m_sExternalIP;$ |& A; ]' G: h' T% g
bool m_bADSL; // Is the device ADSL?% B; x( K+ Y9 \8 [
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?( y" F9 v% ]1 Z+ b }9 n
bool m_bInited;
% ?/ Z) G' P; u7 z1 J bool m_bAsyncFindRunning;" s7 ]- Q( t6 N$ h: a# o
HMODULE m_hADVAPI32_DLL;
: ^+ ~% q' V& D; U8 \ HMODULE m_hIPHLPAPI_DLL;1 G c6 M- c0 J6 \; E; `4 t& l
bool m_bSecondTry;5 B1 U. C3 L; e: S' [- Q& m
bool m_bServiceStartedByEmule;& B; q+ F2 ^/ O6 N% G* V
bool m_bDisableWANIPSetup;' Y6 @" s$ A; q- R$ d- A/ I
bool m_bDisableWANPPPSetup;
2 E# S3 g3 R& K7 R/ M5 o7 _1 u) A, u8 X- ~/ h
! ^$ m8 d! E7 n7 x R# ~1 s) M
};
; h7 }8 `6 ^1 b# Z, Q
$ v' ]- o" y. o2 b( Y- o- ^
, n7 G! _: A" ^* P' Z3 g8 r/ _// DeviceFinder Callback, {# O* I+ p# ?/ b
class CDeviceFinderCallback0 I6 V, N Q1 \- m5 d! ^6 T
: public IUPnPDeviceFinderCallback0 E4 n6 d7 F( W) O% o' g$ S
{
8 x# ]! D* f0 U, O* G6 Dpublic:
" ^ k! B) c& m CDeviceFinderCallback(CUPnPImplWinServ& instance)/ v% n" g4 n% p0 J
: m_instance( instance )' h/ s1 B! A& I8 T% \
{ m_lRefCount = 0; }
& m/ T5 G* i: L! ^/ s4 [" K# ^5 B* L" H
; D% }2 n- q* f" i" H- ]6 | STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 T# r, W) s# P3 c% p' q
STDMETHODIMP_(ULONG) AddRef();
# d; N) R; i' j) [ STDMETHODIMP_(ULONG) Release();. F8 A5 @$ v6 Y5 d# ^
% C+ \( }: [7 ~( w+ T" T6 c' E6 w. \
2 w4 z! s* `* W$ @0 y) n: G# s// implementation6 x* i) O0 ?0 o
private:
+ b! D! |& I: t+ p5 c' i HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);) y7 l$ K$ i- h7 C/ c3 j
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); g+ c7 H' e4 j- ~; c
HRESULT __stdcall SearchComplete(LONG nFindData);3 m$ }6 t: @9 x+ m
# X; o: p+ A' _: {
* \* i% l b0 @/ o1 X& I, D# Fprivate:
6 {' O& l3 Q6 |6 N2 p Y CUPnPImplWinServ& m_instance;9 Y& R7 G2 O- m* F# T/ S! g5 e1 W7 u
LONG m_lRefCount;
% v& X# [% j5 \2 j6 R. t% N7 L};* V9 V! U A/ _
8 |& N, Z4 T6 Y9 h$ S" J" ]
+ S; h- {+ E# ]3 P6 Y// Service Callback
) r4 p( ?& d* B% {0 J& n9 {class CServiceCallback! J$ x9 r3 F# L
: public IUPnPServiceCallback
: p A. B- [; t% x8 J{
9 ^! w! X) M& ~/ f* U6 x; Z2 \public:
M* p. D5 V5 P CServiceCallback(CUPnPImplWinServ& instance)' p' p% Y p w
: m_instance( instance )
# n. e; O, S5 t { m_lRefCount = 0; }
" z; A* c+ v- j( u+ j- m
$ H% Y* z' Z: \/ G STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
7 U, S* ?4 K# d: Z2 D- A [ STDMETHODIMP_(ULONG) AddRef();
; W; q9 S" v4 w STDMETHODIMP_(ULONG) Release();7 b, q0 o0 o; Z, ]5 R
1 Z' L9 @$ F$ h6 P, v1 G! S4 w6 |7 }8 p+ n3 I! K+ b' j
// implementation3 s& ^5 y+ p1 o4 w- y4 ^! E9 y
private: h, X: A" ~( C/ c! \9 Z7 T8 W2 N
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);, X* c4 ?, {$ C; u9 C
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService); T/ E. N9 c( R9 ]4 \" x) Y- K
- e% }+ X/ p s' Y) o
; M/ @. v. |9 ~) f6 q1 n2 pprivate:
5 B- c4 L' \8 \) Z9 h CUPnPImplWinServ& m_instance;& o, T% I6 ]7 f- o
LONG m_lRefCount;
; v9 W7 q3 E6 b* n+ K" ^$ n |5 r};& b7 P# _# j/ i3 h8 ?
9 v$ L* |# ~+ W5 w" w8 g
/ v; s. X b* i0 M8 F p$ \2 {/////////////////////////////////////////////////
$ Y8 R0 Q+ Q- t/ B! [3 p# i! v' {; B% l$ h* _
6 X4 _( ?* s- ^2 B; b! {" x/ ?0 b使用时只需要使用抽象类的接口。
: b' f+ g( `9 bCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.$ ]. m% T% A, x
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! T/ P! T7 Y9 {$ `1 RCUPnPImpl::StopAsyncFind停止设备查找.3 v- l2 z4 X$ x. T0 i( H; u1 r" f
CUPnPImpl::DeletePorts删除端口映射. |
|