|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! _; `8 K9 T, `! v. w
. ?: B3 Z% x7 W
$ z; X) r, V" A% U: r- b
///////////////////////////////////////////# P' e) d6 n5 @# t3 Q
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能., r5 Z! K) H* q" n! o
9 r% w6 i- @+ Z# \6 t- X8 e. X3 S, O3 d" S! Y
#pragma once4 N) ^% D( h8 X3 G% W6 @1 |
#include <exception>
( V. b6 b6 n! a% H0 f) H) R! M: t
8 E+ d* |) P9 w& \- b1 P" B$ A1 n* e, c- r+ p9 h$ g# r
enum TRISTATE{
# ?: I- W- h+ N TRIS_FALSE,
7 D k0 n7 {6 N' D, i: V, r$ ^. o TRIS_UNKNOWN,. D) n" F3 p& G p8 n
TRIS_TRUE
4 g" |; x, ~: `4 W};) m4 ]+ m0 x+ d
6 i+ e6 i1 i2 m6 H% u9 U
$ ?" F" k8 f. E& [& I8 j( m# {. ?
enum UPNP_IMPLEMENTATION{
. H8 D" Y2 m0 W; v2 V2 y UPNP_IMPL_WINDOWSERVICE = 0,' I- H5 q. h1 h8 Z' n. q
UPNP_IMPL_MINIUPNPLIB,3 Q9 m5 q7 Z, F+ {3 v0 T+ k
UPNP_IMPL_NONE /*last*/
. D6 s: G) |6 q};0 a$ r/ Y7 w( }9 T, g3 M! M& ~
. h1 x: C, g2 U1 j) r$ S2 D- u: ?' g, w x$ x
! {2 O5 h7 @9 Q# Q/ {" }
! B2 @5 P" l7 J& }9 Xclass CUPnPImpl8 _% ^/ f# X) n, @+ |' C0 K" Z
{
h5 m m6 O4 _& Dpublic:/ W. D0 | m' N: w5 x
CUPnPImpl();: m" z3 w: t3 O
virtual ~CUPnPImpl();
4 \7 u; S/ c2 [9 X2 F0 W3 Q( K! d struct UPnPError : std::exception {};
& _ ~- E* j. D, y3 a8 o enum {7 ]+ h9 f3 u/ F( B! Q
UPNP_OK,) @/ h, _8 D6 ]/ [6 ?/ L8 s, T
UPNP_FAILED,: C3 `7 S! e( V/ {, t
UPNP_TIMEOUT
9 `0 x1 }+ K( M# B+ i };2 l5 O' {6 s% c) R& k0 t7 f& N
8 Z$ z6 s( Z" I8 W; `- A5 h8 @
5 V$ X0 C$ T: ^# z" G* q3 U w1 V virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
' W* v, v- X! K+ o virtual bool CheckAndRefresh() = 0;" k; S- x9 k2 U9 z6 z5 E8 E. V
virtual void StopAsyncFind() = 0;
: E- @0 ?5 F j virtual void DeletePorts() = 0;2 s8 C6 u, p" O Q/ m6 i! c5 O
virtual bool IsReady() = 0;
6 q2 ?, f. h# o7 J5 ?( Z1 L6 B virtual int GetImplementationID() = 0;
4 C; J& y! {0 T, H$ R# M9 h9 k+ M4 k. \ . C* [4 W9 {0 N+ S: X: {
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping& Q5 u" J- O& s v3 l# Y
& Z' {! J% I0 t% x: t1 s
2 `( ~8 h9 i6 h: I; k! N void SetMessageOnResult(HWND hWindow, UINT nMessageID);: m- U" o, y3 f' {' x
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }1 w! L3 k' J4 u) u. v$ {
uint16 GetUsedTCPPort() { return m_nTCPPort; }
5 {. M. t. C4 G' r" |1 [0 N# ]: T0 R, K' K uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 h' f, T8 z% Q6 J3 p3 ?% B6 V9 u4 P$ c% d ~ @
" K. }( c* a- j$ w# _- W
// Implementation' d! u+ [( o9 }. K( t# k
protected:. W* Z( ^% H }% ~) [! j5 K
volatile TRISTATE m_bUPnPPortsForwarded;
& C, N7 S/ B. L s% C- `7 }/ A void SendResultMessage();
- q4 ^" H: N; E uint16 m_nUDPPort;
& n: h( |9 q6 F/ e, q5 N7 O uint16 m_nTCPPort;/ e+ j# Q: L+ o) S8 N- e( T
uint16 m_nTCPWebPort;8 z$ O. J' x8 H; @4 P0 @
bool m_bCheckAndRefresh;0 f4 E# L6 r& P- z( G& s
- q8 I( W) P/ l. ]" b5 x2 h' f1 X
2 P' x. c1 ]% mprivate:3 F- u }4 e) @" t) F7 e" Z7 C1 P
HWND m_hResultMessageWindow;6 g$ n6 ^7 G" c0 S; l' n
UINT m_nResultMessageID;7 q! y- P- b u' J1 L) V
* ]; i% f/ F' M3 ?
1 |, P |. C3 P2 K, H9 p7 s
};3 R7 {0 }/ g: r9 T# d
4 ]. W0 ~2 x/ K+ [! _# h
2 n- C" w8 E7 ?) r* u4 h2 B( }
// Dummy Implementation to be used when no other implementation is available
8 F& y7 T2 T# e* B; l4 @" X* U' jclass CUPnPImplNone: public CUPnPImpl
5 p( |2 B0 X0 e" i( A{, s0 X V! @6 \% l* H5 Y
public:
8 r+ B+ Y5 \+ ~9 \6 \! f0 n virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 M& B; v+ B( b4 R* J virtual bool CheckAndRefresh() { return false; }
3 y& r5 _0 l+ U- ? virtual void StopAsyncFind() { }
3 g# T; s: D1 n2 H virtual void DeletePorts() { } A+ R L6 y4 Q, N; ?8 U
virtual bool IsReady() { return false; }
2 H. S4 f* T9 Y& ]$ y0 O* w virtual int GetImplementationID() { return UPNP_IMPL_NONE; }# o3 |- _, w9 D0 z* ~3 s6 K6 U) d
};
6 i: }$ h3 p% K& X2 }1 {5 L c' a' `5 J0 u% g- l$ e5 S0 X& k
! [ u( Y& S1 d8 k6 u: l$ |, j
/////////////////////////////////////
. t1 l$ @4 V2 J# f//下面是使用windows操作系统自带的UPNP功能的子类
2 i- `8 m" _9 N8 C0 M* { M6 B
" \) I. B3 p" ^$ R1 Z2 X7 V7 v: ]! I; x( N: D
#pragma once
) r& o3 |9 ?( b$ `#pragma warning( disable: 4355 ), Q+ J- C, \4 l3 R8 n) F6 [
4 c5 ^8 h2 X/ K" U
5 a6 R+ f, b) Z8 N4 P) v8 X#include "UPnPImpl.h"( H8 F" x, {$ m+ P/ n
#include <upnp.h>
+ B2 k3 O8 ^) S$ a0 W#include <iphlpapi.h>
% Y4 g5 }# b# H1 q* q I#include <comdef.h>
' q, B% K; S# E9 F( [#include <winsvc.h>
! W! i* H9 v! _ O; H5 [% Y& T( H" w# \. t" a: i5 C5 ?
: O: e; [. `* }#include <vector>
, R! H* y6 h3 o/ P; |/ a# z#include <exception>4 j: G& `; V; [8 X* P
#include <functional>
4 B. H/ G9 r' m5 i# s7 S
; k/ }$ C7 S) y1 n9 {* i3 _4 Z! x, F: }+ K4 m
/ W) ~/ Q: h' h" C
# I0 t- Z; [+ J# t; o
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
/ G' {& E2 z" z+ s; \9 u y: ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;+ H! S- U& i0 ?7 J! Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;9 b, W; {! w7 G8 B
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;( t" j) u* J# _/ A. h' u
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: I* r8 W' y$ J
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
- d, g2 q/ M2 D% T2 G5 g. Mtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ y" `# ?2 T3 B
/ ]6 Y) ]! Y( P4 F/ x9 X Z# n# i2 l2 v! {' M
typedef DWORD (WINAPI* TGetBestInterface) (
% n( U4 M1 c5 m/ n+ Q3 h* g IPAddr dwDestAddr,
5 A" t0 H* J) r- j( T z% S PDWORD pdwBestIfIndex! S9 \( O2 i( x5 ?2 J9 [
);
4 m+ [% w3 o9 ^' |% @
1 d+ A$ r& W3 ?% {5 n! z! ~' M8 ?5 @2 Q! \# z' t- U. ~
typedef DWORD (WINAPI* TGetIpAddrTable) (, d) ?% c0 ?; H, Q
PMIB_IPADDRTABLE pIpAddrTable,8 s: G$ s) u; j
PULONG pdwSize,
; O% ]% A- k3 ~: M, d! a3 \ Y7 j BOOL bOrder
4 S Q) r! X" b* _4 w);
' h& y0 R4 z# c7 x% b# M0 b5 h8 r9 F9 S0 w! u# h* ^/ O
' R3 s9 n2 x7 [7 K0 J; \typedef DWORD (WINAPI* TGetIfEntry) (& u2 M, k9 b5 e8 I* i# _; G
PMIB_IFROW pIfRow) m; z. S: T/ M6 V8 |
); ?+ E) Z. s' Q6 K' G8 z6 x9 J
, {4 H6 B; H9 g) [! J
/ d# p, g' z$ s& a! [/ Y
CString translateUPnPResult(HRESULT hr);% [: E' M+ K& r k8 S+ D4 I
HRESULT UPnPMessage(HRESULT hr);+ x) Q/ b$ j2 Z! k: E" S5 t& S9 v
+ }$ I8 G9 W6 u7 A
S4 J+ w7 V. @3 v8 D- o$ pclass CUPnPImplWinServ: public CUPnPImpl' A, L( r) G$ b V# b
{
. I9 g# M) e% Y- R friend class CDeviceFinderCallback;; _0 [4 N& D: z( v! O7 L
friend class CServiceCallback;
; k% J9 [# ?" b/ j& |// Construction
) e& M6 q+ W4 Qpublic:, D5 H# \ u* `8 i' Y
virtual ~CUPnPImplWinServ();. ~0 s% b3 e! d8 c, M
CUPnPImplWinServ();
2 b! O4 Q! O5 ?/ R0 d. w
- t5 Q& J# _( b3 {# M# y7 U0 F p- p+ S" \3 {
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }5 u. j7 r' Z. q0 K$ l2 m
virtual void StopAsyncFind();+ u0 \+ S- Q* D5 a- A$ b
virtual void DeletePorts();0 k- Q! [. k. W" }( v* _9 @( }
virtual bool IsReady();
! n& {% r! _4 Z, R* r3 x" j9 L+ o virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( a% |# G( y9 A# j
( V& v" b5 [4 D7 {5 d
q& y1 h+ a# |& N3 l
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)) t5 k9 V* I! z: Z5 }8 M
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 L6 S7 w4 \% }9 U virtual bool CheckAndRefresh() { return false; };% V+ h Z- A4 M/ Z0 V! }8 j9 [: t& ^
' Q) C, X v. f5 ~8 [% A
' t) M+ c1 @" T) b l, fprotected:
3 o1 k3 f6 G% w4 `3 C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- A2 N- N& M2 @' O7 x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);+ H- x* d" ]9 m
void RemoveDevice(CComBSTR bsUDN);
% N8 u9 |/ V, [5 i5 ] bool OnSearchComplete();. U5 |1 E5 L: L1 a8 ]: {- u" g
void Init();
, o1 ?1 o( m1 Z0 ]+ j" T( |0 k$ A- o! `) w
) Z6 f8 _8 i+ F9 @ w2 l inline bool IsAsyncFindRunning()
! [% D2 |6 K1 \$ P# Y. g8 E3 Q: W {
" l- M9 ^6 p; _- _ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
6 D* C) ]1 |7 u0 M$ i0 a {8 q9 U, F a V2 e" w8 F: N
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ E% Z$ f: i5 r0 H" l( G
m_bAsyncFindRunning = false;
6 \7 @/ K6 u* u: g }
' A+ B. c1 `& Z1 t MSG msg;3 k0 E3 D1 ?# b/ P: N
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
( Z4 c" H4 k! V* c {7 q7 i6 v6 b1 c) q8 T
TranslateMessage( &msg );
# [& i0 l v1 E! R# K. R6 R DispatchMessage( &msg );5 x( T& n4 d( R1 {
}& k/ W4 V$ h* M- o8 Y3 D M
return m_bAsyncFindRunning;- q. U& y3 h1 U
}
" ]# ^9 E' {2 n/ A
' F0 |) q6 U! D6 M N, S) f. ^5 a* |1 L7 p
TRISTATE m_bUPnPDeviceConnected;) g9 q7 i: c: ~$ P( n
7 {& N' S* A8 P
5 L! A. e( D- R& ?& B% K0 _// Implementation
. \% f. V' M. N) g% n2 f // API functions
6 b. l( g/ N& N$ V4 b% W SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
# _: S+ `* P6 }* y; ~ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);0 c# n. w; F j p0 Z9 G9 p
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 q) U2 n" O u+ _ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);. Y: {" ~. p5 W D4 [0 Z9 }/ z1 L
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 P9 z- H* F9 M
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);% Y+ z# ] c9 e% Q1 R( C; p
% ^( V6 |9 |, u+ J) c: x: V" S9 `* p! T# c- j
TGetBestInterface m_pfGetBestInterface;
( f! ]1 |7 k* H4 L$ J TGetIpAddrTable m_pfGetIpAddrTable;
+ Q0 R4 l* n& J1 X9 Z2 V TGetIfEntry m_pfGetIfEntry;
0 h1 g3 X& I# |( J3 H4 L6 q, }4 w. `. z" v+ |% \9 j3 _& \
6 v+ ]9 E5 s$ ^% r* U4 e static FinderPointer CreateFinderInstance();# r# i" [* a! X9 C8 \, j' q
struct FindDevice : std::unary_function< DevicePointer, bool >
* ~% F- ^, t5 I6 w {7 ^/ p8 p3 b7 h- S1 R) `
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 w3 A$ u& @9 ^# J6 J# u, K
result_type operator()(argument_type device) const
) v, ?7 c# ]- t {5 p7 _1 j+ ~! R9 g, |3 |
CComBSTR deviceName;
5 U$ v% A4 X0 @7 E0 H6 K HRESULT hr = device->get_UniqueDeviceName( &deviceName );
$ ] Y- X1 _6 R/ P" s, V! i
3 U8 h! N# N: T- |, V: h3 l) E% w7 ~9 ^ m0 C, `# r* {: x
if ( FAILED( hr ) )
/ s. _) G( }! H( J6 f% H( Q9 }4 | return UPnPMessage( hr ), false;- w& n2 ]2 V* g+ H2 V& D: a* u3 O
4 A6 E. w$ |; }$ }. T# w! M8 `- K
! ?. S" U( n# `5 H% N( p: A7 {
return wcscmp( deviceName.m_str, m_udn ) == 0;; r+ b% m/ U% I1 `6 A: [) e* V
}7 b3 y- Q% h/ {- q3 _
CComBSTR m_udn;1 |& _8 g7 \; M4 e( K- D
};( R) Z. Y/ v7 T
( c; p) Q# l: V8 A5 L' C% b void ProcessAsyncFind(CComBSTR bsSearchType);
. y% O, r1 {: F; B" ^" z' C1 o HRESULT GetDeviceServices(DevicePointer pDevice);, i2 e0 o+ |/ @6 b4 ^2 ^2 s
void StartPortMapping();; e; S4 i7 B5 d0 |: M
HRESULT MapPort(const ServicePointer& service);
" j# j' ~' `) p* o8 P; ~ void DeleteExistingPortMappings(ServicePointer pService);
A( D' C4 @7 K$ r. s9 c void CreatePortMappings(ServicePointer pService);
1 S6 C- e. j4 ^. F5 z HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);% [& n/ N( i' H5 _( g
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
( `( g X( J, l! D8 M: E0 }3 Z7 ? LPCTSTR pszInArgString, CString& strResult);
( s1 Q* c- O# e void StopUPnPService();
7 V9 r& w9 T$ E. L
* o' a& W5 x, [; g; h1 C0 z0 ^
// Utility functions; x5 C3 L9 r9 }$ `7 i( N
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 [* m( r. Z( H ? INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
; `2 [. {4 S+ x% [ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
7 ]' s4 R& G+ F8 Y void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ b+ ~9 v) f8 t" m/ n0 m
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
d8 q- ^) m) W) K7 w, b8 \( T HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
# C/ k9 d! S% b2 w4 p& N0 c CString GetLocalRoutableIP(ServicePointer pService);
" i- l: @( }5 ]6 A" S) I! @
# v7 G& U1 Y7 D+ @. ~
: d/ N8 L8 c# f% c// Private members' v. K6 U1 K+ m9 F
private:
0 |2 T/ A! D$ q3 o" Z8 j* f DWORD m_tLastEvent; // When the last event was received?
- p5 P/ T1 l9 p3 W. Q std::vector< DevicePointer > m_pDevices;
! \/ b7 w9 U# _/ r L2 B8 _$ o std::vector< ServicePointer > m_pServices;# D3 G# E- ?5 S7 q! {
FinderPointer m_pDeviceFinder;
* f* I$ W: k% O DeviceFinderCallback m_pDeviceFinderCallback;# S- C$ a! N+ T+ L$ h
ServiceCallback m_pServiceCallback;
* N: k, g- T& s y6 r
, @3 {3 A1 M) p" s; h3 } K" G$ m& X9 h1 N3 X
LONG m_nAsyncFindHandle;
3 n& ?$ v* h$ A- E* M1 y. W, y bool m_bCOM;
! U7 Q: b6 d- R, B0 q bool m_bPortIsFree;4 x. X( A: f' R
CString m_sLocalIP;3 d! q2 F0 e# _0 P/ S
CString m_sExternalIP;
+ ~) ~! w9 T6 v% v) ^- p% \. [ bool m_bADSL; // Is the device ADSL?
% u4 E3 F- M4 A O' `6 b" M0 l bool m_ADSLFailed; // Did port mapping failed for the ADSL device?6 w, O1 z+ E8 `
bool m_bInited;
/ h" C0 l p* p: \( L0 y+ F bool m_bAsyncFindRunning;/ g: R! ?' n. ], u4 ~: E% u1 ~8 j$ Z
HMODULE m_hADVAPI32_DLL;
# ?+ b, v* h$ N! F% _+ F HMODULE m_hIPHLPAPI_DLL;2 v3 m* `/ w& S7 p* Q2 [$ ~
bool m_bSecondTry;
4 j1 J- s. s o, t; k h bool m_bServiceStartedByEmule;: F3 q0 I7 X0 T8 I
bool m_bDisableWANIPSetup;
* z3 d |$ i D6 r3 z! w bool m_bDisableWANPPPSetup;
6 u/ Q4 Q2 H9 ^( d3 M4 O
4 I% |+ E5 C J6 {7 K' q( U8 G" c, C# D
};
2 y2 Y8 ~$ ~7 |1 c2 [ a$ Z( s; Q/ V. K* U* J7 g$ B# g0 F2 y
; a0 R0 S$ H4 Y2 g7 [+ ]+ f4 C. ?+ d
// DeviceFinder Callback
/ B+ X% c0 `% |2 o3 y, gclass CDeviceFinderCallback
9 h9 ?& a$ K2 y4 u! U( i, C : public IUPnPDeviceFinderCallback
5 t: p0 I; U2 K. A: g, _& t U{
6 V, K& N1 ~1 q/ [0 f5 \& Wpublic:* z1 v6 V- B1 L. P$ x/ `
CDeviceFinderCallback(CUPnPImplWinServ& instance)
N5 O1 C \6 d9 @" K$ f4 } : m_instance( instance )" |, O8 j& R; ]
{ m_lRefCount = 0; }' t0 u1 r' m/ p3 J; O
+ v5 o; Z' I& K/ W6 s- G# U0 P9 ]* v: ~3 f* {; H. g7 U, D
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 F9 B5 L9 E9 ~& y/ `0 t } STDMETHODIMP_(ULONG) AddRef();7 Z$ o) a! K$ I
STDMETHODIMP_(ULONG) Release();
4 _* Q6 c. E5 H& l. ]9 u9 i) d
# w5 Y" v, T! w) A0 Z" P5 k/ |( o: v1 q. l, J5 C) U
// implementation
! p7 S. C" L: V. J; mprivate:" d0 S! @" }+ ^4 j H
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' W6 D6 |8 Y3 T HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
6 U- g& |% T% f HRESULT __stdcall SearchComplete(LONG nFindData);
7 j$ u- h8 c+ G% n7 E( l E5 z
8 T$ R) j7 R8 R" _6 ~' _8 u% }/ R# ]& s: v: b+ m6 z
private:
( S0 K+ K3 V5 Q D& [ CUPnPImplWinServ& m_instance;
6 U0 x' q3 x) D$ v6 J LONG m_lRefCount;
, G2 i, ^. N A- D! {. @};
% O' _" o, n* n r& ^" ], {7 M+ D. W
' p$ |+ W5 _' R% @+ t
// Service Callback 4 e" O9 @& j6 j! p
class CServiceCallback% T+ S( L# p0 n, D! I
: public IUPnPServiceCallback2 p: ?' K7 j* f5 N0 a( L
{" R6 G V3 X5 ]
public:
# w1 z G) C6 A$ k CServiceCallback(CUPnPImplWinServ& instance)# r3 o& H# O; ]9 P$ \ j7 C0 u$ c
: m_instance( instance )
" N1 K! T, ^7 ] { m_lRefCount = 0; }
6 d4 @: r' c8 {3 \$ a8 w, Q9 s # D! Y6 x/ V$ L9 p2 O7 v3 M
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 c! D- s0 r) Z/ t2 k: c STDMETHODIMP_(ULONG) AddRef();) V7 ^' O6 }: s7 n
STDMETHODIMP_(ULONG) Release();
) w4 E# {: d; V H1 j0 K/ B& X7 S& P" {
+ b& p+ t6 W& g// implementation1 O: [ M0 w; e2 |
private:! H) G5 r5 I7 L
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
) i. ^" \3 u& M HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" A( Z- o+ r$ [0 f0 ~8 r. C* K
~# w4 K) L1 v9 c* [0 a
/ k$ Y: i. U( Y0 v/ b% Fprivate:
- L( D: F& W# J% G CUPnPImplWinServ& m_instance;
- E, I5 a r' T9 D LONG m_lRefCount;1 v; ]( o2 d" l2 _, _
};
/ v/ n0 y' S1 ]% e' ~
- B2 Y5 T; ] f" J2 ^- ]6 V
+ M- z" k' ^9 A+ X/////////////////////////////////////////////////: @- \" b( S" R& Y0 u+ |# e
" t: \0 I# }+ ~$ f
! Y" u; g2 g$ {% C" }9 ~) l( s
使用时只需要使用抽象类的接口。/ p! Z. @! ]3 f+ `
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. @$ d w( F' M! @+ G6 h2 k
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 I: W9 b: O9 ?2 p: U* q( C
CUPnPImpl::StopAsyncFind停止设备查找.( j! U5 U( H9 I" C
CUPnPImpl::DeletePorts删除端口映射. |
|