|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 J4 z9 e1 H6 J; x1 I- V& M+ x( N/ V/ G
7 J' N- R: ~" w# L
4 E, G* u. k5 ~///////////////////////////////////////////
1 ^& Y* `& w4 T3 j, H( S* Z. }: }//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
% d6 k8 t- f- m/ X
f- I) ~- z: |) H d5 F2 P
' O) L! h- W2 w; O) R) Y8 ]#pragma once
- b2 j, X* R' p+ F9 o+ \4 ?4 [#include <exception>
# L1 _9 S- `8 {: i% P9 A1 P4 Q6 S. c; D, }
- Y' b, J& i; H& C
enum TRISTATE{+ |1 w" ?( F) ^) }6 Q) r* Q: ?
TRIS_FALSE,
" J# X# |0 x% }( S: ^4 y TRIS_UNKNOWN,
! v6 u1 a) c; L2 z* e' z1 I TRIS_TRUE# i2 D( Y- z6 t/ _/ ^- Z5 B0 v
};
1 L% X7 n3 {6 I& n4 o
+ ?: l6 V/ @1 |3 @- Y1 O5 P9 B6 s1 q- {1 V4 l/ x5 s: y
enum UPNP_IMPLEMENTATION{/ }+ }6 e) F; I
UPNP_IMPL_WINDOWSERVICE = 0,
3 Q" m: s. y8 z: V7 N" ~ UPNP_IMPL_MINIUPNPLIB,' F1 L+ N! P- H9 g* i7 r
UPNP_IMPL_NONE /*last*/( f8 Q. I6 ]$ _( e; Y# z, J
};! `: x9 p0 ~* j) @! v! ]
' `. x7 X9 r5 E8 F9 o1 ~5 U& Z) B" u( i# b. s4 p, f
% W6 I( t0 _( a! f/ E+ E) ?: I9 Y5 ^
class CUPnPImpl+ u; G" N7 L; m6 D! r# h
{- w9 k D2 X# P+ T3 l
public:. ^% N* Z* w; s' m# c
CUPnPImpl();# r7 o& y E& D- S
virtual ~CUPnPImpl();7 U: X3 J+ \- G* i; J& _
struct UPnPError : std::exception {};% P$ g: k; I! }' @
enum {4 p9 b4 @0 A( h- i
UPNP_OK," p. c: v- J6 [# r( e% A5 R7 O7 T
UPNP_FAILED,0 e! z1 |4 B; m4 o5 ~2 e- C P: x+ l
UPNP_TIMEOUT* J9 O3 ^7 a; X. V# K" t7 O9 f2 ?
};# O- N/ M+ G- F# V7 Q( B0 v5 n
/ ~- Z2 b* V; ~( u+ @; G
" |, h, n9 R4 B% f4 a* Z
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. A( x% L! o: b9 d+ B$ x
virtual bool CheckAndRefresh() = 0;" b) u. H% B2 N$ S' {& F& p2 p
virtual void StopAsyncFind() = 0;
# r! P1 |. f: F' F virtual void DeletePorts() = 0;
8 l& r! @3 k7 H- }# M! v virtual bool IsReady() = 0;5 k$ ]& p4 [+ W5 b! f8 ]
virtual int GetImplementationID() = 0;
9 V$ E) w2 K" x& c! e ; T6 g; e) \+ C* I" ?: s8 x
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" L8 Z. g' {8 V
& w( V, F2 S( w; T* U$ I: T; o- N. d
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
1 ]$ ?1 }% u3 h, i# U TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ z9 L/ C6 F- `% D0 b7 ~- I! @0 V uint16 GetUsedTCPPort() { return m_nTCPPort; }
8 `5 O4 Y9 l( u1 I uint16 GetUsedUDPPort() { return m_nUDPPort; } 0 H! G- _' {5 F! G- L9 E
' B& ^8 h+ `4 ]/ s4 A
. O* L. L9 ~. Y7 X; t: s// Implementation0 w' I3 I3 ~6 L. M% z7 X
protected:
/ n( B4 ~* j& M volatile TRISTATE m_bUPnPPortsForwarded;
7 b; [3 L6 S6 D8 ?# G2 ? void SendResultMessage();
! H4 C0 r" {9 n/ M uint16 m_nUDPPort;; g0 h% C. Z; K6 q C
uint16 m_nTCPPort;! H9 |- S4 Q) n2 Q" L0 }& q
uint16 m_nTCPWebPort;& i' I2 I7 _- x
bool m_bCheckAndRefresh;
9 ~9 Y" D, {( U6 E/ h, m2 ]" y! K f0 x' Y& n
5 S$ V2 A, f4 b# C7 v' kprivate:* k. A) p, a9 `: i# K3 h
HWND m_hResultMessageWindow;
4 R+ {7 A0 |9 ` a UINT m_nResultMessageID;
9 @ d1 I8 V* ~, W/ F# S; O/ P# g0 S+ C2 W9 I: i& e3 E5 B
+ w; {. Y. Q2 [( ~
};) Z" c, v* Y1 i- o; F
j* O/ t8 v% N6 Q& E. h. j/ i
// Dummy Implementation to be used when no other implementation is available
4 Q0 l1 A8 F6 z4 O' jclass CUPnPImplNone: public CUPnPImpl M$ x! x8 O( J5 ?4 }
{
' ?! m6 V# p- p8 o( rpublic:- X( v# j. D. r3 ?4 f
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; `" w5 n- c, ^" \2 a' l
virtual bool CheckAndRefresh() { return false; }8 G: K6 ^0 O, ~9 O. v
virtual void StopAsyncFind() { }
. A! X0 h% R# e' v x* c9 x6 u9 q ~, V) y virtual void DeletePorts() { }
: M) `* e. y' }! t virtual bool IsReady() { return false; }3 I0 n$ U% z2 Z) y- h) W) T
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
( d1 h. C$ J' ?; }3 x' v};
5 i- t4 E9 j/ [2 S
) p% t9 n/ `5 o$ k; c4 ]
* r- o8 t" {' e( G/////////////////////////////////////
0 E0 m; s. Y y2 P* g, V7 ^//下面是使用windows操作系统自带的UPNP功能的子类" N$ F' r# ]. s# h2 m% A) i/ O
i# o& l2 K) W0 L
: n/ l: ?# \ t' F#pragma once9 D3 f, B, P1 [% a5 g- C# _2 J
#pragma warning( disable: 4355 )8 ^, o% V0 Q* M9 N4 a: u
: I: G) e0 g) r1 F& C
# \, T2 g+ j! B# g8 b9 K/ S
#include "UPnPImpl.h"
) j, L& [% L Y* J#include <upnp.h>" }" N9 v( Y4 u1 c% X, `8 J
#include <iphlpapi.h>
! T' c: C; z) q/ V9 g#include <comdef.h>
4 X/ F& ` I2 C/ y' I#include <winsvc.h>
8 _/ Y k) ]" W3 V. `. K+ v
! _7 @% \& l% A8 B2 z# _
1 I- {$ E+ f8 n( w#include <vector>
% p4 C0 I6 |, z7 S6 T5 o% Z5 h k#include <exception>
8 g. v0 t1 x1 F- [#include <functional>
! Z# b7 j. f0 d `7 i( |; i$ `
0 e" `! I( ]# ^7 o" Y0 L# {' F
. \; i3 d9 K" X8 f& Q0 G: j
: R+ t1 U0 d1 \4 Q2 ?
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;* |& G ~ n: L& t
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) E9 C a' p6 {) q- B2 ^8 P
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
3 C# B+ q" I( Y& dtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! {# y' G- T4 v% i) g3 Ttypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
, V) R0 a+ O; U/ ~typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 Y8 O2 `3 ]$ c0 ]" O. G6 Mtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;: ~- [; o+ X; L
- o$ ^# {& z0 B3 j" J5 H: a
9 R6 k# ^! r8 E4 {, S5 T4 D* _
typedef DWORD (WINAPI* TGetBestInterface) ( X. d& \, O3 l5 e7 J% Y
IPAddr dwDestAddr,
: i* m* J: H" }- g* d PDWORD pdwBestIfIndex
$ o: K% ]( ^% i8 M6 G- Z: [( V+ W& O);% Z. e# f6 O$ T" ?
% d, j9 I# h. Q" J0 _! d
* m% }# ~6 I. ]% N4 x
typedef DWORD (WINAPI* TGetIpAddrTable) (
- H7 ?+ f% L8 D6 r4 D: i; ]2 y9 h PMIB_IPADDRTABLE pIpAddrTable,
8 k4 f8 M" t; H4 k4 U% h# Q PULONG pdwSize,& @, Q/ Q% E7 f9 h5 m
BOOL bOrder
9 U% v# @4 ]- p* ~);
! Q3 Z% M6 U% ?. ^ L# v& m; u+ R; h. x, b0 O7 M( J4 f
2 G3 {' ` C8 _0 k% x0 a9 {* f1 L
typedef DWORD (WINAPI* TGetIfEntry) (
* Y2 N) T6 s- _- q" X% L; S PMIB_IFROW pIfRow
D0 N, ~! M! i8 A$ R7 h);
8 w8 A3 c* i9 \
6 R9 {0 X& j# c5 G) [3 m$ ^, v9 s# e. w/ } b
CString translateUPnPResult(HRESULT hr);
- }& }# D- ~- B& t: E' U; b! PHRESULT UPnPMessage(HRESULT hr);3 Q) K7 N8 i9 I% W: T. d7 t
5 x9 m9 z' ~7 @
" Z' D! K) p$ `$ m+ i) V8 b
class CUPnPImplWinServ: public CUPnPImpl" r$ E# W; q& }' W* c
{3 `; K- Z) Z: ~1 D, r
friend class CDeviceFinderCallback;: M' P7 q( Q& \
friend class CServiceCallback;; G; H% K& J( O; d7 b* _
// Construction
) x) b7 m9 o& C `- r6 rpublic:
9 a6 i W* @! H" U' |; [/ I& _ virtual ~CUPnPImplWinServ();
/ P7 K: }% p( f9 T; R% Z CUPnPImplWinServ();
3 s! r- ^' Q5 \/ _( K; @' @8 u A
: A9 ` l0 d+ H" T, p/ p9 D; C' M, w) Y& t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
$ ?( S3 Q/ A: h z9 F virtual void StopAsyncFind();
9 Z# v3 P7 w' ?9 x8 N virtual void DeletePorts();8 ]+ ?5 W: K5 k. {
virtual bool IsReady();
~! I; [6 r$ g2 P virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
3 l$ Z! K& S5 r& ?5 _
% s. n' T# ]4 z) d: U0 p" {5 ]( D0 e, h1 l' U; f, f
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
$ t5 U. ?0 o; [0 ~2 h4 w% T // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
. ?# o# {0 Y" j/ X9 F virtual bool CheckAndRefresh() { return false; };
, m) d! i W _4 [$ z+ }/ f2 b! M7 a% Z* c2 l
5 Q) D3 j7 U: S8 [2 S3 L* Zprotected:( W! C6 Q6 l' H4 S8 E" P) l
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);8 t/ p2 D* H1 p( l
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);) O2 ?! r9 h3 S. H* p1 v6 n( ~
void RemoveDevice(CComBSTR bsUDN);) n4 v# w- d/ J+ @6 a
bool OnSearchComplete();( q# o0 f8 ^6 ~
void Init();8 Q6 _- b) ?! q* I6 S) W
$ k# e7 d/ }* F6 U _/ _! P, z! c
3 s( d. {% Q, V4 ]" d; `
inline bool IsAsyncFindRunning()
8 Z9 M* o& z" e) J1 Z. | {
3 N* B, |* d7 x G0 |" O/ T. I: v" | if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )3 s' e& K$ @, @! `
{
# Y8 A: U4 ?2 R$ {) b) t0 s( n m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );% B: y) j* A" e8 k
m_bAsyncFindRunning = false;6 o( P* g" @9 x
}
- b. p* U6 d, s/ b4 ]. ~4 I MSG msg;
/ f% A2 B3 O$ P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ): |1 I/ K$ J# I& p
{ r& O$ h+ z4 ~' ]
TranslateMessage( &msg );3 C6 j% ^9 Q& |! M: y. [% \) R3 v
DispatchMessage( &msg );
: X. N7 J6 d% d4 } }( b- |/ p- W, K
return m_bAsyncFindRunning;0 W8 Q9 t( E% [( @
}
' b0 y4 o6 H* r6 H. m! y5 R J& D* r6 _1 S: j
3 }1 F% E, a9 [2 n TRISTATE m_bUPnPDeviceConnected;4 m7 q/ m7 h6 y/ K. F! o) c" `* i
7 S1 N3 @0 R t3 ] P( E
& [* s( c: S/ L5 k// Implementation
4 W0 N: z2 a. ^" |; t9 N // API functions
' j* ^6 I# d$ ^% u9 @4 P' E SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);7 R- @: u6 `0 n# C
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
/ k$ X8 C$ X; Z/ m2 h6 U. H BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);# @2 l+ J1 _9 U2 E2 T4 V ?
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
7 q" _! P! h) _; e! \ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);# U- ?0 l, V3 K) \
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);( b. J# W5 c9 D* A$ ?& v0 Q
: ~& n$ Z" [! b6 `( B
, ~- x( E3 X( n TGetBestInterface m_pfGetBestInterface;4 o! ?2 Y; W+ h' J
TGetIpAddrTable m_pfGetIpAddrTable;
i- m; K t' J! D6 { TGetIfEntry m_pfGetIfEntry;
M$ s- l9 J' S5 E0 z+ d# {' \' X {, x/ `$ P' ^: s
# T+ H7 M, F/ Z0 U" N
static FinderPointer CreateFinderInstance();$ _0 K3 S& H4 ^
struct FindDevice : std::unary_function< DevicePointer, bool >
, f! Y1 U# |# q {
[7 ~5 S; y( L6 o FindDevice(const CComBSTR& udn) : m_udn( udn ) {}$ O4 \8 j; r/ k9 G$ R7 v& M! U
result_type operator()(argument_type device) const' \) O& | A& t W* U; }
{- v& W' q2 J, h r s
CComBSTR deviceName;
; c0 m, \* f; \) x0 |/ i HRESULT hr = device->get_UniqueDeviceName( &deviceName );0 L" S9 }( I7 q; `$ J" Y
4 B6 z4 M& f; X! c L! m% v
1 ^, J5 \/ v* H% `9 l9 g if ( FAILED( hr ) )+ f: X3 f4 k: e1 E. C7 h6 l
return UPnPMessage( hr ), false;
4 e+ M) C9 d6 I$ t" x; o& c+ v0 R7 w
1 l1 P6 {3 K+ f7 @; V2 a0 ]" @
return wcscmp( deviceName.m_str, m_udn ) == 0;' c7 T; M& p5 I, j# \
}
. Y% Y" Z- Z+ v' O: P CComBSTR m_udn;
2 v @' B/ |7 m% ] };
5 K+ ]& J/ {$ b ; q6 d4 f6 v2 o' E% d
void ProcessAsyncFind(CComBSTR bsSearchType);& [2 s# ~' b) f* S) p
HRESULT GetDeviceServices(DevicePointer pDevice);
) @( R3 T% h9 S& a. ~- z# w void StartPortMapping();% s+ o* {- m$ K3 P" V
HRESULT MapPort(const ServicePointer& service);! _0 ^: S( D( E5 r
void DeleteExistingPortMappings(ServicePointer pService);
4 X V5 Z" A: ]3 E void CreatePortMappings(ServicePointer pService);+ `5 F$ J: e5 L
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);5 e) t9 ~4 ?5 ?6 w. c/ p6 o
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, F5 s' ]9 F" G( L% c5 P2 ] LPCTSTR pszInArgString, CString& strResult);
' T$ F5 l3 l! N% j void StopUPnPService();, C) ~$ r0 J2 f9 y
$ r) ~: c, K, ^& H) x
$ z* G/ e- _& j. C& P- U s6 \ // Utility functions) v+ Y4 W3 X B; u9 E3 e8 X+ ]$ i, t
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
" H5 Q6 f. b- c- @$ h# \ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);! i1 O7 _( G2 P: E5 |# Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
/ _1 I4 w1 R9 p+ Q; O void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
: P% q ~4 i! J( J HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);3 i0 g: g. b- K+ q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
9 ]: b: @1 [, J( y/ f6 @% g' P' ^ CString GetLocalRoutableIP(ServicePointer pService);
' ?; W5 u: y; L Q" ^) C* S2 [4 I4 u) f: y3 d+ G3 c# j+ o0 o4 q
5 S- o6 z9 S: C+ _9 v// Private members
/ r9 A1 h! L: i3 P- I/ Xprivate:
" I7 F# J( O+ A9 L1 A DWORD m_tLastEvent; // When the last event was received?3 a+ R9 z: v1 ?
std::vector< DevicePointer > m_pDevices;% z* z2 b! [- }4 O
std::vector< ServicePointer > m_pServices;
" m5 g1 A- S6 t1 q: m, W FinderPointer m_pDeviceFinder;" r$ ?! B! G2 q* h# }' r6 X$ x$ T) f
DeviceFinderCallback m_pDeviceFinderCallback;
" O/ t0 J0 w N7 E ServiceCallback m_pServiceCallback;
: l1 d; P+ R# p- `& n
2 M3 E2 v9 H4 j" K- N: @5 D
- ^4 q1 H! \6 T5 w c' V8 [ LONG m_nAsyncFindHandle;: H5 @( w( Z; f: b9 `; N: k
bool m_bCOM;
+ v, o# z/ l- I$ p* w1 e: T bool m_bPortIsFree;
4 k' O% c1 P; r% g CString m_sLocalIP;: o% B, Q" {3 y
CString m_sExternalIP;
* i) J0 a) u: a' @& ` bool m_bADSL; // Is the device ADSL?
" W; G, U) ?( B8 \2 ^ ~( j bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ q7 l! t2 b% M) `. s) B bool m_bInited;
2 s+ z8 y1 T+ [; V- |+ I$ z1 K6 q! t bool m_bAsyncFindRunning;
& W+ m0 Q) X' H! P& | HMODULE m_hADVAPI32_DLL;6 b; O m% P' E& q
HMODULE m_hIPHLPAPI_DLL;
8 r# ?# [: o1 i [4 c bool m_bSecondTry;
8 S2 I3 D, r0 d7 a0 A bool m_bServiceStartedByEmule;
1 _$ F6 j; i% S# z& L- q bool m_bDisableWANIPSetup; { H4 ]3 q( ~8 r
bool m_bDisableWANPPPSetup;7 X6 f" m/ m1 e0 s- v7 {% }1 L1 C
( B8 ~" }( w2 i9 j+ ] V5 e
' W: i) _" e( J' E};
# Y- B: f2 W+ E5 d/ y( c6 E5 i# ~+ p" S* Y# H
1 S6 C, J, d( r- m$ n" m
// DeviceFinder Callback! x t b4 Y0 G% a* o; C/ a
class CDeviceFinderCallback5 O. C, C4 I' i; {/ s6 u1 z6 W8 A
: public IUPnPDeviceFinderCallback! U) m, I: Q' t& U
{1 B6 u3 e$ \# @3 Q
public:, C3 X+ n0 t0 e: t$ P! n. A
CDeviceFinderCallback(CUPnPImplWinServ& instance)+ b" a* n3 {7 D! h
: m_instance( instance )
: X9 M. ?& U, @! [ { m_lRefCount = 0; } R M* i o1 w0 Q
- h' K0 C0 k5 ]" {4 R* V& h% Q
- [' g: u ~+ o6 n6 Y4 m& a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);* b1 { C. g7 H: z5 T4 ]
STDMETHODIMP_(ULONG) AddRef();" U; G) H0 m3 G
STDMETHODIMP_(ULONG) Release();; J' S& b, A1 F
3 R0 v% O2 U* n, s; x2 _$ K, W/ K9 [4 c
// implementation
" Q/ A0 v8 i8 o" }, J; q' Kprivate:/ O. }8 B: ^8 R9 i9 {0 f
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);% g. k( c6 Z1 h3 I1 G( P
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);) B- j' k6 \8 T9 ?" Y- F& h
HRESULT __stdcall SearchComplete(LONG nFindData);% S2 D* v/ K" R! i: d
$ l. u2 x- `- O, h1 h
' c' ?* ^' t1 z! r W& u
private:
t0 O) i* V' @7 h2 R$ Z CUPnPImplWinServ& m_instance;3 t6 J( c, r' P2 V# r, g
LONG m_lRefCount;# D4 j, _1 Q& [# q1 e; w
};, X* y* m9 b0 {
( D- i R% ]& ^4 s+ G! J/ F S
5 P, ?. Z \7 m// Service Callback
$ [( s" w% H! A: x7 J% w3 Xclass CServiceCallback
T) ^. m" D, |6 T4 r : public IUPnPServiceCallback, T5 D( ^, t/ {' ?
{0 E8 o( E& j2 i
public:
$ j8 j5 q2 [, l6 D B, p( k CServiceCallback(CUPnPImplWinServ& instance)
9 c# K4 M; O: Z7 ?/ M : m_instance( instance )
( v( B8 ~$ [# J3 g* @+ q { m_lRefCount = 0; }
8 F" s x! L- U1 O2 i6 G5 F
t8 ]* g* }& g# M* V: X6 @ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, \# U% k: W7 m; z( O0 Z STDMETHODIMP_(ULONG) AddRef();
+ a* _$ T% I# u( b: \ STDMETHODIMP_(ULONG) Release();/ [4 m1 I$ Q: d
8 s3 ~$ } C4 h$ E! G
+ H& o0 ]1 u/ {3 i6 y" g/ ^// implementation
" K% w/ c. z) L& C4 Fprivate:
c. X' ]' u9 D0 D HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
! {, p9 d9 g- u7 y: e" C' ]5 I( s3 p# ? HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
% M) `$ c1 s7 R, @ r& \) |. T. Z1 m4 l, D
2 l1 `+ Q1 Y* d, n
, `2 U/ B* j, U; X0 l, Y9 ^; s9 Oprivate:; C3 o% N" M9 @
CUPnPImplWinServ& m_instance;$ e5 u; m+ [/ K' V+ ~, r
LONG m_lRefCount;% O5 r! g* y# O( V9 h* K
};$ D& q. ?9 }* k0 ^
1 Q' w5 W+ g4 u, ?: i2 t7 e1 _
$ @+ a, Z+ D9 B; m7 v3 ^0 o/////////////////////////////////////////////////+ Q7 n$ { t, G( v( G( M2 \
- Q6 h; B* \, S& |3 e% d2 d% p# L& P9 y+ r8 @: ^( A( f8 y
使用时只需要使用抽象类的接口。& d) g3 b+ X% J- v
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: p( t% p8 O" l* j
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! y- d' K& z L" C/ d ZCUPnPImpl::StopAsyncFind停止设备查找.
@* W& J) ~7 o$ @( ?+ \) |CUPnPImpl::DeletePorts删除端口映射. |
|