|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
4 a6 k$ W0 |* ] q( I0 q0 t/ _/ e: A$ X- b' _
5 O3 |. {% o$ @/ r0 Z///////////////////////////////////////////
5 f, u, o1 @( H//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
4 J6 e) w9 J8 l! [4 X7 B" N5 Z$ z+ k& g+ Q9 a, m
& R6 v7 M0 p7 Y8 J/ F
#pragma once; W) X6 Y3 X. H3 p! K8 Z0 G
#include <exception>% g4 s8 y) j9 d1 ~
; H5 j8 o/ f' ?4 U; b5 ~+ v7 J- o, `; s9 O, H
enum TRISTATE{3 g! {$ k% D) K3 x* X
TRIS_FALSE,' e6 F- I: q1 x2 I6 X; }$ l
TRIS_UNKNOWN,/ W8 h& w3 k7 l/ u
TRIS_TRUE5 i" a6 j9 a0 Q5 K
};
7 h3 U8 U8 Y% O) G( e# {! P9 E8 J4 R u2 o
& U3 _, {0 d9 _9 w
enum UPNP_IMPLEMENTATION{
# c2 l7 n4 _' u UPNP_IMPL_WINDOWSERVICE = 0,- b% o/ s5 y/ y5 q$ i
UPNP_IMPL_MINIUPNPLIB,
* o @! V6 M$ { G2 @ UPNP_IMPL_NONE /*last*/8 [+ Y9 i8 Y5 T, Z9 x3 M) a! L% }' K
};
) A2 w- ?, b/ G: l0 V- D1 u6 u e8 b6 q# Z1 P2 l1 Y
- U9 R: l3 |/ ?
1 G `, f& `. K* b( R1 M) C
( t4 r* Y# X/ @% P4 \4 y% }
class CUPnPImpl
5 V) c4 P. {3 T f$ y{
$ Z$ ]3 b2 K$ L, S1 Ppublic:
% H' Y* w! d1 Y6 N6 ? CUPnPImpl();
5 B* u, B4 t: U+ i% |2 |8 O virtual ~CUPnPImpl();# w; E- I* }) Z- V- b& [* F. ^4 r
struct UPnPError : std::exception {}; K* T) B5 E5 _, M' S3 [1 G, _
enum {
, U) x* r8 B8 n' L; K: K {' _ UPNP_OK,$ j R. w. R& V" U
UPNP_FAILED,8 X& z! _# |/ ?5 q m7 I: ~ h
UPNP_TIMEOUT& D# u! G2 \. d% j
}; S3 |0 [9 a2 y& i8 l/ D# M- n
1 ? [; e: x5 z) y+ Q5 W
$ x- v- P# W( o
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
$ T0 i( \, y, d virtual bool CheckAndRefresh() = 0;& h* G( G/ t" {- e8 Y
virtual void StopAsyncFind() = 0;* t9 C7 k4 @; V4 D$ j4 }( [ F$ O
virtual void DeletePorts() = 0;9 q0 b7 e5 L$ g- Z; v; @% a
virtual bool IsReady() = 0;& z% w5 `- v6 \
virtual int GetImplementationID() = 0;) |% K# n3 k3 [
$ d# y" o! N, Q- z! X' ?5 w void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" g, F) P! K2 z4 l( W
2 d8 Y% N. s! _2 F
7 P6 k* i" m0 p/ A void SetMessageOnResult(HWND hWindow, UINT nMessageID);- o% j" A! x1 e5 a. F
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ U7 i$ o) Y5 G
uint16 GetUsedTCPPort() { return m_nTCPPort; }
0 Q6 y' n q1 H* j uint16 GetUsedUDPPort() { return m_nUDPPort; }
- q2 O# q- z$ O+ P9 x5 A: [" u, K; l# h' _% |& U/ ]& ]
4 b% D& z# }6 Q- `
// Implementation8 x6 w* c) h `0 Z! J' B/ C
protected:. Y o* Z; ~) g1 E2 F* x( a/ h
volatile TRISTATE m_bUPnPPortsForwarded;- b3 q' G6 x3 {6 n: L; Q8 j
void SendResultMessage();, I3 s3 \4 @' Z2 H5 h& w
uint16 m_nUDPPort;* i( l- @* \% g% b! `
uint16 m_nTCPPort;' n- O. }4 Z+ w& K- F
uint16 m_nTCPWebPort;+ z. w7 b4 J& q0 O4 B
bool m_bCheckAndRefresh;
4 P) A9 ~) C- z+ V
# @4 g( E. M6 n$ t3 y, c/ t
4 U: P5 W: F9 s% \. I# w' Qprivate:
. [3 n @) U# I) K; P0 n: Z HWND m_hResultMessageWindow;
/ n! p( w# \2 y* _% V0 z/ T+ B UINT m_nResultMessageID;
8 J& u) W* @3 c: A
- h" ~6 e4 `" o7 h* c/ E
4 @4 G3 g" H) E F};
: H) S5 n8 ]. g+ a& b/ h
3 [7 b/ n8 |7 t/ ]0 P0 v- W3 R
& g& q9 s3 C) y1 t4 ~# l) z$ `% _// Dummy Implementation to be used when no other implementation is available, W6 ^3 o% p3 s1 y! C q, N1 S; O0 z
class CUPnPImplNone: public CUPnPImpl7 D: w) f, h5 i) n/ w
{
3 V* ?" Q6 U3 @6 n! H0 G; rpublic: _) j- |5 j+ H! g/ ~; Y
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
9 C/ j& \" u' w, ^- L+ _ virtual bool CheckAndRefresh() { return false; }
+ N( l. X" }" \ O2 y2 ^ virtual void StopAsyncFind() { }
* o$ e7 G B4 @/ N, i virtual void DeletePorts() { }) r1 f8 w, \, ?/ R' }
virtual bool IsReady() { return false; }& g- Y G V/ S2 z9 Y# n( w E
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }1 K: H7 |$ A6 x: k. A' K$ X
};
8 f: j: {% f. {' ~9 b. j7 [4 }! U. @
. c% P/ e0 S& R; Z! u) M% j$ p; [, L/////////////////////////////////////
W @1 |! k( A. h1 q- V//下面是使用windows操作系统自带的UPNP功能的子类% [% E, ?: ?: m B6 A5 @2 N& w
3 A% q& |4 H9 ~8 x: h2 y
9 U0 y/ @8 }0 Z% U9 s# d#pragma once
* s2 w8 ^# _7 v8 z# ]! m#pragma warning( disable: 4355 )6 Y+ j7 I6 r( F* g6 y9 J
: Q) }5 l' X9 G2 J1 K
7 Y- i4 g9 ?1 F( F9 J$ L/ p+ J#include "UPnPImpl.h"% k/ q- @/ P7 ]# ^" B7 D$ [
#include <upnp.h>. C' C. g G0 a- @8 N$ d
#include <iphlpapi.h>9 R1 `6 w5 a, D, Z
#include <comdef.h>! ~3 P3 N, l0 \4 L
#include <winsvc.h>
/ r1 |1 c: S8 t3 I9 D2 }5 }
$ F2 ], u' ^% @
0 |$ p* o" j# c3 S0 A, J: R#include <vector>4 M+ N, f$ f) @" ^3 P
#include <exception>
! D- Z4 ^: F$ x7 o# K#include <functional> r. d+ Q5 H7 C. l- f) E
/ t8 w5 L" ^# ^% o: T6 S0 |. F+ i% {4 R$ u8 s$ o' O4 |
0 ~2 b3 C# g) {2 x4 K% m
3 {5 j2 B! |6 A- J$ ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;$ U* S+ a2 i7 F- w+ g3 j. p( B
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
, h2 g9 E: ^; s% s8 D; D% |6 qtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;( G9 B+ y) I" ^) V7 g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
K; b" o/ H7 Y6 _typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 i9 V" Y1 u6 _
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
$ d% O0 T# ^. I5 n; h; H4 Dtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' B- u. A: t ~$ \9 P8 K/ V* U2 Y: @# e0 U& U
3 R1 N; q2 Y: Q$ R( {" ]( wtypedef DWORD (WINAPI* TGetBestInterface) (% L- ?6 N* ], P& K( B2 l6 Z+ s/ A
IPAddr dwDestAddr,3 v) m! p/ S1 f7 F2 R) u# n8 g& e
PDWORD pdwBestIfIndex
0 G `# Z' V/ P% ~! i* Y5 m);
4 n y$ u& E1 t9 M- l$ z; C3 t% C: z$ C: l; v- ^
4 W% U3 Q0 d" ~/ f2 W _5 `: l2 t' {typedef DWORD (WINAPI* TGetIpAddrTable) (- h; M( l+ ?7 j& ?
PMIB_IPADDRTABLE pIpAddrTable,
4 E& s! K7 @# {) h PULONG pdwSize,2 Y1 Z" B$ A; O* E# p+ x$ O
BOOL bOrder! g1 [! U& ]! F; A9 d- B8 F/ b
);
# V% F+ ]' ?" s) \0 K& w3 W0 Y
, G0 Z* ^: G- A7 s/ P' w1 z2 {4 y# v6 i
typedef DWORD (WINAPI* TGetIfEntry) (5 m2 E0 W) u, l4 T
PMIB_IFROW pIfRow0 b8 V; Y& ]7 k" Z3 K) H
);
' `1 E6 F& V% h/ ?2 Q2 N' @$ _
5 Y& x3 X; ]4 x& y. v; ^. t; B2 s& S; \) M, e3 S. f
CString translateUPnPResult(HRESULT hr);
- z" Z5 X" @4 u1 M4 W/ G p3 L2 XHRESULT UPnPMessage(HRESULT hr);
. M6 d, H" Z; _1 A1 n- s( U5 @1 a' K$ f2 q* k
' L* k! ?0 K4 h/ c( l
class CUPnPImplWinServ: public CUPnPImpl( F. M+ {( m& F
{- Z$ ~5 ] U+ F/ U
friend class CDeviceFinderCallback;. Y5 q7 }6 j8 [! h; y D7 ]5 e
friend class CServiceCallback;! r6 B k" f4 q2 H, f8 s) g
// Construction
. b5 `3 B6 [+ x* b$ upublic:8 q& ~6 l3 v: F: n& o. `# S9 v% l
virtual ~CUPnPImplWinServ();# \6 }4 [( o4 o9 r; G
CUPnPImplWinServ();
- M; `! o' m; y
' I) x$ i" m. Y( |
: n' V, q) O* o" j/ g0 U virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
u$ M K( L; J; W1 ?! Q virtual void StopAsyncFind();
7 p% D* a4 R( L1 v virtual void DeletePorts();
% j i" _ L! q) m; _4 i: |) x virtual bool IsReady();: A7 S7 |& v# Y( t( _0 ~& E ^
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
& n8 `9 g$ C$ u, a+ I
2 F0 Q& g- U, `( }( D7 U9 A) }, c/ C8 E2 d$ _# G1 `# e# [
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
7 X+ y3 h( ^6 M1 x- q2 P // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
! m8 w' t% L0 Z& P) C a: w: \ virtual bool CheckAndRefresh() { return false; };
' X. N- f8 i; b; H7 y. ]# i
& W4 C3 Y! [$ W i% i5 L# ~9 O5 J" \
: T H- R5 y i7 n @protected:* q8 Y4 z4 P2 Q
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# j: V2 M1 M" a' |4 d0 \ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);4 Q0 [% I4 W* O4 p- ^ C5 D
void RemoveDevice(CComBSTR bsUDN);8 i7 n( {' v* B7 I" f
bool OnSearchComplete();
( T/ y# q% s3 R) a- g void Init();
1 k. V' B2 s# E6 m4 N3 i: |1 E
+ P; j4 S! ~9 M! F9 Q+ Q" h3 g. |7 V. V
inline bool IsAsyncFindRunning() 4 h' X- `3 F. _: I' H$ H) i
{
" c3 D/ @$ r: _: W/ g. ]* @; V if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )% k; A: a+ q3 T6 N
{4 H2 ^* f) G* ~* @$ t6 j
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );/ j) p4 z# ?" C0 x; |
m_bAsyncFindRunning = false;
( V9 X: W! j# q* X4 {2 y }
' R. _ Q- j! ]# v" s; p MSG msg;
* i0 F: P/ @2 ]# q2 e f while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
3 ^4 O1 d8 d) e5 \/ O! G {$ x+ P) Q: ^# W7 S9 M3 ?* n; G- [
TranslateMessage( &msg );
. J+ B; m) m& L" n" U DispatchMessage( &msg );
/ w% k- q- h4 {$ C; _ }5 s9 U6 \( E7 U6 f6 e# o
return m_bAsyncFindRunning;
6 Q+ X" b! h6 f" I3 y! ]! d6 [3 z" p }
* [, M- N+ q$ t: R
" T) e" P. C4 O/ I) f. h# F
; H: ?/ B3 o$ _. s TRISTATE m_bUPnPDeviceConnected;# n; b; J3 ]" B% \; J) _) {7 N
, s( ?1 d) t; s, s8 A* [
+ w3 Z4 B. T+ {( P0 w: k
// Implementation, ?& y5 N( H- d5 |, J1 g% n
// API functions
; u: h O1 Q* c' k3 Z0 s SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* v' V* D# \+ Y4 q1 M6 B: q2 M0 g SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);8 x% M) J" H' j& V2 i2 P6 i
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
Z1 u/ ~" [5 b: Y0 A BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);* _+ b0 _" {" b. [/ p
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
: `4 }% O" F8 F; E- w& `9 p BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
, `4 q7 t& @1 {" S
: h8 I( c) g. X1 u8 M
3 C, C7 ^3 Y3 P T TGetBestInterface m_pfGetBestInterface;
. a7 K7 x* L, A6 j TGetIpAddrTable m_pfGetIpAddrTable;
; H. {% G% E7 D) o( F TGetIfEntry m_pfGetIfEntry;
( Q. C5 @( u8 p" h1 g; {: `7 X( x6 l! y8 z+ v" K( Y
+ A0 `. I2 o/ M; o* {9 } j: I0 m static FinderPointer CreateFinderInstance();
: ]5 K, \6 A$ E7 q struct FindDevice : std::unary_function< DevicePointer, bool >, K$ @( f* Z8 l: m- t$ e" Z
{% i6 {5 i+ g$ [( O1 N9 L/ _ n
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
7 o0 d# ?2 g7 V! d5 B result_type operator()(argument_type device) const6 _5 w7 M5 e/ l) u+ M
{/ ~, ^4 X0 y6 ]8 O
CComBSTR deviceName;# C" i" P; |% D; p5 e; ~9 s- h4 q) s+ s
HRESULT hr = device->get_UniqueDeviceName( &deviceName );! b [' Q$ z3 b
# A0 I2 T) G" r0 P2 n
( Q' ~, p5 @/ h, {6 t7 ~9 ?0 h
if ( FAILED( hr ) )/ g4 }% S3 X3 C4 n6 D7 N. I9 O! ?
return UPnPMessage( hr ), false;' n, h+ x) O9 R* v# i1 U
) n$ {" q: j( E2 l& m v$ H7 T; j4 [8 d" H! X4 G6 H: h
return wcscmp( deviceName.m_str, m_udn ) == 0;3 W+ P; ^) n3 ^0 @/ B5 t4 {
}
/ @- W* c& N" x5 Q! e6 W CComBSTR m_udn;! r- x9 q) r/ c& _+ a" `
};( X- r8 ?) v9 s9 l( c, V
! v# ~/ D# h o% _ void ProcessAsyncFind(CComBSTR bsSearchType);7 ` X+ ~* m. ~' O) W7 @# v a
HRESULT GetDeviceServices(DevicePointer pDevice);
6 Q- Q( ~7 S% |. M; n void StartPortMapping();% U* S) U4 n" A: F
HRESULT MapPort(const ServicePointer& service);7 V$ k& S0 s x- j5 C/ x5 k
void DeleteExistingPortMappings(ServicePointer pService);
- A4 i8 j, B9 S Z; ]" Q& z r void CreatePortMappings(ServicePointer pService);
( d4 c+ Y) E O( E. f) v* v* q1 G HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ D+ |2 ]' }( X7 A/ ?1 o
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 4 X& R: Z/ r3 g
LPCTSTR pszInArgString, CString& strResult);
]- I! B1 A3 H6 D% t void StopUPnPService();
' X+ k( [8 H$ W4 D1 s" y5 W! T+ Q' t6 g6 i' a; ?7 }2 Y
$ ~# t& Y$ o: ~' L1 e* h3 w/ W5 w% k // Utility functions
( D# {( y0 R" _' { HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);9 H& u% x& e% V( x
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);2 @: A# S4 g+ |" c% N- s
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
; X/ P! M* O8 ` void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
3 c0 e/ c4 H' h7 r HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
5 C8 t2 Y" a* x! B5 L HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar); l; D P; ~- l" H% H$ o) w1 i
CString GetLocalRoutableIP(ServicePointer pService);1 s. d, w' d8 H) Q) k
+ y' M. _+ V2 K
. ]/ f2 n! l3 K// Private members H# q/ n) F' V0 Y3 b4 c- E1 S3 g
private:- |7 \8 p7 l+ S" F
DWORD m_tLastEvent; // When the last event was received?" f2 o o1 k0 w& A& L4 b$ _5 H
std::vector< DevicePointer > m_pDevices;5 W: H0 f x @/ j8 a9 R" l6 u
std::vector< ServicePointer > m_pServices;
+ u- `: I+ O k& `( {& j FinderPointer m_pDeviceFinder;
. U/ v' H9 E+ T- E5 n" [ {! Z DeviceFinderCallback m_pDeviceFinderCallback;: d5 l$ }- S1 l: {7 `) Z0 p
ServiceCallback m_pServiceCallback;, M8 s0 M) k# r% T; T, D
1 J N- j$ ^; _: r
% L5 ?8 a# r' i* g# k& ?0 \ LONG m_nAsyncFindHandle;/ L1 @9 l3 f" G
bool m_bCOM;
, Z e9 c% I* E. M+ `# F5 J/ v bool m_bPortIsFree;
7 ] m0 s* {' ? @ CString m_sLocalIP;1 z) j; A) B! F2 o( B
CString m_sExternalIP;" i0 w. ]( H" \) v
bool m_bADSL; // Is the device ADSL?
/ |2 |& Z3 j9 ]: e. u bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
K7 w4 x$ K; x* N0 F1 n bool m_bInited;5 O: j: p: q8 d0 k
bool m_bAsyncFindRunning;6 ]/ N8 s4 X1 |! I; C
HMODULE m_hADVAPI32_DLL;
) V2 r x; [ r+ [% d+ M+ Q% ` HMODULE m_hIPHLPAPI_DLL;- \7 Y. v: z$ T6 K
bool m_bSecondTry;
% s: X: O1 ]: v M4 C0 c4 @8 s bool m_bServiceStartedByEmule;+ M. u& S/ T8 e, a+ f
bool m_bDisableWANIPSetup;4 @- H8 l4 b" k1 m/ `
bool m_bDisableWANPPPSetup;
6 K4 |+ K; l' z* u+ T
7 a+ J9 Q9 }; a# Z& t; B/ |% u) Q* N, o$ M8 v; Q3 L# j: L
};
- V0 s, H v+ J" Q2 [9 s9 \+ C; \7 I& z! \2 n s# z( S
2 o9 ?" c2 A; f. E7 L// DeviceFinder Callback
4 n) `2 ~- l$ w+ {class CDeviceFinderCallback- ~9 R7 s9 x+ |8 E$ P
: public IUPnPDeviceFinderCallback! }$ q, f$ M$ ~/ c0 P: L/ [+ K
{
1 b+ r; Y5 H4 [( Wpublic:
# W9 B g& }6 c$ [; @9 k CDeviceFinderCallback(CUPnPImplWinServ& instance)
+ Z6 h, M8 ]+ p( D0 r : m_instance( instance )
1 t8 ^4 U# |- E- P; F- n. ` { m_lRefCount = 0; }; K! b7 S8 r- S9 D. \- Y
8 L# f4 O5 Z: k- ` Z7 n' Z+ C% W) p0 u. W5 f( e
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 W9 h$ R9 M; Z/ B \: z STDMETHODIMP_(ULONG) AddRef(); N" l4 }6 Q; o, i
STDMETHODIMP_(ULONG) Release();
- `0 [; r/ c- T* M% R1 I
1 {( `9 K/ `" G1 q8 C
5 z. k- w$ e# j% M$ S7 t// implementation. D, q$ r- d; S, p& u
private:2 W9 I: B* u+ ~, v0 C' d6 ~3 T2 P
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
5 X/ r* |: `% ] HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
# J8 o5 F, x! p; G. m c& a HRESULT __stdcall SearchComplete(LONG nFindData);, d; z, ^ G3 |$ L& s( R q
! P' f* d# n k( O0 ?9 n, o( n" D: ~) p$ g
private:
. d. v9 F% J Q, K# u& c" y CUPnPImplWinServ& m_instance;
6 V: L" u; s$ h8 k LONG m_lRefCount;
+ @" V6 }$ H# @3 r: a};0 R% O8 {5 V- a' e
' _2 w# a9 @9 q$ {
, j) }" r4 a- D( X) x9 G
// Service Callback 2 m; v, c9 k/ W* I. a. T
class CServiceCallback
; a, P1 N( c; m) | : public IUPnPServiceCallback
. X. M9 m+ S* _8 {7 a9 @% ^{
8 _) s' V* R4 D( C9 K3 h: }public:
- r! D5 h, Y+ C | CServiceCallback(CUPnPImplWinServ& instance)
# n6 ]3 v9 Q& Y6 N1 z : m_instance( instance )
, s; k: \: f s" f6 z! y1 N { m_lRefCount = 0; }% o4 ]1 {' H7 R9 V3 ^# j
( f8 C, x, G2 c9 {$ ^& k STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 j( o& u2 @ U! A STDMETHODIMP_(ULONG) AddRef();2 Q6 I6 ^0 i- H' v0 m, v/ J! s
STDMETHODIMP_(ULONG) Release();
( @3 E) ^! V5 a/ h- I
* \7 X$ }* ?& t1 p" R
x" D) H. A: m' O) r7 {4 X// implementation1 \' P* i- [/ z1 v0 {
private:! |5 d+ ^8 a9 O! m
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);. Z: s7 p D8 Y/ H; T# B M
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
. }2 ?( h$ N1 u( J% D2 u( l3 n6 G4 n4 l c8 s" Z
2 V" G7 h( ` U0 @private:4 x1 z; C. c: @2 ^4 j" [
CUPnPImplWinServ& m_instance;
8 `" ^2 f% l) k3 V5 V. I+ ~( r! S LONG m_lRefCount;
4 m5 v# `2 ]$ D7 r};
7 Z2 n- V5 k9 k
+ x& Q [5 F' p) M; u$ h) b
8 `2 O: b% P5 }/////////////////////////////////////////////////" M$ s1 V5 \3 Y! J5 ^, [
! M! s+ M1 J/ d2 e7 x* M& e: n. b
0 N; O# P( x$ |4 I5 j% G使用时只需要使用抽象类的接口。2 b4 Z+ V+ T( R7 J* E
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' ]: Q6 F# K! }' V' I2 _" t8 hCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.6 d0 o+ e, \; M, t0 |) C; g* d+ X
CUPnPImpl::StopAsyncFind停止设备查找.
7 J5 _+ g; @9 k3 ?1 aCUPnPImpl::DeletePorts删除端口映射. |
|