|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,7 e% E t3 b/ {0 ]* m- H1 ~
$ g! B1 w5 L0 ]- j4 [
% @; [9 _' f5 }* H
///////////////////////////////////////////+ L) g* Y( t& Y" J% ?$ F1 i9 F
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
4 h8 A- j5 i4 r3 b: {+ \% `9 G* c2 ]4 y9 q; {0 k! B
2 H K5 j6 h+ G( S0 ~$ ]/ K
#pragma once8 y9 ~1 K. g. d* `
#include <exception># R7 c" S: E/ J' J8 d" V! T
* W; f$ W8 }* ?
. l; d+ x2 `2 g U4 e% A3 ~ enum TRISTATE{- c7 y+ Q; ~+ j/ G
TRIS_FALSE,5 Z% N# T$ `9 A1 S
TRIS_UNKNOWN,
# w4 b; g. D. R( f. S& e TRIS_TRUE2 a$ Y8 ]* o) E( s
};0 i/ N$ l2 d; t$ `9 }2 O. r
) Q3 Q' G9 i$ m. w
. A/ f1 g0 b! [# kenum UPNP_IMPLEMENTATION{; T3 R" A, N8 m1 k$ X
UPNP_IMPL_WINDOWSERVICE = 0,0 _! P4 e0 W4 [8 d. c& [% r
UPNP_IMPL_MINIUPNPLIB,/ q2 Y& x6 L% [
UPNP_IMPL_NONE /*last*/6 Y2 }( W( T2 m4 U5 L0 ]2 h; R
};. x+ P- M* d# x6 K% O
0 x! v5 C2 K: R' u6 k$ g# O0 S$ [# V+ n$ C/ {* _7 `* k& X, R
, q- v* W$ i) y" v/ R; _; `8 t( _6 Q
class CUPnPImpl7 M" f& c, D) a& V( q. V/ O
{1 { E; `6 @, w. V8 [
public:
: |5 ?$ v1 } b, g- g CUPnPImpl();
6 t7 i. o! N7 ~7 X/ l0 {1 s virtual ~CUPnPImpl();
, Y y' [1 n8 O, y0 f1 R) d struct UPnPError : std::exception {};
+ O O5 N" s- @/ g5 h, y: ~ enum { {7 D# f$ R6 N* q( A
UPNP_OK,/ e" M8 Y0 k' D! x
UPNP_FAILED,
' G, {- S& K. } UPNP_TIMEOUT
8 q# b0 r2 e, u- z };
7 w4 F2 A' H0 f* e0 \' Y$ x9 R7 [4 H$ q' n, u1 U
4 D) |1 G9 U1 }: k' M u, a; j" m7 T virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" A& u' U* f0 T
virtual bool CheckAndRefresh() = 0;
4 o# ?$ X; @4 ^ e' C+ d( j' J; d virtual void StopAsyncFind() = 0;" O7 I8 o' d2 E
virtual void DeletePorts() = 0;
: J5 G* M! F- ^) F virtual bool IsReady() = 0;9 b0 D, W& `; O6 ~! E2 t/ `8 a2 ^( R
virtual int GetImplementationID() = 0;! |) k5 R! j; k" i) R3 s' L. X
8 g" W9 Z/ W) ^/ q7 g" t
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 e2 L$ S- Q+ a0 \8 l# y* k( T) o: ~7 t: l2 B" D/ O9 d# \( p5 d
' E2 |# d# o. |$ r/ G }6 B" {$ ` void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 H) _$ J% x! T" n0 f9 D- t$ I TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
8 y+ W+ v8 }1 B- ~ uint16 GetUsedTCPPort() { return m_nTCPPort; }& E# d) H8 p/ v% Z
uint16 GetUsedUDPPort() { return m_nUDPPort; } ( p, n5 L6 m6 m/ r/ b2 F
* m, p: d5 M: F) @( t- `: M9 T3 a) {/ r, t9 a, |. h1 V5 g
// Implementation5 h6 y! {" M9 _& ~1 ]- y0 @
protected:
$ q4 C7 z6 l S" Q6 N8 G volatile TRISTATE m_bUPnPPortsForwarded;
4 i1 X3 L8 ^8 d- j( V$ o void SendResultMessage();
( y$ d( i* V! Q% ] uint16 m_nUDPPort;
/ Q) K4 W( }, r3 i/ F* ` uint16 m_nTCPPort;
4 {6 ]# @2 C! H uint16 m_nTCPWebPort;
: m/ d' ~( s0 |8 R) p2 O bool m_bCheckAndRefresh;
8 G( T4 b0 A, k
8 |( g( Z5 F! F! x0 V- }0 W. }* u
. k# ^* ~ o% c; M+ I& dprivate:6 p9 i% L8 S$ L5 @/ n
HWND m_hResultMessageWindow;
3 O8 y" d4 Q3 }5 V" C UINT m_nResultMessageID;
' d, w1 v- f7 R
6 O. A# o2 @/ A1 _1 S2 j5 d& _+ W2 W+ D; r3 W' N
};
+ T- m# {% n' ^% I% A+ h% u6 Q# C2 X) [
# R% s! n0 v4 K6 n
// Dummy Implementation to be used when no other implementation is available* E& j9 x2 G! ~: c8 }
class CUPnPImplNone: public CUPnPImpl7 W4 W0 w3 U& m! P0 o
{! u( A/ n: f+ S; |: |0 o* G& X1 p
public:8 h8 r% U& o1 ~' Q' m K/ K/ c& ^
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 ~4 _! Z1 x3 k E7 J virtual bool CheckAndRefresh() { return false; }
9 O$ ~( |# S4 Q* n0 j. C; w virtual void StopAsyncFind() { }. w: h w; E! d! z7 X7 f
virtual void DeletePorts() { }+ S- l& @: I: q! y+ W; `
virtual bool IsReady() { return false; }/ `1 L% K# E/ X0 k7 r
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
# U4 m/ e4 q% t' ~1 ]& h: P};
; I: n1 L0 t: ?5 A' o/ |( X1 B
" v0 V# L4 g+ }
# t7 r* t% F9 {4 n# @# s B/////////////////////////////////////- e. X9 r1 p9 J5 G
//下面是使用windows操作系统自带的UPNP功能的子类
6 M3 W" ?, W- i0 [- Y c: [8 |6 h1 ]# X8 [( X: t( h' v
7 j1 d; C% B7 y9 S#pragma once' r% ] H8 ?6 M" y: M2 ?4 j6 b
#pragma warning( disable: 4355 )
. y- g3 o9 t# D7 I0 p' q6 `4 v
% t. u5 B8 M& F2 _2 P" h7 ~7 \ \* _$ \7 n
#include "UPnPImpl.h"; A6 w( c8 ]# m5 N: B# o% V
#include <upnp.h>
1 K+ x2 G8 ]5 d( c! C: H#include <iphlpapi.h>
8 y- H5 w7 `2 o1 e9 o+ A#include <comdef.h>
) G& n+ C. @; T' O8 w#include <winsvc.h>2 {9 Q9 F: s, `+ J W
9 N9 Z w% X/ w2 g7 g0 Z# a
7 B. X+ \. J8 H+ }#include <vector>9 B7 Q( D9 |5 f! G" Y0 i
#include <exception>
" o* _# e- ]1 \6 U" l* s( D$ h- U#include <functional>. k- b; L6 D# z. S' k
. f5 g( o& H( C# z4 R1 l W0 t6 Z7 R4 m" A
. z: ~) f9 `6 z& b
: s% x: Q) d) h$ C: H1 B
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
* e2 ^# h4 r( \+ H5 z- f1 C, ftypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
7 q- B3 G0 V( wtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer; q, P A( x, z' R1 i
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 O; @/ q3 |2 n3 `6 }2 y4 h6 h* qtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
; V" O$ Z! h; O3 m; h6 [8 }typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 o. ^. e4 N5 {# Otypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 z8 _* Z; i" C1 U0 T* Z( `
1 l `1 [' w7 r" V' p
% ^% v6 C- B- U+ U0 _/ e5 ]; v" B1 ctypedef DWORD (WINAPI* TGetBestInterface) (9 i! j0 ~$ A/ x/ A2 ?, @
IPAddr dwDestAddr, D! Z C( _: I
PDWORD pdwBestIfIndex9 G# t; m( R) g& \8 c6 I9 |+ s
);$ B" u! l9 u) y
: k7 z' n# w/ P1 r! C! n
* f- d+ ^; G. b9 S, I! Etypedef DWORD (WINAPI* TGetIpAddrTable) ($ r9 h- [! \2 K$ ?2 r( Y4 u. D
PMIB_IPADDRTABLE pIpAddrTable,8 W* x2 f3 M& z' w" o) N; _7 r
PULONG pdwSize,: J5 P' @5 r/ x" X+ Z/ ^
BOOL bOrder
% q3 J9 H4 G3 X q- Z" F);, L! g) ~" x8 u& j* ?/ ^' ~: `! G$ r
5 r$ d$ e1 x7 z
6 i w- _/ k! y# c" j. r
typedef DWORD (WINAPI* TGetIfEntry) (
& e# N/ _3 J4 L2 U7 s PMIB_IFROW pIfRow) V& {) V# D% m
);; J- T4 v: u4 J7 A" D
; `1 M' P, x7 V; v# [6 {
, V) ?* O: Z: CCString translateUPnPResult(HRESULT hr);
R7 o, [3 ?: H% ^3 z' I7 vHRESULT UPnPMessage(HRESULT hr);. d/ v/ M( k7 h
! J, ]2 t9 p3 K; Y$ }' t2 ]: l5 {& z
) t& A( h/ k9 {' R
class CUPnPImplWinServ: public CUPnPImpl$ a7 j V/ A; w5 q3 W; a) G$ Z
{
/ q9 M6 L# t& Z: ]! c! G friend class CDeviceFinderCallback;& F- x- H7 g+ V9 G
friend class CServiceCallback;
" k( i& ?6 |/ F// Construction [& l, e9 M [* [: C q3 Y2 y I' X
public:% z0 w, t4 L7 D6 e0 A" _, U% _
virtual ~CUPnPImplWinServ();
0 R: J$ s0 a" T CUPnPImplWinServ();
( o; j0 Q8 d2 C' V q
( u4 P% {$ r7 P& ?
$ V5 d8 ^) F, Y* a; q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
) r6 T; @6 {* m* ? virtual void StopAsyncFind();
& t* y8 E/ q5 g, O0 e virtual void DeletePorts();
l$ u. g3 x6 H$ U virtual bool IsReady();
1 |* i3 Q3 Z& X( B9 _1 X virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }' g& f: ~" M+ p/ e
: D* K& E( G2 Z1 j* W$ a
9 V- }/ ?' X; M% Y // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 a2 _/ u8 D$ l // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later7 P$ v, I8 {' L2 a# @* d7 Z2 v
virtual bool CheckAndRefresh() { return false; };+ g, b5 v4 B, E& G" w2 [0 r1 l, D
7 ?9 p9 a+ K. x6 M; w1 F
& x: Z( }$ m5 U$ m3 J0 I: V% g& O1 dprotected:
+ u# b& X) k( L6 \, K5 a void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);5 Q0 M2 u+ I y4 u; i
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
# g" Q! g" g+ q; ?# j: Y void RemoveDevice(CComBSTR bsUDN);
6 \. V4 R* W9 Q bool OnSearchComplete();* O, Q8 C5 T; t# J) P
void Init();
4 ~! g) h$ F4 }0 m- ]& t5 k1 @- e1 d. g- v2 v" u% @
# }8 k' b' i: v% s$ a inline bool IsAsyncFindRunning() 6 v/ e' U3 Z Y( K
{* ]0 S U+ W* p n- ?+ G; j
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )8 P9 J6 \+ v( x) a; k. G
{
r1 v4 O1 [7 q1 o4 k m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
$ E4 `* E, P) Q0 Y8 s) b7 ]% p3 I m_bAsyncFindRunning = false;
' V. E4 ^/ @$ Z5 g. E }
4 \) z5 I( n5 q* g6 G c7 q MSG msg;) a, t2 W" ^; D Z; ]3 v
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )9 j: Z q7 X E& N6 F) X) u# a# Q
{- o6 D1 ^0 e0 N
TranslateMessage( &msg );5 A: e) ?7 |5 ?% L' G+ l) g! Y
DispatchMessage( &msg );7 [' p; {5 ^) w C' t7 o, s
}
+ G( u6 Z/ O. w; F' ?! ~7 h return m_bAsyncFindRunning;
/ z1 t$ U. e# z8 F( W4 Z, W }
! [* Y; n; e5 c/ ^1 Q& G% K( z8 l# e1 f/ N
2 _8 S+ I1 [$ M7 p- C( ^* ] TRISTATE m_bUPnPDeviceConnected;- ^& \, }6 Q. j
3 I5 ]+ b+ f" m: g$ H: s- i- }3 j: r- S2 ~0 B s# Y% O' z. |. {7 P! ^! x/ w
// Implementation
! e% k& L" o3 g3 I( A+ p8 `% [ // API functions L K8 S/ Y! W0 L; J7 I: y! }
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 K' U: {2 [% R9 e( U1 L) ^ x# X SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);: E! e0 g4 E, \- H4 S$ S
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); k) j" U) ~8 y) b) N& s
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 q1 ~0 e4 E' h6 ] J3 b8 }
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 d/ \8 H' N2 g: z0 g9 y4 c* F
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
* |! S4 G3 n4 `4 W0 }* W7 T' ?2 ^. T9 E- [
3 T# _; U; y ~2 F1 R4 B TGetBestInterface m_pfGetBestInterface;( ^( ^/ O: G' @+ G- E# j% d
TGetIpAddrTable m_pfGetIpAddrTable;( [& s5 [: D& \: r$ c1 n3 A" G
TGetIfEntry m_pfGetIfEntry;
5 n8 [( @) V$ u9 U$ M" H& x6 p% D9 d; g1 ?! X! u* ^
" G$ s# p! W0 b5 z O7 a
static FinderPointer CreateFinderInstance();
6 y3 }; O9 W9 a8 y; g( e. ? struct FindDevice : std::unary_function< DevicePointer, bool >
1 C' B! J; n2 R" Q( W {
1 Q) ~ n; M2 D9 Y2 x FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
B) L) h+ ?# y( [/ M: k result_type operator()(argument_type device) const
) f. T5 Y, u1 m; X {4 ?& O& Z Z$ q- A4 k7 W
CComBSTR deviceName;
4 j. i( j9 Q2 Y5 K0 Y HRESULT hr = device->get_UniqueDeviceName( &deviceName );+ j$ p& I. s' R) }, h, Z
! E7 g2 j7 e9 e# d# a" q
5 {( d; ~: E4 F1 Z% f/ u# u if ( FAILED( hr ) )
" r; n; O1 h& O4 A- \) Z0 X return UPnPMessage( hr ), false;, L6 b4 p6 ?& _
% T6 |* a; F, Y5 B/ w$ i: m; }6 e2 h5 ~8 W. f" x7 T
return wcscmp( deviceName.m_str, m_udn ) == 0;
" o& w0 [( `6 c+ ~; k }
2 q0 j2 @$ g8 y CComBSTR m_udn;
V a- j4 Y3 |* T# B };
# w5 c/ o1 d0 j' v6 ]' H! c* V
' t+ r; b8 z+ i9 Z0 x& u void ProcessAsyncFind(CComBSTR bsSearchType);$ L& Z# j( U2 W9 L* O
HRESULT GetDeviceServices(DevicePointer pDevice);
$ T! i/ J! H$ L$ n" m5 i R+ g1 x void StartPortMapping();
0 v0 T3 [* c; N0 o HRESULT MapPort(const ServicePointer& service);! O- l+ L$ Q0 Y9 |. [; I4 Q$ I' m" h
void DeleteExistingPortMappings(ServicePointer pService);' E& w Z7 ?) K$ _3 S
void CreatePortMappings(ServicePointer pService);
9 h" Z: F& T f HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); p+ ^6 ^5 r, p/ ] J9 E
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* R) E' h1 ]$ q3 A1 d. Y LPCTSTR pszInArgString, CString& strResult);+ h9 V5 B3 W; `8 z
void StopUPnPService();
4 Z4 y0 m/ ?& I* H }) X6 _) j; P$ E3 D8 u2 t! A
9 {2 |( F% |/ y; v1 K6 E // Utility functions' K a/ H. @; H" t' M5 ]4 d* n
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);: S/ j/ ^0 @/ g5 a; Q
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
# a; D5 S. e$ y; x& m: n INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
+ O2 u6 q/ y* T& E" U& Q3 T/ v void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
3 p6 T1 L9 o/ B5 N5 [8 v( ^- a+ l HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);4 k: J- X6 q0 g% n/ O
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 Q+ d/ v. ^1 X1 w+ o
CString GetLocalRoutableIP(ServicePointer pService);
- x! O! |6 p4 q, }/ }5 V" A& ?0 A* l% q( ?: x% u
5 s! m: m; W. C% {2 J// Private members5 j, @7 {) Y' e w
private:
9 f- C. w! l3 B. q6 O+ @' A DWORD m_tLastEvent; // When the last event was received?
( V& t7 q% O1 s6 k, a" i( d std::vector< DevicePointer > m_pDevices;
@8 E& m- }! W% a std::vector< ServicePointer > m_pServices;4 m R' ^1 U2 g# K$ h8 A
FinderPointer m_pDeviceFinder;" m3 I, E; i* k. n! Y/ K
DeviceFinderCallback m_pDeviceFinderCallback;* C, Z9 b% J1 x' s; Y1 j* k
ServiceCallback m_pServiceCallback;
$ z# `( s/ Y3 a, q# A* |6 ]$ T4 Q0 G! d
2 o4 j* M7 |+ _4 a' p: H
LONG m_nAsyncFindHandle;
+ w h* t2 j/ b! v0 L7 M bool m_bCOM;8 V: |# {8 M' J, A! m/ p
bool m_bPortIsFree;
3 T S* j- o0 S0 I; x- Z5 x- } y CString m_sLocalIP;
3 E& C: k, w i6 x% w CString m_sExternalIP;
6 a/ Y6 h3 S# Q7 K" H bool m_bADSL; // Is the device ADSL?
& r, `( j S: H. l; b5 Q bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
) q$ E# K- e7 t( Z) R3 W: ~ v% u bool m_bInited;4 b S5 ~' r# ?3 P4 U' J: Q
bool m_bAsyncFindRunning;
2 [$ g( J9 \' M HMODULE m_hADVAPI32_DLL;
# u" J/ T5 V2 q8 C8 ]5 P6 l HMODULE m_hIPHLPAPI_DLL;
. u, D Z. L# ^" @# n# R2 s! E bool m_bSecondTry;
* o5 E+ d% B& A* j4 T bool m_bServiceStartedByEmule;
% `$ E- Y8 h( w, u1 V9 V9 A2 P+ J bool m_bDisableWANIPSetup;
9 }# c! s6 O9 S% S/ t2 j" K: A bool m_bDisableWANPPPSetup;
( d7 w4 G- U4 g+ N9 r) S( e- `) l4 S! ^7 |
4 j! M+ P1 I) C' j6 g5 l: p9 v# ~};
) [* J9 \. x8 F9 m0 h' U
" A, O- t' Z# V
# q3 ?, E& p- g& e4 O1 C// DeviceFinder Callback
3 r8 {% ?- A- ^8 {% F6 Iclass CDeviceFinderCallback
' H {5 B, G* q2 B" b6 A9 J : public IUPnPDeviceFinderCallback
4 l7 k7 V' g6 g( Z; y4 a$ t/ y{! y+ b- M: a9 v( Z$ D* b
public:2 f/ y8 L( q5 E! @* s
CDeviceFinderCallback(CUPnPImplWinServ& instance)) e+ Y$ H \4 q' H& B
: m_instance( instance )
O/ K: H' C1 P7 q( g { m_lRefCount = 0; }
$ S: z& y! {% C: i2 v' b% x# G+ O( n/ p7 g
$ `) L7 Y9 o# \! v
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; {9 q( v# f+ m# v0 e) [) g STDMETHODIMP_(ULONG) AddRef();
: Z9 }1 X# v2 l3 m STDMETHODIMP_(ULONG) Release();& C, [2 I. G: |( M8 ~4 q" Q( u' K
4 m7 W4 U9 Z4 M# C2 y. w
8 I5 {/ u) Q& d// implementation
1 e# \8 I4 {6 ]/ aprivate:
8 C! `- m5 K+ T$ W7 ~ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
* F: F7 Y$ w3 c9 A: W4 y6 Y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);4 ]. d: x# L9 ]4 g) @3 C
HRESULT __stdcall SearchComplete(LONG nFindData);
D4 x6 Z5 J# K" Y8 ^! L+ U& o! i# Q( n ?9 k
- W' M. m1 j7 a4 w' s1 @: x
private:
* @5 a2 \) K( l4 h% a: x CUPnPImplWinServ& m_instance;. Y* N, V& ?- V# O* @- Q
LONG m_lRefCount;
7 M1 q- t d: X3 ~7 D/ p};
" p w3 H9 r" B% r) m, x# `* S, G: W! U% ]- ]# C) ~" M
/ w* J; U; g. a# m4 `# ?/ o7 ]// Service Callback
2 C1 n) Q" `) `class CServiceCallback
% \/ R" k& p' s1 [* r9 A" q: W# U3 E : public IUPnPServiceCallback
7 r! e& @# |5 k) X{' k7 m8 _5 I, m7 b P" ?4 r
public:
) C% W# I' T+ h8 j0 R CServiceCallback(CUPnPImplWinServ& instance)1 B7 U: U- X) Q: `6 S% g1 u
: m_instance( instance )4 d4 ?) r+ b3 \/ Q& Z' H
{ m_lRefCount = 0; }, }: G$ P; s" ^# w. P
9 j# R7 e t d* j# Q5 i% C
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- O7 r: x: ^) E( q STDMETHODIMP_(ULONG) AddRef();3 w+ K3 ]2 T% |: b+ ~! s* S
STDMETHODIMP_(ULONG) Release();
Z% d; _* M+ v) r3 G
: V9 n2 P+ c8 j2 y* ^& n4 F4 N7 H6 t9 v" n
// implementation) a" O m' e0 y, C- {* E3 h# c
private:
4 }2 C0 f7 K/ W9 X HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% h# l: e! }" y
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 K* r# h1 E) Z i8 C- q1 A8 P0 T2 d v* A
' o% ~# U/ C% `! J" dprivate:8 M0 F6 u2 p" C3 }" ?) V
CUPnPImplWinServ& m_instance;% N- K1 s# r- N7 f. S* V) D% |; \1 ^
LONG m_lRefCount;# }1 O1 i+ Y9 X/ J# ~' B
};
2 r6 s$ M! \6 o+ W1 n# ?( ^
" z2 k9 b6 D" x' q$ v2 v) z
' {" e6 n- _$ E6 `( W' T- O/////////////////////////////////////////////////6 p5 E1 Q5 w$ k, G! N" y
0 @& U) t7 t9 t, s
4 \+ Q/ O- k0 i+ N" f
使用时只需要使用抽象类的接口。- ~5 q; n& o/ h1 F7 e
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.) v# u' A/ t/ j/ z- Q0 ]
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
. z0 }% x7 m3 l$ RCUPnPImpl::StopAsyncFind停止设备查找.
0 A0 t% q3 ]. d$ b" @) b4 xCUPnPImpl::DeletePorts删除端口映射. |
|