|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ V7 g3 z/ Q$ I: \# E* A T3 F! \# C
; J! W" b6 k" B# U///////////////////////////////////////////
& `- r5 X# O! D9 E6 X0 Q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 i7 @* P p3 o' a+ t
. U+ i" W- J) B0 T! {8 A3 `5 A a1 L! Y' G& {/ f
#pragma once
: e2 {% u, K2 B6 |#include <exception>
5 s5 L" \* F! @! ~& a! [6 R \1 f1 U% l$ P& d4 K6 F: Q
" D! V; x7 {+ i4 w* \ H
enum TRISTATE{
! C G a* I7 L/ _1 a: u: g6 ^ TRIS_FALSE,
* C6 {- d3 b8 u6 H+ W( R& O5 I1 x9 W TRIS_UNKNOWN,
3 L( b& A. D0 _8 d! t0 i- c9 K TRIS_TRUE5 u: L$ U0 \7 V, ?, F
};/ x# w8 V0 \% a& E
- }/ U% X7 ?; R% @
; D1 E8 O# J7 ^* f) f
enum UPNP_IMPLEMENTATION{
2 S5 Y3 K' R& m A& C UPNP_IMPL_WINDOWSERVICE = 0,8 D" n, Z4 {( \
UPNP_IMPL_MINIUPNPLIB,
) ^0 _& {/ ]( |2 ^% E# X8 e, A UPNP_IMPL_NONE /*last*/# a& ?6 Z) R1 E+ ?7 B6 ~4 U
};
# g: S( u" h: H; E6 i
0 |$ ]& C. r1 {3 p- a; ], h6 E l2 a7 g {' F w9 d9 E2 T# I- X
6 b! t" E, P& \* x! o5 |5 o F
3 P6 V% n. S# p4 b9 ]" e3 I7 \class CUPnPImpl
) P! j, o1 ] t* I{# z' O y! g I5 d% K# F
public:9 w% T9 \2 H5 q
CUPnPImpl();
" `9 b: f' N) d/ [& V virtual ~CUPnPImpl();
5 }& ^# o6 U/ b( E) t1 P8 ^ struct UPnPError : std::exception {};
# f f4 y5 E: {& I4 V, P enum {$ R# {4 V0 @+ a4 T: @9 ]
UPNP_OK,* x# {3 H$ Z }
UPNP_FAILED,
`+ b% g, ?2 i1 q5 R* d0 ] UPNP_TIMEOUT
: ?* u% d4 _2 ?; m+ W };
M8 y4 }0 {! R) H( I& B% Y
5 W. L+ [' W5 B: H: e3 H- D
. R( q6 [7 w' h! R virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 O# ?1 H7 O; Q( Y virtual bool CheckAndRefresh() = 0;+ a Y7 q; Q- b% z
virtual void StopAsyncFind() = 0;
7 S' b4 l: S! N6 R% g' Q( \. _6 V virtual void DeletePorts() = 0;
8 p: p+ G5 @" b: ^ virtual bool IsReady() = 0;
4 ^; b) z1 }# r& d5 W" c6 N virtual int GetImplementationID() = 0;' P# X) I3 Q7 S; i+ u
6 Y! ?7 I! o7 N; e) ?; K D void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
7 C, Q& r+ T6 h* m( w
. J! K9 A% C0 P8 ^: Z* C6 |& f! v2 R7 R A/ K( C& C, w
void SetMessageOnResult(HWND hWindow, UINT nMessageID);) ~& t b$ N5 n9 _
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
9 s( v4 E5 \4 o$ v( p4 W+ C uint16 GetUsedTCPPort() { return m_nTCPPort; }% o; G% m2 F) U& g, y
uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 z. S' r, y* O- ?9 |, a/ d5 g Y/ U- s4 c( C6 Z% G7 A \
" C( I+ ~ U M
// Implementation
0 w; T: Q; S' V3 C, vprotected:2 R; L1 f, |) _, ~- G9 ~! Q
volatile TRISTATE m_bUPnPPortsForwarded;$ S# B; s7 j6 B$ _5 t8 g
void SendResultMessage();) o$ {1 t% t2 u1 z9 b. N" U$ B) Y
uint16 m_nUDPPort;
* R. s9 X, K. D0 ~ uint16 m_nTCPPort;
1 u& M- Y _7 D) F3 C* u4 N; k uint16 m_nTCPWebPort;
3 h5 e2 b2 U( y! ]" r: e- @5 c bool m_bCheckAndRefresh;
2 w* Y0 x9 v. Z0 w& K* b2 r# U0 J4 | i6 L# W: i% b {
# [5 E$ v9 ~5 v8 e& p; X2 i4 Aprivate:- c: G8 G. G' Y! ]4 ^' { y
HWND m_hResultMessageWindow;
1 Q% t3 R( i6 B, x3 \6 e9 S UINT m_nResultMessageID;% E' h" v- R) d2 L& ?% {
7 f) \) n! O1 ?# A# C; {; j
) K- j6 h1 `% U) S! {};
1 h0 i# K3 c7 P( c; C9 U$ S" r7 `0 [9 q( l, j/ F, T
1 W. _0 j+ }- {" C
// Dummy Implementation to be used when no other implementation is available% @- \ D1 l$ v0 l. b( j* B$ I
class CUPnPImplNone: public CUPnPImpl5 H$ X+ [8 f$ d- a! U4 E+ g& T% r
{# A- x( T* f9 i$ {0 U% I
public:
' @3 H3 l8 }3 W u; f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; x; g5 F6 O" E* |0 U
virtual bool CheckAndRefresh() { return false; }- T |2 C A& e+ V4 ^: K
virtual void StopAsyncFind() { }( ^: R* U8 m; s) n
virtual void DeletePorts() { }" t/ V; z Z. t. A* R6 n
virtual bool IsReady() { return false; }9 F# @; e ~1 z5 v9 m4 I! d2 z
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }# {+ ] H$ i$ P' L' T! A
};
( |' A7 X6 [5 @3 X( ^7 C: \" J( ~4 U" ~
; d l7 ~) { j4 b/////////////////////////////////////2 F, E; O- y5 T* L6 U6 W; t1 p
//下面是使用windows操作系统自带的UPNP功能的子类
8 h$ j% Z" o- ]$ h: J4 j( N9 L' A z# w# }. m% ?
3 K" Y: w5 D8 ^" A3 g& _3 _#pragma once* N2 M9 ~; } d/ L2 D
#pragma warning( disable: 4355 )2 j/ j# }+ r7 y2 m g5 _
& y7 h4 q7 `1 o! |8 \* \
1 ~$ T$ `+ M, @$ w1 _0 I- u! B#include "UPnPImpl.h"
. l8 ^7 i) e# H9 I- v#include <upnp.h>
. ^5 g' R: J$ R( k#include <iphlpapi.h>
! g+ _6 y0 x* a8 T+ ?3 ^- L0 ~9 u#include <comdef.h>; ]8 S) g3 A0 C' B$ k
#include <winsvc.h>
. L7 J7 b# _, \) r2 m$ D, t) {% y4 {! H
# a& N; w/ B7 a2 o/ ~4 k#include <vector>5 m, h8 M1 k: n4 h$ ~
#include <exception>! |9 S8 @8 e# ?4 s! R& p# R
#include <functional>' L; ?( D+ _" k2 W! k2 C& R! z
9 z% V/ Q7 v- R, Z, K4 Z5 T+ [
# ~( z$ q6 m( q- `5 Y+ q4 ]& s* d) b- k) [$ J
6 i; d# w1 D% ^+ i+ ]5 b
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;: R/ ?+ C' p1 v3 ?5 f6 V' }8 t
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
: }* E/ @2 E. y; | G8 g" H: M7 vtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' |4 A0 L# n. `+ @* i/ xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" Y8 G8 R2 {" k6 T$ d0 V3 ]
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;5 P! M' f. w [2 U% Y' F% x5 z2 c
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
2 |- A/ W ?+ btypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;+ W- Y, D1 L/ F/ \( n
5 f, O9 A7 i9 J9 g$ {' P
; T8 T5 W+ ]. |( ]6 b% mtypedef DWORD (WINAPI* TGetBestInterface) (* }8 @) M4 T& J9 W% H- R* x
IPAddr dwDestAddr,
+ l# b( ?7 a* S. A PDWORD pdwBestIfIndex
# j9 e: h& z$ d);6 u8 M& Z( w, B* Q8 S2 k
* y* P, A' R. _7 p, A
& g: h$ t) j; h% k+ Mtypedef DWORD (WINAPI* TGetIpAddrTable) (( u, J5 J$ w6 F* O0 v* C
PMIB_IPADDRTABLE pIpAddrTable,0 i) \! ~3 N% _0 M( N
PULONG pdwSize,. {4 c' k) X6 z9 N2 K6 [! O5 c$ A5 n
BOOL bOrder- a; R8 ^- n/ J: g2 U9 j' G
);1 v. D6 L9 i9 n0 K! w
) i; I! g# x m6 o( @. F. a7 t" N. P- l' v1 e! a1 `0 M
typedef DWORD (WINAPI* TGetIfEntry) (
+ {3 r) P) I. [4 h d7 {3 {8 ` PMIB_IFROW pIfRow
* |4 V; i! a! g$ a4 a9 r* g/ ]);% `7 b2 _3 @% I/ ^+ @* h
' d2 ^8 d7 l9 ^6 R+ G# a( P& z- r
CString translateUPnPResult(HRESULT hr);
+ r& `5 v* ]1 u' @4 E3 W' q3 eHRESULT UPnPMessage(HRESULT hr);
# R% j9 Z) A1 M4 G2 I% O' u- H8 X, \+ e
" k1 O" |; D7 @# b7 s( B; L
class CUPnPImplWinServ: public CUPnPImpl" L# o: I2 Y, g, w E8 m
{
+ y, Q1 l( o' y* W7 L+ y# M! u friend class CDeviceFinderCallback;
3 D( ]8 _0 J4 W& ]2 v6 M: d, N4 | friend class CServiceCallback;2 `; N& @9 Z4 |2 y, R6 n: G! B' w9 \, P
// Construction
+ t" f# I6 Y* S# b2 x1 mpublic:: D- W; _. m+ ]7 U- ?
virtual ~CUPnPImplWinServ();3 U/ g3 q) i2 [
CUPnPImplWinServ();
) r& v9 V1 a. z( B. g, c- [$ \" @- ~. T0 P9 M. N7 }0 G
0 m% G0 A' J9 T" K9 L
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }1 ~# T1 _( E. w9 o
virtual void StopAsyncFind();
/ i3 C' a1 ^; u o: N/ L8 T virtual void DeletePorts();
+ J* }! `! M, q0 \4 v! X+ k8 W virtual bool IsReady();4 I J2 {% a4 [( ?; s
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }& U3 y1 _/ R0 F* p
) p7 C3 d6 Q1 d
3 P' N7 C8 I6 p) l v // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)9 r6 G- k3 w+ b% C; o+ m* u
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later0 ] p9 q' U, g/ ~6 _1 ^* g5 Z& l
virtual bool CheckAndRefresh() { return false; };. x8 B' e# u- ]$ f/ Z$ O! |
# Y2 a$ ^6 s: k( ^2 q
T0 \! p" J0 A; X' {
protected:3 `. @( C* s' c
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
" j, h+ ~( g) b: b+ l" B void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);, |% P7 {. J+ b- ], b2 f5 z
void RemoveDevice(CComBSTR bsUDN);
% G; o' k6 Q" D; I bool OnSearchComplete();# k0 a" Y7 `( K" }: u
void Init();
[8 J. q/ Q& i5 X2 s
, _# e% R2 u0 S4 {0 I8 P! E# x2 _
inline bool IsAsyncFindRunning()
' b! L% C. T/ }1 o) U& [: x {
: u( A q: K( B5 Y6 t% V' y* S' c if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
- f6 ` y( U8 z4 m2 L# f {1 ^/ _6 [1 z- K
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
* `% I! x1 G( x' e6 J& @( y m_bAsyncFindRunning = false;3 j+ r) M8 y7 Q7 p' @* D9 r- {* k5 O
}/ e) ^# \6 s9 M7 q* e1 Q3 @
MSG msg;
8 N6 V! n6 `" d. } {: E6 U while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )" [) J' g% t8 w7 B2 I) `
{
' d: d& p" T. a0 x TranslateMessage( &msg );6 k5 h9 P: K% Q
DispatchMessage( &msg );
! w+ F' x- ]% d- b" h' z5 Y }
e# K1 Q E% v. t+ y: ? return m_bAsyncFindRunning;6 I: J" u& W1 `9 _. V; O$ Z1 g
}- \% h: K5 R ]
) E5 a3 c0 Q2 J# T6 c
# ?9 t5 z8 C% t' x TRISTATE m_bUPnPDeviceConnected;. v8 d" `9 o# h! I0 v- Q) j5 R
- E5 }% o; d: p% H# F4 e
4 M, V0 N k# \6 D1 R3 `
// Implementation
& a4 h8 C$ w% }% j // API functions; i) _5 P- V, x( @7 o# Z9 ]' r& t0 j
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);& @2 Y2 c, P6 C
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
7 M3 W5 L/ k8 v: ]- C7 M% j+ O5 w BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! w3 |' e3 e, Q j( s f BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
5 L" ]* q/ X" H6 D% ~& u BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
" l1 O/ H5 d1 P" N BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);2 e, P1 Y/ m) \$ J, ^( l
1 E7 c9 i& o: a3 u6 i
+ a" W( P4 E3 z TGetBestInterface m_pfGetBestInterface;
8 d2 W# b: W, w }: d1 ^! `' ? TGetIpAddrTable m_pfGetIpAddrTable;
! U2 r6 s1 p4 K7 |( e TGetIfEntry m_pfGetIfEntry;
+ j- X6 I( v* Z. r) R# v$ k2 k6 c
) W9 R* N, L* |) F! Y. Y+ |' l
5 U# f- A9 Q% i, k$ f N9 m, [, x! Y static FinderPointer CreateFinderInstance();
+ o' Y6 K+ }( ] struct FindDevice : std::unary_function< DevicePointer, bool >
" ? g* A: T* F {
/ J0 \5 u" ?0 i: S8 |, W0 i. e h7 h+ S FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 ]2 [, H6 r3 E1 }6 ^! {) p" n c& w6 A
result_type operator()(argument_type device) const/ v! q: J/ Q" E! T
{
; y; u+ P' H2 i5 O: G) O- I CComBSTR deviceName;
- \. e$ {4 p: _: [ HRESULT hr = device->get_UniqueDeviceName( &deviceName );1 j5 { q1 u5 F- Q
5 S/ U9 s0 c$ P7 \# ~* c8 d8 i G# X* u1 T2 @2 \5 l6 W, Q
if ( FAILED( hr ) )& B) ~) x1 k3 ?( N+ d2 ~2 j; j
return UPnPMessage( hr ), false;% c1 h/ v, d" Q/ V9 `
0 f; S& D, t q& b H" H& s2 I; _& B5 K$ I
return wcscmp( deviceName.m_str, m_udn ) == 0;8 z% H) h% H1 Y4 Z+ h. N
}
$ T" I& |4 a. `, u; R* {& B p7 O0 o CComBSTR m_udn;8 L% t. S5 L& P. z5 Y
};
# a& I w# ]+ Z) u( x
6 f7 r3 a( Q& G void ProcessAsyncFind(CComBSTR bsSearchType);& b& m* A6 T+ s6 p
HRESULT GetDeviceServices(DevicePointer pDevice);2 h" [! W6 R" b ~. C+ W3 \0 m! m9 I
void StartPortMapping();% P9 Q. p) [" T1 h. w8 h
HRESULT MapPort(const ServicePointer& service);* O% u% h% ^/ J& w/ f+ w0 }. C+ E
void DeleteExistingPortMappings(ServicePointer pService);
+ p8 K; c% I+ J6 D) ` void CreatePortMappings(ServicePointer pService);* @. m5 W" e, m4 l. i. {! |, D' h
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);" L, \3 @3 e3 i/ Z
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
% O7 {' T+ b' Z) K# d LPCTSTR pszInArgString, CString& strResult);
+ e$ L; x2 |! k* `7 f* j void StopUPnPService();
! W/ ~7 ~9 l5 O) X
! Z' b3 t* a+ z6 X& j5 d& L. Z! d! `$ h h
// Utility functions _# C8 B/ Q" M9 s2 S: J- X- d
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
$ F1 o. w9 @" E0 Y% u INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. ?! H L8 ^& N- e, }# B# v# O INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);+ W, t/ J3 N0 n. L! y, m
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
. _& B2 _# d" }/ C1 k! F$ J+ h' F/ } HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
# o( Q+ v# J" ^* f8 Y" G& F& @ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- f" }2 `) i6 E6 b' t6 K \: V CString GetLocalRoutableIP(ServicePointer pService);
4 H4 w4 }$ d7 \2 [0 N
3 N6 V: n3 ^0 B6 ?3 y5 O$ ]' J0 I2 ?4 b1 y2 d" G
// Private members
: m/ \4 o+ d$ O7 d* L1 Tprivate:, ~/ m" f0 E' f# Z" U' n
DWORD m_tLastEvent; // When the last event was received?/ L7 i' O9 A; p' S' q/ ]
std::vector< DevicePointer > m_pDevices;
* ~2 ^8 @0 v% m* I* G std::vector< ServicePointer > m_pServices;' F4 @( S# S* Y0 ^ e
FinderPointer m_pDeviceFinder;
9 q1 \* @( Z3 {) q DeviceFinderCallback m_pDeviceFinderCallback;2 N* Z* X8 W( U8 F+ M9 _" ]
ServiceCallback m_pServiceCallback;
4 f* q- ^/ ~! K2 n3 m4 A# j
$ @( O$ @! m5 v% \
% A3 Q$ z* c7 I) H0 M+ p& K LONG m_nAsyncFindHandle;
1 Q% @% G! Y) L0 r, s& a2 v bool m_bCOM;9 B8 j6 s+ c2 J6 G# O# m
bool m_bPortIsFree;, a' X/ A, K. h/ T3 h7 M
CString m_sLocalIP;( r% h2 [( _ S/ n" n$ d n
CString m_sExternalIP;7 @6 }" b9 B# o# |3 l- s7 k# H1 L9 s
bool m_bADSL; // Is the device ADSL?8 ?0 r6 G) b% Z0 G
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?5 S) T' k* m* r5 h2 r
bool m_bInited;& Q' R# K1 i) e: F: t+ S) b* m
bool m_bAsyncFindRunning;
8 v1 ^" ]3 s1 S3 R+ M HMODULE m_hADVAPI32_DLL;/ Z ?, F0 h5 J& R# X
HMODULE m_hIPHLPAPI_DLL;
% C0 D7 k7 J3 ^ u bool m_bSecondTry;
8 h" {$ j, ~. r5 r bool m_bServiceStartedByEmule;
" i" k9 l! \0 T5 |, A# m bool m_bDisableWANIPSetup;2 O7 k& C5 w$ k/ @
bool m_bDisableWANPPPSetup;
1 n$ A, h! r& |- J+ @' P. Q u
. j* Y% {, O; i9 N! h
8 z& V; B8 _+ r% Q+ w/ h};7 U; @% l1 C1 _: u% u+ \0 B1 h
, ]2 C9 v, }" H/ n4 _8 H: @
6 y& o2 |) L3 e9 Q3 @. l! [$ \
// DeviceFinder Callback
0 L) j7 Z% l/ Zclass CDeviceFinderCallback
, w# c' t2 F0 L& n: w6 D9 S : public IUPnPDeviceFinderCallback9 A3 Q" R F$ n) S+ W
{
3 L+ G4 q% {; \public:
# @9 A% X- L; A CDeviceFinderCallback(CUPnPImplWinServ& instance)2 N- C5 C' p5 `/ c
: m_instance( instance )
; _2 K2 E5 M% @3 L& v: X { m_lRefCount = 0; }
1 Y8 J, j0 P2 {& L; [$ j6 `) ^: [, [# Z8 ?# Z ~& w. `% h
4 B0 D; T3 V% J4 x
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, B8 h) }/ C: ?# K }6 G0 R
STDMETHODIMP_(ULONG) AddRef(); o3 [+ A" \: U2 a# W3 _
STDMETHODIMP_(ULONG) Release();
+ [- D. A/ J3 ~3 U6 S" l0 d& `
. B' Z* P; o' a) g3 t
1 ]4 O( q: T- j- Z8 Q. r P// implementation% ?& s( I- `9 `5 }5 T- O
private:
9 X( R1 @, @, I8 N( ? HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
i2 C3 K9 h- ?0 C5 c6 G4 N7 P HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);2 L& a5 j, M J' ^, | l
HRESULT __stdcall SearchComplete(LONG nFindData);. e# W2 q2 f; V' ~6 a# n$ W- f
, { l+ d4 x7 e
: [5 ~4 \3 _# _3 Z4 W# l$ yprivate:
7 J! T1 I$ p& q7 q% Q6 _1 f2 ~6 o CUPnPImplWinServ& m_instance;
+ X3 h* H1 y M7 S% z7 z( C# ? LONG m_lRefCount;
& N2 Q9 {% m# M1 P9 Y v};
. a8 N) b7 n- m! |% e9 k* u6 t' a% @- l3 S2 D- Y6 G
% y( j( O d, g8 K9 V! T$ I5 r1 i1 H// Service Callback
, i9 A" W( ]/ ]% Y$ G/ _0 @8 dclass CServiceCallback# ]# L1 K, {- b2 T/ Q- T" T7 F
: public IUPnPServiceCallback
9 x3 w. e2 O5 I( R2 u{
1 _' K$ m9 B) S. z/ {: Apublic:
A& D* B0 U$ _" T) q0 [ CServiceCallback(CUPnPImplWinServ& instance)6 t) Y1 F* d) c0 f
: m_instance( instance )+ r) X$ u1 c. [* E1 P( {
{ m_lRefCount = 0; }+ E V# X' ]+ W7 t
4 h: Q# y. H, K" c: i9 `
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
|. W+ X. s+ _ STDMETHODIMP_(ULONG) AddRef();/ y8 ^ l0 h. h. G/ o7 I
STDMETHODIMP_(ULONG) Release();: H. e' P9 [$ F) o' g5 ~. U
% c7 d+ @! F% O/ }7 y. F
* _* G. r$ A" q8 w0 F// implementation* m% L% T: r2 u! b; [
private:2 v6 P- u3 R* @$ _2 u! ~
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
$ C8 P. p5 r( q1 Q7 m5 z HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
' Z+ K: d4 a6 ?9 b! r# f5 p" x( @" w S. k
/ D, `4 @2 A6 A; ^5 j
private:
1 D) G7 q, F* q$ L2 n CUPnPImplWinServ& m_instance;
; [6 B9 ~+ X- G7 w LONG m_lRefCount;
3 S0 z: l" Z9 t};
# \2 ?. \5 s' @+ c3 [3 c e% L% h, i5 V: _
! D1 k; {/ u: e. o, S
/////////////////////////////////////////////////6 M! H, {7 M+ Z; Y2 |" `5 T& t7 p
+ R- ^; A: M1 i2 N% J% \/ h- N
/ T, o- u. m' F
使用时只需要使用抽象类的接口。
8 [) s: r0 ^' O: k" eCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. o6 K& H6 h0 S4 w, r/ h- S
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.1 w- c( f: {' k3 J4 O- | D
CUPnPImpl::StopAsyncFind停止设备查找.
( z* J% l' }# o3 mCUPnPImpl::DeletePorts删除端口映射. |
|