|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,# ~, J$ K L8 O+ `7 T# h9 A
; V# O8 Y! w% S# K% A, e
" r3 v- ~; j( Z
///////////////////////////////////////////
; ?2 b1 p1 z* ]2 E//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- [+ `9 A4 S4 k0 p& _
/ B8 F) A4 R9 s0 a3 k r; E
; ` [. w; t- C( ?#pragma once- U! @% V" U9 d6 h7 S
#include <exception>
% I+ {$ ^! A: c: q H, j6 v, ~# b- x- |# S& J; F
2 g9 |' y# G) s$ @" `3 d& | enum TRISTATE{
4 ^/ }' e; s' e1 C% {8 R TRIS_FALSE,
' y% o: W6 T4 ? L1 V TRIS_UNKNOWN,
/ {" x$ G% x# P+ Y( X6 b- T( Q TRIS_TRUE
* C8 @$ X4 W2 z; d7 w};
% ?/ H5 Z0 s: D6 t) O) Z3 p
; x$ E. { k" b
5 D/ g5 j B% e& w& Wenum UPNP_IMPLEMENTATION{" ~# t( A9 x8 N% [% d
UPNP_IMPL_WINDOWSERVICE = 0,& u/ N- @) _% }5 i
UPNP_IMPL_MINIUPNPLIB,# d$ I, B; B9 p- C
UPNP_IMPL_NONE /*last*/
; [' P- c6 m/ c& J2 O" |};
/ `* T# p6 Y! X
$ d ~% k6 ^) `# X: ]9 j
8 @ p- ^6 A8 f0 M' D; s
d, n9 b( P6 B! n! Z$ j9 e9 H0 C, u
& R1 ]8 @. F9 ^ w8 vclass CUPnPImpl
- a, |, \; [! _, C9 N- s4 ~; ~{ H2 b9 V6 @; h. P
public:
( j/ s' B9 Z" L3 U- p CUPnPImpl();
9 J5 S/ a5 a$ |) d# N% [" N virtual ~CUPnPImpl(); S( ` z2 D& `) \! e
struct UPnPError : std::exception {};5 b; p4 B! j4 z w/ L, Z
enum {/ y0 [% \& ~4 A( O2 |$ E3 _* \
UPNP_OK,9 G7 J# x- Q! k2 ]( U1 @4 ~" o0 m
UPNP_FAILED,
3 y0 z$ L/ c3 T4 V UPNP_TIMEOUT# A* w5 d5 f4 H
};
3 G* z. r* `: x' O! L& O( u7 Y+ k' L3 J9 f9 W
/ q$ c% @# p; V' a7 K
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: e) Y7 Q7 L. P; T; ]" K
virtual bool CheckAndRefresh() = 0;
9 J' l# t9 D7 g8 N. B9 ~ virtual void StopAsyncFind() = 0;# ^2 O. s0 G X- ]; `3 N0 t
virtual void DeletePorts() = 0;
. q7 f! `* G6 F# z9 O3 v virtual bool IsReady() = 0;7 w( ^* x0 J4 \; k
virtual int GetImplementationID() = 0;
- m4 u3 O' Q, g4 ?2 F. u . ]& F1 \" V- A
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping! M9 P9 v4 \7 T- P. U- H
- q. M5 P' j5 F& i) a6 m
3 ~) S2 e0 U# q. k" Z( k
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
R( A! U D* a; Z3 f TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ w$ l2 E1 r0 r4 \; `
uint16 GetUsedTCPPort() { return m_nTCPPort; }! L! Z0 c7 ^0 U( \
uint16 GetUsedUDPPort() { return m_nUDPPort; }
6 D @2 ^" G' n) R: ^! y5 p6 _$ h0 k3 U$ Z- Y8 y
( d, B" i J4 S
// Implementation
' T6 ^; p# R1 t0 s# s: @protected:2 } f( |* D! R" P9 N" c. W# l+ A
volatile TRISTATE m_bUPnPPortsForwarded;5 b+ ^# d7 G* a* ]5 [" F' L
void SendResultMessage();
/ x$ L9 O) x# `; {* [! v# l4 x( K! y uint16 m_nUDPPort; B! D' ~& K* H) L$ c/ X
uint16 m_nTCPPort;4 j) L; w0 @; W7 r" y9 F) ]
uint16 m_nTCPWebPort;
6 y. s+ U/ M2 }5 ~4 l bool m_bCheckAndRefresh;0 V7 u. q N1 w
: Z) p% \7 D+ [, ]( f1 t t
' G6 S* b* v1 D" k! mprivate:
, o" a8 Y* E6 I- n$ L8 w, j HWND m_hResultMessageWindow;
$ D$ e l. Y5 ~4 [3 @9 C0 h UINT m_nResultMessageID;, h9 j" F7 I( l, D% m
) N- e% ^; _5 i0 u+ |! B
; C; z1 G" I6 n: P5 c0 T3 i
};
# T& s; T$ i6 G/ l3 R' P; p8 t
3 e" n3 i6 b, T: F3 Z. D3 l4 f/ L- L6 C/ }- n! H
// Dummy Implementation to be used when no other implementation is available
# i b5 _4 Z9 p0 aclass CUPnPImplNone: public CUPnPImpl+ X, R* }: R5 {$ m- X
{7 ]% a2 I+ k. j+ w
public:
$ T7 C5 [% B- r! u' I) r virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
# Z# m: ]" \ d0 s( s$ o! ~ virtual bool CheckAndRefresh() { return false; }
' D, g- i8 Y# W# @7 r virtual void StopAsyncFind() { }
* ?2 @( d2 C: ]$ {6 _ virtual void DeletePorts() { }
X! L I2 U% |+ D, v virtual bool IsReady() { return false; }
! `1 t! b2 T" V9 b3 [9 V virtual int GetImplementationID() { return UPNP_IMPL_NONE; }9 ^9 X* J! ?- m, c1 @
};
a3 o3 y0 g& T c$ P+ E" [8 J
& Z$ w9 v: v& Y, R ~' [% _* w u/ I# m: I1 P$ `
/////////////////////////////////////
' p( h. B8 {+ X4 s3 V [//下面是使用windows操作系统自带的UPNP功能的子类" B/ V9 R) G+ _) N6 M$ F
6 u) S3 v" r6 y" f
8 Q" H ^1 q8 |! n D7 m! `$ `5 {( v#pragma once
+ ^8 o+ s; v' h5 v#pragma warning( disable: 4355 )
; Y$ L- y1 F8 @" q) Q" \
6 w5 w# T% Z, l+ Q* _
B3 \! B/ n+ K% [( t#include "UPnPImpl.h"
8 u! E/ G j' f, ?#include <upnp.h>8 ^: f1 `) E0 \2 A
#include <iphlpapi.h>
, ^* G' X- P* \* @! Y+ }#include <comdef.h>
8 A, ^& J, a: J( ^#include <winsvc.h>
: d9 Y' | Y$ P$ Z# i. Z* b/ h" V0 M$ K# s* x8 s
# z) n( h5 t, ^4 \! C- o- ~" {
#include <vector>
7 s& W4 Q# l! t4 T* |#include <exception>
% C4 {" X0 R; k( H* G3 n#include <functional>+ p0 M4 K: I, a- v: Z T* v
) O Z O: p- e/ |7 u( L# N0 @" V1 f1 @7 D7 S
5 W/ ]% W" l6 ^
* s3 f. f5 ~7 jtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;- g' ]! A8 H+ q0 _( Y p
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;! n5 ]7 c+ F( m9 ~1 \% d4 j/ Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;. V: ^" S3 r- r
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;8 W; H1 k, K# V3 K# {+ I
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;8 L# u: E8 w2 o( d' ^- A1 Z. n
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 p4 N/ ]' Z/ W) h
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ `. Z7 E; ?. g/ k$ o E
! L% N l0 G" f7 | I
2 w& w: E% y& w: Utypedef DWORD (WINAPI* TGetBestInterface) (
) T8 R) p1 Z, u$ G IPAddr dwDestAddr,
, i0 i C5 N* z, _8 e$ J6 J PDWORD pdwBestIfIndex
: o" v9 _0 T+ |4 _1 |, n);4 j- c' ]; l' ~
; p: k0 ~$ W& ]! t
" a' S, o/ E: Q5 Btypedef DWORD (WINAPI* TGetIpAddrTable) (1 @5 Y! H& y1 o. i: x6 D
PMIB_IPADDRTABLE pIpAddrTable,3 ^9 r6 H2 N& d. R" L" k
PULONG pdwSize,
0 i5 |# a. t1 _- A$ d5 U! X; U BOOL bOrder5 i6 D% v% m- K3 K$ F1 [
);& \, P& ^9 Y+ h( Y* d
]! s+ e9 \) a* S2 L# n2 D ^. K p. U% l, z! r
typedef DWORD (WINAPI* TGetIfEntry) (7 R* b0 k* t* H6 J4 r/ C5 k/ Z
PMIB_IFROW pIfRow
' v ]. ?5 b- T);* [" M6 e" H7 i) y5 c+ ?0 d
6 S4 `3 W) J+ l+ R( A1 V1 a5 `
! S5 N/ h" [" e9 z zCString translateUPnPResult(HRESULT hr);
; g, ]. g. @# k1 U9 J6 xHRESULT UPnPMessage(HRESULT hr);
$ [4 _/ G5 o5 s9 l, u6 f `3 D6 P1 D" C& D; H0 `
. G/ c1 h) A% S* a: ~# y; A
class CUPnPImplWinServ: public CUPnPImpl- x1 U5 P c$ _9 Y3 F
{
5 G3 U9 ^6 {, A% U! a friend class CDeviceFinderCallback;
: a* g$ O6 K: i2 n8 c8 J friend class CServiceCallback;4 |( g, `6 C% k S8 x1 N# C) ]; O
// Construction
; }. q5 r- J* N% f) t3 hpublic:
: W0 w9 d1 S3 [" u. M6 _5 f4 l virtual ~CUPnPImplWinServ();
! J1 |, H0 @+ g' k! D CUPnPImplWinServ();
- }% ^# J3 F1 ^2 ?$ v4 a1 Q9 J2 s# e% _' i: p
2 f3 z/ X' b# Y virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
7 Y0 G' [% p: u) i \ virtual void StopAsyncFind();( R9 v& A: A# U2 c6 P) P" g% W, M
virtual void DeletePorts();9 c; }% A- }0 t; Z' l
virtual bool IsReady();& U0 b* ]5 y, y( F
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
$ D2 U) f/ s" c6 h1 `! V# d* A4 v6 f2 _3 U6 O
& i' ~2 z+ r5 B$ `4 W$ ~ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
* ?7 f6 _5 M- h3 l2 ] // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 A" X0 m! [* J. }7 x virtual bool CheckAndRefresh() { return false; };* u9 e0 }1 R2 Z
e# p1 _4 j, ], n
5 Z7 M+ ^/ J% w% g. L. s; Z- R
protected:* N/ H$ ~+ m$ g5 D& [
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);% U( T) `1 G- S3 Q, K& d* I
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);8 p. J* V7 _6 L7 g/ |3 T% x
void RemoveDevice(CComBSTR bsUDN);' [. z* E9 Z5 ?3 C$ w& _
bool OnSearchComplete();
( f1 b$ L$ L$ g5 v2 B void Init();
6 D3 o0 m; u7 K% Y" b
3 s; h0 d1 K% Z) e: R2 `+ n; e" T G. V" N- k
inline bool IsAsyncFindRunning()
# \; ^) d1 ? U2 Q( {: l. S, t {
8 y0 E& b( h5 e- ] if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
. G$ z* L8 ]" k S1 U {- j: w! i5 G/ S% D" D' E% p% f
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
s& C) F; f' c5 [ m_bAsyncFindRunning = false;, F) ?5 K& l/ F9 }
}
; [) `( i% Z. t# b& s/ M MSG msg;
! E5 J" A2 y2 ]; s+ O$ r' @ while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )( j4 e4 t" r6 c$ B. ]
{- h1 B0 c- ^# @
TranslateMessage( &msg );
- G, f. {# x5 ]( g+ z# J& k DispatchMessage( &msg );. Y. o$ h ^; E) l
}0 @. o" B7 ^! G5 x v7 [
return m_bAsyncFindRunning;& i9 S7 }* D9 M3 g9 c
}
0 u1 i% b s: u( s; r# ^" D1 e! u+ W' p# ~
0 {/ C% ^, Q6 D! l6 x TRISTATE m_bUPnPDeviceConnected;( A! W, Y+ l& a: Y) l, y8 m
1 g/ K' ~# C( \2 `/ w& l
- ^; u% r3 t( A, w// Implementation' ~7 W) T7 T/ [( q0 y2 {
// API functions
5 V8 d! \8 u' X @9 J, X SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
0 J8 m/ R% W# o8 f0 r SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);4 ^9 Q4 g4 R5 s& n# B, x
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
N# j+ K! p8 }, P! }: O BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);6 w5 T! j/ F, Q0 Q% z3 U$ m
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);( d' h5 x3 J: Q2 {" c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
U& f4 f" o+ ~
) w2 U+ t6 K+ U4 A
- S5 M \* b, @7 |1 ]+ M9 F TGetBestInterface m_pfGetBestInterface;
' w7 ]$ X# {6 ?% `3 B1 }% q4 j7 K# K TGetIpAddrTable m_pfGetIpAddrTable;. N' N) X4 j; I/ d9 u; e
TGetIfEntry m_pfGetIfEntry;
+ v: W' o* y$ j
- G/ P, l2 }) @! O5 C2 x
- x. S8 T3 E. T5 C static FinderPointer CreateFinderInstance();
! t M0 S2 Z3 a1 L; P% p* r struct FindDevice : std::unary_function< DevicePointer, bool >
" ~$ e; X% g7 a4 y {
5 l# d4 U) y' M3 K0 L FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 E9 h) ^+ z0 [6 {, X' p$ J0 C
result_type operator()(argument_type device) const! h/ m% f/ R V- ^0 s. F* k
{
U0 s1 C+ m! E3 V5 n: T) m CComBSTR deviceName;
; x+ y# v; c9 Z" {5 j HRESULT hr = device->get_UniqueDeviceName( &deviceName );
@" V4 P' e- I8 Y. I# H' o4 ~. g/ a) \
& B0 g. t0 w: q; f
if ( FAILED( hr ) )
% X6 n+ a/ {5 D+ a% V. W. D return UPnPMessage( hr ), false;# {. f* |- O; f; W" ?8 C7 g
* F) c' r" B1 u9 v; _
+ N# E) G( ]9 P# X
return wcscmp( deviceName.m_str, m_udn ) == 0;2 i% f: o% p* B/ E1 z/ k
} Q0 v3 r( D: ?, \
CComBSTR m_udn;
3 V) M. x% d! O: k: ]+ W1 w };" B3 `% s, M6 d
" f7 U) v7 G% v9 _' [/ E
void ProcessAsyncFind(CComBSTR bsSearchType);
0 g- a: c2 l% d1 M/ V1 D HRESULT GetDeviceServices(DevicePointer pDevice);. x& w Z" G( `- @5 z! l. r. j
void StartPortMapping();
+ g7 S) f8 d1 {. f HRESULT MapPort(const ServicePointer& service);
9 n9 q- z( a+ W1 ]( q+ i0 r1 Z! n void DeleteExistingPortMappings(ServicePointer pService);
7 k6 Y) W9 w6 y! D: [ void CreatePortMappings(ServicePointer pService);' r. l0 R4 r# K$ g
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 H: \% n" {/ m) o: R& E$ k
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 9 y( o. Y: y1 p2 W, P
LPCTSTR pszInArgString, CString& strResult);
7 P& N4 d* n3 v3 Y- E void StopUPnPService();
( x: c' z) Y& z5 D. T2 B6 `4 w/ F
5 M! t: K5 D) l4 S. O0 m& n# ?$ C$ Q. W! D' P0 c: G9 D
// Utility functions
& O' G. ^& \4 H6 ~+ M HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
" H2 o; b% A7 f: ~ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);' W0 h4 ^! V% d5 _
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* _9 A1 U) K) v void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
5 `" s" K- A6 ~ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);$ Z. r+ P# Y% E9 ^. k
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 K# y5 D, y# Q CString GetLocalRoutableIP(ServicePointer pService);( t0 N6 c4 w) @/ u t! n
/ }8 V: Q/ w( o$ N/ m) v8 Y$ _% t
e0 y4 n8 p0 B0 }# D7 b// Private members4 Y+ A8 B/ w9 u3 ^8 M; ^
private:
% l+ v' z. b& d/ m0 k DWORD m_tLastEvent; // When the last event was received?
6 n d( Q) [, W5 x std::vector< DevicePointer > m_pDevices;
1 b' e! P) W' E8 f+ A5 | std::vector< ServicePointer > m_pServices;
8 _# m# Z' }) D- j( m9 j FinderPointer m_pDeviceFinder;9 i5 T1 X; X3 B8 _% z8 G9 h( H
DeviceFinderCallback m_pDeviceFinderCallback;
% Z. [' `" x6 O8 Z* c ServiceCallback m_pServiceCallback;& v4 u' v* u5 K" ~. I
* n" Y( s8 ?4 j; I) {3 F
9 \# z) `- l- U @. p LONG m_nAsyncFindHandle;7 _5 A. J9 ~ U* D6 {& U" F
bool m_bCOM;% N/ Z" Q+ j8 F. U
bool m_bPortIsFree;5 m5 V3 Q. \+ a; Z k: n4 I
CString m_sLocalIP;& X+ q( ~( J: e) _
CString m_sExternalIP;
" b6 I7 G3 E( P bool m_bADSL; // Is the device ADSL?
3 V% O/ ]# i- t* t5 u: c1 h bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 k/ k, f% I% d" y; M+ M
bool m_bInited;9 n% U7 ?% K& u( b! K, K* \6 z7 X
bool m_bAsyncFindRunning;; w6 _: z. B$ y" u: `. }! O& M k
HMODULE m_hADVAPI32_DLL; Q# O# o$ L/ U8 o4 N
HMODULE m_hIPHLPAPI_DLL;
$ e* N) i! _% |+ e7 B5 }. m bool m_bSecondTry;# R) Z2 N' m' Y6 |; c
bool m_bServiceStartedByEmule;" G* b& f P/ h4 `% L# n
bool m_bDisableWANIPSetup;
# R# V- K" ], | K" a# A bool m_bDisableWANPPPSetup;
2 I4 f% Z- Q# R# y* f6 ~
+ Z6 v; x1 T4 ^" G
7 ]% {( G1 W$ L' |7 I' ^4 h}; H$ q' M5 n X4 X1 l' q7 i% u
, u6 V, ]# }8 f; V9 f) A
- f/ x# j, F4 g+ ]// DeviceFinder Callback
) E2 ?; K7 M$ r& E% T9 |class CDeviceFinderCallback/ J+ }4 W$ U4 h3 ^( S
: public IUPnPDeviceFinderCallback
+ L7 @: v4 R+ n) }{
2 [. [, Q+ Y3 E5 q9 E; Jpublic:8 j% Q4 `+ d+ s6 T6 T
CDeviceFinderCallback(CUPnPImplWinServ& instance)
) ^& s X2 a: L1 q" N : m_instance( instance )4 Z" i$ z( @+ W+ q6 O
{ m_lRefCount = 0; } X% L+ I: H- @$ \
2 L, Y t% t8 i0 ~$ ]2 H0 T
$ k% Q3 k- M6 B" Q
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& O2 t! ^/ f- ^4 T# e8 k
STDMETHODIMP_(ULONG) AddRef();) t# v7 K, [ i, n
STDMETHODIMP_(ULONG) Release();; ^- w: b$ L# k/ d) h! l1 z, {6 U
$ }$ l+ m" c5 y) I$ O" ]
1 d+ \5 }. U* `// implementation; l8 U* D- P4 I$ w; W6 i
private:
! o. \8 a' k4 }( |' O& F HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);; A! U$ H3 m# M; T
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);" |4 d' P- j7 j7 d* M* C
HRESULT __stdcall SearchComplete(LONG nFindData);
+ ^; u" ~" L! p5 E: ~8 j/ j* K2 ~9 Q# p: j7 P$ p, j5 c
4 t* W; s ?/ g' S9 E
private:& @# U4 f$ i9 I! o( D
CUPnPImplWinServ& m_instance;
# _1 y& ^4 u) k" q LONG m_lRefCount;
d, H! _9 J& Q};5 f+ C, X5 Z' l& U0 U" j) j$ h
0 _- z6 k& V/ f. o4 Z6 b
, ?8 v L5 u; ]
// Service Callback
' R2 N* B/ ?2 T- Nclass CServiceCallback
+ v0 x7 E% t! W, Y* K1 ^ : public IUPnPServiceCallback
8 `/ h* r- O+ G{: S+ Y. h* ]' J% j, ~1 n" S- }
public:5 l& k: R4 j" f# F2 w' R
CServiceCallback(CUPnPImplWinServ& instance). j4 p. |& ^) }7 v* t
: m_instance( instance )" e2 L" j1 @ }, y2 [6 s
{ m_lRefCount = 0; }- {7 v9 K& D M; Q# f2 f3 ]; w
* I6 @, U2 ?6 ]1 \0 L STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- w) k" p; D! o4 b3 k3 m9 E
STDMETHODIMP_(ULONG) AddRef();
: h6 P$ h1 e# C% J$ l STDMETHODIMP_(ULONG) Release();
6 y6 r# P$ h9 [. @ Y
1 [5 U* W! R$ Y, A1 E" t; p- g
% r `' P/ k& V* ?// implementation
- l- H# l9 a, s5 gprivate:0 m9 r" ^6 I9 W! P F+ }5 e* \1 c1 o
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);4 s( m2 H6 e4 v# U
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" H/ ~; p8 V5 O/ k# I
" z3 w/ h9 l$ d _ i$ c+ u4 {1 k7 g f6 s
private:
- q$ H @; h: c/ G CUPnPImplWinServ& m_instance;0 j/ s# O7 J& B: P5 Z+ s
LONG m_lRefCount;
' J3 b1 I( G6 G$ F% D8 {5 o};% f8 d/ G6 q/ Z8 P
6 H1 W; [3 @* ^ R
, L1 a2 e1 L! a. ^/////////////////////////////////////////////////0 `, a* R, r0 U5 `
: V6 V# ^! ?: `9 _
* z5 Q1 _$ J1 D2 E5 y7 U使用时只需要使用抽象类的接口。
3 B/ [$ m) Y* X. a: F/ M, cCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.$ ~$ O, A z' T$ `; w/ K! h0 l
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.. `& U1 N5 T& t8 P4 O
CUPnPImpl::StopAsyncFind停止设备查找.) P) y: c# g9 V
CUPnPImpl::DeletePorts删除端口映射. |
|