|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 c( o6 ^9 g- Q0 f9 m+ v: B! E
/ Y0 h9 W+ F2 A3 | B# V, U
( x% j0 S4 t9 u///////////////////////////////////////////9 _* I9 w2 R5 @) `
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.6 G' P6 ^( L* T& @/ F7 O0 \# ?# [& l* W
3 P! X- N% Y# I+ w9 U n9 j$ k& S8 Q& _8 L
#pragma once
7 d% Y9 A+ A4 \+ ^#include <exception>
4 E+ {* |7 q3 _& J7 p9 T) t% k/ T6 ]5 R9 W' W
, Q4 Z( g- g" r
enum TRISTATE{
! r& T! ]/ k2 T* l$ a1 d3 N TRIS_FALSE,
f1 }, a9 _7 P# D) I. [$ E X' M TRIS_UNKNOWN, f' Q: f! d' E# j' W: g: O
TRIS_TRUE
. p) j# V1 ]1 V/ U- p};) ^6 N% s- R% g( L
: }/ y5 G& H1 ?1 E' C( i" `9 T/ {
enum UPNP_IMPLEMENTATION{
; f3 o: Y0 f% ] UPNP_IMPL_WINDOWSERVICE = 0,
: E+ N& n" U/ D+ u" Y- B* h8 j UPNP_IMPL_MINIUPNPLIB,
7 |5 ^! H) L( k% Z$ {' _0 X UPNP_IMPL_NONE /*last*/
2 m4 b1 n' T$ g& g. G) T5 F};
& j) }6 D" g r8 i5 I7 C
5 t5 C0 n" L7 d3 T0 `& [
- t9 q' o7 S0 V" H* n. {2 P7 b) j8 c6 o" m) ]/ m* L, X' O
9 M" d, ]3 C! _* x+ u) cclass CUPnPImpl
" \8 y1 K3 S2 F, B3 Z{4 A* }4 o0 A8 W. L
public:0 {5 j4 E; }4 S1 S
CUPnPImpl();
! L) Z9 }% s7 C8 Y$ V' b; B virtual ~CUPnPImpl();
3 H d7 G( s0 y* g# U struct UPnPError : std::exception {};# n% V# m4 _7 ~$ f7 F- Z
enum {
! M4 ^) ?; a! D* I. w/ j+ x UPNP_OK,
/ r% W6 T0 c) b! f- Q, ] UPNP_FAILED,7 E/ Z' H _: x7 q
UPNP_TIMEOUT7 ^3 ?1 j' S+ @+ J% `: b
};
9 y8 V0 `4 t$ Q8 b) n7 g& }; [% W6 [7 t0 r) t/ Q# j# ?3 r- B$ ?& ^
4 q+ D6 N8 z2 g2 a% U1 t& }& h2 M
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
, s; B/ M6 S5 X+ X z- [6 [8 x virtual bool CheckAndRefresh() = 0;: `7 H$ m9 [4 ?& C( I
virtual void StopAsyncFind() = 0;+ z2 h8 E" o$ S- O1 K
virtual void DeletePorts() = 0;+ o; |' a3 ~$ I! x5 ~
virtual bool IsReady() = 0;
" L$ d; h" g5 n8 @/ C# { virtual int GetImplementationID() = 0;2 E/ F* b7 L: X; `# f
2 V+ M" p, p, o4 M0 x void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping* T, @9 s% `9 { z: L
, U3 }8 j8 G6 i' B4 f0 i' x1 }
/ F C4 V1 i- N% t
void SetMessageOnResult(HWND hWindow, UINT nMessageID);/ d3 P' X0 [. Q. m- q
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }7 f, q8 ~( e! a" {, o. |9 r
uint16 GetUsedTCPPort() { return m_nTCPPort; }
' x. o( O p" Z" k) R4 G uint16 GetUsedUDPPort() { return m_nUDPPort; }
6 P, L3 _# F, w w" \: _. g) \6 _/ u* Q+ o4 I" b" u
. R9 l5 s% ]) p// Implementation1 n& X. G8 w$ V3 M+ ?& Z
protected:
( ~; d6 ? Y7 y. U; I( ? volatile TRISTATE m_bUPnPPortsForwarded;
( ~; K6 c$ j, b& z% N. o X2 g void SendResultMessage();6 F. u' m0 h, \$ k& F( F7 X8 q
uint16 m_nUDPPort;
7 `" f. r( h6 B uint16 m_nTCPPort;0 Q. f- U, o0 @# L0 K* [
uint16 m_nTCPWebPort;
2 T3 ?. D9 L. c/ ]* f* Y bool m_bCheckAndRefresh;
0 C6 ~3 C5 g! j( N, u, y8 V7 f& b& ~, K7 E
. q$ t0 S" r0 k% b* Xprivate:
* g; n, r' w3 M1 v# b$ S HWND m_hResultMessageWindow;
: Z% w% c: |! Z UINT m_nResultMessageID;
/ |1 e/ x; K3 y4 y; B3 [* Y8 V5 _7 u2 L. `9 j! r3 N8 _
7 F) u) o4 H* s8 z. U: L
};; L3 H8 P4 @: D9 s+ ^! V
$ H* U% v7 ^: s
! ~5 Y) |) p" l: o// Dummy Implementation to be used when no other implementation is available
' _$ F( v4 u# t9 r _* ~class CUPnPImplNone: public CUPnPImpl7 X1 n, p, e2 \7 W) w
{
) N( i" X) g6 m/ S1 mpublic:
, s; ]1 \) D2 M" E/ e# _ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
& ~8 Q+ j3 f8 L. E! x/ c' }$ O virtual bool CheckAndRefresh() { return false; }
" q4 F. z6 ^5 H( j4 x0 r virtual void StopAsyncFind() { }9 v! G6 @0 L6 M, N) }+ r' M4 |* A
virtual void DeletePorts() { }
m% k/ R# g) D2 n virtual bool IsReady() { return false; }; N2 R x9 A/ Z" ?8 \) V; k
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
& T$ T( O1 \" k; p) U/ F};( U! b- H+ \) R
- l4 S- h% Z+ P) ?: o; }) r
' s* u( H9 K( A8 Y/////////////////////////////////////$ D' X: h r5 u, K6 h7 S0 P, K5 U
//下面是使用windows操作系统自带的UPNP功能的子类6 `4 U9 ]0 F+ \% o
' P" [" e3 N& X5 B
! W6 S; X! t: q#pragma once' b7 M8 b: H% g4 _
#pragma warning( disable: 4355 )
: I% b. |% j, i g* Q$ Y; s
5 b+ u' X5 \/ r+ Y% V
' K/ l+ K A: M; h8 j#include "UPnPImpl.h"
; g& v+ f1 w, [( ]#include <upnp.h>0 `, {! i: i! \" _7 h
#include <iphlpapi.h>
: D9 Q5 o9 F/ }3 B- d$ a#include <comdef.h>
+ W7 ^. B/ d/ e- ?#include <winsvc.h>4 l4 J$ S# i3 i. c* ^0 e
% V& @& `1 @ J8 M0 \
$ N% X- ~, w- ?9 u/ ~ L. ?% }2 p#include <vector>* \' N9 c5 z: ?3 _3 u( | j
#include <exception>7 J# e& g0 R0 |
#include <functional>! L0 r: Q2 L5 D
! G- f8 J6 L. I5 ?' ~* X! r2 G; K8 w4 F0 K( b$ Z4 z$ y
* T A% N) ]. x' f
9 s5 ?" U% k- M8 u3 I
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. n( v3 |2 r6 i( k9 etypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; {8 M5 `& B/ B1 t! [
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;9 w+ Y7 U; Q) d9 W/ v
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
' j- ?' m5 \% k' J& K6 Jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# T) E: [" c& S+ C% d% [ v. ?
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 R$ u/ V6 P+ A, S4 I" G8 Etypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;( n6 j3 P" z( f
~6 i2 z6 Z5 d& t' T5 K& E/ M
( e2 O& [% Q) g
typedef DWORD (WINAPI* TGetBestInterface) (. d* i1 @$ V. d! N0 @5 Z/ X+ {) k. n
IPAddr dwDestAddr,
; _& y' e1 y, o. d PDWORD pdwBestIfIndex
8 y! O( D/ A o R0 [);- Q/ i& C3 L( X3 P/ _
% m6 s9 f# O: q& L% c
- j' j! i/ J1 d8 qtypedef DWORD (WINAPI* TGetIpAddrTable) (
! C0 i6 L5 d4 Z PMIB_IPADDRTABLE pIpAddrTable,! P% Q0 h; H4 r3 e' F
PULONG pdwSize,' i. [: N7 i/ _0 X
BOOL bOrder
2 o; Q8 o5 I* N9 B/ b$ M/ u5 p);
, X* X0 g5 j2 a, \) Y" s& S% B( a: b+ L: I6 I
0 ?3 ^4 f4 d1 U* Ntypedef DWORD (WINAPI* TGetIfEntry) (/ N& T4 h, l' C2 Q/ R
PMIB_IFROW pIfRow; d. L X% l+ s) i8 }( J
);
" |# ?4 o+ L3 ^: B
* ^* U9 X$ G9 n: M% u' {+ R
2 A0 a4 ^: d- d, X1 vCString translateUPnPResult(HRESULT hr);) j9 G7 ~( |+ a
HRESULT UPnPMessage(HRESULT hr);
2 k+ W" A0 }, I6 [7 B
# w* \/ H- a( t$ _) d1 K" d- J! x0 Y6 \
class CUPnPImplWinServ: public CUPnPImpl
! n0 t7 j1 u1 M' W# y* a{
r) L# o- N/ _% X( o) a friend class CDeviceFinderCallback;
7 V3 U6 ]0 M) l. k) E. ?6 X | friend class CServiceCallback;
- b% N" _6 O4 f( |// Construction0 n: |/ f1 V" ]# j2 j- j5 j
public:
7 b# F5 {' W) R+ K+ x* ?/ s* ^ virtual ~CUPnPImplWinServ();
, _; k; @$ o$ } CUPnPImplWinServ(); X: z( S9 u. [' i. r9 Y* [
% U- v. o+ ~$ L: c9 m; t
7 p/ f: y7 h H x7 v( M( s virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
8 t- d9 s4 Z# B7 j2 P virtual void StopAsyncFind();
" ~$ ?) l4 ]# }( h) s) l virtual void DeletePorts();% f; O" ^& }+ X3 {# \- R
virtual bool IsReady();2 j" U: h- g3 G
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
6 E1 G8 H: c9 B6 d% f- o
8 F1 l6 V: h4 `' K. V; `8 M- Y# b6 ]. y' u l) H, u
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
( F2 r" a% M% ^+ V' H: u- w- s // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later* @* h2 ?% l9 v& h g
virtual bool CheckAndRefresh() { return false; };
5 b4 P' h4 e! q' n
5 T, o9 ^) B7 c5 W$ Q6 L* j" d7 w$ h6 x8 D6 g
protected:7 ^# G+ _+ h( _3 }4 e
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
5 n; ~6 q2 s) J& s. x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& m/ E* r: d+ o0 ?5 L
void RemoveDevice(CComBSTR bsUDN);- b- E/ A3 ]4 {- \" F
bool OnSearchComplete();
$ N8 K6 q' h# B M, [; K. c void Init();7 K/ h* T) U; |. @1 @+ v& F
. C. G2 T. H, f& {/ l% L2 e$ {, a- L/ Q* ?! q
inline bool IsAsyncFindRunning() , z B+ w3 \8 ?' ]' k8 T
{
- o: x: X( a: B1 C# e if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )2 o8 w: o; z/ N, n" N
{9 Q" X" d4 f+ v( e9 i
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 U0 \# c* }$ j j' M2 e0 w m_bAsyncFindRunning = false;# }4 ~& w0 v+ G3 U
}
8 n" G* r# R+ c& v MSG msg;
: @! Y1 v: \3 Q( I* U while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )" b7 i4 I" e& u4 x* S9 r
{
L3 p: T. C, P8 [- w5 }% @ TranslateMessage( &msg );; ?# m9 r" R. \; R6 B
DispatchMessage( &msg );$ {7 x# k& ]* }: y
}
. {# V: r/ |' M3 }6 y& B return m_bAsyncFindRunning;/ [0 ]1 i* K" Q" u1 `% l& H3 u' n2 I
}8 x/ c2 k- ?3 ~5 |
9 D; ?3 j0 R6 M% E D
( O! I3 v6 V$ n* @& F TRISTATE m_bUPnPDeviceConnected;( x5 E$ c B. F% c$ e( A4 Y
7 o) l5 E. c, t+ d# ^& Q; b& G1 K
/ u. A+ n9 |' E1 p: y M1 d$ n// Implementation3 K4 x4 h7 r" [/ |' f3 i% F9 n4 t+ Z
// API functions) U. E' Q8 h3 [! W) L C
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
- h! N6 ?" W2 b L0 | SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);" c, u, K! p3 A6 ~# w
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);% E- R9 K z: n
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
/ y+ U4 B0 g- M BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);! g6 [. A/ o6 }9 l* y* d( x
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);4 C2 R' @" g1 {/ Z) q8 T
* [$ T) k( r7 [
, |- T" X' q/ x2 p! v1 Z: A TGetBestInterface m_pfGetBestInterface;4 b) K" M1 L7 \% V; f) h+ J
TGetIpAddrTable m_pfGetIpAddrTable;* F1 `$ p3 ~' c
TGetIfEntry m_pfGetIfEntry;3 _0 e1 Y1 y5 {3 J: U8 N
w. ]0 L* G9 z
2 t4 |9 P/ Q0 n- A static FinderPointer CreateFinderInstance();
. A6 y/ v y% F struct FindDevice : std::unary_function< DevicePointer, bool >7 D! s- u; r$ {: [
{/ J( a% l: m* E% s
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}5 n g' K% z+ ^1 ?; O
result_type operator()(argument_type device) const
7 Z# g& [( C7 @$ q9 a {
" a5 E; M% U- [2 U$ q5 |% A* ` CComBSTR deviceName;
8 m4 P7 t! W. ^% F- d) @: l HRESULT hr = device->get_UniqueDeviceName( &deviceName );" |) B- A- O# g. q
2 @5 n+ q$ k0 p4 R, M5 d$ L
' h5 e, v) L5 u) q: n: {5 B if ( FAILED( hr ) )
* n. `, H9 S( \" Y return UPnPMessage( hr ), false;
$ c' C* _. ?2 r2 e, k2 L2 ~* Q( O$ ^5 b* P* s8 N. K
/ ^& H$ P- m, S. f! d return wcscmp( deviceName.m_str, m_udn ) == 0;/ d. G" q1 B1 _* C% a
}* a1 A9 T) o4 w8 X7 g2 X, V) W
CComBSTR m_udn;
3 |$ n! Q- U9 Q* V/ Q3 n };
0 q, u+ b# ^9 c4 E
; v# }/ e7 {+ J8 z void ProcessAsyncFind(CComBSTR bsSearchType);) v) p9 `9 a& @
HRESULT GetDeviceServices(DevicePointer pDevice);
" o* \6 U; e7 @ void StartPortMapping();) X7 q* Z; t! b* a+ P% U3 a D
HRESULT MapPort(const ServicePointer& service);
7 O* Z1 F7 }! w/ d0 J9 ]5 R' l void DeleteExistingPortMappings(ServicePointer pService);
! Y# R$ _ x: j9 S' ~ void CreatePortMappings(ServicePointer pService);
+ w! N, h' P" ~$ X HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( `4 e1 _% f: B7 {+ Z6 H8 B HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
: S. P4 U8 N1 p' a LPCTSTR pszInArgString, CString& strResult);" u+ F; G/ V0 T4 o z/ r) P# _+ m
void StopUPnPService();" S0 I0 H& a$ X, h% H6 L8 y. q
' [1 y; E6 o S/ b, D C W& E' t: f
// Utility functions
- ?6 M# A! I- B$ r! Q8 j/ |6 l HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
! U# o# V) y& z2 k% } e, {5 r INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. F' R8 T4 s3 @2 `0 X INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);& F5 v" s% a* D# R9 P4 _2 `
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 g! E/ r1 s C& v# u/ L; Q HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);* y( g$ y# ^% \
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);3 Q/ m7 ^ M5 j, W% \: D! e
CString GetLocalRoutableIP(ServicePointer pService);
' D& M* L2 y |' N4 [" G/ N( \. }. ]3 R7 i1 T3 f* |9 {, B3 E
& r2 w2 B1 q M n. k// Private members
* V; Z) l7 \/ R" \/ x# _6 Xprivate:; Q% ]) C, x+ }$ i" T2 l" l
DWORD m_tLastEvent; // When the last event was received?
: ]3 T2 Q" Q% P8 j' y4 V# i std::vector< DevicePointer > m_pDevices;# Z w+ R7 c2 x: m% Q
std::vector< ServicePointer > m_pServices;
3 Z+ v2 J* R( t9 Y, |6 Z FinderPointer m_pDeviceFinder;
& Q5 l2 W6 i& N" M) F F DeviceFinderCallback m_pDeviceFinderCallback;+ Y5 l# z. }4 F- j% W
ServiceCallback m_pServiceCallback;
) N4 Q0 H3 {0 n; S( Q% q+ E( V" Q" \: @+ `
, G$ y( y# V4 J2 u' m LONG m_nAsyncFindHandle;
3 E# I4 v* q, p" D! {% x5 D bool m_bCOM;7 ?% Q' z/ z4 c B
bool m_bPortIsFree;
) W! B/ u" A- v CString m_sLocalIP;( w4 I' g, K7 U8 P/ n4 T& t: g; l
CString m_sExternalIP;
2 U' p. n6 p3 p: J/ b9 \# h3 X, } bool m_bADSL; // Is the device ADSL?
( q3 i* X# _0 k' K+ Y1 J, m bool m_ADSLFailed; // Did port mapping failed for the ADSL device?2 W6 `- ~# d9 b+ ~4 Y
bool m_bInited;
/ B/ i* }) ]2 n7 q+ y5 B9 ~# o bool m_bAsyncFindRunning;" V" k4 m$ T# F5 x1 Q: S
HMODULE m_hADVAPI32_DLL;' t; v3 ?1 v1 R! L
HMODULE m_hIPHLPAPI_DLL;+ A; t9 \6 E8 @' j. x
bool m_bSecondTry;
5 Z% K5 s; T# h& W bool m_bServiceStartedByEmule;' z E: d% j6 l/ V2 ^# y
bool m_bDisableWANIPSetup;
+ ?; M4 d- ?$ \ bool m_bDisableWANPPPSetup;
8 I4 g4 {$ o" K6 N) T, ?( ?, T
% R0 Q/ ]4 J' Q! r
3 G' E# B4 j- _& o( ]& q};, M( F1 d& ~1 ?! U2 ~2 D. @2 F
, _2 m7 E6 g* d5 J, I+ A
9 M2 S' i+ n L4 D5 M// DeviceFinder Callback
5 f0 [9 y0 R; H0 `/ Rclass CDeviceFinderCallback
; \; u# S; p* u0 ^ \# H : public IUPnPDeviceFinderCallback
0 f8 R+ e( ]6 d0 n- r# X{$ j- q0 [$ y" y; j5 R
public:! o' r+ W! j* a. P
CDeviceFinderCallback(CUPnPImplWinServ& instance)
- R6 x% h" s, o4 G( E1 B : m_instance( instance )
+ f5 n. x! g% x { m_lRefCount = 0; }
! `$ q* D' B% q- l9 l/ Z) }6 J" O2 J& q% O3 c. j1 o5 m
, {' D. {- r( l! S: j4 ^8 K* O0 ]' F STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); m& ^8 Z) F+ W
STDMETHODIMP_(ULONG) AddRef();
: l: n. ^' S8 E4 W0 x% E9 e& u" M STDMETHODIMP_(ULONG) Release();* r2 K; v4 b6 O6 k G
$ l2 X0 j7 V& C6 `7 B% C, D
- m2 M' k( K* [/ }
// implementation
: [3 I3 Z e r) m% i$ c% Vprivate:) }9 d6 y9 R; t1 i
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);! S, ~$ W$ k& J% H
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
I# ^5 |: I9 ^2 k1 @7 ^ HRESULT __stdcall SearchComplete(LONG nFindData);% @$ ?& K5 X# L: R
" ] S; Y; N, ?6 P9 G4 A7 ]* {" [- U& P
private:8 z# U4 z2 m0 f
CUPnPImplWinServ& m_instance;
$ L/ d( {5 L* E8 V6 ] LONG m_lRefCount;! @% N; `8 Z% o. v3 m X! P+ w! t
}; g2 c$ d; s% H1 j: s/ B% h6 x( J
9 D: c, ], L2 N! @) Y
7 {/ _ F" ]( ]' x% C
// Service Callback 3 C* k% Q D/ D9 n( c+ O
class CServiceCallback
' q5 t, W/ H& o/ \$ F : public IUPnPServiceCallback
% m, L% y, [, ~( B" o \$ E{
; z) ~4 G& u1 j6 fpublic:
6 T1 c. j9 m0 P( r$ f CServiceCallback(CUPnPImplWinServ& instance)' d, c$ j6 c' Z+ U: B
: m_instance( instance )6 J, J2 z. Q- A4 F
{ m_lRefCount = 0; }, ^' _. K6 N2 r( A1 _+ z7 c
" f p& f* n0 Y1 a8 t# {6 Y. ~
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% b0 a- G7 A8 u- Z
STDMETHODIMP_(ULONG) AddRef();
) e& j5 N6 W) G; @- @ STDMETHODIMP_(ULONG) Release();
/ ]/ _( f% N4 O2 i% _ U8 N' Y* z, Y; p% y3 @5 u9 A8 ]+ F5 O
8 F4 J) S8 r" ?1 l3 ~' E: S
// implementation% j. Y. }2 d& C1 C
private:9 s, {9 }+ ?) {4 {7 l, f; n
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);6 s, f0 f. m/ g P( B
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 N- F6 C. [ n" o
1 v" P" I1 L$ P+ `; h' S+ I6 U" F& Y$ e- X) b. V
private:
! [! v' Q' W2 S2 b/ n CUPnPImplWinServ& m_instance;0 W+ C5 Y2 {$ J5 d2 v/ k# @! x
LONG m_lRefCount;" Q; T$ I9 D9 ^9 _
};
+ G9 \6 @& R4 T" p9 o* K! M6 x
K+ n/ ?0 E. S& L5 `8 c9 R. B
# Q. P" h. e- m% x% T, ^, }/////////////////////////////////////////////////5 q1 Y- [. v: f4 J( t- ^) N
9 I E- u% D$ i* I
: T5 S. h' Z) b& a9 l! t4 q使用时只需要使用抽象类的接口。
7 o, {* J) @ R" x+ Q& tCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% h3 P: W( R; q6 n7 rCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
5 H3 }& S) O. @- }& M3 U8 dCUPnPImpl::StopAsyncFind停止设备查找.
8 ?, ]9 G% p/ `" V4 o2 GCUPnPImpl::DeletePorts删除端口映射. |
|