|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
) G. a- W9 b# z- o9 y7 Y0 e
+ W, P; H$ `: c) w
$ l1 e$ B2 M& h8 u3 }% ~* f///////////////////////////////////////////& ]" b. f3 x# P' p
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.4 A z' O$ E- j, `. x
6 Z0 O8 x- Q9 g5 X/ E7 ^# T9 v8 {8 G; A: @
#pragma once
0 {# h* c- ~" x5 u% r: n$ t+ S4 M#include <exception>
) e6 P+ L* n' d9 b& u" O: j9 U; O2 `4 y$ T! S$ o F! n
/ H' |6 E( ?! b6 o, C enum TRISTATE{
8 W& E0 Z0 e, a1 g1 h! ^! ?% @+ ~ TRIS_FALSE,, [& D) [( \3 @5 ?1 D
TRIS_UNKNOWN,3 E' G% \, s5 ?8 N+ k& D. A
TRIS_TRUE- T, f! S9 u, M
};! Q# s0 r( w6 R, w: z
2 s7 I) a% R6 d/ h7 q
9 I6 w4 y i3 I* V
enum UPNP_IMPLEMENTATION{( h9 P/ b$ A+ ^+ c/ a
UPNP_IMPL_WINDOWSERVICE = 0,
3 n' s6 Q. T6 t& N) H UPNP_IMPL_MINIUPNPLIB,
4 n! R4 V2 B9 N UPNP_IMPL_NONE /*last*/( z8 V" I9 j5 t2 e- ~
};( p8 A O" U, ^$ }7 ]
]( l1 i# L8 l Q$ Y5 z2 j! X) s$ p2 D7 t2 L6 t/ U1 X
- y9 _& T3 m, e6 k. {$ F8 p; P* x
7 _% o4 ?! Q& `7 pclass CUPnPImpl: V% [5 L9 Y$ t- m! c
{
) J8 f: M& A; N2 t$ fpublic:* |( ~) f0 Q7 N$ o
CUPnPImpl();; v0 \. @3 G4 [& e8 f/ l, Z
virtual ~CUPnPImpl();
" C6 m$ O! T% A% j0 w7 w3 d struct UPnPError : std::exception {};
, Z9 l6 Z+ G" n2 u" ~ enum {
2 e# Y) W+ [& T6 t w- H+ W# A UPNP_OK,# m1 Y5 x$ x' g7 P' L* i
UPNP_FAILED,
. [# J' ?" u# Q. _3 M UPNP_TIMEOUT
# A4 }$ b, b/ B };: D. `+ j8 v4 J9 Q& m
/ }4 C/ p% e1 o, J/ O. O
3 }1 g) R% M" k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
1 | f% u7 G( L/ [ virtual bool CheckAndRefresh() = 0;9 U5 I/ [7 M) d5 J7 i
virtual void StopAsyncFind() = 0;8 M4 V; M& `2 f" b% o0 B2 b
virtual void DeletePorts() = 0;$ S, S' m/ F; V" ^" |% z0 W
virtual bool IsReady() = 0;
/ D4 Z7 q9 z& G: ^1 N8 J1 f* ~, ] virtual int GetImplementationID() = 0;4 X1 H3 A7 y6 n& a$ h
6 K0 D$ N6 n3 P6 W& `; a! Q8 b
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 q+ |+ o' I# V0 l& l
8 w5 N4 K8 o3 W0 J: K; V
& E( w J' l7 G0 a6 [ void SetMessageOnResult(HWND hWindow, UINT nMessageID); [) A v, i$ f
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
# X* e- ]7 w# F! I# s3 z6 J uint16 GetUsedTCPPort() { return m_nTCPPort; }. A! T& n0 ]0 T1 x/ k- c( {
uint16 GetUsedUDPPort() { return m_nUDPPort; } ' q% E& {8 D# g) ]
2 e& ?, x/ r4 |8 @8 p& n
4 H1 X( z9 g. ^4 x$ N// Implementation6 M+ m0 m- }% C5 g+ i
protected:
6 Z) M: K4 a' Q5 y/ k volatile TRISTATE m_bUPnPPortsForwarded; e; y& F* {% S! }/ t3 Q: C
void SendResultMessage();
# K0 \. v. |' ]" m" a/ r4 H3 Q( ~( v uint16 m_nUDPPort;# @ c. j3 \ d& y* N
uint16 m_nTCPPort;1 t% Z; @6 K1 B
uint16 m_nTCPWebPort;; Q1 J/ e9 N# C4 S# {0 ]5 f
bool m_bCheckAndRefresh;
& F3 A, n' e& g+ O$ W! A# O, G& g8 C7 C9 `0 r
; a+ n& n8 g, R z& uprivate:' R. J" P4 q" ?/ n8 d" z
HWND m_hResultMessageWindow;+ w+ y4 \ \" g3 A+ q
UINT m_nResultMessageID;
# [& O8 z3 I- L/ S
4 g3 k! o& Q0 V* c$ U
3 T' m/ p4 e$ P4 Q' `) R};
! e8 K7 N% Q7 \7 @
! V( l) T i6 B0 b7 s$ s# Y- j2 g" E! \6 @: q _. G5 |
// Dummy Implementation to be used when no other implementation is available% P; u9 ~* P: F. Q; X
class CUPnPImplNone: public CUPnPImpl
) B( O- t& x7 z' w{7 @( p6 ] l, U( K) w" s
public:
* t: Q# o1 f7 k: z9 P$ z virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
; u# {0 \3 [3 f# G0 M# z5 s7 G- o8 C virtual bool CheckAndRefresh() { return false; }: F9 v; z* ^4 H" k; B6 N* J9 |
virtual void StopAsyncFind() { }6 g! P, H6 [' I5 _0 i% B# e8 g
virtual void DeletePorts() { }% h9 k1 J \# a$ K6 Z1 F% t, d
virtual bool IsReady() { return false; }
" P, d; k* D: X virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
; k8 z$ t$ @8 G. \};. I+ p7 u2 s. [
/ U! X B0 ?% Q
( B/ i+ i& H& U$ ^/////////////////////////////////////
3 t4 s" M2 l' K/ y5 E4 S8 a5 G5 X8 s//下面是使用windows操作系统自带的UPNP功能的子类
/ X- L6 {- }3 k# m y& I
* x3 z# i- @" J* r: d# ]$ L" R. y$ B+ U2 ?
#pragma once
! ], W4 Q- |/ E5 h1 E; v#pragma warning( disable: 4355 )) t B4 Z$ m% D+ q
, F$ ` J8 y) W' g
7 a% P+ |$ z! L" _#include "UPnPImpl.h"+ c* j( E& b& U% K: K5 \
#include <upnp.h> s8 ?. h$ {1 c: X% R# X3 b
#include <iphlpapi.h> V6 ^. s6 H/ R) E' ^
#include <comdef.h>" V9 ]& O, v |* Z
#include <winsvc.h>
( ^" G; _! Z' L& q( s. [
# I* B" O. R& b7 S( A3 q6 ^- G- [0 Z( g3 Y" W' R/ n
#include <vector>
) ?4 [/ _* c1 Z% W0 s' }" j#include <exception>0 ], b& Y3 M9 H) P! w
#include <functional>9 ~9 _! C( c9 ]% Z( K
9 j# ]* A& }8 n6 s7 k2 F7 _- _0 C# w. A
, k% E$ B/ @2 t% U5 V# d5 s
! m& s7 V7 Q! Z8 O% G- I7 l
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;( r3 \( g4 x- ^) x
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( x. a$ f: X+ y# Mtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;# H- u6 m; w3 d- W" Q# i- v
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;0 o# J5 o- z8 I1 v
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
: l* p+ P8 L- jtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;; u3 K% H9 F- m" n( s) Q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& y. {8 O C; i+ ~- }: T
d3 U! f8 S/ K" |8 b! o
8 L3 @+ }( _, P( t6 jtypedef DWORD (WINAPI* TGetBestInterface) (
8 N# u+ U( L1 j# y2 k/ s, G2 { IPAddr dwDestAddr,3 X3 |* l0 u8 F
PDWORD pdwBestIfIndex
/ C* C5 t# s- e M1 {);' v! L) z' f1 l: {2 v
0 _+ Y% p# M. F$ e0 J
1 F% z# c! Y9 p1 R Q
typedef DWORD (WINAPI* TGetIpAddrTable) (
1 V" S+ P0 ~8 ]" Z0 o PMIB_IPADDRTABLE pIpAddrTable,$ t+ j& \6 u% B O# O# | f5 \
PULONG pdwSize,
" }- G7 D/ g4 q# u BOOL bOrder6 a7 Z4 P5 j0 E' E
);
/ z& D8 U$ c0 e' p5 I3 C+ R- k- V3 Z( j9 w3 r/ x; k7 Z' p( o* g) D" G: V
, y3 ]" O, u& ~. A$ G6 C5 V$ M
typedef DWORD (WINAPI* TGetIfEntry) (4 c4 |/ d9 W ?" H0 E, K
PMIB_IFROW pIfRow
1 {8 L W! d m. @* z: O);2 h' ]% S5 H u4 P4 D) F8 [
& Z+ G, l7 e7 h1 ^( B9 L1 V
( |) y q$ a5 g. @3 {& F2 T8 {2 G& C, V
CString translateUPnPResult(HRESULT hr);. S, I# f4 L( [, E& o
HRESULT UPnPMessage(HRESULT hr);
, q# ~: f$ |' T" n. W9 g; H$ T
% b+ F8 l& v9 C1 g) p6 h! a0 Y* F) H2 B! C) i
class CUPnPImplWinServ: public CUPnPImpl
3 S/ @8 e2 Z' K% F" l/ o6 g{/ c+ t l7 \; `8 m- l+ E; `
friend class CDeviceFinderCallback;
; d: m; K/ x- G( r' ^ friend class CServiceCallback;
5 _/ x2 x$ R. v2 y7 _% I8 e// Construction% K% B, U1 y( f
public:
, {* J) ^* H- D& k& J virtual ~CUPnPImplWinServ();% g2 D# K8 G- e4 e; h2 M2 p; R+ k. r( ^
CUPnPImplWinServ();& i" ?! X/ }0 V4 ?% g B) f+ h$ r
, g/ B: O0 o9 e+ H/ h
- W8 w, P7 C5 U0 J8 E+ l
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
8 |: ]! z2 U8 n8 x7 D virtual void StopAsyncFind();
% G: c) p9 W: \" @+ \: _, } virtual void DeletePorts();/ _) r. y! n* b6 B( {2 e3 J
virtual bool IsReady();
( Q+ h) s7 h- v' r$ ? virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }3 x5 }/ a* }5 m: c, E a* } n/ G8 f. |
& j/ d8 U1 j: ~/ ~/ T' l4 |* Q3 \4 m
- C1 q2 R$ z- d: I
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)' Y/ S$ c( ?5 j8 d* ^
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later% w! |1 k# F+ r8 Q) K( j& y
virtual bool CheckAndRefresh() { return false; };
' [! u" G" u# F/ {2 i
7 j* c* _ A8 N7 _0 |5 Z
% v; d/ f } T$ m3 S5 Eprotected:
: h3 L2 J9 f6 ^- u; P. u void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
7 q4 K# |7 ~9 a* o! Y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);$ w* B# z' |# ]. j
void RemoveDevice(CComBSTR bsUDN);9 l" R1 C. `2 m5 I, h
bool OnSearchComplete();
3 d/ X* I9 ?1 o1 L0 `6 \) S void Init();& F0 m9 W4 g- X) ]! K, Y
4 G5 Y# O4 i& ?+ q
7 H( D* Q# X' \ inline bool IsAsyncFindRunning() 6 n, V: i/ A5 S- s: G- [: t
{1 T7 b; c2 N7 U. B3 V7 A: }" W
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
6 }. a' s) _# O* v {4 S% m- R5 f. i4 ]6 G
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );1 m- l4 M1 o5 u% v
m_bAsyncFindRunning = false;
8 f5 v0 x) A1 z8 V8 G }' C6 `. w R$ M8 Z$ ]
MSG msg;9 U# m1 ^; o) U. D; Z5 W
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
2 r* A0 v0 s1 R1 |4 L9 ~ {
: e! U6 v( h3 `: F( \: Y3 w TranslateMessage( &msg );
9 {9 N& N# z: K+ S6 n DispatchMessage( &msg );
0 O2 B/ b* A. z1 o! Z" U, H4 h }: z" [6 T: S d+ o5 g: q3 W" G! z1 o
return m_bAsyncFindRunning;/ }) z) H# h; m+ B0 b: n, }
}6 f) U: a, B2 X% m( f3 E( a$ T
2 n& H0 T/ n& g1 p3 o2 t9 I; E8 L1 }6 l$ w5 f
TRISTATE m_bUPnPDeviceConnected;
3 A6 p, E) Z& B) \
. L& P! V8 w5 E8 M! R. [( D" M5 S$ ]0 v1 V* ~4 @* I
// Implementation
7 r% ]- v! c) h0 @3 C, g5 T8 [: H // API functions
9 c) N; z; S6 p/ X8 h SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);4 f3 Y6 t" X1 u
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
6 O* q7 v6 _8 B" [ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
9 D+ M2 {1 H. J# d9 R: ] BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);! J& R6 |4 f/ g8 Q8 u
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); n1 z: D& Z. E& o9 c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
/ R* @# E6 ~% _* i$ \" j" L1 r( n d- ?; K9 s; W9 F3 ]& P
, T1 x. a8 A1 P7 |
TGetBestInterface m_pfGetBestInterface;
7 e1 K5 t: j/ m* S TGetIpAddrTable m_pfGetIpAddrTable;
" l' k( l" w- {: m& A* r1 v, W) F h TGetIfEntry m_pfGetIfEntry;+ e, ~# | [& e( U3 m
) a% Q* F+ }$ o3 R# a. p2 z, c, C/ r. ]
static FinderPointer CreateFinderInstance();; t2 ~5 [0 Q; L# B
struct FindDevice : std::unary_function< DevicePointer, bool >
5 M" ?5 T: N% @0 m3 c$ }9 h( ^ {* M+ T: o* M2 I2 M- }1 H: t4 _
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& K7 Z; u. M5 I( C+ D& b% d) W( |
result_type operator()(argument_type device) const6 ^% d4 E& y" S/ ^' Y
{5 S/ D$ g# U$ r0 _) v3 R% g
CComBSTR deviceName;; p9 m% k, V" y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );) ~7 t ^5 b$ y2 k- B* ~, w; d
" i ?, g* T$ k1 {1 g" c; }
# O3 M* v+ w) `* Z; \+ ]5 ^
if ( FAILED( hr ) )( [: g+ H+ l+ v5 ?' `
return UPnPMessage( hr ), false;/ G, ~! q- m) c( r/ n, q
! T4 ?6 F$ x' Y4 P
) r2 C/ D6 o4 {1 e3 j. _ return wcscmp( deviceName.m_str, m_udn ) == 0;2 }5 ]# x: ?& E6 T- c6 {- X
}
: h* I9 V" \+ P) P: N CComBSTR m_udn;3 F8 X, ?3 b. G. M' _
};- ^9 |! B! J9 H4 u0 M' Q5 G
, c; R& ?3 e9 m. u& n void ProcessAsyncFind(CComBSTR bsSearchType);7 v: k. D: u% Z& E' i* @
HRESULT GetDeviceServices(DevicePointer pDevice);, f$ W5 x: @1 y, o- n7 H
void StartPortMapping();( m0 a7 _" e8 F1 ^
HRESULT MapPort(const ServicePointer& service);
/ }6 M) B" s7 I* v void DeleteExistingPortMappings(ServicePointer pService);- A0 Y$ f( f# k$ H. @: r' s
void CreatePortMappings(ServicePointer pService);
; m6 `, w1 W' T- N6 H7 {$ ^ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ H h' z: f% Y, Y( k' D$ H: | HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 V+ @7 H" o2 u: e9 e3 p LPCTSTR pszInArgString, CString& strResult);5 g' S% ^8 \( d& d: ?# Z0 @! o
void StopUPnPService();0 N2 H. I% X0 f( [+ P
# B) a. U$ Z& X P2 t. L
3 U+ ?& J, U9 \ ^2 r3 Z& Z: u g' q: U // Utility functions3 W2 ~- n. b. b6 k R4 }: q$ c/ ^+ w
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);! J" O4 g" ^1 Q3 r% U
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
9 L V; ^5 d! C1 k( K8 h8 P1 Q INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# r8 X- v% q' j# }, ?, G3 X void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
- H! p$ f( l1 B O$ L( G% A HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
0 k( Y# k0 |, {7 [$ _% G3 D8 O8 l HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
+ j# W& K2 q2 L CString GetLocalRoutableIP(ServicePointer pService);
& z9 ~: o) x1 n$ v$ C+ D! U& Y7 f) a# K( N
9 S& U% \% U% j* w1 K \* {) A* l
// Private members
% T J8 u. i* b! [+ d; f: f. Gprivate:
2 X: O3 m- }4 d" n$ Q l# N DWORD m_tLastEvent; // When the last event was received?/ U' J) N9 b |2 r3 ^7 S( z
std::vector< DevicePointer > m_pDevices;$ H$ N: v* V! B
std::vector< ServicePointer > m_pServices;2 {" K( B) m( G5 ^- B- c7 W
FinderPointer m_pDeviceFinder;
: g. @' J. [- @ K' G DeviceFinderCallback m_pDeviceFinderCallback;
& q. c7 M( V( g+ P3 F4 @- y ServiceCallback m_pServiceCallback;
- ^! G) ?( O2 F0 H( r5 n! M; u+ F
7 `5 y0 A, a$ }% @5 \$ } m/ Z$ G, B/ ?7 ^( ^- E3 y3 T
LONG m_nAsyncFindHandle;# u; O1 D/ v8 Q) M# A9 n
bool m_bCOM;
' y* k3 d+ i6 q! e. E( w bool m_bPortIsFree;
7 B6 L& v, W) H8 D/ d CString m_sLocalIP;& k' j! P/ g) e1 b) V
CString m_sExternalIP;
$ F# M8 X# f8 S0 k. R3 Q: o7 r bool m_bADSL; // Is the device ADSL?' [3 z: z9 x9 ^( R% M* G1 X
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
& `6 ~' J g8 A4 t# ?8 i bool m_bInited;
! I: `: @& @7 E& w bool m_bAsyncFindRunning;
' P# s' l6 g* m5 V# K& t HMODULE m_hADVAPI32_DLL;
9 U( X( Z- [3 O: X j: c6 Y HMODULE m_hIPHLPAPI_DLL;
- j/ z" A: N! I( Q6 x bool m_bSecondTry;/ Z+ d! I9 P: A7 ?8 j' U
bool m_bServiceStartedByEmule;
/ C6 Q% a8 y* ` [) u bool m_bDisableWANIPSetup;2 \4 C5 i- O! z7 Q
bool m_bDisableWANPPPSetup;
, \1 p% V" E* N) S
* a( k# X7 [; B( I& r
" s$ Z4 ~- s1 U# C};5 F; K- l! E4 n, S1 ]
' f- J9 \* U1 I6 h$ N
& a# u1 B, g. f- i( e% K
// DeviceFinder Callback8 `% d2 D% T' z& G7 i
class CDeviceFinderCallback2 J! W$ Q3 M$ z$ k& ^
: public IUPnPDeviceFinderCallback
2 t' x* y$ p( g' W) ]8 |& k{
7 ]0 T* l1 d5 {public:% D& ?5 r- j3 V! p1 G
CDeviceFinderCallback(CUPnPImplWinServ& instance)
( P8 S+ q! x* w! y% p5 S : m_instance( instance ): L$ R( ~/ C) H0 N
{ m_lRefCount = 0; }
, s, d$ s {. S
; q4 ?& B; `4 Q" `' f- _3 q0 C& {
3 N0 I4 [( |" ]( y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 u( I( d# r+ q# I$ B STDMETHODIMP_(ULONG) AddRef();1 s1 H0 J# I$ A2 g
STDMETHODIMP_(ULONG) Release();4 k4 h: ^* O4 m$ m& I' B; k g
! Z9 C* ~* h! |) }4 m/ @; x$ {# M& Y$ ?
2 \. Z: ^+ k8 H// implementation; k0 M! {9 t" p! r
private:
( A# d+ W& J4 `( h4 L$ T* A HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 g$ r' ~0 [$ { HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);! @9 W: D3 W# Q9 }- I5 N
HRESULT __stdcall SearchComplete(LONG nFindData);
; `* k+ j: a" J6 a9 M5 C. C$ f3 N7 _& D3 y! ^+ _; E \9 d
4 B M) t* s% b% ]0 |/ ~; \private:
) s! t! m. Y, j6 I! o! a2 i6 t: S CUPnPImplWinServ& m_instance;9 ]1 `# i9 F) ~2 p/ K j. K
LONG m_lRefCount;
6 D% H) N* \ c3 c& f2 t};
$ a/ u. X% k6 _, r n6 B
4 Z& Y2 _' r& |% Q/ z8 l) [
7 V, }; p0 z! k, H* t4 q// Service Callback ; K' T$ ~. b+ f
class CServiceCallback+ u5 \9 }. E! m) B
: public IUPnPServiceCallback
3 h4 H5 c6 C! N1 g; T! ]{8 A8 B1 T, u- d: {
public:
# S; V" J& z: h CServiceCallback(CUPnPImplWinServ& instance)- n7 S+ T5 F8 v
: m_instance( instance )
/ s: ?1 D ?/ o8 ~9 [ { m_lRefCount = 0; }; x+ A" w7 {# y& s& ^9 x, A2 {1 H2 Q
1 y) f6 |# C5 Q+ f STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. p5 O2 @$ B3 g5 y/ {; k% y4 i
STDMETHODIMP_(ULONG) AddRef();
8 m1 S9 O9 ?4 U3 F/ _) |/ W* U STDMETHODIMP_(ULONG) Release();
: [4 m, S$ P- }% t! l% L. A+ p. O
( g& R( L# S, y8 C6 `# _
2 }& S, m' y5 G: b* W// implementation* K4 E$ S$ p/ |* @5 Q
private:
! h; n9 A% Y" A* b4 f3 H- ^+ a HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 o# R. j# q5 d- K HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' p; w' l9 U' e7 d$ k, u7 j8 c
2 p9 T* a6 c. d5 A$ v- T* ~( k2 X+ E+ S* F5 a! }* R8 d
private:
* E1 Y) R, W) c* r Y CUPnPImplWinServ& m_instance;
6 \. U8 u1 n/ a' V* z LONG m_lRefCount;
$ a( v: \5 w) U+ U. K};& ~" i: n( V& h# `
! k, O/ k2 Z4 `' U
$ ]8 K- p4 u. k' F
/////////////////////////////////////////////////
1 K' W1 Q# @3 M- ]: A$ {
6 ?% |5 R! ~# d( c6 _+ [- p8 X
( C) n( w% c8 t' _使用时只需要使用抽象类的接口。
6 ~' W1 J8 ~2 r2 O9 ZCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.4 R" d0 Q, |- t9 B) T' R
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.# t" |$ G8 f7 O8 p; a( w. i
CUPnPImpl::StopAsyncFind停止设备查找.% X& `5 A7 }4 Z, t0 I" P
CUPnPImpl::DeletePorts删除端口映射. |
|