|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 n4 M( ^1 B( P" a
! c* b, T2 K6 E, P! _6 m
/ G5 t( c3 v3 q$ O/ \) k///////////////////////////////////////////
6 M& A$ @3 g, `, P' X# c//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
+ ~' l0 ]4 ^2 A9 u5 z* L2 D- [) H5 l/ H, J( R L3 C9 x
& N/ f% l9 f2 ]$ G8 r
#pragma once- Y% L/ q# P/ a# h; s7 m. b% E9 L
#include <exception>
% V) w8 X( x' }+ a+ R2 e4 ?1 j+ |& Q7 P" U. _8 t+ ~
/ u+ v2 i5 ^, E7 s6 B; | enum TRISTATE{
1 L$ S- i6 T/ |9 a; m TRIS_FALSE,
' y( Q% N+ k) w2 l# u% i TRIS_UNKNOWN,
+ P/ K1 P7 Q8 \8 k# P3 C' f TRIS_TRUE
' R1 i& g6 F8 J& P};
6 P3 W$ C Y E% n$ l5 R1 P
' ?0 c. [& f7 G
2 N: `( c( T( D- z- genum UPNP_IMPLEMENTATION{( V m; a' p% K6 E* ^
UPNP_IMPL_WINDOWSERVICE = 0,$ ]* O4 \( o- z" x
UPNP_IMPL_MINIUPNPLIB,
- @# y8 P, q6 V1 n UPNP_IMPL_NONE /*last*/
! c7 b% A: E o6 P5 ]( [7 ], p};
6 E9 t0 ~( j# E; x
( c" u& p- I. J$ Q: r
" U- x8 [. M- e" W# b0 N
, y6 t/ m$ x$ |* ]0 x
" P& M3 N. n- X1 h5 m6 l! x0 Eclass CUPnPImpl
# [2 d; x0 ]! j- S{
( T7 L! c/ u$ O4 z, Apublic:
5 i" }( t4 _! l3 D7 e- k* J CUPnPImpl();
0 c) t. H( G6 g/ w" o' G virtual ~CUPnPImpl();) n- k# ]6 @9 B: d2 _
struct UPnPError : std::exception {};/ j0 B( p' o! h+ b! I+ h
enum {, d) r! T# T7 o
UPNP_OK,
) c8 t- L. f* V& ] UPNP_FAILED,
/ V- @5 @& q: ~* D2 j! u8 W UPNP_TIMEOUT
7 u+ \1 b# M5 J% I, B4 D4 L };
2 o, X' ^$ E8 ]% x- E* w& Y* ^2 K5 Z" j5 Q! g% F* E1 j
9 y1 q( {+ j. u+ _! z/ A virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;6 l9 {5 K% m- u
virtual bool CheckAndRefresh() = 0;! P( P; @) o5 g) s. }; Y
virtual void StopAsyncFind() = 0;0 `1 U7 v) t+ U' l" G' |
virtual void DeletePorts() = 0;
- f# M8 V& ^4 W8 W9 a virtual bool IsReady() = 0;% _' \. f8 S) A$ ~1 Z" j C1 n) k+ E5 o% X
virtual int GetImplementationID() = 0;; ^/ i6 ^8 ~: d! V9 K
- x# ]* J* c5 q3 a- Z8 f void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ e- h* o4 X9 j5 U% u8 d- C1 a4 W( W ?6 h
/ x; `9 Q9 r6 v4 Z: U
void SetMessageOnResult(HWND hWindow, UINT nMessageID);9 C. V: [" R5 x* n2 F: F) W, k8 N
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }# ^3 P/ z; O! Y/ ?) O( t: L2 A
uint16 GetUsedTCPPort() { return m_nTCPPort; }4 U5 L8 _, J( a" ~. E c8 _
uint16 GetUsedUDPPort() { return m_nUDPPort; } # x# @# C4 z2 x+ o" X* F% u: [
) P8 \+ x; t' V: i; f; ~! k( m: c
" B8 x8 d9 W7 l9 p/ f
// Implementation
4 o9 P! H: V- n0 i$ ?protected:
" |1 D( M, c! y/ Q0 e volatile TRISTATE m_bUPnPPortsForwarded;
! K# \4 R: P- m& E void SendResultMessage();. a9 m+ {" s: q% h: V; N/ B/ P3 C
uint16 m_nUDPPort;
4 y/ X! T* Q6 L. W6 T uint16 m_nTCPPort;
- S. k1 f3 j. @; i3 _ uint16 m_nTCPWebPort;
2 B# ?; R: e, m9 o bool m_bCheckAndRefresh;+ ^& Y& ^0 u( ]& w
: N5 R9 E9 Z( s( W. @
* t! H9 _+ w1 s& gprivate:
0 [( Z3 I: l Q% J) X, r HWND m_hResultMessageWindow;2 u2 W5 G/ v+ q3 Q. e0 l
UINT m_nResultMessageID;2 a2 a0 g; y0 u( W# \
! @" U3 o+ L) E8 r* O
- D- D0 H* Q# q% P6 d
};, U$ K4 P) s, m$ R5 S8 N
, k$ W7 h3 W }1 k8 K" [, D: X
3 i# r( N. u# A% M6 @# h& O// Dummy Implementation to be used when no other implementation is available% B/ X) Y6 \! L) M- O; d# a, R& C
class CUPnPImplNone: public CUPnPImpl9 X% p x5 [9 g) J5 J/ y5 l5 Q( J
{3 p* f5 _9 {# [7 \- N h
public:
8 ~$ c5 y, _* E, @8 W virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 K" @6 S+ Q$ e# B& x: X: w/ W virtual bool CheckAndRefresh() { return false; }8 w$ n$ n3 H5 B$ k2 R: H1 D) X
virtual void StopAsyncFind() { }
1 o+ }+ L$ u/ V virtual void DeletePorts() { }6 w( X2 `( v' ?5 J. t# S) g4 j. m
virtual bool IsReady() { return false; }3 N. Q$ ^0 N }) ]2 F, ?+ n
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 \( Z7 c7 u: i K0 T; N& r
};
" S$ F4 Y6 U5 n5 m9 w1 z) a' g, ]1 b! B- R7 O
6 W/ W: e& e* {/ G1 }: B% R5 g/////////////////////////////////////5 H9 D# U, N* Q
//下面是使用windows操作系统自带的UPNP功能的子类
$ Y- v# ~# f2 H, C
8 [7 M, _$ I. Y$ ^
- P* U' r/ Y6 a#pragma once
. o- ]1 A+ ]5 F+ I6 r9 e2 B4 V#pragma warning( disable: 4355 )
$ r7 X' f) e, S6 t" c" K" B: E% K- c) a7 `. y# _0 s
! X! `/ n0 v: Q' |% j1 [1 [#include "UPnPImpl.h"/ E6 D+ G7 ~7 C3 x0 x% G# q; ~
#include <upnp.h>3 f, D$ ?& p. C2 o. g2 `. s( X* u
#include <iphlpapi.h>
4 X# {; P) l7 u' I# u, Z& h3 D#include <comdef.h>: I2 k8 R$ C" E
#include <winsvc.h>5 c' \2 y" S4 @# N8 A$ H
+ C$ J' ~. S# P+ o; _6 o" P
6 c& P/ y. [) ~5 u#include <vector>
% q' t/ ` a1 Z4 v8 g" s#include <exception>; ~$ K# Q7 h& k
#include <functional>* U- ]7 U& l+ ^
) j7 v" \0 m+ R# o8 U- C( q* G' K
5 G+ ^5 W- E2 C6 R; I0 \ F7 G+ u
* f0 A3 M1 X. n+ M/ T! l
+ V2 o% i, a% b# w0 C
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;% X$ {: @( B2 Y
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 P3 J+ D9 g- E6 t2 K3 w9 B0 c
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;$ h0 s3 L9 y+ ~1 g0 u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
: O" N) K) o& ]% W( k3 ltypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
. b9 a1 E* [) }' y5 t. Dtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;, w/ H$ t0 c' D# J; b5 [; [8 ^. W3 V/ A
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
3 x. @, _" Q/ F o4 `" Z: R* i/ C/ ~6 _
" ^. {" d) P! p
typedef DWORD (WINAPI* TGetBestInterface) (( H4 ]! F$ t. s! a) c% ^: g, k6 L
IPAddr dwDestAddr,
( M$ z' z# o* w8 L: P# ?( l# \ PDWORD pdwBestIfIndex
: E9 S3 ?4 ?' e4 D$ ?7 c4 _3 S5 \);
* @: J+ E' h! q/ k; |' \3 x: X5 ]6 g6 Q5 y
5 G2 M9 R' |* U, g3 c i+ p5 d8 ~- _
typedef DWORD (WINAPI* TGetIpAddrTable) (6 W) H. W/ S; w
PMIB_IPADDRTABLE pIpAddrTable,) `/ j- i. I2 d% b6 _
PULONG pdwSize,4 w- q! }9 d& N- p& W9 X' h4 w/ O
BOOL bOrder( I$ ?6 [" p! l
);( c3 G- D, t8 k+ T! q3 N
- h- \* ?3 S# r* Z
# u# {2 k5 z# b" y2 k0 j g8 M( k4 Ctypedef DWORD (WINAPI* TGetIfEntry) (
' Z) C* F3 I' a PMIB_IFROW pIfRow: l9 Z" O! p# W5 M6 p5 N
);8 y; s& ?$ W) `8 a6 B3 x
, { H, C( v( y, _
* Y+ z" X% y5 ^
CString translateUPnPResult(HRESULT hr);
; o# c6 b( @0 z# O% MHRESULT UPnPMessage(HRESULT hr);- H) s3 ^: s: W) L9 N
! A+ A4 C3 U* ]$ W& Z
9 C3 H5 ~- b' B! A/ p6 P, vclass CUPnPImplWinServ: public CUPnPImpl
7 J% a8 U. W) {{
/ w% J. u5 C& V4 x friend class CDeviceFinderCallback;
' e/ ?& {: t' t; g7 a' G friend class CServiceCallback;
* W( C1 j* p; o( z// Construction
& _0 Y5 w+ ^- H9 J+ s, mpublic:
' y2 K2 k# s( z, \ virtual ~CUPnPImplWinServ();
4 u/ i0 M' i8 G9 @3 C- H6 c" q CUPnPImplWinServ();
0 `+ ^% R( s& u7 P2 }9 E+ @
: c. ]+ ]5 _3 `; m/ o8 S9 x' P- k& Z+ W% H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
5 }% E" @8 Q: X3 n- E) ] virtual void StopAsyncFind();
, c- U- n3 e$ z0 p virtual void DeletePorts(); s4 s) K8 i o S0 B
virtual bool IsReady();4 Z; N3 b8 i, r5 B# q6 Y
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ d9 x7 v& l: Q& E. d9 K
- h) }" k7 @# g5 z/ |" q! u. R
: X2 k' \: ~( o2 `, }( R) t
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% U7 A* [$ ^* g% G* ~* S6 ] // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later- \, _2 s' i: d* F6 ^, ~
virtual bool CheckAndRefresh() { return false; };
+ {2 m* z' C+ ?; g
# L0 q2 A9 M* E0 m* @: L1 p, l$ v
8 o) A2 {( V0 I. Tprotected:! Y; v( J. u$ j: ]* k+ P$ ?0 O
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) \! W' \: [) L' L0 ~ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
0 w. h; d# ]; `% e5 i* c( ~ void RemoveDevice(CComBSTR bsUDN);
b& T0 ~2 C; B7 G bool OnSearchComplete();; a3 F/ r$ O7 K+ v$ k
void Init(); V1 B" e+ ~+ v% D
/ W/ t& D1 `5 K" K
( k. s# r5 i1 d0 J! u _: P x& x inline bool IsAsyncFindRunning()
4 s; A% n3 p1 s z5 R {
( V7 B- {) l+ X2 q J; F6 x if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
' \" U- w" p! e" H7 d8 | {
* m- l5 |8 K( ] m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle ); {* Y& }5 w, K
m_bAsyncFindRunning = false;
}! c8 |% X4 R1 |9 a }& S% |* a0 s$ g% ~% k ]* T
MSG msg;7 z7 w+ ], n* {6 E6 J( v9 L
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
3 {0 j' K' N3 C' O0 S* p {
, W2 A* L/ x! g) b0 V TranslateMessage( &msg );
- Y" f( v5 G+ j8 R. o: S3 \ DispatchMessage( &msg );/ `8 G1 t; a' K/ y& C9 c
}) B* }( H0 K! M- k A
return m_bAsyncFindRunning; ~ b+ x& N/ H9 r) y% W
}' s9 ~4 z& I+ v& _# n
$ m' M$ _/ X9 j
/ C$ w2 O, E1 H* q TRISTATE m_bUPnPDeviceConnected;5 S1 x+ e) d6 f+ O
3 v, k& P/ r, K2 y+ e) U p7 r, Q1 [0 ~; U2 L. ~
// Implementation
7 [5 Z% Z7 L# R/ j* `: ? // API functions1 O8 ~$ Q7 f( C" D: f6 C5 v5 q
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
G: A0 r% f! b' ~) h4 s SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
4 K+ _; M+ ^7 {% o) _! h; @ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- S& b/ y; f M6 X& O
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! {$ t* O$ I3 _) A1 b" F+ \8 z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; H8 ?3 V# O0 |1 T! I3 s1 t n. u3 E9 q BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
' U. g- Y) ^$ V* b0 X# w# ^( l! m1 w3 s4 Z, ]
: R/ d3 k' V3 u5 ~3 ]& ?
TGetBestInterface m_pfGetBestInterface;
: ?5 R* B0 s8 c) n3 r TGetIpAddrTable m_pfGetIpAddrTable;' O1 E2 n' [; E2 P6 j T
TGetIfEntry m_pfGetIfEntry;3 P4 F8 U( J1 C0 `: P6 u
: X% P( _4 ^ R$ i/ Y
0 E+ @4 e# t5 j* }2 Z static FinderPointer CreateFinderInstance();
" `1 h- ^$ c {- _ struct FindDevice : std::unary_function< DevicePointer, bool >
, u/ U- ~+ h* b% P5 ^, L6 Z {
" V5 t M& F! F( \, n FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
; F# ~ h! m3 S+ U5 }( ` result_type operator()(argument_type device) const, M# Q4 ?+ P/ I6 I$ R
{
; Q2 [+ E7 S9 ]2 I& P" y; d CComBSTR deviceName;
- v! @$ b% B' z/ s S HRESULT hr = device->get_UniqueDeviceName( &deviceName );7 u/ Y% c4 U9 h0 J
/ m$ F' d# v) e
- z4 y G- X O' y( O: t
if ( FAILED( hr ) )
! w; ]3 Z B5 s# p9 v2 a return UPnPMessage( hr ), false;
' B: i" [+ B! j$ I5 W
* g7 z* v+ T. Y
$ _0 J0 U$ V0 W; S: @ j, m. [, G return wcscmp( deviceName.m_str, m_udn ) == 0;
7 ?/ {% ?$ c$ [8 {4 U/ H( V7 e' A& | }0 E0 Y8 M+ ~" ?8 m; S
CComBSTR m_udn;
|9 ]4 d) ]: F0 C, h, Z };
- V* C0 m' M8 t, [
/ p+ R# j0 m, W7 Q void ProcessAsyncFind(CComBSTR bsSearchType);' U. l% i3 P- I, m* D ^! d' l
HRESULT GetDeviceServices(DevicePointer pDevice);
: w4 \6 ]/ U! E void StartPortMapping();8 f; d( X7 W" {' g: R* ~, D
HRESULT MapPort(const ServicePointer& service);2 E! A/ ], z; s; T
void DeleteExistingPortMappings(ServicePointer pService);
! `; p3 b, {% N void CreatePortMappings(ServicePointer pService);
5 r5 }$ n& r2 \2 S' h6 L: W HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
3 J( }2 M( E6 n8 f HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, @; Z. E* T a6 N# X. X LPCTSTR pszInArgString, CString& strResult);
/ H0 z6 d( J* e& z( k; x8 S! M; d0 c void StopUPnPService();9 ?- U: B3 o& M, B* I6 O2 L/ g1 z
5 g4 {' o F; L( L0 S* Z
: C' f1 D+ F, I; e" \. _1 m; X2 M2 p
// Utility functions
- x, o: l' G. Q. Z O; @+ m6 W/ Y HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);+ R2 ^$ \& E3 f d! q
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);8 E& H2 l) J! h+ ~, Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);! w( `2 F- e$ x
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) d3 r2 i e/ q2 [ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);( j) c3 Z$ H8 }7 g2 o
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);; s! |5 b+ \5 M, N, L N
CString GetLocalRoutableIP(ServicePointer pService);
( Q I7 t5 |/ W$ U/ ] V5 A) f2 `
" Q1 m8 R+ j- v% p7 i7 j! z4 E5 {' v) M
B5 C. j# o; Q, h2 ]. k) R// Private members' I1 ]* w3 g; _1 l
private:2 T/ K5 J5 a7 p* G
DWORD m_tLastEvent; // When the last event was received?
: A$ U2 G! q0 @ std::vector< DevicePointer > m_pDevices;: Z% C6 L W, Y
std::vector< ServicePointer > m_pServices;
% _9 e! [" M" v: K/ [4 L4 l) A FinderPointer m_pDeviceFinder;
u+ G l0 m2 B7 D6 F3 H DeviceFinderCallback m_pDeviceFinderCallback;
( e7 a7 U+ Z+ P8 @# V2 k9 V ServiceCallback m_pServiceCallback;: ?2 \! }' N" v+ J/ a7 f
* d9 e" Q) ?! v. }, g2 C8 S! m: z# N4 }% t, x% @
LONG m_nAsyncFindHandle;' i, F8 A' e5 K; w
bool m_bCOM;
: R) K( t% ]3 d6 c% w0 [ bool m_bPortIsFree;
% r: q: X- ^ q/ Z# F4 l1 O# q9 x CString m_sLocalIP;0 }6 |; m$ k% h3 A
CString m_sExternalIP;! S l) }; P9 j/ a
bool m_bADSL; // Is the device ADSL?
+ {( a% d$ f$ l/ m bool m_ADSLFailed; // Did port mapping failed for the ADSL device?1 g! Y. H, |& G6 Y1 b
bool m_bInited;
% g5 z0 I' h j' P( O bool m_bAsyncFindRunning;
& B- W; F5 { ]$ M& p+ W HMODULE m_hADVAPI32_DLL;
, a7 a" u: E4 [- R5 T5 H9 Q HMODULE m_hIPHLPAPI_DLL;
N* d8 |+ R1 ?: J" B. X bool m_bSecondTry;! k( c7 y! m5 f8 Z6 ?
bool m_bServiceStartedByEmule;
, P& b. a. `- c4 {+ @' g8 S, s8 j bool m_bDisableWANIPSetup;/ ^: X: h. H/ a2 h! I
bool m_bDisableWANPPPSetup;
& s% r1 ^8 z( V4 q9 G, r
- ?( L8 |/ D$ N) i, m# |
: J6 d% l. |: e7 y9 j5 y7 m# m( n* b};
0 N+ |" e6 ?$ O" x; p3 u( ~% ^- s, C- J
& {/ L. }& f8 d, x! o3 F) ]3 `# k1 J
" ]( J3 z7 R2 u3 O1 ~// DeviceFinder Callback1 z# g$ C; o p8 `; }
class CDeviceFinderCallback# w2 f! N5 i0 H
: public IUPnPDeviceFinderCallback
! t* T4 X5 C4 ~{ `2 N( Z$ Q" _6 f/ y7 d; y
public:+ R6 H1 T Z. s: L, ]: K# p" t6 _& u2 l
CDeviceFinderCallback(CUPnPImplWinServ& instance)
9 P2 Z, R9 S/ s5 f: U : m_instance( instance )
# |3 V5 h W8 i) ~2 T; O { m_lRefCount = 0; }
3 Q: t* C \1 N! u9 o |# Z' p1 L: I2 n9 @* }; o# p
; f ^& s# A5 R6 `" i5 @9 H" x
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 _/ O4 D# d2 Z* g) L STDMETHODIMP_(ULONG) AddRef();
: d% E4 u4 x9 k9 p5 ~/ W STDMETHODIMP_(ULONG) Release();) H- m1 @7 O# g( K- Z2 o
; Q- p( \7 N; n: {* k
; d( y6 `" J' Q# Q* g* g8 w// implementation/ L. a/ G! X' V& E
private:
' P, F; L, E' i3 E- Z! o HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
, e4 \; g) q" p C7 T# l' v& D HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. w' E$ v% Y, E, W6 E- g4 J
HRESULT __stdcall SearchComplete(LONG nFindData);' h2 V" `4 p5 K7 P* u" i& T, n
; j4 |; M y1 F) k6 `
: U5 X# w+ A E, u* _0 M5 A/ gprivate:7 R4 _1 x2 ^8 k' o
CUPnPImplWinServ& m_instance;
8 R) _* m% o1 E8 ` LONG m_lRefCount;: J9 [ U. f4 R7 f' H
};8 Y( I* p. G3 g' N) N( V9 I
+ o9 ^$ Y+ m5 j Y+ F* \
' h) l" T+ K% y8 y! v$ z/ h7 D// Service Callback 9 V- F' _9 ~. H
class CServiceCallback
& M. E' y/ Z6 }4 c : public IUPnPServiceCallback
5 P |+ H; c% o( C* y! p{: U. E+ s. u0 ~ k8 B+ t2 a- \
public:8 Q/ A) n7 b4 M: X8 t
CServiceCallback(CUPnPImplWinServ& instance)4 a& p, l5 U1 |% F9 w2 q
: m_instance( instance )
( g$ ~; q7 ~& ^$ j4 d( J6 @ { m_lRefCount = 0; }
4 T) R/ G7 G0 x1 F
2 k4 j0 g$ l. _) f$ Q N STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! [* v: s5 K* D
STDMETHODIMP_(ULONG) AddRef();: s2 R$ L2 J$ g5 ]; L' A
STDMETHODIMP_(ULONG) Release();; E+ ~: p3 v. ]* S) H( h
; {: e1 e7 o: O: f4 H
5 G7 [) W4 f, F
// implementation& k6 B- m0 H1 g' k! G, i# H* @. k* J
private:8 j2 B$ P$ `- C7 @( @& \' S, J
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
$ a7 i( K9 ?9 Q% k8 o. ] HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);5 a2 z# l1 ~0 W/ n0 u( I5 K5 e
) B- J* h- [' K) e |5 ^4 f' t' j1 e, N. h8 }3 ]; u
private:
% S. {9 w- J% r CUPnPImplWinServ& m_instance;
: @0 F# D0 U8 c: `. B LONG m_lRefCount;1 x( E; B) m, {% Z" M9 B5 V
};
6 V; ?# u8 _) N5 v$ V( h9 J v
! I- f% k- M: t% X% H& s5 ^. t; `
/////////////////////////////////////////////////
2 ^6 N% m, N. J, N3 q& f# _/ z/ c3 ~( {# b( M' F- N `1 a3 H; U
2 `2 v7 l, Y0 D% ?- N8 X, Y1 y H4 k使用时只需要使用抽象类的接口。0 ?4 q4 G7 l/ I" y
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.* m! p# M# H" R J
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! Q( \0 s% C; X! q! C0 n6 p
CUPnPImpl::StopAsyncFind停止设备查找.8 m+ v5 i5 p: J/ j7 U& }
CUPnPImpl::DeletePorts删除端口映射. |
|