|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- r, y4 K5 L& x. E6 V
) G: I( G) I5 C9 T5 k' H
: p' I R' ?* i. V2 j/ T
///////////////////////////////////////////& o3 F% J7 S: w e" d
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.4 T* V. ], e- Y; A' q9 n7 w
: l9 _3 U, {7 O8 h( l$ k$ y& ]$ X) s9 k1 @8 l6 C' W2 ^
#pragma once
, w' ^- s6 p+ T5 u, {% A+ o#include <exception>
' l$ H0 `9 l+ x2 T* C
+ f% F4 e0 u' v& u
$ d5 Q( X$ i3 U7 \ enum TRISTATE{
; K( m* F, ]! o4 u* r4 h TRIS_FALSE," u+ V' S# P! U& V2 Q; c- r
TRIS_UNKNOWN,6 i) T& g* u$ s- ?& Y6 }
TRIS_TRUE
0 W; F/ N0 o9 {& `9 o' s$ x};# F4 {% p* G0 d4 r4 X
, U1 j' o6 J. P' k: p1 H) w9 |5 b& ^6 z3 W) }
enum UPNP_IMPLEMENTATION{9 |+ |- F/ z) o8 p. n, f
UPNP_IMPL_WINDOWSERVICE = 0,
+ d5 u! i6 [, @+ P. O UPNP_IMPL_MINIUPNPLIB,
' g% q$ a) _# {2 ?# F. W }4 L UPNP_IMPL_NONE /*last*/" G4 |$ b" a4 R! F4 }
};
* H. s7 p+ E$ ~3 V9 g/ {" W* E+ ~# G7 I8 l/ H0 u$ i
- j' V: ?1 E4 ~9 ^4 h- w" L/ ?8 ?+ w( w
3 s+ _. K, c! A8 K
1 b" Z3 B; N; C6 D
class CUPnPImpl
8 |7 w3 c- g" C4 Y' Y5 E{2 W6 M3 \/ z9 C7 m: T; h3 Z
public:
9 V/ N* ?& T0 o# d; b/ U CUPnPImpl();) o4 n/ k7 s+ \+ k
virtual ~CUPnPImpl();
- {+ r$ n& C) f5 c' m: ^+ T" e& _ struct UPnPError : std::exception {};9 z6 b, O' N. b) n# K
enum {
2 r+ u* s" D2 |1 c' d. J' c UPNP_OK,
+ |* r" w. y( B8 ~7 D" n UPNP_FAILED,, k4 t& B0 W3 o% i
UPNP_TIMEOUT& o8 z2 l, q. J! q3 U
};
( Y) G5 D! [# P# }9 a& c
; {, l5 ]0 M, \- {, N2 G0 N w
9 B: G7 u9 O7 X& g! R1 x1 S virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;2 c% g- W& m/ K4 \
virtual bool CheckAndRefresh() = 0;
1 a7 A) E5 H3 k& r$ ~8 R# y virtual void StopAsyncFind() = 0;' G. i" h6 J" G/ |
virtual void DeletePorts() = 0;0 O# B0 U, W) p1 v$ j2 z9 x' u c
virtual bool IsReady() = 0;
8 ^4 `& K. Y6 @, l4 W- D7 T( L virtual int GetImplementationID() = 0;
5 D5 ?2 G- S. h' V/ T , [9 I7 K) J# @. z2 O
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping# d- |% x; x x6 j1 |5 U9 L
& G" {) b: ]+ P% I V" ?, _9 Z
6 b2 j: j9 L# r3 n/ U8 y( z
void SetMessageOnResult(HWND hWindow, UINT nMessageID);7 [1 N: }* Z2 r) t/ ~7 k
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
% H( l: K; J+ Z; m; A3 R! S I- \ uint16 GetUsedTCPPort() { return m_nTCPPort; }
5 O7 C/ j' T% T# L uint16 GetUsedUDPPort() { return m_nUDPPort; } - n: G$ A* J ~) E8 Q
( ^ Z5 Z, m4 c; p* s/ F% d
5 T! l& n. Y; E3 G) ~: H
// Implementation
' ?" \3 g3 v9 D; [; O- lprotected:! f) ^# G" d$ l9 R6 p3 L; l
volatile TRISTATE m_bUPnPPortsForwarded;5 Y/ N) @3 _! y9 R9 c- y
void SendResultMessage();+ T# x/ L# S; n7 B
uint16 m_nUDPPort;
5 o8 e( h+ a1 z! O/ a6 w' L uint16 m_nTCPPort;
$ m+ E+ ~* n/ @& O/ G z uint16 m_nTCPWebPort;
% c+ e$ R/ w# |, b7 y0 W( \, T bool m_bCheckAndRefresh;
* S' M0 H$ r. Z C7 j
. s% g- m4 b. g6 L" o
" O9 b* s. X/ ]" w$ A# Nprivate:3 O( i7 _$ f( ?; n5 ~
HWND m_hResultMessageWindow;/ Z1 ^- U6 B0 G; G$ J" f
UINT m_nResultMessageID;5 t2 \9 @7 Z* s+ l
" k+ s3 y9 `. }" k: ?, M, y) S
! L' j( I( v* c. D};
+ `* c" j$ i7 Z; V7 Q3 b
5 K+ B. u6 @1 o u
* p( s% c! a: i4 ~# ]6 Q// Dummy Implementation to be used when no other implementation is available8 E1 f' @- e" l+ J4 E
class CUPnPImplNone: public CUPnPImpl
5 ]; P; T5 G7 N9 E' M{( |. W: H( G( }; m+ `+ j# u3 ]8 _
public:
1 U1 v9 \, q9 C- w virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
; W c9 g4 T- z0 p( T virtual bool CheckAndRefresh() { return false; }# q9 r9 Z6 f5 X0 t) K6 H
virtual void StopAsyncFind() { }: Q8 F- ?2 r( W% c. X
virtual void DeletePorts() { }4 q4 X6 F+ y3 S5 U1 q: O5 u
virtual bool IsReady() { return false; }
4 Q) W3 n5 N4 X K virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
3 u/ I5 m) s2 V& h& T};" k3 E! {7 A- `* l5 v* K
" M" x7 s+ Z8 q4 P9 d' U
( E( v# C& k4 y- v2 \/////////////////////////////////////$ g2 C( ^3 U4 k1 h6 c
//下面是使用windows操作系统自带的UPNP功能的子类' {1 F" H9 D# B1 }
$ L9 Y& o2 e4 r" X1 W6 K- x R; h6 S/ ?0 x+ Q$ w% S; G0 p% ^
#pragma once
4 l) H3 J9 J: y+ K1 k5 R#pragma warning( disable: 4355 )
% b' b4 J( n6 B; o: o8 [/ U) P1 S, ~; e3 z+ `* m
* h5 c/ L$ ? J; U#include "UPnPImpl.h"
1 W5 _' ~) E- {% p! v# f#include <upnp.h> k1 e2 ]/ x. f5 k; f
#include <iphlpapi.h>% t j0 F9 i d- `2 Y1 r! L) s' G! ?
#include <comdef.h>" }2 w3 |: o5 k
#include <winsvc.h>
' T' Y/ j5 I1 H* k) O2 ^5 P( j* S9 `. i& [; A5 N+ i6 l7 D
9 J7 L. [1 c0 d; _6 `3 Y
#include <vector>" \/ G% _# w0 o+ _( e& `$ \
#include <exception>& C' \7 v& s/ \, H
#include <functional>
5 S5 i2 G6 u# B2 e/ r1 ?
, W) t2 L% C* r" ]- }) [6 P$ j
2 w& M, M4 i: B6 ^
( t7 R/ Z$ c1 b$ a( I1 l; h7 r& {. k' l) t/ u. c
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
# w3 ?+ v* j( U' P' Gtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;3 Z4 J& T# z" N: c& Y( d
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;& c/ p6 g; }8 z; b
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback; m. B- O0 {( V ?
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
: n$ Q. A7 x, b7 g" W" ~typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
3 M- S& J# T7 b3 q. }7 Ttypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;1 n/ s' {" ?6 ~0 j3 K
' o. o' F2 h- n: ~: c3 Y9 ?3 t* P) [7 o, R
typedef DWORD (WINAPI* TGetBestInterface) (6 `, }! s8 H+ X" r3 z! o+ s0 \
IPAddr dwDestAddr,
% j5 Z5 }) j9 ?7 E, Q. y PDWORD pdwBestIfIndex. O( v% m" e5 j$ S! f# a4 e- C
);
5 C% y; R4 A/ v. z: }7 V4 ]0 x" a' v' B5 e% J* n& A+ d" G
$ k; `+ q5 B- \7 N8 btypedef DWORD (WINAPI* TGetIpAddrTable) (
+ ?' V+ k" L6 ]3 \ PMIB_IPADDRTABLE pIpAddrTable,/ C* D* t$ a2 U0 C8 L. N$ N( x
PULONG pdwSize,; T/ B& z! M' z5 \0 S
BOOL bOrder
" g8 a7 {) U" Y+ s) d' C);: y4 W" w6 Q7 d$ o, z% ?$ t
& @ w) @$ f7 O6 s6 G7 _* p) ?/ B
typedef DWORD (WINAPI* TGetIfEntry) ($ n3 T0 j4 C4 }' b- U
PMIB_IFROW pIfRow2 g L0 M& P6 z4 J v( M
);& F2 i3 u" ]) C/ J
8 g: w1 P! Y9 ~, E( q1 @" L
8 G# |6 Z1 r9 r
CString translateUPnPResult(HRESULT hr);
$ r, I Y7 z) _2 J5 q, h, p$ M \4 Y6 qHRESULT UPnPMessage(HRESULT hr);. }: p4 s! n0 H) N
9 Q+ _4 ^# k/ w/ ~$ f
5 u9 h: f& _& }2 b$ R( V" }class CUPnPImplWinServ: public CUPnPImpl8 j5 R0 g- V4 K9 y5 s" n! @' a
{2 @; g: a! u8 t" R
friend class CDeviceFinderCallback;
/ k4 b/ ^/ Q$ c& l4 F8 z8 ? friend class CServiceCallback;* w" e2 B6 K) X. ~
// Construction
/ u$ E1 ~$ l/ s) Z1 K, s& \public:
5 j# a4 G7 A. `" O' U$ r virtual ~CUPnPImplWinServ();
1 X5 S% s1 J) y0 B$ J, B- { CUPnPImplWinServ();
! v. n& P3 {* Q. `, H2 ], P! N# U, D+ V
' L( A: G6 M/ v virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }6 K' B) N! M/ x9 p+ Y3 E4 |3 }
virtual void StopAsyncFind();6 q0 f8 T# N) F8 \8 S9 {
virtual void DeletePorts();. g3 Y5 E4 }% ~% _
virtual bool IsReady();
% i" C. d! c6 ]% v4 S9 ^ y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }* N8 @; w- K/ p- I0 ?
1 H5 D& z$ [; m7 J) Y
" i" Q8 C8 f" [' i) l* O // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 q: B$ N6 R# V; ?3 a. f$ R // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later' { e, [1 n7 T, S4 M8 Q' `
virtual bool CheckAndRefresh() { return false; };
( ~2 q, m5 J! C! _
" ~1 [& b7 w8 ~5 V8 l" `( h
K$ C/ H4 t5 S7 Xprotected:5 D& L! }% E& r/ ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; p# [0 A. v+ t, C: k. p void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);5 V7 w9 k s; C
void RemoveDevice(CComBSTR bsUDN);+ e5 Y/ ]6 Q$ s6 ~- W0 }5 e5 b
bool OnSearchComplete();8 U% r+ \8 z/ s" y
void Init();' }" R, b5 l, i5 {7 R0 [% |3 k# H
, W; K- }* U* Q
' j& z3 [& M! ?1 r$ D6 { inline bool IsAsyncFindRunning() 1 q% e3 j& k5 b/ ^5 e2 P
{1 M, I+ }/ @0 `' L" y# g9 ~* a
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
5 M9 _ o1 Y3 a4 _. o {
4 s! I) Q! H0 S, p m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
7 V0 J2 s) w% A, r0 _ m_bAsyncFindRunning = false;
! D- \6 B0 x0 s4 K }4 m3 J6 C( d2 I5 R
MSG msg;+ b' E0 {, T7 H. ~! p, X1 |- h4 `
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )/ z! s A. K5 P" M: Y0 ?
{. [: r. S y* f( k
TranslateMessage( &msg );8 w5 v* A! d( t( O
DispatchMessage( &msg );
! S$ U( R% ]2 I( {- I, e% ?9 t }$ Q4 j" G% Z! B" `. p
return m_bAsyncFindRunning;) P, F+ u; Z2 V4 i
}5 a5 q) G5 x4 e! L7 j2 V. F
/ Q5 n- l' F' y* z
. w1 X3 P# P: X0 ~0 L( M9 y TRISTATE m_bUPnPDeviceConnected;
- I- L$ H; v# `0 A6 z/ ^5 E: S- ^3 s
8 H z3 W/ o2 a$ {
// Implementation
( u" ]# J1 D; t // API functions" u- ^$ O! C5 [/ \
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
% {: E( F8 W6 l8 ^ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);. P# }' M4 W2 v! Z+ Z
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); w8 N' x H9 L* ?
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);) G4 N( n7 f! n5 _2 a. V6 g
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);" ?. |# X5 p+ L5 @. k+ B
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+ h4 h- Z8 X. W; j; {, o( f
F! E5 s9 R. p% D* T5 u1 e" i1 Y* W7 C3 i% ~: L# h
TGetBestInterface m_pfGetBestInterface;0 {7 |' W3 ?5 Q6 l) N& b9 _0 ?" Z9 v o
TGetIpAddrTable m_pfGetIpAddrTable;) v& o7 e$ M" r" R0 O% t) w
TGetIfEntry m_pfGetIfEntry;6 t; m' X( a6 A
) E, r4 Z3 T) n/ G
4 p! m" ?; `6 H! o; w) H( d static FinderPointer CreateFinderInstance();
9 V+ `# B- `- D* b7 b struct FindDevice : std::unary_function< DevicePointer, bool >
( _! [# s! @5 z9 L$ D {# W8 P" G/ e. P$ s5 t# e0 }
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ L, \4 W! N; ] result_type operator()(argument_type device) const( i9 A: }& G/ k2 P# ] z" \7 Z
{% J. ~4 E( }. G3 m5 x
CComBSTR deviceName;# ^" R, E6 l: o) T5 ~# `
HRESULT hr = device->get_UniqueDeviceName( &deviceName );- w- G4 l6 V _- h
, @# b2 C" Q6 c9 ^# ]" a' P6 z4 t8 y* [( |: d4 R
if ( FAILED( hr ) )
4 |+ u' p4 }$ z# V return UPnPMessage( hr ), false;7 l8 p; `6 J" q B8 }0 Q
7 D' R& Z. ~) Z, u ^/ J7 T) J* y8 i) B: ^: I4 K/ t/ L6 n. b
return wcscmp( deviceName.m_str, m_udn ) == 0;9 G; h6 g/ p3 h3 w' ?/ x0 ^
}7 C8 T* }6 s, v% e0 x
CComBSTR m_udn;$ O3 ?/ [, X0 t8 T
};" o& k# a4 Y$ `9 X: u
3 P, ` _3 y7 _" K5 g/ A( T
void ProcessAsyncFind(CComBSTR bsSearchType);/ N; c; n. ]/ A" k6 r; W4 t
HRESULT GetDeviceServices(DevicePointer pDevice);8 x& | T! R5 d( [" G2 n
void StartPortMapping();
8 V# Z! w$ @! g" R9 ~/ C' y+ f+ y. [ HRESULT MapPort(const ServicePointer& service);
* F2 z) p" n0 Y6 W4 |# C void DeleteExistingPortMappings(ServicePointer pService);6 E$ j0 v, I6 _* f, R# K
void CreatePortMappings(ServicePointer pService);
1 {. ~% W1 I7 N* k/ h8 ] HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ m6 k6 }# u4 G+ j HRESULT InvokeAction(ServicePointer pService, CComBSTR action, - y/ q; e; b# q o$ q; k
LPCTSTR pszInArgString, CString& strResult);
9 K$ Z0 q5 `; `/ H: j; R void StopUPnPService();
2 j$ I! \. E1 n0 `1 P( R2 F* J
! v, K/ e& H- i* d9 V7 v2 P o+ \5 h7 a
// Utility functions
: q9 m7 f( y7 k! D& R# r HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);7 g! X1 I% T1 ~3 m# G
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* Z2 G* K" ^1 q* t INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* |- S, @$ q9 D void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);/ E3 M7 ?2 k; t7 S
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);4 G# G2 `( x( R
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);& K# F9 b4 D4 X) g
CString GetLocalRoutableIP(ServicePointer pService);
* S. i% b' s9 \: U0 D
3 ~* b6 M! ~% z$ C% e- ^
, e! A1 Z7 D+ t% I1 k' `9 Q// Private members
$ g' n- |# i L0 n$ `, Q) Hprivate:: v& z4 X* m, ]. C5 P" K: A
DWORD m_tLastEvent; // When the last event was received?
$ e& y+ L% z5 v& q7 i4 X8 I+ H1 @ std::vector< DevicePointer > m_pDevices;$ X# M" {0 f% Q+ D0 \" L
std::vector< ServicePointer > m_pServices;
c$ G& ^0 G t9 D FinderPointer m_pDeviceFinder;
- R' Q. A( R$ f DeviceFinderCallback m_pDeviceFinderCallback;
0 ]+ b3 b# b" k8 W* E$ r ServiceCallback m_pServiceCallback;7 A" M `5 C% T# l- \! ]4 h
$ e3 |! f) c4 Y" z0 y E6 N) `
2 Q& }' C; e: E
LONG m_nAsyncFindHandle;
1 V4 ?/ e+ M" i- r bool m_bCOM;) \( u; A& S9 d, K9 ^1 {
bool m_bPortIsFree;
4 c) v, n& X7 {/ q CString m_sLocalIP;
3 {- n8 `7 i. ~" w& p CString m_sExternalIP;
- G/ @9 |1 P% v2 C$ |. J bool m_bADSL; // Is the device ADSL?! a( A1 E' d8 L, R2 i8 o
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
/ e1 C7 `" n F& Q" k$ p bool m_bInited;: z& G$ I/ x1 q$ Z/ W5 g0 V( K
bool m_bAsyncFindRunning;# R& N* x- W. X3 Z6 k. U2 ~+ r
HMODULE m_hADVAPI32_DLL;+ t9 @6 H/ ~2 G. ~) \% v4 ]7 m: v! d
HMODULE m_hIPHLPAPI_DLL;- [! \$ @0 D5 l6 v8 Q8 A' A
bool m_bSecondTry;3 c: q% U5 K9 u, }$ l/ N& W
bool m_bServiceStartedByEmule;/ \2 k* ~9 o [: [% Y. [" F
bool m_bDisableWANIPSetup;
% ?/ }, I* x. ? K. e+ I bool m_bDisableWANPPPSetup;
/ Y) E, J# U$ _7 @& @* I- ^3 h
+ M* H/ c/ T8 s; W1 k# R9 B' V& N& n6 }' _( H+ I& E
};
- J5 x3 b5 r# y% `! q D
* c) a& o0 H d/ y8 }( s: K4 o9 z: r. g2 }; _$ s8 q( Z) Q) R
// DeviceFinder Callback# y6 R d4 x# _
class CDeviceFinderCallback
+ A) q. |( L8 R, D% q. t2 Z : public IUPnPDeviceFinderCallback; g& e7 @& H, ?2 `3 z
{
8 i( c1 _9 H# q0 c* `7 spublic:; H. g, Y+ B/ S0 c. U4 l- G/ j
CDeviceFinderCallback(CUPnPImplWinServ& instance)
) q% o/ B6 s! I) {' H : m_instance( instance )
- q, e9 q$ m4 s7 f; h { m_lRefCount = 0; }
$ N8 Y8 V+ x5 A5 f; n" C0 O
: V' s0 A$ E$ d2 \1 _8 Y1 E
* F3 ~7 P: R; C6 r9 P STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 L6 [* u4 R$ @, }4 D STDMETHODIMP_(ULONG) AddRef();6 c8 W' P, Q m+ ?
STDMETHODIMP_(ULONG) Release();
/ |7 ]( P7 U$ j) b G* K
) o7 Z( R! @/ q: K# l0 O' M- E# ?3 c, K: s
// implementation+ u, u+ j) w9 ]- `
private:7 v F* v$ X; s, ` @; g
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
! }6 b ^8 D6 B5 e# n8 O2 V8 N HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
' t9 p2 D5 z9 s5 X3 ]; j- ` HRESULT __stdcall SearchComplete(LONG nFindData);
5 i# j+ c* S1 I7 q/ S* b+ P
/ E. ?) z' K7 o1 i2 ^
- p+ u6 ?7 a& _$ W% Eprivate:
8 ^$ D) R" h* }5 I CUPnPImplWinServ& m_instance;* a/ c1 O, x7 }& g; u" k
LONG m_lRefCount;
& B# q: t/ m4 p- c4 `; T};: b3 Q8 p1 e+ S4 W& \! ]
0 ^7 K& _; O8 f8 c# \1 J' s
" `' X) Q# f6 l9 [" }* u1 |// Service Callback ) j! B3 I/ \$ H( P7 J, P
class CServiceCallback, m3 W# _8 K" }/ H1 ^- C
: public IUPnPServiceCallback8 u' A$ o' a) l4 [
{
& C1 {! J) Q/ N* @) M/ upublic:% P4 a. z$ E- f! z: \8 \& Y6 G) g
CServiceCallback(CUPnPImplWinServ& instance)
! y6 y4 a! R* M( ^1 q! Q f : m_instance( instance ); i: E! y' e7 W1 ^, m1 J
{ m_lRefCount = 0; }3 o8 A- Q' U) s8 \
) _* x" L7 t* U* I: N/ b4 ~
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
6 y4 f" s3 z9 W1 ]+ h STDMETHODIMP_(ULONG) AddRef();
# @8 m& N' n, ` g( w$ L STDMETHODIMP_(ULONG) Release();* K* J. Y1 Z6 c- p. w: ~0 R
# T' m/ S9 v9 d) K5 ^, H
9 j" t0 w( T0 q' J6 v: p# E
// implementation! B$ c9 l+ e* D6 s3 ?+ R( s
private:
2 e9 r' }) d- L HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" R/ d! Y% X# J3 }5 J
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);! |! w) B- S& f% D
/ O& d5 M+ e0 a) l; I' ]9 I
' j' H4 P$ n: ^) _: x9 v& J: s/ Zprivate:
' F0 B& y# f. \2 S/ i) a CUPnPImplWinServ& m_instance;) c* F/ U) R3 j8 I! i$ [
LONG m_lRefCount;" ]& m3 R; u7 ]0 C- B! g$ R* c
};
[8 M) J) B4 Q* G: k4 j( `& j* z3 ~2 C% `/ n; _
+ Z; H- R$ M' Q, @
/////////////////////////////////////////////////. a. v/ @/ }+ F
$ x; p1 b& I) `* s- [. S; d, v: u1 ^! i' A$ V0 T
使用时只需要使用抽象类的接口。
& G+ Q) l% Q! U$ PCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
. }) k7 M$ d, C( m# MCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
6 }: h1 k P0 ?. W+ UCUPnPImpl::StopAsyncFind停止设备查找.
3 E, j# P6 B7 d. WCUPnPImpl::DeletePorts删除端口映射. |
|