|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' @4 \ A0 b5 p F# d$ K: y! S' g, b8 j# a8 b) B* B
9 U. ~$ Y4 J: l% ~///////////////////////////////////////////
) v6 |( \ G) Q/ g//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
2 f' M& G9 C- g$ I( C) i5 I3 {; s
0 t: {4 P0 Z% o* D/ r) f9 o; Z3 t, x# y1 z' f
#pragma once
6 H, ^# x( N7 m' F) s8 x9 }#include <exception>
% Y- F& S# O1 E7 _9 R
$ j+ ^; c# M8 Y! [, @$ ]# F' p0 d r: h: h7 J9 |; s: \
enum TRISTATE{
|8 E: h& S- k( r8 X$ S TRIS_FALSE,+ A T$ X3 T2 v' q8 E0 \
TRIS_UNKNOWN,
6 c+ @" Z/ `2 m5 w! F TRIS_TRUE" t8 u3 f& C x+ r/ v! H
};* N1 P& h8 a! x9 \. Y
% s2 ?9 [! z/ }+ `9 m- H+ S
5 L0 W! U# H# [/ Eenum UPNP_IMPLEMENTATION{) f1 m) |1 I, d, J2 \& D9 U& c
UPNP_IMPL_WINDOWSERVICE = 0,
+ Q& w3 X% I+ Z0 j+ M* z Y$ _% w UPNP_IMPL_MINIUPNPLIB,
7 g+ T& I7 J" [7 u" a UPNP_IMPL_NONE /*last*/3 k* u" a# W; n9 ~: y D
};. o! }( l& }) Q( [4 I* I% R
1 }2 X; D& }4 B
' }& [) q) r5 T' X1 d4 B9 D
! g1 P3 ?0 i- s6 \4 H ]0 I) \
# j6 g" q8 ]8 D6 R6 E6 t0 ?/ bclass CUPnPImpl
5 q$ O4 n2 _) w7 L- ~{' O. r" o. Y0 |+ y# a L" a
public:0 \ m' o0 ~& a" Y* s
CUPnPImpl();
$ o. [$ p" n5 R# a virtual ~CUPnPImpl();
. |% P) d8 q9 r) ?6 y struct UPnPError : std::exception {};2 Z# f$ c1 z( y3 w/ y5 A( C
enum {
' D B2 t4 `8 F UPNP_OK,
4 N( N& r) s$ Q4 m5 } UPNP_FAILED,
! o" @. d0 V/ i9 k1 @$ P. _9 r, Q UPNP_TIMEOUT
; V" h3 p) L: ]( _- `. r" Z };
# t S* C. a3 B- v: e3 @* e6 K$ V: V$ ~7 W3 b {' O5 h
! R3 ]$ v6 @( M2 {# Y7 q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;$ Y! K; Y# ]4 v
virtual bool CheckAndRefresh() = 0;
" {* C/ R' l/ ]/ ?+ ~' x9 @ virtual void StopAsyncFind() = 0;
/ |% a; K/ A0 K, ]8 h virtual void DeletePorts() = 0;
% {6 Y6 F9 x* t0 F virtual bool IsReady() = 0;
j$ j& F. k" j5 e3 a* e6 K" @ u virtual int GetImplementationID() = 0;5 ~* A7 f0 C7 k- A
! l4 a" O6 L& j# \8 I" ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping% u$ g; J! i4 d
# Y6 L& S8 @! x! V2 ]
1 I3 ]$ W6 ?9 p6 k void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 B! H" h7 J! J0 k
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }4 J4 Z, S% X4 i2 a. q, E
uint16 GetUsedTCPPort() { return m_nTCPPort; }/ r% Z- h) {' x: K+ B8 V: E" D
uint16 GetUsedUDPPort() { return m_nUDPPort; } & O% Y% Y0 U: ?1 L" G
$ q8 U. B0 D& x: x7 i2 D& J; d7 u4 A$ |4 z$ B; n) g' F4 o: @: V
// Implementation7 Z8 H, v) W: i6 K# ]
protected:; c) ^$ d& S( [4 v
volatile TRISTATE m_bUPnPPortsForwarded;
9 |- q0 ^2 v | void SendResultMessage();
. z: L$ A" `# s2 Z7 ?2 Y uint16 m_nUDPPort;
9 |; l9 l( A1 C; u uint16 m_nTCPPort;5 F0 D; H! H% ^" r5 f" [
uint16 m_nTCPWebPort;/ d' L/ x- z! w# S
bool m_bCheckAndRefresh;6 u9 L" l% R7 l9 P1 K" ?
% x i7 A( j6 x2 v! f7 M
K" M! G0 l; l) `
private:- @# A3 ?9 `' r4 ^$ z
HWND m_hResultMessageWindow;
/ x# `/ `9 K& Q0 ~5 \. ^- x0 K UINT m_nResultMessageID;
2 n7 I0 `5 g" V$ W4 T- Q: X0 a4 S1 t3 g' i8 ]" m; V% H
7 z1 q; h' e& U1 F G( m1 M
};" M& `% y0 n/ g! x7 L0 V$ M3 v
% `9 A+ d0 C% S# B
% [* s5 S, p% R5 ~9 c4 m// Dummy Implementation to be used when no other implementation is available y3 R; Z+ V O8 Q/ y
class CUPnPImplNone: public CUPnPImpl
& \% p! D/ _7 F{
& Z4 c* u, Y- bpublic:" _# @! }7 y" a( f
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( }3 X/ w6 D% z virtual bool CheckAndRefresh() { return false; }' A) Y5 j) O& D, i; l4 j
virtual void StopAsyncFind() { }
: l; s" @7 n" S1 m) @5 } virtual void DeletePorts() { }
0 g- p5 ?- ?/ i virtual bool IsReady() { return false; }" ~* E' e- f- y1 [9 m; T
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) O/ _. \" [! L, n6 L/ a9 `" m
};
9 G& Q8 f3 Z7 Y3 Z% \( }1 ?
' I9 u6 ^1 v# H- k: |
( }7 ^' ?0 w7 P% |' x3 @/////////////////////////////////////
, u4 g/ H- [ |9 ~//下面是使用windows操作系统自带的UPNP功能的子类
: U1 H' X1 e0 ~: o* B( X
* F4 V0 r! a- W# |) Q
2 k, g0 b4 M# C: w& t- X0 B7 r9 P4 Z#pragma once3 r' Y7 k1 G0 b
#pragma warning( disable: 4355 )# g* q- c4 v% m w$ N, F% k
6 B2 }# A% C: i! g/ g! F
9 V4 C. `# s8 [- v; E+ }4 d#include "UPnPImpl.h"
2 Z# E3 k4 }, W2 X#include <upnp.h>
2 r0 l3 }3 ?% f- @2 y#include <iphlpapi.h>- J( j' \0 a9 j( }# t
#include <comdef.h>) d" D% D) c( U$ @
#include <winsvc.h>; @' c" H. o; s8 A7 u
$ |3 j; `' D( c$ C6 |- m
+ q" u, N; F9 h% j4 A7 Y# S% V. X+ C
#include <vector>9 q4 K' I' l6 Y6 K+ X( i$ ^7 n* P$ g
#include <exception>- N2 e& W* r% K. m$ _; h0 d
#include <functional>% B$ c: |; o% P. G1 a
, ?4 _7 R- N1 u2 `6 a
0 V' ]0 M4 }* b9 J5 V9 V: a
6 `" l: n7 a0 A
3 R7 U. w1 ]0 l4 J& C4 jtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
( h" ]7 C3 K2 i/ }, ?, u8 K5 Btypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;, ~$ z) m9 q* a& Q3 Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;/ Z& \& E0 B3 y, a
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;, h+ M) ]1 ` }# J
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" g7 c, `- P- z3 t8 f9 T ^, ctypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;! U: n# z3 ~7 Y. L
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;' Q0 Z. i$ D3 y7 `* Z
$ }/ X# D( `8 P4 _; X1 ]0 W
& _3 d; v' h+ p& C8 a* jtypedef DWORD (WINAPI* TGetBestInterface) (( @+ N$ O) F. [# C1 h a+ h
IPAddr dwDestAddr,& c m* ?5 Y& v+ q' f
PDWORD pdwBestIfIndex/ T, k4 A( _# X' p7 i2 V
);
& U. ]2 L g9 [; ?2 ], G7 m5 Y6 `8 [
2 i7 r: L- }; X/ _# ?' u7 b
typedef DWORD (WINAPI* TGetIpAddrTable) (9 b0 c( o$ o) a; d# F
PMIB_IPADDRTABLE pIpAddrTable,
}- F9 W% z& B) \. E% a PULONG pdwSize,
; W j5 J1 K0 K$ `6 N/ f BOOL bOrder: u. \8 x$ |: L
);
4 I- X5 M. i8 J K: v5 x( e
2 y: `7 t* r5 d3 t/ E' ~; n) N9 I1 ~4 w
typedef DWORD (WINAPI* TGetIfEntry) (
2 E& U) u6 s# a2 p- N$ Y1 ? PMIB_IFROW pIfRow6 Q0 t, f7 @2 M$ N8 J
);
$ R) D- J# F w R: i o- g' H* ^! E3 M z% v- e3 R' u! I% ~
& i9 E, F7 x1 y+ \4 h4 ^. X! c$ A
CString translateUPnPResult(HRESULT hr);
$ P7 p9 j8 h- U2 l/ B2 H ]1 T/ @, gHRESULT UPnPMessage(HRESULT hr);4 ^; m! @! }2 }4 W( x6 a, L
6 [7 |4 ~% ]5 s2 `0 x2 S# c/ `& P4 f' [2 a/ D
class CUPnPImplWinServ: public CUPnPImpl
5 V1 m5 U) M+ N" q/ Z{' e; A5 `0 y$ |( [2 u3 z& N
friend class CDeviceFinderCallback;3 S k6 S9 c3 o% E# S8 ?
friend class CServiceCallback;
# E0 Y2 E8 X" ^1 X5 b% ?" P// Construction
$ g0 ~ M# v- R- E3 Ppublic:0 i6 ]- m6 {/ i3 [" a, [3 d4 R# j
virtual ~CUPnPImplWinServ();) j" O% ~7 j$ i: P9 P' {8 |
CUPnPImplWinServ();0 ~" ^, ]& X- V) s. V
$ V( ?# U( [" O. u4 X# w% E
1 ~% _( p% L4 o$ B. ?8 f- C k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
' m+ d4 i: L1 X$ S# m) y. s/ [ virtual void StopAsyncFind();
: i6 j! o5 |. c7 J& j& ^2 x% I4 R virtual void DeletePorts();! [8 A+ l1 L2 K! q& T: l% `
virtual bool IsReady();
9 u, J$ G( z4 r$ J0 s5 F* B y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( f/ Z2 C4 [8 p. U! r
- v) F/ n$ d( @
! e; w- t2 r& ]+ Y // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
& c5 m$ g$ j, w; r# P // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
' P6 b7 u$ F' L5 c8 [! M virtual bool CheckAndRefresh() { return false; };% K/ K: [6 d# [$ w
! H! |" |) z2 @/ i2 Q% i( J9 u
' o% \& C! M$ _protected:7 p* m2 K% B+ M
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
5 D- J6 z0 y* r8 ?, F4 x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
2 }6 F! q7 i9 N) F/ @) B void RemoveDevice(CComBSTR bsUDN);
: s7 P& G9 Z1 a" W2 n$ N bool OnSearchComplete();
; t" b( {" w% G) U void Init();$ W% ]+ L( ^6 I8 ?9 f$ j6 F# E
5 g, n) ^ C. }- T7 L7 }. j! |
* v& g' c1 N0 {; g9 B& J5 o inline bool IsAsyncFindRunning() 5 t. Q$ z$ J: r: n; L# ^3 [4 B0 i
{
% `' A( V/ G5 v9 V if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: _% K7 `4 ^) g# B2 Q5 _& p* p {# ~0 o$ E9 P7 M0 K9 }( H% @
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );& M) n' h; v" Q3 G A# M3 a
m_bAsyncFindRunning = false;' U! H {8 R% m% o3 v/ C# x
}( q) d5 }6 A1 z' P
MSG msg;
% D# H8 J1 w6 m+ g3 C while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
1 L) |4 a" m: y6 P {3 ~! x* J& d- A, _
TranslateMessage( &msg );8 e5 W F" C2 l3 V
DispatchMessage( &msg );
: u/ f4 \5 b/ c. r }3 P9 H) r+ }+ y
return m_bAsyncFindRunning;
) U3 H3 ?8 Y9 ]/ C }2 K: C! h5 Y: s8 \9 t! o
9 x1 G9 y6 |$ r( m
- i' H7 ~' {; Y; X9 `# L! O' A3 U
TRISTATE m_bUPnPDeviceConnected;
8 C( H! E+ Z B" }) s7 t
3 O$ s3 E- t$ f7 Z. M8 y; _2 k7 s) R
// Implementation4 `- Z4 M/ d/ o$ K
// API functions
& i: g0 P# A2 l& ?& w1 P; a SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
! Z6 t2 Q" L7 [1 B SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);2 R1 {: e9 \: F* J" T
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);1 H" P# B* G2 x' v# M$ J7 B
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);/ P; R: o% y( Y6 h6 P: b0 w" t
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& G; v" G$ T" o6 g
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);. T$ D2 M6 ~& Y+ N
8 s% M; }6 T9 _; o: Z
* ?% X2 C" `' c* G+ q TGetBestInterface m_pfGetBestInterface;
3 K! y) V% C j TGetIpAddrTable m_pfGetIpAddrTable;
+ T3 E" u" q0 Z. {, i# b7 s% } TGetIfEntry m_pfGetIfEntry;
" \, f+ Y9 k/ H* ~' l9 O+ [3 O& c
5 \, s ~5 {9 q- j/ N/ g2 m6 M7 ^) i4 r6 [. z3 @% ~, c" V+ M1 f
static FinderPointer CreateFinderInstance();' ^0 W5 @/ H$ o; _; I& h
struct FindDevice : std::unary_function< DevicePointer, bool ># y0 g3 b# O7 X) ~
{
& G7 E9 _# n# n6 I1 `% x, N. |# _ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}% M+ H' [' n1 d+ M5 C
result_type operator()(argument_type device) const$ b: o& \3 Z0 N, C: X1 `
{
6 a: Y7 T- z7 \4 h8 ]" X# y1 U! f CComBSTR deviceName;
, _' P3 U) c/ K9 f7 u0 a HRESULT hr = device->get_UniqueDeviceName( &deviceName );, O. t* Y+ F% \$ X
: H$ S' C+ Z9 z; E1 x% s0 h7 ]5 p5 V. `# `! s4 ~
if ( FAILED( hr ) )
6 ]% ?6 k% C3 V# R5 E1 { return UPnPMessage( hr ), false;- t3 t" `! R$ e+ o4 G4 f+ U
3 E8 Z+ |! }2 Q' `* J1 m# e
9 j' J1 ]+ G, g0 N1 m: @; ? return wcscmp( deviceName.m_str, m_udn ) == 0;
" S, t/ o. o- U0 k1 B/ A5 o1 H }
0 n/ ?: L% [5 L& J# ]* n# Q CComBSTR m_udn;
. S" @- x& f+ q* q. H/ Y };& \' u0 j$ H1 b% L
/ c0 F, L) B; c/ P void ProcessAsyncFind(CComBSTR bsSearchType);# F& u' `# Y P8 c! P# m
HRESULT GetDeviceServices(DevicePointer pDevice);
" J) f6 m. C. K* Y void StartPortMapping();
& N7 p7 p) ], `- R4 r9 C2 | HRESULT MapPort(const ServicePointer& service);4 @5 {& @' O& V: l) S
void DeleteExistingPortMappings(ServicePointer pService);7 O' f0 G# H+ I3 \/ q7 F( `9 C; `
void CreatePortMappings(ServicePointer pService);- T! c0 L H4 _5 E! v9 k" N/ v
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);+ Y9 B9 G: K+ g# a/ k
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
M9 p$ q, E; C" X" R( B- ` LPCTSTR pszInArgString, CString& strResult);
* _0 K" u9 j( e; q void StopUPnPService();
/ A8 k, U4 ?; h5 s; s# I8 B$ F* W. S* v6 {2 P
' Q! U9 t+ I) H$ [% q, K" j; U // Utility functions
: j+ G) N5 v0 ` M' u% U. D HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
: W, j( E: G' ^5 N; }) s INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);3 z1 f9 W7 H7 ^( o
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# l1 R3 s3 b1 [7 `8 N- w void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);. ?/ d% |+ M' M% a9 u C
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
6 `: m' B/ n* b0 r HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 e) ^+ t4 `# D$ b! Q/ h7 _
CString GetLocalRoutableIP(ServicePointer pService);$ ~* n S1 ]! Q+ r
% G. O( F) [! ~4 l8 Q) l X
8 A; i1 a6 ]$ D+ M9 D// Private members
& U) L! Q1 r" S6 s& ]0 Jprivate:
8 L& e1 Y6 X6 e% R y) K DWORD m_tLastEvent; // When the last event was received?
3 ]8 e+ \$ t9 _7 e/ S& m' O std::vector< DevicePointer > m_pDevices;/ y) ?% U% M0 q0 b4 q
std::vector< ServicePointer > m_pServices;
& y" }8 M) j. j' v8 I FinderPointer m_pDeviceFinder;8 L1 d6 ~6 T+ }
DeviceFinderCallback m_pDeviceFinderCallback;
* P2 ~+ R3 o$ k5 G ServiceCallback m_pServiceCallback;
) {9 Y! z% Z& V1 o+ E0 e) `; N
2 f* ?7 @3 Y" ~$ b+ {9 H9 Q4 c& {! ^5 g: d3 @" P, I
LONG m_nAsyncFindHandle;, O6 k5 x" N0 J# ?0 ~2 P' [. E
bool m_bCOM;
6 ~' j% @% b' w. H5 V2 S3 X U+ y bool m_bPortIsFree;
; l- |/ ~1 S, d* U# g4 `4 r5 h5 X) @) Y CString m_sLocalIP;7 m* [; L6 F1 x) G; w r
CString m_sExternalIP;
, U3 b$ e5 N0 n$ q2 |8 v bool m_bADSL; // Is the device ADSL?
4 {; Y: T }! r! \6 H" y$ ~) m6 { bool m_ADSLFailed; // Did port mapping failed for the ADSL device?% {9 a: F0 Z$ o8 c3 q
bool m_bInited;
8 N4 k* N7 K0 l9 A: Q3 Q8 K. M bool m_bAsyncFindRunning;+ n$ U F: S6 N, |3 Z A% O8 x! C
HMODULE m_hADVAPI32_DLL;
- ~% Q, Y- l7 N) \# _$ n* J HMODULE m_hIPHLPAPI_DLL;
4 n, z- s% w0 c! h1 K bool m_bSecondTry;, ^7 {, l3 C; c: a( _. S* u
bool m_bServiceStartedByEmule;. p: o9 l! g2 c9 j+ f2 Z5 z) v, `5 d
bool m_bDisableWANIPSetup;
- ~; y- Q7 }6 A: s7 V+ j' f3 s: H( ` bool m_bDisableWANPPPSetup;
5 y! B9 y* H% d8 N$ z
0 I) e" L1 ^: _, r( A2 B# q* h4 Z: y: k1 u w7 R7 a; k: `4 q/ S
};6 \6 f/ [ ]/ m3 K0 b: t& ^2 U
1 Z, {8 E0 r, J
- @& f+ |7 j2 r; \; t1 f( u
// DeviceFinder Callback
/ y# e' |7 a' w5 w4 `* @class CDeviceFinderCallback
- Z' X M1 E! J; {2 c8 U! A+ z8 w" s' q : public IUPnPDeviceFinderCallback1 A2 ]+ T/ b; y' u/ m5 r
{
' E1 [3 d6 F1 d4 W! @public:5 M% c9 H5 l; C9 R( V
CDeviceFinderCallback(CUPnPImplWinServ& instance); Y: D: s& S' m) r0 ?
: m_instance( instance )
" w6 U6 Z9 l( S% V" \. p { m_lRefCount = 0; }8 v# U( A& M+ M/ }) e u( _( `
/ k+ O: D& A Z. y! n! t. I1 N4 V+ v! S- |! _& D0 W
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
( m$ r0 { i3 ?' I STDMETHODIMP_(ULONG) AddRef(); x9 b1 {+ C: G* r. ~
STDMETHODIMP_(ULONG) Release();% z+ ^- A- h+ x0 y# H
- L- w: A7 o# P/ ^0 w% B# C8 q, e
/ @0 [9 |7 w$ a/ y3 J// implementation6 B! Y% ]: ~4 f" r8 ?+ D0 U
private: N m9 H. B: |0 t& O- `
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);$ ~: [, I( M; ?
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
* Z* r4 W# U# `# a/ }5 U/ `0 _ HRESULT __stdcall SearchComplete(LONG nFindData);- M; ]3 _4 u7 X, {' N
3 A( G- @1 a/ x y. i1 P4 ?
* M/ s' ]- T7 F( ^! z: j& Q8 aprivate:6 \* `/ X/ Z# L
CUPnPImplWinServ& m_instance;
: a$ D6 ^. @5 @$ z, B7 o, n; @ LONG m_lRefCount;2 @0 J# t, a0 P6 Y
};0 q2 f% b8 S# _. { f
F6 r- k! M: l! k7 p
( l- k3 J! m! q& ^+ x0 n n. l
// Service Callback " I% y& J$ N) H) ^+ K, I
class CServiceCallback
# [. Z$ ?2 u. n( t3 n' K% F : public IUPnPServiceCallback
5 B( b2 u( r/ }6 H1 O* D{+ A! c$ r6 Z3 _" {7 P) T) D- P
public:2 M% W, Q8 g" l. a3 e! f
CServiceCallback(CUPnPImplWinServ& instance)/ ^1 I: y2 X6 w4 T
: m_instance( instance )+ s, L E4 c q( g# {" o
{ m_lRefCount = 0; }$ U7 \0 `( ?& ?, F, x6 }
% z$ s# f& Q. o# ]+ ]
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
E6 ]$ g; Z/ b% L9 U STDMETHODIMP_(ULONG) AddRef();
5 M8 R' [# ^" A B: ?$ ?& { H STDMETHODIMP_(ULONG) Release();. e/ |/ B4 D+ G9 i, H! C
3 H7 V# m* x# T8 h) d- X
8 f# ~; V9 l; A, g// implementation7 u8 ]0 [ I* A8 _: o- l
private:
0 I* e6 D, |/ S1 }6 y0 F; U HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);/ R2 N8 N3 J( G/ z6 w( O+ E9 ^
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
2 `+ ^+ P2 g8 |& f; U) P. ~) O* ` a5 O. v9 z8 \
7 ?" b" H! }; @6 t6 G- t4 a" Cprivate:3 U, }2 e8 d/ F
CUPnPImplWinServ& m_instance;! K7 A8 l" ]0 }6 a; j e4 {
LONG m_lRefCount;
) y/ P, ?8 B- a};
# }4 x' H; k* U9 l( _3 \! |' @7 e
/ w5 M1 b5 L5 x% e: N
/////////////////////////////////////////////////. I; b$ `0 y5 c3 x' E3 D* T
% _! P! p1 J/ g* E
, J; I% {0 k5 @: P: {$ L' a使用时只需要使用抽象类的接口。
|( t( U5 t# A+ Q1 i2 e! _CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
. q; t+ _) [9 [1 FCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.8 a7 T# t* B# Q" d( X5 Q
CUPnPImpl::StopAsyncFind停止设备查找.
; R5 N, b' I0 l" PCUPnPImpl::DeletePorts删除端口映射. |
|