|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,1 R" B! s" Z' O4 D' I% L# F) {
- H5 R$ X% v) B/ k& ~
1 [4 ~/ D9 J, Y# L$ {/ f///////////////////////////////////////////
3 C6 E% r' y$ ^) B5 K//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
4 z: m) y( D; h. v! C5 X2 d' H( X: X8 H# K& `% o0 h& _
; Z3 D& J+ x% o2 ^
#pragma once! U: a0 g4 c) R& y
#include <exception>4 O! W6 s0 L) T, x1 Y
/ L; q+ n6 \4 e$ ]& J
7 D3 J [5 ~8 A; X) ~ enum TRISTATE{( V: e9 z) E4 C0 O) p8 F! M
TRIS_FALSE,; Y4 t) j) i" @! t9 Z3 l* u
TRIS_UNKNOWN,1 j: v g8 W, n l' B" A" h
TRIS_TRUE5 k6 G0 A" W) [- a/ j
};
7 P% B# u5 A. v7 ^
4 I5 I4 W2 f- O p' m# i) L" I/ t1 P$ D
enum UPNP_IMPLEMENTATION{
2 w7 `3 W$ ?% _8 `/ A% T UPNP_IMPL_WINDOWSERVICE = 0,* T4 {$ y& o7 \. q w
UPNP_IMPL_MINIUPNPLIB,
" g' X+ ^8 R; I4 @/ C UPNP_IMPL_NONE /*last*/( N8 ~. H& r8 M/ G) g
};) B4 A) o4 [3 v" P' p7 _, e2 L
! G; z+ N( W6 e2 a1 Q2 r) E
, R9 {. M# t5 J
4 g C5 F7 G8 {- l! [ N
6 D1 b; t# {' d2 ~5 q8 w. W2 zclass CUPnPImpl4 o! X0 a3 ?+ K, M! h# |. H) |
{
Z t: q1 `0 y3 rpublic:
# c; t9 @3 E% Y CUPnPImpl();7 w; p# [3 a) C/ O) F
virtual ~CUPnPImpl();( m* f$ ~/ F7 z9 ~* m
struct UPnPError : std::exception {};. G+ \8 \! T% R
enum {! u4 {5 b: X7 x" G
UPNP_OK,
5 @' k' ]" {! {/ S( y UPNP_FAILED,1 v0 E2 C- A% S8 L# C% U1 U: R. G
UPNP_TIMEOUT
D- l9 U' L( I$ ~3 G- x2 A3 H };) e) q) |9 P, G
5 e: p! \2 S+ \, _# l
1 [1 s D! n2 c" N. I8 m virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;/ J/ @2 ~' |" C+ x8 H6 `
virtual bool CheckAndRefresh() = 0;
2 b# z3 d% G! ] virtual void StopAsyncFind() = 0;
8 A- ]: g+ I, f0 s# u virtual void DeletePorts() = 0;
) Y. D4 N5 L% ~+ B virtual bool IsReady() = 0;
7 d1 {' ?. }5 [) P: `8 C& A2 P2 X4 | virtual int GetImplementationID() = 0;" c" F$ t8 f4 j4 i5 v' I
/ D; C7 z9 b ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; l; {" d+ C; [3 C* \: _1 {7 G
/ i; E b, Y5 [4 w" m4 ^- J* z
4 R5 K2 X- s. A- _$ ~ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ x8 I- F8 v7 ~! B TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } e. p. R" r+ O' K/ A! g
uint16 GetUsedTCPPort() { return m_nTCPPort; }& d2 m4 ~. x5 j1 _, T1 x3 t
uint16 GetUsedUDPPort() { return m_nUDPPort; }
# s4 \5 p. E3 F7 p! U [, R
4 }/ [+ o% _( b: B. h% ^: p2 d9 s' J4 k, r
// Implementation
7 v! O) e- X) j' c# ^& W0 @protected:: N1 q! D) t& b: B- _ ^; ?
volatile TRISTATE m_bUPnPPortsForwarded;! v. b! J( {, y
void SendResultMessage();0 l; n2 f: s S! K
uint16 m_nUDPPort;. f1 q3 z8 i" |6 {7 d
uint16 m_nTCPPort;$ P: g. ^2 Q) V3 g' h" Z) \2 B2 ]2 @
uint16 m_nTCPWebPort;
: e/ H- @6 _* B$ n: K# T bool m_bCheckAndRefresh;
0 r2 ^' X! n1 e( O; e8 X' A+ D6 r' ^% b* o8 ?7 G, }7 c
/ l0 I1 H; ]. h. T5 `7 w- V
private:
7 N9 f/ [* @2 v0 c+ l0 b& r6 B HWND m_hResultMessageWindow;
# t9 k% ?. L; L4 B. G UINT m_nResultMessageID;$ F. @5 V5 d2 m& r& \) r
( H8 d: d- ~8 K; G: c
& ~5 Z4 c9 c7 D; k: H' I};
* H5 T$ l* {4 |% R( {3 `( Y" P9 {9 `" t! f3 F! l4 B
- p6 I9 i( N2 v- b6 U0 O' R
// Dummy Implementation to be used when no other implementation is available9 C/ c6 r: W, L7 u1 ?* F+ i
class CUPnPImplNone: public CUPnPImpl
( }4 w$ L9 j. S3 j( ?+ X3 O{
X* e- C% V# c% ]$ N6 R4 I; lpublic:0 h4 V4 Q/ r8 m
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
0 k1 a+ M# t# N7 V( c virtual bool CheckAndRefresh() { return false; }
) ?2 C& R( F, N virtual void StopAsyncFind() { }. D% @7 S9 B G. `2 {/ f( s! {+ H
virtual void DeletePorts() { }
5 l" Y0 D( ^% `" I" ?% C8 { virtual bool IsReady() { return false; }
4 {( p5 z" `. v) B2 B% c& o' r virtual int GetImplementationID() { return UPNP_IMPL_NONE; }1 n0 s4 E ?8 W' c6 ]" a6 D" ~, I5 Y
};" w9 w( |( ?- Z2 N) w6 v/ e3 S. \
9 d, u3 Z, @) \+ W p! c& d$ ~8 n4 o+ z. }# Q, y& c) ~4 n
/////////////////////////////////////4 G/ M. D8 f, C+ F8 H2 {
//下面是使用windows操作系统自带的UPNP功能的子类, d' w! U5 J- l
3 ?' T, m8 t: V3 R& }1 Z7 j/ Z5 y( b* ?; o7 F
#pragma once
J0 y7 v5 m% F+ E9 u#pragma warning( disable: 4355 )
$ I5 L1 C- @% D: T
- R4 B2 C- ~9 } z; y. j5 m7 G! ?$ U# b7 G, N5 r
#include "UPnPImpl.h"
5 V p0 c0 w( Y" q$ o#include <upnp.h>
: O$ ?4 T- r; C6 _: k#include <iphlpapi.h>2 `9 i( |2 e) U# [( E7 L/ F3 U
#include <comdef.h>
: @ c+ c5 v7 K#include <winsvc.h>' W3 e0 H/ `: a- L6 I
c; p2 l0 @( ~) H9 X' r* c+ u, e
8 w7 D1 Z K7 N#include <vector>: p! f3 k y, S& m. g* B6 P
#include <exception>0 n, F& _' V) m1 }# c2 B
#include <functional>
# {$ P$ |" m3 a$ e8 U. S+ ` {" d2 R
1 j2 f9 U {- ^8 Z2 F, O4 \4 Z
, I7 r3 Q" Q$ e" V! Z8 R! }7 `. |$ o3 m9 F, H3 o8 e
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
) |2 e; J* L# b- ~typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;! h9 D3 z, \! e
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;9 g. p) n9 a' l$ V: d
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;2 j6 b5 X+ A8 b
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 M( p' U9 Y& [- Gtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;' g* G$ Y7 X1 j) Q: H' y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
! O) p6 R) \1 Z7 z6 Y; |: y* B% \; c
# `7 W: U8 j1 w: H$ i
typedef DWORD (WINAPI* TGetBestInterface) (7 L; H7 S& Z) r/ d8 t
IPAddr dwDestAddr,+ C% U5 @; b# E7 `! _3 G- ^
PDWORD pdwBestIfIndex
" y$ n" a7 |) g, `8 F);& f1 m( }+ X9 k% Q! d: N
" ?' M: i: a. N& R7 w
3 l& n6 s" f( e a/ Otypedef DWORD (WINAPI* TGetIpAddrTable) (
; o* U1 o3 _$ `0 ? PMIB_IPADDRTABLE pIpAddrTable,* e: D' E( h, x
PULONG pdwSize,, C+ M& Z: m1 q6 i/ Y- Q. k
BOOL bOrder6 o& @6 {) G& U$ P Z1 K5 |, Z
);
1 O6 P( ^9 \/ Z/ ^3 B9 T0 ~! b7 `7 ^' u& F
. j% ?* O2 r0 y- `+ i
typedef DWORD (WINAPI* TGetIfEntry) (0 T4 _) r4 D. G6 Y0 x
PMIB_IFROW pIfRow
6 a) S6 m3 C7 y2 ?' H- u7 r);9 j4 O5 C2 i' P3 L: g
( }% Y0 J. L2 V
@8 o0 ]. \1 F- t2 |% J9 XCString translateUPnPResult(HRESULT hr);/ |, s$ c% w; g$ I2 O
HRESULT UPnPMessage(HRESULT hr);
8 N- C0 P7 O% _% @2 ^. i
& ?% K0 H2 B* z3 {
) r- D, `5 t( J& j3 J7 _8 M& Vclass CUPnPImplWinServ: public CUPnPImpl% s6 Q! N7 o3 e& r% z+ z
{" ]6 ?, Y" p7 X, I% I) P
friend class CDeviceFinderCallback;' [) D, [3 C0 X5 z" P. G/ Y; ^& i' n
friend class CServiceCallback;
: x! f/ d B; R2 E7 d: d// Construction
% ?$ _5 t) L2 j" _' {5 @' [public:
$ v. t) C" Z$ M; r( T0 F. ? virtual ~CUPnPImplWinServ();' Z- p9 w$ j- V2 g4 c2 \
CUPnPImplWinServ();; n5 i. T! x8 ^7 M3 q. [
3 N$ Q* P4 k* K" z0 }9 m" u+ x8 G8 W7 D+ y6 P% H0 S% g' M
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# ]7 N/ W, m, ~/ J! d virtual void StopAsyncFind();
2 x( }0 S, G( n, U virtual void DeletePorts();- j% F/ }: z1 D ]2 n, [: i
virtual bool IsReady();
; ^3 z. u# l) w virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
+ Q/ ]# c4 S& b* L
& ^* d% {4 V4 X; n' `8 r$ O! P3 D9 M/ K( T% {7 w# q
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)- M- N8 U& Z4 H9 B, J- g
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
3 f9 ~. N& X) T" r8 N% e virtual bool CheckAndRefresh() { return false; };
& B! R d% ]5 \: w b# R8 X2 `9 L$ R. n1 W6 A. E8 V
4 Q: ^! S. I! T9 r6 s; eprotected:
: G1 d, }) M; r/ c void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);1 s% X7 N# v( [
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);9 E9 J$ X K; ]6 w7 V' k% }2 u
void RemoveDevice(CComBSTR bsUDN);, a3 t1 ?- l* `; e; p0 N5 |- k
bool OnSearchComplete();
* \( ?8 \2 H" h/ _& S! v0 R void Init();) g' B: d9 c6 u2 U4 R- K: ?
3 H$ Q! I9 }+ r$ h: G. U8 r8 @7 f" @
inline bool IsAsyncFindRunning() . p" u7 L+ ^9 t" u7 S0 n. E
{7 ^: A& k2 g$ R3 s! r
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ). P2 C* ~+ D9 G( ~5 h0 b" J
{0 E; @, _% ?' ~2 y6 j, y" J$ q& ]
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
! h# i; P6 J* K3 J5 W6 D m_bAsyncFindRunning = false;
! x1 C3 S$ N! B% ~ }, g ~8 z* b: E
MSG msg;
B/ {9 O# I- K while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )0 W/ }1 m9 O8 E# s
{5 ]. k/ o. n6 l% \: |
TranslateMessage( &msg );, B: _; C6 @/ b& f( M
DispatchMessage( &msg );1 a4 v$ g2 @6 p$ B- N
}/ M' l$ @# x9 {# g k. ^, [
return m_bAsyncFindRunning;
. {( u' R! c: K* `) O; c5 E } q7 k( a! \' g1 c
N1 C j4 {8 Q* t; v
2 L% b. A" Z/ E/ I. \0 v$ ^ TRISTATE m_bUPnPDeviceConnected;
) S) x! ^/ P; ]6 u0 b/ {1 a4 _$ y% s
4 ~$ l! ]% v6 T// Implementation. j7 o/ a2 ^) E: x
// API functions
/ E/ [& e+ Q3 n! ]! m8 s3 w SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
! c* t. q/ [- Q, | SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);* @& |" d4 G! T9 q
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
; D# K2 h. h; K* M8 ]: _ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
- @5 X' v5 q1 J8 e7 Y, k BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);! E% V m$ b2 \2 b' `% e' u
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
2 \; o; x' n0 s5 ] U: O9 o% A* M# r7 l
" l9 k6 ^5 `4 [/ [) G
TGetBestInterface m_pfGetBestInterface;
n$ I9 L t2 @0 A8 w: Z' H TGetIpAddrTable m_pfGetIpAddrTable;
, w, Q; E; `$ ?# Z$ Z TGetIfEntry m_pfGetIfEntry;
" w0 x7 e- x" e. L0 B. H8 x
. }( O6 W) y0 \' W" `, [ D; }* o/ n8 |, X0 U: F' d
static FinderPointer CreateFinderInstance();: h( @1 S, T& Z: B$ c, m
struct FindDevice : std::unary_function< DevicePointer, bool >: E5 ]/ ~+ b, g0 f
{
% S8 C. v. L$ X8 L1 x7 y FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
$ J. m: D5 E, r5 t result_type operator()(argument_type device) const# i) C3 m9 C! Q1 \ \5 e3 M; z
{0 \7 T8 D, i) q. k4 L) Y3 d
CComBSTR deviceName;0 N% A: H: |: m4 I
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& |3 Q. D8 Y& q! g- `- E+ q9 a
9 _% E; l. d' @. a. h, \
if ( FAILED( hr ) )
# Z7 `( X6 Q0 U. v' Q B1 _2 b, I return UPnPMessage( hr ), false;7 r3 D5 n* Z5 ~2 Q
~* s4 t3 z' `, i; \
7 C& x# V+ t1 v. |! E return wcscmp( deviceName.m_str, m_udn ) == 0;7 y: T. Y% l: H0 v
}
, _5 m& x7 @6 k/ m1 ] CComBSTR m_udn;! H, `7 _. m7 o3 R* P
};( v5 f; x# j6 @5 J R" @, w8 q
8 ^0 X3 m7 G" F6 }1 j& T4 [+ i void ProcessAsyncFind(CComBSTR bsSearchType);8 ?, Z" c' J+ S6 b* W' \& s
HRESULT GetDeviceServices(DevicePointer pDevice);
+ i2 i" X7 u, h' @8 _" _ void StartPortMapping();( n7 c+ ]8 f: [3 L2 c. M
HRESULT MapPort(const ServicePointer& service);& c7 E% S6 ?) \) L# g
void DeleteExistingPortMappings(ServicePointer pService);
/ e/ K9 X# N: s& u) y+ c2 Y/ Z void CreatePortMappings(ServicePointer pService);
0 g! w2 G# }# P* z$ e/ F* {, ^, P HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);( \: G" R2 q/ [
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 3 Q" n! I5 @4 u: a% o
LPCTSTR pszInArgString, CString& strResult);) M2 J8 Q$ h/ n8 e
void StopUPnPService();# p5 i1 N2 m, k. d/ O( K' ?5 G9 m
, |. y+ K- D# p# r' Y' f+ D
% }1 R2 c& g/ f9 D n X // Utility functions( {, f9 m. T# Y0 r3 N
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);9 v0 M3 q8 Y1 T2 H, H9 S
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 U9 ^. _% v8 o: L6 t+ H# C INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 n; F7 b# b9 j+ A5 A
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
- d! |* E$ M. C4 {+ q HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound); ?& P; U, N4 n; x0 D2 u0 y8 ^
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
$ T2 X! W7 o' d, e7 k CString GetLocalRoutableIP(ServicePointer pService);
' t' N3 T+ V6 Y! C7 O, C/ F" d3 s1 d2 s) e' c
" }! i) G% U# _) Y' q( y// Private members
! a7 i3 r; |/ `private:
: ~- p/ M: E8 k; s DWORD m_tLastEvent; // When the last event was received?
. F; T1 K4 s6 @4 H1 R. q% | std::vector< DevicePointer > m_pDevices;
/ g/ N& Q" Z; D0 g std::vector< ServicePointer > m_pServices;
2 o/ y1 [, r' Q, k. t$ w FinderPointer m_pDeviceFinder;
- [, l+ t5 N& p$ Q" \ l% Q DeviceFinderCallback m_pDeviceFinderCallback;
1 i( v* W* a' K1 l) E: b, o ServiceCallback m_pServiceCallback;0 Q0 _5 x7 Y3 r3 C' Y9 Z! N
5 Q5 H3 ?: J- J( N( O4 V8 g5 ^
( k: U/ W: C1 o" \5 ~4 g, R1 f# {/ t LONG m_nAsyncFindHandle;; a; ]7 c2 P1 J
bool m_bCOM;
, O9 P5 Z' H+ e l5 t bool m_bPortIsFree;; Z4 o* g- n% ?" v
CString m_sLocalIP;
9 w8 R$ Z. o, M# n) d( ^. W* V CString m_sExternalIP;
+ i8 F& b& `/ R3 F bool m_bADSL; // Is the device ADSL?; O% C6 J7 I* x4 @
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
# x' A# p0 ^/ b7 f: { bool m_bInited;. v( L' @2 [, {6 T
bool m_bAsyncFindRunning;, f& A! |( ^- {' Q- \% \; g M
HMODULE m_hADVAPI32_DLL;
; s6 M" |" z- G5 o R8 o HMODULE m_hIPHLPAPI_DLL;
" _$ C6 n+ s# L; p o& y bool m_bSecondTry;
0 g6 S; D+ W3 O) Y/ Y+ y' c& o bool m_bServiceStartedByEmule; D) }- ~. E& Q, _1 g
bool m_bDisableWANIPSetup;
- _- |- T0 }. L$ x6 g% ~7 ?2 ~# V bool m_bDisableWANPPPSetup;4 g- B+ g( m# b1 v5 R+ K
4 v/ b9 D' h9 A4 O1 V8 G- }, N* D0 y
3 s$ R2 D. L$ G: H};
4 B) f, }5 v7 q- i- k7 N o
6 x% F- R- \+ B/ U- _8 x$ E5 q# |0 w) _8 U7 h3 J6 I
// DeviceFinder Callback9 O& r& `/ L8 M" P2 `
class CDeviceFinderCallback
b2 d3 N% G3 u% X$ k : public IUPnPDeviceFinderCallback
/ H) {' Y; }5 h5 ~{6 p; r/ X |6 k. |& Y6 {5 R5 o
public:$ |7 E' Y3 `9 t
CDeviceFinderCallback(CUPnPImplWinServ& instance)* w* K6 q( ^( i( }! E9 B
: m_instance( instance )
& j, r2 y+ q p5 e( _ { m_lRefCount = 0; }
7 {/ e5 a/ M& q) ]# n; y
9 [2 x( g) {) I% O |
- ^& T. P9 c& d/ M2 i STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 M5 Q" m- w$ [7 } STDMETHODIMP_(ULONG) AddRef();
3 l" W: Q" P' L. I5 m STDMETHODIMP_(ULONG) Release();
* L0 r4 P3 _; g$ s( C/ W
9 ~) p9 B# \1 |' q
6 i+ J% o O1 _, A// implementation& L6 c" y& I# _9 w" D' ^
private:
2 s8 M* `- F7 `, x E% ] s" }1 Z HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
. c& ^' z C( J3 I* S* x8 Y# \) U HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
4 w# }" g2 Q8 ^2 F/ q HRESULT __stdcall SearchComplete(LONG nFindData);1 U! g. _5 p' O1 K; N( n7 s
( I7 r+ i. e+ |" c
: x) u- D" Z, c9 }0 A2 ?/ F( O
private:
7 H/ A x$ J* C% h! C: D- i" L, u CUPnPImplWinServ& m_instance;
- l) | i6 T \# t' {( d/ X( N LONG m_lRefCount;
/ ?5 F0 {# `) w Q) n- j};* O+ a" b7 @ A" U2 W
: C, M; q6 g( h
/ C6 Q% Z0 c1 C: S" V/ `/ b
// Service Callback
5 v/ L K4 u& a" F& kclass CServiceCallback9 {; P7 E R' ?) Q) }7 X% A
: public IUPnPServiceCallback6 \* d9 w0 j0 d" f, Y, i# ]5 b
{" u: G8 t. L% V% Z' { c; U
public:% l2 a9 w) S3 j2 f* V( I z7 j
CServiceCallback(CUPnPImplWinServ& instance)1 }8 K/ Y( z' N7 }! F4 P( m- L
: m_instance( instance )
# F; ]/ N) U3 _) A8 \ { m_lRefCount = 0; }& g0 s2 P+ s7 k7 J( V4 G
- e% T$ C! E7 I! @! s/ V/ w0 a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 F% e6 B( J! ?8 w% [2 z/ O# J
STDMETHODIMP_(ULONG) AddRef();' }$ o1 I. q j& p, b0 F
STDMETHODIMP_(ULONG) Release();; ^: N1 P6 r0 M) K2 L8 c9 l
7 i) G: w* y$ Z) H- p
8 K1 g* P; j/ g% L9 r. W M// implementation
- S5 [' F, t% ]2 H9 K6 o6 z4 _ Rprivate:
) _0 Y h( @; p* f1 N+ ?4 l: @ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
8 Q& G# b% }3 c* o6 V' _8 Z- R; ` HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
/ O* z. d+ S2 L- G* t$ Q
8 t2 Z Q+ t( m k; W/ A4 U& `8 l5 G
private:
( f" W0 b Z; `' K CUPnPImplWinServ& m_instance;
% V" m; m2 C4 { S7 _ LONG m_lRefCount;
) O% V: @: ?$ [$ M k8 d" |};
' S: R2 d- P( D; ?1 x
. Y. t9 E! T6 c
( X6 ^2 ?# m% L* E* b+ ?& a/////////////////////////////////////////////////( K2 l8 s# D& |1 j+ f2 b& z2 A
8 {. u: H' K s& O! k @
7 B7 Z" n& E4 Z& u
使用时只需要使用抽象类的接口。
- n6 Y! S" a! Z) j! k& H C; mCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.& d8 v( c$ z- }% H5 L8 ?
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% P4 w0 S. ?# N) s }# H& MCUPnPImpl::StopAsyncFind停止设备查找.5 y E: @% ~9 Z4 ?7 R% Y# W' r; Y2 F
CUPnPImpl::DeletePorts删除端口映射. |
|