|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
% X2 R8 n$ V5 S2 `* w v( \# Y, F# H l$ ^
% c1 b4 J8 n, I Y
///////////////////////////////////////////, V* `$ `# ]2 \4 Q9 f4 H
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
* f/ }# c3 ^. R3 m- r7 z# p" B+ u" ^- N
& m0 d7 O) |# j! }#pragma once# U# p) @, b- u. b6 q6 m3 K& _: q1 ?
#include <exception>
5 E+ V4 m) i6 q; t% R
8 J3 W3 P3 W i; z& `" I3 X, Q- u: T6 @0 q, e' }( r9 h- D
enum TRISTATE{* l5 i6 }# Z# N B
TRIS_FALSE,# R0 s. I k/ [
TRIS_UNKNOWN,3 h, V5 z) e' ?* F
TRIS_TRUE$ ?2 d+ [3 ^/ T" p8 p7 Y& ~8 H9 ?
};
. J' i2 ?+ E4 A/ `4 O9 j- ?. H5 h( q' E
" X; u) F3 e3 n' X
enum UPNP_IMPLEMENTATION{
9 h2 V' Z: i6 @ ^2 j3 W j0 C7 B UPNP_IMPL_WINDOWSERVICE = 0,, Y/ t7 E+ Y" a s
UPNP_IMPL_MINIUPNPLIB,
& [- @8 s8 E6 P) d& z UPNP_IMPL_NONE /*last*/
8 V; w/ S1 m" `};
, n' D+ K- |7 s1 J( J; f8 I. E0 C% n/ \
$ n6 n1 s3 G1 r& D# B% `
4 \: {2 V7 P$ w* d2 ?1 |
% G! \' U8 q* P Lclass CUPnPImpl
9 Z3 U. [! c; o: [{$ I; Z$ _" K% B% i! b
public:) x$ N) J" G4 T$ ^, ]5 T
CUPnPImpl();
- |' c3 j/ d: V# n0 k virtual ~CUPnPImpl();
2 c& M, i. e& m2 J) H struct UPnPError : std::exception {};
+ T: O9 P0 K$ r0 b8 v5 S8 Y/ z enum {
% r# z" |7 T; g3 _6 L5 ~* u6 ~& N UPNP_OK,8 s. h2 @/ S9 H* K. j* Q
UPNP_FAILED,6 I- O2 W( i4 E4 u
UPNP_TIMEOUT- d) J0 q$ c# x* o. q$ m
};
0 b) U/ o Z7 M* v- b0 Z4 C8 C# I' g6 |, `% E' i+ q }
9 t6 V `( v& y' v$ k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;+ u: G% T& d( I9 A& \
virtual bool CheckAndRefresh() = 0;
- n" P9 L1 A$ F7 O" i) B virtual void StopAsyncFind() = 0;: J* F! Z0 ?9 c) e0 l. Z
virtual void DeletePorts() = 0;9 E6 ?' h1 \, c$ T- ]/ K
virtual bool IsReady() = 0;
- t b" `# H2 B& {& h- M& U* b virtual int GetImplementationID() = 0;
# d0 @0 U" v" J$ U% g: E1 U# y& V 8 h1 [( Y$ W, q1 I) m9 u/ N) M
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping* P( o1 Q2 Z3 x# E$ G
* ]: n( I8 |& ?0 M) g
% t2 p/ G: }* h: ~( i void SetMessageOnResult(HWND hWindow, UINT nMessageID);2 [. }2 V6 g0 T) j' G- j# P7 K
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ E, V2 Q; o$ m5 U; P uint16 GetUsedTCPPort() { return m_nTCPPort; }: F4 `# n8 ?! O* b( I' N8 ^+ k
uint16 GetUsedUDPPort() { return m_nUDPPort; } + ?, v6 O" ?2 W0 V' I( Z) `
3 G" Y. {4 x; _4 J* f; n( C! d! C: p5 Y
// Implementation
' O, @: f6 f! E$ t7 N s; f9 Lprotected:
+ s' Z6 X4 _, T; O4 B volatile TRISTATE m_bUPnPPortsForwarded;% q0 s8 K/ R6 m- V. Z2 e
void SendResultMessage();
& P7 S) W1 r9 S) e uint16 m_nUDPPort;$ r D, i+ ?; {. c& _. ?- Y$ n( M# h
uint16 m_nTCPPort;8 s. P) K, Q: [3 b/ K2 I9 h
uint16 m_nTCPWebPort;7 ?6 r2 m3 \7 C2 H& ^4 U$ d9 }
bool m_bCheckAndRefresh;5 v% N2 F+ D8 R: @3 ~4 V
, D7 Q9 O* y* `$ v( X
3 ]- }4 r; i5 }% U, `' V1 F6 @7 I
private:8 }* B( }! V, Y. o* ? M$ C w" C
HWND m_hResultMessageWindow;3 G' t# M" y7 ^4 @% k8 {1 t
UINT m_nResultMessageID;2 ~( z. Q- O* R$ r; {- a
$ \( [! |1 U# |
?! b) a, b& Z9 Y. Y! I1 M
};4 O( X8 Z6 {" H
- D5 ~% @$ F+ |. {+ w
0 h o, C5 r+ a2 P/ ^! d0 W) v( d// Dummy Implementation to be used when no other implementation is available$ G% k6 I+ h1 z
class CUPnPImplNone: public CUPnPImpl
/ L) m! p$ B3 B! j% `* A8 Z5 O- ^2 W{
5 ?# K: v1 v3 ?4 opublic:2 l G; ^/ K# b* I' p
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }7 N2 t& y8 H3 O5 u" w
virtual bool CheckAndRefresh() { return false; }9 V9 h7 G5 [7 _, `: n5 b
virtual void StopAsyncFind() { }- A" Q7 e1 @. p: n0 A' N! o; Y
virtual void DeletePorts() { } C Y) L, Z) `1 O3 ?
virtual bool IsReady() { return false; }9 }) G% j, t& h2 }5 g( s
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) e! q& j7 E6 x! |( s6 p8 |};
; V: i! ?( R. V% Y: P! B: @( W. ]. s% b v! u: U/ j% L9 X" y
! M% E+ p0 ?) D' |1 c6 r/////////////////////////////////////. O" h c! f: \" n7 t
//下面是使用windows操作系统自带的UPNP功能的子类
( P7 X, U1 F2 x: t: q. m! z9 G; j# a% f
2 v% C( Z* T1 C) C# I4 A7 U, I1 [
#pragma once
; o& r' \& k, |& g# ?#pragma warning( disable: 4355 )- f' q0 t6 |# C6 J2 d/ _( W3 c
, l! y( j3 e+ `' S6 v
& l/ P. q, ?% o0 o J; ?' R
#include "UPnPImpl.h"
: J; Y" E$ p& N' A#include <upnp.h>
3 n5 ]4 H5 v! g$ n4 t5 g$ p& s#include <iphlpapi.h>/ L7 w% D W) F
#include <comdef.h>
f% `" ]. F" p. j) I5 m#include <winsvc.h>
9 g- O" ^. B% ~; _
2 ^* J& s @- s! _, u2 r' D' e7 }" d; l) V6 Q
#include <vector>
. l* o) M1 F+ D- f1 ~& d, l#include <exception># X1 g0 J0 p$ x* j* A
#include <functional>9 e1 q$ N) s; ]* e& ?
( u. x; m8 G9 x; L3 \
# U g+ P5 b/ ?0 v. Y1 ?7 R# c4 s% n2 h! c W
7 R1 X3 @# O6 gtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
9 k0 X. x7 N7 `+ otypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
3 @0 G& Q/ T! J" s2 Utypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;3 t- @; Q7 x7 H* {! T" B1 n
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ h: Y. v* X# _typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
8 y, C( X' s7 s6 }( W/ ttypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;* @: Z! c, V$ F! U3 q1 A
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ |; j# m% |" |& A2 S
( t7 B8 N0 q* R/ o0 D; } V# b. n% K/ r9 D7 k8 |( _6 B
typedef DWORD (WINAPI* TGetBestInterface) (9 q: z& Y, E* U
IPAddr dwDestAddr,
( I) G( k" \9 C' z2 [ PDWORD pdwBestIfIndex, _% D& C- Q M: M X
);) w+ ]* I! U$ r! `- Z; [
s! D" D. C9 }/ |( Y7 ?- M! N( s9 e" r1 G+ }7 O% \
typedef DWORD (WINAPI* TGetIpAddrTable) (
9 Y2 }9 x0 g# w. ]. T1 | PMIB_IPADDRTABLE pIpAddrTable,
" O4 u. @' ~/ ?* }$ a PULONG pdwSize,
+ R* f/ h: X3 a' l, W2 F6 w; f BOOL bOrder
+ J2 o: k5 H2 s' E G);
5 H5 w. E0 L: I1 q# a4 Z9 P. z/ f# `$ Z2 A5 M+ K
% H# p- c( Q: [' K, otypedef DWORD (WINAPI* TGetIfEntry) (7 k4 [: N7 _. ]8 s
PMIB_IFROW pIfRow
* }5 U" k( A G);* |1 v4 `4 v. G V* d& U6 ?# n& Z
1 v8 U. ]7 h) k C- u8 |8 ~
6 d3 e9 |, F2 }" ~CString translateUPnPResult(HRESULT hr);7 k9 ^8 g/ [6 f6 |' n( r
HRESULT UPnPMessage(HRESULT hr);
( y- i3 l: a* n' d1 U u) |# c/ R+ N
. X5 u. X) A+ ~5 D8 Fclass CUPnPImplWinServ: public CUPnPImpl
8 ?/ e3 ~9 N1 g2 V! N0 J, Z3 l{8 N( ^- y5 P' C$ J
friend class CDeviceFinderCallback;( K$ s! U' }( i! ?
friend class CServiceCallback;; T! k* O/ J) G, A; ?, z, _
// Construction2 O' z) x, h+ ?& V6 s
public:0 i) |) z8 f, ` h; V
virtual ~CUPnPImplWinServ();* E+ p5 Y/ {; j% d7 b! n; s$ s
CUPnPImplWinServ();3 D; {: N; Q& s/ u, g* G' W
( ^, d0 x: H }; I# f
. C$ M1 n6 u* w' r
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }2 e( A& S) O R4 F
virtual void StopAsyncFind();! H/ V- v4 l6 e8 B2 p) P
virtual void DeletePorts();% Y/ w) R1 B$ E7 {! ^
virtual bool IsReady();# W& r9 P/ Q6 a. ~1 j, w4 b9 l
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
& p3 m, V+ t; e( {7 ]# B) p) j6 e" K i( @
' Z+ w9 A' x. e& Z) J8 ^- l! S // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% f" T% A9 p6 W/ m( F! W // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
, A$ m ]7 P2 K: L virtual bool CheckAndRefresh() { return false; };" Z$ z. E0 P. ] Q2 f' z! M: Y q L
6 R3 @0 v. s/ O1 q. @7 W, Y7 H3 \) r6 Q$ ?! i& Y0 |
protected:: a9 |7 Q4 _' A$ m1 h
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
: p9 d( b4 O7 u4 \ i( l void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);" x5 p3 d8 @& _: X8 U
void RemoveDevice(CComBSTR bsUDN);
' l! {$ b& A+ z) r: ~ bool OnSearchComplete();4 s# J4 R7 u8 V9 D w G6 A
void Init();
2 X& t4 f. r0 G' Y n- C' s! f5 K( T6 w, o4 g$ b# @
% Q+ R5 E Z/ [9 X0 ]
inline bool IsAsyncFindRunning() & U$ }1 r. N' i1 A) p! [
{6 D1 D9 H1 Q h( r9 Y7 F8 `
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 b2 r* O i2 v+ B( [( h
{
- E2 U \- P# v. s! I8 ]' \ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
# T8 h1 e8 H* Q$ R$ X2 }8 X6 c m_bAsyncFindRunning = false;- K% K2 q: S) h% K# ~
}# [( C8 K) h9 R& n6 K5 C
MSG msg;
) F* O( p1 z! M% H0 G$ |5 { while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
: J/ k$ w# B6 E. U8 j; r3 G {
1 z+ I0 P. @* N6 G1 e/ ^7 A TranslateMessage( &msg );# D: X- @& T) ^8 h" m
DispatchMessage( &msg );
0 O, i+ V- e Q: ~) E" F. e2 V }) }; p* o9 ]9 _: X9 D9 k
return m_bAsyncFindRunning;$ m: C1 H U+ c [- ^' q
}' Z6 E0 B- p5 B( J! P
. x- R4 W* A3 h. N. r) z) ]
) J# g4 `5 ]; o: A5 \+ q TRISTATE m_bUPnPDeviceConnected;" `! X0 s/ c4 V: W( F7 _: m6 G0 u0 z
+ H, F/ J& @1 r* `6 h
! W3 Z8 ~6 ~' D @// Implementation8 ~: P" s4 ~9 F1 ?) A9 W( i4 o
// API functions4 W) T! [9 h7 A; Q6 j4 |7 @
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* \' F" b; w, D( f1 G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);& c* W+ c. I1 }
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);8 @5 D) _& |% c4 L
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);# \8 ?# ~* }& B9 j; o5 w6 s
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% B- ]3 @" @, J7 ^9 H5 X# i2 Q6 A
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);# l; K7 h. T' W2 G& L ~
' q1 T1 ^2 h7 E
' w. g: E7 N1 D& M' Q
TGetBestInterface m_pfGetBestInterface;+ M7 Q* H) c4 H: Y
TGetIpAddrTable m_pfGetIpAddrTable;6 m S( N/ G+ I5 }/ z- b& O5 o1 G; e. \
TGetIfEntry m_pfGetIfEntry;8 W+ A8 z# d* m" O" ^# I3 M2 S
* Z- u! Z! B, j- `$ a* h
9 L: B: F& ]6 Z E& C6 E1 ^6 g8 N( A static FinderPointer CreateFinderInstance();
* m( U, I# [% i' L9 S struct FindDevice : std::unary_function< DevicePointer, bool >' ^" V% ~1 v2 D
{: r5 t+ k9 @6 ?! ?: X3 X9 X
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
! K) A* g9 W! a$ ?( W; s( r result_type operator()(argument_type device) const7 W! z$ ?7 k5 E. i- C
{% n( U5 ^/ Z3 _2 z; r
CComBSTR deviceName;+ ~* B' m+ x2 z3 a6 ~" W) C7 B
HRESULT hr = device->get_UniqueDeviceName( &deviceName );4 p* `+ Y" L5 N) C7 r" p3 ^
5 ?5 N$ Q5 ~8 u Q" g
3 r( U L6 \* U) P" `/ Q. u if ( FAILED( hr ) ), J, U1 F: R8 n& R1 s3 l
return UPnPMessage( hr ), false;! U4 K& o0 r3 {
( v! c" x+ I" r, g4 \( B' Z: e! u/ C* r8 S- a
return wcscmp( deviceName.m_str, m_udn ) == 0;$ S* [. h- T5 g( ~" J$ \# E
}4 a) ?6 |' N/ E P) a
CComBSTR m_udn;
. t, u/ D1 `/ D- Y };
0 d$ ~$ c# b' M8 r# X7 I- v
! b; `/ @) g Y& g void ProcessAsyncFind(CComBSTR bsSearchType);
; s7 J" W; G' E v" Q HRESULT GetDeviceServices(DevicePointer pDevice);
D+ f2 P4 ]) C7 j2 C' N7 L3 W1 Y! d( } void StartPortMapping();2 U) y4 ?2 o* K9 B) U$ g: @
HRESULT MapPort(const ServicePointer& service);
8 h" J; R+ C5 c" H4 I void DeleteExistingPortMappings(ServicePointer pService);
+ e( y. O. q, t+ E7 C9 {. K7 W ?4 c void CreatePortMappings(ServicePointer pService);
7 K5 ^8 p8 @' X. j9 D. [: ^# B" E9 o HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 R& @, y3 K0 A$ s0 ^' r5 y
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 2 ]" P! y) t2 f9 H
LPCTSTR pszInArgString, CString& strResult);# r) ^! _/ s" J3 v1 Z7 K
void StopUPnPService();& A* ?0 ?% j) K# e0 W
, _: P8 \ K, W2 L, s, |9 {3 A4 B% a
- K: m7 |) `4 ~+ f. N; T
// Utility functions1 K8 Y. a/ m+ Q& @) Z6 f$ |
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
# Z9 g; |: M/ S& M) W INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);3 }) B/ V# y* t+ Z
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);# o9 o: W/ Y3 i, }( z1 u9 i; u% s" ?( }
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);7 k1 p2 A7 ^4 }* L* B6 X
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
. I1 ~ N% a2 C* j HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 B* A9 S( a9 X8 p CString GetLocalRoutableIP(ServicePointer pService);4 N, ?2 S7 a* w! i5 r. ^
S6 L6 h4 W" r4 r3 W7 O7 m0 j% Q2 x0 d; U; \
// Private members0 I( e/ [) Y" _, l0 l
private:
5 z3 @. y+ s2 L1 _: T% r DWORD m_tLastEvent; // When the last event was received?& |8 d1 T: Z4 o
std::vector< DevicePointer > m_pDevices;3 Z/ i% A$ x" g& V
std::vector< ServicePointer > m_pServices;
7 Z% h7 j; o: Y n3 j FinderPointer m_pDeviceFinder;5 [7 U1 |' K" v. d8 T- k B- K% h- _
DeviceFinderCallback m_pDeviceFinderCallback;( a0 L3 I3 t( Z1 P2 k
ServiceCallback m_pServiceCallback;$ k7 w1 ?. L) q k
- S0 f' Y/ }- O& n( j- F) S# U& T' V2 o3 W2 A4 s/ K6 g# D6 m
LONG m_nAsyncFindHandle;' L( `5 n8 y P& \/ Y0 l/ R0 o9 s
bool m_bCOM;
# c' d6 |% d5 k' H* k bool m_bPortIsFree;
/ t: p* q: y. Q& S1 R CString m_sLocalIP;6 l! S5 E9 {, d+ x2 N, `# v4 i! v0 G7 H
CString m_sExternalIP;
$ b0 `* q0 ~$ }& @. e8 c. A bool m_bADSL; // Is the device ADSL?! K6 V! i' N, n Z6 ?" g
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?3 k# K' t: }2 N; u- V$ o; _
bool m_bInited;3 q4 t0 C: I! s R* F
bool m_bAsyncFindRunning;
1 [& k7 m4 F1 ? HMODULE m_hADVAPI32_DLL; j8 G5 x& d3 T3 u& [* f1 r
HMODULE m_hIPHLPAPI_DLL;
# s7 u* N8 p4 E7 r. i0 T4 m bool m_bSecondTry;; X! g% q o. T& N
bool m_bServiceStartedByEmule;
- {* H0 D) W; C4 ^ `- z) q# C' @# W( r bool m_bDisableWANIPSetup;
' N" ~8 e" [9 y" G* B1 q bool m_bDisableWANPPPSetup;
7 G( h. E9 [, d/ j0 }
' |6 t9 H: y5 a; d8 o) _; s9 t) g6 x/ A7 Y/ t
};. B/ w7 L: T2 H/ s1 W2 `
; E( D4 o# U1 _3 Q2 i* y" O
3 {& K& A* F2 s/ ?" c/ f, ^& x! u
// DeviceFinder Callback* O/ X" u+ A f8 w. }* _+ G
class CDeviceFinderCallback
' P4 J3 k- ~6 \ : public IUPnPDeviceFinderCallback4 k) r5 n( \% v8 u/ Q! P
{
$ _$ O8 s; o3 `8 Y1 L5 Bpublic:$ I/ b) C2 }3 R4 R6 R! R/ w
CDeviceFinderCallback(CUPnPImplWinServ& instance)
* n# \1 f2 H9 |9 J/ w' O7 \ : m_instance( instance )2 Q2 v# @0 F3 x! R. g( c3 [* A
{ m_lRefCount = 0; }
& J! H6 p7 n& [7 x% k) K- _- I0 ~' L
6 t. u8 B: i9 |- R1 d STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 K0 C4 i) s* l
STDMETHODIMP_(ULONG) AddRef();
! k7 c8 v. G/ t, X7 Q9 v STDMETHODIMP_(ULONG) Release();4 @% [+ p9 R+ A* o4 g% ?1 n
8 V0 q3 ?/ J: V4 y2 C4 \& d4 k& p8 d
// implementation
2 K+ ?8 i& o% Y/ H$ p' dprivate:# h6 \! M( z( i, \. \5 f2 c. {
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
5 {* p" M' V/ G; H2 Y/ P& l HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
6 y( ~! p# i' b HRESULT __stdcall SearchComplete(LONG nFindData);
* N5 G7 J8 y3 v/ ^/ E# V; Y& q A& f# n
# x! t6 L% t7 R! I8 q
! u' h# l0 `5 [! A# |- Tprivate:
% M) T- P8 y5 h7 _6 P; P& D! E5 S CUPnPImplWinServ& m_instance;' r8 f. ^' I, h" k( `
LONG m_lRefCount;
! `8 [' I) B& d5 D, y" T};
, v. T4 p7 D7 T8 O' z1 R3 U2 V
; ^* n( ~/ \5 X% [5 `$ J( T// Service Callback - Z! l' A7 @ u& \
class CServiceCallback; X8 a/ \' U1 b- a; r
: public IUPnPServiceCallback) K* o! [9 @1 R( J {$ f" @9 O
{
1 U+ ~7 h1 s2 d* ~8 Spublic:0 K3 K. \5 u3 b K
CServiceCallback(CUPnPImplWinServ& instance)! b7 ~! E- Y: t6 ^
: m_instance( instance )- H) c9 m h% h. m; M9 J! c
{ m_lRefCount = 0; }. q: x0 p; g6 z$ r$ U0 f
0 M0 c. t* W, q1 H L0 T STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, |7 ~2 Q$ `* ^ STDMETHODIMP_(ULONG) AddRef();
3 g# E( ?& c/ D1 Q& u/ X; h( C/ ^. g STDMETHODIMP_(ULONG) Release();
2 i+ ?! F$ p' m. f. o1 H$ i* g0 M( |" V* Z. @- T
# B( I: L# {' i7 d/ f0 R; D+ s// implementation
# k7 w$ r# ~9 r" M1 s# |private:5 x5 t: k6 i" z4 z% m2 o! x3 O
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
0 t/ F: w0 ?! F HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
1 S7 i/ W K% i7 H: W- Y' E+ m# {
) p: i& ]9 ]+ c1 T; H% T8 u1 _, B# J! f, ]& r, P4 ]5 z# W
private:" l% Z( t j; b! n) c+ a2 `$ r
CUPnPImplWinServ& m_instance;! L1 F) D# i) K1 e* \/ w& @
LONG m_lRefCount;; F; M9 |, d$ P8 [3 m. b3 ?' S
};
8 N' D) J6 ^ f* {. i3 _% r- k5 @8 P; b9 `) W; F9 W6 I2 Z/ ^
& t8 C0 V4 T- N2 _/ x4 u/////////////////////////////////////////////////; C& k) ^/ a; ?& B; V' q
/ ~" f- c; f/ @$ v- F% l" w% H" W! s* O' R, h2 P4 N% `
使用时只需要使用抽象类的接口。
% B1 Q+ v4 U/ A0 O3 ^CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.+ `' Y# s* e2 z4 e5 c! p
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
, S; A# T8 y% W# A4 a2 G* F9 a3 K7 X: zCUPnPImpl::StopAsyncFind停止设备查找., ]2 R; |/ `# k- G: ~' J
CUPnPImpl::DeletePorts删除端口映射. |
|