|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
. Y0 f5 t: b; `7 o, x1 L) C9 V) M0 O& S+ ]" d& t N
* I! z0 }* V) v( H2 c3 a' d///////////////////////////////////////////
! R7 n7 j( l7 L8 U- Q4 U; H//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- z7 H9 @1 Z' H. l
2 G4 S# U, t' T) |5 F7 Z, { O' F- B( r; [5 n: I
#pragma once
' i- r S1 H# x0 c#include <exception>+ B& d' d; H% A2 s
# `% w! z* n% X. N- b2 x1 Z7 a( ?9 x" y V- K% }" I$ A, ^
enum TRISTATE{
$ v U$ C! o$ [7 w) g TRIS_FALSE,
3 {4 u7 Z; C/ E+ n7 a4 M TRIS_UNKNOWN,
1 I8 p; }4 J1 Q8 r/ h; ]& E TRIS_TRUE+ _# I2 Y* z* O( r) W3 X' n9 p# e2 S
};
4 t4 W* f3 L( N$ d8 m" K, C0 a$ L6 n( Q+ }
' m9 }2 V, u3 U0 T3 aenum UPNP_IMPLEMENTATION{
; m) s2 Z3 o: H' T: s4 _/ L UPNP_IMPL_WINDOWSERVICE = 0,
2 n, D- ~& z: E* x: I3 a UPNP_IMPL_MINIUPNPLIB,
) R' d, R. [0 \ Z" r0 t UPNP_IMPL_NONE /*last*/
4 `& G) N+ i B# r};
1 w x$ w; J/ y1 W, H. C
3 h, p9 {. M' m, N+ m! Y: P$ }9 g" E$ j
7 F8 x- V7 ?+ }+ G7 X
+ q9 B1 D% y* }8 }9 g) M2 bclass CUPnPImpl% R/ t8 g0 P6 F, n
{
5 m8 G, I, r* }0 s% A5 e& L$ Apublic:
* x8 b- r/ b5 J# ` CUPnPImpl();
# C7 x( Y7 P7 K virtual ~CUPnPImpl();5 T2 A3 p9 Z/ B' N) e8 D
struct UPnPError : std::exception {};0 R9 O4 Y9 u& y P" {, {
enum {
" k1 X* H: H! L. c6 m5 k6 J1 _( d UPNP_OK,
! X- ]3 \+ M, j+ e$ y- M% V. O UPNP_FAILED,
6 u7 W, f- \6 f$ z: y UPNP_TIMEOUT# @9 f6 B" `0 L/ _# T( G
};
0 D0 {9 O6 U$ q3 F. E
* L5 K. x$ W4 |) [! _- U" x3 F2 U5 m z* z: v
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
( c# } K) c3 n: M virtual bool CheckAndRefresh() = 0;
* Y5 _3 i0 F& O/ h virtual void StopAsyncFind() = 0;/ j# d5 d) u: h/ n+ M! |7 ^
virtual void DeletePorts() = 0;
. j2 o' L, x$ X% Z$ X& Z" b) m virtual bool IsReady() = 0;, I+ q& u: s" N1 P
virtual int GetImplementationID() = 0;+ L$ @% s/ h9 j6 p& W5 g6 C' O/ k5 p3 P
& n0 M8 f8 k9 ^
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
6 e7 _* }6 ]1 w; g# z! M
$ `8 U7 q' K/ l/ p6 X8 u: \* I8 v4 Q' W( h
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
5 a% I/ i; f/ n: Y5 X: s TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }3 j) Z( F& @8 H( @" x' j0 N
uint16 GetUsedTCPPort() { return m_nTCPPort; }4 Q/ e) p0 l M
uint16 GetUsedUDPPort() { return m_nUDPPort; } ' L; [9 @& N* g. U
, L, v) @) Y4 W1 {0 X7 I
. A4 y" f5 f; Y3 V1 ]2 V! S0 v7 D
// Implementation
! S8 F- ~+ w5 W. G; `$ \- y# ?protected:
. w4 o q! e, I7 q& o8 m# Z N( `% h volatile TRISTATE m_bUPnPPortsForwarded;' B& V4 ]5 i1 i; W, B* S- o0 ?2 P
void SendResultMessage();5 i$ w2 n: N# g8 B
uint16 m_nUDPPort;$ l; n2 Q4 T+ U) U% U" a: k/ C
uint16 m_nTCPPort;
( n5 s# j; I" B1 s2 d0 Z' Y! \ uint16 m_nTCPWebPort;; m4 s6 B' I; i x
bool m_bCheckAndRefresh;( W1 n% s1 t3 i5 P O6 a
! G5 K( b+ ~7 s o& P j
1 V* e+ W( }! h6 f% g2 eprivate:6 S6 c+ d; u7 g2 c7 k" j# e
HWND m_hResultMessageWindow;' v: `! t1 V. O( {( D
UINT m_nResultMessageID;; S+ a/ }# y" u K1 l7 ^
; N# a4 p, M* |0 h: A; q5 x8 s4 c/ V! t8 `! A$ e
};
' C2 q' [/ R; N- J) X0 A; u! h5 Z) v
- c S& I, }6 c* F) Y// Dummy Implementation to be used when no other implementation is available& J$ j- s# I" B/ ~2 n
class CUPnPImplNone: public CUPnPImpl
% D/ F5 L4 h6 E' R- |& {+ c+ k{
7 R V9 n9 V; D$ Bpublic:
X7 r; N1 `$ o( _2 _) g, i# ~ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 d) C( f0 ^% M9 t virtual bool CheckAndRefresh() { return false; }
$ j' M. g7 h, l2 S5 l virtual void StopAsyncFind() { }
. h5 q J+ ~ N" Q) C+ u virtual void DeletePorts() { }+ G" p3 C# f: A" V1 ]* F
virtual bool IsReady() { return false; }
6 T$ d( I2 k8 z% y# x2 O# I+ V virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, ~9 U* ~3 W' }2 i};, e; {- |7 J1 g0 U; m1 w
: b) R& b4 i: E/ |$ z' E" ~) E4 K' M- @+ D* V
/////////////////////////////////////% ^( k$ t$ I7 I. n* v" E2 B
//下面是使用windows操作系统自带的UPNP功能的子类9 z# I+ W Q @
5 E4 Q- G5 F' P$ C, P
! A2 |# E0 i+ R$ R+ K9 E
#pragma once9 E2 y" b T6 |* j5 u
#pragma warning( disable: 4355 )
9 X* C* p+ f \# b- m/ G% ~5 J2 i" ^) h. p. x. I7 x9 t: ?
( C, A- h G1 |% Q
#include "UPnPImpl.h"
& F: _: k" q: G. b: f#include <upnp.h># r) R* J" ?1 D& ]' G
#include <iphlpapi.h>5 L# ~9 h* ~1 @2 |1 @8 w8 q
#include <comdef.h>
% Y) R. g7 c. i/ U$ n#include <winsvc.h>
" j% G- T2 k$ z* B- F. U- ^$ X" m5 ?" V# {
' M. ^5 L6 l; M6 d9 J/ |
#include <vector>6 h" ?& ]4 H+ [; |+ B3 {
#include <exception>, C" t( m0 ~3 t! n+ r W9 \& u
#include <functional>- _8 a# X+ B9 E
# s" A$ o1 o; a1 C! o$ A$ l
! v' _3 e* z) E" p7 s1 t! S/ x$ E+ b) Z( }
* \4 p7 S7 @' m- R, n/ Utypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;) Q; G, O$ R" I
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( A7 _+ G8 h; N2 }) J
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ U9 R9 q) Q8 wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
. K! t1 g1 K9 N2 H& p; B6 vtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
4 Q2 a: H: a }( M# E5 Q0 ~typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( `" k5 G! ]8 ]5 F8 z8 C4 l2 [9 k# L Atypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
) Y+ C: y; U4 ?% S0 }; A0 h. L4 ^& ]; n
' s9 R4 Q* s. H3 f. w0 a2 ftypedef DWORD (WINAPI* TGetBestInterface) (
) X% d L: r: r& I8 Q2 o IPAddr dwDestAddr,, ]9 n7 o5 {' Z5 F5 A7 m
PDWORD pdwBestIfIndex
0 P7 O' S8 L' W$ y1 j) W& P);
3 y7 _6 E) C& C
4 m! j+ M3 z! [+ p" Z' P8 K S% X) @/ q; o* z7 P' B- G6 H
typedef DWORD (WINAPI* TGetIpAddrTable) (
' R& U C5 v1 {$ L PMIB_IPADDRTABLE pIpAddrTable,: K4 f$ [/ E4 O" D
PULONG pdwSize, y) F, v& e3 m# v g6 [2 j4 g
BOOL bOrder
* ~' m. b7 {1 H4 c, A A, @);( W: Q9 T- R/ [) \
' b. S' h2 J. z! _# \
" i& d2 y1 w1 g2 h1 J7 h& _typedef DWORD (WINAPI* TGetIfEntry) (
0 N1 M1 G. Q9 f4 A* I6 { PMIB_IFROW pIfRow
# Y: N0 p& R9 Q" U! T, @);
& z! @( X" R6 p2 v4 @' ]! x# d
% @8 r- c1 M4 V5 g% M$ @. Y* i i8 I
CString translateUPnPResult(HRESULT hr);0 O$ `1 B4 y7 ^3 r
HRESULT UPnPMessage(HRESULT hr);
- M7 u) g$ `5 P/ Y% o$ C1 p/ m" n: N& `. A
1 e% o0 r4 }2 t. z: P
class CUPnPImplWinServ: public CUPnPImpl
3 K6 [3 g- k c: [" H{
' z4 J4 f) F0 M friend class CDeviceFinderCallback;5 G0 I# {, L+ o7 \" b
friend class CServiceCallback;
! S+ s" o7 e; a- Z/ ?// Construction
: Y* Z W" u( J' Opublic:; ]# G( Y, D# v& ?
virtual ~CUPnPImplWinServ();0 m( Q% I' w) x- R! J6 a4 C( d
CUPnPImplWinServ();- i' C& C- d& ^7 ]: [3 M0 T* t
2 i- B6 `' o; b6 z) A& r) z2 q3 W6 f4 T+ u1 p8 I4 [4 Z
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
0 G4 H, D0 Z7 L" A2 e8 C& @ virtual void StopAsyncFind();
6 f* d: ?; L3 e3 {" }2 |: i( O virtual void DeletePorts();
7 J. ~ y0 O6 r% i# u0 X6 B& H4 ] virtual bool IsReady();9 m' S* q ~& M3 \4 Q
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( G" e8 M: P$ }5 q# R" X- `1 o0 o, |4 m+ U9 X E g
$ \* k# m" b& e* ~/ X1 ]
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)0 B! G4 W) e& P( u4 v M$ I% |
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; r; C7 Y* E# x4 Y virtual bool CheckAndRefresh() { return false; };% Z, F, Q- u9 {3 t C
% n$ a& N$ d# k% W8 `- G
0 b2 z8 `) k; J# N7 tprotected:
& a, z1 W# P, X7 Y9 c3 T void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
' [; m. K$ _2 b' X9 F void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
. @* {5 Q% p' G* L void RemoveDevice(CComBSTR bsUDN);
! r, i( M7 h; g8 a* M; M) l- _ bool OnSearchComplete();9 L/ y! a% p& _ \" O! s/ X" N6 |
void Init();' Q+ S% Z" h3 G
8 J( U q& y7 i9 {' x. o
2 k3 i% Z6 f7 Q5 m" s8 h inline bool IsAsyncFindRunning() " ]( r3 Z" k7 ^# l4 _
{, n6 Y9 n6 p+ f+ |, I+ a& c0 E
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
" e2 |' S6 \7 J$ r2 A$ N& h' i {# H' F1 w- X5 j+ f8 o
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( h. Q9 ]* p. _1 c m_bAsyncFindRunning = false;5 |+ d0 \% [, b5 c( m' r7 _
}/ c! Z6 t8 T% {- ]- ]% p/ q
MSG msg;5 c' q' M; y6 \( h. _% |
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
# C; Z* c n) j7 `+ d/ a {
( t/ S+ a. F( s; M' Z/ i TranslateMessage( &msg );3 I* V" G/ w0 \
DispatchMessage( &msg );4 v4 t2 D6 w% y7 m& @( K
}
" T' Y4 x7 b$ K5 a5 V- i0 T6 @ return m_bAsyncFindRunning;
; n) J4 ]! E2 F1 l) M) X }- k% X- S; Y# L$ G, q+ V( w! p9 C3 \
: N( i! e/ E- a: k' h+ _$ x
7 K9 N8 S% P6 }* |& I! Q5 J
TRISTATE m_bUPnPDeviceConnected;
+ r) k1 ?- h/ f6 G, m. x" q, t9 n& Q D) Z6 l1 \
$ g" y' _& E8 E# I! e
// Implementation2 E; H! A J1 T" z3 L+ l# c+ \
// API functions
1 c0 e! a8 W* C6 |: q) S7 @ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
: r/ d1 m5 F6 E" ]7 @ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);2 I6 T# P3 n: ?+ u a
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);0 {5 ]0 c1 w3 @) m: Y
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);$ }& D( C" x P. O& r2 ^8 D, e
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);6 i X8 y! l; j7 Q5 _
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' i1 P4 {) J* M ?
1 w0 g0 Z R( L" t
- B( f6 w t& L7 c2 u TGetBestInterface m_pfGetBestInterface;6 r$ @- Q9 n' M' u: p
TGetIpAddrTable m_pfGetIpAddrTable;& }! c, l" h* j7 F/ Z5 z$ y. V
TGetIfEntry m_pfGetIfEntry;- j$ {5 r7 P2 a, ^# b
% k4 d7 U4 q- X# E7 P
R8 G! d. l! g Y1 ]" e static FinderPointer CreateFinderInstance();
& H+ K3 J) ~, ?; R struct FindDevice : std::unary_function< DevicePointer, bool >
; Z( K4 E2 w" z1 z8 S' g8 ^ {
$ t/ g1 g% G( W: x/ Z FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 ]$ F. t" M) a3 m* L
result_type operator()(argument_type device) const
2 \2 M% F2 A: {- `4 f, o {8 s' s. _9 C: b
CComBSTR deviceName;
7 ~" @# ?4 v4 M+ ]- ]& P HRESULT hr = device->get_UniqueDeviceName( &deviceName );
; U% o/ D/ T# A( \! _' }, N9 {+ ?1 O& e
+ x# w" f7 U% v8 ?6 [0 K8 [/ M
if ( FAILED( hr ) )
" y( ]- f& c# M5 j; {* H5 v( M return UPnPMessage( hr ), false;! R% Q! {# h9 s# e3 N8 K) z
5 Q# J4 x0 a6 E/ d; c5 o
$ P5 ?* M; T: |3 ]6 x8 t
return wcscmp( deviceName.m_str, m_udn ) == 0;
7 p' B( E$ H# A8 C4 L }" b# T5 S1 f& w; ^ u' U. Y, S
CComBSTR m_udn;
- d) Q7 O; C4 O3 s. X1 u1 a };+ o, N% B- P8 u& r: w
+ a$ m& |1 n }& o! G6 u$ p7 i& h. D' f
void ProcessAsyncFind(CComBSTR bsSearchType);' N x0 q+ c0 ^1 \9 T: n- _
HRESULT GetDeviceServices(DevicePointer pDevice);
( n. n" f* h4 \4 M. B3 g void StartPortMapping();* h5 w1 G* B! h
HRESULT MapPort(const ServicePointer& service);8 {% k; ?! s+ h5 Z+ U y6 h
void DeleteExistingPortMappings(ServicePointer pService);7 i }) r0 U1 y$ }
void CreatePortMappings(ServicePointer pService);
; q% E8 r- f9 ` HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; p, R, Q. o) H! A) ~( H
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 O- w. E: ]9 z, p5 _5 g LPCTSTR pszInArgString, CString& strResult);. A- L4 J/ `- a8 z. F% c
void StopUPnPService();
' c' i5 V. w& S$ |" B6 Q; A' ]+ J9 F; l1 b7 w$ B% n: O$ ^% S, w) W
/ P2 { a) D# B3 h# S# n6 ^ // Utility functions3 b6 s. W8 x% ~1 z( f a
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ u, P7 [( U7 s* o4 g. w
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. S V* m/ I; z5 w# I2 N( ?7 J INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);; p9 t4 R+ x6 Q$ k
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);- ]! f# Y- w& I4 U4 X1 e6 x3 w
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);+ `* r7 {8 {$ k0 G! `
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);4 a5 J ?. Z, v1 s) R# K) x
CString GetLocalRoutableIP(ServicePointer pService);! _/ T- d$ P1 ?' I: j& H" A
+ ? H* _2 ^1 b: E) M
" j; `$ x( b* J' x// Private members6 c- C' K' A0 u5 P! G; g0 a/ Y
private:6 P- b8 J6 E: c D# S0 x
DWORD m_tLastEvent; // When the last event was received?
) p$ g' x, u3 k; k. ]. f) V std::vector< DevicePointer > m_pDevices;
( Z! m, z* t& P# Y6 [ T std::vector< ServicePointer > m_pServices;
, M. {3 e. G0 t FinderPointer m_pDeviceFinder;, h7 | Z2 ]. m. S6 E- O; `1 C
DeviceFinderCallback m_pDeviceFinderCallback;' Z0 }' s, C+ ~. F1 \! s
ServiceCallback m_pServiceCallback;
; u3 O# F, k8 l) y# H% P o
0 [2 d. u( L$ A+ {# w: e- o- B* r+ g5 r9 \9 {. m X/ M
LONG m_nAsyncFindHandle;1 I3 M! C" E8 b) {, A+ ?( O+ S( w- t- F1 L
bool m_bCOM;
. l9 V' h+ B. `' E bool m_bPortIsFree;
4 h O4 w+ {/ h* t CString m_sLocalIP;
$ r. h! p5 B. i( ]7 h1 t CString m_sExternalIP;
2 c: Y% c P1 \% l5 S9 V bool m_bADSL; // Is the device ADSL?
% j: ^; n7 A L. Z4 ~8 } bool m_ADSLFailed; // Did port mapping failed for the ADSL device?3 Z; }0 O5 w9 @, T* }
bool m_bInited;
% S1 ~/ }8 C- c+ I# j4 Y+ ? bool m_bAsyncFindRunning;
& s! |5 R2 p! X! _3 l HMODULE m_hADVAPI32_DLL;
( b& }; P: }$ H; W3 o( B1 W* r HMODULE m_hIPHLPAPI_DLL;
' z4 i; }% _/ M% V# t0 K bool m_bSecondTry;
5 o [& L; t; M2 y3 N bool m_bServiceStartedByEmule;
8 `+ ]" U0 S+ m1 c4 |5 G3 } bool m_bDisableWANIPSetup;
1 g% ~0 E& }5 P& P- s# o bool m_bDisableWANPPPSetup;
6 ]' ]' u! b7 i% R* W: H& e, |0 S, U) {2 o7 R
0 |) C3 _* b7 F# F( r5 Y};
6 @6 T/ G" F7 R0 u: B1 D$ t( l: X1 Z! p+ D4 q& f$ f
, S9 M8 }7 E, k& K# k// DeviceFinder Callback
4 w9 M4 X+ u# b5 |/ @0 ~0 a, O0 C) ]class CDeviceFinderCallback! M+ E/ g4 O6 k/ q+ G. q
: public IUPnPDeviceFinderCallback
) a* l. y# f1 _{! ^! H2 p/ j! Q
public:& O6 k; E( c! ]* t3 f$ y1 }' z
CDeviceFinderCallback(CUPnPImplWinServ& instance)9 X% X/ y6 [3 {* l7 T& P+ }
: m_instance( instance )
" q" Y* S5 ?; u: U7 A( { { m_lRefCount = 0; }$ B( }6 @( M; b; g; x) [ i2 z) Y
! g$ S+ y, v: e; z; }0 n
/ A- o1 a) w) K' Y2 q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; e( q/ w5 ^" B. @. l/ i STDMETHODIMP_(ULONG) AddRef();
& j6 D' g7 a3 C# l STDMETHODIMP_(ULONG) Release();& x* m1 h6 g5 A- k
& ~0 U2 v( h/ Y" U" i
; ]- k3 _0 v9 X8 [: j. z// implementation
5 i d4 `; ?- v a+ a; v6 U% P: S1 gprivate:
W6 n E2 P5 k1 K. I* i Z. e8 W HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);; f2 S4 B) H, j, b( w
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);) V* ?5 W* T* n
HRESULT __stdcall SearchComplete(LONG nFindData);
- g: d4 c' Q( q
( i' k! D- m# h0 \1 X B% F9 k: v8 K$ x4 w J1 ?8 t+ A* ~
private:% z+ E9 r- t' I7 ^, `) z8 r
CUPnPImplWinServ& m_instance;
2 J- A% r% E" g( r' X- T LONG m_lRefCount;: T3 a1 r# z. J7 X# e1 g; r
};) \0 [% u; c* Y# e
: d6 e3 J" Z8 s+ p) d: g
$ m9 s& O6 d9 _$ {$ i- b; a/ N% @
// Service Callback " k) {* c D: Y# h% Z- G
class CServiceCallback
7 O+ E* t' S5 q% g* m% J : public IUPnPServiceCallback% f Z* ~) F( a# }# y6 c3 |
{; d- J2 j% W" Z7 o
public:" n5 W% ^* \0 N
CServiceCallback(CUPnPImplWinServ& instance)! Z2 g, F& o& H0 T
: m_instance( instance )
+ W9 [" f7 B& U; [, f: R2 J6 v { m_lRefCount = 0; }
; N2 I" K/ |: u
; B8 i3 Y: E7 {( Y: w+ s2 W STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& v% u& i2 k, b& N( _3 m STDMETHODIMP_(ULONG) AddRef();) W- q7 E2 c8 p6 X# J
STDMETHODIMP_(ULONG) Release();( A5 z1 D1 z0 G# |7 K" }
/ g0 w% o- ]) v9 J! W, S7 r, g4 K# Z/ w4 K5 u
// implementation1 w3 C: F" @% F) Q
private:
6 Q- c+ W* J- W. {8 Y& `: D( Y: d HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);+ X2 K9 L h8 ?1 D
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
; B! j, \5 \* N; Y8 N5 J* V
m) ^5 ^7 K, }
2 E+ r X; ? g! z- H( Vprivate:2 F* O) g: o! \6 S
CUPnPImplWinServ& m_instance;9 `* H6 `7 y2 w9 ] e- Q2 L
LONG m_lRefCount;) X, F# g1 k c; s/ b- ^' b8 o
};" b; P, f( {5 G6 r& `/ p
4 H0 }" r* F, z8 G0 ]
, q- _" X" A5 R( p' n' z
/////////////////////////////////////////////////
7 V0 F! ]5 h d' l' y8 ]0 a3 L% G! L4 @' _* S- V
: X3 F2 S, B" V使用时只需要使用抽象类的接口。
5 n! G, [- X' W0 w/ h" yCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID., e; _6 s9 D* v+ h; O, g+ U+ H
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
3 A7 i! P8 M1 p& [CUPnPImpl::StopAsyncFind停止设备查找.9 Y! ]. c: e6 Y( J9 O8 {! N2 L( A
CUPnPImpl::DeletePorts删除端口映射. |
|