|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
1 o" x& A4 C0 n+ c( Z7 t6 p$ P \
# X/ c2 Y! E# D/ n1 K( [! T* _# ~3 ]
///////////////////////////////////////////+ m+ [! }& _5 K) Q- Z- t
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- f, \8 [! Z+ f8 `
: ^/ s( R& S# L- S& b6 @3 |4 m. I2 c6 \, j
#pragma once5 }& @0 m' Q2 [' ?* M9 J
#include <exception>9 e6 z8 D% b* o. G3 a
3 T! R3 r) _) e6 F
2 }0 R9 R* ]; ^ Z& @
enum TRISTATE{ ?8 U$ I, j6 _6 W1 c0 }$ A0 T
TRIS_FALSE,
. G+ z1 n {" t$ N0 s! J TRIS_UNKNOWN,) ^5 C b$ a9 x' R
TRIS_TRUE' k% W, z1 a( b
};4 j4 e' [/ a7 t* b+ u5 e
) T; D2 V: V1 |
2 }7 X( B- `% T% p/ xenum UPNP_IMPLEMENTATION{
$ v$ g3 ]5 R" D1 x8 [ UPNP_IMPL_WINDOWSERVICE = 0,
6 Q. \# S3 u5 @4 m; V& M UPNP_IMPL_MINIUPNPLIB,
) l$ ^3 L" c% u3 ^2 ^' P UPNP_IMPL_NONE /*last*/! t j1 t% Y( t# i; I A5 [* I9 R
};
9 Y9 A9 g5 k! I; |3 H& ?- J
6 {, l; R& ~+ Z$ w- w9 N
8 S3 I7 O" e# w- o& {; t% ~! X# e2 C! T
) C! j% C9 t: O( W' @. O1 g
class CUPnPImpl
0 e( B' D6 C1 ?2 \( k S- q: D, J{( O0 E$ x5 w t4 `8 @4 f
public:8 ^0 I/ V+ d7 s3 X" w
CUPnPImpl();
& ~# Z: h, T: u virtual ~CUPnPImpl();% o8 }: E# h' w% m' E( B3 T* g$ `$ J
struct UPnPError : std::exception {};
; b; G- a+ U4 |5 O) \/ g enum {
$ l9 \6 ]+ \# i& l0 k: Z* K UPNP_OK,
" r( i% K1 B+ v* A8 \) `9 K& D UPNP_FAILED,
% P, N5 q: ` Z7 i9 f3 S: B. s5 P UPNP_TIMEOUT+ ?; q; M6 G/ T$ c# m
};0 t; c0 W& o. D1 z, S/ h) i: w
2 [. x9 G, f2 S0 M
+ U% I7 n! d. I- P virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
! Y6 ^5 `6 A9 P! [# W virtual bool CheckAndRefresh() = 0;
3 D) V' B8 V' K& I- ^. P8 i virtual void StopAsyncFind() = 0;1 }/ i$ O" B% y
virtual void DeletePorts() = 0;
! o( g" L0 v) J5 M' a( r$ w virtual bool IsReady() = 0;, Y: p, [* I X% E
virtual int GetImplementationID() = 0;, l) w8 k) Z- M+ ^
& {& q; V- f3 r( I. _# L% z void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 x* s* e' [, p9 I% C
2 {$ `2 F4 c# |; j2 P
1 c; _* ] ]7 M9 ]8 @ void SetMessageOnResult(HWND hWindow, UINT nMessageID);# L) ^5 L. {7 |
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
' S5 R, J' G* C! d3 N uint16 GetUsedTCPPort() { return m_nTCPPort; }
( f8 S, y* H1 W% g" \ uint16 GetUsedUDPPort() { return m_nUDPPort; } 5 v% j$ x* ?& m9 n) i
: O9 g% Z+ V# U! U* n3 V' K! b8 k5 x5 y1 p, X
// Implementation' D. g0 D4 r6 [6 v
protected:
+ t4 Y! O% y! g8 ` volatile TRISTATE m_bUPnPPortsForwarded;
5 Z( O: d4 `5 U- Y3 _+ r" ? void SendResultMessage();: c7 U1 q0 D7 C9 ~( n
uint16 m_nUDPPort;& f% Q+ q Y/ P4 S/ @" _
uint16 m_nTCPPort;
. L0 g9 H- A2 f* s uint16 m_nTCPWebPort;/ a# B. M' ~2 r t
bool m_bCheckAndRefresh;; m# ?0 O7 p& \2 r- m
# J/ y4 f0 O r& o" x* d/ f- n" }% Y" e) }6 j
private:9 w9 s; b, j* _
HWND m_hResultMessageWindow;6 L3 @2 H' R' t; D" D
UINT m_nResultMessageID;
* X$ h- p/ Y8 {7 M
. C2 _( D0 O7 e3 }& |7 `7 D" f- O( n8 c* l3 r: Q# U
};7 i% r9 S9 \6 q& Z/ o9 ]3 c
% q# J0 }" N( c4 [3 g3 A" N
$ r2 ~6 m- n& S7 j/ y// Dummy Implementation to be used when no other implementation is available
; w" O1 P; y* W8 Z% g9 I) c" ]/ d- l. ]class CUPnPImplNone: public CUPnPImpl% S- d6 z0 B5 s; z0 J# M. t
{
% Q' i7 g+ P4 |public:
* N* {( R* E# Q. R1 Y* \ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }* c. m9 d$ q. {* P* K: c
virtual bool CheckAndRefresh() { return false; }
/ d4 D, W/ O! G- t! C m virtual void StopAsyncFind() { }
* E: |, m$ m# K3 v( U3 h virtual void DeletePorts() { }
0 q; L5 B! c" v* X4 ]+ Z virtual bool IsReady() { return false; }7 b ` F) E6 {" b
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
' X6 N5 x" V9 c! a4 C; ^};
+ Y+ p$ [3 h) s# o+ N) z& w0 S
5 ], x. M, _9 r+ ?) S# d
) W3 h2 U/ {3 ~" a2 U( Y, t: `* X4 j* u/////////////////////////////////////
$ x& o; a0 O, M$ [4 u# @//下面是使用windows操作系统自带的UPNP功能的子类
5 H" P: K G/ E( P
* U- k8 @. c9 o: Q" z( J4 _( l% @
" z8 P: B7 n: f G& M#pragma once9 Z3 |# b9 u2 K# d
#pragma warning( disable: 4355 )
. a# L. ^3 t) c' y, F5 k; X* c8 [. F; ?2 i/ p% ?
$ D5 j$ s5 L4 J( Q" y) ~9 F& `
#include "UPnPImpl.h"
" n: X& X: ~0 {& ?& X#include <upnp.h>* o1 B" a" s/ P: i* I5 W3 C& ?& H
#include <iphlpapi.h>* L* S8 x# d9 h2 q' q9 K* [9 I
#include <comdef.h>9 F# N# `5 ^: c {
#include <winsvc.h>
. L- w" q! s6 B; I
* J/ X) e6 W! m9 S: l* D6 w0 N" k5 ~4 l1 w; b: W% V$ s& p, |
#include <vector>
* z& f( O+ `1 s$ R5 q- V#include <exception>
! z( N7 t- f2 X+ U! E2 n( h#include <functional>3 ?* r+ ^7 C0 L- I1 J3 F
1 b! m/ {! t9 W9 Y& K+ I# R
& u* q% D, f2 V
& V( e6 k3 a# H Y2 H4 ~1 ~" E( q' O/ e) M L) z8 m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
: u9 z( b+ O' a! F, O$ r* Xtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; L; H& q- Q p( O
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
0 `% y2 C1 Y8 Ctypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
- B* Z. H9 N" x$ Ytypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;6 [9 _3 R: T( u- @1 R: i# J
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 `* F! u; B9 |! _) z# vtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
1 |5 n5 [: X. G& x- l! W1 A( T, S5 V) B- F, L
' a) a' `) D; O8 }# \ q* `5 ltypedef DWORD (WINAPI* TGetBestInterface) (
: C( f% w& W5 l IPAddr dwDestAddr,' ?! h5 o' k& l1 h
PDWORD pdwBestIfIndex( B8 G* D3 q" Y4 x9 I7 E/ N
);5 Q" }- S! I. u; q" v5 [; c
. V) B$ y" S3 [( I% i( P, V0 C
# Z, k# K& ^7 G3 o
typedef DWORD (WINAPI* TGetIpAddrTable) (+ X: X w. Z+ ]1 K0 t
PMIB_IPADDRTABLE pIpAddrTable,8 I/ h# A9 y. A r
PULONG pdwSize,1 z% t& ^ _0 i
BOOL bOrder
& v2 G. e3 R3 l! e3 ~/ n8 t);* ^- J7 Q+ G6 g% w, k# n
# O' ]8 m9 ~* v- _3 A; O, f' Q* @) z( f- l, Q
typedef DWORD (WINAPI* TGetIfEntry) (3 v* o- f( R4 z/ S8 s. U, a
PMIB_IFROW pIfRow4 D0 \3 \) k x2 f& c
);
' T+ m1 D% A9 j; O- | k1 c0 T$ [2 _
9 J0 l0 O# x* a& Y! v
; Z0 b2 C( r! hCString translateUPnPResult(HRESULT hr);, P U& x+ C8 H6 s
HRESULT UPnPMessage(HRESULT hr);3 W# P; x0 B1 ^. ~, n7 r0 V2 T$ t
9 G% @+ @; K1 C) b9 F" Z) G# ]9 O5 D0 J' Q. J; M" T! p* W b
class CUPnPImplWinServ: public CUPnPImpl
% [' R- B+ F5 U, v. n, I{1 b$ [3 {% x& ?$ A v/ \
friend class CDeviceFinderCallback;
1 D- i0 C3 p P7 H friend class CServiceCallback;3 l5 w6 u- r& b( {
// Construction8 |" ]7 T) |* J& Q/ F( ^
public:
; f) }! G& b0 K9 r4 H7 a1 o virtual ~CUPnPImplWinServ();
: F7 a% n. ^+ w CUPnPImplWinServ();8 c& K. H1 L% A( H/ s
$ D) K* ], C: _) P% i [: ?
7 G, @2 V2 s3 \$ q5 o7 ^ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }1 G, L) T, f1 R' ?0 g3 Z3 g8 A. c
virtual void StopAsyncFind();
) J) Z3 A' ]9 l7 t; F virtual void DeletePorts();% B6 H$ O1 Q: C f J) Y1 z W+ S
virtual bool IsReady();
& H9 L) F0 V$ z3 Q3 V2 F virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( t1 Y# A2 m2 T
B# o- A/ {2 T" O
5 v5 e: t* I- d+ H! \5 _7 @
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)1 ^) \3 b5 w( w7 K! m1 w- `
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
A; c- m3 R/ y virtual bool CheckAndRefresh() { return false; };. V$ e& H4 B0 ]4 G; _) A, g; d( z
- T6 r0 ]6 t3 D/ Q: t
! ?# T) x! h2 Q; Mprotected:" f2 B4 `0 N; b8 ~# p
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);9 W. H* O1 E0 `/ R$ I6 c+ S. f
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
# I- ~% I$ J! ^2 `' q4 T& F: U void RemoveDevice(CComBSTR bsUDN);
( J% R* l) F5 p# k+ \( ~ bool OnSearchComplete();9 A$ f( A: `. O8 m# k: T
void Init();
' k/ U6 o& t$ a J8 h6 ]7 {2 B
. I' a' ~; Y% ? inline bool IsAsyncFindRunning()
; A* ?. {' ~5 e9 v$ d- J* M8 g {0 F {
- ]' L- ~& p9 w! W' h if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )0 K B5 k' O# g( r. w0 x
{# V) N! D/ t/ b5 k& A" l
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );( P' A$ d& K7 Y
m_bAsyncFindRunning = false;* u: A* Z: @) ^$ z/ c0 z
}
0 J& g9 m s0 a, U0 ? MSG msg;8 n7 e- e! r( h- Z% A3 ^0 g
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )% S6 C P/ r) ~# ? ~. r
{* V+ ]. P$ Q4 O
TranslateMessage( &msg );! ^5 C) X. ^" {: j$ I1 ?
DispatchMessage( &msg );/ t+ }% j6 ~. c' L
}# D Z) [. H0 M- Y3 u
return m_bAsyncFindRunning;5 V5 e: r% f& k5 X: S; B
}
' V) d! A; x% p, m2 M8 h* L/ D$ f. m$ r9 ]% r
& @! O. ~5 f. ?' m+ \ TRISTATE m_bUPnPDeviceConnected;
* | w# h4 u3 w. Z8 z1 @7 K) p: c, l& b& U% z( C
! l9 N# F7 j6 P) r1 a" L
// Implementation2 Q5 y; t- j4 v8 o6 W' M
// API functions
' x$ M4 g6 H7 d. R4 m+ t3 d) B' J SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);. P }2 U, u, i5 l) K% w$ I
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);! j6 d+ Q ~5 v; T# M4 ^
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
8 k5 s5 Z P) q BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);- x! |3 `( U d+ l* R
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);1 c9 ] ?0 v9 E" m8 c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
5 o: B d# E5 r# c/ ], m' `6 {( C1 a! }
9 p+ s' X+ Y& N( Y8 e TGetBestInterface m_pfGetBestInterface;
, ~! a9 i% F0 Y# { TGetIpAddrTable m_pfGetIpAddrTable;
% u& v5 f) N* E5 {; e% h TGetIfEntry m_pfGetIfEntry;
7 }0 h/ j5 D, Y! V2 H: W- W% s2 ^+ |; z6 s' ?
" Y+ k3 O) x6 H% c: [; l$ X, p static FinderPointer CreateFinderInstance();6 C! w* i2 S& z l
struct FindDevice : std::unary_function< DevicePointer, bool >$ `6 _) q3 w, s) j: h8 ?8 L6 F
{
! q) O/ o. a8 ?) Z+ P FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
' D7 B& G1 [: h. C result_type operator()(argument_type device) const: t" R) K9 z$ i
{
5 G% V& q6 a. q7 G CComBSTR deviceName;
5 T: w6 C! A0 h E) f l/ ? HRESULT hr = device->get_UniqueDeviceName( &deviceName );
1 U/ ]7 B) d) p0 _( [+ H3 c, f: l& K/ D/ j6 b' |
+ d0 Z/ X7 l# X$ k if ( FAILED( hr ) )
e e3 d$ A! c1 G return UPnPMessage( hr ), false;/ \' e- q) O$ o
: X; s: w# n. |) @
1 J: Q6 Z# m* Q3 ]* ]8 h; u
return wcscmp( deviceName.m_str, m_udn ) == 0;
; M) s3 [5 j1 Y' n+ Z6 j }
5 b$ x1 C- m2 s) w' P CComBSTR m_udn;; T9 {+ c5 M, @# K( G' L0 k
};
! b7 J! F. g4 H6 c! x9 } 1 V# w/ M; M# u1 b
void ProcessAsyncFind(CComBSTR bsSearchType);
. \) {0 O/ z6 ^; C0 B HRESULT GetDeviceServices(DevicePointer pDevice);
4 v3 ^ @1 F5 C void StartPortMapping();5 b' F2 o& i0 m; R7 W' @
HRESULT MapPort(const ServicePointer& service);, e/ _& o6 m) @
void DeleteExistingPortMappings(ServicePointer pService);' s' i6 G6 T0 } g$ v; Y W
void CreatePortMappings(ServicePointer pService);+ N8 X/ X E( A0 V6 S x
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ H, Q! Y; ` R- o w! A HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
4 @9 p# B+ T$ Y6 j/ B' c3 ]) j* D LPCTSTR pszInArgString, CString& strResult);
, K; D% T; }& E void StopUPnPService();
/ }. N+ n6 K( Q: \. e' g. q% F9 f9 o7 D3 F) m0 Y! _
) B/ K; C! h" y" o5 k // Utility functions
: T9 c0 G- K f HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);3 {5 a7 Q' Q% P0 V1 [; T
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);& O) k( D- j0 H1 Z0 q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
( I: p. M) _9 j0 J* c8 x void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);$ ?: N4 U5 Z6 q
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
/ S: F1 t1 q$ A3 U' X2 c- ? HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
0 l2 I3 j4 N) r5 E+ N6 n5 c( q7 ~ ? CString GetLocalRoutableIP(ServicePointer pService);$ U& F2 P/ e2 ^9 u) @& b
3 ^* a) h* Z9 B! R# {
8 S" Z7 ~* c! @* G" }: p1 j
// Private members
6 D2 K* Y+ s' G, U9 Fprivate:% M6 i& F, L5 t% ]" k) E6 Y$ H( H9 `
DWORD m_tLastEvent; // When the last event was received?
9 M9 a' r2 c, G# @; f( D$ N" D% [ std::vector< DevicePointer > m_pDevices;) z$ r% A6 @, C& U
std::vector< ServicePointer > m_pServices;$ A$ H, Q- [" t2 X2 m; d1 j
FinderPointer m_pDeviceFinder;7 k) y, n* Y4 Z6 m5 p
DeviceFinderCallback m_pDeviceFinderCallback;2 h2 }, Z* I2 b8 O9 K3 x7 Y
ServiceCallback m_pServiceCallback;
3 }. c5 j. ?/ X6 L% J* O8 _* u% n, K' i* f* _$ W
2 x- A4 r3 @/ | LONG m_nAsyncFindHandle;
5 g; [4 }% B/ V bool m_bCOM;
" K' x4 K& P+ q bool m_bPortIsFree;% n6 s. D d- {/ U
CString m_sLocalIP;
# \$ H' B+ c: Z0 i) @* r; s! ]# N CString m_sExternalIP;7 R; N+ H: n) X
bool m_bADSL; // Is the device ADSL?% U$ {9 x) ~( x5 y; f
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
* r Y+ R* q, P3 C5 T4 d! J4 v& j bool m_bInited;
7 r! L2 M7 o4 i9 o8 g) n bool m_bAsyncFindRunning;& Q! a7 |* @5 }1 c" b) y0 O! h
HMODULE m_hADVAPI32_DLL;
9 ?# r8 `7 J7 v8 H3 b HMODULE m_hIPHLPAPI_DLL;
0 U; h" o' }5 L# ~4 U bool m_bSecondTry;, N. N6 [( l& n: q* l
bool m_bServiceStartedByEmule;* \: O2 l8 B4 o2 j# m8 D6 e! g
bool m_bDisableWANIPSetup;8 f; O/ N' N) b& ~" t7 |& D4 l
bool m_bDisableWANPPPSetup;1 F( y" y3 a+ l2 e/ d
9 Z/ W y% i* C. }! m6 y8 o6 ]- G3 j+ L3 E6 z) _5 x- X N) @
};+ F& M' z- X1 h' t# e, P4 y
) {- Q5 \, t& y6 B P$ g
& x% y2 ?6 Z% b/ [. b! L4 q& D3 [// DeviceFinder Callback2 s1 i; Y$ C& _) W$ I) Q, o' i
class CDeviceFinderCallback
& S5 H' b4 s- I9 d! B3 [ : public IUPnPDeviceFinderCallback
9 Q3 D( ]* C* g& y{
/ I* K) F7 H7 g) ~9 \. k/ ~public:: d& e' I6 `, A' n4 t% @
CDeviceFinderCallback(CUPnPImplWinServ& instance)' O L2 k2 j1 c8 {8 S
: m_instance( instance )- y1 S+ a3 a& G' P. o" d) n) s& ]
{ m_lRefCount = 0; }. d7 n$ ~5 u7 D2 s
: B5 A/ k* @/ Q# q! G! c) c0 W" S" d
2 {4 n- N6 E1 K( Z* y; w1 E+ Y' }
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 r) b) ?1 s4 c% K; X! @0 ^ STDMETHODIMP_(ULONG) AddRef();% H2 ]7 X: c* _0 D& s
STDMETHODIMP_(ULONG) Release();8 p9 g/ z/ p9 V# a& a0 i
0 C# B7 m: k. i& t4 [; ~* ~4 w. [
. ~) B6 p$ u4 u9 Z
// implementation* r3 Q1 i2 r# h! e, s" v
private:* k+ A- i: g! g2 p
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);- v( L1 ?( G0 U1 I8 p- I
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
, K6 @& X+ y; _1 U, A7 p4 L1 V. |+ S HRESULT __stdcall SearchComplete(LONG nFindData);
2 y) M9 k" V& i" c; l
' k1 U3 F# k: f. g2 j3 p( D
' \( Z( y9 h3 Q3 B9 u+ cprivate:- G9 h' I5 l" y Y' M* ]
CUPnPImplWinServ& m_instance;; f, h) ^# D2 k
LONG m_lRefCount;: l; |4 t0 s' E; F1 K2 k
};8 H3 j, O7 T) B3 W+ D
8 V0 r- }7 w; n7 K
+ {9 W4 |7 ^7 x0 A, l! J I2 m( N
// Service Callback
4 u; r- s7 X6 o& ~: Fclass CServiceCallback
6 D( D! m7 b/ T/ b : public IUPnPServiceCallback) |& r5 B6 u/ ~: o8 y
{' ]( e: c5 U, C! P0 @) v- ^
public:+ y9 s6 R5 |# b
CServiceCallback(CUPnPImplWinServ& instance)
6 G" {& t: e5 {: @, _ : m_instance( instance )
+ {- O2 X. P9 u7 B { m_lRefCount = 0; }/ Q0 V8 T6 u. @, g! t: \
. r7 P# G8 _ l- _7 j STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 w6 C' h% r) N2 \ q6 a$ t STDMETHODIMP_(ULONG) AddRef();
1 w' n( h3 V2 {4 D' w2 n# G+ |. h STDMETHODIMP_(ULONG) Release();
& r" I1 U8 G: S9 S! \
3 m! U5 K; |: l: s" ?: ^/ [0 z- {/ [- d+ C1 E' L9 x# G+ F
// implementation
. F) F& ?4 X5 J- G$ X8 }2 R& Sprivate:2 h! n9 I: }/ Z3 H7 @; _1 p
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
9 B: _' v4 e" N% \2 u) {; K HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);: d! o4 }7 m2 d* {
$ E* u! C+ c: S% c; G1 ~7 K
8 N @8 L: a( r1 z6 ~private:
9 X" H4 |" S4 t0 a CUPnPImplWinServ& m_instance;/ V7 u+ d3 ?; c# ~
LONG m_lRefCount;
, w+ L: e8 u( q" C0 u, w6 O# R) Z};
: S6 B! Z5 c H4 |
/ ^9 I$ V% c: ?( m$ D( X$ }8 }6 E" R: W
/////////////////////////////////////////////////+ [( r, [$ g8 \( l% s: N3 D
9 f* s& b, c7 I% `
9 M: ~# ^+ V2 h; |/ ]) I! S: c使用时只需要使用抽象类的接口。" ^/ }4 ^* {+ `
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
2 g3 P) i! c% T4 mCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.$ C, Q5 }3 o2 K, Q4 F3 E
CUPnPImpl::StopAsyncFind停止设备查找.
1 r ]' J: Q, E9 ?6 V9 Z6 g+ m: I/ WCUPnPImpl::DeletePorts删除端口映射. |
|