|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: i' J0 N& ]% Y; j! q9 }2 o3 }7 O) ~" C' J* k+ `' v, ^
l9 J/ H* r7 E///////////////////////////////////////////5 l; [# d5 v5 l* Y. P
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.7 U; n3 K- i0 M. l& f# ~4 ]
! V) n! _ o$ }3 y
G+ W5 T" Q, I#pragma once2 W( \8 _6 J! I
#include <exception>2 d7 r# w: @1 G+ p
' m7 r X& p: v4 H+ y
3 F9 ~( Y# p- Z! d1 N! p! d& ~
enum TRISTATE{! m0 v. a- M/ L
TRIS_FALSE,
4 L$ o2 U6 c B TRIS_UNKNOWN,
/ ]7 p6 B& ]# r$ m TRIS_TRUE2 S: u1 V) m; m4 q
};8 s# Z+ a% G8 w, T0 f# j$ J: O
; T* w, H1 O2 i$ q* O `
& h5 w: A: y t7 x4 B9 _enum UPNP_IMPLEMENTATION{
6 G' l+ S/ ~/ N q3 J' `& ]/ `) ]9 ~ UPNP_IMPL_WINDOWSERVICE = 0,
( i Z: b1 p+ H9 v2 p8 N UPNP_IMPL_MINIUPNPLIB,
& u$ @5 X( m8 `, N6 |4 m UPNP_IMPL_NONE /*last*/; q0 ~3 P' y( g, G8 G, H w ?
};
/ ^' N1 Y- M, l Y+ T
6 {9 N' B8 Y, X h$ n; p2 ?7 ]! E* n) K$ Z
6 r, N ^' P: P4 P; V: k+ f1 P: ]" B
, E/ r& n! J" [+ g' j( |class CUPnPImpl
- c) ^( f, B5 E6 z7 P; Y3 W F{
6 P9 r- C3 Y# X6 S5 K# ipublic:
/ J! r+ I8 W { CUPnPImpl();
# ~/ z8 ]! V3 ~$ P) n4 g8 ] virtual ~CUPnPImpl();1 y7 y- d6 K4 E" g; z
struct UPnPError : std::exception {};6 [3 F+ m3 P' Q! w: c* V- h; s7 [6 L
enum {( x5 A& e+ W3 N* i: `5 M
UPNP_OK,3 [* }: l I* H M8 ?
UPNP_FAILED,
' L# _/ q8 Z- G UPNP_TIMEOUT
2 r4 N) c! F3 d" i! k- X ?9 S }; X9 @; u% [- K3 o
* N, t# Y. u+ c, R3 w
0 H: O7 `- x2 e virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
' }5 R. t7 a( v4 D5 b, W virtual bool CheckAndRefresh() = 0;
& r7 X& e0 X4 [' e, t) s virtual void StopAsyncFind() = 0;
) x+ e# k9 P4 A virtual void DeletePorts() = 0;7 t: z7 e. `7 f
virtual bool IsReady() = 0;! w: q; ~. ^& B' B7 p6 W' B
virtual int GetImplementationID() = 0;: ^4 N/ D1 F1 U4 m! I) n
1 X: w5 v) d; m& ~ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping. n7 C) W. ~2 w& A& Y' }( i7 r
- h! K$ c: o1 h
4 U6 p. k! k/ |7 @4 G; g
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
+ h( t) T' J& L4 S TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }5 ^. [! z: f# \( L3 j2 U) P
uint16 GetUsedTCPPort() { return m_nTCPPort; }
1 v) \8 F# N7 `9 v0 [; T uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 }8 K0 [6 O2 Y3 L3 Q
* o) U: r+ k3 l: o+ U" m6 y) U* @# j5 ^$ Z5 \, K* I& b
// Implementation
& W# a# E+ H! m! K$ _protected:
6 _. y8 `% ?: D volatile TRISTATE m_bUPnPPortsForwarded;) a# p% H$ i/ o: C* L! E! B
void SendResultMessage();
* |; P, D9 E' z8 r; E' S$ U' { uint16 m_nUDPPort;" a- T+ c# A. Q! Q6 V7 b/ X
uint16 m_nTCPPort;
4 L a% ^# t! T, ^" {6 f uint16 m_nTCPWebPort;) _3 u& q& e$ k
bool m_bCheckAndRefresh;
! H: J* j- ?3 O1 c1 M/ i: G# T( u! t* f3 U5 u& a% c S
0 y% y! N- e5 i+ |. {$ n0 pprivate:* s9 W% m. M/ J ~0 X* k' |
HWND m_hResultMessageWindow;7 N' `* G" {5 E# @: o
UINT m_nResultMessageID;1 a8 x' h* b; y; W" T; k8 P
; X) a1 L4 r$ ]6 {- D x1 }0 _* G9 F* e8 \. M: F" m/ ~
};
" U, x( D1 Y. _7 V- M4 m8 }- v0 f$ N/ G6 o9 {' J" e
. y% z# M, @: ?8 q+ w% U, j" }5 j9 H
// Dummy Implementation to be used when no other implementation is available7 s5 d# E5 J% d- q4 y
class CUPnPImplNone: public CUPnPImpl
8 t1 p& P, `! I, B' E{
2 a9 ]( ~& j" G! G6 zpublic:
: z9 P. { O% E8 E7 r! q+ X" S# x virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }5 N0 X8 H* ] C( h) {
virtual bool CheckAndRefresh() { return false; }
6 _% L! o0 _! i/ W, M N virtual void StopAsyncFind() { }
@0 w0 q, e* _ virtual void DeletePorts() { }
+ A( h+ x6 B# e8 U/ Q virtual bool IsReady() { return false; }
1 i0 ]' q' g, B virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
Z f: a% x T; b};' K. h. D1 C4 q7 n
* u/ I9 C, b7 K, [9 R& W
- F# S4 j9 @6 F; p/////////////////////////////////////8 Q: n/ j5 H2 c: X9 w
//下面是使用windows操作系统自带的UPNP功能的子类. ]2 U. ] h, c0 Z
) N+ u# m! b6 V0 `' y+ y5 X3 d$ e
#pragma once
. G( N% l( K2 v0 Y7 c#pragma warning( disable: 4355 )6 m- L D n0 e9 i8 P, n3 B' S
3 P& X! M1 ?" }2 h2 }+ J3 h' J+ ^/ j% @" q
#include "UPnPImpl.h"
1 z: L, s/ X4 {$ H#include <upnp.h>& v" p1 s+ I, l% z( K* e8 I
#include <iphlpapi.h>* W# u" l; m: r; F. Y
#include <comdef.h> B" ]$ l* I" Q6 r
#include <winsvc.h>6 Z7 }! P! D( e2 F
2 S9 b! C# J1 j" o7 g) `( g% x
2 F! v( L( U9 `9 s#include <vector>+ e" [8 z6 b' K
#include <exception>
6 I8 ?: O- D" P7 L#include <functional>
4 h0 c, P0 q9 @7 C% _6 @. N" F! [2 N$ L3 n: S
4 V( m/ d, M: l) E
: p- E! q5 L! `# h" Z2 U+ ?$ `2 z7 ^3 p
% d1 f/ V5 K9 Q" Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
5 A, @$ _0 q$ f( R- J& ztypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;" J% U8 U9 Y3 [& Y/ @; T. I
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;5 c! X3 r: X; b1 U
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;% [7 c" V! t& {% I, q6 d3 E4 P" i
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;! L0 d1 C! C# O
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;5 n R- \. q% q( s* b2 w7 ~1 E
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
, a% x1 O2 l1 [* V- W. N! d/ A1 S* E9 P
}) k5 f+ C; Y& J6 otypedef DWORD (WINAPI* TGetBestInterface) (4 ?0 i% s! ?/ R& N- r
IPAddr dwDestAddr,9 D+ k7 u! c6 `. h% c8 P2 X, A
PDWORD pdwBestIfIndex
/ r) A/ W# Q$ _9 `' E! ?);
9 z1 I2 C% ]; T2 q
, k$ a2 G) ~/ G/ X* S# E) g
: c0 e9 }. E/ e" `# v# Mtypedef DWORD (WINAPI* TGetIpAddrTable) (
7 `3 o" s8 E& z* [ PMIB_IPADDRTABLE pIpAddrTable,
9 y4 F$ W5 W, c; X# O PULONG pdwSize,
6 T: q7 {9 K# w; N. f- \/ D" G BOOL bOrder
5 u% _( Q9 z4 i; `( H);& L$ Y |! J. D" e, i
' p; i6 V* P0 A8 e/ F9 k) b2 u2 D( {; b/ o2 n
typedef DWORD (WINAPI* TGetIfEntry) (/ U P$ G% g; e, w
PMIB_IFROW pIfRow5 ?' U, j4 J! q
);$ h0 P' R( A5 ~- G
( o x2 Y- j5 Z6 X1 T- }4 V8 A
2 r* x. }; j; z# S2 ~' w: x Z1 L
CString translateUPnPResult(HRESULT hr);4 s& r3 M `) T
HRESULT UPnPMessage(HRESULT hr);* X# D) Z( o% R+ E
3 z3 }( V4 {, ?# P% A3 V
5 t7 }7 a. s$ `class CUPnPImplWinServ: public CUPnPImpl% s" ^* i2 C2 P
{
{5 L5 ]( r" O+ A- j friend class CDeviceFinderCallback;
2 {+ z" W: w4 Q friend class CServiceCallback;
0 C J1 o E% h6 ~+ N ^, o// Construction1 _. N1 B; S# I) ?2 j
public: l& X% j0 u0 n6 }" Q7 S+ [
virtual ~CUPnPImplWinServ();% y+ t; z$ W8 o4 \
CUPnPImplWinServ();
4 r/ b2 l4 K9 V) y' `. y& p# W$ z$ y& {4 N/ N
4 U; E5 I8 E; l0 {6 o
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; W N1 H+ l( Z- ~4 V; k m: ^ virtual void StopAsyncFind();
3 `* {+ f% E' g+ D2 `% w8 P4 T4 N virtual void DeletePorts();
" L, Y6 b) w' n9 {7 } virtual bool IsReady();
7 h+ ^) r3 z( m! i virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
! T. f6 H7 s% l9 s) `% D4 |4 W$ I& n- n+ U' }2 ~0 v) r" N
a- j! v* ^+ G; U
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
x, \" a2 ?7 S6 d // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
$ b2 b6 x& l) r5 I virtual bool CheckAndRefresh() { return false; };
% B% R N( N' w2 F4 ~9 j$ l8 r
# i- F: h4 d1 f5 \" O5 Z# Z5 ~9 Z0 e
protected:
5 V7 a. F$ ^8 w2 V void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
: k( _7 B+ \ y. t void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& x/ B" }. f$ \2 o0 |+ q' ^
void RemoveDevice(CComBSTR bsUDN);
5 f! t. Q9 f9 ^ D4 ]8 C+ ? bool OnSearchComplete();3 o. t j1 S) K
void Init();' ]( c! ?2 W, Z& ?0 r2 \
2 f7 m( e6 i& n+ Z: h$ I) ? X0 f& F
inline bool IsAsyncFindRunning()
' r/ B5 I' z% M9 j* p {0 w, P5 I6 g1 J: p
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )$ A% O8 N* @1 m( l
{
2 `% c n$ r0 F4 Q, X9 ~# g% _ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle ); Q1 b* W' }. H9 Q- S+ o8 Z+ s% y
m_bAsyncFindRunning = false;- j$ p i4 J4 w/ t3 L, {5 S- c
}% @7 ~3 Y/ q6 {& v
MSG msg;
) i$ p7 {' O3 w while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )! Z& B. I. g a. U+ x' j
{
8 S8 m8 k* R. e/ e! ^+ ^' T- ]1 N. E TranslateMessage( &msg );9 g- H0 v# L0 h9 G
DispatchMessage( &msg );
' z# I( E' n, [3 ?/ H# x/ X& Q }' G9 R. y% [* c* O5 H* t- a$ H# t0 [! P
return m_bAsyncFindRunning;
3 J. p2 e2 a8 h U3 O' k! G: p% k }+ h7 W; E1 o6 e2 u7 q6 [( p1 o
' \ U" s; X, W) T' I# N
# x3 x5 m6 a. T8 O) Q9 r' c: E f TRISTATE m_bUPnPDeviceConnected;
2 d$ t7 [# e8 g/ f5 G1 o, o
8 j5 v* b$ o# f- P' O
# U6 W5 P% j8 o/ ]7 L; S3 t// Implementation
- }- A1 K$ g5 A5 U // API functions
* d+ H2 V: B$ ~# J7 F# \. Q* F$ r SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);/ H5 s8 _$ D6 H& F
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
$ [" h' h' ?3 B4 Y" H5 X* U BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);% f, U3 [7 I& C8 U
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);' v: Y: ?0 J8 G( K, I
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% e- o+ k d0 a4 |3 @! B
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);0 v! V& l+ Z, ^- w" N) s
; Q& w" i. g7 w% t# b' [: G
" Q' p E2 r9 y/ d& N+ f& t TGetBestInterface m_pfGetBestInterface;) v9 d+ @* x2 N
TGetIpAddrTable m_pfGetIpAddrTable;
1 C& h6 V; G4 Q) m& a4 t TGetIfEntry m_pfGetIfEntry;
0 _$ ~6 g" k8 w! r- S. R: x+ _6 k G1 [
3 F. {5 |. X4 t" Q/ ~7 |+ k B6 k0 `' `6 X7 K9 j: j; a% v$ q$ |0 X
static FinderPointer CreateFinderInstance();
+ |, t( w4 i% b3 s struct FindDevice : std::unary_function< DevicePointer, bool >" {% ?) u' o! X, s
{: a6 A7 j9 i5 A. m5 R% `5 n
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
% n+ H4 I2 Y9 L5 r2 W/ R7 k result_type operator()(argument_type device) const' {3 O6 i1 v; H* M, {
{ ?7 _- ^5 _; n% c6 g$ N' c
CComBSTR deviceName;2 q, j5 l3 f: o
HRESULT hr = device->get_UniqueDeviceName( &deviceName );3 \2 h6 e+ @ ^6 D0 Z" x
5 Y/ V3 x* }# I; t w( F6 \( ^0 K
2 v; U) H) Q2 E h3 C D if ( FAILED( hr ) ) c" _5 _2 Y5 s; f! Y6 A
return UPnPMessage( hr ), false;
2 J/ ]: Y# v1 n& G
0 M1 i0 K* R2 k$ B3 o
) E' J3 v$ I" K7 I" F' c, R return wcscmp( deviceName.m_str, m_udn ) == 0;
! d4 `& P( e- }% s! s8 T7 o }
6 A& Q5 g7 R5 f8 g- h CComBSTR m_udn;" x. c* I- [$ |" k; z6 t" v
};
4 q- l% h* L" l$ h R
! a9 ~0 Y1 M# h" q# k) U9 M+ Y void ProcessAsyncFind(CComBSTR bsSearchType);
+ x, t% r. G$ }7 | HRESULT GetDeviceServices(DevicePointer pDevice);+ q7 r& c6 t3 L8 w
void StartPortMapping();
7 b, U4 f% f% k2 e, ~( U! L HRESULT MapPort(const ServicePointer& service);/ t' p8 M% s3 G0 N+ k" x. K0 w
void DeleteExistingPortMappings(ServicePointer pService);: K9 }, v) c$ g/ K
void CreatePortMappings(ServicePointer pService);% M) Q; m* `) P2 A5 |
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* U5 o; r6 ]/ F HRESULT InvokeAction(ServicePointer pService, CComBSTR action, & j) G1 h+ A$ ^: m
LPCTSTR pszInArgString, CString& strResult);
, d7 U# W2 } I$ G0 N) t void StopUPnPService();
/ n& o1 I& Y8 M" \6 o" R% k4 w+ |7 r: L) R; [* T4 v9 i3 `& Z
' @/ {! B/ ]: }2 @
// Utility functions
% _ w* ^0 }9 B8 l; S3 {" G HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);* W7 X0 T0 O5 v7 H! ^
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);2 t2 j! E7 n+ |9 x' `
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);9 V/ Z/ r* h4 A0 i; T$ @
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);* i0 n, Q3 G) N. \& o; [
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
, R: e: e# g6 j4 W; T3 Z) Z+ O HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
" R) t. ~% g8 L CString GetLocalRoutableIP(ServicePointer pService);9 S; V6 u5 n8 n( x) R3 M
) h, f( F$ M6 A) N) u5 e
7 H; t6 G, J, L) ~7 u// Private members9 k4 @3 M/ g2 X1 v0 b2 g1 U5 R
private:1 G; e7 V' ?" @! v
DWORD m_tLastEvent; // When the last event was received?
; J% T8 K# @3 N- D std::vector< DevicePointer > m_pDevices;
j* h* m6 w6 z std::vector< ServicePointer > m_pServices;
5 I) r+ _: T$ v z FinderPointer m_pDeviceFinder;
$ O* I6 i/ S! K DeviceFinderCallback m_pDeviceFinderCallback;1 u, X! ^% p( Q g' h$ h: T
ServiceCallback m_pServiceCallback;
9 g$ [0 g. e5 e; ^' ]+ q0 A2 T, E5 Q3 t9 A5 V/ ~ j
5 J ^' |" T) a% q' l, X2 z
LONG m_nAsyncFindHandle;
$ n4 K) L/ Z& u) V" A! n. [ bool m_bCOM;1 ~: F& W9 }+ i+ J' N6 N
bool m_bPortIsFree; |/ \$ b* ~" ^& p( ^& M
CString m_sLocalIP;
. O1 O9 C+ f+ | CString m_sExternalIP;
3 ]# E+ X0 T& z: v8 z5 l bool m_bADSL; // Is the device ADSL?
2 H/ J: }# S" n0 i bool m_ADSLFailed; // Did port mapping failed for the ADSL device?& P' I4 ~& X6 d1 A
bool m_bInited;' {, _+ O0 x0 W d& G' | i
bool m_bAsyncFindRunning;# L# C f! Q. a; e+ Y
HMODULE m_hADVAPI32_DLL;
& [* w3 }0 ?: o& R HMODULE m_hIPHLPAPI_DLL;
" |, j: j( K) P* G$ z bool m_bSecondTry;
, Y: i) \/ {. B+ Y* H c9 R bool m_bServiceStartedByEmule;
: F. s2 j- ?8 X" j bool m_bDisableWANIPSetup;* ]7 [9 a! [ D2 c2 B- o# e
bool m_bDisableWANPPPSetup;
9 h: E. o" \1 q9 X
( M9 h" F V3 \# t; {6 E
9 W" P# {: {3 w5 B};
$ J8 g: ~/ P3 ?/ v$ t" h% j" P( `) T8 `
& ~7 i9 _' B& y8 \ K& T6 `7 {// DeviceFinder Callback
$ z: H G. m! B2 W) B5 O8 O! C; |, Dclass CDeviceFinderCallback3 J, B: c: c9 F" X0 e
: public IUPnPDeviceFinderCallback. o& W, i$ W, f
{% D: U4 R! ~2 L* {6 Q4 y
public:
- W; y. b2 n0 \# `# k% O CDeviceFinderCallback(CUPnPImplWinServ& instance)
" Z/ r0 q) D( K' i% |7 ? : m_instance( instance )
+ {( ^7 a; M9 { { m_lRefCount = 0; }, h2 y5 `1 C1 u N H7 e( E# d
0 n* N, X) `# ~. w
8 f2 f" g# G8 A8 a+ K( A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! O8 m+ n/ ]) v" S1 R& i7 R
STDMETHODIMP_(ULONG) AddRef();& K* x/ [. a: S$ X9 |
STDMETHODIMP_(ULONG) Release();
& B; t" U3 ^$ ]' f" k/ H" T/ [$ r4 h
, b2 u7 s* L( O8 y
// implementation A* X+ o. t6 v. q' g9 x
private:
9 P. s+ O& j" {! j) [9 C HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
# P. s0 M9 _4 d: n HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);; e/ Q' x' }5 [. G$ d
HRESULT __stdcall SearchComplete(LONG nFindData);
: X) `: y& \$ Z* O5 ?' u3 _" n% Y% E. g, h* X5 e' z0 K4 n- z) I+ C. R
/ T- L, A8 o' T2 }private:: ? r7 S: n4 N/ h" n6 }
CUPnPImplWinServ& m_instance;
* `+ @+ l2 |' Z, ?+ c* o LONG m_lRefCount;" l2 U% t$ Y- r& {' f X
};
. r7 Q- n* c9 p- E0 V! M& |4 y
7 |, p& Q; v( |4 p( @1 e6 P ~ C9 q7 M$ e& L
// Service Callback
' W# Z( `5 X$ D$ o0 M2 cclass CServiceCallback6 Y, g9 e3 @" z& B
: public IUPnPServiceCallback# o+ y' a1 w3 x9 n" Q0 n$ Y/ s
{8 ^. ?- J y: Z& M& Q. t n$ D4 Z" W0 q
public:
& J; t& [2 i4 y" C CServiceCallback(CUPnPImplWinServ& instance)6 P' N% O* {/ D+ i% W: F; |$ I
: m_instance( instance )! [( w1 s7 y+ s- ?0 g1 @: l5 J
{ m_lRefCount = 0; }
" E h9 C! w; K# _' p8 n2 S. w / A- J9 C7 F6 x0 d( P1 V6 }( N
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% N# E! a+ m9 i s# E+ v
STDMETHODIMP_(ULONG) AddRef();
6 g7 ^9 y5 [% O S STDMETHODIMP_(ULONG) Release();
$ B. J0 h' C3 k, I
( o3 ~, w9 c4 M* J5 t+ B
6 y$ Z2 z% C7 s0 T// implementation
" u4 l, l8 ^' F" Cprivate:
: P8 G$ A, V+ Z5 L4 N7 ? HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);4 O }5 Z; c, D0 q2 d+ f- r
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
! [6 ~2 H- I/ B* v; v
, F. L! f$ E8 p; V: b; h& C# d- V$ O8 X& d- S+ [
private:" k/ A5 U2 V# v8 |$ J( E) I
CUPnPImplWinServ& m_instance;/ h( l; Z$ P5 ^9 w7 K+ \6 L' o
LONG m_lRefCount;
; e/ V# K1 L& e! o5 X7 ~0 a$ A( R};3 J1 D+ `; d4 a+ _, `, a
/ n( I$ J0 r$ l3 O- r* V
- a- b |1 R+ h5 G: m* ~( [* t/////////////////////////////////////////////////
+ _" Q8 ]) T0 O- {; u5 ^0 ?+ I
3 n. x) M! C! K. l$ i/ y4 Q. ]6 \/ M5 v" A" o2 c2 k5 H
使用时只需要使用抽象类的接口。
( @0 k+ z5 D/ n& Q. ?: _( VCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
! T: F( m2 U. N0 E6 s& ACUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 }8 `4 E/ N( l
CUPnPImpl::StopAsyncFind停止设备查找.
. R: | ]9 g8 v" d7 GCUPnPImpl::DeletePorts删除端口映射. |
|