|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
3 r: {8 u+ C, d/ L7 ^9 V
$ v' K8 o& j {1 ?6 }8 b- s- ?1 u% W8 R1 g! l
///////////////////////////////////////////$ q7 o' @' ? G: h1 k( ]
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.$ A( C) h# B6 e0 o
+ K0 W9 H0 f1 }* X' z, y' P
$ |* U {) x2 g( D#pragma once0 @/ w/ O. x4 R" a. l
#include <exception>- l* x& }+ h0 E9 o3 R
5 Z. `3 }; B" @( W) T* w/ O
: K/ O) S( h' B% [2 z( N enum TRISTATE{$ M+ `' u9 r5 E1 q; y: `( a" ^& ~
TRIS_FALSE,
" j7 o6 R u$ w$ U& p TRIS_UNKNOWN,
0 ^1 C. f" e/ f) | P7 ^1 X4 J TRIS_TRUE7 X# d2 f+ Y; i: e% R/ j6 J) ^
};
2 _* d! C' q. \* d! G/ C: j E% {& s0 d7 }1 A1 D+ j& I T7 p
# ?4 J7 @6 h% }, o. V) Renum UPNP_IMPLEMENTATION{1 L6 t2 s8 b9 D# \6 ^3 R& ]
UPNP_IMPL_WINDOWSERVICE = 0,
9 n" t' V) i& S1 s" s- a# b UPNP_IMPL_MINIUPNPLIB,
6 q4 A1 `! Z! G& ]2 @7 { UPNP_IMPL_NONE /*last*/
" { Y1 w4 o, Z X; M};
- J% U: C; X4 B3 u$ j# R: I; X7 o0 o: F1 F4 y5 s) b; Y1 N2 r- l
0 {0 }1 c, l* \ S
. Y; c+ Z. L* A" h
8 z' \/ e$ A: N8 k M2 W; L4 A- Xclass CUPnPImpl
# `/ q7 `' Y* b2 _{
' f$ Z2 j C( t9 R- t+ b2 Epublic:+ ]4 H% x1 `5 Z& T1 A" X& y
CUPnPImpl();
5 R5 D# r P9 }& p9 g virtual ~CUPnPImpl();! R- y6 _5 F. j- U# b
struct UPnPError : std::exception {};
0 o6 M. \% N1 |# y3 j$ U enum {9 j( X+ [5 \ q2 B
UPNP_OK,1 o. \& z7 m! X, w: j$ s+ } K
UPNP_FAILED,
/ g. z% {; o. U2 Q9 n UPNP_TIMEOUT' G( x$ E% _3 J _4 n+ X8 `( e
};) M' b0 y8 x5 B, i7 j, |$ `
6 y2 D, {3 x+ ?* L
0 q9 K! i+ S# k- d" ` virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;( J( U- w9 C* P* n3 P/ @# b4 l7 o7 N
virtual bool CheckAndRefresh() = 0;: _6 b! L; q9 I" b8 V( V8 I: @* K
virtual void StopAsyncFind() = 0;: O& y3 O4 X3 ]
virtual void DeletePorts() = 0; I4 N* F6 w- Q5 O" G
virtual bool IsReady() = 0;
, k6 V. e7 w2 b% r# Z; h virtual int GetImplementationID() = 0;+ H3 x4 c, A, i, ?
: Q" q, l v0 e
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
( t _) m7 t& o1 P( D! s7 R! l4 r$ N1 `6 M3 {4 T8 j7 J
* J: j. j( l6 J- i1 n3 Y void SetMessageOnResult(HWND hWindow, UINT nMessageID);, ?- n( P, L j: d' R2 z. X! Y: z
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) l, W3 n( H- }! {9 p. Z' Z uint16 GetUsedTCPPort() { return m_nTCPPort; }7 N6 J! m' [/ x0 d
uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 M8 L9 c. I. F* F& q0 a
" z8 h8 e }* f" A
9 O' F# k# R1 c6 X# Z( ?- r# i// Implementation I K+ e( e" \) t0 b
protected:
& n0 M. T T/ g$ N8 }+ x# |8 R1 [/ s volatile TRISTATE m_bUPnPPortsForwarded;
2 h& L* }5 m3 I void SendResultMessage();9 W7 N. i4 L" k& Q
uint16 m_nUDPPort;
% o, ]# C/ v8 S6 t* I uint16 m_nTCPPort;
I2 u3 Q5 z; }- C) [, J7 m8 ^* l uint16 m_nTCPWebPort;, _# t: u$ C& J& ?, J
bool m_bCheckAndRefresh;
* G7 T% A0 N* H& M1 [
* i4 | Z, R$ w+ w2 d- d: g6 F- a" @1 a8 y8 P
private:
2 _1 g+ I" l9 h5 }$ ^* | f HWND m_hResultMessageWindow;
' X V4 J% ]% F/ g8 L& R6 f UINT m_nResultMessageID;
& A: M- }) w7 M% a! I
& _2 H: X! b2 e: H7 V, T. w
S/ O2 U- c8 M: |2 _};+ r g/ W+ ~8 [& S; Y
* s+ g. ]. i* y" t+ A' w
( _$ \- @% J+ O" `// Dummy Implementation to be used when no other implementation is available) k8 _# J, |0 L! f
class CUPnPImplNone: public CUPnPImpl6 |) N4 K7 n2 x/ x
{
+ M) R8 v: |8 jpublic:
8 j, v3 |9 j* m5 H! m4 q, n, q virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( B# d+ q' Q, r, f4 ^ virtual bool CheckAndRefresh() { return false; }* V" X6 Q$ W8 e q+ g
virtual void StopAsyncFind() { }
( w( k$ M8 d: a4 q7 U virtual void DeletePorts() { }
0 F* t9 G# A4 Z; x0 W virtual bool IsReady() { return false; }$ V! l* P, d" F! A/ \" o7 z8 X
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }5 z B V& c( p# q! o2 w
};
/ d/ |" H! e5 ^2 d8 o0 s# n$ z! e3 t# ^& N
* Y' G' y4 u7 f9 ^/////////////////////////////////////( z: k0 g, \9 [9 a( T9 p. G
//下面是使用windows操作系统自带的UPNP功能的子类
. `6 Z2 A# b# ^8 g6 y$ E- l( Z8 n# H( Q: O
% G$ E4 Y* Q' } J4 U9 z7 y8 S! K
#pragma once
, F* b+ C! h) y) J' | [+ g/ S6 X# S#pragma warning( disable: 4355 )" D* a9 W4 z+ C1 t% Z1 L# c( q
( a k- \, X; R' z! w
# ^* s# a \. S9 P+ @#include "UPnPImpl.h"( C) i1 L$ t2 A- n& e) [$ c
#include <upnp.h>
W6 J& a# v+ y; k- w#include <iphlpapi.h>9 K/ x" Y! w7 y2 {- K7 z3 Y9 \1 E* Y7 V
#include <comdef.h>+ d. S& Q9 e k: h
#include <winsvc.h>. O2 k# w9 h5 a* a5 I J* c7 k
7 r1 a' Q X% S% [! c/ N2 C9 c+ F# b
#include <vector>, n# l5 q1 a" e0 ~+ P4 o- u$ s
#include <exception>$ W$ Z3 h+ _5 r! {6 z! U" s1 T
#include <functional>6 l& G2 H( q1 E5 z2 V) T! c* v" R
7 A3 `4 m: Y b6 t$ \4 ]3 @% F/ ?+ @- b5 L7 V- M
1 {' F7 G! j+ w
4 v" f4 A! J4 L% p! L- t. Wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
& f* P8 G4 k$ Z# ?# x1 \typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;- C* `$ L, o8 V. |+ J: g
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;* U0 H& U j7 N& ^' p; Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! D2 g& a% J0 j: n
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
j( w& m/ I6 }1 c" i0 \typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;) |, m, j" u, L- q/ L, D( r; c
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
( k ?4 Q* o |, A% M) G/ H. i
V P$ n0 ^6 B+ v' K
9 j# W4 @" k# i* Btypedef DWORD (WINAPI* TGetBestInterface) (
8 Z0 a; i$ E# j" b( { IPAddr dwDestAddr,
, ?* m" L, Q, j& `0 C! ]" h PDWORD pdwBestIfIndex
7 T& ~% j. a1 M);/ c3 w1 z7 P: K: _- H. e/ \
2 o4 B( T' }' Q' \* K$ j
' `4 x: q8 I/ I; p6 x
typedef DWORD (WINAPI* TGetIpAddrTable) (/ Y5 ?5 ]- B! u0 O6 W1 D! v
PMIB_IPADDRTABLE pIpAddrTable,
! C$ P& p; v. J3 k8 X& Q9 P PULONG pdwSize,
& v$ e! s; G+ C! \6 N) _ BOOL bOrder( w0 h. l+ Z2 ?; k& E
);$ h$ P5 o; m6 F* J
2 u2 ?8 @. c) p' F! w3 H5 U
9 F) S/ [. s6 G) F6 X+ A2 |
typedef DWORD (WINAPI* TGetIfEntry) (
8 W) g5 N* }0 N. T2 e% x* {& w4 M/ ] PMIB_IFROW pIfRow, M' U% F. z3 C: @7 q
);
9 B0 b2 g, h- i; `3 a1 G- M
. V7 p" ]) T0 S6 Y, J. X& v7 H4 q- L' f. i6 _# f
CString translateUPnPResult(HRESULT hr);3 V2 { x6 i9 F! s" {7 h
HRESULT UPnPMessage(HRESULT hr);" s9 B) _/ X" e- B7 I5 s4 [
9 n3 j* ?1 L& h1 t# r/ x2 j! f5 A) o; g2 z* ]) V# ^- `
class CUPnPImplWinServ: public CUPnPImpl
" s- F% w9 i, T{
$ v# ~' \* H/ k8 w) O3 l | friend class CDeviceFinderCallback;
% ^/ M' t% N+ v4 z5 Q3 |' t% C. ^ friend class CServiceCallback;
' r& ?6 ^3 x( f& p6 u// Construction& K2 }; ]5 W! c6 C4 i
public:5 B* S3 L8 K3 s% n' f8 z2 A0 N8 c% N
virtual ~CUPnPImplWinServ();
, n! i) p# G" l; s; p* i# l CUPnPImplWinServ();; x, A3 V) S" f- C) \# L: {
0 |3 E+ `9 ]0 I+ i4 u6 l; B
- _+ m6 a5 K% o$ Y! u6 [* G a virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } f( C+ n2 G+ u
virtual void StopAsyncFind();
, a2 [7 c/ k/ r/ E virtual void DeletePorts();
. J) ]- `* Q& G L/ r virtual bool IsReady();
- V& b. c; i0 L* Z) A virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }4 L& w. F, o5 S- v' X* y! e
D% ~5 t) G5 u* h) L' I: w
. p- P) L: r# r9 o // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)4 M( _/ c+ R n% U0 V" v$ k2 @
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later: {' J) l& O& g. Q( ~3 z- b
virtual bool CheckAndRefresh() { return false; };/ H9 p0 W9 T/ i9 f7 A$ F
3 h+ i* b- u" m3 l! G& `7 C6 G; S& A$ f; [
& g+ d) f, S7 c* e6 M0 }0 q; ^2 t
protected:
( k* b8 h$ J& D" a8 n! f void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);. \$ W6 m( i) B$ Z
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);; k. U# ~+ H8 N- i) U
void RemoveDevice(CComBSTR bsUDN);
; A9 E- m G0 B, n: ^ bool OnSearchComplete(); e u& L8 ?0 ~2 K
void Init();( D" k7 ~. j9 S/ v4 i
# Y( ]. [. C$ X# V- \$ F5 @
" J6 m7 q: V5 D; u5 l4 E inline bool IsAsyncFindRunning()
* H. |7 _' K) H5 _7 ^- Z; A) N5 P {
2 f7 l* [$ _2 x3 v/ _3 @ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )8 g1 I. n j) [
{
6 l5 K& f6 ?. e2 r1 D } m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
* h6 s" u+ ?! P$ e# j m( { m_bAsyncFindRunning = false;8 F/ @1 e9 q1 {) b
}1 G7 g1 O, g, v P
MSG msg;: I1 M% x5 S/ d
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 ~& j6 |' M" c1 L4 M$ V/ y& ^
{
$ S; ^2 p$ e7 Y+ c8 F TranslateMessage( &msg );
9 E( V- O: ~8 d: y* K( `2 } DispatchMessage( &msg );
' {5 M; V6 u; q: o }: ?5 |9 t3 U Z$ m3 T
return m_bAsyncFindRunning;
' n2 b2 w, N5 G, ~ U; g }) i/ i, ]6 ]" Z. q
0 q# _. z& i3 d/ V
; V( ~8 Q# g- _ TRISTATE m_bUPnPDeviceConnected;; s6 _+ |" U1 W0 h1 G# Q$ [) B6 M
1 E/ d5 d7 \3 {: n/ i; \
% U6 q% u n; ^
// Implementation0 \3 V) P7 m4 s
// API functions+ d2 i) l/ m( U& }9 ^
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);0 T; k g* ^- f* E6 a
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);* ]7 O3 C5 ?( V( S8 g+ {
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);8 E: T5 g- Z8 v# ^
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);. Y3 D- a6 y5 h# t/ F) T, ?& C
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
V4 K. w6 }- a( m0 A BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);2 I H% w# ?8 I0 \- E
4 a. q! ^: u& C: v7 ~5 ~: c9 q, v" T' K# ~) ^) I6 c; k6 }8 E
TGetBestInterface m_pfGetBestInterface;8 u, d9 J, ~0 H$ K( s
TGetIpAddrTable m_pfGetIpAddrTable;+ b' z! [) i# i" x
TGetIfEntry m_pfGetIfEntry;
1 l$ n6 w6 O& U! P5 Q3 F
* L4 B$ o( ~% k' f+ N# l/ e# b Q& e5 a- A
static FinderPointer CreateFinderInstance();" W( q. N. k* `: w3 Y
struct FindDevice : std::unary_function< DevicePointer, bool >
* Z" u! T' {+ H {" S" T2 \, T. e' d( A' d! I* D2 p
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
# U+ q$ G+ ^" h6 G7 T: I' R8 d result_type operator()(argument_type device) const4 c1 {3 g1 t8 H
{7 Z9 J$ [. X! Z) N
CComBSTR deviceName;
: z; Q) |. o9 Z, B HRESULT hr = device->get_UniqueDeviceName( &deviceName );( b5 G, ~9 } ~" m+ i8 o* z) i
9 X% {& ^0 o O% p/ o/ }4 w q' V' w9 V" J9 U" l, v
if ( FAILED( hr ) )
! p. }: `( @8 m& D$ U8 K return UPnPMessage( hr ), false;! H/ k4 n8 `& O5 ]
. y' c% | \& |/ j2 X
; E' C6 B4 j. [3 }
return wcscmp( deviceName.m_str, m_udn ) == 0;
A1 H* k) R' f0 t' ?) L% { }
. j4 W9 I( w$ a* o CComBSTR m_udn;
b5 Y, M, M8 u* [5 [5 k+ u };. d h2 w& N. }5 d; K
: w" Q# G7 k2 T
void ProcessAsyncFind(CComBSTR bsSearchType);
8 t M4 ^( q! z HRESULT GetDeviceServices(DevicePointer pDevice);2 {- M+ n! A y$ D
void StartPortMapping();% `; D3 d6 |/ N7 D
HRESULT MapPort(const ServicePointer& service);
6 _% S l% O2 I3 ? void DeleteExistingPortMappings(ServicePointer pService);
* Y7 e% @$ `/ B. I void CreatePortMappings(ServicePointer pService);; G0 s% L! H, Y! C
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
# a9 S3 d% `* L. [ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
5 w" s( g( s$ S7 ? LPCTSTR pszInArgString, CString& strResult);
- H9 }# \" L+ T. C* D void StopUPnPService();6 {; \0 g+ t b% E
( {; \2 T7 t4 E# D6 m& U. z2 @; m, O" N5 X' G5 P
// Utility functions Q- h o5 ~% U& J) u- Z$ z J
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ ?) q9 K; }$ \' v
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);% P% O7 m) V }' [6 F9 Q$ w! _
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);. Q/ g4 ^. w6 [; ]8 h! L
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
# I- g0 k* I) |3 S HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
. X" {6 v/ t2 e6 h* ~ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);: O5 r. T4 {1 L" l
CString GetLocalRoutableIP(ServicePointer pService);" T8 Q( e0 G% L& P# ]
5 p/ F8 Q o3 L
+ ~: M4 ~5 F; h; t
// Private members' s% g; Z5 G$ d* b9 ]
private:
4 [1 [2 q- l( W0 V# k5 g, [ DWORD m_tLastEvent; // When the last event was received?0 B! ]# _, t' ^$ y5 l
std::vector< DevicePointer > m_pDevices;' o/ P- s! W# {5 ]. Z9 u
std::vector< ServicePointer > m_pServices;
0 x) M$ t" o( n6 H. v FinderPointer m_pDeviceFinder;
4 \$ \9 P8 T3 |; c- u# ~: k6 E) { w DeviceFinderCallback m_pDeviceFinderCallback;
( I4 a' ]% k, ^9 J& ^ r ServiceCallback m_pServiceCallback;
1 S9 _; [ n9 |
% Q- N, Q. R0 F. W( `; Y8 o/ L1 `( o, h. I/ i4 z( N/ ^1 V
LONG m_nAsyncFindHandle;
; H# j$ h2 K X) X3 E& i9 r bool m_bCOM;( E7 G, e% }& |- L2 C
bool m_bPortIsFree;% l% M# p: H8 w
CString m_sLocalIP;3 k. a5 X+ A# ^3 t: [" O8 }, Z) z
CString m_sExternalIP;, F8 [: u% U0 S0 _! \/ d0 {- G% H
bool m_bADSL; // Is the device ADSL?$ i" @: I5 X! D% n. d
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?# }4 r7 |: ~; k% f5 t
bool m_bInited;0 i' o! W& ~! w: J: d
bool m_bAsyncFindRunning;5 p1 B9 G& Q7 D& J7 h8 t6 B+ @
HMODULE m_hADVAPI32_DLL; M4 k- T. T+ M5 E7 T* O4 I, p) L2 |
HMODULE m_hIPHLPAPI_DLL;3 R9 \. ?. Z# i* D/ A# w( D
bool m_bSecondTry;7 V7 c8 z& |; V
bool m_bServiceStartedByEmule;
; y6 z0 q& j# |0 t6 r bool m_bDisableWANIPSetup;" m3 M# r/ s8 `) J
bool m_bDisableWANPPPSetup;
6 V9 L; @8 e( u$ C% `
" [$ |7 n" u2 A
) Z- ]& t. K, a8 k$ q, d};
7 Y. Y, T! [$ ?$ {1 G/ f5 _* e& i( c
% ^7 \( ~: u4 `; C$ A. ?
// DeviceFinder Callback0 y. Y- D$ r# M% f
class CDeviceFinderCallback6 ^' P& B' j1 [0 L. }
: public IUPnPDeviceFinderCallback" v5 u; V/ t& e
{) N; ~" D( S+ j# o
public:9 \+ ]* T5 z% Z& P- Y+ o1 e
CDeviceFinderCallback(CUPnPImplWinServ& instance)
) E& Q" N3 g) ?; j1 F6 }$ D1 ~% q : m_instance( instance )
1 o( p7 _! d8 h { m_lRefCount = 0; }
& E- }2 z* |$ H: W
5 k1 V6 G: N4 D
9 G5 p' a7 k$ N6 D8 t5 n2 N9 z STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. ]" b7 a; B+ y( B9 T
STDMETHODIMP_(ULONG) AddRef();
& v- ]" K6 Z; c/ `5 ^! V STDMETHODIMP_(ULONG) Release();4 `* R1 c5 H+ I1 Y9 I5 L
8 I" L. Y3 Z& o5 I- z
3 ~$ o: q, w5 r2 X) N/ L: Z( F
// implementation" J6 j( n: J1 Z5 t: f1 E& W
private:
% {& o+ n2 a) @8 e HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);/ f% t* N* B4 @5 q, D( q( V
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);( w0 [% h+ Z# J8 Y, L3 _
HRESULT __stdcall SearchComplete(LONG nFindData);1 B) H+ u) _7 @
; ], {% m3 A# X( C, I
* f5 A- T* [1 ^# c3 _- A& U; K% Aprivate:
; ?! H z7 L: a$ ` CUPnPImplWinServ& m_instance;
; s! p4 B4 D/ |- I. g LONG m_lRefCount;
- d; c, l6 U$ Y+ E};
3 j& Q2 t4 Q3 `8 o. z& z0 Y* \5 [. ^! |6 t; W7 x, y; F
/ a( M9 o" g- w3 j4 n// Service Callback - l; W* ]4 t5 d# U
class CServiceCallback& t: Q* b: S* C" U8 }
: public IUPnPServiceCallback3 O1 o& I1 _9 l/ o% k
{
' m8 w* y2 h; g' u& E. Bpublic:; L. B+ Z& b' E6 q0 i
CServiceCallback(CUPnPImplWinServ& instance), |+ s/ C) N" B. z' W
: m_instance( instance )
* l9 i" Y$ \+ J d8 L- ]* J8 [ { m_lRefCount = 0; }' v$ w5 i$ M1 ]' x" R. i, p, @
# Q- R. V6 x9 r" i9 l2 J2 W2 ^ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
6 R3 d4 i6 r4 Q0 Z STDMETHODIMP_(ULONG) AddRef();5 q' C2 p/ n4 J1 W( S3 b
STDMETHODIMP_(ULONG) Release();/ ?# N! p: e: O& [& G0 ] w
+ }: j* N" }" B. B8 H, E% ]
% n1 E3 s4 A8 [: q1 B// implementation- u% W9 [6 F) t" m) E
private:/ F4 ]5 @3 G. K1 Y L8 Q- W. @
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);' F2 w& n% Q' Q) Q4 e1 H6 d
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ y- r8 w4 o; y' A) W. _1 F
: R; u Y$ p O1 U
# L, o2 ?& G5 }) `$ ^) ~* aprivate:
1 a3 B3 D3 T' `: s CUPnPImplWinServ& m_instance;
1 }0 R$ i* {' r8 z4 @2 E+ | LONG m_lRefCount;
; X6 I3 z$ e: j, f0 R! S. m' k};4 u& v2 `! e4 ~. o' R) U1 H5 o
4 ?5 t& G4 X% E9 v( Y5 M5 {# Q6 c, @
/////////////////////////////////////////////////
2 k$ z' ~0 S) G. U' k, L! @; N
2 D8 q' C, O( W/ i使用时只需要使用抽象类的接口。
$ v) U" |( ^& cCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. F+ O( _3 i+ c
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
' y. ]$ _) p: a b PCUPnPImpl::StopAsyncFind停止设备查找.
( p6 J; i' }8 B) dCUPnPImpl::DeletePorts删除端口映射. |
|