|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) \% A' R! U! w2 `3 ~4 d! c2 I
& i+ D0 a" E9 H5 y6 c7 Y
. N" p2 n8 B( F1 c& R///////////////////////////////////////////" G3 F5 {- V3 c( t
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.& d, o% V' D! t: U8 v
+ s& Z* ~4 u, N/ C2 z- m
0 J( M4 N$ y& O3 P+ f! l. k0 |2 q0 h#pragma once
3 ^( E( m" O$ q( G6 y! Y2 Y#include <exception>
/ ^$ _ z. Y+ l- p. Q4 [6 b; s+ G U$ D- M) H- X/ q
) y" d: H% {/ D7 `, U" T5 s enum TRISTATE{
- ~* W G* D+ L5 S7 A0 y TRIS_FALSE,; x$ ~5 T% O6 ^1 W
TRIS_UNKNOWN,
) B4 h7 o: M* i/ S# l" h6 \. I TRIS_TRUE
& C' S+ ?$ |: M4 D# J {2 d: [% M( H};
4 O, i1 M) ^" s9 S# ~# i% r
1 J3 p Y: {- S+ j$ G
$ z1 G2 r( _2 `: Z3 C+ O: W' Y" f5 Zenum UPNP_IMPLEMENTATION{
- [" ^* T! W( C+ [- [ UPNP_IMPL_WINDOWSERVICE = 0,+ j1 A3 J( m# G% z/ a
UPNP_IMPL_MINIUPNPLIB,. N3 S3 Q8 N. C# ~
UPNP_IMPL_NONE /*last*/
, F4 L& y+ g8 [5 I7 @};/ M7 h; V9 j6 k+ V: h
4 h( ~( L# j5 T! R8 s
5 d' K8 Q" h) R( u
' `& q: j- t' i: P: D5 T: |2 Q7 _ L* `3 a; d7 i
class CUPnPImpl; F- u- E- Z9 K
{9 Z" D8 d3 C8 A5 F8 {2 }! I
public:
# X {- T! {! k; S* K( W CUPnPImpl();
8 K6 p/ G' z: T" @& Y5 T) W1 p virtual ~CUPnPImpl(); a; \( q' R2 }
struct UPnPError : std::exception {};' A$ Q7 V7 }+ E Z% A
enum {
. h0 }2 Y9 y# M; z- y& j9 e UPNP_OK,) O- e7 k' W3 T, s9 @' _
UPNP_FAILED,
6 \( u& o% _ k* W E0 @9 t UPNP_TIMEOUT
9 t! g- G4 \- e* a$ z };0 {- X: ]8 C, r
* w/ R& c- {' c9 C8 u2 D' ?( y7 L* ^# ?4 N6 O+ B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;( o! v1 g; @! \# C
virtual bool CheckAndRefresh() = 0;8 A7 D; {" k& T% y6 U: o A6 U* T
virtual void StopAsyncFind() = 0;
7 W1 g0 j$ r8 l# h8 F5 v virtual void DeletePorts() = 0;& p7 L$ P+ i! o# z" m
virtual bool IsReady() = 0;* y& s2 W5 J: {
virtual int GetImplementationID() = 0;! V3 y# p3 _7 { j; n. T4 U! C) c. o" k
! `5 ~& s: h5 ~" \0 u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
3 i9 \' C6 V+ ?* v2 J* a0 g3 h
Y% d% P, g% c8 a6 y
/ e, Z6 N9 j& e8 @; } void SetMessageOnResult(HWND hWindow, UINT nMessageID);
& y: M( y+ u8 r* W3 ^( i TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
, |5 {! h3 w4 p uint16 GetUsedTCPPort() { return m_nTCPPort; }
1 D5 w) O, r! E uint16 GetUsedUDPPort() { return m_nUDPPort; } % a6 \" P+ X0 g1 P
! F. D$ I9 z: p! e3 Z7 `
7 I4 N& Y+ i& U! \8 `0 d
// Implementation. \3 n9 p; M; B" G% F0 w
protected:$ F2 ?5 `9 A; u( O. Y
volatile TRISTATE m_bUPnPPortsForwarded;9 k' E9 `0 @4 E1 x/ R, D8 b
void SendResultMessage();9 A" ]: B' t/ s' w) [2 Y6 D- T1 L
uint16 m_nUDPPort;
" @, I p$ i+ B uint16 m_nTCPPort; L" M R: S% i
uint16 m_nTCPWebPort;
5 D+ h* Y$ F& m* T) g/ c8 ^ bool m_bCheckAndRefresh;
0 _' X7 b4 h% x$ ?( g, N. s1 L7 g9 M0 H- Z
8 s3 w6 ^6 X0 T" U% Rprivate:. ]# f% n. `4 L2 l$ ?6 T
HWND m_hResultMessageWindow;
$ ~+ \/ N! Z4 L# l UINT m_nResultMessageID;0 ~( g r& |, a' V# j: V) `7 u0 s
$ g% ]) S) r; {
. J. b4 _* h2 q};) J0 r; ] u/ W- \/ W) i" I
6 M/ o" z9 F7 T
1 l2 G8 D# E4 G# J- l# l// Dummy Implementation to be used when no other implementation is available
$ I, }; l9 J- ?% aclass CUPnPImplNone: public CUPnPImpl
2 n5 p! ~. l1 w3 y0 l{
8 j4 W( e H) \3 L/ `1 zpublic: B1 M& R' A( a) l6 c4 Z' R3 ?( u
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
a3 L; Y, P3 k6 F" l. p8 ~4 A virtual bool CheckAndRefresh() { return false; }! E. u5 |% N3 p, V! X4 l
virtual void StopAsyncFind() { }
* n" i4 A2 l' e5 _* v virtual void DeletePorts() { }
% G+ p6 J) O+ _" |+ K/ v2 N virtual bool IsReady() { return false; }
n* J7 }* L7 z+ W0 ~ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
k" e B9 D, H& H% ]+ ~) u$ I# \1 T};
9 l* d7 r' a c- ?
/ ?( m& U( D4 a9 N! T
- H/ {0 x- @! |1 {' ?, U- N4 f/////////////////////////////////////0 U; `: l7 w' |( i2 {
//下面是使用windows操作系统自带的UPNP功能的子类
/ }9 O& `$ r# V4 D/ \- L$ \# l3 N3 ]0 J
* A- b- `1 u2 [, ], c; i4 z
#pragma once0 [& N2 v& \3 ~' b
#pragma warning( disable: 4355 )
1 ~3 T9 }, Z* k1 U( S7 h, N+ d: ~$ M3 ~& \
% G; u5 l7 w6 H5 [#include "UPnPImpl.h"5 i5 b: S/ h$ k. c- _! B
#include <upnp.h>
3 @$ g0 T6 _+ s' ~#include <iphlpapi.h>
s7 {+ m- h" W$ m, {/ i7 n3 j#include <comdef.h>
5 n0 t6 z7 A8 x; \6 [# X#include <winsvc.h>
$ ~" U4 F/ M4 L" Z
! y" Y! U$ D c! J [& [3 ^8 T1 y% @9 s, ^
#include <vector>
- G( Q4 }- O. L) p* J" s, d. R#include <exception>9 F3 [# G) A8 A8 R0 W
#include <functional>
! W7 l0 ]1 X* i% a2 O9 X; R! J: P) J
; y; i" C0 h# f$ r0 O5 Z) l$ I' A/ ^/ B! H
% V" e$ L4 k4 F* Y+ D0 Q: ^
* v: \2 y0 H" U
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
1 t# U) O$ Q9 l5 `* R6 F8 z! {typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: d n( k! \& G/ l, l8 f: y0 f% w
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
n8 j# w* q( ~4 n) e/ U' K) etypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ ]5 d, j1 U8 \! f1 s4 Xtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' m! a. p% ]; I+ {6 f
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;& ?1 U3 Y( y3 e* G: F+ J* L
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
" X- f' @( d: U& O) |5 T/ D2 o% w" U# F" v/ o5 Q
8 @0 E# [2 `/ R
typedef DWORD (WINAPI* TGetBestInterface) (
% Y) t: X# [0 P* d4 y IPAddr dwDestAddr,4 A0 E' x3 }7 w, D1 o
PDWORD pdwBestIfIndex
# B( |' l% K) u N);
! y! i) x- R# K* ?# e7 G1 y0 a; g5 H9 M; k( t& i
/ |$ W ?( ]3 G& @+ {8 mtypedef DWORD (WINAPI* TGetIpAddrTable) (/ u1 J' n& a* V8 z3 H! h
PMIB_IPADDRTABLE pIpAddrTable,$ p) V7 ?, `! \0 [
PULONG pdwSize,
8 o# i2 }$ d9 G" L O) p6 u BOOL bOrder. H" D/ Y$ F% \, ~+ g+ ]# e* c
);& ^% u$ |3 o5 z# n
- z9 V* _3 q. r5 z3 c) T3 z4 ~% N3 l$ ]/ o6 f
typedef DWORD (WINAPI* TGetIfEntry) (5 m* @+ N k" z1 w, U( B# l( R) a4 X
PMIB_IFROW pIfRow+ t+ Z. |3 a6 g
);
/ v: Z! b! U# l3 j* j* v
' g" F) U0 s& C5 @, ~# ]1 @4 }
& X6 Y( }" r' Z h6 yCString translateUPnPResult(HRESULT hr); H, \# R2 Z ?
HRESULT UPnPMessage(HRESULT hr);
- G9 z. M# z7 R8 l' R/ Q, P
9 _. Q c* @2 w" ]0 c9 ~) D% M) Z# ]6 p+ }" j4 n E
class CUPnPImplWinServ: public CUPnPImpl3 I$ S) b! W. J5 V
{
$ {/ m: R' G3 t# o/ o S; | friend class CDeviceFinderCallback;- B& E6 s& M- E+ P9 @
friend class CServiceCallback;
9 @: [- V. V3 @" E// Construction
: { @' R% l- n$ v7 a! i4 w( `! W0 z% Tpublic:! v- m2 V- s, ~/ X
virtual ~CUPnPImplWinServ();; q' ]% e5 i7 e2 G* @8 G
CUPnPImplWinServ();
3 ? ]- I+ B0 Z- g1 V. Q# V
, f2 y, K5 c* B0 c6 v9 w
) p7 W; L* H/ v: Q' [ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }6 U# o( N" W6 L, B8 f# g
virtual void StopAsyncFind();& D# ]0 y- e1 p% Q1 t
virtual void DeletePorts();
1 O$ E7 }7 W/ u, A virtual bool IsReady();
( R0 \ L k' J: w7 ~ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
% O7 P. Y" f. Y; H7 [/ \7 U- t# a5 P6 @1 r
4 F& J* S7 y. t, X# N3 g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
3 Y! ~$ s; |: O( S: C8 ^ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
N4 ^$ d" n+ i virtual bool CheckAndRefresh() { return false; };3 J, X$ ]) ~, u" y6 L" C
& t2 Q" \( m6 H, b$ L7 Y9 \
5 A) _' d* G+ p; L' j( X. rprotected:
8 ]' r& a' q v+ T9 Z void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& R0 {+ f5 o6 Y9 T: N& ~! ]: V void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
# Y* o8 }9 q* k2 `3 S void RemoveDevice(CComBSTR bsUDN);
+ c, d+ V. c% P% D0 k3 V1 r: _( G bool OnSearchComplete();
5 d- S+ V* m6 O) H4 F void Init();7 k! g) c0 q: \; P' j/ d
( c. z5 h g3 Q% S* ]: c2 f1 m
|3 C4 a/ s: A. H inline bool IsAsyncFindRunning()
" T' E# x- I, K" L R" r {
p* _/ g0 J6 O1 h6 i if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )1 _9 y' t' G* J' }" L3 I, H
{
; B" c$ f8 F( e6 f. Z$ y' f8 C m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );8 u" t3 D1 g1 |# O6 e5 w
m_bAsyncFindRunning = false;
9 F. I# q( F6 a' e- Y }
2 Z, L# C/ G" u# F MSG msg;
5 I5 R( q# p0 y% c. E while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ T3 I5 Y9 L* O- Z0 e* Y
{
" H2 D* V, v. g% f# ]& O TranslateMessage( &msg );/ Z& j0 s/ s. ^/ l
DispatchMessage( &msg );- B; p, n& x* E& {- S! M2 Q8 @
}$ a" |+ i: l- y' w! @/ c
return m_bAsyncFindRunning;
/ f+ F+ o3 m( B) @ }# j* B7 p4 P6 f
1 ^( K# ?( n+ i2 x2 }0 i* w# \
TRISTATE m_bUPnPDeviceConnected;
F# q. b; B+ o2 Q% T$ ^' l1 D- ~ j! U' w" Z
: v$ h3 C5 r: D: L: L# W// Implementation
& q$ a; h2 r4 v' |/ E$ O- V3 d0 y // API functions( `+ f0 ~6 G5 i) s) y
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
, p% v5 ~& v- S; v- N9 R- m# i SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, B; M2 I1 t5 q0 x6 M) g, G
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);6 N' [. @$ \) \ y
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 V2 h) \4 p2 D* I* Y* J; s
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
0 z/ S# H4 y5 e& ^; S3 W! {& @7 i* R BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ ~% y9 \2 Y `6 x# Z2 o9 u6 S4 N; F8 S, a6 {9 v
; U3 ^3 u# _/ x8 q, R TGetBestInterface m_pfGetBestInterface;
# c+ a8 M2 P y6 i. X: a5 ]1 Q TGetIpAddrTable m_pfGetIpAddrTable;
4 Z: }& Q+ F+ Q1 z4 S. \ TGetIfEntry m_pfGetIfEntry;' V! V) [( \7 y0 O. d
- v: x- X, J, G' F* F3 F' K* x7 q( o3 W9 M
static FinderPointer CreateFinderInstance();8 j3 v& M& @4 ?4 E) r& R
struct FindDevice : std::unary_function< DevicePointer, bool >
! s) `" U0 z6 o, l3 f {
9 `# J i0 o. W& g, B, O; [+ G FindDevice(const CComBSTR& udn) : m_udn( udn ) {}4 g) L( m/ l `) Z
result_type operator()(argument_type device) const
& {% k; w% i6 O6 w8 ]) w% T/ ] {
+ g R- z$ A! a/ p1 w CComBSTR deviceName;
6 [% e7 W& X2 \- F! n7 `/ Z7 p HRESULT hr = device->get_UniqueDeviceName( &deviceName );' `9 v) N ~% p* F: D e# c
2 y. R' K' c, u, {* I* V8 \' C7 ~/ j4 |. O" s
if ( FAILED( hr ) ); K2 f" t$ o: [- Y k
return UPnPMessage( hr ), false;
2 O k' u; \( f, P' g
3 N0 R0 b% E9 N4 d$ {# ?/ s; f6 F/ z3 m- l7 D
return wcscmp( deviceName.m_str, m_udn ) == 0;$ ~% Q% _( P ~+ r: A0 d* J
}, ~0 n1 u9 E R9 B0 U. U
CComBSTR m_udn;4 @6 @% j9 r6 [: _0 |; R
};
% M( v/ @" Y' v
' o. e x0 L% Q" f1 H; C6 B- v$ h) a void ProcessAsyncFind(CComBSTR bsSearchType);
# W. \+ D' [) u. c* G# N( t HRESULT GetDeviceServices(DevicePointer pDevice);
0 T& b: Q5 ~, }( b3 T t void StartPortMapping(); Q) K$ R& B: H9 I- A
HRESULT MapPort(const ServicePointer& service);
Q- u' h6 |3 H void DeleteExistingPortMappings(ServicePointer pService);
{: l; S$ {3 v: \1 s/ T7 y void CreatePortMappings(ServicePointer pService);
1 K3 X3 o. M8 w# ] HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
4 U; b- ?2 x! u3 y6 m( i HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 8 {6 n0 @. W" f: q/ s
LPCTSTR pszInArgString, CString& strResult);
" r4 ?+ } r" b: S+ x void StopUPnPService();
" V4 m6 S0 p! @
- m F( s: F* X2 W+ U9 f3 N1 E9 ^6 D$ Y3 R% }0 H% ^
// Utility functions4 l1 ?. C, I3 n3 U
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);! B [( U, q+ B# e& ]/ L E* R
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
7 Y) X5 U7 W; {2 y$ f INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, _0 M2 \1 @! E1 k& L, b2 |
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
; p1 G) D; |+ ?- ~" H HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
2 `6 \$ _7 s6 z+ i& s( J' A HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ ]! N3 j; X+ L1 x1 b8 M
CString GetLocalRoutableIP(ServicePointer pService);
$ }9 K% P7 l6 T: ]7 L. F* ]2 a: R( }6 v( r3 X- z$ u; D. P1 s% j
' \% w! i2 C& B9 S4 J// Private members
L R, y+ p3 ^private:( n6 [. S' G3 T- O2 g
DWORD m_tLastEvent; // When the last event was received?& R/ M K8 M2 u( F+ B
std::vector< DevicePointer > m_pDevices;
" @$ v1 M) a; U% T2 D std::vector< ServicePointer > m_pServices;
+ O! X4 P' z) q& Y FinderPointer m_pDeviceFinder;
% ^# R8 b! q! Q2 s2 Z DeviceFinderCallback m_pDeviceFinderCallback;0 _) i+ y/ s! i) F
ServiceCallback m_pServiceCallback;
; @2 o' y3 N6 J9 E
* S; S( z' J9 F6 j# A; d9 m ], s) D5 o k; k, ]- m! o
LONG m_nAsyncFindHandle;. N9 m& h$ D) I9 W' l" A
bool m_bCOM;
" B5 S# _) W; I, X0 b4 n bool m_bPortIsFree;2 M* P6 `- y( z
CString m_sLocalIP;
, X! @! [, B. z4 Q, r& r CString m_sExternalIP;
, B; L7 T; r0 w. l7 F; D bool m_bADSL; // Is the device ADSL?* E+ } Z+ ]: E6 p/ y
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?; Z/ N! P/ L8 o' o; z
bool m_bInited;
* R, e5 b6 _! o A6 S; M( R bool m_bAsyncFindRunning;
|$ \+ P+ T$ Z5 w0 S H HMODULE m_hADVAPI32_DLL;- m4 X! f4 M: F, e. k) `
HMODULE m_hIPHLPAPI_DLL;
2 `4 @. {: [5 J bool m_bSecondTry;& o; b& ?2 Y/ S @
bool m_bServiceStartedByEmule;$ j2 @( x* n1 L# x9 ~
bool m_bDisableWANIPSetup;2 Y3 \- _- X; `# ^
bool m_bDisableWANPPPSetup;
1 O6 w+ i% r5 p
% q9 h- p- [1 P8 i# ]5 v: R! o# P* u2 L- Z: V, {0 J/ T+ I x
};
+ K. l5 f0 q0 T
- |! Y& J) K7 l, E2 l9 L4 W
' ~( V. F* y5 `0 a9 F! d: W// DeviceFinder Callback
; z0 P- d9 o' Y8 `) qclass CDeviceFinderCallback8 \* j8 k6 o7 n! N+ C6 g
: public IUPnPDeviceFinderCallback
* r4 {9 d' d, _# R+ }/ j{
7 o5 ^" w0 @! [9 X1 j" H; Rpublic:1 B0 h5 @8 T2 E' @ p' F: w+ I7 a
CDeviceFinderCallback(CUPnPImplWinServ& instance)
0 X# z: r |) e* C$ g& V : m_instance( instance )2 u- r# `; {2 E+ k+ [. L" r! ], ^2 q+ E! q
{ m_lRefCount = 0; }
* P) ^5 B* `% q. i3 e7 z5 y; _7 s% K- j' e5 G" ^5 m) R
- Y9 Y6 W `4 W+ R STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
% |/ L8 ^) L+ R+ t3 } STDMETHODIMP_(ULONG) AddRef();. b7 V: R* J9 t" B4 p7 {$ B
STDMETHODIMP_(ULONG) Release();0 U; t2 {( G* [! U
" Z2 x9 i+ Z! S
6 ^# X8 s/ Z. u5 c) M' b9 a; E
// implementation4 P6 w2 }2 F0 {$ A; t
private: `4 n, ]) V, g! }, z3 P3 i& |
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);* }0 v. r8 ]0 O1 ?
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);& a) L+ x) y; Z U- U( f, v
HRESULT __stdcall SearchComplete(LONG nFindData);
' q% J$ m2 h; z) ]! M% o: u% b4 l: R/ o; I, x
U& M7 H5 R& a4 c9 n) z" qprivate:
, ^- j' U. k9 |% [3 k w CUPnPImplWinServ& m_instance;4 ~6 m7 Y$ j6 K
LONG m_lRefCount;
" Z8 U; t3 w8 F+ f1 C};
: ` p2 E3 i3 e3 Z$ x- X6 d! I7 `7 b7 S s8 p& w7 b4 c
& l( d$ A/ C- I: C
// Service Callback ( C/ k! a6 G4 r7 b# s! K
class CServiceCallback
" }+ m* B/ ]+ S+ d& W8 v, k6 s7 a : public IUPnPServiceCallback7 _+ y; O: I2 U1 c& b# n
{( ~2 M' g& w0 W3 B/ Z7 \
public:
+ D( F8 H9 F% d7 m+ H0 q3 ~ CServiceCallback(CUPnPImplWinServ& instance)3 ?& X! y- q! w: k* m' x
: m_instance( instance )
0 p& e4 V( |' u { m_lRefCount = 0; }
U' K8 S2 c* X. R$ I% K# T
" @3 x+ W# W4 h- C0 a3 l STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 M$ q1 S) w9 Q+ \& }9 E
STDMETHODIMP_(ULONG) AddRef();# ~+ v* ?2 U' E3 ]
STDMETHODIMP_(ULONG) Release();
3 ~( d" O& a# d7 g6 M
: e. u( J( c$ }2 ^. V, q7 m# Y" C4 T9 y- p) x
// implementation
7 W4 d4 M$ P8 Fprivate:
! |+ V1 ^& N1 A" t' x HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
3 J! m% L; D6 b @# i HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);5 Y$ o5 F3 q2 h
/ N' h: Z* }2 L# r d' U/ d- c
+ O0 J% d- w }' j
private:; e+ A# X5 i5 l. e
CUPnPImplWinServ& m_instance;
: ]6 U, q& K/ r0 h) q3 n LONG m_lRefCount;
- d! s1 R! S; p};8 P6 ]# w5 a! G b% [/ O1 u
" C# _, M6 G1 ^$ t, K0 V
) P1 _/ F- w( @
/////////////////////////////////////////////////
6 W- m: Z3 h F! K% ~0 Z" M* g6 S
8 W, ~5 @. }# E7 l4 w$ w7 E; A& R# Z: M/ y* {
使用时只需要使用抽象类的接口。
2 V, G& s0 S. |3 G4 V PCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.9 y( c/ a: {- p" ?" ]: Q
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
' x9 Z) N; `+ iCUPnPImpl::StopAsyncFind停止设备查找.
: V S+ e+ L8 }3 f' mCUPnPImpl::DeletePorts删除端口映射. |
|