|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
2 ?- u' n4 q! ~7 A3 g4 C
( z, o# U6 n6 X2 a: ^& Y
' ^8 D* z6 F* J* @( W* {///////////////////////////////////////////0 \2 u/ p2 ?6 @4 {: E! O
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 t. ~) H4 k6 ]% O& x z2 i5 k6 @+ W$ \) P8 r& B
" o2 ^ A+ ?9 m1 }#pragma once! Q! Z& E1 D6 Z5 q. u" F+ c
#include <exception>
' {# ~& H1 T% M) _/ g
; X; k( G4 ^$ ^$ _( h$ W$ F
4 s* c6 E6 p8 N5 v" H enum TRISTATE{
, h( G/ F- c7 k1 x" L TRIS_FALSE,. x2 Q l$ M/ S3 K8 g" d
TRIS_UNKNOWN,4 w9 h. i# M* a* L3 F2 z# @* Q
TRIS_TRUE
: ~$ k' {: ?+ f2 ~+ Q8 s% i: m K};
( e1 y8 s) o* Q7 `" l: ]2 V: K0 [5 a+ n# K- `1 o: L6 U6 H
1 f$ k/ J0 p+ E/ v/ B+ cenum UPNP_IMPLEMENTATION{
6 U2 _8 |$ P+ J% h0 ` UPNP_IMPL_WINDOWSERVICE = 0,
( w) ]/ n! i0 ?) P" n, M( q UPNP_IMPL_MINIUPNPLIB,3 z9 M6 k+ n) r9 I$ F* @, T: X
UPNP_IMPL_NONE /*last*/
8 [# k$ \" E" T};# J0 H3 a: O0 ^ K# e
/ z. S+ u9 B: y% _* j1 d1 K
' l2 B3 Q$ _0 Q0 F
+ Z' C& z, {1 b- ?% u
( c8 s9 V, }, k# Sclass CUPnPImpl
; ^' m# x, A! x$ U! O{& u ^9 | g1 e# q/ J$ n, G
public:
) V$ C4 }# `4 }8 c$ G9 e9 E& b CUPnPImpl();
' L' ~' h( ~- ` V5 T virtual ~CUPnPImpl();
3 E0 ~+ h& F0 X# Y% J5 T struct UPnPError : std::exception {};- h2 H* s, C; {, L
enum {
* U" w$ `$ g8 C: L( |( k0 Q5 C5 z UPNP_OK,2 h/ A" ]5 z) @% o
UPNP_FAILED,7 G2 l# k$ j% O0 i8 x% x% V% ~
UPNP_TIMEOUT
, Y/ m# I9 [/ f; G };9 t! ]: R$ v& h2 g5 _3 Y( R
6 b) U3 _, {8 p$ U' M) p+ ]. P2 u0 R6 e( M. h2 U+ j i
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;- B0 P$ A- S2 @$ F
virtual bool CheckAndRefresh() = 0;
; U/ f- v! a% ^! e: l! S" a% T virtual void StopAsyncFind() = 0;
) Y8 M% A, o' Z3 d6 ^' V: I1 D virtual void DeletePorts() = 0;
$ b5 W7 n3 ^" l virtual bool IsReady() = 0;3 N+ E+ e: s; v% T0 y2 f1 ~
virtual int GetImplementationID() = 0;
, H, m, r" o; U" U9 W" N
4 A: V" m4 Q4 x0 P4 u# ] void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: O# M7 `3 b% l' a" K& V* ]5 }+ r1 G1 T
3 L! t' v4 O% O* ^+ U- S' r% X void SetMessageOnResult(HWND hWindow, UINT nMessageID);
) k7 }0 g; B0 _- O; F TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }& H/ g; a1 ]) E
uint16 GetUsedTCPPort() { return m_nTCPPort; }4 V" S" U, E/ R& _
uint16 GetUsedUDPPort() { return m_nUDPPort; }
- _7 i9 T2 t& |- `* v) Z0 R+ H! K0 Y) V( z" q# z8 p
) _% s7 p- W7 B" r! {9 H: O% m// Implementation
" l8 `0 `& O5 ]protected:
1 z9 j5 P: v( U7 o/ o2 o volatile TRISTATE m_bUPnPPortsForwarded;
$ o% ^' s3 A6 J void SendResultMessage();
8 F& w2 u0 u' {. l uint16 m_nUDPPort;9 u% @& {5 p' T; i
uint16 m_nTCPPort;
: h; G j( |% G4 L+ @1 ^ uint16 m_nTCPWebPort;* G0 K$ O9 K, \4 U& t/ i
bool m_bCheckAndRefresh;5 L8 n& U3 ~3 v: X) {- Q( ~
6 Z3 m* I/ h2 i; J7 S5 H# [7 C5 G, g4 j8 Q$ [# S" O/ ]# z9 G2 T
private:5 ~. K. v& S' F3 \8 x7 k3 ^/ _
HWND m_hResultMessageWindow;
( D Q3 r' C& r9 d8 X( Y UINT m_nResultMessageID;/ W3 A4 S+ [) Z D9 [* l9 A
7 E( d, _' H8 F$ G4 E9 ^
& y" c8 Y: |% `2 s0 W8 [: J};
3 v2 i; G+ _4 |1 Q3 v% Y
( ?5 e6 [' h* [& Q$ O9 U: z& ^
# T% T' U' Y( H4 n// Dummy Implementation to be used when no other implementation is available3 ?; a" N/ c I x* @: X, m' D
class CUPnPImplNone: public CUPnPImpl
1 x! D5 W( J7 P+ z' b3 j. }! Q: E9 a, z3 E{% Y Z. z# p5 C# a& |# Q6 k
public:
$ k* s0 ?. O0 K: e2 w. M U" v virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ u$ c) M3 w. ?! x U) N1 q/ t, [ virtual bool CheckAndRefresh() { return false; }
* @/ s& e$ [3 U1 C2 C/ j! Y# \+ ~ virtual void StopAsyncFind() { }6 `; a6 B' b: ^% z3 g+ L4 g% }8 Q
virtual void DeletePorts() { }- L& e/ h+ s' X* D3 y
virtual bool IsReady() { return false; }0 r1 |7 h: a0 }" ^( @; J; }( Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
4 G/ @5 E0 J3 x& a; @! D# H$ K3 v};
4 K/ _; R1 n. u m" j: \6 j' F' d9 u4 z2 H3 I( z. G8 O* O" K
/ m. G E2 [. \, r/////////////////////////////////////* J0 _9 [/ T( D+ }
//下面是使用windows操作系统自带的UPNP功能的子类2 `$ d: E7 i; S- P# A( v/ M, d
! p" L' l: C2 D! Q8 r) T1 e5 @' q9 T
$ f r* \" Q$ P& Y7 ^#pragma once
+ o& ~# c0 V% E9 h R$ P#pragma warning( disable: 4355 )
7 b, o0 t" Z; e X8 {$ U4 P7 {' Y) q8 p" d) R1 P% I
- s/ d Y1 R# }8 b& R8 K; n
#include "UPnPImpl.h", q7 y) I1 V4 z( }% d7 m
#include <upnp.h>
" H, A5 R. P6 b; |#include <iphlpapi.h>
8 T5 V7 c2 w5 b#include <comdef.h>$ T( G- @6 |3 Y# Y
#include <winsvc.h>
+ Z6 B' l$ Z2 v$ f! f, s5 ?$ p1 I6 h
% u( ~+ g& V+ @3 W
#include <vector>
4 N- c+ G6 u" a2 `#include <exception>
* F$ y" O% j& ?. w) r% C#include <functional>
& g. M. w% m) b: q' d* H# ~- D+ D
7 T# f, h" T r- P1 H# R) v2 z# G4 R
; X& p1 L5 t' q: J- q. R+ ~* Z
" W) L" I1 C( {4 wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
" F) N9 G9 e, Xtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 \; ?! M* A+ ^7 x. I
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;8 b$ I1 O' g6 V1 \) d" ]" o8 _
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
: [( O/ d* j- _& a; }8 v$ n* O% Ktypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
- ?! o* k( i3 T6 a" [1 _typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
/ t+ Z6 b9 U8 g& }4 W( t5 Vtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;- R, V6 l& a7 ~0 n9 R. m- n
0 y* W% |0 q8 A6 \( x4 U
. d/ f- ~$ M. ]
typedef DWORD (WINAPI* TGetBestInterface) (- U+ _( I. K9 Q+ r
IPAddr dwDestAddr,
: d5 P. ]& k8 E1 K7 K) U1 M PDWORD pdwBestIfIndex. F6 f$ Y& t& {# J3 w3 ~
);
5 m4 k/ M7 s" K5 Q$ i$ H& j$ I2 x! g5 F- s# V: B
& g0 T; C( ~' N% g C Y
typedef DWORD (WINAPI* TGetIpAddrTable) (
( h7 ~' l/ Q& z( e, R5 R* H$ h PMIB_IPADDRTABLE pIpAddrTable,
% I8 E, S4 L* y. W PULONG pdwSize,' [6 A/ c7 t m2 v
BOOL bOrder' q+ I* X7 N% t# s! ~# S
);
" N Z1 m9 U1 m7 L2 _" i: ]3 H! q$ p& I1 }. x
: Z+ ~7 F1 @# Z+ ]1 y. B% `* v
typedef DWORD (WINAPI* TGetIfEntry) (: O8 X0 V D6 n
PMIB_IFROW pIfRow3 `/ m# |( n9 T$ o$ v7 S
);6 s+ c0 P: F8 C8 E0 J' S
" B) }5 T- @8 P+ {
, r# t9 ~2 r- LCString translateUPnPResult(HRESULT hr);! S% e+ c `9 x2 f8 g
HRESULT UPnPMessage(HRESULT hr);
5 t. \5 }& q2 V/ p4 e9 U( B0 w5 E+ e2 \
) `' U* `! O- x7 B0 F s2 n2 Sclass CUPnPImplWinServ: public CUPnPImpl( N _5 u* C. J2 }9 a& i
{1 V) S1 {( y' H4 B+ t6 F
friend class CDeviceFinderCallback;
0 s6 I* U3 w1 A friend class CServiceCallback;: ^- j4 K) ?* Q9 i( N
// Construction3 n9 U' ^+ D9 s+ t" [9 i
public:
7 e3 ^: O2 D2 J# C* F virtual ~CUPnPImplWinServ();
/ A( h4 O1 V8 P4 w, _) w CUPnPImplWinServ();( N2 l3 `5 A2 y( n, D: I# y) s
# R' m' o! L- S& o! }7 a/ ^
' c5 ^) x: d7 B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }% f/ w1 e" s0 } L" V4 @. R5 h
virtual void StopAsyncFind();. p/ h6 y' t7 V
virtual void DeletePorts();
8 c, k: R4 @$ l! l, H( u" y6 t8 a virtual bool IsReady();" M6 _# A E7 P2 t' N
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
9 o( U- B; S% X+ D- l. \2 X
8 |1 ^ o/ u3 Y5 t3 y) F3 g; a# v- G- }/ Y( ^ J
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
^, H; S* }- t8 Y- Q, [ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 O0 P5 Y% z" t2 T% L
virtual bool CheckAndRefresh() { return false; };
' r9 f, Y. d* p# p
: {$ g: s) g+ o8 L8 w' \! ~/ L1 v e, E4 W' H" N$ Q W# T+ {
protected:
. W8 u- M! m8 v6 \) @9 y, X void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
6 y4 k7 r/ A2 U! ~1 X% x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
$ O$ `6 \5 ?& w void RemoveDevice(CComBSTR bsUDN);
3 X$ T; n) s9 u8 p5 C bool OnSearchComplete();4 z& r. X b( M& ^9 x5 k# u
void Init();5 k) w) M, g% J3 q" j2 w3 {
3 S3 P8 O7 M9 m E% e
, ?* B3 b6 E1 K2 O) F8 d# x; A inline bool IsAsyncFindRunning() ; v% B5 d9 n4 w" X
{
- A4 l- T Y7 ]7 S. l if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )9 S9 L/ h v7 W; _( k; _
{" w" M) c7 X! y5 |
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 C) r p* f: L" k
m_bAsyncFindRunning = false;
, R* f) J! f& K }0 K" T" l. y/ h9 T( u1 {( V7 E e
MSG msg;! y6 B2 z3 X' K2 v
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ). o, \# d6 [, a7 Z0 O" h% {
{
: J# k4 R: A+ F5 Z- V% v& X TranslateMessage( &msg );
# ?" {, n) K% S DispatchMessage( &msg );
7 ]* T+ t4 i5 B }; ^4 L( e$ I/ ^5 t& s) C: ?
return m_bAsyncFindRunning;
/ \2 _9 H: U6 P, D$ T }! z- M9 C# r P/ Z' J3 M2 P! g
, ~: [- P4 X: \* L+ D6 E
1 M$ R( t. Q1 D$ c8 h/ p& P
TRISTATE m_bUPnPDeviceConnected;
& S9 p5 F; |6 Z7 p8 L9 P3 \/ t' O+ O3 q: u; d6 n
' [) K! j& R4 E6 g( [
// Implementation
) p: A2 K9 p0 l9 d9 E9 L // API functions
, \- b6 C4 j$ W SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);5 x* |& o. q; ]
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);6 G7 K& T; }! Q# V
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
# O+ V# K3 p* N0 d$ C BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE); o. _8 q G1 A
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);2 z0 ^7 n; t2 L% G2 c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! F2 ?& L& ~* E' \
6 b1 v# q7 H& p7 S/ ]2 a
$ ?/ H- y* e4 @% i3 h TGetBestInterface m_pfGetBestInterface;; I& K; ?, q; l7 P M/ h5 E
TGetIpAddrTable m_pfGetIpAddrTable;' ]) I S; E2 E1 C
TGetIfEntry m_pfGetIfEntry;$ g9 `: o: \8 G: T* U* [
E8 W* X% c ?# f; W2 e$ g, `
0 E: F" |; A. J" K static FinderPointer CreateFinderInstance();
- p& S+ C, U/ N struct FindDevice : std::unary_function< DevicePointer, bool >
/ u- P& M- T/ }) v5 c( Q {
0 J& |! i0 D9 N* o6 S FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
, N" f) x5 S, ]/ o6 |2 W, d7 X result_type operator()(argument_type device) const
! z' t' Q7 L& X( ?" k6 E& O {5 ~5 k/ d9 e! k$ n! C5 A6 e
CComBSTR deviceName;
$ a/ O. }& h# F y HRESULT hr = device->get_UniqueDeviceName( &deviceName );
% f* z; O* p- `4 b- r) Q. z$ E" f$ @) M
. h# | Q2 }7 r- M) [3 f! T if ( FAILED( hr ) )# }- Q% p1 T* I7 ?3 A, c; E
return UPnPMessage( hr ), false;; c# g$ J( F- `: _
- T# O5 C; r8 M0 _$ N. u( A$ } c1 d7 B$ X3 U" P4 T
return wcscmp( deviceName.m_str, m_udn ) == 0;
! ~& S# h6 B" U* A4 M2 K3 { }
7 V+ V! W t" b" {0 h6 q! C ]5 Y* y4 t CComBSTR m_udn;( v) w* v% ~, w2 {4 v
};# Y# C- t- h8 @! k
* E- k/ Z* a* ^& e; D) x! e$ g void ProcessAsyncFind(CComBSTR bsSearchType);
; ^1 n/ o' b) K& @ HRESULT GetDeviceServices(DevicePointer pDevice);: \# K$ U$ |4 m+ _
void StartPortMapping();
9 Z6 U3 m0 v7 R$ n# I/ N HRESULT MapPort(const ServicePointer& service);
2 E6 z6 X) c" f9 m4 T N void DeleteExistingPortMappings(ServicePointer pService);
+ A: Q5 V6 |& | void CreatePortMappings(ServicePointer pService);
. I c2 a& x/ y" }% r0 _ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ D; G1 {! S2 Q% ^6 P
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ! o% O9 o) ? i
LPCTSTR pszInArgString, CString& strResult);& V6 l; _5 u9 e) N$ F
void StopUPnPService();
* M+ s; F& `9 T) d2 A3 H2 _
, E+ K" d& o O; K. ^. Y4 _' c+ o9 f% O4 v4 f
// Utility functions
: t; M0 {0 D5 y$ _ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);' l% r: r9 s4 c. \. j
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);0 D4 `9 N8 U- K7 [4 E: c
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
: g$ i1 ~+ {. \2 P; H% }3 \ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);* T$ w& ^( e' y% V$ ^" U. X
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
% E! e/ v6 V' n( Z8 o' i' E# R HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);5 L( l8 @4 e" O4 V& t: Y
CString GetLocalRoutableIP(ServicePointer pService);1 a. [3 c& C7 o8 P+ h3 M
2 C' ?+ v _4 ~7 g
. y% D5 m0 e; _6 T4 E! l+ y// Private members: ~/ F4 }# q2 c+ s
private:
1 y+ D" o: L; U" n+ u DWORD m_tLastEvent; // When the last event was received?
7 I- ^6 J! p4 K) d, T; F std::vector< DevicePointer > m_pDevices;
1 S' f, u2 ]. r! A9 q3 ~. d" t std::vector< ServicePointer > m_pServices;- ~3 ^' I' [+ d
FinderPointer m_pDeviceFinder;0 o" w# d- j, ?; Q% ^& z% e
DeviceFinderCallback m_pDeviceFinderCallback;; I' P0 G0 o8 j6 d- Z
ServiceCallback m_pServiceCallback;6 V" Y+ Q, u. a8 J# s
$ l. I+ U- J$ e" y7 o% W
. B( c2 s' s9 R+ p. g LONG m_nAsyncFindHandle;
; u6 C! Z. U, A, v# @, L8 e bool m_bCOM;* U+ f' E; Z+ j8 X0 |
bool m_bPortIsFree;5 [: ^' `: n- D
CString m_sLocalIP;
8 S# b+ s' E2 u2 B: ~" H CString m_sExternalIP;! @ ~) s. h$ h1 _5 ]
bool m_bADSL; // Is the device ADSL?+ l4 `1 {# L+ ~( g
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?2 U* L \3 f4 h: j5 {1 l
bool m_bInited;- E6 F; `2 @& [/ v( S7 k# f
bool m_bAsyncFindRunning;1 c. d8 ~) |1 W+ c5 j
HMODULE m_hADVAPI32_DLL;) s+ G, m: R/ M' b! I1 Q! n
HMODULE m_hIPHLPAPI_DLL;3 [$ L" k( U' C0 E1 C5 h
bool m_bSecondTry;: ^3 A. e- [6 Z
bool m_bServiceStartedByEmule;' r6 p) I" h' n. e3 o7 w. P
bool m_bDisableWANIPSetup;& Y! @ W3 x) V: m$ d
bool m_bDisableWANPPPSetup;: P/ U' x% \2 ?6 `' r0 |4 R
% ~" x( ]/ Q3 N( R
1 @7 E# o' D4 o i, d; ]};
8 G* |: G8 i2 K7 B0 t( s' k; C8 { ~: W
- W7 {/ A3 y3 S! W: V// DeviceFinder Callback
# X6 U- W5 U; S5 G% k. q7 r; [class CDeviceFinderCallback5 Q% g( a0 C1 j! V) {0 v/ K& K
: public IUPnPDeviceFinderCallback
4 V0 s: g' d& O& [5 ?0 R* D{. }% q! m# K% \3 q. q
public:
2 V& G$ T0 q( {4 e CDeviceFinderCallback(CUPnPImplWinServ& instance)6 Z2 l8 l* p# Y4 j( @
: m_instance( instance )
% U# T! h( ?- E# D { m_lRefCount = 0; }
! o# a$ P8 q8 ?: g* D3 Z) J# F# R8 @/ r/ ], y3 g
! E {5 [% b! R1 r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( m& M5 R9 M: B- j
STDMETHODIMP_(ULONG) AddRef();4 S1 m% l, i3 S. R! S
STDMETHODIMP_(ULONG) Release();
$ z& q! z! ? d& w& O! a
' _1 c2 W N$ r& r* ~+ U3 r( r
+ T6 Y9 U9 Y7 V) R1 y; J// implementation
+ A+ N: y9 _3 I; Y& ?5 Gprivate:
% Q: T; i- D2 S* [ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
$ Z5 i6 h7 M) D* g6 ~ HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);8 ~7 B4 {4 B# E& k* @* I: @
HRESULT __stdcall SearchComplete(LONG nFindData);
0 u$ \. S7 `5 B0 v0 a* @+ E3 W0 l2 T$ l
- Z2 t. Y5 Q7 L, _" k. s, L2 q
private:
" Z J9 G! q! j ^# K& T8 g3 Y' R CUPnPImplWinServ& m_instance;. S1 l! T: W6 F; W! O7 Y- P7 s
LONG m_lRefCount;. ^; v! u' {" E* \
};
$ O3 u/ Y( f$ V$ ]8 e
" D/ C4 A# v8 t9 Z$ ~( L& y; a( Z. A8 l
$ c$ ^# K& U1 v# i. f6 g9 f// Service Callback
# B, V9 U2 ?* z6 q% X9 O$ bclass CServiceCallback
. L4 V% n$ N5 j: T) }! h1 w* y : public IUPnPServiceCallback& `' ~; J7 U& @; j& |; n" |
{" }) N- X, K/ N8 h3 D/ X3 C
public:# j. D1 i- y# j+ L# ^. U$ j* s3 g
CServiceCallback(CUPnPImplWinServ& instance)
% r' E7 G& U2 s% @4 A" W% q : m_instance( instance )4 ~" B$ r' D7 u6 `. b
{ m_lRefCount = 0; }+ C: M& j. k% j g$ N
! h5 j6 @# A+ @/ S% I4 J STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
( K8 c. ~" P" m STDMETHODIMP_(ULONG) AddRef();& z* d8 B" X& M1 \
STDMETHODIMP_(ULONG) Release();
! M' H& }( X L. L* c$ `
/ T8 |; J+ i* A- `0 ? G2 t- e. X. B; `
// implementation
: W6 g, Y% ^, M3 o+ Aprivate:
! x& P5 j8 N4 \$ }* Y HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);- k! j' T9 I% a- h: I' I- L
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 c: K, I1 _; x ]) w
) b1 ]# T" f g4 }# G( s7 D/ l( z s/ [& ? f& C1 J+ v; |4 C
private:- p+ m5 A/ D6 b; u$ q, ]
CUPnPImplWinServ& m_instance;' @2 T8 M/ [+ d4 a3 j, s
LONG m_lRefCount;* A K8 y% V f' ?, D
};; g" k, l% K0 o: @
$ h" k" Y# U' Y4 x0 [
1 h% y1 m9 q4 Q; s+ L
/////////////////////////////////////////////////
* @9 ]1 b/ `8 [% Q. K$ L; n3 ?% m" W* [6 o
) X9 ]) G7 m4 f% ~, V K7 ]! _. O
使用时只需要使用抽象类的接口。
6 t, V4 z) r; F7 ^* s9 O. j. rCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; K/ u8 y4 D) H* g, c
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.4 k- t5 n6 B2 \4 H8 }8 l! F8 o. m( ?
CUPnPImpl::StopAsyncFind停止设备查找.
4 h5 S6 `1 n8 j! r! pCUPnPImpl::DeletePorts删除端口映射. |
|