|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
! I/ h- j3 P5 J; z6 H# C* b& D4 K" C+ F
9 {' R3 h7 r* I; A. @* | d" V
///////////////////////////////////////////
5 _* [7 `/ W; P8 V% |* ]) s//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
2 O* b5 F4 T# K) T2 V% W; ^2 [- v& Z3 |
3 w2 d% |) {8 ]4 Y0 o6 j0 S#pragma once
2 R0 E5 x; w1 S+ z, F, I#include <exception>
, ?5 B; ]; E' f9 Z2 y) L8 u% Q* L5 ?0 Q! M6 C R6 {, N6 B+ P
/ K ?7 j; F3 U/ P9 ^+ S8 `9 G: ^ B
enum TRISTATE{
e: F, @6 n% l- O. v TRIS_FALSE,
- [* h$ n& F* W9 H1 _. g+ a TRIS_UNKNOWN,: Z/ P/ A7 W0 g3 @
TRIS_TRUE
( b- |5 o! p. ~3 ^+ z M1 I% h};# c7 J2 }( ]" O% ~$ ]0 f O
% k2 s6 e$ a8 g* w. U- n
3 G0 `) @5 J0 F' q) g$ p- r
enum UPNP_IMPLEMENTATION{% S9 s) c# G; Y* k% Q ?
UPNP_IMPL_WINDOWSERVICE = 0,
m+ e' M I$ u: x/ M- B6 q: x UPNP_IMPL_MINIUPNPLIB,' Q L5 e/ F( L x' c5 q: S
UPNP_IMPL_NONE /*last*/
- q4 Z& g) U/ w" j8 q! O& ^};
7 H! K; t! y) W! [, {
8 W% B" }! k" @
4 h' l/ x: m/ z9 A7 W5 C0 e+ F3 H5 y: z$ Z- m
% D9 E4 `2 \2 {0 bclass CUPnPImpl
9 \% f# e" |/ e! N# u{5 C5 C$ L' G- ^' ^1 s/ J
public:4 @9 w: I9 I. M" G4 o
CUPnPImpl();8 y, I! c/ O( P. j1 L8 Y
virtual ~CUPnPImpl();, ^7 C9 ?5 e d# v- R
struct UPnPError : std::exception {};4 S; Q/ F1 E! |' s( O/ m' c
enum {
7 @. B0 T% b0 [8 O* d UPNP_OK,
' P6 q- m( ~8 m UPNP_FAILED,5 B/ O0 c* \& I t4 H& U R
UPNP_TIMEOUT
; S! C6 D$ `" D" S };
J v5 t6 ~- m0 w
& U6 {. J- N6 \" ]$ u7 L4 T0 a* P4 x' n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 t$ }9 s) g& |3 |; ?7 x- `# P virtual bool CheckAndRefresh() = 0;" k" i5 a0 p0 ]- r. V
virtual void StopAsyncFind() = 0;' u# M% w8 x# D& c8 ~" ]# q
virtual void DeletePorts() = 0;8 m% l+ Z! |6 @+ T
virtual bool IsReady() = 0;
- W% I9 G8 g7 k7 d: S virtual int GetImplementationID() = 0;
; p" X* p( ^6 ~ & b5 \# ^& ?0 B
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) d0 l- S& D9 t
/ X! p, @; _( m3 k, D1 y6 k
3 R5 |3 T6 o- X& ?: K void SetMessageOnResult(HWND hWindow, UINT nMessageID);
% e( n& h$ {' N5 \0 q TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
$ K3 u5 u( A, c uint16 GetUsedTCPPort() { return m_nTCPPort; }
$ r! G, G, V8 G; U uint16 GetUsedUDPPort() { return m_nUDPPort; }
* q( A: Y: ^/ N. S6 E, @6 v( ^0 I* E" s0 f4 O7 P% v
* L6 i6 W2 a; {, S4 p. [$ ?% E3 H
// Implementation
! B4 [# J2 T5 @5 v' c) Lprotected:5 f0 }* g! M2 k2 A$ u/ k
volatile TRISTATE m_bUPnPPortsForwarded;
( w* f' L! ?6 } void SendResultMessage();( v. h' M( v4 K% `' s
uint16 m_nUDPPort;
. u5 K/ z' X# g uint16 m_nTCPPort;
& g% k8 H+ h% N9 Z$ P uint16 m_nTCPWebPort;
0 u1 W& E h( L) ` bool m_bCheckAndRefresh;
8 i" C8 ]! q! r% z' w( A9 x/ M) K: r0 D- u
% E- K: t- m4 _# A2 t, w/ N
private: B8 s8 k1 ]. |8 c& c! f
HWND m_hResultMessageWindow;
" c3 i$ U5 B! @6 ]) _; R1 V UINT m_nResultMessageID;5 y v) |- _6 T: {
5 v) U9 o0 N A7 b* O
! Y4 L h/ ?" ~
};
7 Q& |7 m) X. R9 X, i' A& k3 `# x" S% O( @1 D! b
6 |; V V1 ^: \6 ~1 l! r( y1 O4 |
// Dummy Implementation to be used when no other implementation is available
; c( p1 C0 b- ?3 |+ \class CUPnPImplNone: public CUPnPImpl3 ]2 }: I4 E' H8 x; g2 A1 o
{$ k. P9 R, y7 O
public:
' F/ \& v; e' G; @' K virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
- t ^/ \6 d( R# @$ `1 P virtual bool CheckAndRefresh() { return false; }6 p( [: d7 a5 n1 E3 s
virtual void StopAsyncFind() { }# A, B3 |7 o4 k( `+ m/ X
virtual void DeletePorts() { }
+ G- x" N1 m3 y+ ^( [ virtual bool IsReady() { return false; }! C) J/ _5 Q4 J* S- g
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) I: `6 \ }/ h5 N};
5 z' _0 \ [1 `) g" u C: `( a# D! I7 E! o8 r
9 C% E1 |6 u/ T! \& n/ t/////////////////////////////////////
2 o1 B# ]- H6 h7 h//下面是使用windows操作系统自带的UPNP功能的子类' [+ e8 ~' v& l! E1 O) a
: a. p0 H7 V+ ^9 Q% ^1 p6 ^1 R5 r; j
# @. I1 Y+ K1 b' N/ T#pragma once, M/ f* J0 k$ @- |: z, F# g
#pragma warning( disable: 4355 )" r3 |+ f0 X+ f* S" \2 O7 i) V
: u3 C0 J, x* E8 _' o s& }& f
$ i; H' G+ M7 }: {( O
#include "UPnPImpl.h"
4 e& o' g/ T$ H _( u+ H6 o s#include <upnp.h>
; x) ?* n5 M v/ y1 w#include <iphlpapi.h>8 o+ G: ]/ _" u
#include <comdef.h>8 @7 w: A) _3 t- I; K- L9 F5 \: v
#include <winsvc.h>
% W+ L0 f% _- h6 q0 r/ {( t
. r7 [# i) C( ~6 ]* j3 W2 p9 C5 N
3 m1 W! @ U# a' A( H* c#include <vector>" [$ E! G" U: _0 R- @' m
#include <exception>" k2 V$ r& q) q; M! @
#include <functional>5 n* f( Q" [' E8 n% ]& o N7 F
6 o, x9 D, \% i( c8 p+ E* V- p6 z# y1 X. {' v8 _
$ c' L; ~' ]! l. J R0 Z* l! p5 E7 v
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ c/ P0 i A2 F8 g/ Ctypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;& [- L( a5 r9 \4 f- {$ Z [9 i9 i6 n
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;1 t5 z* a# D7 N. E
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
R- i6 i) e" z! u% |; C [: v& a- etypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' N" P6 G, J; \/ }! J' _2 q# k
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 o d: z7 N$ wtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
0 R# G, K0 W! u5 J. h+ ]9 G5 M: k/ }* \- I# D; z
. R; X! ~! V: T4 G" {6 h6 C, ltypedef DWORD (WINAPI* TGetBestInterface) () B2 L' D9 W. ^, H2 O7 C% ]; }
IPAddr dwDestAddr,+ b+ e6 F0 M" t+ W( D4 c. G' G
PDWORD pdwBestIfIndex* Q% ~; s; E& R# r) {& Z# w
);
8 p8 S z! I& W5 i/ G* e3 j/ u# o+ [% V, _6 g/ I- y
9 o$ c1 Y4 B0 |0 H" ^& p! o# T
typedef DWORD (WINAPI* TGetIpAddrTable) (
' g+ @* W7 S- N PMIB_IPADDRTABLE pIpAddrTable,$ _- m4 |0 L8 V) n
PULONG pdwSize,
0 F0 A/ Z! `$ J& D BOOL bOrder" i) m; c! q X
);" R/ i) z' {1 G% B
4 o# A; j/ {0 H* l& |
$ {6 ~+ o: D0 s7 `, I" ntypedef DWORD (WINAPI* TGetIfEntry) (+ q6 I# D" G9 ]. x
PMIB_IFROW pIfRow3 e) ?, b/ i3 e! ~4 ?
);; J* p/ h. `& W2 e
' e9 h+ V. H2 k9 c9 x8 T- Q9 O) v) R3 q/ n9 u& Z' ]! }% d" R* r
CString translateUPnPResult(HRESULT hr);9 p5 c# [ D7 _! O5 g! x6 x
HRESULT UPnPMessage(HRESULT hr);
- [$ B4 h8 Y; V9 G7 y! V C' r; w2 q6 ~
" H0 n( \& g/ o9 l2 W/ N$ Qclass CUPnPImplWinServ: public CUPnPImpl
' E _; j4 d. Z{
- I4 k. X) H% @5 ?& ?1 v friend class CDeviceFinderCallback;
4 H5 R) c# D, I8 i# b9 _ friend class CServiceCallback;
% V& Y0 ~# }+ v- T2 o1 R// Construction6 M1 h+ }9 x$ P4 g
public:
" a+ C1 t# k r: _! n virtual ~CUPnPImplWinServ();! V$ H+ R2 \- E7 u$ g6 {1 {
CUPnPImplWinServ();
3 z$ \& ^" P* _$ n' P9 r {6 m* p" `* z" K5 z+ e: K/ K
( v% V/ [- r7 ~
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }2 f: f9 |; F3 g; K# } | a
virtual void StopAsyncFind();
8 m9 g4 Z1 |. j) y0 h9 J virtual void DeletePorts();
/ @+ E& I Y$ ]0 |# {/ B) T virtual bool IsReady();
6 ^* i% |! M& Y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }6 J9 M: x; ]; G5 q& n j9 P
0 s, V' V. z: v
i" r$ q& n+ L // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 M& ^4 j! q6 m2 P3 \ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later9 s+ C6 D; m9 W v7 V
virtual bool CheckAndRefresh() { return false; };
- E0 H: l. p6 g* W# l0 I: {; Z# B
# a8 m w% R2 C& q" `) u6 J# J; D; P+ ?; ~4 k% ?3 l& F0 [6 x
protected:
u1 }! h5 w: u$ @, ]$ L) y void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);) Z0 h4 y% a9 c9 I( [% z; F
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);( K' p4 x4 M# _
void RemoveDevice(CComBSTR bsUDN);
8 H. a2 l; k* L& C( Z; [- r bool OnSearchComplete();/ r. j4 Z0 N7 @: k2 H9 C& f0 ?2 J: |
void Init();$ u9 w, ~( { b* B' l
5 b8 M$ |1 N6 g
. a# \3 g, Y- b' W; F! }! n5 [ inline bool IsAsyncFindRunning() 0 J9 \; J- A+ u7 V0 B
{
* i9 j: o2 a9 V+ \! h6 S6 G if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )- V9 q! i+ t0 V
{
' l1 P6 f/ `* ^& q J m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
8 X- N- V$ |3 P3 W m_bAsyncFindRunning = false;$ @) h3 @3 Y! M0 w) c0 m! Z2 Z& d& x
}# ~! }: t y3 X
MSG msg;8 H1 H: u& u n! A8 o8 U& T
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )9 o. s/ u9 }, [$ i# {
{3 k; }- V( b* T) i( m
TranslateMessage( &msg );
1 V: ]$ D5 e% d4 w DispatchMessage( &msg );2 x! m+ S! Z0 V6 l3 |% C% ~
}
6 K$ s5 {* f% w6 E; Q7 w e# i, p return m_bAsyncFindRunning;
/ f( J- U5 \( W, D }
3 }) J+ k' o& C5 g+ ^: a4 _$ A( E0 Z( O% |
$ h2 t' |1 D7 p, Q$ G
TRISTATE m_bUPnPDeviceConnected;+ o. U: }( l; z }+ R
8 L( z0 b5 ~8 N. O) c
* Z# X1 o, O2 t5 S// Implementation) M6 J. ~, w' s/ d: E, ]
// API functions' y- {5 `0 M9 x. l: g
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);2 p7 k* w# _ s: f2 M
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
, j; k, r% f- A$ z: d1 Y BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 e% Z: \+ l; ^9 p2 V$ u3 Y
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
3 D2 y4 U( h! v8 k5 J# d BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);' n% y( y. \# j
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) U5 D; Q: Y$ c+ w* ^- F3 \) \/ `' b3 k( z3 B
- A3 [0 |. U! @: B TGetBestInterface m_pfGetBestInterface;! E; F) p- r* s+ U. \5 N
TGetIpAddrTable m_pfGetIpAddrTable;
4 Q3 |5 Q% l) x TGetIfEntry m_pfGetIfEntry;' z7 B4 P0 z! Y1 }
: U7 F0 _' x/ D8 S* C y- s! _+ ~
7 g( x6 P; W7 i5 K5 R
static FinderPointer CreateFinderInstance();
I% u5 e4 M6 n1 a i/ p/ x struct FindDevice : std::unary_function< DevicePointer, bool >
' f& I: }; }) [" B5 J {
# p; X( G2 a7 m FindDevice(const CComBSTR& udn) : m_udn( udn ) {}! b! X1 W3 K8 E. c) r4 l# w
result_type operator()(argument_type device) const$ ]+ I0 [% R- H5 D
{) h( X% `5 U; A. C* f3 u
CComBSTR deviceName;
4 f" g6 [. N" t: _) { HRESULT hr = device->get_UniqueDeviceName( &deviceName );7 f. S2 H' b* G5 M1 y- ]4 T ]
* y0 ~5 d! H. @# F' i9 a
; b2 Y+ ?- r9 J* t* e) e if ( FAILED( hr ) )4 _9 Z! H+ P. w
return UPnPMessage( hr ), false;: k8 A) u t' h# I
+ \( d; p9 {6 e9 \( C3 L& c, x2 `/ j+ R/ F
return wcscmp( deviceName.m_str, m_udn ) == 0;
& ?: A! A( ~! M6 } }" s+ \" g! T2 j5 L$ G0 L
CComBSTR m_udn;5 Z4 ?& G! v8 _
};
$ ?$ f" e" ~6 Z1 ]+ D7 D! b ( v7 i+ o8 a! b. p: Y
void ProcessAsyncFind(CComBSTR bsSearchType);% I$ O- ^9 M2 D
HRESULT GetDeviceServices(DevicePointer pDevice);
5 U: z) K+ v9 r4 _ void StartPortMapping();
; g. ~) H' c2 _/ Q! x. L) T HRESULT MapPort(const ServicePointer& service);' w4 G; {2 | P4 b8 K7 V+ A; F2 ?
void DeleteExistingPortMappings(ServicePointer pService);. j9 \9 L6 D/ g. u8 r
void CreatePortMappings(ServicePointer pService);
& k G6 p6 R- p" [, z7 I+ @$ {, A) ? HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
4 N( F" [; Y2 W3 E HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; d' V2 h4 n& G- b/ K \ LPCTSTR pszInArgString, CString& strResult);2 `& d$ b* n& ?" d) q- g
void StopUPnPService();+ N( y% F# U; Y& L n
6 c& L8 h* g+ V% R+ f* g! G
4 l1 m% V) I. G# l1 Z // Utility functions
) ] H" k) M9 z3 j& ^ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
* H8 J7 n: I. y) ^* v) x) B5 l9 p INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* Y6 R$ [9 F: Z; H INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 h& z- g) F% p& Z, R# `
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
: {, {1 P0 ~: j3 E HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
3 @4 C" J/ a5 M HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);" [% j; [+ b& [3 q
CString GetLocalRoutableIP(ServicePointer pService);+ X" _- Q, n& T
; c0 x3 i* M0 z4 M) H( w C# X4 g4 I ]
// Private members. ?# _4 ~8 R) {& [8 p! N, x8 _4 y
private:2 X7 n# ^! U4 t9 X: p7 n
DWORD m_tLastEvent; // When the last event was received?' L$ J5 C0 C# A7 U& m; j% A! T
std::vector< DevicePointer > m_pDevices;2 `% f( `* c" E2 n+ w3 |0 ^1 ?& j. I
std::vector< ServicePointer > m_pServices;! q% O6 {# J' s; A3 G9 \, x
FinderPointer m_pDeviceFinder;
' R8 E* y% m+ u3 }+ G DeviceFinderCallback m_pDeviceFinderCallback;
" V2 I% U! l+ x ServiceCallback m_pServiceCallback;' \2 n: O2 L$ B# a, H. a$ s' u
8 \5 M$ {. u- x8 c% H; x% n) C
2 l+ n9 Y8 @: T8 m2 S; Z- z5 `+ O LONG m_nAsyncFindHandle;
) m' Y5 d6 W1 J9 e/ [ bool m_bCOM;
* g c% Q$ x0 R; j8 r bool m_bPortIsFree;3 [9 X- p+ v; J# V3 ?& h! `
CString m_sLocalIP;
, [% K A0 D. L8 Z2 e9 D, X, j CString m_sExternalIP;. X. j) Y5 p1 x0 ^& u
bool m_bADSL; // Is the device ADSL?
. D* h1 h: P% `- ^8 O% I bool m_ADSLFailed; // Did port mapping failed for the ADSL device?; m: H. x3 W: R1 u7 t! J
bool m_bInited;% k" \: f9 Z. p U: z% |+ [
bool m_bAsyncFindRunning;
3 l: U/ g5 l4 `/ l. F. b+ b% ^ HMODULE m_hADVAPI32_DLL;
7 w3 P' y1 l' p$ d HMODULE m_hIPHLPAPI_DLL;
2 k3 ^( v/ M3 K& y6 ]& _ bool m_bSecondTry;- Z7 W$ C) N4 i& Q$ [
bool m_bServiceStartedByEmule;1 E% N) c* R6 @
bool m_bDisableWANIPSetup;. {9 d3 u C4 f) E2 q. |0 S! ?
bool m_bDisableWANPPPSetup;
) z. L# `7 } g2 o' N
: J: L! C3 {- v3 J! b- G
, c3 ?0 y& p/ ]$ i};/ t- p9 N9 U. g5 ^
, \6 E1 { n( X1 I$ P+ D
* a8 A2 T9 F) a, E' \% [// DeviceFinder Callback, K: H6 Q* }. V/ Z2 h0 X M
class CDeviceFinderCallback8 m3 |. j q: c9 y1 ~
: public IUPnPDeviceFinderCallback
, A6 y' o2 m2 C- |2 b" w2 w{. I, }6 m: c7 U1 M
public:
2 i$ G1 p. _5 @4 a- ^ g CDeviceFinderCallback(CUPnPImplWinServ& instance)
4 P, X" d2 r* s) ~ : m_instance( instance )
2 ^+ ]5 `- X5 ^& } { m_lRefCount = 0; }& i* R* T8 }& N- o2 M, |4 J1 J
# G4 F9 i) J+ o& |& m/ m! s
: W+ T9 j1 V9 u) ] STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 {( L; H. D6 s) H- P7 u
STDMETHODIMP_(ULONG) AddRef();1 q. Q4 Y! q5 k
STDMETHODIMP_(ULONG) Release();
2 }* R) _2 W0 M" @" m- o3 R1 p% @3 [2 c0 m" v% c2 A9 k/ [/ [2 [3 n$ J' @
0 Z6 s6 [1 J8 o( l3 O; Q9 |# ~! Y// implementation& _6 F* ]0 H5 l1 Y+ R6 Z# N
private:7 r2 m8 O0 G) ^1 Y/ ^
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
: P- P; H" Z ^* w HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
/ k3 r4 i2 f0 U% ]3 b HRESULT __stdcall SearchComplete(LONG nFindData);
+ L1 x7 ^; l8 l$ c* }2 T B3 J7 {% `0 m7 a
5 S8 u" @. u# _private:. J9 ]0 m! {; W, { ?
CUPnPImplWinServ& m_instance;
1 w3 a! k6 b; p8 O# H& o LONG m_lRefCount;
% C! v' [4 P# p. I% i: t/ H' @};
* K0 w* F- w7 S: I( A* l" ^) Z( [
. i) P3 g, X; y! }0 Z2 }3 P' ^8 Z: l2 s! B
// Service Callback
4 V+ z7 ]. _! Fclass CServiceCallback
& `; o3 X. T- y1 W8 F- a : public IUPnPServiceCallback- ^2 K# D: b! T" F9 Z5 \
{/ W: `: _6 O O0 A' h; F+ Y
public:
, |& G( x' K- h- ~7 q CServiceCallback(CUPnPImplWinServ& instance)/ F. x' c( m; C1 ~# v( u+ ~0 f+ O; {" i6 U
: m_instance( instance )# X3 q+ E" r0 Q! I) ? ]
{ m_lRefCount = 0; } W7 U0 I! w' d
8 O1 K; m, ]- Y* r! _ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 X: R& `6 e% p! c+ I
STDMETHODIMP_(ULONG) AddRef();# a2 n8 |2 f |7 a
STDMETHODIMP_(ULONG) Release();! K0 P1 I7 m+ n, e
( N$ e0 a6 ~% n/ c& h. \. `3 y" l' D4 r z
// implementation
3 ~; {* S6 D3 u9 gprivate:' }2 a o; b8 q, x8 a4 Y: n3 M
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; Y$ B9 A0 S: [+ M; d+ J HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& Z# A! }0 h S4 `
$ y5 ^4 Q4 h. v; O" e! g4 L
4 n" ^9 C2 J+ R$ [9 a. i6 V$ K
private:
: M$ I: w1 G( l, e# z CUPnPImplWinServ& m_instance;
+ N% e; g* f5 [. k, w6 h2 \ LONG m_lRefCount;* U, l% a9 l1 _# {
};
4 y2 N$ H# }" |
( [/ O/ V9 m# x: s, f. ~. \
# K- h8 @6 c5 M' W/////////////////////////////////////////////////
7 W. l( t8 m* z! v
3 q' M' h# x# r$ V* v, h7 S$ t& V. w. h8 ~8 Q" ~
使用时只需要使用抽象类的接口。 M2 [* F8 x. u8 K' ~
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.0 i/ M- P) e0 e! X- S4 y
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.) O+ N6 f% p+ g# u$ [2 V# a
CUPnPImpl::StopAsyncFind停止设备查找.
6 |. j! e4 ?$ ^3 ]' x- kCUPnPImpl::DeletePorts删除端口映射. |
|