|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
# I* I2 R9 O4 ^5 R+ M, I6 `* m& ~
1 l* C J3 K4 l3 S) `6 I; y
///////////////////////////////////////////2 t, _, f) y s5 t0 ]
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- K' N7 m5 W% Q3 p( k" I$ F0 X2 Y
& \1 O/ e5 \8 S
: B# R! f ?5 ?8 A4 t
#pragma once
6 o% B4 B3 D) x8 }6 u' [" `#include <exception>
D$ ?3 B" I& T5 X
' b O- j3 v4 Z# K" P3 X( W$ b1 q0 E$ v4 ^6 z! s$ E) G9 ^- J# s
enum TRISTATE{. @! m8 D5 J, G9 q s+ y& L
TRIS_FALSE,* Y1 C' E0 ], B0 h( T
TRIS_UNKNOWN,
' s) R# o2 e+ v. N6 l TRIS_TRUE. z+ c+ f3 `0 [$ ~1 ^# w& t& _
};
& Y& M n# f6 R) ?2 j( P
' W. h1 j1 q$ v: N* a- ` x* G% N$ Y* s/ q- w6 i- b+ K7 ]1 _
enum UPNP_IMPLEMENTATION{: k# y9 E: i) U4 L2 Q' A7 }; m
UPNP_IMPL_WINDOWSERVICE = 0,
/ H% Q3 G: w% ]4 w' H UPNP_IMPL_MINIUPNPLIB,, R: J4 {& z' n$ y, r* ~" M6 J6 k
UPNP_IMPL_NONE /*last*/0 R% ^7 E# m/ D- o# H
};
" b7 z, F1 Z0 E/ l; c9 ]
) C3 ?3 Q7 J& v8 I& \0 H- a. |9 ?# a: X
# e* {. w- T: L% a$ ?) O) }
1 V: E8 r4 e; Q1 p, ]class CUPnPImpl6 X; a8 m- X# ~4 N
{
3 g% @% s, N/ b0 H& [4 Tpublic: n, e6 x) X1 X# X# `, v
CUPnPImpl();: C& i( A k, Z5 h; a# Y
virtual ~CUPnPImpl();
% E+ M! O; t/ g0 p) i* I9 K% w# p struct UPnPError : std::exception {};6 O+ R% V! z8 t+ @
enum {
G+ F4 o' \3 g [ UPNP_OK,3 d4 n9 ]5 J, j0 ^; J
UPNP_FAILED,+ }6 R. X2 D7 K$ {$ Z- h
UPNP_TIMEOUT0 p; F) a8 r' F- q/ g
};
, {( ?( \7 \. e* I/ B' E& @% F1 c
$ g! ]6 B L% B/ D1 @) l
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
9 I: O( r# W- H+ W7 Q virtual bool CheckAndRefresh() = 0;* }2 D" @+ {6 _" }
virtual void StopAsyncFind() = 0;0 n0 ~3 R ~* [7 @& M. g
virtual void DeletePorts() = 0;' i6 W: M/ I* _' O# _
virtual bool IsReady() = 0;7 y$ n! a, M4 e2 H0 @1 |9 Q* Q
virtual int GetImplementationID() = 0;
+ Q2 F2 E K( A
) c+ z0 G0 R1 T8 B( C void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping8 ^2 X8 m$ n) Q# M$ P
3 }+ a7 c. z- |% I
3 S9 A: \- ?. N, E; G void SetMessageOnResult(HWND hWindow, UINT nMessageID);7 _$ K! B- p# ~7 n' W! F% O! Q3 P
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 |6 g! x$ U' B$ @1 z4 b. O7 P1 T
uint16 GetUsedTCPPort() { return m_nTCPPort; }& V* a7 z' @9 K
uint16 GetUsedUDPPort() { return m_nUDPPort; }
) F5 D0 Y/ x4 y" l3 H, \. D
/ k/ k c" U, ^) W& T
S) { a3 C* G* Y// Implementation
: j' z) d ]8 q% C( G; W0 W+ Uprotected:, L7 O' Q3 x# O
volatile TRISTATE m_bUPnPPortsForwarded;
8 K, N0 ?8 x$ _1 ]- E2 I+ H void SendResultMessage();. B Q/ B' {0 i& T
uint16 m_nUDPPort;+ H; b7 ?$ e0 V3 B/ I3 ?
uint16 m_nTCPPort; V( ^3 }/ ^/ V6 D& N& C
uint16 m_nTCPWebPort;
0 i$ E# w$ w- m( f1 K$ M bool m_bCheckAndRefresh;
; N' l V3 [, u9 b5 w
$ l& V& B$ m: r# A8 q; N5 e' I( i3 d9 C
private:% o- c2 d. P+ S1 h. e: K
HWND m_hResultMessageWindow;1 `3 v/ D; B0 B
UINT m_nResultMessageID;- i6 L. h8 n0 U0 y4 U& |9 k& H+ n; @
0 W; a' V! F6 A$ q
7 ] T0 T/ g+ F/ ]& a$ Y
};
; b' @1 B" e( M! b: ]
( Z* W4 U$ g& o3 }, {: Z; D# @" W6 W( g- @7 f
// Dummy Implementation to be used when no other implementation is available
& y" p# Q. C3 L7 Lclass CUPnPImplNone: public CUPnPImpl
% h6 d0 L B5 J, H$ e8 F{/ }% l, V- [% z. \1 s
public:; Q, f( D( ~" c* l
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 L5 K1 P: O# O virtual bool CheckAndRefresh() { return false; }4 J: w" J. |) M6 V+ Y) Q
virtual void StopAsyncFind() { }6 r, X) N T% i: K
virtual void DeletePorts() { }
N9 H3 M+ s+ d" d6 K: k) ?% n virtual bool IsReady() { return false; }
; v# }9 Q+ \; V0 ]* Y6 c# G* u' x virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) g; y7 V% h. a- B5 {# `5 x% ?
};! s- j' a" B4 ]( ?$ ^4 @
0 D/ v* r, }1 ^, t, G2 J) r$ o) o2 ^: {' x! d' v
/////////////////////////////////////
9 t! c/ i0 J4 Z; X& l7 U3 _8 T//下面是使用windows操作系统自带的UPNP功能的子类, ~, {7 r/ ?, [$ R7 m
) `( a3 O2 @1 o1 ~
# Y1 i1 R# o$ A& |" Z% x" c#pragma once. `+ D% N, h( y( H
#pragma warning( disable: 4355 )
) V* c" f; z( @- B( D [& w$ h. T5 o3 ^) Z- e8 q
4 V$ H W1 s4 ]3 @1 S' j. {5 t#include "UPnPImpl.h"8 H- i% V; h' G& _
#include <upnp.h>
7 j7 {& d0 @0 J4 c9 J& g0 L#include <iphlpapi.h>1 D. {% A6 X' g+ r
#include <comdef.h>
. o8 H. ?3 C! U7 D0 M' o, t#include <winsvc.h>
" k% y6 ^. ^7 S Q1 i
! z. l" d1 \5 F8 ^ z/ d/ W- `" n: I ~
#include <vector>
: u5 U X2 D* _5 B#include <exception>3 ^/ O: O) _1 S# j$ l' C
#include <functional>
0 f8 i, P/ R4 l( i; h# L& M& K6 x- Z' l) e2 }
( B% h. L+ ^6 e3 x* }( ]
# C4 G4 R* r6 ~9 I% R+ Y; O& i. {& U( |; F) |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;3 L( N4 T0 S: n
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
7 R1 l$ ^2 v: T' [typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;9 k. C' I7 r \* i; g% A, a
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 O; }7 e7 `# u' y, c2 Q7 D( ?6 V
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
$ z; r: `" |3 _$ Ltypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;8 E/ }# w8 X/ W; j# U
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;2 z2 [' w9 A5 a, U4 d2 S& \
) i( }0 k# }0 X0 k0 Y0 p# J
4 p! j5 T7 o2 r, `# f. @typedef DWORD (WINAPI* TGetBestInterface) (
$ [% v" U7 y. l% `# a# ` IPAddr dwDestAddr,# Q' o2 H: d! r/ J/ m
PDWORD pdwBestIfIndex( Y4 m9 W- _. l9 a, P2 y$ R& h" q
);% z; j, J, _8 f, u I( Z6 u `
! k; B) t* A& r' m
1 O5 _" s9 T7 J' Etypedef DWORD (WINAPI* TGetIpAddrTable) (
5 y) `# ~! s. i. \% d PMIB_IPADDRTABLE pIpAddrTable,; Y6 l. t4 Q1 V2 e
PULONG pdwSize,. n+ Q" z6 }" q7 Z# d$ W
BOOL bOrder, _4 S! s/ T* Q- h
);
, B! Y% H9 o8 w1 d) Z2 e
9 k5 V2 [! s; d: g# R( k
! V j5 Q( X$ a3 u3 B6 @ \6 x) Ctypedef DWORD (WINAPI* TGetIfEntry) (
" P- O, P/ |; H" F4 J/ v9 u PMIB_IFROW pIfRow$ K8 u. ?9 k( ^) A- E9 J; D- W; W! |
);! [- k3 ? @( o4 m" E, }7 R9 G) J
& b; f) ]/ A9 ~; p3 u( _, ]
6 G/ r7 u" e2 A' A2 p: T0 C, d# JCString translateUPnPResult(HRESULT hr);* C' b! Z; ~' L6 R$ n4 n# E
HRESULT UPnPMessage(HRESULT hr);5 U1 Z. Y5 r) @& l2 f5 t2 n' S
. ^+ m# h/ d+ l# i5 g5 I6 i$ {
6 g3 H$ `5 i$ k! l3 n) h
class CUPnPImplWinServ: public CUPnPImpl" h( P) U# g4 a5 @2 U) P- w
{
3 P* E! Z6 U9 v* _& y+ [$ F friend class CDeviceFinderCallback;
( J, x% U& u U4 b0 J friend class CServiceCallback;
7 D) ]0 o" B6 d5 R1 _) I// Construction9 v" Y3 u: P& O3 z. [& C8 Z" n3 E
public:
) Z, x! g" q5 `5 R/ i+ {% V virtual ~CUPnPImplWinServ();
( g3 |2 |" T K CUPnPImplWinServ();: S5 P+ E* s9 a: J6 Q& d
/ q( _$ G9 h7 M* u# U
; B+ K T* U: u. W( Z2 Q. Y+ F, e virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }* x$ C$ W) e+ k& U
virtual void StopAsyncFind();
! I7 i# P, I& n- q5 o* j7 D virtual void DeletePorts();3 M3 P9 M8 O1 O" R0 @2 {
virtual bool IsReady();
" A; k) V; W3 }2 K# [ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }/ x: ^- q& b9 ]# t- m d, \! z
7 W3 j( h& T/ \$ ~
Q+ [- ?: U6 B // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)! G% T" r& U* Y# r- c
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later# J: U/ b* |/ J$ G9 B7 x
virtual bool CheckAndRefresh() { return false; };
$ W& V" x" ^* C% B; b3 W7 p+ Y5 c- _" D6 u) E7 q
) ~* z6 w( E3 \7 X8 p' z
protected:% k' G; B, y! Y5 a' e
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; c6 I1 q7 ~9 D* o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);# [& G3 O) V' j' t. _% _; Z2 y
void RemoveDevice(CComBSTR bsUDN);* S: m7 R" u# \7 i' i
bool OnSearchComplete();
, a: `4 @( i& z void Init();% q& j* Q$ Z9 }* r: W4 r
. \( F3 T& n; f& T* O4 e* M6 q0 m" r& V9 o% z! I4 B" R
inline bool IsAsyncFindRunning() 1 B# [% ^0 B0 R
{
. | k/ U/ ]6 c- L if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: E! v E( z+ l {
7 ]5 `; M5 v* q7 K$ N% t) _ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 j2 d8 E- c7 o& }
m_bAsyncFindRunning = false;* U6 D6 i: n. {; ]$ [
}
+ N" a/ N+ e2 p$ M( n MSG msg;
* Y, f: C B6 ^' l/ L% K while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
8 J9 a* y* o" Y& ]0 W4 Z {
& a2 X+ n$ }. {( V: y! Z2 k# g9 } TranslateMessage( &msg );
& \& O7 E) Y6 {; G$ r DispatchMessage( &msg );% e- g, {' N6 M6 B- ?' w8 }5 P" ]3 R# a0 R
}1 s* |5 O% p: Z) @4 I! Q
return m_bAsyncFindRunning;/ ]- L- P7 ~5 ~% D% V7 {: A! |7 F
}
t$ B) ~+ J9 ?( J) J) n, G* B% X: c' Z, e2 m o- o
& k# ]3 l) O4 K. D& @* T6 o TRISTATE m_bUPnPDeviceConnected;8 `( U G4 S6 d5 j
6 ?8 Y9 G/ \1 U, h: I
! j3 r6 m# T* p// Implementation
% q k5 k& x( }- ^! F2 T // API functions
. y: B6 n; Z3 [: u0 S- q; E SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
" u3 v8 z7 c; ?4 V# p" t9 n SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);1 s+ u: @& f" Q1 e
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
% t7 D5 q; d$ k- a BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( D5 F: T- r, {+ H3 J3 M
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);/ H! X; X( j, J6 m: L
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
# x. A% f% w ?; Y2 Y6 A6 k z6 I
?9 d, l# D" _4 Z& B% c) I- J3 }
TGetBestInterface m_pfGetBestInterface;
$ x6 m" o; R) q! W TGetIpAddrTable m_pfGetIpAddrTable;
5 A- ] u8 E! ]+ E: ^. Z' U TGetIfEntry m_pfGetIfEntry;
/ K3 g; h2 P& r7 V4 w
% m- N. N) K! `. T
9 j, a! _) S+ c9 [- [: m static FinderPointer CreateFinderInstance();
$ l; b7 Z) a) q: T+ l. v9 e6 L7 g8 E struct FindDevice : std::unary_function< DevicePointer, bool > g; u% ]! W0 ^; `6 n4 Y
{0 [1 q: M: I) X, S, ^2 t8 H
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
9 I) |. M! K& q W( g& [1 n o: G result_type operator()(argument_type device) const) A& `9 J( F7 x) p4 U R- h
{
# a6 O( a2 H% o5 F% m. f CComBSTR deviceName;7 r- E6 o' K% m. y* Q, i
HRESULT hr = device->get_UniqueDeviceName( &deviceName );* E O( `' W0 j+ N# E
" I2 i2 K1 F( l2 o
: S5 c& U& Q% B) Z* R if ( FAILED( hr ) )/ b) Y+ g6 V% O W5 ~
return UPnPMessage( hr ), false;
5 h6 i6 s! |9 x# J6 d$ m5 N
+ N, h7 {% K8 u& B9 X3 J% [1 @$ S1 l1 z
return wcscmp( deviceName.m_str, m_udn ) == 0;
$ k) k7 Y: Q M" G' ?- ?& ] }
: }! a. @/ S0 v8 G3 }' q } e CComBSTR m_udn;; G" m! u- V. q; g2 u
};- d F( @6 l1 p M2 A9 g6 ?: ]6 H
+ D0 k. F/ ]; G
void ProcessAsyncFind(CComBSTR bsSearchType);0 x( X. |2 _* g: a9 o% `8 k
HRESULT GetDeviceServices(DevicePointer pDevice);$ D- I8 U4 S3 g- @ c) Q6 l( I
void StartPortMapping();4 K1 |; _9 T1 X/ Z$ K
HRESULT MapPort(const ServicePointer& service);3 \" h" B1 [* F g+ n# N
void DeleteExistingPortMappings(ServicePointer pService);
! {" F5 V8 W9 ]! b/ H void CreatePortMappings(ServicePointer pService);
$ R( d J( I: a: {7 N HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);. |- Q G* K7 Q9 E3 }( d
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, : F0 C0 i- J o. }/ [; |
LPCTSTR pszInArgString, CString& strResult);. q1 w7 T' b; e. `
void StopUPnPService();) R* f2 o0 n& L: O; U0 F
' _. L7 M6 p6 I
5 m* p7 d0 e, \' K9 U t
// Utility functions
7 l: t+ t c6 J HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ O. y: y0 _" j' {% e) s( F c$ D INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. q: D4 {, p/ y, Q) X
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 h( ]) w) B- P2 Z$ w
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! C) L! h5 P* K2 d& ^
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);( m( h, j- s9 X8 m1 L
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
8 D! S6 Y( e; G- n8 `3 g* a CString GetLocalRoutableIP(ServicePointer pService);( q% \3 T0 q) [) c) L/ S7 l
" f/ A2 K5 S# j6 j( f K
& U% s0 J/ S. P% O. D+ A// Private members
0 r& I/ g8 L9 l0 T2 `private:
# n- k' p& F1 v: D& t$ f DWORD m_tLastEvent; // When the last event was received?1 B' p0 U& O+ w' z. V" N
std::vector< DevicePointer > m_pDevices;
1 I% R2 l' T5 ~! `- E- H% p std::vector< ServicePointer > m_pServices;
: I3 @% @' h" @" w/ G6 s b FinderPointer m_pDeviceFinder;
0 i/ U4 }8 D1 z g2 Q$ u1 [$ b DeviceFinderCallback m_pDeviceFinderCallback;
5 n4 h7 g8 G3 v8 V7 C8 x% |& {( J ServiceCallback m_pServiceCallback;
$ D e# {" N- J8 E+ b* |/ o! p" p' R& N$ n
( @4 h8 V/ Z% `1 P/ X% h# Q LONG m_nAsyncFindHandle;
% q5 `* [: r# V6 b# I bool m_bCOM;8 b9 r+ H+ N2 G E- f
bool m_bPortIsFree;. q# A4 |5 i: G ]4 Q6 _
CString m_sLocalIP;9 N1 G2 H* f0 N* X; I$ k
CString m_sExternalIP;
) K7 n# ^6 _3 J n bool m_bADSL; // Is the device ADSL?& p3 D1 t3 b3 r
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?, j' P! L7 B5 w% S. p" A3 a
bool m_bInited;9 @- ~! z) A) J! w- D& T
bool m_bAsyncFindRunning;
4 x Z9 ]/ ?4 K& {& H* r HMODULE m_hADVAPI32_DLL;: J( ^8 T6 A1 Y% q- a4 X: K
HMODULE m_hIPHLPAPI_DLL;, O- ~$ j- C/ J
bool m_bSecondTry;) h) v4 K; \1 c; D& D( q
bool m_bServiceStartedByEmule;% x2 |' T2 Q% N9 U
bool m_bDisableWANIPSetup;
" [6 m7 Z- Q. l bool m_bDisableWANPPPSetup;! f9 r( ~! d+ i, W' R% T4 E
$ \+ q4 |/ ?2 C7 g( d
' c$ d: Z, ?7 |
};
( _6 m. J, u9 {8 c8 P& _; f: h# Y" F3 y4 x! F9 i! T0 f
' E4 ^8 M0 [& l, ~# }3 Z5 q
// DeviceFinder Callback3 m$ ? C" Q& b* B
class CDeviceFinderCallback
5 I4 }% L/ i( [8 x9 ?, S0 I : public IUPnPDeviceFinderCallback+ d- J. I @# z; [4 i E
{$ J6 O/ u9 D: z
public:( v s: t3 K+ Q1 Y& o" H7 `
CDeviceFinderCallback(CUPnPImplWinServ& instance)
5 f) t! M+ S+ J" q( G: w : m_instance( instance )( K0 l4 u, m+ x% i N+ `* s* n
{ m_lRefCount = 0; }
5 x7 e, z K6 ?% R: s2 `( s
& T9 h+ b% Z6 j X/ |$ T, v& p' M5 }/ j. S
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 _: a: L+ U' U' k' h. c' B5 N STDMETHODIMP_(ULONG) AddRef();7 l: a1 Y; @9 q: Z* F
STDMETHODIMP_(ULONG) Release();% X% U7 p2 ?3 P4 Q( u7 q
, p' e: Y6 l& @( m, Z, z* w. s$ V: j$ k3 @* J
// implementation+ f0 t% ~# Q3 y7 A1 H2 K
private:
- `# k$ \' V' @0 j: W HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
+ A* t# J2 L) l5 P( a HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);' n& s% \% @0 x: H8 `- g+ b
HRESULT __stdcall SearchComplete(LONG nFindData);
/ ]9 m3 ]. k) L. `4 d
: w5 B3 p {" Z( {. Z
9 r% i) F* t, d2 Iprivate:
& r% q9 }" S, U CUPnPImplWinServ& m_instance;) P' p$ u9 i7 I" S
LONG m_lRefCount;. ~' k; P: y" c4 ~) Q! P
};
2 \* O8 j; |4 a: g; f5 C
2 y Z5 W6 x- C# N8 m# r& h/ R& a
8 y$ H5 S1 V8 \9 Z5 e1 z// Service Callback $ w) ], \ I7 T7 G$ v
class CServiceCallback
" S- a9 f) i: \1 L : public IUPnPServiceCallback0 l5 E1 B6 h/ z- _2 o1 d
{$ h9 }0 d2 Q! ]% w
public:
, F! A1 ~! {- Q CServiceCallback(CUPnPImplWinServ& instance)
& C/ b: U* d' `# m. h: h# R : m_instance( instance )8 C% p9 u3 f, g& g" e) _1 N. _+ S
{ m_lRefCount = 0; }
1 t' N% [, h0 ~# o
( m0 e0 o5 p7 q1 H$ l& U J/ j STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! U& ~0 k8 k( R/ ^3 C$ @% z$ s STDMETHODIMP_(ULONG) AddRef();/ I5 x5 i p& [) z8 W
STDMETHODIMP_(ULONG) Release();) l/ c0 c9 n* B" N, N( _; N# f
5 C6 Y$ D1 U! H# x
/ Y+ _ O4 b8 D% n// implementation
) D: X' k/ y; S- vprivate:1 V0 {# Y1 S7 l
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
, w, \( i8 O2 r6 d. G* Z7 | HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' m3 j t9 D" }0 q$ v
% k- k* d% s7 g7 Z9 H) _
. B) N3 T# Y. Fprivate:
8 A* v2 y, c2 @: l6 T/ k CUPnPImplWinServ& m_instance;
& V1 E; k+ Q2 e LONG m_lRefCount;
% W3 X9 ]# W$ J- \};' B( x# j2 t# D0 h
) O% W: d$ f0 _& Y2 L- |
; n, |! M$ A* B2 G. g/////////////////////////////////////////////////: A# P! u2 A0 _; E
% v7 I5 m0 g1 n* a
4 ?+ @6 X# z; P* G使用时只需要使用抽象类的接口。
; E* q$ z; B% t& h/ V! pCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
, D& ~4 t6 V4 j7 x5 m& oCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! k2 Y4 H) e; I' a
CUPnPImpl::StopAsyncFind停止设备查找.4 W% y( Z5 D$ n b; M( @
CUPnPImpl::DeletePorts删除端口映射. |
|