|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
0 r6 C/ w# O1 F
, m8 @1 x% D4 S3 J' J" S1 S
+ Y8 N5 A2 c/ @, p. w///////////////////////////////////////////) n: k! F( o T# o/ w
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.2 c! `0 L7 L' A+ V+ Q
3 @% Y* F/ B8 ]
7 `* p& u& t" c+ T( Q) Y#pragma once
; H1 C, b7 A/ ^9 W& |#include <exception>( _ W9 q L/ N& \+ S
% M- Z, L7 S S6 l( c6 }! u+ W3 ^0 e/ s- W% ^" l
enum TRISTATE{% l( _. i/ W2 j7 O. @
TRIS_FALSE,
* X6 x1 ]0 U* C8 G TRIS_UNKNOWN,+ ^; t- K% {: n ~7 \! L K
TRIS_TRUE
! F' d: W$ C$ b, Q' F};
& f$ N E' H& D: Y! c# h. j
) T w+ y: |! e M9 e* G/ m. r/ d# N7 J- D/ o6 z5 v) F
enum UPNP_IMPLEMENTATION{
/ S( v/ L9 q9 a- Q$ [ UPNP_IMPL_WINDOWSERVICE = 0,
H8 @1 c) ]4 t, W% x UPNP_IMPL_MINIUPNPLIB,
0 u& x/ _/ L: J9 C0 Y( Q UPNP_IMPL_NONE /*last*/
$ @8 ]/ j( p9 X4 M4 f9 r: u};
3 j# @4 m9 P, t5 M' H6 O9 O9 B) c9 [8 G$ f* [9 F
1 q3 ]' {$ C* ^5 v( Q7 g; r* j4 Z* c, U
8 j2 ^3 |+ \2 i i [! \class CUPnPImpl
9 b+ `) i, B6 [{- c7 x* ?0 U9 ^* N9 z; i
public: w/ r4 h4 Q N' p! ~" ?' U% c- Y$ c
CUPnPImpl();
/ n7 d& o5 [; E1 D virtual ~CUPnPImpl();, l' { u6 X0 r: C+ P
struct UPnPError : std::exception {};
! @" ]' G' F% q( e7 s enum {
* Y% e7 ?. d* b$ B UPNP_OK,
|2 }9 `/ F9 e$ ?4 b6 m UPNP_FAILED,& D& \! l8 ^! Z* C5 l9 G
UPNP_TIMEOUT
- H( M8 Q! g- c. A v };
( k: v4 ?% @7 M
- z6 k3 O ~ | a% | w8 m% w6 U T" E5 h
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" a: t6 }/ E" f& d; k% Y+ B. i
virtual bool CheckAndRefresh() = 0;* v0 \' n9 u9 S+ c! c
virtual void StopAsyncFind() = 0; H; P, A# J. w
virtual void DeletePorts() = 0;: f* V/ K8 {4 V. L j' k; Z4 W
virtual bool IsReady() = 0;
& x/ e) T+ `% r- U9 J+ V virtual int GetImplementationID() = 0;' u' X' V, K, @7 w+ E! M/ V2 X
5 Z# T; M5 w4 ~ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
, C0 s- B2 I" X% \, a1 t D9 V3 d U; k
; U2 s$ ?) t% k9 r, X void SetMessageOnResult(HWND hWindow, UINT nMessageID);
0 v" q5 f+ u2 u: l2 q% [. s3 u' K& Q; U6 D TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* [6 M4 a8 I0 q8 l- P uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 i0 c% C# f3 m3 t k- c; G* d& v( Y uint16 GetUsedUDPPort() { return m_nUDPPort; }
# v2 E7 H$ o+ i" s- E
- U1 ^( @' C* I+ d4 j" B7 x) j' t( d- E) z3 t; x4 @+ J( \
// Implementation
- U* l6 E# x! P# Lprotected:
/ f7 v/ [1 B* j: g6 y9 }" A# u* U# ? volatile TRISTATE m_bUPnPPortsForwarded;
' z( A. m9 A% B$ H$ I4 s. M void SendResultMessage();
6 y4 \6 G" P$ A7 e6 c' p uint16 m_nUDPPort;
+ z1 F+ [. R5 x$ X uint16 m_nTCPPort;5 C9 D# `9 K9 u$ @+ c
uint16 m_nTCPWebPort;
: L: _3 ^6 G; k# n/ F bool m_bCheckAndRefresh;! ] ~# z$ Q& i
8 \6 `+ G3 [* l- U3 H
5 p% E# I2 L, J+ W \& a0 i6 @8 x
private:& W8 L9 s: q0 o
HWND m_hResultMessageWindow;5 g* R1 N+ I/ p' J
UINT m_nResultMessageID;( b+ @( c. C) N) q& E
; B" Z! F3 z+ V4 w! `& i2 V
9 G" f' Y4 b1 p. w};
/ M8 k1 m% [* L+ J& L% ?
0 }6 h( g+ [/ t9 V4 y r) q+ j: f% n' s! J& h
// Dummy Implementation to be used when no other implementation is available& X! X( q/ K6 W* G
class CUPnPImplNone: public CUPnPImpl4 \ M1 z/ ?7 ~+ g
{( q$ o' m4 R/ G+ J: Z
public:
! R6 ]) W: Z* c& O& H. S virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }' R S2 G' }8 o
virtual bool CheckAndRefresh() { return false; }+ H6 I. e6 o0 n9 k0 s- \
virtual void StopAsyncFind() { }
5 Q( K A, z- Q2 [: Y virtual void DeletePorts() { }
; u- K {- z$ o- s! C7 a virtual bool IsReady() { return false; }1 |2 `; Z6 x% D
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 ]8 |; R: ]( R e- F
};$ i6 p1 g' Q: U' r
O3 s* F% N8 |/ t' ?8 [* D
8 t3 a+ o8 e% F. k/////////////////////////////////////
3 d) t2 I2 `' C( N4 j//下面是使用windows操作系统自带的UPNP功能的子类
& X+ \$ b! K7 D0 j% H4 Y' E7 W( b A
! b8 H9 P, c' l" S
#pragma once
4 L: l( |( g- [1 X9 w#pragma warning( disable: 4355 )
. t. L0 Z8 F- w( H9 W7 g! M* I$ S0 U% v4 c' c7 m' E
/ L+ K% o6 g& ~# i' z s#include "UPnPImpl.h"
0 n; G# B% Y6 Q3 r/ b' z#include <upnp.h>6 P2 P( O3 F4 U$ @6 r( J: l
#include <iphlpapi.h>
' U1 W8 s v. q6 n$ }#include <comdef.h>$ [7 z0 S W5 J& a" h) H
#include <winsvc.h>
# e( ]4 Z% ~& t8 D
) m/ j* j- R" i" b: [+ I5 C
4 L5 J4 S' i6 m, x9 ?5 q#include <vector>
" z7 r% [% I. F) @8 A( x#include <exception>2 o) S& B7 _9 L: Z! x: j# u
#include <functional>
3 J& l3 N3 L* O
& H2 U5 [( `5 n% ^+ j5 a8 d
% q" g& C/ U3 c" b- J
% l: g0 T5 H) I! f$ V1 M; T
* Z& ]* d4 G& G' wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
4 o; @" m9 [; { btypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;3 V, d8 D+ p- M) U3 @9 l4 B
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
. Z) N/ |/ s3 V/ B |8 otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 i8 K$ {2 @, K. C2 l
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 b/ ]5 @4 a% z7 r! @* k/ Ctypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
& z7 G. u4 J) t/ {0 w: {typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
, x# k9 U3 ~5 b" q( U8 u, ^9 U( J- E
8 k2 a1 h3 a9 f! \typedef DWORD (WINAPI* TGetBestInterface) (
" {1 S2 {6 w4 _+ a1 T7 W. ` IPAddr dwDestAddr,2 _ C" I1 f. b/ U, i
PDWORD pdwBestIfIndex
* I" U J9 x1 M);* Y8 R) Z# N+ ~( Q
9 K8 h U; t# f; I* {
* }" X; }5 o0 a: ^7 v+ ]typedef DWORD (WINAPI* TGetIpAddrTable) (
5 @' m% n; N$ w8 a9 O% P) l* x PMIB_IPADDRTABLE pIpAddrTable,+ ~, |( A: |7 X4 O% c$ B' A0 z2 V' r
PULONG pdwSize,/ T# c+ `0 v, L( ~% J3 W9 m# ?4 l1 a
BOOL bOrder6 J" a0 R- [/ v5 Z1 L. S& G) e+ Z, L) H
);
2 ?! `' o2 Z! z+ e L$ y2 p m
6 S t1 M2 u& Q
) C1 M( n* \" D1 o9 y( X7 G6 |" [4 jtypedef DWORD (WINAPI* TGetIfEntry) (; \- k, }9 @1 h: T: k; e
PMIB_IFROW pIfRow: G/ L A7 i5 r: L& y' [6 q+ ]
);) C. b1 W7 \4 F7 a
8 J. K% X& o" Z3 ~1 i
$ Y7 T- T5 a# S7 l% L. \7 ]# YCString translateUPnPResult(HRESULT hr);4 p9 ?) o5 P2 r( p! ]
HRESULT UPnPMessage(HRESULT hr);1 F2 y( [) P3 u) u: p
) R, |) C: f6 f: n) O8 g( g
0 d- p4 H ^! L o; q' nclass CUPnPImplWinServ: public CUPnPImpl a) R; _0 ~% X4 i9 n2 F* g
{' c ]% h" @3 C; {0 n7 T
friend class CDeviceFinderCallback;1 d! T& [& u- Y' K/ T$ }# m
friend class CServiceCallback;9 v& t; n5 x0 O, r2 M
// Construction
; O! D4 C! L7 `- }) Epublic:
2 l" b. t9 e5 j) ~+ z: O4 Y virtual ~CUPnPImplWinServ();
2 s9 I* |. o7 H* [9 W" \1 I) d; \ CUPnPImplWinServ();
2 Y4 l, y6 {8 T2 P) g9 R" `- ?3 O- R) t
9 Y/ Q; ?4 {9 j/ b& ?' q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
6 |1 k0 L; }1 Y' ~5 v" n virtual void StopAsyncFind();
' [4 a6 @' @" T: C( V1 F7 s, N virtual void DeletePorts();1 I! Q, o, T& a( p
virtual bool IsReady();
& F, r; s- ^0 H9 [4 x3 K3 ` virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
! ~/ n6 n& `1 F* V# m ]) j2 c3 l) i* t3 b$ u
0 h/ z2 [: [7 }6 k% u. p
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. a- J9 |. o2 Q: k // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later x) g) L! r1 X2 M- P
virtual bool CheckAndRefresh() { return false; };5 c ]8 S! J+ O/ c) F) d" a
3 {+ z) ^9 @! P: {0 p
5 B5 ?) ~( w" b2 F' E z) v0 lprotected:
1 ~- O, d7 b& H( a1 {! s3 A void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);" S. w1 a7 Z9 l5 z
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
+ a$ s( D& k: G# m X A void RemoveDevice(CComBSTR bsUDN);5 _4 N2 s: n# x+ G, S
bool OnSearchComplete();: o' _2 y% L* g! k F2 }; v
void Init();
$ G3 g: ?3 V) J1 t/ d8 |$ E+ W; m6 S
" u' E0 F, _% H4 x# ]: L1 j& J! }3 s7 X
inline bool IsAsyncFindRunning() : w" @4 `0 h5 Z, ]& i
{
, g7 r' S( X! k. g1 e8 ]% y, p if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
# c$ l" B+ V/ M6 u {3 m, i6 O* B s& {
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 }: |7 c2 [8 ]# Y m_bAsyncFindRunning = false;% ?4 W* X. s6 J0 j) E$ Z
}. l" @" _5 n' s/ J/ `8 ?9 G
MSG msg;
9 j- G5 U' N7 G. n! `% J( { while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% e0 {& H2 b5 Z1 @ { R/ A3 a, V0 R
TranslateMessage( &msg );* W9 D! V: `+ z8 S9 V: t% y% X
DispatchMessage( &msg );
( Q5 V4 ~) T8 U, A }
2 w+ A: L2 ^6 d% M return m_bAsyncFindRunning;
/ q! z5 K" [; d: _ }
( _* i( G8 f4 a; N( z7 V+ Y% L. x) a+ b, L5 ?. M6 \* e9 ? M
8 n$ l3 w% W: p# V4 p0 \
TRISTATE m_bUPnPDeviceConnected;
% C, F! p6 D% q1 [% N" c" `* }' i# k
+ R( q, u6 D1 B$ ~// Implementation' j6 `' h/ ^" @0 @/ f) X' k
// API functions8 z( C. ~) \* T7 H
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 n5 W. \+ Y# U SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);/ ]$ B- A2 G6 Y% {) C- b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
# _4 K* u2 {* U5 B BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
& I c4 |4 Q" u* E9 P BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% H( _7 v( L) M, Y$ r% @
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);8 Y5 m( A+ k4 _2 w* W+ w
- i' z+ ~% c6 P2 z$ o+ P$ ?" k& I9 }- t, X
TGetBestInterface m_pfGetBestInterface;9 w( k9 O) b, {8 z L0 g
TGetIpAddrTable m_pfGetIpAddrTable;
& b r: n, ?" F TGetIfEntry m_pfGetIfEntry;
" p6 D' w* D1 g8 B* a0 r/ l# w( x2 w$ ^, b [
5 l) s, d2 u0 a! L
static FinderPointer CreateFinderInstance();
) M C4 m* G8 C( H( B# Q struct FindDevice : std::unary_function< DevicePointer, bool >
' J. C1 \' _1 l& F# h/ \, t5 g# ~ {
1 v# F4 U( W |. W& ]5 c: z$ D FindDevice(const CComBSTR& udn) : m_udn( udn ) {}* X$ Z# n, N3 U) j
result_type operator()(argument_type device) const8 Y7 X6 i; h6 D9 d, D! ^/ ?2 N
{
3 T3 a# Y! l0 o8 B+ ~! V CComBSTR deviceName;7 X7 u3 c2 d4 o
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
: ?/ |! Y& t# y: `' r3 a% w, f; Q* C2 Z3 W+ H) _* i& w
# [0 @0 |! m0 B5 Z/ r2 ^3 O* D
if ( FAILED( hr ) )
* {+ X$ s+ F3 F return UPnPMessage( hr ), false;
8 n% L! r, m0 A9 Q7 w+ S6 y: V' }) X( y
3 b4 ?3 w$ D& u return wcscmp( deviceName.m_str, m_udn ) == 0;& n2 c6 }8 W7 y6 g6 r
}& b, v, m( g- ^, C5 i9 F+ _
CComBSTR m_udn;
+ A! G3 P. V6 j( N; H( u. c; C# h };
* N. S. z# y8 q0 k s6 _$ U4 w4 U! O ) X/ }4 @+ q/ v0 L* j) n
void ProcessAsyncFind(CComBSTR bsSearchType);
2 f* x. m& A- `1 D HRESULT GetDeviceServices(DevicePointer pDevice);
/ C& T6 s1 R( w- U* Y void StartPortMapping();8 \8 y3 Y" G3 V5 P- O, Y3 s/ f
HRESULT MapPort(const ServicePointer& service);" [7 d- s9 i, p& Z4 A) m, }8 N: ?+ V
void DeleteExistingPortMappings(ServicePointer pService);
, u+ s& o$ G* a+ J% C7 Y$ J void CreatePortMappings(ServicePointer pService);
8 i6 f2 s4 O( q" o6 \( h& d HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* `2 H5 Q' {# h9 J3 s HRESULT InvokeAction(ServicePointer pService, CComBSTR action, " M& `$ I3 U6 L J1 }5 ^ p
LPCTSTR pszInArgString, CString& strResult);) T" V, X2 s7 _) `
void StopUPnPService();4 G2 ?: z9 j# L8 G$ e) S$ E
$ ^5 t9 O- h* a# L- G/ C, U9 \
b% ~" u4 h- G. J4 m$ ^( H0 o // Utility functions
) X6 O: f0 M: G( D+ t. | HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
9 G- M9 {8 V$ k6 R' B; G INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);, [4 F- A6 Q; Y/ m6 |4 n% Y
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 I; f. S+ U8 ?4 ^% O2 Z2 ^ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);* O4 d- q8 }. @: i+ _
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
/ u+ x. n* ?4 `) v- i( y: y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);" \. Q K8 D" H p2 W( m5 x
CString GetLocalRoutableIP(ServicePointer pService);
! a7 |0 n' L* K( q' x7 {
6 v A. h. ^% V. g \- B) T! E( F" ^8 a9 r. G1 j. x
// Private members0 w) L( w3 k& y' J
private:$ s8 e7 U) c! p6 U! p
DWORD m_tLastEvent; // When the last event was received?# u+ ~7 | a; t7 t$ E1 A# `
std::vector< DevicePointer > m_pDevices;
: Q( z3 `; Z, Q3 ^ std::vector< ServicePointer > m_pServices;
; l4 p' O5 a8 V FinderPointer m_pDeviceFinder;, i0 ]! g4 Y, D; v
DeviceFinderCallback m_pDeviceFinderCallback;5 f2 U: `6 r1 h, B' b. b
ServiceCallback m_pServiceCallback;
8 U3 H! e8 H: R- B7 T) y6 k! _% q/ I9 A$ t3 L1 Y
5 ~/ b2 X% W% W LONG m_nAsyncFindHandle;7 ^8 k' S1 U4 [8 {+ [8 J
bool m_bCOM;' {/ Y6 N& U3 t o: v$ n8 `& s$ N1 E
bool m_bPortIsFree;
) x( {: A0 ~- z# Z# B: g CString m_sLocalIP;
" k8 a( N" e0 U, @, Y- E7 f CString m_sExternalIP;
9 \2 b# O) j/ D+ O- ?" P( k bool m_bADSL; // Is the device ADSL?
. {7 o3 ]) L G" A/ I! Z bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
+ J, T5 d. _# c; @! t bool m_bInited;1 |" @/ R+ @& H% y. c
bool m_bAsyncFindRunning;) P( A$ D( q F. l D: T) i
HMODULE m_hADVAPI32_DLL;
" T4 b. R' ~3 V- V HMODULE m_hIPHLPAPI_DLL;
: ~) g% w$ \* f! t' Z7 G# O bool m_bSecondTry;4 ?0 ~* [/ q! w2 I; t8 w4 V; A# j
bool m_bServiceStartedByEmule;' ~' J% q- x6 L5 `% Z' I
bool m_bDisableWANIPSetup;2 n, P3 Q8 X% ?$ _4 W
bool m_bDisableWANPPPSetup;- ~: s: |* c' x# F& Z' S' N) h
' Q5 X# D% `: h8 f$ @ |
: j, g7 o* S0 B' R3 O1 x};* R. _9 A3 B, r2 ]6 v
, R. W/ f1 _% {: u* P+ {8 z
* v0 ?! O' F* \. {
// DeviceFinder Callback
' n" h' P, C5 F% H7 ~class CDeviceFinderCallback6 U" ]9 K4 y" M! \% @: ?! ?, e4 Q
: public IUPnPDeviceFinderCallback8 l" x0 |% U$ _9 h. L1 G
{
# N+ ?! ?* }0 b0 }public:
& _, @& l% C+ S5 T; ^* A CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ F1 `0 w: Z! m$ t8 {. Z) S : m_instance( instance )& a6 i: S: g$ a, v+ d$ t; |
{ m_lRefCount = 0; }
0 U, Y8 A; F( B& B/ a w
3 u% x: u5 V# \2 N6 l9 X5 b4 x" U/ e: M' c c* \" Z% t
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 Q! H: H( u6 `5 b6 r* m9 C; v STDMETHODIMP_(ULONG) AddRef();* z5 `4 b5 ]2 s2 {/ b* T
STDMETHODIMP_(ULONG) Release();
5 |6 Z9 X& O5 d- J* a- M2 j! e5 A" }+ J4 a( a5 `: a4 a
9 M. e4 j6 a+ K2 U// implementation9 i' J1 Y: c% R) ~& q
private:3 P; A5 s0 ]. n0 ?) g" ]6 f m x
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
( a" Q! `# L1 H9 y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);6 O" t3 x" V+ O; u% Q" Y
HRESULT __stdcall SearchComplete(LONG nFindData);9 m" j: w7 R' r$ E2 u+ Q
5 q( Y- V9 V! j. z# y, \3 E
5 K. r) D* I9 P6 F, L& lprivate:
+ p q5 C/ l% G8 ^* a: h CUPnPImplWinServ& m_instance;4 C+ C/ Q! t* X- s9 i1 s
LONG m_lRefCount;* f# N8 R& T* m ~1 d
};
+ T# y8 T W0 `0 M2 L% U6 M: ]- \, |, l
4 o8 q M8 |& U- k$ A
// Service Callback - n, E. a8 Q0 q
class CServiceCallback: b4 u" ]* v1 I2 y3 a8 t
: public IUPnPServiceCallback* J, A3 m! k6 @3 l( v3 E2 Q
{
6 H* d }" v9 I4 r' I6 H/ ipublic:* d3 t+ F. S9 s; \7 ~2 e
CServiceCallback(CUPnPImplWinServ& instance)
- G& s0 e) {7 K6 P- x6 A6 M4 x! U : m_instance( instance )! A* ^1 C" }) p# U% e& V
{ m_lRefCount = 0; }
0 b- `2 J/ @! d7 E6 B
% e0 a4 A( F' j* d, r STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
u, A* j% K# L+ C6 X2 x STDMETHODIMP_(ULONG) AddRef();
4 O; x$ `5 r2 ? n* P! R/ {1 o" A STDMETHODIMP_(ULONG) Release();: i0 J0 Z4 w1 u# G
/ Q3 [4 d! l' b$ Z$ F
4 S+ }- c/ f9 F: x// implementation6 v: x+ q6 M3 K8 C+ O
private:5 a# O. q. W2 V( v- z* n' @* E+ _$ I! v
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);& Y# |8 } j1 d. j! G3 ~2 J# E- W
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);5 w9 @8 ]# b0 S7 z8 g3 s' t0 ?
i3 G3 o c3 F( L4 Z- Z( P
- e# S5 k( V! G" a* [8 P& j) hprivate:
0 A( a/ A0 _5 F* Y6 j) o CUPnPImplWinServ& m_instance;
* \) H% H4 \: a/ q9 O0 Q LONG m_lRefCount;
1 P) R) l2 y! U% V/ G; E};
3 O; S- R+ a7 M l! O; v" _+ S1 K" q* D! J J7 x. s W3 X
- @! q% C+ O" l& L7 A
/////////////////////////////////////////////////, N9 U* I$ ~8 k6 X
; o6 {3 e6 ]0 X6 A, [% x
; E9 p# A+ ]$ N$ |
使用时只需要使用抽象类的接口。# F0 y- u/ {$ b$ u
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 q, Q$ B5 N9 x4 R, \2 I, s1 _CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 V6 B& r4 D, v; a: [7 B
CUPnPImpl::StopAsyncFind停止设备查找.
2 y0 W& Y. [4 w8 {9 p5 fCUPnPImpl::DeletePorts删除端口映射. |
|