|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
; S) i2 ]1 z& X& X- e7 R/ q/ B" g8 _: h+ R& a6 D& S, p, m
! P' M- K3 i8 e9 P# U4 B5 T& j
///////////////////////////////////////////
; r3 {5 O1 s5 S6 `8 S3 d; x$ n8 V//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
w, L- ]! E' t3 E& d0 ^3 `8 {
6 ]2 i4 @& Z# u; K4 |
7 |) i+ G8 D0 Y" Y, j' b#pragma once
: O) S4 A9 ~' l2 @4 `; c#include <exception>4 l) j5 S% e3 e- A9 r4 J9 ?
, ?; y4 D) R8 t, l% G9 J# T( ^2 J" ^% L0 V
enum TRISTATE{
Y9 \3 b; }4 e7 L" ^* I( }4 v TRIS_FALSE,/ J/ q& G2 o }
TRIS_UNKNOWN,
* q8 Y5 w8 B# x: p& S$ U TRIS_TRUE3 j6 Q! M$ ~7 y' c$ M& o3 D+ L }
};6 @* S6 k( d R0 i
8 A# W- v( I+ \# W+ b% s
2 ~- c8 a" ^7 N. ]5 O: |2 D0 menum UPNP_IMPLEMENTATION{
( r8 ]+ G( A! r0 K$ n; z8 } UPNP_IMPL_WINDOWSERVICE = 0,) C+ e. n- D$ g& `
UPNP_IMPL_MINIUPNPLIB,) M$ R# O* O, Q8 M& N
UPNP_IMPL_NONE /*last*/
/ ^. G) x2 H6 v};
' J2 X- ^* W. ]! }0 a+ J! L7 l* N6 a! H- |8 O, ]
! L1 M; K, J. f
" ~9 v8 E( Z+ s6 H2 G% | _/ ]& ~+ j4 {. ]1 v
class CUPnPImpl
3 V6 G6 i, B7 _" ]8 Q{4 H+ F4 r# x# r- c
public: J3 V+ x% j' a$ k
CUPnPImpl();
5 m# D* R- O1 s4 N4 M virtual ~CUPnPImpl();
' n1 |4 Z' S0 A2 A4 g7 \) J& z struct UPnPError : std::exception {};
# o3 f8 a8 A8 Q& i* n5 X enum {+ R8 N8 A/ M4 t1 X9 ^8 _, R
UPNP_OK,
% q7 v- R3 h0 j* ], y UPNP_FAILED,( x0 b/ o& o2 ^; M1 Q" g$ B
UPNP_TIMEOUT. n7 ]2 v0 O6 G& p' r; X
};
! {9 J) W- v9 E) q! W0 M8 U# b; Z$ H2 T, k+ E8 ?
( R1 Q( S8 Q8 g8 L
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
" P# ^: y0 x4 o: p; G" u4 W+ x virtual bool CheckAndRefresh() = 0;5 r& D% t8 F+ \
virtual void StopAsyncFind() = 0;) X4 {' u4 |* d" D u9 K6 T$ S" k o/ V
virtual void DeletePorts() = 0;
, o) I' I' U% A1 A! F virtual bool IsReady() = 0;6 l6 c; k" h$ ]' J- p
virtual int GetImplementationID() = 0;
! G6 l8 Q, R- x 5 Q9 S& y" {- O7 E) E: N
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping. p" v6 l f+ z) X! l
6 S# r E' {0 P& [" g/ Y* Z, h/ {
void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 I2 E1 g; m4 m$ ^
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 a' P) N" y; S$ i+ K; S3 h uint16 GetUsedTCPPort() { return m_nTCPPort; }
4 w* R# S! `+ q+ b, D/ L* ^! Z uint16 GetUsedUDPPort() { return m_nUDPPort; } . h- F8 a* L; l* A
w3 D! _7 \" Z5 Y6 Z5 D- D1 Q w: @9 ? T- C; @
// Implementation
! T& R# \0 W( u, S; h% xprotected:9 o5 I# Z- [- \1 ~% G1 \7 t
volatile TRISTATE m_bUPnPPortsForwarded;; B7 c+ H( G3 P
void SendResultMessage();/ e! o5 q8 u; i, P8 Y5 C
uint16 m_nUDPPort;) {, z) ?( p( i. F
uint16 m_nTCPPort;% }, Z3 ~& }1 @, V) A
uint16 m_nTCPWebPort;* D7 G& P* G& v" g! w
bool m_bCheckAndRefresh;
5 L5 ?" H2 k$ P* d* n% @/ g+ V* x3 X$ }) I
3 R7 E) O( R5 m5 u1 o
private:
" @* j+ W$ q- M! T HWND m_hResultMessageWindow;
5 H; ?3 c0 O4 Z0 f UINT m_nResultMessageID;0 z5 q3 I9 v; {& c) h
- U, T8 g5 n( l' U
* g9 G5 m- [( |. Z& X};) x6 M( k* s" {& d7 }( f! L5 `
! t4 A6 q5 ~7 M# b" y# v! J9 B
2 D' V2 {. [: y' a2 E, e$ w8 m& H8 j" y// Dummy Implementation to be used when no other implementation is available( |- I8 L, |5 x8 c! ] f2 R
class CUPnPImplNone: public CUPnPImpl
# X" u4 X1 g5 {: t% K; z B5 w{
9 x$ u& x/ i, t$ v# zpublic:8 i; F% m2 F/ H: ]# F4 e' u
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
* ^) Y. S R* j5 f/ }$ S+ _ virtual bool CheckAndRefresh() { return false; }1 N- I( `6 K) n+ c9 G7 g
virtual void StopAsyncFind() { }7 c2 L* s( ]9 ]
virtual void DeletePorts() { }
0 ~" }; V5 j: y* E5 s1 D1 r virtual bool IsReady() { return false; }" |* i/ {" X- D% k* n+ N! V
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }0 m' n4 z( Q9 Z; v# _
};
- d+ u4 g/ _& e. L) x, l0 Q8 q" @3 v
5 ]4 L2 \, [; m$ z/////////////////////////////////////! L( |7 M d' R; P9 x1 Y# x! E
//下面是使用windows操作系统自带的UPNP功能的子类
0 Z% l; V& H! G9 ~4 G2 X2 g8 G, D& }, f
) j ]$ K+ k# N+ e+ N* U#pragma once
! R7 [# \' e* M" p# a& ?#pragma warning( disable: 4355 )
# x" q4 ?: O* _6 \& V$ |% R( K8 Y8 U) N8 i/ X1 [- Q6 Y, E9 b
0 t5 d0 Z% x* |) ^8 C% S/ f#include "UPnPImpl.h": }7 Z4 ~- Y, J; ]6 Q$ m) T
#include <upnp.h>
; T/ N \. }) C2 t: b$ |#include <iphlpapi.h>
) W* N( S: [7 m4 w d#include <comdef.h>
% V; t. _( `! M, ]/ j I#include <winsvc.h>
( r9 U r0 X1 P
. {8 {6 w$ o4 R3 j2 V2 e1 k1 P. m
8 x( E1 }' R3 P7 J2 D#include <vector>
3 N. k. _/ e/ _9 ^6 {- m* b#include <exception>
3 |; p% V6 M4 s9 K7 ^9 V2 F#include <functional>
* c0 ?. w; |# Q2 h& |
. @6 `3 u8 r; i; k1 S. t, `7 q; ] o# }1 o3 h7 D8 `9 F
- B( V& ]* P" v; }/ F) {" c+ z( d' i1 F& A
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
& r5 {- X+ Y ^7 D6 m+ G0 U5 [, Itypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
! e$ d" w' P1 H! N# f- Y3 \typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" w7 c1 u8 B! x% H
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;: n! R# s- Q" X9 L M
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;+ n8 W2 E! h! e: ^, C
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 b/ b) r' R' Q) n' ~typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' R- Y" l0 d8 M+ f9 }" ^
5 E( U5 `4 @0 L4 S& Y4 a$ k8 W
. v4 Z- p6 _" K- m9 m) T) d0 b+ l0 Ktypedef DWORD (WINAPI* TGetBestInterface) (
8 A* w# f3 D' v! T4 N IPAddr dwDestAddr,) m7 a$ g2 n4 Q% }
PDWORD pdwBestIfIndex1 r# `! J* s6 g- Q, q& u* p8 o7 W
);
* O4 e, ^7 C2 C& X- q) `- T- `
3 B1 \/ Q# x9 ~3 I
; c1 U5 Y3 j4 S0 ltypedef DWORD (WINAPI* TGetIpAddrTable) (
! a- E; o2 A/ W0 |% y PMIB_IPADDRTABLE pIpAddrTable,
# {+ a% T' ^& U# S PULONG pdwSize,* `4 ~9 E0 W9 Y" K5 u+ Z8 B6 D( Y
BOOL bOrder
f' }) u7 A! G" A! M/ W! ]1 a) G);
* u* F2 ?9 D6 ], V+ ]6 ]4 c& e: g% ?9 r
: J" J) `4 J( t0 z- U! y0 p8 Ntypedef DWORD (WINAPI* TGetIfEntry) (
6 d2 m8 Q- |6 W4 F PMIB_IFROW pIfRow/ L6 Q% S+ o9 b; [$ v
);, X9 ~# Q$ b. w- \2 r+ @
0 w' _2 ]3 w; K
' D8 U! r( X8 }CString translateUPnPResult(HRESULT hr);- p2 j+ F2 `0 l! h7 V6 a
HRESULT UPnPMessage(HRESULT hr);/ n( u% ]+ ?2 s, V: [ `
/ P' p: ]( c( ^: U( S9 x X: h% R( O5 E: L$ J, M4 M- \2 I: H& t
class CUPnPImplWinServ: public CUPnPImpl& T% @8 O) T+ r. f! g( Y8 P
{& _, Y) w( L* c0 ?9 l! u( ~$ z
friend class CDeviceFinderCallback;! @! C( b$ S: I$ e0 u, S- v
friend class CServiceCallback;
% l" ?4 Y: x( f6 Z$ i// Construction
8 y1 _$ q S& h9 X" a t' Qpublic:. A: R2 w x t- i! Y0 d
virtual ~CUPnPImplWinServ();) P6 }* l/ x$ f! o* e3 U
CUPnPImplWinServ();
# V2 T9 J) d* m% _2 x. ^( y! f! R# h. S
) ]; D' R" O( L* d9 Z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
7 N* T1 t5 D1 C, D2 V6 t virtual void StopAsyncFind();
6 ?7 W! q' l$ u; T% {6 C& f virtual void DeletePorts();
4 s' J9 a6 P& T7 a& U virtual bool IsReady();
2 w5 }8 ~3 B. W$ `/ p virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }% f6 ?" j0 z. V: X, K$ I* |, m
! ]4 L! [0 W4 p2 G' Z/ t* i6 g7 s# I3 T3 N8 [( s. N
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 q3 r( L1 N3 s4 G& f0 e // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
4 v( o8 q2 T- Y% P2 H. Y% }! h virtual bool CheckAndRefresh() { return false; };
! d% U! q% P5 O: o4 { m# o e% a, q2 J3 f
9 `4 [8 x$ D8 \/ ^2 p- uprotected:
" i9 u; V/ j$ q( p# [ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);. M! k$ S: K1 F1 q
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
% `6 C" h7 Y" U, J# S+ L! a* G void RemoveDevice(CComBSTR bsUDN);
4 C- n4 Y+ ] Y# z: ]4 h bool OnSearchComplete();
& K* a3 V4 j& g4 } void Init();
5 w0 y. K8 [1 y0 w, ?, r
# d4 w2 c! @) X- L5 c, n9 W& ^
; [" y {. L& q3 [7 r inline bool IsAsyncFindRunning() % p3 b5 J( L* Z" {/ v) T
{
! M; |5 h# P: i) [8 o! V if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )0 b' Z7 K4 M! Q# n- ?$ e/ Y
{7 j) n7 J8 V; a4 H
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
) j+ Y* P; K( s m_bAsyncFindRunning = false;. t- I* n+ ~7 h. a: H; i1 M8 w
}
; ?- B4 P& I0 |+ b MSG msg;
2 {; G8 x1 M- u1 J) [2 G while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
) {0 U" c1 V9 S: U) g {
; c: I, f% U2 N" u TranslateMessage( &msg );9 l) e/ m, r5 a$ _' ?
DispatchMessage( &msg );$ Z8 ^3 G7 }# S; p- w
}; J r! O* F# y8 N/ W
return m_bAsyncFindRunning; |; r- `: {! e5 h3 f
}
5 @2 M. E4 K, X
, ?+ O3 {& S: t
: p3 i8 N# w% b! d TRISTATE m_bUPnPDeviceConnected;
# Y: q2 J- p6 n7 M5 {
) O& C l4 n- {; G2 W9 w( x" Q9 V8 n0 `0 X+ a( ?! P
// Implementation: Q; b. m: _. B- o
// API functions+ N! s9 s7 ]0 \0 F' c8 c
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);1 E0 r$ l/ B: @+ I! Z7 T m
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
q! }# F* i8 @, @# O3 P% {& |5 z BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
# N" e" P! e4 j" p- s BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 g% c; N$ k( _0 p8 u$ | ~- ?
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);7 J% M+ b/ A( e7 A* u+ [. v
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);; U* \% d1 ?9 ]
: _+ ~9 T4 F' g8 U" [: z8 d7 h
5 [1 J9 u$ Q3 m) B) V
TGetBestInterface m_pfGetBestInterface;* k. R! {6 {4 [+ }
TGetIpAddrTable m_pfGetIpAddrTable;& W9 Q, F6 B% C3 I
TGetIfEntry m_pfGetIfEntry;
) {! C" t& K; J- k, @; G3 r
* f! v% z' |/ ^" C' E* a( I4 f2 J% ~* {! Q" s
static FinderPointer CreateFinderInstance();% y7 \ I3 d8 m# ~
struct FindDevice : std::unary_function< DevicePointer, bool >- z, m$ U- C N
{
( Q5 w" O" [( f) B; A9 _0 v FindDevice(const CComBSTR& udn) : m_udn( udn ) {}- J: \( G, x4 O3 Z+ u9 z" o
result_type operator()(argument_type device) const
8 J2 Z/ n5 L/ l! S9 Q {5 H2 W) }4 ^( s3 r0 @% N- ]
CComBSTR deviceName;
2 {! I5 w F) h5 F HRESULT hr = device->get_UniqueDeviceName( &deviceName );
6 ]2 m) V0 V; ?
W0 q6 z$ s' c: Y! B3 Q1 w
, O2 ?: T8 m8 s D if ( FAILED( hr ) )
2 |6 ?* o# C0 _9 g. V* L return UPnPMessage( hr ), false;9 X0 H( p7 x+ _" T# {: d# f4 [
% A3 S+ I3 o6 b6 k' E) T: r- c* |$ c A* n0 ]# k( }+ p9 |
return wcscmp( deviceName.m_str, m_udn ) == 0;+ v( |7 K1 R9 r4 }* C3 P, p
}
3 b0 J; ]/ I7 S* m CComBSTR m_udn;4 }3 e! S5 h! o5 X9 u
};
; S7 K6 X1 r" T" \9 h q+ o : i6 ]. e, n( E$ c Q; p; K( i# s3 J
void ProcessAsyncFind(CComBSTR bsSearchType);
- c7 Y3 ~) I1 q, L$ e HRESULT GetDeviceServices(DevicePointer pDevice);
" Z! D6 g8 }' K void StartPortMapping();' b+ W% F! @; Q4 Q! r* p
HRESULT MapPort(const ServicePointer& service);
6 f3 I( r8 C G; c) _! B/ n- R1 H void DeleteExistingPortMappings(ServicePointer pService);& X0 \/ t* E- g" V2 Y/ n
void CreatePortMappings(ServicePointer pService);
) [# Q3 `$ V% y; F% V$ r HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);9 G+ A, E4 {' N7 G) K, w6 C4 Z; m
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
) f) M) ]3 e9 H P5 l LPCTSTR pszInArgString, CString& strResult);9 {3 Y% k+ N u8 z. k6 [
void StopUPnPService();, W* @! [/ g- r
- j8 x: k8 E6 R$ h1 E5 I0 @" I
! G7 ]9 B( G7 e- u: J
// Utility functions% H. L+ l; S) [/ @ @; R1 C1 l! O
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);! ~2 q2 _! d* v$ Z
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars); X6 ]1 E4 j$ l5 X
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 w- @& W9 e: M# C) F* J
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ ]8 [2 j( x9 F HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
6 k4 [/ `8 q O2 R. O6 c/ D. T HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
$ _! D1 B# [% u! i2 G) n CString GetLocalRoutableIP(ServicePointer pService);
! W8 l- B( | H$ Y- U* o: E( Z# i7 ?, K
9 U: y, q$ S+ y
// Private members
9 \ t! E4 T- `7 Wprivate:: `( Y9 j- y2 V4 {& q9 s
DWORD m_tLastEvent; // When the last event was received?
# n) h" e0 ?6 ^, K/ `. V# N) K' k std::vector< DevicePointer > m_pDevices;
% C! J$ V+ {- V+ E% |' P2 z' Z) Y std::vector< ServicePointer > m_pServices;7 W! j8 N) Z( {7 e/ c$ K
FinderPointer m_pDeviceFinder;
, U# j& t0 e9 R0 l! i! E DeviceFinderCallback m_pDeviceFinderCallback;
& v8 i" d0 S# p d2 K9 v3 o' r ServiceCallback m_pServiceCallback;9 a8 F C1 Q. w9 _. @/ g; O
; m7 K6 ]$ O4 @% n9 m
: n- {& O- N# O& d# R
LONG m_nAsyncFindHandle;
9 {) [2 O( h3 a/ |5 _ bool m_bCOM;8 @' l8 ~6 h" L; c
bool m_bPortIsFree;7 S4 a6 |' {0 z+ b
CString m_sLocalIP;5 a ], M; i9 {5 \
CString m_sExternalIP;3 F9 r8 a4 k- d! U& L) c) c
bool m_bADSL; // Is the device ADSL?5 \- [( i9 [$ y% \, e/ g' K
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
' i( e) V& E2 D' Y2 P( F bool m_bInited;
" H8 ^1 [5 }6 y: |8 q/ j bool m_bAsyncFindRunning;1 Z8 a \# F$ ?, z2 Y: c5 `
HMODULE m_hADVAPI32_DLL;' O3 y @. ?$ a z$ G" F
HMODULE m_hIPHLPAPI_DLL;
* O( \& a d9 }) i: J* h- S bool m_bSecondTry;
. w$ \9 S/ C! v c bool m_bServiceStartedByEmule;1 [2 z# F3 l; n% ]* y" s7 ]) {/ \
bool m_bDisableWANIPSetup;# k3 o w& I, B5 x1 e$ Z/ k, m
bool m_bDisableWANPPPSetup;* h+ S8 {% o% M: f
+ L" P# ?* G5 J; n
4 l# h4 q. |; Q, }' v* d
};$ f4 ^+ M# z. x+ n2 Z
. u8 o! _$ M2 }& _
! S8 f" x9 l, H1 `5 m% O// DeviceFinder Callback
/ P- e9 w0 b* n1 m- r8 r. c9 ^class CDeviceFinderCallback% J* m" t4 T& r% j
: public IUPnPDeviceFinderCallback
4 D& u! p `+ {/ a$ p{
( h5 h9 B/ h- ]) D# Wpublic:0 b U* }, S6 c* w% y3 [3 c
CDeviceFinderCallback(CUPnPImplWinServ& instance)# L) W7 n8 n9 [6 \% r1 S7 Q7 P
: m_instance( instance )& p) Q* x3 I! a9 F
{ m_lRefCount = 0; }
! k! q$ ?- O- W% E! h. U
* \7 H- l$ S% [3 j& j+ v" y0 D" H* x7 z/ d3 k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. R" C. c1 q3 T( k1 S
STDMETHODIMP_(ULONG) AddRef();2 H& W: ~* i7 v$ C
STDMETHODIMP_(ULONG) Release();
* L4 n3 T: A! k4 A7 K6 T4 y
9 I% V: |, E+ F, W! o1 i
: t5 {! v# z7 `' u( F0 i8 I// implementation, m5 B, Z% N& a* R _! n O/ n' a
private:
+ H' f1 Z. P+ `% V( R5 s HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
8 q$ a1 K5 s3 z4 @, l/ M HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. y* w6 v( _- X7 \6 u
HRESULT __stdcall SearchComplete(LONG nFindData);% v! g" C. T" X. e+ S7 G+ M% P
4 I( U, u- `$ s) I; Y3 v
5 n$ u0 H- T, |3 U. Aprivate:% g4 m: @5 L# @! Q
CUPnPImplWinServ& m_instance;
: }9 o8 A( ]9 |$ J! R! } LONG m_lRefCount;
) C- P6 I: V2 @3 ~9 a};- E* B( y! I0 _9 e% i; k) h4 q: {
1 ^& g7 N a1 K% T
] z9 ^' U- W2 ^0 k' M% u// Service Callback
* s* P: [) e- j" K( u; aclass CServiceCallback
7 e# ]+ G2 A1 I0 @( h: h) ] : public IUPnPServiceCallback
) F6 @+ R- E: A9 G9 r{/ S$ w$ d* [3 |) c- e
public:5 o5 L! D& K9 {! `
CServiceCallback(CUPnPImplWinServ& instance)
; c& V3 y4 Z h9 u7 Y) y* e1 T : m_instance( instance )
! n1 b9 m6 w9 I; d D# x) B { m_lRefCount = 0; }
0 q9 R7 U* _2 O# _% I+ U 9 Z! }* e- B/ N0 \' t% X
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 S8 Y$ R4 e: I& v! F STDMETHODIMP_(ULONG) AddRef();2 S& K. O3 Q3 h4 ^8 R& P( B. [
STDMETHODIMP_(ULONG) Release();2 l( _, }1 m; n
6 X1 ]! i% x( Q2 K
9 o# g1 x& W; \) j// implementation
' Z# c$ U! ?! N5 jprivate:2 S) `. h* E' l! g6 C4 ?$ M( `
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);& G( R. r0 n7 W: T$ m' V% k
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
% H% M( f" J4 a" X5 N7 u
% z: D/ F$ z, e2 p1 p9 s7 J7 j; D% k& m! f
private:, E; W$ {6 ^5 p4 F1 U
CUPnPImplWinServ& m_instance;* M, w R( k2 w7 Y4 |5 `0 J
LONG m_lRefCount;
+ c$ S- {& ^8 F% H! D};) i- V& j ^; Q! R' s
/ o& z3 L" P `7 D- x1 C y
8 `( W3 Z/ O' @3 `. Q; B% g; k% ?/////////////////////////////////////////////////
+ O+ P7 P1 }3 R
5 S r* T" }2 t6 f+ [6 r6 _+ }6 \# E. I
使用时只需要使用抽象类的接口。" T3 t( a7 [" F1 a
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
2 e3 E) T0 Y3 @# F. N9 GCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
( w* n* m" t: d8 \! MCUPnPImpl::StopAsyncFind停止设备查找.( F& V9 V0 P Z, {" C; `* N4 Z$ x' k
CUPnPImpl::DeletePorts删除端口映射. |
|