|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
+ A9 u, i# G0 \! F% W8 |) ]
# h' @! Y" ~# T, N2 C2 o* ^; V
; A) l7 h, p8 {0 H% J' j///////////////////////////////////////////
) b# o' j L# f# \//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 M7 z3 ?. s, w( y- d" r4 o
/ e. _) j' x/ F0 p! z6 _
+ J' K1 K4 B/ ^" ]#pragma once8 K+ W: _: t* h
#include <exception>
2 `& F0 E3 @; Q- C- a4 j- |: a( t
* O V5 ]1 ?4 _" u* k
- y6 m" r+ z" m; Z enum TRISTATE{# |4 ?5 h2 t0 s& x- S. V( c
TRIS_FALSE,/ @. s* [4 e$ J' z5 s% C
TRIS_UNKNOWN,) ~% A$ N8 T+ Q& M$ W7 o
TRIS_TRUE
. F6 V/ }% y/ ^, i- Y+ P2 F. Y4 S};. g# Y9 S+ ^, j
! I! z6 \: s) p, g0 W
" v2 x" e1 j/ f* Y9 ^9 W; M, ?% t6 W) _enum UPNP_IMPLEMENTATION{
4 w) F- b$ M, j+ } UPNP_IMPL_WINDOWSERVICE = 0,
, ~4 D9 e1 R g+ ~, o3 v5 a) r UPNP_IMPL_MINIUPNPLIB,
6 j K6 F4 S3 n3 e: h8 ` UPNP_IMPL_NONE /*last*/
+ B% i) A" K1 C( y/ j8 X};
. o9 Y0 c9 s" T3 i& v& Y- l% }. z8 W9 l4 l6 |, `4 g Z# I. F
# t- R+ ?5 B8 b0 g# I
' S2 U& ?( V7 S) T/ h U
) o2 g7 {4 _# q( J; y: V5 F
class CUPnPImpl0 n, f- i" B' C8 g5 J
{
1 T* S' A0 q2 }2 Cpublic:
( T; r/ [( M1 h" r CUPnPImpl();% \" E5 b) x* Z) m3 Y
virtual ~CUPnPImpl();, g" \0 {9 {; Z7 j0 ^6 m& D
struct UPnPError : std::exception {};* |- H. e( H4 K( c8 Z' Q3 W
enum {
a# E; C8 e$ M! [2 }; D8 Q UPNP_OK,
1 V1 K1 u2 _& G UPNP_FAILED,5 X2 _- B0 Z. G7 _$ d9 \* x
UPNP_TIMEOUT
) i' ^) |! _2 e# ^ I* ?' x };( D7 F9 |9 {2 ]8 Z) d. _6 h
5 k( Q- A. W# f/ G3 |& e9 f. D. m4 B. N4 l7 [% C1 }- S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
0 Q& W: ]/ i+ A- e2 ^+ y- o1 `' i virtual bool CheckAndRefresh() = 0;( J& o N- \- ~! |, N% H
virtual void StopAsyncFind() = 0;% [9 j" C' K1 s2 w, o/ t% g
virtual void DeletePorts() = 0;* g% Y' A. J& s
virtual bool IsReady() = 0;8 k+ w# M. V! X1 A
virtual int GetImplementationID() = 0;- E8 f2 a& Y4 r. m
- f) I6 C e/ q- F7 D8 b
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; b- b8 i0 k- v `( i4 C
6 `, r! r8 ]# m9 e2 J' j2 H; X8 R$ x4 ~9 [7 f9 S2 _/ W
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
4 W6 m; l$ R0 G% P TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* U2 x5 x! A( u. J5 `2 a# Y uint16 GetUsedTCPPort() { return m_nTCPPort; }
9 c: Q1 ^8 y$ Z9 C uint16 GetUsedUDPPort() { return m_nUDPPort; } 6 l* L! p8 e9 c7 F* Z1 |3 {
, |: \ k( v8 B6 r/ b1 `
% l. D8 K0 H/ B
// Implementation! R" B0 q H/ o7 Z. r& T
protected:# _. O- V' X% E& T2 i
volatile TRISTATE m_bUPnPPortsForwarded;# u& H/ _) }, a3 B% U3 |2 ~% ^0 e
void SendResultMessage();' p. Z* t3 w5 g4 D" [- W1 b
uint16 m_nUDPPort;. ~! k# H8 M1 y) Y' k4 u2 I
uint16 m_nTCPPort;7 c+ p' D/ `* P1 `+ W3 F3 I
uint16 m_nTCPWebPort;
3 Z6 s- c3 M$ W bool m_bCheckAndRefresh;- t! S1 V3 b. m8 n7 x
& Q* S; }& Y/ u7 k6 V( X
( V2 _ x* F D/ L& \& ^# P jprivate:$ b1 @2 Q5 _ i- s8 N* Z
HWND m_hResultMessageWindow;, ~( y' g' N8 I3 V: R
UINT m_nResultMessageID;; I' k: _7 v& M! }7 h" W; Y; `
3 Q) Q, L# C# m( I/ w( M
, n: A- Y8 k2 _};. @- B" z9 s, T( J* S- Q/ w
- b2 }2 p. S; \# V3 ?8 k
0 e- X* F& B9 @, @ u// Dummy Implementation to be used when no other implementation is available
8 d/ h3 d5 [/ @* z5 Eclass CUPnPImplNone: public CUPnPImpl4 r6 e- W% k4 R& g1 ^3 E
{
, Z$ ? k/ a P2 t4 v6 Npublic:. w" ^! K( M1 I2 D6 W
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 V$ r, Y7 p7 E9 `+ U4 Z% M @7 ?# | virtual bool CheckAndRefresh() { return false; }, o' V+ X w N- U0 U
virtual void StopAsyncFind() { }
8 [, N$ \9 `4 w+ b S virtual void DeletePorts() { }9 d8 f# F2 R$ }
virtual bool IsReady() { return false; }3 p; I3 b: [' w; V9 k
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }- A. U: d$ g: g, G
};4 m. f- r4 ?; T
" w: h. e, u) c) V( p9 ^( p
9 L; ~1 b* f! l1 G8 K% R2 j
/////////////////////////////////////* P0 s% j: t, R' W4 T" z: T* ]
//下面是使用windows操作系统自带的UPNP功能的子类' @" O! b3 c( X9 W. z
3 v. R1 R) P/ ^0 n4 b
8 }7 w0 L$ H2 m) L+ R/ b#pragma once8 `7 O( O; E: r3 C* q+ u
#pragma warning( disable: 4355 )- p7 d3 L, K: q2 f& o$ P
( ~" J3 p7 R2 F3 n$ ~0 s
* }" V8 T! V- d! B#include "UPnPImpl.h"
4 ^. B0 a( O, w N#include <upnp.h>
5 Z* T0 |/ C3 k$ p: f#include <iphlpapi.h>+ @: ~* I; j8 i# J
#include <comdef.h>4 P7 V0 T+ |$ B/ X9 g& g
#include <winsvc.h>
: S$ B0 c5 h. k" q( b6 z: B
& K: W3 @/ ~8 g; [( I/ A6 G) u& p/ }" S* e9 b E
#include <vector>
K- h* E& j( T0 m8 @4 r#include <exception>
3 ^1 O5 B- b2 m* `+ a#include <functional>' m- L' P+ W6 U" N4 u/ B
" l9 R& C4 Y( }% ^
& t% g6 l3 N0 ?% W4 ]- {6 X3 V0 C8 E R2 O% s1 c
N8 I2 A$ _+ m/ `% Ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. F, _0 X& b1 u! W- O7 ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
5 Z* \1 b; s' n9 q% y1 Z1 i1 itypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;2 Q( I( j$ u" @) X3 S* J: m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
: v- m! @/ G6 ~! b; ^/ T9 E2 Q' r8 xtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;2 W& ~. \+ r: z7 B5 @! ], S) }
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;( T5 h4 f/ e* ~
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;: G, Q' {! u2 I! Y, w* D; o9 D5 u
3 K1 s1 {# R& r- }, C0 w' e# ^) ?. L. N6 ^ J+ o
typedef DWORD (WINAPI* TGetBestInterface) (, D% Z9 L! X3 d- p; q
IPAddr dwDestAddr,' ~ G- _: R8 [, _' Z8 H
PDWORD pdwBestIfIndex9 i( O, z+ I; _% x2 ^
);
, U( m* I2 j# A4 v; s, K8 J0 W
. o6 C1 M( a+ z
5 N: P; M7 k" e; @ ktypedef DWORD (WINAPI* TGetIpAddrTable) ($ I/ `8 Z0 Q T# x/ C3 U
PMIB_IPADDRTABLE pIpAddrTable,
6 E/ S; g7 c& D2 u5 W% h' z. y PULONG pdwSize,. u. @& c% R" v8 X$ p3 B' H
BOOL bOrder" `4 s9 k, o3 K: W \: H& j3 h6 X8 s
);
% ^* [9 {/ q4 Y" {: a" O
. r/ S+ ^& k+ L; D9 `1 D/ a4 e1 ~9 W
1 B+ R3 Y: u8 E- c% s! Wtypedef DWORD (WINAPI* TGetIfEntry) (
@) T6 Y W5 c% s PMIB_IFROW pIfRow; V4 h* Z9 M- v1 }# \
);' f% b) Q4 i; _, v
, z) t1 U1 _0 B4 A I7 o1 ~6 p! m+ Z {& z7 u
CString translateUPnPResult(HRESULT hr);
; B+ n% A1 B0 K7 _! }: _* N. s" ?HRESULT UPnPMessage(HRESULT hr);$ h4 b+ k' k6 M" N# `) C5 j
`- L; V9 \; o5 Q: V
) U5 E7 k9 I8 f6 b) O% hclass CUPnPImplWinServ: public CUPnPImpl
A/ ?, W% \+ a8 a3 E& e7 y{6 v0 `0 U# n8 T2 Z
friend class CDeviceFinderCallback;
- |. J8 b. O W" H) L friend class CServiceCallback;
# c- v3 q4 \* \6 ?0 k# Z) E// Construction
' z; c( t1 D9 G0 k, X2 ]5 Xpublic:
* i/ C! N5 W7 K- m% Z3 c+ i- s3 T virtual ~CUPnPImplWinServ();& b6 Y; f+ }! N( K6 X
CUPnPImplWinServ();
: b) v: G$ \8 z0 U
- q, _6 ]! K. U4 P- \# T( W5 _3 C5 j
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }" |* W/ Y1 l% O7 r6 P3 |
virtual void StopAsyncFind();
1 J% w( T# T# G& {+ d' n* d virtual void DeletePorts();
( ~% f; I# h% s1 ~8 z5 m virtual bool IsReady();( Q( M. o! J! g3 n; S" X
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
/ @! X9 l5 C4 W) l8 V" D! Y2 _
5 \ f$ Z% |5 L/ B3 {
$ ?$ G4 u8 n6 O) S/ D- ^ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% z4 H9 x& m/ p5 X4 ~ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later$ k9 g) q+ t0 a& |) c
virtual bool CheckAndRefresh() { return false; };
9 N5 T+ k/ ^: J; m+ h9 x: l+ C' h M3 I/ {. R+ M
# ? R2 P- ?% p* i; f# ?protected:4 b5 F6 a5 A5 s% Q/ C
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
1 e- x7 m! q' L& o void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 \: D- r# c8 u5 j- M void RemoveDevice(CComBSTR bsUDN);
1 q: O2 n+ }1 R4 H2 Y P$ M/ [/ m$ D bool OnSearchComplete();
* a% j2 _4 `. O void Init();! t# p7 x0 ]3 y& V/ S _
4 W2 ?5 K1 ]3 G0 g# z4 y4 c) w( ] n, X M
inline bool IsAsyncFindRunning()
7 ~ Y! C b* K7 D9 X8 p {: U2 W# B4 j4 S' Y2 }1 P Z
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )9 }! [. ]; |0 L3 w O2 W8 l
{
) g* a1 J2 \# X2 D m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* N' S$ w' S2 M/ o6 q
m_bAsyncFindRunning = false;
# o7 I* z) r# a: i2 Y! b }
- _% G, m9 s! |/ p MSG msg;
7 g3 v: Z% b V: z# q4 g while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
4 M0 I" H. O1 U8 k: v8 r1 F* y {
, Y. f# e4 P0 A5 U/ `* {; [: A* _ TranslateMessage( &msg );: _6 a O4 H; f5 n* w
DispatchMessage( &msg );7 i, ]( d: g& N0 S' z( x0 w1 v3 L' T' w
}
. Y3 w5 r7 v* ~1 I; b return m_bAsyncFindRunning;4 H! z. |! U' v8 F$ R! {1 l1 o8 `
}1 |( `6 d( r' v% `2 a! M4 {4 z
% f6 w9 g6 i" ~+ U7 M& h- q
9 [% P1 V; y, m. x: t( ^0 G4 ^ TRISTATE m_bUPnPDeviceConnected;
; g! Q5 \; n& y4 x$ r
4 i8 I: J2 a) J/ s: K' a1 f2 U; b
1 l/ }+ e; W# g: x r* t3 H// Implementation1 g% }8 }4 p! A+ c- D4 v
// API functions
& S$ l7 p8 K/ k& |) m: A: q SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
+ B$ J2 {2 Y3 s9 N0 F* z SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
3 c' t1 U+ _3 M4 t BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);& G) L/ Q/ b$ u w' j
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);- d: p/ k' F8 v
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
6 W6 l* r3 V5 y$ l$ U! N7 j BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
0 W( K4 J- y. S! Z0 C1 c6 {; n: V9 u4 |% Q0 w
0 p/ O$ R3 d4 R/ P+ `4 j/ J# ~
TGetBestInterface m_pfGetBestInterface;4 x$ {8 p) R2 n. z# W% U; e3 v
TGetIpAddrTable m_pfGetIpAddrTable;0 A" w# J8 V, ^- Q# l
TGetIfEntry m_pfGetIfEntry;/ F# d+ X1 B( Q; Z- o
( P7 X4 P. ~0 b" F f. }7 K) Q9 y1 Y! G$ |
static FinderPointer CreateFinderInstance();+ u( [' \: B |5 L' ~9 R. i. ^' m
struct FindDevice : std::unary_function< DevicePointer, bool >' ~: Z5 \" y6 c3 s
{4 S8 j$ w2 G8 j4 r' ^5 o
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}5 y6 B& x% X- a3 W2 a4 N; v
result_type operator()(argument_type device) const
, Y3 s( R$ d# T- C {
- ?3 [1 a; Z, Q4 q# [* b CComBSTR deviceName;. @6 @ T. m4 f, h# e
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
+ V9 _* M; G5 L! Q/ e8 [; `
, V* a- @3 J1 d" g" \% ~2 F! Z2 ]
) a' m! F9 M/ a. V: ^3 C if ( FAILED( hr ) )
" R& ^0 F: ?, ^" l- G/ N3 B return UPnPMessage( hr ), false;
1 Y- K% K9 p, |. N9 `2 n8 Q/ o: r$ ~- ?) W" x8 K
' p; E- i8 ?# Y: \7 m
return wcscmp( deviceName.m_str, m_udn ) == 0;
* O) N' O @. q/ U+ G4 n, O1 X }* u9 K% g: m1 v' W# v/ v4 o: b6 c- m) o
CComBSTR m_udn;
% z* p) T D9 Q. W7 r: n& o };% O& C6 b+ [3 k4 R
* A$ e' n. |5 @8 j
void ProcessAsyncFind(CComBSTR bsSearchType);4 o" v) o. a! g9 e0 @" q6 |
HRESULT GetDeviceServices(DevicePointer pDevice);' A! W) {& P( }, ]
void StartPortMapping();
`& r& ?. K% d HRESULT MapPort(const ServicePointer& service);
( z6 W. Q" i- t7 o: \- h( d void DeleteExistingPortMappings(ServicePointer pService);
) X( s3 t1 K1 o& G void CreatePortMappings(ServicePointer pService);# d: `. G+ [2 O7 ]* f
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);. ~/ N2 l7 d0 c: P3 v) ^3 I. V0 q* d" ]
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
% {4 ? \, c- P* S( B LPCTSTR pszInArgString, CString& strResult);1 b$ ~; \5 @, f4 `
void StopUPnPService();
+ J: W- V; j; b( u# g; G" f9 n9 K! ?
" v3 J7 c& j: O3 |! Y# d: [" j( C
// Utility functions
, O" p4 z( v4 T. @/ |2 w; m8 w( Z4 t HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ Y9 X; U) L; R% M6 Q1 |
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);- k6 ?- o. o/ q& Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);- D! Z B) {4 U' E: S
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" w- R/ ~8 a5 X HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
( W) f. T/ ^5 k4 ]& o9 Q, u% y4 g HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
8 C9 L" O. s: u( h$ P$ c' S CString GetLocalRoutableIP(ServicePointer pService);+ T8 C; Z, h7 X! g( M4 {
: Q2 n, t( _% u" [- Y# X) k( F6 `
// Private members
" q- K: X2 _6 G, f& kprivate:
5 H# r1 P, e3 r( q6 N3 l9 I4 W1 L DWORD m_tLastEvent; // When the last event was received? Y( l9 Q7 n# X
std::vector< DevicePointer > m_pDevices;; n4 q2 P' L7 o' ^+ S! `; o
std::vector< ServicePointer > m_pServices;, f% N$ P8 _& n9 r. I% g
FinderPointer m_pDeviceFinder;
0 j5 [/ A, {8 p( {* |! p9 U( L DeviceFinderCallback m_pDeviceFinderCallback;
( M) x! T) Y: S6 a( N+ }0 c. U$ p ServiceCallback m_pServiceCallback;
l |% E8 h: d9 z. C5 g2 d/ K1 e% ^/ S' a
, Q9 ?: u% L6 J LONG m_nAsyncFindHandle;- V* A7 }+ j0 s7 Y$ c. Y; l
bool m_bCOM;
% k! ]5 e& r8 Z# h$ ]1 W6 A( P5 I bool m_bPortIsFree;
# z t) b, ]+ X" Q4 K CString m_sLocalIP;
, O0 r6 V: _: a1 L! Q CString m_sExternalIP;
* ~) a* w" G- y9 p bool m_bADSL; // Is the device ADSL?
! d2 G+ h7 E6 ^' p$ x5 ~ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
2 b$ ~/ _7 O, u. {. q4 o bool m_bInited;9 q4 k; C2 w3 r% c5 {0 {
bool m_bAsyncFindRunning;- R" d( b0 E4 W" q* d3 ]& D
HMODULE m_hADVAPI32_DLL;
+ J% l9 _( M$ C/ @2 k2 ~1 `6 T0 ] HMODULE m_hIPHLPAPI_DLL;
4 L* `! B' t" X6 ]0 h bool m_bSecondTry;
. c& I6 _& q0 N: W bool m_bServiceStartedByEmule;% {# S- d+ V, \" Z4 ^5 W
bool m_bDisableWANIPSetup;
' C2 n2 |7 P: E/ M/ q, e; E bool m_bDisableWANPPPSetup;/ z) @9 |) x! j) w* @- `( F6 X( C
, c, Z- d7 O- y/ h' w
0 m8 Y) ^/ _: {! \: j- X b/ C
};
9 A. _% d' E5 j1 v/ ?
5 K z/ \- ?5 {; ]# H- [5 I- N5 o6 E8 a$ d, D h' R5 e
// DeviceFinder Callback
- B& M4 R C1 ?$ g9 ^% ]# ~: J' [class CDeviceFinderCallback
* {$ H1 F9 y* V* ]# L : public IUPnPDeviceFinderCallback
! M) V; E3 f, u! O{
) a5 c% G3 G2 ^; k: l4 @- Lpublic:
: j; h2 r5 z: A CDeviceFinderCallback(CUPnPImplWinServ& instance)
y5 X/ j; k3 P- l : m_instance( instance )& V; z" C8 s3 N8 q- @9 V4 E
{ m_lRefCount = 0; }
2 p# n# L5 Z# x9 L) v/ x
6 U" n- r; Q5 a# k. s
" \: J% _+ r( g5 V6 L3 [2 P0 }( t STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 ~/ H' q9 |2 F! w# C! Q
STDMETHODIMP_(ULONG) AddRef();5 j6 o6 ~6 Q( l
STDMETHODIMP_(ULONG) Release();7 [* g7 n( d+ Y7 w; `' j
# @/ r; G3 g; N S
+ Z2 Z8 G& b5 M. H4 Z, n& w% p// implementation
1 X5 t: q. S3 S& T2 H% _# rprivate:( l: ?, q4 _1 S
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
% n- D. _! q5 m HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 G8 m& k" w7 E% p0 W9 h HRESULT __stdcall SearchComplete(LONG nFindData);0 G. L7 N' f1 y
v, b8 v' T/ }/ y E* g( M
: A2 w, P7 S. o, ~0 n+ vprivate:
, i- X' A7 `# ` a( D CUPnPImplWinServ& m_instance;3 R9 O% k4 p f( F
LONG m_lRefCount;
7 B% x c3 C0 z2 w) n; U* E( ]};
5 g3 \( E7 q2 E& D' D" g( B; \: E3 \6 q( l' E$ u \) t
" w2 n* D$ L& f4 [
// Service Callback 6 P2 F' E$ X/ J' [4 G
class CServiceCallback* L7 A. F' q+ z
: public IUPnPServiceCallback+ S8 Z. f) V U1 c+ { j
{
# |( {- R3 A6 `public:. `; m: n) L7 U* |7 O
CServiceCallback(CUPnPImplWinServ& instance)
' U/ p6 C; u7 ]9 W$ y : m_instance( instance ): c. ]; ~% P6 c' y+ e5 E- q
{ m_lRefCount = 0; }
1 f: u1 D: L! c j8 |/ Q/ B9 T; I4 s- v/ M. g
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
* i1 S% o, h% [/ j& C STDMETHODIMP_(ULONG) AddRef();
' m+ W V& q* @7 Q9 Z; x d1 B STDMETHODIMP_(ULONG) Release();
1 ~! D+ Q( m5 I# ]" f! b$ Z. F9 s m- v, u+ L1 W4 R/ d
0 A2 ~7 y9 Y! `- I4 }
// implementation3 x; W' d, M7 U% Y+ Y# U
private:, @( b- Q% q0 b I1 U
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
8 l' Y; {9 m/ S( Q% V HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);; L. C) A9 J e* J
- E. Q' d! T/ L# b- G- Y' V4 ]7 x! q) m& D
private:
' P4 I" f: i% V CUPnPImplWinServ& m_instance;! [7 D% k/ R* ]4 a# ~: [& W9 a5 |
LONG m_lRefCount;
0 E3 P6 k4 _: j( Q% Q};" C6 l" ^' x. P1 }6 W- @
' H9 f7 X5 Y9 Y( x7 r2 `/ }
5 B& `+ c% Y5 @% U3 c
////////////////////////////////////////////////// i: j& Z* g' p0 l; W! p; \( V
' M n; I7 @5 B
0 \9 p- k( G( v) l$ e3 n使用时只需要使用抽象类的接口。
' ?# m* D: K; E$ Q* }6 ZCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
& r7 z B1 n, |3 G$ H" f* ~CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.2 P) M! F% [( @* N8 V
CUPnPImpl::StopAsyncFind停止设备查找./ b- b- Y, t0 ^& L& ~ p
CUPnPImpl::DeletePorts删除端口映射. |
|