|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
( l4 w6 b) L, @8 C& P, \* A2 {( T, {* w" e; d% O3 H
+ r9 h2 p6 T3 d2 y4 l///////////////////////////////////////////3 Q6 ]( |6 Y- f. F! Z; \0 I" p* C
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# ` Y. [) w/ R E4 B y" Q% |0 X6 ~# N/ ?: F$ z
4 ?. z$ F0 k4 s( S* e" w4 D$ m
#pragma once k/ {% b, i0 t! S/ L6 J2 b
#include <exception>
5 e# q5 m3 }' T5 @$ ?
* I& j! e7 v' q8 B; ^6 ]: n0 [/ v6 _- _5 G
enum TRISTATE{
" |, J3 R* O# |' l, l: V TRIS_FALSE,
: w9 J% }7 U/ ~/ w$ ^ TRIS_UNKNOWN,$ f0 f& f7 |* s2 @; q% U
TRIS_TRUE' M p X% U& b, l- M
};
, R1 a5 S5 g9 A( b# Y3 N: J6 N% y4 P6 |
& O' D0 W% D* C; Z0 oenum UPNP_IMPLEMENTATION{2 T8 _/ ~5 T" T; e* d; E
UPNP_IMPL_WINDOWSERVICE = 0,; I4 q2 l5 h: w R' \: C# F
UPNP_IMPL_MINIUPNPLIB,* {( Q; P4 z) k* @7 I
UPNP_IMPL_NONE /*last*/
& {' w' D; `+ ?6 s4 ^4 ?0 c) O0 |};# N3 ?9 U) S* Z' y8 M* R" r
J6 H* E5 A3 |: G2 x P
; K+ W! V t+ Q0 U+ U5 B# j) K& r6 M- V( `! Z& G" ]
$ H6 @& C& ], a# X+ w; rclass CUPnPImpl
. T% _2 N+ e) [5 ]+ G3 A, J{
2 `! b" t/ }4 k( x/ ^) q) spublic:' [. o, I3 `& O0 g+ w5 o9 U
CUPnPImpl();3 Y Y5 z. v6 _. B! ~# H
virtual ~CUPnPImpl();* F9 y3 X2 F+ w# c! D0 c
struct UPnPError : std::exception {};
& ], {6 e: D; a1 ^ enum {
) O: u8 S" D9 B UPNP_OK,; _- R% u1 n: V0 u
UPNP_FAILED,
! r5 d3 n0 B+ h1 ~6 X% z$ U# z% l UPNP_TIMEOUT8 d4 W2 U- I1 _, a
};
5 F. l/ ^; ^- B8 H) I; X" P" U1 P I5 ^6 R$ r/ S
' X% g) O6 u: R. t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
: P1 }7 e7 ?" D& |0 }* I virtual bool CheckAndRefresh() = 0;' J* N2 l, y [, J! p1 @
virtual void StopAsyncFind() = 0;% {( U8 X$ N7 F4 O0 q1 H3 ?/ F
virtual void DeletePorts() = 0;
0 t) r3 M5 p# J. z; e) {' [ virtual bool IsReady() = 0;
8 z+ t1 N' n. V) I- l: W virtual int GetImplementationID() = 0;# Z& q+ a/ z* A% T
# j5 q4 M4 `- N4 k% b; l
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
2 C% M' h/ o4 b) K+ A
- n: W2 U1 ? h: A# d9 C1 D
) h* n2 W" t" l! `( h/ c6 u void SetMessageOnResult(HWND hWindow, UINT nMessageID);
: u4 ^, W, a- w6 B- T TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
9 S3 h% k5 C" \$ u6 y1 _' b7 x3 M uint16 GetUsedTCPPort() { return m_nTCPPort; }6 x$ v6 |! o$ Y8 I2 ~
uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 l; l* Q: {9 R. N1 @6 \2 K O
3 W3 \1 h3 W; G C r8 [+ v$ \5 [3 Q6 X' G1 n
// Implementation
; k# Q9 n9 B/ t7 Yprotected:
6 B2 j+ R0 X% c) ?, R( r9 n volatile TRISTATE m_bUPnPPortsForwarded;
$ B h: \: ]2 f! T5 I void SendResultMessage();
7 `' k0 ^5 ~ b: }# `6 F; F uint16 m_nUDPPort;
/ y! ~# i7 D% G \# C5 S: l4 o uint16 m_nTCPPort;3 T; o7 [) F0 x* k, Y
uint16 m_nTCPWebPort;4 |, G3 G* k H! g
bool m_bCheckAndRefresh;4 E3 [' t. N' D. z
: p: E6 ]& x( E w2 v& W+ c2 x3 ^- p- i
private:; B) c4 M- a; z( q* O7 t: k4 Z
HWND m_hResultMessageWindow;
/ u' v5 t; K' a( }/ u UINT m_nResultMessageID;
* k) A% @0 |: M8 _' d: V) G3 m) ?' D" T. C8 _
1 t C1 o6 y- q' l6 |7 Z
};. X0 L* h# ^9 t, L
8 M! `: l5 `( Y/ P; v; V& z9 A: d
# W" D5 G' E( Z7 X# r// Dummy Implementation to be used when no other implementation is available
`% w* S- ]1 I' q' }% uclass CUPnPImplNone: public CUPnPImpl
; F% R; A/ ^: {4 o5 ?* J/ O( U{
7 A# ^) W+ U0 d, f' L; Ipublic:
2 p( Q! Z8 o6 ^ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }. n0 E9 _7 R9 C( F
virtual bool CheckAndRefresh() { return false; }# F; Y5 w h8 {* A
virtual void StopAsyncFind() { }* g S( a4 q' R# Q' w$ h
virtual void DeletePorts() { }! w) Y) C5 }, U& ^7 W; X# q
virtual bool IsReady() { return false; }6 f; o1 ~) d4 a3 S% c# t
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }* C$ O3 j8 S' v! n: C
};& v' n% Y5 L" m* ]! x- A1 F$ B
8 Q! i$ e4 _5 }. r
5 ^7 ]. l7 r+ b4 Q8 k' u8 S/////////////////////////////////////
B2 G1 A; ~* m( e$ B4 j& V0 D//下面是使用windows操作系统自带的UPNP功能的子类7 e0 O1 h- ?$ C. T2 f3 Q) k
X" Y+ x8 i/ F b! y: m6 `, x1 ^7 K3 k- Q
#pragma once- Y3 H5 z( E3 N8 R* q5 l
#pragma warning( disable: 4355 )- u: {! E- `' {. t
# }8 v. q# ?2 S; u# E J
! m. m" U1 i% }" u: k#include "UPnPImpl.h") e9 }8 _) r$ O! A# X1 o: J
#include <upnp.h>. N- G8 `* y9 h; W# k
#include <iphlpapi.h>
* z# J7 W! F$ @) C, C$ \#include <comdef.h>
! }* i/ d A$ @# x+ P6 w#include <winsvc.h>
4 X5 D' r" c( e) ]! y7 }: \7 R, A5 S9 X( w1 K% E5 e
& [6 M( N$ }# R( U. D
#include <vector>6 X; k; p L# G% ^3 d
#include <exception>% G! [: G% T' G7 m u! V8 x
#include <functional>6 X# @; F/ A( S* D$ @. z7 v
0 T) [2 Q, X) H7 A# ~7 V# A! A6 c
g( N3 L6 A4 o
% W" Y5 X8 |' Q2 K c6 X+ F% g8 E, N' I( q: x* _- J
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;: U- k. [/ a1 H5 k) @. k7 Q H
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
6 u6 T! H0 S9 u3 d7 Xtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
9 v; G' F" d& |) X7 ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
X# j0 r) x A$ A6 m8 t+ atypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;2 Y# A8 {( e6 X _, Q8 Z' N0 @. I
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;. J1 w/ c4 O, J. G0 U) {2 d" K
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;% ^& c; ]9 n# K
: l/ s8 r$ s# Y
* r/ `4 m% I& E# r) I0 X# p5 |
typedef DWORD (WINAPI* TGetBestInterface) (
8 T4 N1 U5 K' r J IPAddr dwDestAddr,
. f, o0 }, R; I: U8 A PDWORD pdwBestIfIndex
3 b4 f2 h/ r2 r8 s);
: \7 X4 J) o& j- Z; u) o& z" h7 ~( ~ T
5 ]7 R& N5 G. c4 s3 j) s2 ltypedef DWORD (WINAPI* TGetIpAddrTable) (
/ p1 f7 S# ?; k; F. i$ A/ A PMIB_IPADDRTABLE pIpAddrTable,1 w, y3 H! g7 Y
PULONG pdwSize,9 g% a3 ]- U! |
BOOL bOrder# u+ K0 V1 v; k( a" h
);
# [: R! T! }- y s( d* n8 F6 l8 b1 c& y2 X5 e6 S' s5 u5 F" S
9 f/ u0 d0 {, Y3 ~
typedef DWORD (WINAPI* TGetIfEntry) (
2 H! w/ w; ^% e1 B% \; Q6 q PMIB_IFROW pIfRow
- j7 Z0 N2 N q);
# J) g* ^( q5 u, I9 @ g7 a
# H O& Q! B3 E5 {" k* a- r; m3 J7 [
CString translateUPnPResult(HRESULT hr);8 t3 f" r; V% I! Q4 e
HRESULT UPnPMessage(HRESULT hr);! [; T# L# \/ ?) K
. n- u9 G6 J6 k" l5 x. I
$ ]; E. m% l' H! C# f& J+ d
class CUPnPImplWinServ: public CUPnPImpl
+ D& t1 M! G: E7 C) ^2 ]% i! P2 W{
- ]2 ^8 U$ ]( ~% \: G8 H friend class CDeviceFinderCallback;9 `1 C% i" {$ O3 s I6 F
friend class CServiceCallback; X( A9 D6 I$ H5 m
// Construction8 I+ G6 d$ ~- q9 H9 r; f
public:/ p( t$ h. u& `" w
virtual ~CUPnPImplWinServ();! W! P0 v8 D! P" d9 p8 r O; k/ a4 F
CUPnPImplWinServ();
) D% F8 O6 M- H& b2 S' t) ~1 y4 B5 f X ^
' @7 a2 p$ l$ A( @9 Y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
! q3 P" b, F+ ~5 G6 \8 ^ virtual void StopAsyncFind();
" k! { ^. K( ]5 ` m+ C6 h5 T5 K virtual void DeletePorts();
& b* J! D1 v. B+ i, V7 n virtual bool IsReady();# E' |& O, f# j9 t/ W& h4 m
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }& E* y% A/ {4 J$ n5 v9 B
" E% [" l" B+ q# n7 C% k: w
; w! c4 Q3 T/ `, h# r( ]* b& V) f
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 Q9 \: o- Y6 m7 C$ y // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
, Y* W# n" S$ l. Q9 S8 a6 S virtual bool CheckAndRefresh() { return false; };+ x* g/ Y6 i& M% x& J( ^1 D
2 d4 {- c8 d0 i" ?! X
. P( Q# y: Y& l. h; qprotected:2 W, S/ T, \6 ^' m- a
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);5 L) ?1 x& p$ j% X' K9 Y
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);9 a9 }* N* T2 G
void RemoveDevice(CComBSTR bsUDN);
+ M/ D$ F" r4 L" r* |) M bool OnSearchComplete();# w [+ }, M; m; T6 a
void Init();
( j0 @( }) U/ z; @& m: C, g7 W! M$ h0 G* d2 B: g' H& m# h+ |
5 N8 p- f+ O+ f) i inline bool IsAsyncFindRunning()
6 ]/ |' S1 i6 o3 m {
5 Q H1 S, _; ~9 g: r( i% O if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 A5 `, _) I) v# @9 y
{
' Q0 ~. J3 _- @' q: u& g/ i/ e, y m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );, p8 h9 k" B0 [
m_bAsyncFindRunning = false;- L; u9 s' L8 |3 c" V A& p
}0 Q) Q# o% j( t
MSG msg;3 f( Z% Z; `; V) J
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )6 D. W0 q( W7 y: x' S* R
{
, P, F5 y; C$ u% ~, c: q TranslateMessage( &msg );' [$ ]& z2 k; H( _
DispatchMessage( &msg );' k& c k. q) V
}' ~$ s* C9 K1 W [; f/ Q4 G* b
return m_bAsyncFindRunning;
) ?7 B" D& I% c3 `! q/ [% @ }! F% P3 S& R% I o* Q
5 s7 K, I. a2 k' D6 A. W% Q
u7 U6 M* u" y+ q% u% ~% t. X
TRISTATE m_bUPnPDeviceConnected;
) r9 T) _8 ~" q! }- o, k
7 |& h; P& h( Y8 y1 p' e: M' g) p! a/ z( p. e2 ^
// Implementation
`2 n4 _* _: _4 U( G2 ^* K- c1 t // API functions& m" |3 {9 K& p+ i
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);4 E( O0 h: N/ g0 U2 D9 @1 _
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
. L6 N" h9 Z7 Y3 Y5 F6 _ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
. N- F; t) w' M9 E9 Y4 c) w' b1 ~' Y BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);8 h- s# ?, Q8 \
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
E. A! q) ^( V# n7 E6 g2 w BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
3 e6 O+ A: o; G1 f5 v, L; P+ g" y5 V. p% y# P! Y9 U
8 w2 T0 X% N8 n. Y+ W4 U. }' Z/ ^ TGetBestInterface m_pfGetBestInterface;& R4 S0 s+ S! K( I& z7 ?4 [. e' }$ m" ~
TGetIpAddrTable m_pfGetIpAddrTable;4 {& Q0 g9 x# b" Z3 B
TGetIfEntry m_pfGetIfEntry;
* j/ M& V7 `% O3 J2 G! F" G7 Q! B( i7 z" d/ o. U
4 t! k, ^* X! j
static FinderPointer CreateFinderInstance();) S7 A/ Z9 a' s0 ^
struct FindDevice : std::unary_function< DevicePointer, bool >! j2 J) v* [6 |* {' n4 D8 k0 x! ?% K
{
0 X& a s# B5 I; B FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
A8 X, g, c, D( H3 W2 _2 s result_type operator()(argument_type device) const( t2 B" A+ Y+ [. h7 s5 R8 i
{ Z% v7 q$ P( j2 Q
CComBSTR deviceName;
% P# k$ {0 o( W# n5 o+ @ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
/ ]: ^8 D. ~0 O7 ]9 G; G# j8 ?
& E! [. {3 E8 c# X$ s5 o5 r0 A; [: x) P( \
if ( FAILED( hr ) )' c' l3 G8 p0 f0 @
return UPnPMessage( hr ), false;( Z4 D; U5 V$ D! q& G: t$ n
+ K: m- }- f* U: ^8 H6 F) Q3 H6 c' z! w' f# a4 X# o/ J8 {) q; Q
return wcscmp( deviceName.m_str, m_udn ) == 0;! r/ s. k3 E% D2 j: H
}) [+ P: j V% e2 }) O; V
CComBSTR m_udn;
3 W9 m$ m5 {% ]6 I6 ?" J0 }/ r };2 g# H7 U# Z' l6 P2 H/ A1 U
) U$ R4 t9 b! ?' K8 V8 c# V9 R void ProcessAsyncFind(CComBSTR bsSearchType);) @6 A7 A) J. r) {& n5 e- R/ |
HRESULT GetDeviceServices(DevicePointer pDevice);
$ p: m. Z* L8 X) Z0 _5 |: C void StartPortMapping();- H8 d: `) s! n, r0 i2 I7 D
HRESULT MapPort(const ServicePointer& service);/ o5 `. r) [7 l, b
void DeleteExistingPortMappings(ServicePointer pService);
) j. E, F0 L' s8 V9 e void CreatePortMappings(ServicePointer pService);
2 e% U7 r* S; [% M2 w HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( |. E/ n' j) p3 E4 H& ]. H# `- h& O HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ) z9 ]2 f% w/ h& B! [
LPCTSTR pszInArgString, CString& strResult);" `/ f% E2 L3 ^) e% W
void StopUPnPService();
% e5 I/ S' V: h" z, R* N0 \8 a7 j+ M$ d u) A8 n; o
8 ]* c6 c1 J3 N5 `
// Utility functions
$ o8 u9 Q' L4 y$ b5 o/ W0 Z HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 F. V6 P; {( R INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
" F( h* W% z: t& Q4 J INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
& t+ z2 q$ `0 S( [7 q$ z2 d void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
% ]# W8 H4 D" U8 ^- H8 T HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
9 m5 W- `/ z" N/ h HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- i& u) F/ f6 P( _6 h CString GetLocalRoutableIP(ServicePointer pService);8 N6 _" z5 j) G `
6 k# {" V g7 Q9 Y' m/ X& s
* u- p; [+ f( E// Private members: o- s& W1 S: p, M, }/ [8 K
private:
/ o2 M( N' O8 r$ D0 N, D DWORD m_tLastEvent; // When the last event was received?
$ [+ d5 ]8 H9 O* G std::vector< DevicePointer > m_pDevices;/ u+ h: ^0 N9 x% t
std::vector< ServicePointer > m_pServices;
" D b0 z! G/ ?& }1 h4 P FinderPointer m_pDeviceFinder;
5 B5 Z# @# W$ C/ q5 \" l6 B! v DeviceFinderCallback m_pDeviceFinderCallback;( L, d7 [1 O$ n) P
ServiceCallback m_pServiceCallback;9 N8 \2 w: f8 E) @, w, w
5 D2 t; r+ D0 X' s" Z' s& N
^; F/ p+ s, W LONG m_nAsyncFindHandle;2 b3 {# h- W0 L; S. _* y
bool m_bCOM;5 J8 ^! |0 D6 |
bool m_bPortIsFree;# D1 n" x' a, }! @& Y2 [5 o
CString m_sLocalIP;
$ C( J3 J, G1 Y0 M CString m_sExternalIP;9 ?6 L# t. n0 f/ e/ B
bool m_bADSL; // Is the device ADSL?
7 }1 W" S' f: E; s9 V bool m_ADSLFailed; // Did port mapping failed for the ADSL device?/ B3 x r1 [3 a3 T6 p( r1 f
bool m_bInited;$ h7 l% D/ V% j& Y
bool m_bAsyncFindRunning;
6 W7 l6 M& e9 Y1 Y! \( c HMODULE m_hADVAPI32_DLL;
" t3 M+ p3 y+ y( @- V& X HMODULE m_hIPHLPAPI_DLL;
) b1 O! |" R% Z" D. `# h bool m_bSecondTry;
2 E; B' k+ [. w9 e1 Z6 s bool m_bServiceStartedByEmule;
$ q) W) Q# a1 H. \8 l4 r' ?7 } bool m_bDisableWANIPSetup;
' f* A- W2 l6 v- C; c) W6 e g bool m_bDisableWANPPPSetup;
, A) Z8 T" Q2 w9 n+ }+ n! {6 ]1 f- f8 F# i! [% Q
) R4 f" r% k3 { P7 @$ V+ v
};& A7 w4 c' j( p7 l3 b* x
: e. n$ L# s9 r( i2 J( _: n6 p5 @7 p" Z
// DeviceFinder Callback
/ y/ f/ z2 V! b* Uclass CDeviceFinderCallback3 M1 Z- y8 |% n S' f
: public IUPnPDeviceFinderCallback) C. ~- A; @- x. Q5 @3 h6 z* y
{
, c2 ?: h) M0 a3 [4 Q D* c- E3 q$ x4 ^public:/ c. ~, p+ k# ]: E! I( n3 Y
CDeviceFinderCallback(CUPnPImplWinServ& instance)
+ _# M* A$ l5 h/ q : m_instance( instance )
$ h9 @; [6 J6 A% y8 n, \- A { m_lRefCount = 0; }
8 f& D( I# s3 c( I* s. a& Y% d
2 u9 M K1 V* O! Y0 G4 ~1 x% S9 P6 F" r* d6 h; h. y4 n9 s
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ M5 G6 c2 `, Y STDMETHODIMP_(ULONG) AddRef();
" S _/ N) B' A4 Y; P4 k* J5 ?4 h9 Y STDMETHODIMP_(ULONG) Release();( R9 t0 b5 }0 m, b# Y$ D! |( H
( M V) P& r/ |. e4 ]) L- u0 B
: O3 z8 n3 j% C: a/ \9 _3 H// implementation8 H, V! q6 K7 H( u
private:; f' y- ~8 q, E6 W% E, z0 n
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
: f# ~- B6 k4 M4 R" {2 P HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
! T$ L2 ]8 v) p- A HRESULT __stdcall SearchComplete(LONG nFindData);4 x) x9 A2 _- O, b) r
3 q0 o5 g8 x: k+ b
, Z9 q4 M T% L: j, W- K
private:
( J8 G7 T- \* [% S: d2 p0 X CUPnPImplWinServ& m_instance;
/ R/ ^' o. P- R7 d LONG m_lRefCount;9 o' f3 e9 U, k' R: n9 }+ O
};
9 f9 K! l4 p& a) {9 ^$ u/ b& O! P! Y6 R7 U$ C" T! X, z6 |3 L
8 D! H' Q w, ~7 i, J* h// Service Callback
& ` C1 T- l* xclass CServiceCallback
1 D ?( s3 `4 `& u : public IUPnPServiceCallback
. ^( v3 u6 T0 C0 u+ z! o{
2 D! X! \8 r% ]public:& A& Q: u8 W1 d8 q+ u
CServiceCallback(CUPnPImplWinServ& instance)
6 O1 h" S# u9 E6 a : m_instance( instance )
3 E6 }! ]) A* N { m_lRefCount = 0; }
* O. ?7 n" `: ? # N. \) C. \4 `* d
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 G }& k/ z( w; d9 b* _5 g; r/ |/ @
STDMETHODIMP_(ULONG) AddRef();
C3 v! M& d3 @0 @; ?' v6 i6 e) r STDMETHODIMP_(ULONG) Release();: w u$ r( g5 X; s: J' S
" V* q% \4 |. y: t4 o3 t
n; z' @1 R5 p- M# v1 F) l// implementation, ]$ U$ i6 Q$ V4 J- F' \
private:
* r0 |) R* k! E HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);+ [4 @3 `. {, V C( v9 o
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);1 }& Q3 f1 d9 f, [( o
5 d, T/ g7 y! S& E7 s3 y2 M' o" y( e4 D( c: ?- Q, [: X' _$ E
private:5 o6 E; ]1 T% j9 Q7 `# J4 `4 @* [
CUPnPImplWinServ& m_instance;
' ^! n7 B- \' w4 _" @ LONG m_lRefCount;6 Y+ ]! I% F' G3 d1 N" n6 s0 F
};
& a# s/ h& M V1 a: j5 w Z0 E4 m' R
% C, t/ X5 W" ^1 F1 F: y( b9 E' f8 B9 H) B- D+ a8 w! K4 l7 M
/////////////////////////////////////////////////- o) d8 s ]% X1 ~7 c# ~
/ R0 R" V. F6 I, b5 ^6 g. A. \1 V. R! V
# N) Z8 Q. q) k7 ]1 C- I
使用时只需要使用抽象类的接口。
" K# y, C+ f# p2 W# RCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.- G A5 F) {. D3 c
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
2 X& V0 P: \# G+ i' ?CUPnPImpl::StopAsyncFind停止设备查找.
7 p& z: _) Q9 A1 D6 |# cCUPnPImpl::DeletePorts删除端口映射. |
|