|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ J$ f; X# `1 i' t0 m( y5 V4 _7 Z" G- ~ w
7 C' X. P/ _( L N///////////////////////////////////////////0 m' S/ z/ S1 {. _/ H1 U7 D0 i
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
' o6 \, ?% \& E
3 l% o# N0 O3 o9 e+ Y
5 Z/ N9 I4 l- H/ v#pragma once
6 }+ `0 G4 Z, L/ N, o#include <exception>
1 E9 _: }9 ?8 {, h% i3 d9 U5 i
' w$ G: Z7 ~" @5 f( L. }
! d9 h' P! @7 M2 X( Z1 ? enum TRISTATE{9 K# O6 e; N* `* N& b
TRIS_FALSE,9 y& i o! M* J# n
TRIS_UNKNOWN,1 ^9 B7 o1 |2 s& c# C
TRIS_TRUE& l8 H; {+ s3 I4 z- J" ]% v* ~
};* v, e6 Q" z) J9 w, T' x+ y+ k
) |! W, t h& [" l( u' D
( [) J" G! ~/ \- Kenum UPNP_IMPLEMENTATION{ E3 N: T) O! M/ d7 {/ h/ r1 z
UPNP_IMPL_WINDOWSERVICE = 0,; C6 |- q. b% ` a
UPNP_IMPL_MINIUPNPLIB,
7 E: S* i9 @7 d2 K UPNP_IMPL_NONE /*last*/& i$ I5 ^3 b {1 A# Q' O. l
};# [7 R; N4 g8 ^
7 @; c1 U: H8 F4 x, I; p+ J
M5 `' p, y: G0 D
5 c! n! b2 U2 a0 e8 b
2 g3 |2 j2 b2 i$ a: i8 dclass CUPnPImpl- V! v" _& A6 U0 s8 w" v# g1 H
{
- f' I* g% V5 r* v# R* b4 _public:) @5 K0 J2 I6 s' H1 ^; @: b
CUPnPImpl();* D; ]' f3 Z" X9 r( T3 `9 ]
virtual ~CUPnPImpl();
$ b( \4 Q$ r2 ~ struct UPnPError : std::exception {};( w) q- `# |* \; q
enum {
s; s# k. n6 I* T* r6 ^ UPNP_OK,6 I0 a7 s: \/ Y5 }4 @6 S' S
UPNP_FAILED,
' \- s; d F2 x, }& E! z$ z UPNP_TIMEOUT
$ l: W7 g+ Z: z+ E$ m' g };' c9 q+ n" `7 R+ b2 i8 ?* F( J; E! R( I3 L
. {' R; j' Y$ y4 E- K Z: j- y! a6 a9 y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;5 ]! \" A. E# o
virtual bool CheckAndRefresh() = 0;1 R- k* ?% L1 k
virtual void StopAsyncFind() = 0;) g5 W. J/ `7 x
virtual void DeletePorts() = 0;& | Z& U- S0 B- L0 t; M3 `
virtual bool IsReady() = 0;
# @1 \0 `0 e* h, n" _ virtual int GetImplementationID() = 0;# a: K! Y6 L+ F% f
2 C# ^2 V5 @1 g u% e! Q4 i: i
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 @2 w! t" o$ a" w% I- Z/ x2 z v5 f3 \. y
8 j5 ?$ u. L5 N void SetMessageOnResult(HWND hWindow, UINT nMessageID);$ _3 t7 c6 F$ h8 y2 |9 m
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: N0 p& e7 t9 n/ {* o
uint16 GetUsedTCPPort() { return m_nTCPPort; }) u/ M! m* g) F$ E# A& Y$ B
uint16 GetUsedUDPPort() { return m_nUDPPort; } 0 @; A5 R- S8 E1 O1 e7 \
- Z+ y2 J: N" f- V( }, N( |
6 n) z: m7 w9 W( o* _& w// Implementation. H1 \: e. B* |9 o% Q, l
protected:
3 u% a( I4 H' Y9 N volatile TRISTATE m_bUPnPPortsForwarded;& }. t$ m3 ]7 S6 g F% {5 F
void SendResultMessage();
" ~4 X$ j4 R& [2 W* y% w* l uint16 m_nUDPPort;, k# |9 C5 `* a. M. X6 a
uint16 m_nTCPPort;
. Y$ k5 |. J8 [9 U4 j uint16 m_nTCPWebPort;
4 z. O5 {% ?# u bool m_bCheckAndRefresh;2 |) I) C# E8 _( d4 s7 b8 v6 |" ?' g
( g N; f4 c# H, g' Q
' X2 P1 l+ }6 T! iprivate:0 K" |/ @1 o6 V6 O/ L q* k
HWND m_hResultMessageWindow;3 B, V7 F* X5 c5 S s
UINT m_nResultMessageID;8 Z8 |5 e$ n0 N) `4 p1 B
: |: ?3 k0 ^- S U1 T
2 r' L* [9 x& D( P6 ]% n};2 m! @, P2 Z p( K& @
) f( o- ~( d; C! k7 x
" ~5 T6 c2 m: S5 d8 c; |' l// Dummy Implementation to be used when no other implementation is available J1 e9 s6 }* W! h3 p. k9 ~
class CUPnPImplNone: public CUPnPImpl+ Y" W/ R) r- f
{
i; } |" A. ^, x) \public:
& d' y% V- C5 D T% }1 M virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }6 D( M% p: [6 B1 O# \, j- `# D6 r" ^
virtual bool CheckAndRefresh() { return false; }
5 V' I* @& G, D/ w9 e virtual void StopAsyncFind() { }* B4 H& f8 _2 a* x: ^( k, R
virtual void DeletePorts() { }
3 S9 D" b7 }% Q, D6 [ virtual bool IsReady() { return false; }: V; B o, ]4 p3 r
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 ]% ~5 @6 E! o7 _ ~; f% K$ c};
+ p/ ~5 I" C W: L+ h! i9 w% T( S$ X4 ~& A2 y' `1 E: E* b Z
) R+ L" ?9 j/ l B
/////////////////////////////////////( g" w( A+ A# i- |% ^
//下面是使用windows操作系统自带的UPNP功能的子类8 [1 u( U6 \4 G( T
# u7 D$ d/ }. o, e- v H$ f4 Z5 `* U+ @& P
#pragma once' Q* T* n( c) q# b4 N, d
#pragma warning( disable: 4355 )
& w$ t& }$ H6 o4 ]: u
) m" R1 D- x& G e h1 g
) Y! Q- a6 b1 w8 h# H" s! S#include "UPnPImpl.h"" t# k1 ~# P6 n0 Q6 f' J- }
#include <upnp.h>+ `( W# s4 [( E4 y
#include <iphlpapi.h>$ l. z/ ?# Q0 p: r2 x
#include <comdef.h>8 {* j0 p( f3 J# u- f% V) s6 N
#include <winsvc.h>: V( |6 N/ G0 u
) ^6 F8 g/ Z( {0 F" i% g
6 c2 @/ | p/ K" @6 M/ c
#include <vector>5 g% O0 x2 Q8 d( _" I" y6 a1 V
#include <exception># E/ g2 j9 l- R7 g, o0 I, G) _
#include <functional>
Q+ a' q7 `. ]* o' C! }
- y1 E P( }5 z- d/ P/ _: h% ?' W; l. _6 T; \
; m7 ?4 }% m% F8 S+ r9 D5 F2 c
4 d/ E; d% t' s) K
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. i0 T) J' G% e" _7 Mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;# \+ X7 r k# u9 z9 _
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;$ s: q( H0 n9 o0 s* Y5 t, A0 h: h6 I- r3 C
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
4 u- O* D+ g1 ?typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;" a. V" k+ y& i0 P3 {
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
/ o' b2 H; N# }/ Q4 Jtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
: f' J6 r" V4 p( P, X+ c
; w( Y' s7 s- I+ o/ o) a/ v6 Z/ j( T
typedef DWORD (WINAPI* TGetBestInterface) () ]# m) N# M0 X
IPAddr dwDestAddr,# W6 T$ B/ ]% ~. x# l
PDWORD pdwBestIfIndex( u; u7 p8 n# n8 P4 a7 r l5 j/ r
);# f1 @# _( a1 g6 d2 n7 O, P8 O
, K& E- l5 I: \$ n; i
" o4 |# r3 s. n& ~) k4 ktypedef DWORD (WINAPI* TGetIpAddrTable) (
) {6 `# R! g* N" I/ W, Q, W, y* M PMIB_IPADDRTABLE pIpAddrTable,! V3 W( x8 x+ L
PULONG pdwSize,
4 c# i; a3 i3 l. U- i BOOL bOrder+ g" T" b( S. b
);
u5 u4 b. i5 n- F- W% R
# K5 P7 j4 u, W# d+ q4 s( z; r' @% T s, W3 u* h' P# \
typedef DWORD (WINAPI* TGetIfEntry) (' E' G% ]1 o( P& |
PMIB_IFROW pIfRow! C3 i1 I; W8 C' m+ B
);: r2 B. t0 }' o5 N4 g& W9 m. _
, d1 j5 E9 J A1 X, |4 D8 G
, T, l, |5 Y9 T5 B3 ?+ kCString translateUPnPResult(HRESULT hr);- f- H1 h% C; K- V
HRESULT UPnPMessage(HRESULT hr);
2 P/ B1 k( y. A3 F4 d$ M) t5 o
) \2 {/ K$ D5 c, Q& A! ]: H" t1 s& D2 m8 J1 S5 H, M `# y
class CUPnPImplWinServ: public CUPnPImpl$ ]# i% a3 E' K) j4 P; F! M
{
5 c+ y8 D- L& t friend class CDeviceFinderCallback;
, c+ c$ c' u# A' n) }% u& q friend class CServiceCallback;
+ @9 I% w: a4 v- [// Construction
+ Z7 A' [ I3 h5 _public:! @& j( o$ p0 L8 G1 C) a& P/ g
virtual ~CUPnPImplWinServ();
5 [! [* f& A1 T: K: M( w' X CUPnPImplWinServ();
5 s7 h2 |# v9 {( C6 u5 s& P- w. L5 v4 q' B& M
: Q5 F7 j g- n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; j$ g8 m: ^9 u" p virtual void StopAsyncFind();
- A3 C% l# H6 Z+ l* j4 [( O: y virtual void DeletePorts();
& J. L/ O& Q" _$ a- [" V' \ virtual bool IsReady();
/ r3 o/ o% R7 q7 c: f# o7 s virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }1 u9 Z6 V6 t. b* k6 @
% S: t. y, w# I/ k+ `/ S' s
/ G& p1 ]) G* {% Y# [, b f% l
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)0 D8 ], v0 L7 D% p# a! d
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later' t0 u! E. n: Y/ K8 _4 S1 p) ?8 _) A) e
virtual bool CheckAndRefresh() { return false; };
5 b+ M( c- {; f0 X$ `; F/ u5 c+ c8 }
}) P" d$ j+ ?- z8 R- W7 p. W/ P
protected:
. @6 ^' E* ]; Z* j void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);$ L8 G* m: |! \0 m% {6 ^% Q. J
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);0 m* ~! l! h6 ~& ]# q
void RemoveDevice(CComBSTR bsUDN);
P/ D+ T2 R! u" g/ U( J' N' { bool OnSearchComplete();
0 B9 h- G: p& @! K5 }$ T) G( u void Init();
6 a1 b `! E8 j5 h8 S' j# K1 H9 X1 M
6 t, |' O1 K7 T: G inline bool IsAsyncFindRunning() ' Y% u- d+ R0 N( H/ w+ H& G# z
{
) d. m/ e2 L& U9 V/ r1 W2 I! t if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
( [& B% @ v T {5 h4 D; F0 O% P7 D7 a
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ z2 N8 J! t3 F+ z0 \1 |% H! C: ~
m_bAsyncFindRunning = false;: K4 B2 d9 [; ~
}2 g; Z1 W* f4 {* m4 B7 f
MSG msg;4 {9 q- K. Z( L& k9 ?( h- Z- x
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) d$ b+ m* @2 N0 x; [
{! H e5 M1 ]) L' ?$ x2 H
TranslateMessage( &msg );) y5 j" E! F+ a2 S+ x3 I" S
DispatchMessage( &msg );6 o/ _: j' e2 `6 D' x' Z
}
9 y5 J& \+ B: u' z3 ~ t return m_bAsyncFindRunning;
3 a: O) O9 ]" c% {+ s% B }
3 Q4 U! _! ]: j1 N2 i F" e9 S4 z6 [7 b9 } V6 g* c
; D- e1 d6 N- j4 T5 Q+ b: A2 r TRISTATE m_bUPnPDeviceConnected;
, }6 G$ D! [" E" t* h1 v6 }6 l( }2 `' b: _! }, P _+ j2 w, z6 c# h
; Z0 z9 i& F" p8 D. Q2 y( p
// Implementation
2 X/ K3 }# V. n // API functions
# v/ w9 P. y2 K/ J2 v SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD); l1 M1 S; `$ V! G9 p6 A
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
" k, Y k1 S9 S# L BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
) u+ z0 o/ }% \ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);! }2 J8 | L, x! r# R2 |4 R4 S
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 X8 m6 c+ |. B, A( K
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
; X+ L# c; P" A' M( R: j! E/ G+ u/ N1 |4 ], J2 C
+ s0 M7 f! ]7 b: t2 S0 { TGetBestInterface m_pfGetBestInterface;
2 S1 I7 r* L- J# R" N6 S$ h TGetIpAddrTable m_pfGetIpAddrTable;9 E1 C) G0 o3 z4 e% O5 l9 ]) l
TGetIfEntry m_pfGetIfEntry;
+ W( V$ d/ Q# H$ W: T& c8 e* @: h! A/ p" u0 W/ V0 Q
: E4 [" E* u3 _1 Y* U static FinderPointer CreateFinderInstance();
0 q+ U( M1 p N0 v* u0 e struct FindDevice : std::unary_function< DevicePointer, bool ># W5 X j4 E+ @. a6 d5 \
{
7 C+ j# m9 G, W3 Q$ L, u FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
6 y0 F9 T+ h; `/ O result_type operator()(argument_type device) const4 ~# M" b) B5 G+ c) L$ S9 [
{) ^8 K; U1 D1 N$ J; h
CComBSTR deviceName;% H5 e* d7 G% ~0 f3 V; g' a7 `' M
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
6 p) q9 p+ A9 {3 |; t7 n. D$ \- y: @4 u
3 t& q1 T, o% z) X+ I! ?, w3 i2 t
if ( FAILED( hr ) ) w6 [& X3 |# s4 V
return UPnPMessage( hr ), false;; c$ Z& k: _+ u- u9 ]9 j
- G; W! X* o8 s) r& |* W
" R- s+ H% t+ ?8 Y& F9 t return wcscmp( deviceName.m_str, m_udn ) == 0;
% d# d& Q( {9 h: {1 m* m }7 B% L0 M; G- a* K- m4 Z" {; L/ [* ^7 a
CComBSTR m_udn;4 t0 d- X5 l0 S' M0 }. _
};
7 v) q+ N8 G2 z6 Z
: Q' g6 f. }% I% N void ProcessAsyncFind(CComBSTR bsSearchType);
, `8 _2 B+ d) [4 a* A8 X9 R HRESULT GetDeviceServices(DevicePointer pDevice);7 e- Z2 o7 z0 e ~. M
void StartPortMapping();% @6 k9 q: L' M+ s: @4 t1 i( [+ M+ B
HRESULT MapPort(const ServicePointer& service);8 z5 ]+ N/ z% q* \/ m r6 f
void DeleteExistingPortMappings(ServicePointer pService);
5 T w" y7 v8 |- X! C void CreatePortMappings(ServicePointer pService);, U: e. z4 K! K5 f
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( {$ V$ ?; ^. E. u4 N) |3 V6 p" S HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; s# w/ ?1 _$ t LPCTSTR pszInArgString, CString& strResult);
( Z1 a6 M. L: M% @: K0 Y void StopUPnPService();
& J+ ^# v5 @8 R2 L% [0 k( k+ m3 K7 n" c. S2 W
( \$ V/ w# Z, Z2 \) Z
// Utility functions
9 O! m8 Y( w$ b HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);0 _8 i) \5 V, V5 y( V' u
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);( x# x) F0 |, g1 H. v2 X1 `
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* d( w! i! G* e/ O. }7 s7 i) g, @ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 G4 h7 l' |, g9 E HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
0 G# X; L5 r* O" j) ]& N$ o+ M- S HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);5 G4 P `2 z) X! c. S
CString GetLocalRoutableIP(ServicePointer pService);
# i+ a7 ^0 [$ K* H9 i, x% k% m& g+ p& b
; y# x2 v/ ?8 ]" Q5 @; b( W// Private members
' a2 y9 ?7 V& l6 {. d1 N* tprivate:- N3 y6 k$ h( P( T
DWORD m_tLastEvent; // When the last event was received?9 F/ G; F/ o, ?" s! F2 Q0 Q
std::vector< DevicePointer > m_pDevices;
0 _& d% ~' ?. f! b+ z) n7 h std::vector< ServicePointer > m_pServices;
3 _4 P! w; T6 w; @ FinderPointer m_pDeviceFinder;5 a( J/ n1 S) S3 {$ B2 }; p. u
DeviceFinderCallback m_pDeviceFinderCallback;) \8 \ n- u* ?$ ?% m
ServiceCallback m_pServiceCallback;
! ?6 R5 Y% P# G; a2 L( U5 V) b* y( d0 ?
: D! h4 |$ S5 W9 w1 c/ I5 a. M LONG m_nAsyncFindHandle;
$ X! l) G( E' B* p bool m_bCOM;0 y3 n8 S- d$ T$ W1 y( i" w
bool m_bPortIsFree;5 v, Q4 H( g+ V0 |
CString m_sLocalIP;5 P. n$ N6 {! G. d T2 G
CString m_sExternalIP;3 m% J& L* U& O! m `
bool m_bADSL; // Is the device ADSL?
! X% H* |: X" d. a2 { bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
) K' y+ w: ~0 v& y bool m_bInited;$ g# b: e* I( l- |: H5 D
bool m_bAsyncFindRunning;
+ j0 |3 u1 H" O6 g- y+ f HMODULE m_hADVAPI32_DLL;& D! r2 J _: P% Y6 Z
HMODULE m_hIPHLPAPI_DLL;/ u+ j2 J9 x2 ?6 R% y
bool m_bSecondTry;
b2 N% R6 m& \; t bool m_bServiceStartedByEmule;
' T6 s( x1 I1 K" { bool m_bDisableWANIPSetup;
4 ~( t& Z( c8 |3 P; E bool m_bDisableWANPPPSetup;
+ }- }' J( o: @* l0 W# v! ~4 y, ~! v* P- f7 Z L
" D, e$ f+ e0 U2 s: f) x: }};
% A& N3 V- v" c$ R3 ]7 B+ S* h9 N! I! x6 T: q7 `% @, J
: i4 }1 _4 B( J5 }0 N// DeviceFinder Callback
+ i; c! G6 R( m( b0 Eclass CDeviceFinderCallback. ?5 f4 n: r3 f+ v! a5 I6 d
: public IUPnPDeviceFinderCallback7 p& X1 v. A" b; h
{ y/ b+ x3 [/ r" D2 z }' C
public:6 z& Z: |* s5 J1 h8 \7 p' g) q( T
CDeviceFinderCallback(CUPnPImplWinServ& instance)
5 k2 H) y- _+ S- o) H5 R : m_instance( instance )& F3 s7 f! i [4 { R4 K
{ m_lRefCount = 0; }
5 a5 p4 ]. `0 m4 v3 |4 V' x2 ~/ e/ Y4 t. B7 m
, T5 h9 k, t" b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);* w, V6 l% z5 Y+ D$ L1 I% ~5 m
STDMETHODIMP_(ULONG) AddRef();
7 a- N1 U3 B1 S9 Z3 l2 {1 k STDMETHODIMP_(ULONG) Release();
# U h5 T1 C4 C; u! H; B4 P; q) R+ `
! Y. m! k& I0 f1 P6 f! S// implementation
, g. W; y% C) Lprivate:( z2 \5 e. t4 Q7 n0 g
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 S' r; {* J8 o8 O" B
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);2 @+ h$ G: F8 D1 w( U; ?. \3 R
HRESULT __stdcall SearchComplete(LONG nFindData);7 z: n. M, r& t* \% z- m
2 q9 n2 r* h) j* l
* k' ~4 l) W7 j+ B& Pprivate:
: S# m: U+ p) p4 e# t2 u: c CUPnPImplWinServ& m_instance;
! f5 N$ w! g j! t: L1 S LONG m_lRefCount;7 i8 i# C% w) [0 N8 ]5 o
};
# h* s" l" V7 @2 b) N
& ^2 `$ t0 v2 @- \0 `; ^7 \6 h3 }6 T/ ^* C4 Z& P
// Service Callback - v* b; N& B* ]4 U1 W( b
class CServiceCallback
( Z- J" z7 W; j; a y! ~, e : public IUPnPServiceCallback, A: W- a- m! P, W0 A; R! g/ F
{
+ A. J9 ? \: I8 G }7 @public:, V) G& j7 z( k$ Z+ e
CServiceCallback(CUPnPImplWinServ& instance)4 G3 Q& T# m6 q* l$ |
: m_instance( instance ); K: ~+ h. n' b
{ m_lRefCount = 0; }- p7 Z+ j3 |# b8 P
# L$ ^# E# n) x1 _% ]+ \
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);7 B8 Y7 S3 M, `; z% j! G6 _
STDMETHODIMP_(ULONG) AddRef();
. @( O% f: U) ]. D8 _# g STDMETHODIMP_(ULONG) Release();! f8 l5 p4 X, h7 \; A3 y* o- \
# P; ]$ J& @. t
) \" u7 _* R; C% y. r
// implementation; Q5 @. f; Z. d# t$ {) }. w
private:
: A; n" w9 @& t) ^0 t8 y HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
! V: s+ s' z M& d4 ~- z1 Z. s; w/ d HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
2 H# E+ U4 H x* E
; V' {, W% @+ q
, F8 p5 z4 K0 f/ A; q- a1 qprivate:7 y0 O! E- D- g( q- N" V$ P
CUPnPImplWinServ& m_instance;
6 q2 F I. H1 }8 q1 H8 J/ y7 g LONG m_lRefCount;
1 R+ B# ~% I5 I2 ~};( y% m; h/ t; T) d! W
8 \& i9 z: Z0 x6 X' e z
- a k) |1 y8 Y" z# h- e/////////////////////////////////////////////////9 y( t6 w- _+ V
" M# F8 k9 {6 O8 x' }- K4 u
8 @ w, U8 h3 s% P% k5 F. R0 o8 Z5 g使用时只需要使用抽象类的接口。
2 ~+ B0 i% `$ kCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.2 B# r5 N6 u& s3 o" ^& F6 Y7 W2 Q: P
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
7 C- j0 o v9 UCUPnPImpl::StopAsyncFind停止设备查找.
/ n, K2 j5 J# v- vCUPnPImpl::DeletePorts删除端口映射. |
|