|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
8 z" T, Y% i4 Q2 d3 R' Q
8 _- g1 {; i2 ` z! D: c! [& {) }0 G# _: f# @
///////////////////////////////////////////
* M% v. M, m+ @" x! q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能./ q- s+ h- A* m: j) g; l7 s
2 S" ^6 \' v) |% E! r
$ t1 S4 J( W, J! ]& w! F& q#pragma once
9 Q8 R7 q! p' p6 S#include <exception>
6 q' c! G! w7 e# d2 y/ A6 Z$ C* m- K$ @: v& y0 L7 O+ z) y% Z
9 }9 Y9 w7 R/ R9 D$ ` enum TRISTATE{ h& |( o4 c9 x
TRIS_FALSE,
0 C" x, a; [* A% h# x" G TRIS_UNKNOWN,
; v, S6 }3 ^" A$ m5 Y, T' F TRIS_TRUE
0 S+ a# h- H+ d. ~- J% A};
) r- ` Z2 h e; a
8 B H, q; I5 G+ Q2 A4 L* _- n! c
enum UPNP_IMPLEMENTATION{, r- h' _$ E2 o2 _
UPNP_IMPL_WINDOWSERVICE = 0,6 s! e) _2 j+ g
UPNP_IMPL_MINIUPNPLIB,
. b" F( O- u! d4 L+ B UPNP_IMPL_NONE /*last*/3 T. q7 u0 t# d! [/ d8 q, v3 i% X
};0 K7 Z; i' L! \. I9 F+ o# k
( c6 j8 I/ E+ @+ _$ O' d9 t
7 I: c8 H/ u% @' Y
2 q$ p, w5 i0 S& t
+ Z3 ^" C2 S& O" @/ d2 }! Q* wclass CUPnPImpl
+ g: u* F. G3 A5 W" v+ ^) Y1 G{
3 J6 A1 W" ~) tpublic:
* b( A" [$ U, Q. F CUPnPImpl();! `9 r* {2 t7 [
virtual ~CUPnPImpl();' P* }7 x1 g2 H2 h1 m0 x8 Y
struct UPnPError : std::exception {};
' o; _- [* ]9 R# }3 u# ^2 A% X enum {
, c) m& z' e2 d. T4 | UPNP_OK,' Y2 n! u: P2 S4 q+ |6 T
UPNP_FAILED,& {% a P' C' q
UPNP_TIMEOUT
& \3 m# v& h! t7 G6 j- | };
- Q3 R F2 _3 ~) S3 l
1 V, K5 r& i) r$ y* h( E) i; B) ^3 L" v5 }, r; j3 G7 t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;$ F1 X; q2 f# W2 Y
virtual bool CheckAndRefresh() = 0;
5 e8 B/ R9 N8 m' F virtual void StopAsyncFind() = 0;( t [5 ~* l! S+ ?
virtual void DeletePorts() = 0;; ]/ m1 I6 C ?, v
virtual bool IsReady() = 0;
. D) g, C$ f* A5 i9 G% [ virtual int GetImplementationID() = 0;: H' y$ @( r; N6 P1 @
- i, Y j! ?3 z' D3 m void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping o" e0 y. c/ p9 U
8 }3 O% I$ |& E- j/ R. j- H
2 G3 e+ s8 i5 s4 p0 u
void SetMessageOnResult(HWND hWindow, UINT nMessageID);' T' g% e& m) I+ I# u* D% }
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }) K+ E. V+ c# c- B
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- X% ]- z8 k5 @3 m! B+ h uint16 GetUsedUDPPort() { return m_nUDPPort; }
3 R# U; j; V& g
C7 L: V9 h( Z. U4 X& x+ J6 n; Z$ M7 C2 F) O3 j: w, w
// Implementation, S2 }' P- r( z- b4 k0 z
protected:$ q8 \" p. o6 E% Y! \8 I$ l
volatile TRISTATE m_bUPnPPortsForwarded;$ b: T% C! ]; z/ X6 p0 e/ S
void SendResultMessage();
# w! d+ h& K( x( c0 v; A5 m uint16 m_nUDPPort;
% y4 i/ S0 P* l" y: I, }7 ` uint16 m_nTCPPort;
- D" @* _) u3 \5 { uint16 m_nTCPWebPort;6 b2 {# r C* b0 k. [2 f
bool m_bCheckAndRefresh;/ D0 V) [. A W# G1 l
' h& ?: H, t" o; l2 u
6 d# J2 n- _- h9 L' m! Tprivate:4 B9 c5 X3 m3 J$ Q8 M) e( H" P
HWND m_hResultMessageWindow;
! j8 }2 e& j; u) L& n! t+ t2 w UINT m_nResultMessageID;
% m' H: ^3 H8 |# [3 w2 y
' N1 V q0 |. a
" v& x& U# i/ i2 R5 m# R2 w6 h/ ~};
7 [8 y6 I9 F! Y; p
$ ]# g& r, {' r: ?0 m% Z& x
1 I- {" L; m* \% Q7 \// Dummy Implementation to be used when no other implementation is available5 ?& \+ A. |2 O( ^- |' u" z9 d+ z
class CUPnPImplNone: public CUPnPImpl
, b: i- x# Z( T- {{
5 e$ Q* N" A C& e6 D9 m2 Vpublic:9 A3 |7 O8 ?* `' i( {
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
4 l3 f) U7 H; J( h virtual bool CheckAndRefresh() { return false; }
7 |' q, p% g4 E% j1 a4 M: e: S4 d virtual void StopAsyncFind() { }( }: p9 ~! A0 G/ R. q; N
virtual void DeletePorts() { }
% S" E3 h$ K+ T- ~2 y virtual bool IsReady() { return false; }
' ^9 ^3 p( R2 u9 g virtual int GetImplementationID() { return UPNP_IMPL_NONE; }' {' [- n1 _/ ~% y" l$ H
};2 l3 v! p& x# g; p
7 x$ r" D# @$ b
$ s9 _5 ^+ [: p/ d4 b2 @2 G/////////////////////////////////////
3 C; [ b# w7 Z9 a6 }//下面是使用windows操作系统自带的UPNP功能的子类9 K3 X* d) t1 c' w% V6 L
% R# `- b' f9 o, }8 ]& v' ^2 _3 B. i6 { T5 ~2 _0 \$ I
#pragma once: x t9 W! L/ D- H
#pragma warning( disable: 4355 )
3 X/ `) r6 F+ I3 W' l
: m, ^) Z# \7 W4 Q
5 R" r( j: ?/ V7 I0 c9 A#include "UPnPImpl.h"
# R- M5 J0 j7 d' M- p#include <upnp.h>) @6 D2 k9 J+ c7 g, q8 c8 c
#include <iphlpapi.h>
" L0 ^. }* Z% p' L- u% P#include <comdef.h>1 x1 l/ W$ K' i1 D+ T
#include <winsvc.h>* B( K# X8 h9 s* d% X
% k* c. G, ~; _( T2 k1 _6 u7 H3 g$ g! X
#include <vector>8 Y* g, |0 ^' J% U
#include <exception>' J- a6 x8 O1 R" T- j8 S7 a0 ~
#include <functional>
: I7 [# a) j3 @1 {
- G: p" L8 O; m' ]' W$ L0 P( Y1 R2 q% N+ y. X& [
" d! U$ P& Y, X. p7 w5 N) Q7 ^: B4 \; \; c
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;8 R, r4 i) i! F" F( }
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
, I3 @9 W2 e: Y' G } wtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;# A3 t& I# ^- |, D4 q# R: g5 m8 p7 o
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
G% f9 T$ q9 ]9 l9 R: Rtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;) a- |: d2 b- \" f7 v- f$ ?. g& U
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;; m, j1 v4 D$ W9 j4 _+ y. v
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
6 W! F9 L- @6 n$ y# x$ D( R: \- B$ p+ g7 F3 H
/ ^$ j) t+ X4 R+ ?: Z& Ptypedef DWORD (WINAPI* TGetBestInterface) (
+ o) z/ h7 r# E$ \# h IPAddr dwDestAddr,
/ I Z) y* a9 n' E3 N/ f% p PDWORD pdwBestIfIndex
( {( H1 _. o, F7 x* X. _* O);6 n* k+ L z! [+ J0 ?3 G
# S/ j7 K8 r# f2 K$ C! t
1 e: a. }4 x4 B" Etypedef DWORD (WINAPI* TGetIpAddrTable) (
3 a+ ~6 F% ?, h* R; T! e5 D9 ?" [ PMIB_IPADDRTABLE pIpAddrTable,' x$ v( f7 e8 Z( R1 D8 b1 g
PULONG pdwSize,
$ K" H0 p y, r+ o- } BOOL bOrder
9 q% @% U+ R8 o);
7 [& Q" X) q Q% B
, k) H8 e" h+ H8 U, x R$ M' O5 V# c, y5 M, b1 O* T' s* `
typedef DWORD (WINAPI* TGetIfEntry) (
2 K5 }4 `, b6 W PMIB_IFROW pIfRow
, }7 D3 u$ n+ H& T6 {" p9 @" W* W# i);
9 Z9 `) [6 O; w7 k6 H5 W+ Z/ e. B- O. N. b) _$ `- q# ~( B
6 {) l* R2 I* L
CString translateUPnPResult(HRESULT hr);
+ K# F5 F G+ ^/ U& xHRESULT UPnPMessage(HRESULT hr);& r# Y; Y/ l8 V9 C+ Z/ F& ?9 Z
" ^( q& W: {+ k5 R) n3 D* T, n
+ N8 M- N' q0 E! R3 \, P ^5 xclass CUPnPImplWinServ: public CUPnPImpl
/ E& _- i j4 X2 f. U( S* y" a{2 q5 m+ \* D: m. e8 W- [1 w4 X6 E
friend class CDeviceFinderCallback;
* J; p5 b: z) Z friend class CServiceCallback;& B4 S$ ^- g0 O5 ]; O. C
// Construction- a* [# q) R. t$ `, I4 h! {1 Z: y
public:; t5 H; x3 _$ A
virtual ~CUPnPImplWinServ();
) c* I0 l" K, P# i3 | CUPnPImplWinServ();
! ?- [! n0 M \- ^8 I% c. `( q
k" X9 w! Q4 \; U9 a# v4 u2 I* a" n1 B5 E
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }7 H7 b5 i2 V3 O- F0 {* ]
virtual void StopAsyncFind();1 o1 K. r/ D6 a4 ?7 e
virtual void DeletePorts();* S: a% q' p! z( H U2 J
virtual bool IsReady();
8 z5 n7 m' a/ E8 m! H virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }5 _4 g1 F" V' t8 e, e6 | ^
6 ]7 }- Z, l2 M* r
; v3 @# T4 K; {+ F2 F4 e
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 N# M2 b0 } A8 c/ E1 @ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
1 L" X2 c4 W- c0 V) ?/ r% l virtual bool CheckAndRefresh() { return false; };. r1 E% `0 u. z3 Z
) x/ p$ }8 |6 h4 \0 U7 H6 }, D' o9 ]' {, E! B8 V; V
protected:6 Z% ]2 c" @: U+ j& S
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);: j: r: P1 E' Z+ y
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" ?( X% d$ Y' j void RemoveDevice(CComBSTR bsUDN);
) q8 W- W& d- B) e/ ~. v n0 I bool OnSearchComplete();
, \1 f# }) P7 C; j C void Init();' ~% G/ j( y& f2 r9 e
! x( x! }8 P) ^$ E: y
; a6 F# I# T. C7 q- I
inline bool IsAsyncFindRunning() M5 R$ A( f6 N% Y* B7 w" K
{
7 y" }# ~ L4 G% N5 u2 e% Y4 _2 c if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: D1 E' M+ f% e) R- { {9 o `: _1 Q. g1 C3 E
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 A6 x9 Y) N4 i# T, }6 M" Z
m_bAsyncFindRunning = false;- M/ c% ~) B9 }& ]( y$ v: G
}
& F% X. h. N+ i7 K# L! k MSG msg;' i2 [/ z$ U% B8 v' E8 _% E
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )9 u, e0 K, ~% D R% G
{' y' r' |- M1 T- D
TranslateMessage( &msg );
3 @- Y! o; z+ z1 y9 k1 o$ ` DispatchMessage( &msg );
' `, v* m, h8 Y! d }0 v) l6 _7 C- |- H( g5 U! A
return m_bAsyncFindRunning;. \+ Y7 ~6 j8 s$ J; l& A; K
}
6 c6 ] t$ P2 |: A `- G& L
9 b' H: }0 W3 F
j' U @7 Z" N8 g3 E TRISTATE m_bUPnPDeviceConnected;
* ~: `& F+ Y5 y: l+ {: h. K9 i3 Q, H- n& U7 Y0 |9 w6 e
9 p. {7 Y) I. X z
// Implementation' v2 @0 h% m$ X( [9 J
// API functions
% v) l @& V4 ~" \, b SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
' J8 i/ Q6 W/ Z6 g- l SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);3 w! e$ |" n2 @, z7 d0 }
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 b! }- K% T! U! [* e( ]! h4 j6 [* A! H
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);, t* O; \( R; M& [4 R5 m7 H
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
6 ~# E$ @( Y" Q3 [8 p6 d5 b6 M4 d BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
5 ?$ z& v% a" v" T/ e$ D
+ s8 f D- c$ z& K$ w
2 d/ i' V; P8 p7 o TGetBestInterface m_pfGetBestInterface;
! n& t3 q7 \$ U8 r TGetIpAddrTable m_pfGetIpAddrTable;5 g) w; Z: c+ A3 D; S
TGetIfEntry m_pfGetIfEntry;
. A5 [( z2 ?* M; D& F* Q9 }: W9 V" C
" k; {/ c: D% ^; p1 c% m, U- W
static FinderPointer CreateFinderInstance();) G3 R h1 U3 n! d4 i$ _8 V: e5 h
struct FindDevice : std::unary_function< DevicePointer, bool >
8 b; I7 o0 U# S- r' w- K {# k7 V a# _, S5 T, v* B
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}7 ~6 Y# i( S" L9 K1 q# |3 i
result_type operator()(argument_type device) const9 v0 P# L0 I- y2 _8 {& F* M; t7 ^
{
* X9 y! L, `, d, e4 _2 I# C" c CComBSTR deviceName;
& n! a8 W1 ?( C0 P. g2 k HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- }2 G, J2 S( W
3 D0 s- j( Z+ Y' ]& g( V# S* ~6 C$ y8 g
if ( FAILED( hr ) ) n$ }% }, X0 B5 F
return UPnPMessage( hr ), false;& c% q: l9 T, G2 A6 g
% {: v2 G5 {& x6 A
5 Q; P6 {& M! U& p return wcscmp( deviceName.m_str, m_udn ) == 0;0 @' W1 h" y1 ?4 L7 H3 M
}/ ], u/ o# v2 `* D! [
CComBSTR m_udn;* L3 D7 M5 \" Q. ?5 J+ x/ n
};/ l+ f. D( l4 l. h! z
i. x# f4 Q3 m. k
void ProcessAsyncFind(CComBSTR bsSearchType);4 ^' Z( l! C' ~/ \4 t. J8 s; f
HRESULT GetDeviceServices(DevicePointer pDevice);! d$ b7 n( T4 I/ |( j' s, i# p+ O, p
void StartPortMapping();' \! ]9 |9 M/ _$ M6 E" H* m
HRESULT MapPort(const ServicePointer& service);2 X3 X3 O! `* ^- ?
void DeleteExistingPortMappings(ServicePointer pService);
3 ?. b+ I; r; d" T% M) r$ R. }# A void CreatePortMappings(ServicePointer pService);7 Q3 f- J' s, c
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);" w! p6 ^! Y V" p
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ' R+ l" Z6 S* u
LPCTSTR pszInArgString, CString& strResult);
4 N' Y6 {2 A7 _! v1 V void StopUPnPService();% S4 E' P M8 F3 F, j) T6 H- s
7 w$ T' ]* o6 G5 {
9 F; Y/ x R% |" X. n8 I // Utility functions
: Z9 d5 u* \! U+ F/ J8 Z' i9 K$ `5 S HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
* B2 c1 U, v R& j INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);8 {3 b" |' k! W" L
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
7 }( o( w/ o+ B void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! h$ x( s3 v% j' N" T
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; T# L @: Z% ~( O0 p3 j7 P2 W
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* O. ?& {* y6 T' @; t2 a# s1 I6 p2 g
CString GetLocalRoutableIP(ServicePointer pService);
3 g# G/ f/ B- ]1 a1 S
1 k, ^$ Z1 @4 a. q- O' ^; k* g
9 ? ~9 I3 l& \* }% B ?// Private members
4 p" Q$ ~$ }- i- j- S5 yprivate:
4 v' t5 _3 ~1 z) `( X' D DWORD m_tLastEvent; // When the last event was received? V& X, |+ W ~* d% t G2 ?" C
std::vector< DevicePointer > m_pDevices;7 `1 C. v6 v% ~# ^
std::vector< ServicePointer > m_pServices;/ _* i4 e* J3 y( }9 n: k; |
FinderPointer m_pDeviceFinder;! R3 }2 E& ?* `' Z- ]9 O0 e
DeviceFinderCallback m_pDeviceFinderCallback;
; l: c+ K' y% z8 [6 R! U ServiceCallback m_pServiceCallback;; P3 @9 k4 j1 S
& ~1 p# \" `+ d) |! H" K
$ W) C- {, N) l9 d6 [ [7 s LONG m_nAsyncFindHandle;
0 e' c, t. V! Y' v% t9 C# a9 B- j bool m_bCOM;
1 D/ H3 D. o( Z: a bool m_bPortIsFree;
% V [# U$ ?3 M, b, ^ CString m_sLocalIP;
7 r! g8 \# Z! k$ s; }6 z CString m_sExternalIP;; ~, j( v" U/ s' O/ Q7 `% {" N
bool m_bADSL; // Is the device ADSL?' ~+ L: Q7 b) z! } H5 d2 Q
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
: c) r, d, q% ^: }) Q5 r bool m_bInited;
0 y1 W! Y @) C) l, V7 K; P/ n bool m_bAsyncFindRunning;* ^- O' P' r/ C8 s
HMODULE m_hADVAPI32_DLL;
$ l/ B5 m L( p; ? HMODULE m_hIPHLPAPI_DLL;# s' n# h2 R# S
bool m_bSecondTry;
. F. m! `& U* E4 ~! B bool m_bServiceStartedByEmule;
/ n: b4 b$ M' M3 G bool m_bDisableWANIPSetup;
. g1 R; h) q" i# N9 } A5 o ` bool m_bDisableWANPPPSetup; K' Y6 y4 a4 k# p2 R( ^" V
* A: Q9 X9 |9 |6 V" @, P
# D* g# U4 L% L7 ~4 U3 i};
- F( ]. T: B9 R9 j# B) d/ u
3 m) V+ {5 O) ^- A! R% R, d& q' w, Z- h1 d& W% ]
// DeviceFinder Callback
# l/ f3 T& Z3 b4 O/ W* n5 Qclass CDeviceFinderCallback) F' y) o9 U) J2 _/ `2 T
: public IUPnPDeviceFinderCallback- F% U" r- ~- G. I9 |
{
; I9 x1 | c9 V2 ipublic:4 k% {4 }" c, Z O4 e. l. {) x
CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ Y0 J2 N2 q% P+ e : m_instance( instance )
# G7 B& `7 }# X; z0 h { m_lRefCount = 0; }
; q4 ?7 l: M2 j# m) [6 Q/ y! Y! j, e/ ?# t6 K a- @1 k* s
9 y3 i$ b1 f; i: s1 a: a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);: S1 H( \+ t7 @
STDMETHODIMP_(ULONG) AddRef();' ~* S* _3 X) L5 A$ ~. y# a E! @' z
STDMETHODIMP_(ULONG) Release();
; e8 w7 e7 G- P: n7 N& \& R0 |& v+ n& C8 U6 b Y6 V
- E7 p g* A/ q; Q m, @// implementation
7 s+ P9 x1 `8 b! ]! A* K* N- m; Rprivate:, B9 A9 c4 Y* {7 ?$ {- b- Z
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
3 n9 G+ r' U, P5 h HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
5 w, n; B& A$ G HRESULT __stdcall SearchComplete(LONG nFindData); {2 z P+ E& c2 Q" L( q8 {$ ~/ O5 `0 P
" _7 N+ h0 e) a- y& C) A3 O+ @ N) P; H
private:
3 h: M& ^$ n. Q CUPnPImplWinServ& m_instance;
3 K9 I. X2 A4 G9 @) ~ LONG m_lRefCount;
7 Z; A5 g6 b# l4 h+ K* s3 z};+ w9 B* U% e5 k! N+ C
% T3 d6 q; b- T c" d* ]( S" Z
) I3 H3 C% `! D& g( F3 N// Service Callback 5 W% h& `9 ]+ J& X
class CServiceCallback0 `5 \( H$ _' @4 v) j, x5 R. c+ z4 a
: public IUPnPServiceCallback
+ p. g0 u6 N) c' o2 H' }) }{
# R9 K0 H' H* [3 a* R5 }6 epublic:) S5 q! y2 j! N4 O. X5 B- Z* R
CServiceCallback(CUPnPImplWinServ& instance)
7 K c; N f- m H6 v% F : m_instance( instance )# q) V( { J7 B* g% S7 P
{ m_lRefCount = 0; }) D2 B; v% z8 r" H6 c j- `
5 t2 N- C, Y/ O
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; f2 m! B3 h9 h3 n+ K* D# E
STDMETHODIMP_(ULONG) AddRef();
9 m+ t7 J7 x# y' z. z STDMETHODIMP_(ULONG) Release();7 E: c- i2 K- f
n6 L/ {* r( l
9 v% h" J0 E5 C. M// implementation, M" Z# h0 t- ]7 I8 L
private:: M2 {/ p* I; g G' P
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
0 v. e& S% J \% p3 K3 p8 A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);! N1 k& C3 K( Z
" M: F# u' d1 P- W
- j- H* r5 g( i! ^& S$ S
private:4 F: q0 H3 P5 d6 F1 l2 N9 E" K
CUPnPImplWinServ& m_instance;
. d# E3 I) D. N7 g LONG m_lRefCount;# D8 ~9 X) @ D& h0 A
};
; U/ _+ ~1 z% j! |+ ~- F/ U5 _5 N, J$ ?+ ~9 Y
5 ~$ x$ d7 }$ Q, }. _" i$ i
/////////////////////////////////////////////////
0 }9 A. W/ X: L8 u4 @5 `3 Q9 y& l
! b; p2 M( c' Z A( X. v, H' d j5 b- @" X3 s# `* @; i
使用时只需要使用抽象类的接口。: M ^9 I, s9 X
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
, n% N! b1 m; J9 s4 rCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
5 v+ U: o8 q' z1 `CUPnPImpl::StopAsyncFind停止设备查找.2 F7 \( S# {7 a! W4 M
CUPnPImpl::DeletePorts删除端口映射. |
|