|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,; d$ \: b% E0 B
! w" o, b" Y& u9 e5 J' B6 @8 j. U- P) P1 Y2 E: V
///////////////////////////////////////////
# R* o" r: C3 { P: R//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
) b. ^9 h9 x, o/ x8 H' b/ o% Y1 J9 X. v" \" G
; j* j5 L9 [4 B, \/ ?6 L) V6 Y#pragma once' o4 A' x, J) j$ |/ w+ \+ |
#include <exception>/ [. O4 v7 u3 a& q
; Z8 N+ W9 ?3 k% u
1 m$ D6 V. K X
enum TRISTATE{
! k9 N% J, z5 ?" }) _) f- u TRIS_FALSE,
! W* L% e- u- ?! `9 ] TRIS_UNKNOWN,) Z- o; U) W9 a) O$ e7 {6 S
TRIS_TRUE
3 D3 c | Q& ~};
: f( t3 P2 R8 T. a
# J) u1 ~+ x) e. v0 @
5 L# k9 H2 ]- U" W7 ]( f# Renum UPNP_IMPLEMENTATION{" b( \9 l' l; d
UPNP_IMPL_WINDOWSERVICE = 0,+ l8 w% F r9 V. d( O
UPNP_IMPL_MINIUPNPLIB,) H7 @2 F0 \7 ~* B) y Q
UPNP_IMPL_NONE /*last*/
! g6 b4 l9 f& M3 J};3 ^0 I+ B+ ]/ E9 b) l a
% q* q0 ]. x: B3 e0 E7 A, C: I: Z* c6 e" g/ B
: S- n* L' F. Q' m3 s9 M0 a
: h( C. K t; C p# x4 ]class CUPnPImpl1 y" g1 c7 e' e" w1 x% p! _
{! m# q0 Z& ?1 V P$ V0 h
public:
3 u# U+ k" R3 a0 h/ G/ u+ v CUPnPImpl();
5 Z7 ]: d- m# k7 ~4 Y! T$ h& P virtual ~CUPnPImpl();! R% I. k3 B' l& Q2 I" }
struct UPnPError : std::exception {};
$ ^. c8 H& ]* Q- Q( U7 w enum {, `# _4 N4 L4 c& ^" m
UPNP_OK,
. Z. S# ?+ |0 `5 [0 R9 B4 M UPNP_FAILED,
d9 D# X% l% w5 I. J UPNP_TIMEOUT |. T( G$ F% [
};
% u$ U( I( _6 J
3 u* Z$ j' N# `6 C
9 f4 M" \' i5 O# G8 Z. l- ?; W3 D virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
0 e8 @1 P+ w0 Q; r6 Z4 _ virtual bool CheckAndRefresh() = 0;+ }/ u3 i. E x! U0 g* N2 R7 g
virtual void StopAsyncFind() = 0;
7 |7 a# N4 g/ b! ~ virtual void DeletePorts() = 0;& } v+ i( \$ o+ W) |, R0 y
virtual bool IsReady() = 0;
/ `- U' y( o9 `) @" | virtual int GetImplementationID() = 0;
2 C0 w+ H8 s- O" x+ y- X 4 a% m% }3 R2 e" a8 u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
& m) b' c# a- `% ^9 ]9 l+ F/ I
' V) k/ h: b D; Y, S3 \! H" d2 X2 }% q7 t' G3 C8 D: f& p3 f0 ?
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
, f2 Q) j1 Y. W1 G j- e) I: q TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 [5 H5 q% C4 J J+ Y7 U. B. m6 s
uint16 GetUsedTCPPort() { return m_nTCPPort; }# v. O _! @9 V) H1 j
uint16 GetUsedUDPPort() { return m_nUDPPort; }
; N! N- U) h6 T3 M5 T2 P
1 g8 Q' h! u1 |6 n5 ?2 I1 ] i! r" l/ V( K% I( ?" [8 R/ J# [( S6 c
// Implementation; f. n/ e7 A& l7 D% p: @0 t5 o$ Y& D
protected:
8 x6 A% h. w: l1 `0 P$ H. P volatile TRISTATE m_bUPnPPortsForwarded;- R& b7 H/ S8 a8 t- h' v2 X
void SendResultMessage();. m) A/ r* X# b0 T( k9 W$ ]
uint16 m_nUDPPort;7 H3 o7 Y ?/ b: H- W8 J: b! ?
uint16 m_nTCPPort;8 B; S% f; k, `) ^( v
uint16 m_nTCPWebPort;3 X( s- S \3 k1 n3 m6 d" t/ ~
bool m_bCheckAndRefresh;$ A& n$ d3 k3 m3 k$ t
9 i1 y2 G$ X7 Q
1 n8 a3 `6 k) C* O! O i6 Y- zprivate:) V: J) w9 l2 _! L& p
HWND m_hResultMessageWindow;- j# }$ l0 Q; l: X
UINT m_nResultMessageID;0 c; Q$ b3 p0 r ?# }
) u' x4 {0 b( Z% |+ E
2 o1 r' m) m( D; x: Z+ B- C# N' I
};# h: g; h1 _1 i, h$ J5 r0 [9 e' w8 P
& M& g2 R) W \4 Q
$ T5 ~6 h7 H* q; k; e- l" X
// Dummy Implementation to be used when no other implementation is available2 R6 A+ H, e6 H& L
class CUPnPImplNone: public CUPnPImpl; b* s- |+ T `& F, i" N
{
; f& E+ }9 R- c( Xpublic:& L- R+ f$ f1 ~9 {! o
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 u2 n F+ @" \, {2 G# G5 B virtual bool CheckAndRefresh() { return false; }; A( ^6 F1 w2 S; O' t4 h
virtual void StopAsyncFind() { }
0 Q* @/ W. \+ o: c! k, c3 d virtual void DeletePorts() { }
2 A' q& f4 u b" w0 a virtual bool IsReady() { return false; }. w0 k8 m6 v$ ^" c
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) j1 [4 D$ j: f7 l. R+ H};- I) @- y6 D* j$ v& `
$ o: {0 @* V ^/ f! Q" V. p# h' P4 m N- J% d' s8 @3 E
/////////////////////////////////////" p' y/ `2 e5 B( s( |
//下面是使用windows操作系统自带的UPNP功能的子类9 S& R7 f+ p2 Z! @) c
: Y" j4 q* w7 g" J# R
) g' `4 n9 ]" L( ]; Z2 Y#pragma once
+ X q* L1 c! m9 N# h8 ^$ w#pragma warning( disable: 4355 )
9 L/ x/ ~" z# t# ^% P
$ o- ~9 A2 \3 z; V ]
' ]$ Y; [9 r3 \8 S#include "UPnPImpl.h"7 x( i# I6 e& ]5 r" v7 d% z Q
#include <upnp.h>
- C9 ~# S; y1 K3 j, [#include <iphlpapi.h>3 h, \4 h1 x+ t3 O9 e. ]6 M9 `
#include <comdef.h>
7 r: z# D% R4 ~9 Z8 g#include <winsvc.h>' V' d8 {# b( M" T
& A1 p0 ?, L6 r( i' {6 L! V- [
( j# y; I+ _% G8 P/ i1 T#include <vector>
8 s$ ]& U& D' ]7 ~& t* D#include <exception>
7 `( o2 ^* n! @& M5 c#include <functional>8 O3 Z5 E9 }: ~; O2 G6 V' K
7 g" K9 W* `) H4 s7 a
* \% `2 o3 Q' O- o/ }+ X9 g
; o b& `# k* _5 b# A j: ]! u* @$ F9 ?6 g. n( W6 j
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
* n- x+ f# ]1 L& dtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
+ u- w* o& f# t! o i3 o% g+ F# |typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
8 J: c3 L% _/ x* Z, ]( ]9 ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
4 D# ?, X- r) g% @typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
( u* R% Y; _" ]; |$ J8 otypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* u" P2 ]( |8 r! gtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 M5 g/ ]2 y$ Q' R' ?+ @' C
0 U: q R+ v C0 M; o; |/ f( J' n9 F) Z
typedef DWORD (WINAPI* TGetBestInterface) (
* R. O& |* ~: @ IPAddr dwDestAddr,
8 m% X; S( S" N& I PDWORD pdwBestIfIndex
P, X0 T: Z1 ~5 e);: w8 f2 e1 V. l" s w' O0 W
# f* a8 C R% e5 J$ a: ^
/ I' i/ q0 y- P+ G
typedef DWORD (WINAPI* TGetIpAddrTable) (
: r* ^0 m: F+ }& s) { PMIB_IPADDRTABLE pIpAddrTable,4 C4 u- [# T) ]
PULONG pdwSize,
: P7 G+ t- B- }# v BOOL bOrder
/ M3 C9 z0 ~) G4 a' ]);7 q& a. e( d" H3 N E
$ n0 h. S/ D6 @4 R! d- x8 }0 F. O
8 K3 S+ H, Z% S0 {! ^, _* Otypedef DWORD (WINAPI* TGetIfEntry) (% @9 Y3 _" N2 G/ {7 Y+ e q' _: J U
PMIB_IFROW pIfRow
% G1 H/ \# k+ o: \; P/ T+ V$ e);( _: _+ n6 l: d' U4 j
, C# o' L ^ c% Y( A; V4 t! Z' B
E9 ~0 l+ v, p: Q" }
CString translateUPnPResult(HRESULT hr);
( c8 S3 y6 d7 d6 a2 ^9 t* dHRESULT UPnPMessage(HRESULT hr);! i5 d# x8 b2 b1 b# t( ]1 T
& C5 w# y+ ` S1 P9 s( x# {
5 ^$ W8 r" @6 `" c' d! `3 Z( L( Zclass CUPnPImplWinServ: public CUPnPImpl
9 c3 j; F6 `% l J4 U4 N{
# e2 k: }1 z$ q, V0 p8 V friend class CDeviceFinderCallback;7 J. K/ I5 \0 c2 M
friend class CServiceCallback;9 v# v3 @/ N) y }( v6 T
// Construction% k; N5 j' _; K
public:
+ p/ }8 u1 ]8 W, ?8 R: }" e virtual ~CUPnPImplWinServ();
% ]2 o( q7 w* R1 ?3 C CUPnPImplWinServ();4 a+ B$ W/ J3 W' s6 H, D
( Y. `. f, G# ?- d8 t( {, k
* p! I+ ?. Y E& b7 |3 ~3 w
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }( |3 s; S" L1 e" ]& s
virtual void StopAsyncFind();8 n) q8 I0 J" W. n) g( D2 I' s }
virtual void DeletePorts();) G4 Q( M9 k% s6 w5 L2 P& t' ^
virtual bool IsReady();9 i/ E+ }+ g$ R+ H8 L& |# Q
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }1 Z. q& j0 L+ g' ?2 Q
. _9 T; k2 \( z; L2 c+ o |/ l9 Q3 ~; k
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. P! F9 @- K e3 T+ m. m7 j" ~ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later* I9 Q8 [+ |* o+ |3 ?* r" N
virtual bool CheckAndRefresh() { return false; };
6 E2 ] {! n- _: B; d/ O6 d' e& z$ W) L. _7 i s7 [
. P! a6 n/ d, g* ?) G/ s- P" b2 u
protected:
. L' M; }9 n2 E0 z0 \, Z, o void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; u$ @, ?: a; ?) D# ^ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
' @2 f, i$ b9 N, _+ E% Z1 s$ A, | void RemoveDevice(CComBSTR bsUDN);
/ E! ^) E- d* S$ R r& O) F8 u# Q4 W bool OnSearchComplete();
. H' L, I+ F# H void Init();' v# q; q% d0 |4 \* d! Q. J
- i+ X" Q& l4 s7 ~" D) X* r% K) @$ W6 i. C$ b
inline bool IsAsyncFindRunning()
! L8 z1 E( e' {' T+ j& `& q3 q {: k, }. G, b9 X9 _% W. {; l" p
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
' N9 x4 ~" c8 {; {( ?3 j {3 J) L3 e" T6 h$ I/ O& Q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( o& N2 D0 n& x% t+ z8 Z. Z- C m_bAsyncFindRunning = false;
8 u4 J4 s: _4 P- Y- o+ U }$ [% }" B! h d1 |" z9 a
MSG msg;
! l4 f. v9 X7 h% O. m, Y8 I4 @- e/ N while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )( G$ F) P7 m6 [8 ~9 a2 X1 r
{ G4 V" T$ y5 `8 F
TranslateMessage( &msg );
# X3 A" W% t, e$ @6 j+ u8 n7 ? DispatchMessage( &msg );+ T, ^6 I0 q. w! V
}
5 N9 w; M4 N$ e return m_bAsyncFindRunning;& \8 Q( i# t* Z- z' u/ j4 |
}# M8 Y; V+ W( G; A! A* V7 C* ?2 B
" U& S& f# v! K( g' ^% ?9 I, s9 x3 Z& s( U* D
TRISTATE m_bUPnPDeviceConnected;6 M( b; j+ j/ v; c2 z
+ c, j% e/ R. T' P
& t8 o8 q* I) x
// Implementation& `! X7 r$ W& f n
// API functions
n0 K9 c* I4 N1 Q" l SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);) E. N4 G+ Z+ S* y0 S! a8 \3 F4 {2 r
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
* q0 M3 Z, N8 m3 J: ]9 A4 `" U BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);9 J. O: K6 p2 Y" k0 Y4 r
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);4 K. P' t0 }8 M9 D
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
& s% \* A4 W. B' o0 V- J! u BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
3 j" _* R* F+ t, a5 t. O3 s3 w% w9 O- \/ t
* R1 ]' V; c# V t9 q D2 M TGetBestInterface m_pfGetBestInterface;
. \" i/ L/ o6 Q* S* E# V6 A TGetIpAddrTable m_pfGetIpAddrTable;2 J1 K( h: H% s. z; S0 S9 W
TGetIfEntry m_pfGetIfEntry;
2 I' W( e4 \# y Q0 P& y, ~2 _# U+ z* X( f' Y9 h
% X( e, E5 K# ]& a! S% A3 { static FinderPointer CreateFinderInstance();
! T6 W' G6 i5 F$ ^: u2 i struct FindDevice : std::unary_function< DevicePointer, bool >( S: ?6 i/ @* P0 Z( f
{
6 ]; O! `0 s$ D FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 L" `2 x( p: l1 O. J! C
result_type operator()(argument_type device) const
' }$ t: k- Z$ Q: ^5 x9 i x {. |! `1 s z: y+ D+ R1 X
CComBSTR deviceName;
7 b4 z8 R& k; \$ B HRESULT hr = device->get_UniqueDeviceName( &deviceName );! y8 H* W% N4 ]7 T' i$ s# q
9 P& h7 R6 }6 I, Q% R0 v
4 n1 K& f& L% M5 H; O3 X( A& l if ( FAILED( hr ) )1 {- z0 _" n) H. D
return UPnPMessage( hr ), false;
`- n. I9 G9 k* s8 Q5 S
- t( r6 R2 J0 k
9 T# I1 a0 i! Y8 v0 n8 o+ | return wcscmp( deviceName.m_str, m_udn ) == 0;
# L) }/ r, S4 i0 g( G" v: j$ | }8 N9 q. K: v) ]1 f
CComBSTR m_udn;
% I. {! P v% M' Z6 a };
" n H! @* W! k$ C
, b" s( U+ [: F6 l+ a3 |$ Y5 q void ProcessAsyncFind(CComBSTR bsSearchType);
]$ K; G& g9 g( u& o HRESULT GetDeviceServices(DevicePointer pDevice);9 ~# o E: v$ r& U2 \3 I
void StartPortMapping();8 T$ R3 S. o& B$ Q" G
HRESULT MapPort(const ServicePointer& service);
* E% n* W9 F0 `: I void DeleteExistingPortMappings(ServicePointer pService);
5 y& w6 W- N: ` void CreatePortMappings(ServicePointer pService);+ m) g9 [7 B7 M4 o% B3 F; D; K2 n% ^
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
$ P$ |, F- a. \- ~ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 {6 a7 C6 i1 K4 r% @) i LPCTSTR pszInArgString, CString& strResult);
( f0 l5 B7 c$ I5 I( } void StopUPnPService();1 M2 ?& L# { N6 Z) }6 y
4 ~( |5 u* L2 w1 L: E A0 b5 |7 ^
$ z( x; V0 v6 j // Utility functions
+ z# @6 S, ^, } z" v$ p/ e HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);2 ] \ w+ h# ]
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);, ]' J9 u* K4 M
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 x6 [# K; B$ t/ v, P7 r
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
& c) t% `0 w* e; _+ B HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);, m. I; b( e0 [9 b4 c
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar); j# V% A# n8 t% Y- J. W
CString GetLocalRoutableIP(ServicePointer pService);% v% F7 l* S# m+ N
$ i' b: M' x. ~ B8 E2 m6 Z8 }: r7 F6 m2 H$ ]! _
// Private members
+ K4 j/ U. ~: d6 aprivate:
7 i8 h: G$ I: |& Q% H# ~+ e DWORD m_tLastEvent; // When the last event was received?' j* O; h3 X& R% F* {! m
std::vector< DevicePointer > m_pDevices;
$ V, L% B( ^( c& [# E/ E: m2 Y. | std::vector< ServicePointer > m_pServices;9 j6 k, L* X# n( X. c
FinderPointer m_pDeviceFinder;
# b, _8 p1 @! p DeviceFinderCallback m_pDeviceFinderCallback;: v. [7 f- `5 _% C) F) q6 M }7 S
ServiceCallback m_pServiceCallback;7 D: ]6 o* v, B9 i% X
7 [! |/ V: ^3 Q- c j
1 D; O5 ?$ v- G2 @& {+ l3 f
LONG m_nAsyncFindHandle;( c( |' r- I: Q6 ?
bool m_bCOM;' K7 W$ t* l) S( s
bool m_bPortIsFree;
6 j8 i, _, N; h5 V. r: g7 P CString m_sLocalIP;& K, p+ f* ^; T6 K2 Y
CString m_sExternalIP;
) e- m0 J* V2 a5 m, o# v* o2 q bool m_bADSL; // Is the device ADSL?
& j0 j7 y/ I6 r bool m_ADSLFailed; // Did port mapping failed for the ADSL device?7 h: T8 H% Z5 i4 R
bool m_bInited;5 ~) s& }0 |+ y3 R: @6 h
bool m_bAsyncFindRunning;; v. l6 z E7 U5 Z2 G3 P: {6 |5 @0 k
HMODULE m_hADVAPI32_DLL;
+ B3 p! F5 ^- V# Y HMODULE m_hIPHLPAPI_DLL;. {( i+ \0 z/ _5 V6 Z# A
bool m_bSecondTry;- d$ ^. n) q2 _* n$ z1 t# z1 _
bool m_bServiceStartedByEmule;
6 ^5 V9 S, p' L/ n bool m_bDisableWANIPSetup;
* m0 o/ A. X2 o9 W' k" n$ I bool m_bDisableWANPPPSetup;
$ T+ W0 n: P& `6 J
# J: T. m; J2 p8 a7 D: ^0 Z% A7 g$ O
};
! O9 k) F* b) k: X, V$ d4 ?- |8 N/ y% X4 R0 y
0 E+ D2 O' Z3 W" n5 ~
// DeviceFinder Callback- @+ I8 Q' U- e" O' g* m
class CDeviceFinderCallback
, h, V$ L% K& W$ j : public IUPnPDeviceFinderCallback& R3 p) M. T2 E6 z2 V
{
0 h& w. V' W7 g0 ipublic:
( L& g& W1 ?/ E$ J1 m6 ] CDeviceFinderCallback(CUPnPImplWinServ& instance)
; W9 }$ v$ b/ ~* D5 y6 I* Z : m_instance( instance )! n5 C; q1 |' W8 h1 n
{ m_lRefCount = 0; }, [( e. E* L* `& `. J9 m: O0 V
3 k% L! c7 t& f) |
$ A3 Q9 T/ L' ?3 ~1 U5 K+ W9 ]; d
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ `: E- P! F3 y, u) Z! z
STDMETHODIMP_(ULONG) AddRef();' f! J% B; k: X# V; q
STDMETHODIMP_(ULONG) Release();
# w1 L A- I1 c, \5 [# D+ |' J* `( Y+ ]! C) X. P/ g
) H6 c7 i* m' {8 O) Q" Q. b
// implementation7 C8 B) { I4 B( ^; R" Y
private:
. m* p: `, |3 T# {5 k) V0 [* s* ` HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice); M8 _* Y6 e! f& ]2 v8 o' q/ {; F
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);( \ w# ~+ W1 O3 m2 ^/ n
HRESULT __stdcall SearchComplete(LONG nFindData);
: I. p- `' J0 n; B# V3 O* }/ n, x- l( i# {% i# h
& d, S3 b# r5 c4 L, J
private:
/ p9 ]4 G: P9 \3 c f CUPnPImplWinServ& m_instance;5 L4 F2 T, X8 q4 }0 j( r) c
LONG m_lRefCount;
/ n0 l9 L9 d/ N};5 d3 A8 N) J, p9 Z
* [1 Z) M5 b1 B
7 ^4 b v; ?; j8 O" X
// Service Callback 5 o/ F" }1 g. p( c% P& Z
class CServiceCallback
4 q7 s' o/ d8 p; W! M* C" f# u : public IUPnPServiceCallback# H. ~1 w" w! S# E
{
6 n9 l n; Y1 y$ y0 j tpublic:
" u+ o; d! K$ y H1 \0 @6 P5 | CServiceCallback(CUPnPImplWinServ& instance)
# e. b- i4 g) ]) J8 ?* a9 O6 C7 i' |* P : m_instance( instance )' ?' p6 J4 x5 ~8 h; D% t$ X% W2 ]
{ m_lRefCount = 0; }" ^( p; J! c/ L6 `
& q$ C4 e ]: a2 s# ~8 N STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ C/ V' D9 ]" s$ L* j8 q STDMETHODIMP_(ULONG) AddRef();
7 L2 u6 Z) J3 E* y/ V7 i' | STDMETHODIMP_(ULONG) Release();; l# k) F4 c4 i3 o. m
1 Y+ e+ ~8 Z5 P' R; `' c' {( ~" q, W/ s2 |2 u
// implementation
! b$ U& \+ W! M& |: xprivate:6 G4 U# |2 W. j: L. J) E; v
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);) Y" k; H. G6 H3 h7 e
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService); p7 i# U& Q9 T
8 v7 A; \- j4 ~3 }. a- a
; Z: v* x7 W) N* a6 m: M
private:
! i2 i. y% b6 l Y; M2 Y CUPnPImplWinServ& m_instance;! M7 v+ C2 }" p% F& J
LONG m_lRefCount;
: Z% _- _) i \0 I2 w3 s @};
( `# v% E- M! G4 j4 g* a( F! i9 w0 {- d4 Y# P! M" K. m( Z' n, S
! x" J' F3 C3 I9 W# N S: O9 z
/////////////////////////////////////////////////' c3 B/ o2 A* K9 R* }
) B( @. {! d6 ], V% m; m K
3 U7 T! ?2 E8 m' ?0 v使用时只需要使用抽象类的接口。6 c: D2 M) d& G% e* `& O2 g( i/ h
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.+ `' A0 i6 `3 g8 R6 n$ }
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
. B f' D- t4 |& u! mCUPnPImpl::StopAsyncFind停止设备查找.
5 N7 R- z+ b0 d! a, n" Z$ Y+ ZCUPnPImpl::DeletePorts删除端口映射. |
|