|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' G) g! d' ~8 X3 n# b7 }+ [! N
: Z" Y& g; A2 G. Y* f7 p, [ r7 Z }7 a
///////////////////////////////////////////& C+ B& J' E" G2 `' U7 I6 F
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
& G- ~4 i( v/ \$ h; d _5 D% d( D+ C6 j6 f
* ~7 U8 }* M3 J, Z, x2 k. t
#pragma once
3 S9 u3 c6 A0 d#include <exception>
9 |) K& o2 Z+ k
3 `/ y7 H; \# Z3 N6 ~
+ @* T; C, T5 j* Y enum TRISTATE{ k: l4 N+ u4 |( L
TRIS_FALSE,
9 c- t8 \# @" b( }7 Z TRIS_UNKNOWN,
& T6 J( h4 t* l TRIS_TRUE- b0 L2 n" I/ v1 P: d5 D* y' U, z
};
1 b$ ]7 ~3 e& c
0 B4 h. f! a) S& ~; A8 ]
: R0 ?) q9 v# Z8 y0 qenum UPNP_IMPLEMENTATION{
* T _: `; \: R0 Y) j* \/ } UPNP_IMPL_WINDOWSERVICE = 0,, z3 P2 u% [% Z* s/ x0 J, n
UPNP_IMPL_MINIUPNPLIB,- E+ G- U5 p" q" v2 v. y
UPNP_IMPL_NONE /*last*/. E8 m$ v$ \& F8 z; P" _2 ]
};0 g( c2 O4 s& ?* p
' n$ v# W0 Y. c; `" x# Q: v
; m v2 Y' I" p" }: k- ]/ R" C
5 x5 {. B+ t( ~! f! P$ ?& `) i: I6 O! |
class CUPnPImpl P# t9 G8 K/ U0 l4 A: K0 V1 {
{
$ H d; x3 ?- k zpublic:
& M! M B# F, Z$ W CUPnPImpl();- z% J, V. z% M. Z7 x# }& R
virtual ~CUPnPImpl();# @. O) P. C2 w$ Q4 t% @+ V* A& ?, H
struct UPnPError : std::exception {};
: e0 `- P7 ]! S enum {
/ m- u$ ?, {, q% d UPNP_OK,, `% P' D. g5 U
UPNP_FAILED,; G8 w1 X( _& O) v3 A% Y! Z# b
UPNP_TIMEOUT2 Y1 I7 R' }5 B
};
& X: {3 m& s9 D% j0 ^% X& R e+ W: ?* |3 _ j3 `
8 Q' q; k" t) d$ {- }1 n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
* A5 z; ~1 a7 X. _ virtual bool CheckAndRefresh() = 0;. B' A: `% |, d9 v
virtual void StopAsyncFind() = 0;
1 q" ?' {! c5 w virtual void DeletePorts() = 0;
3 y6 F+ k4 F+ Y) _- b4 L5 h0 T virtual bool IsReady() = 0;
4 [' o# s2 S! D0 f. K virtual int GetImplementationID() = 0;5 t& ^4 B2 @2 D
: f) h! j7 u# s3 O void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: z- _- O& F* R, e, \0 x# i# E- K1 R$ K; S2 J! z/ e4 b- |' \& t. o
( T$ y$ Z6 S! h
void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 @: [6 i! S# D
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }" Z* q- y6 `+ [! J/ [2 X" m
uint16 GetUsedTCPPort() { return m_nTCPPort; }
) G. {0 D- H9 w5 G uint16 GetUsedUDPPort() { return m_nUDPPort; } ; x: R0 l8 T: @4 i/ U
4 t* i6 T& p/ ^
8 Z4 t- O) l( @// Implementation( y& t1 v+ b" w& {6 n. Y
protected:
, q4 q4 ~: e4 v1 H) C volatile TRISTATE m_bUPnPPortsForwarded;
/ j* n/ `! b- U void SendResultMessage();2 K+ `0 ]6 c) J8 u4 s
uint16 m_nUDPPort;# V% u7 _: ?$ c V, z6 d
uint16 m_nTCPPort;
+ }6 R' f* [; ~/ r8 z. h uint16 m_nTCPWebPort;
( X. A% {% R! d3 O# K bool m_bCheckAndRefresh;$ m* Z' O. V, ?! m3 D0 {( Y
2 M. R/ [$ N+ `9 w0 W) x7 h0 ]6 y5 G4 d& U
private:7 n5 J9 U. a* J* F) W
HWND m_hResultMessageWindow;) p8 j6 j3 |4 Q& y2 a3 U8 X
UINT m_nResultMessageID;
$ b, P) ?; c U ^9 ` K' s' D% ^2 R1 z6 V
3 _- B/ Q$ G/ b5 Z/ v3 A
};' ]$ ~# w* ^% x8 c n. F# `
& L6 V$ B9 X+ x p+ Y. O1 L* j
. V8 s0 {6 b- T0 P' n4 J* b
// Dummy Implementation to be used when no other implementation is available
8 H$ |7 V `5 x0 Kclass CUPnPImplNone: public CUPnPImpl
) ~8 f* N4 F7 x) ^8 _{' B8 G. q! U. o
public:
( l- w& e) x: W0 a virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
" V+ p' ?8 R. E( q& P4 V$ Q virtual bool CheckAndRefresh() { return false; }6 U: x& i" Y9 s0 Y' _8 g' O) B3 c
virtual void StopAsyncFind() { }
. \7 ?3 `( Z$ T9 z virtual void DeletePorts() { }
+ N) M: b' ?( L C5 ~. q, V0 ]0 I virtual bool IsReady() { return false; }- R d3 X. t. ?" { \6 v
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
1 E5 g0 A" v* I. f ^9 ~$ ^+ A# F};1 {& b5 T. u0 } t* r: K, ]3 k
8 U9 c, E# K( p' h* O
0 W; C; v+ ~4 r- F/////////////////////////////////////! M! N2 L/ v8 c) H8 d
//下面是使用windows操作系统自带的UPNP功能的子类4 I) O+ h* ~) \) c
, ?: |& N9 T; U4 s- e/ C5 [
, c8 h( y" a: y4 s#pragma once
) Z/ h* P3 K3 g#pragma warning( disable: 4355 )
/ y8 }$ K$ F: w) }( V/ w7 u; t5 P8 v7 y
' {8 v- X& F' N7 J* ^9 `) o#include "UPnPImpl.h"
% f" {; S1 I9 i1 F! g2 X# U#include <upnp.h>
. t1 Z6 c7 V1 U8 r#include <iphlpapi.h>
8 g' z: I/ R5 @#include <comdef.h>
9 s, k- {- T( s _4 C#include <winsvc.h>
" C6 z! Z; J% |) `
* M* y# U+ x& [$ j" ~5 G. {6 l# u$ ^# Z5 Z- t/ ^
#include <vector>) n4 O. W; ?: x" g; {* z
#include <exception>
; o; A5 Q P! T#include <functional>6 C4 j6 X' J# x3 h: V& o
9 Y& l- v( q* R$ m
2 j0 B9 h9 c N% F7 ?' U; ]: v6 `& ~6 Q8 d+ _7 B
4 o: u. _1 N6 J4 E. v' |typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
9 J! m0 q! f: `: i% n. z6 P% H* \typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; ]* G7 s* E9 w1 m$ `! c5 n
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ A6 M/ ^( |' M* j0 g* htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
4 D& x; N/ C& b8 a. u( V7 Ytypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
* D; b+ ~6 N* D& c* s6 @typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* M0 G" d3 y2 d& X: }% ?typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;, |7 W- M' y* d0 K9 R+ g! z! Y
' i, x) C5 {$ g4 O3 v! b2 \
- O$ K+ { q# ]typedef DWORD (WINAPI* TGetBestInterface) (
$ h9 V( i* N+ z IPAddr dwDestAddr,
* \! z# m8 |* ~3 k! Q2 |6 c4 Z PDWORD pdwBestIfIndex! |* U" |8 D, v
);
$ U# S) J8 ^( f$ e
) S6 V( g7 k5 M; L" n& C6 E
4 m1 V4 i! H. d3 F6 r6 V8 ttypedef DWORD (WINAPI* TGetIpAddrTable) ( `' |2 _* _' E+ i- o
PMIB_IPADDRTABLE pIpAddrTable,
5 ]8 i4 ~+ I. ^; O% p. G, Y PULONG pdwSize,
, _1 E. c3 M0 L5 D- Y$ {; H BOOL bOrder
Q$ @" k, u& [0 O$ Y);
0 J& P6 J. Y5 U$ x# w2 @+ s: w$ s' |) X
. f# _ ?* O4 o1 c& z$ N2 i& a. Ktypedef DWORD (WINAPI* TGetIfEntry) (
; a3 ^8 w, f5 f+ k" r PMIB_IFROW pIfRow
1 p! [6 F3 v% l0 ]/ g);! u. ?- u7 J2 I/ z( U
9 k: x7 z) \0 Y2 Y" U, y& s$ A+ [" n; ]# W
CString translateUPnPResult(HRESULT hr);
" T) B K) y3 Y5 h, t! a0 LHRESULT UPnPMessage(HRESULT hr);
# n& i; T* X: R, E2 V7 G6 ?
! a: n1 i/ F' ]* d
; u' S0 n. Y. L4 D1 [class CUPnPImplWinServ: public CUPnPImpl6 @) d, {! S2 u0 K$ k/ o: t
{
; U, T4 e4 s7 }; @" K4 D" a friend class CDeviceFinderCallback;
3 `- V6 `- b, }* O friend class CServiceCallback;8 c& n( L: o- C3 K: U
// Construction
' j5 R% v% l, P _1 Gpublic:' d; V: ]. q" c
virtual ~CUPnPImplWinServ();4 J. \# c# f6 A& _4 d6 C
CUPnPImplWinServ();$ M4 I( G; l% R3 X
! N: x% F5 ^9 f) f+ l- m
2 z- g6 P: n/ ^: |- z. r virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
, W/ q7 G2 |$ P( Y6 x: p virtual void StopAsyncFind();
$ O5 v- U& v% w$ ^; X virtual void DeletePorts();
5 _5 u2 s. b R ^: L# h virtual bool IsReady();4 `' H$ l" Z" D# V% j
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
8 S' Z5 S, l5 J9 T! \: {& o o) a+ Z9 \
0 {0 S) ], N" n, W+ Q4 i // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)+ q, L* K% u0 g, W, ~* }4 u1 h
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 ^- `, f8 S: G virtual bool CheckAndRefresh() { return false; };
8 J8 p/ c# v V' t0 E1 e
% S& ~9 \8 ~- p8 \5 A- ]- ?$ E( d# T' k9 `, x' ~
protected:3 K3 z+ H8 ]7 D0 U* A
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
8 _" R# u: I# ^. }' |8 B void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
! O% z( [# ]9 \7 B4 w, p void RemoveDevice(CComBSTR bsUDN);
. e% ^- b( n1 ~) E bool OnSearchComplete();
7 I8 M: s% j [9 H& X _1 g void Init();
% I9 e; v. y7 G3 f6 i
) ~3 Z- `! s$ }( g2 |1 \0 t# ?: V; A e: U' U: x9 q( W
inline bool IsAsyncFindRunning()
4 ?! V5 M( o* z4 H2 a {! J- d, a) |: c3 B# b7 {
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
" Q, t" r( J" V# n8 F7 C2 k {
. L3 e; F8 A2 K4 A6 ]; E m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );. [( S6 _* x) t1 c8 p! x8 Z3 b
m_bAsyncFindRunning = false;
" j2 O9 H$ j1 b# U$ C- V }+ i+ J$ P0 d5 v
MSG msg;
& S; d1 \/ J& M4 M4 H! m. H while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" F' M$ D( L6 {8 C1 J9 q {: u( }5 i: z9 i
TranslateMessage( &msg );% t* ?8 t$ T# c( B% E _2 y
DispatchMessage( &msg );# w2 o7 {$ f5 g- @
}; `% `/ `8 r2 r% ]4 n* o/ {4 _
return m_bAsyncFindRunning;: c E% R+ v$ {/ Y0 {1 z; G
}
" I3 z7 c- B8 F1 i3 C# M; |1 |$ j/ n9 V4 _) @# {0 l
6 ~- O7 N$ H' X' y2 k
TRISTATE m_bUPnPDeviceConnected;
, Q1 `$ n0 }& M) D
1 n& e4 f3 i* w8 W% X$ J+ [8 [" H' G
// Implementation: j" P$ c. k4 s
// API functions
1 @: G8 S+ W; }; O) J SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' e5 J3 J8 ^4 ]* E9 F: c; T3 O
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);- {' u2 z( f5 r, b8 m
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 }8 @/ ]2 p9 o- M/ f" Y# R BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% ~; ^" H; M7 D' K
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
! p" {% _3 R! o0 g/ q BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);5 `8 L5 ~: e9 Y
3 s6 D5 s5 t: m7 R; r, n
( o# K- r7 m6 u( b TGetBestInterface m_pfGetBestInterface;
( Y( ] ?1 F3 J/ ~$ }# w# a, g; F TGetIpAddrTable m_pfGetIpAddrTable;
+ n$ r7 {0 v! L/ P; U( y5 I& B& |; R TGetIfEntry m_pfGetIfEntry;
0 q j% ?5 I, U0 W5 p9 ?! V8 R, x- u( ^/ V ~7 M
9 t0 c! s: S7 L9 m/ U% u# G' }
static FinderPointer CreateFinderInstance();
% @+ O9 T$ ~4 O- q struct FindDevice : std::unary_function< DevicePointer, bool >
" q; v( B/ f& h0 f/ V/ ]3 }7 O {' @$ c* i$ Y# s8 f" ?! {* n
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}$ T# p# K$ x- U" }* ~: Y
result_type operator()(argument_type device) const
9 b: P3 {' w8 r) @ {& ?2 N5 ~! x1 u$ n7 q
CComBSTR deviceName;' J$ k$ X. r5 \* U# d/ ~) f
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' t5 d& y! ^0 E+ g" X
3 N9 m7 y( B9 _: M- P, z, D' ]( p% _2 H4 x: A F' b: [: y
if ( FAILED( hr ) )7 U( ?: D# m! P
return UPnPMessage( hr ), false;
3 D6 \% B8 l$ o$ e* q K+ g, h/ _
/ F& y7 G7 e; ?+ M8 Q' k3 S
return wcscmp( deviceName.m_str, m_udn ) == 0;$ \* C1 ?+ t; ^0 p; s
}) E: j& g7 t: Q1 L: o
CComBSTR m_udn;6 B# S8 P. }: p$ U* }
};
+ i! z9 |" S$ l# k
5 Q$ _2 |% r, G2 a* h; C$ ] void ProcessAsyncFind(CComBSTR bsSearchType);% F# d- V# n! {
HRESULT GetDeviceServices(DevicePointer pDevice);. N: I4 {3 k8 r9 Z3 K7 s
void StartPortMapping();( ?- @0 v9 M$ S, d
HRESULT MapPort(const ServicePointer& service);, R2 V U6 c$ s5 W
void DeleteExistingPortMappings(ServicePointer pService);
6 X: c" J" O3 j. X/ O. _" C* O, D void CreatePortMappings(ServicePointer pService);# k: D0 k1 K: g) L
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
$ ~% w- ?0 _6 R' Y HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ; F( p. O$ x c& \1 c1 s3 N
LPCTSTR pszInArgString, CString& strResult);
" S1 F, H6 H8 I8 R, F' O void StopUPnPService();- D0 {1 E5 j* M: x
; |3 Q' w4 m8 h2 t/ X
5 ?9 b8 i" H3 j! f // Utility functions( L! O5 R4 u: ]! P9 V
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ y% i3 g9 w+ ]9 |+ s5 G) ^ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);# W- a, R, O6 z' S; w' L* v
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
1 B. o+ M9 A+ ]( O C void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 c0 a. j: |) G5 i: S2 k& X
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
4 d. J( h6 f/ h3 F HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ X0 k: S, r. K1 W7 k
CString GetLocalRoutableIP(ServicePointer pService);; y9 E3 a. ]1 p$ A* ^3 \9 k
( K7 X0 r5 I( A" F+ m7 u( E7 f* l0 A
: ~2 i! m* g: X- U/ k; V( Y// Private members
4 ~& D; w t; Hprivate:
8 L6 h i6 i* G/ R9 { DWORD m_tLastEvent; // When the last event was received?
/ n# P5 L1 s, z8 a d. ?4 Y% a std::vector< DevicePointer > m_pDevices;9 Z6 H2 I: j" G( s3 g
std::vector< ServicePointer > m_pServices;
" u0 E5 Z7 ?0 n FinderPointer m_pDeviceFinder;0 F2 l# o+ n0 w2 s# }
DeviceFinderCallback m_pDeviceFinderCallback;3 M1 h6 A+ g" l; x, p
ServiceCallback m_pServiceCallback;
8 p6 m. j9 c) e' G* Z
! e$ e3 \ h; t% R9 U. I
$ r. \. z5 H5 l# W" E LONG m_nAsyncFindHandle;. G1 F1 S: B% Y7 k. D: ^ P( |
bool m_bCOM;
t6 k9 `0 w$ t2 t8 P, K bool m_bPortIsFree;& _5 i0 ^# ^4 c: \
CString m_sLocalIP;
9 [5 T1 [ ~ s, f CString m_sExternalIP;
* o% j. b$ |0 p v: @ bool m_bADSL; // Is the device ADSL?, F+ {2 ?& z. T( E7 o2 W8 V& q
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
: Z' P4 v6 F- t0 T' L bool m_bInited; G- j$ C n( g! x, }$ o4 M
bool m_bAsyncFindRunning;4 l1 f6 C0 i c, O
HMODULE m_hADVAPI32_DLL;
+ Z6 b' j# D' a# O HMODULE m_hIPHLPAPI_DLL;# H2 \+ D# Y4 l( O# ~) l- e* X
bool m_bSecondTry;
' O( {) Z: G6 j: H bool m_bServiceStartedByEmule;
4 g7 f I$ U9 Q% a* |! M) r7 d bool m_bDisableWANIPSetup;
* |2 s. k$ |: K( W' w# { bool m_bDisableWANPPPSetup;* c( j: F4 l1 h/ v4 y$ i- _* H
4 u! S* _/ q2 e: d8 V
( f5 s! k: z$ b2 I};
; y% m* J! z0 R4 l' t" ?4 x- D
2 f- S6 q; V9 \, H
9 J7 m- I8 ^2 ]// DeviceFinder Callback% W6 p/ A6 ~: \3 d
class CDeviceFinderCallback5 z3 A% m+ C, \1 ?& {2 K! |
: public IUPnPDeviceFinderCallback
2 T" r, b- }7 ^$ x* n" @{
5 h0 Z9 u" f" y& }# b7 Epublic:8 ^. T" }5 [- h/ G- G1 y( P( i: z
CDeviceFinderCallback(CUPnPImplWinServ& instance)
! i2 `& i* m+ a+ H W& b : m_instance( instance )
& A0 k' T" h$ ?. S# C { m_lRefCount = 0; }
0 K) K7 f6 K# b% R& Q6 {; Z+ k3 M) \, ? i( {2 p, B0 f' O
8 W @ G" W1 h& v9 X STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% p$ O: t& l* ]( x0 b
STDMETHODIMP_(ULONG) AddRef();
5 F7 F7 Y! {1 }/ D/ m. L9 _ STDMETHODIMP_(ULONG) Release();& e. @/ Y, v% c6 i
6 Q$ _# J3 P; f& g" b4 _) h+ P
+ s& W3 r1 e9 Y2 }8 v8 Q/ p# M
// implementation! Z$ W3 Z. ^ l0 T1 o
private:+ T, t$ F e3 c5 G% d
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);/ \8 ~# W, o" |
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);# y: E+ w2 g! S- e
HRESULT __stdcall SearchComplete(LONG nFindData);
; C u" Y$ x4 H
# `2 g& A" p$ j3 M# E7 Q/ U! Z# w2 w0 R1 |9 [. s" S% J7 \' c/ F
private:
# H8 }" k' C# o CUPnPImplWinServ& m_instance;
b5 R2 _$ m c! R+ M LONG m_lRefCount;
7 q7 l2 j! |8 Q9 S) R d* r% m+ S};
, f' W6 L2 k# z1 Y% D- V
; T; K4 \ N5 C2 b' i& V* `. N& v+ \! r) M
// Service Callback
0 q8 [2 o8 x) j0 H; {4 ^; fclass CServiceCallback
: f% \. Y. X3 @3 h : public IUPnPServiceCallback* D" |: q* D0 E; q$ s' }, x" s
{
, T: s) L+ D h3 Cpublic:
4 G% k: J6 x2 k- z0 \ CServiceCallback(CUPnPImplWinServ& instance)9 p; P0 G7 N6 M M7 \% X1 D7 x# V8 w
: m_instance( instance )
' j x+ a: I) {) Q { m_lRefCount = 0; }
& ?: P8 l* G3 k& J7 k q" E
1 F$ I( O7 r M+ W! k$ w! D STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' h; n0 k! [& N, k& t1 \
STDMETHODIMP_(ULONG) AddRef();
! q; z4 `% f9 v. @6 O STDMETHODIMP_(ULONG) Release();
$ b6 I" V ]3 Q2 H
+ p r9 q. V$ m
0 q2 B/ X* i& }$ q! ]// implementation
# n' `- z2 L4 v3 h# C. eprivate:
8 y- ?4 w9 }2 K2 e) e' e HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);1 t$ \. f! |" @7 ]% M0 Y2 ?$ _
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' \2 E1 p: F; L% Y, O
% d5 O1 W1 ]' n6 I
2 j+ s2 Z# j7 g- ]( }1 Kprivate:% g4 N7 `( I6 H& `2 ~
CUPnPImplWinServ& m_instance;4 ?$ G; }% P5 a
LONG m_lRefCount;/ ~% s1 x( T$ A1 }+ ?
};$ T% E! g) r s; A2 g3 j# g4 A
8 | [ B- d2 e( ~% K7 L7 N) } t. @6 }% }9 b7 J( M! u. m
/////////////////////////////////////////////////
" p* O7 d& r9 P7 }% G+ p# J+ Y: U# M; {/ G# z) \/ ~6 p
) i. l! U! o7 P- B: R- ^使用时只需要使用抽象类的接口。2 P+ s$ O7 ?: a9 O
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.0 k; w4 k- j `$ o! N$ k; w) B1 s* ^
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! V& v, }% }! D1 S. l; l o1 i
CUPnPImpl::StopAsyncFind停止设备查找.
# u1 h% W1 N4 F. D/ M A% z: |CUPnPImpl::DeletePorts删除端口映射. |
|