|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
4 y: q* z0 l! m/ q% R& F9 i* B9 }9 t4 f3 G0 e' U
9 o" |4 N' A% f5 V6 v3 s% I2 {$ y///////////////////////////////////////////& L; r' Q0 U: ]2 \
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.* p* b+ A) G( @3 Q
. E: f5 q8 R1 ~% Q* m ]
7 O* {1 z/ F$ m1 B# |9 X#pragma once9 o q; J) H1 z. Q0 k* U m
#include <exception>
% j( ]/ i. H" q( Z# | J+ K) l' o
1 N% `5 t$ W) p! S9 P. u" V" a2 n6 F. u, m/ E9 M% I; w
enum TRISTATE{6 f; ~9 U6 W7 s7 s1 w
TRIS_FALSE,) h9 t- Z% x* r: l- k
TRIS_UNKNOWN,/ c% x) I3 j5 H1 H4 `
TRIS_TRUE
3 G( j, b+ E: N6 r4 n+ Q* G, I};# Y0 W# o6 Z( }' i8 q, P
0 x7 u0 S9 k( C5 o4 X
8 X( T! a* X: ~6 Tenum UPNP_IMPLEMENTATION{
9 q, Y, B$ U( U3 Q6 ^3 {( d UPNP_IMPL_WINDOWSERVICE = 0,
- o2 M' s) E% O# M2 P2 X UPNP_IMPL_MINIUPNPLIB,9 p8 G1 ~2 L/ A/ }
UPNP_IMPL_NONE /*last*/% B9 |8 d- l7 r6 p
};
+ N7 ]" U$ K9 b
7 e W% l' R! W" g2 ~+ c+ H: f' W, M [6 v+ ?
# D" t* l1 u) O' k" Z
* m2 W# w, b9 {' K) ]class CUPnPImpl
T" q: A! V% f! T/ M{
' ]: B0 }2 J% e% _public:1 K" p+ h$ I5 I" W
CUPnPImpl();
% J# v$ Y' U: K7 `. `& q! I2 r virtual ~CUPnPImpl();$ Y3 q3 S$ s# U# S7 v4 |
struct UPnPError : std::exception {};* q. i. T: C5 `' J4 |
enum {
; R7 l) N% Z3 ]9 m UPNP_OK,
' x" @7 S. ?6 d UPNP_FAILED,7 F1 n: @- {' l* ^4 g8 g
UPNP_TIMEOUT
; B) b4 ^* R2 L; c# B; w };
. F' i3 [% x' ~' t/ h2 y
; L0 N. _* s' }( u+ S" |. _& A1 \
' J: ] L" y7 z u! J. |) m, E virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
2 y- g8 M+ E) ~7 A/ M virtual bool CheckAndRefresh() = 0;
3 a ?) m$ c# L- J/ }# [7 Y) J, Z virtual void StopAsyncFind() = 0;& f9 Q' W0 Y5 X* l T5 _7 {
virtual void DeletePorts() = 0;
( Z M: K n, C4 E virtual bool IsReady() = 0;
2 \( i% B% c9 P4 t, f virtual int GetImplementationID() = 0;
. V# I2 o4 [& T6 D! ? # y' S3 ~* Q0 w
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
- y( W, X+ f: @6 w! j/ H: X$ E" _2 M: q. c u% @
) ]2 w4 h- p2 P, H& y5 x" a8 [
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
2 r% I; n3 P/ T1 I* E8 { TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) s# w/ q1 j2 R& s% |) ^) |/ t uint16 GetUsedTCPPort() { return m_nTCPPort; }% M+ e+ J5 Q" `( |% ]; u% R) e0 X; F
uint16 GetUsedUDPPort() { return m_nUDPPort; } + D8 x8 u) Q% Q* A
O5 s" V" E) z$ c, L, a
. w% e/ j ^; I6 j5 z" `// Implementation8 U1 l' y/ T! m% ~ w" g- h
protected:
- C/ S0 N1 t) y( q# c" u9 { volatile TRISTATE m_bUPnPPortsForwarded;7 P* R! `" b7 Q7 Z9 W
void SendResultMessage();
% U9 k& ^4 b3 Z uint16 m_nUDPPort;
& \5 E0 k# ]$ a( S uint16 m_nTCPPort;4 Q, i2 S, O) G) K9 h/ R( }
uint16 m_nTCPWebPort;
3 K/ w# w( `0 i bool m_bCheckAndRefresh;7 K R% v0 Y! A' M P- e/ F
, h4 R9 `. P' a2 V) f" }
8 A" e! i: \7 P, Cprivate:
7 B K. X. A+ Z1 a: h( [9 f1 W HWND m_hResultMessageWindow;
: m1 ]/ Y. a' D; N( c) L$ v UINT m_nResultMessageID;
% ^& G. |$ s6 t8 n- I \) a4 C+ l6 x$ T9 e, p3 h
# K2 p- n$ T1 ?* E};! @9 F0 ?+ R" a* H, |
" M2 n& Q+ x; |& p* i
) g) c6 Z5 j* j
// Dummy Implementation to be used when no other implementation is available w. N6 w4 I, F+ ^( x0 R7 \ o# E
class CUPnPImplNone: public CUPnPImpl
7 A6 A0 j# t9 T6 K5 B6 _$ ~4 ]4 A{
" Z+ M' ~ I; n+ {; D, O- z- ppublic:
0 h: I& n) w( A' k9 W) X virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }# r% F2 y( c; R' q
virtual bool CheckAndRefresh() { return false; }& g" H$ T+ y+ ^- D
virtual void StopAsyncFind() { }4 m {! d b+ R
virtual void DeletePorts() { }
% _# u7 w" @: V7 E; s: U/ j virtual bool IsReady() { return false; }
$ L \2 Q% P1 [$ q) ~3 Q virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 w- n$ X6 d$ k# ^2 X# f* W1 l};* z7 C1 T4 ~' o" b9 t- G- I
! z7 T) I" G2 C; a3 u! j' L# w5 a, l
/////////////////////////////////////
, h: }" l( H7 c6 Q2 _& M//下面是使用windows操作系统自带的UPNP功能的子类
) q- H: P5 _# ]) o- N
' w7 p9 w& Z9 \. ~
" ]% Y) [ L' P: E! A6 N) {#pragma once
* e2 \# M# V; M7 W- |9 c$ x: l#pragma warning( disable: 4355 )
: A9 ]" j* u" y A
: j& K) g# z0 L% R3 Q- e1 Y! A
# A1 m* y0 x5 u. u" D4 o6 f#include "UPnPImpl.h"
3 k& ?1 C; ]5 o" E% A1 z#include <upnp.h>
4 a4 O7 n* k6 h" ]3 J" ^ L q1 ~& U7 E" s#include <iphlpapi.h>
: k) [3 E+ Q P! ~" j8 f' w#include <comdef.h>
& s9 E9 T' a' x* B* W1 A#include <winsvc.h>+ z; i" H5 r" u, h
* p* B9 l0 s5 P2 o5 m0 ~' c0 m5 T8 S5 X: Y# V
#include <vector>
2 J! I! t8 z( t3 m, @' f2 g#include <exception>
% q1 _& i" e. M" ^ k; L#include <functional>
0 W$ C) `7 p6 ^8 o- F
! B! H% I& s4 o* Y: R1 H4 X n1 [& |& X$ H- H$ k. t, X
5 p' b3 z. b4 N! G
; }: X; R' a3 p. N& u2 q& G) qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 A7 l8 O+ _ A; E5 V6 \/ vtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
9 j4 L% d! J$ ^6 o x- qtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 M0 y( D6 l7 S( K+ N4 o; E
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
: h! K' l! m: `$ |typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 _- C7 A! y1 Vtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;, H' @$ o, i; f+ j8 l5 |% R
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;, H) t3 s. B/ ] k
1 C9 m6 B! X/ U4 @6 H/ ^( |6 ?, N, {5 r5 ^, H: `
typedef DWORD (WINAPI* TGetBestInterface) (
% U B( N0 y% d0 | IPAddr dwDestAddr,6 Y- S- e4 I. k- q* y; {
PDWORD pdwBestIfIndex5 I5 V M3 \6 {, C" N0 f
);
D- s7 d, W; u2 P4 z3 b/ Y1 s% m7 C X) I+ m/ l( @
# }. D" y! M' U. d: d: ?
typedef DWORD (WINAPI* TGetIpAddrTable) (
. o1 f% n5 b _/ R PMIB_IPADDRTABLE pIpAddrTable,; p$ G8 C7 U' C4 [0 O# e
PULONG pdwSize,
( v+ u6 Y& g9 V7 D3 { BOOL bOrder, M7 H' A/ V& q: w- }
);& a& m) v" c3 D! L; P7 E, S
: ?) q! t/ m/ k4 ]( s6 F9 |. W5 K: l. T- b9 u x
typedef DWORD (WINAPI* TGetIfEntry) ($ x# z4 D$ Z8 u7 U7 d
PMIB_IFROW pIfRow
& ~& o+ ` t+ q+ y9 }# Z });
9 [0 n9 {3 f ?/ x/ Q5 [9 \) J5 }, A- e. p m! S
( t/ K8 p3 a) |; D2 j9 ]CString translateUPnPResult(HRESULT hr);
1 p, u/ e! `% d4 M2 PHRESULT UPnPMessage(HRESULT hr);4 Q3 y! K% l9 t: a' J: r& Q
) j! j; q+ K3 \1 T( R4 @8 c
* e, M7 d! f d. mclass CUPnPImplWinServ: public CUPnPImpl4 H. r# C* R, k9 {
{# x- f. F! V, @/ }; ?: Y
friend class CDeviceFinderCallback;4 q5 d6 s9 n: z
friend class CServiceCallback;& _8 J. u" Q6 e
// Construction& ^+ f; H3 g- s+ B0 `5 g) Z
public:
. K5 ?0 a, w. k6 |) X3 v virtual ~CUPnPImplWinServ();' d+ }: m0 v- _: p" h. o2 f/ z
CUPnPImplWinServ();$ R3 X3 ^4 @+ K
4 b8 m* k. b, [: H2 y: c
5 M% y4 Z1 `2 J/ ?# h; G
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
- ^& _2 j! I+ ~8 i* ?9 Q T3 T virtual void StopAsyncFind();
/ b5 D# O8 \8 C virtual void DeletePorts();$ \% p- J# R7 L
virtual bool IsReady();; c0 [) A, N. W9 f# b4 g
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
2 s" Z z u/ i7 f# i
3 A, B: V) a0 O) E. x+ N) q& Q9 e4 g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)5 O# S( [3 s' R3 t5 t
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
. d0 W) P' A5 p' M6 J9 }7 R7 c. W virtual bool CheckAndRefresh() { return false; };
- ?& r* T1 [+ x6 G3 H" n5 ?( x5 r8 F. M) y7 _
% l* A2 B& m K8 j
protected:9 t2 m& K) M; B6 y
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);6 w' Y; h1 Z1 U3 K7 Q4 u: B
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);3 ~7 s+ @: B2 F% |: q
void RemoveDevice(CComBSTR bsUDN);
" l. } ~+ T& } bool OnSearchComplete(); t- s3 x1 i1 F) v
void Init();
$ X* ?" b9 _% }1 {$ O ?; `
3 D6 G+ a$ O* K1 S! Y( x7 h; W: g3 I& R8 e; x) B
inline bool IsAsyncFindRunning()
! r; l% q5 ^# ^' i( } {) @/ t% Y* q. U- G- c9 t5 j
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
' {* i \: F5 t9 s4 u& d {; m9 z1 V! C9 \
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );% Y3 y1 n" E+ k
m_bAsyncFindRunning = false;2 k9 k& m# O) i6 G3 P# d
}
- a/ ]" [& m$ W! } r& Q8 f0 w MSG msg;
% \, @2 R$ z( _: W2 c7 B( D7 c# S while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ N6 z1 U" E; d% l
{
[. L X" c) n# ^ TranslateMessage( &msg );
- Q0 ~6 |0 q" l/ g DispatchMessage( &msg );" B9 n0 Y- ]2 h! r# A
}$ W0 |& o6 x) r
return m_bAsyncFindRunning;
) L5 T0 E; S/ o }+ d. _8 |1 ?* @
6 W0 H3 w4 E/ n6 D9 g
+ A, t; Z: v+ o! D7 E4 F, k% | TRISTATE m_bUPnPDeviceConnected;) `+ Q0 G& ?8 V( E5 x# i9 Y8 h8 w& {( ^
' y- \/ m( t6 q2 R$ N
0 ]4 w+ C& f1 H, w4 H5 Z// Implementation
0 ?: `5 w2 T, k4 e# s- ` @ // API functions
- P8 W1 V2 E0 \3 A* H- N4 W6 p2 D SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);" X+ o' S% K. M
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
3 {+ _2 N$ w# ]; t BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
" _7 g0 i0 U1 X7 [' x BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);" r( l* U2 i. U! N# o
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
* W. Y) w1 x6 W: l' {' [& p; W BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 ?- J W( h% Q. X$ S" v" J9 O" H* R( N! {9 f2 u5 P
6 ^, D6 W( m1 ~4 V4 H) E TGetBestInterface m_pfGetBestInterface;
4 [3 l5 ?9 N6 f6 u( Z: D9 w* g0 [ TGetIpAddrTable m_pfGetIpAddrTable;3 F3 e; {1 S# B: Y/ x: U
TGetIfEntry m_pfGetIfEntry;& O0 O% K& n9 _( E
3 G: Q1 p- K; D6 t1 Z) R; g y2 p9 t# a2 C4 P
static FinderPointer CreateFinderInstance();8 d9 x$ B% |1 a/ A3 F; `
struct FindDevice : std::unary_function< DevicePointer, bool >! q" _7 K* ]+ B9 |
{5 O$ z4 N: G- B* _3 l& k
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
1 O: \# d; p3 {' L$ v0 P result_type operator()(argument_type device) const, r0 _6 O& b1 `5 u; _$ }2 G9 N I6 ^
{' i; r9 S7 q3 q5 [: H
CComBSTR deviceName;
: k' v+ }2 \+ M! K6 ~ HRESULT hr = device->get_UniqueDeviceName( &deviceName );
, m8 Q4 \' |6 Q3 |( Z: y4 t1 m5 R4 [. f- j0 K7 x3 Y8 {
8 l9 y w) N( j* Z! {, a
if ( FAILED( hr ) )2 d4 Q! z1 u: f) a' r1 T/ t
return UPnPMessage( hr ), false;! {0 v) R# ~' f
- i1 E4 k7 ]9 y9 v. a# [' I( B; U" X) W
return wcscmp( deviceName.m_str, m_udn ) == 0;) @9 M. K; S! K' @* O. [ ?
}6 ?' A9 e# {3 k
CComBSTR m_udn;% C6 L- l1 J( H
};/ p: e# i' Z# i4 j, S3 t
# x1 p& ]7 n; q
void ProcessAsyncFind(CComBSTR bsSearchType);/ D4 M' T9 B: x) u6 H/ l0 J5 E3 f7 @
HRESULT GetDeviceServices(DevicePointer pDevice);# y2 F0 H% v9 U# B1 N; R1 `) W3 g8 X
void StartPortMapping();
# i8 g0 @0 A& G4 M HRESULT MapPort(const ServicePointer& service);
4 y% I- a! y, t void DeleteExistingPortMappings(ServicePointer pService);
' J4 x; |: G2 {& d6 ] void CreatePortMappings(ServicePointer pService);# G, |7 a; Q7 }+ c4 ~
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);, c# a; h/ W5 Y) Y2 v
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
( J% T6 k/ b& N4 b! ~( g# d" E/ i LPCTSTR pszInArgString, CString& strResult);
7 ^& n% q; H7 v& M void StopUPnPService();
5 N8 D7 c/ {+ z [! P1 d/ U% J0 Z# D* @
" g8 Q7 A1 R5 Q; d5 S // Utility functions
# w: |* U* u1 A, F8 }; l HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ V; S) a7 P! y* U INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);8 |" w/ C+ \* l' Q* M
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);' e( e8 H, Y8 n5 L
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
3 t1 B" r- n3 s# o& G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
& ]* r4 s) `: x* u& h! P5 o HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
q m; p4 U% W: L F' {9 T$ l- n CString GetLocalRoutableIP(ServicePointer pService);- _! b8 X6 n+ `3 [9 A
0 f. g ?; s7 v' h4 ?
- w9 x1 b8 j3 G1 `
// Private members
4 q" o$ L+ Q0 Rprivate:
2 ] v$ I' L" I0 S* d DWORD m_tLastEvent; // When the last event was received?# j- v. q: X. E) n
std::vector< DevicePointer > m_pDevices;7 d6 O/ n, X- n% O: r+ p! c$ p% N
std::vector< ServicePointer > m_pServices;
# Y0 ?8 E! W$ O FinderPointer m_pDeviceFinder;
" t: K s( n4 k; B DeviceFinderCallback m_pDeviceFinderCallback;
8 ]) ~! B7 A/ w% I5 k, s# K ServiceCallback m_pServiceCallback;
, k% E; l) V$ _% r c4 z
4 w3 X, ?/ \+ p1 ?' h4 W2 T. ^
8 r( G; M8 Y5 M, n8 _ LONG m_nAsyncFindHandle;
% D1 C8 W2 z0 C bool m_bCOM;
( L' {" @0 ~* R bool m_bPortIsFree;. h/ K8 \- Z# l9 U4 E
CString m_sLocalIP;4 I3 J- W8 v% I$ V
CString m_sExternalIP;
' T& V8 U& y$ a9 t. V- W bool m_bADSL; // Is the device ADSL?
: T! o8 h2 K/ F$ m( {2 l bool m_ADSLFailed; // Did port mapping failed for the ADSL device?. s1 L6 L! g( [
bool m_bInited;+ `: L+ _ ~3 t% F0 w2 F# M
bool m_bAsyncFindRunning;; ~; S) ?0 z( n* A
HMODULE m_hADVAPI32_DLL;4 }3 O1 ]& N/ ~( j$ p
HMODULE m_hIPHLPAPI_DLL;
$ R' ?9 v; T9 i bool m_bSecondTry;
3 g5 ]( n' F% N. X2 @7 n. c bool m_bServiceStartedByEmule;
) q' U0 F: K* {3 R" y bool m_bDisableWANIPSetup;
8 _( e4 y4 ~' J) U- Y3 R. } bool m_bDisableWANPPPSetup;1 I2 v, L6 H- \# a) E; w( \- f
2 G2 W5 n" s7 q/ Z6 f
! K+ K; H* j; B7 `
};
: G+ n. I* \. {+ z4 }' w) K, Y& `& h% P
: b( v4 }7 ]/ b9 j
// DeviceFinder Callback
) o* O1 e* }+ [. @: {3 a* Sclass CDeviceFinderCallback
5 [$ Q# e2 W& F9 C& M& @ : public IUPnPDeviceFinderCallback) m; W7 q0 \' N8 }% s2 s2 {8 {
{
7 I& @& [5 Y0 ?$ w: `: epublic:3 U+ [5 a5 o! v) K
CDeviceFinderCallback(CUPnPImplWinServ& instance)& h7 Z6 E" u" W! }
: m_instance( instance )
% [9 _! q! C5 P9 e9 P { m_lRefCount = 0; }4 r3 t" ?5 Y e" O, `9 h9 A2 Q: N
0 |0 R' E) o% M& a& J' G# e! R0 J! f9 u4 @ @" ]# w" F
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 o4 R/ S: @* e" R7 v$ J3 [. {3 G" w
STDMETHODIMP_(ULONG) AddRef();
6 ?# l% X2 v. h- J STDMETHODIMP_(ULONG) Release();
# U. _7 Y- f3 l- C9 k( H% x% c3 K2 T
5 [/ f. \: T$ g+ Z7 N; ]) E/ j" _$ Q
// implementation! w5 B5 N" ]- K5 `2 a
private:
) T3 e. M' @( z/ @8 g HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
- n7 q, U0 ]+ c. x8 \% T HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ R- }$ {! I8 x+ t# b! T HRESULT __stdcall SearchComplete(LONG nFindData);' q3 C: J9 s4 T1 D8 M6 `; S
+ a- q8 n+ \! Q" ~/ s5 i" r: I' T6 c. E2 Q; {$ ]) }# D
private:
" r% a5 W. {( s# E CUPnPImplWinServ& m_instance;
) I ~1 F) s! b" s LONG m_lRefCount;
2 |& B: x( w) Y/ x3 z6 m};
& W4 i; q# g& q4 R. [$ t$ K1 g' K
8 n! Z6 E* T0 Y1 d. I$ z// Service Callback * F/ V/ J9 ` V" k0 I5 g5 B8 O$ R
class CServiceCallback
2 s6 Y2 w8 Y0 |2 d( c : public IUPnPServiceCallback
+ e7 k% m; G, P6 v0 I{
+ T4 K z" a! N5 l1 Y3 D% q! j$ N9 apublic:
6 s' T0 |( F1 Q CServiceCallback(CUPnPImplWinServ& instance)
9 r1 L6 R! H! N/ c% ~2 w8 Q P! { : m_instance( instance )6 ~" T+ Z7 g: \1 x
{ m_lRefCount = 0; }
6 m" S" j5 ?# u# u6 |+ D
8 s1 I; {: C+ |" H: u/ i. n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 u8 q. p- F+ O3 S& f
STDMETHODIMP_(ULONG) AddRef();
* M* d$ ~7 S8 [9 X# X5 j) v1 s STDMETHODIMP_(ULONG) Release();: K7 M5 u% I4 U6 {3 A0 E9 [: m
6 A' i- u6 w+ k6 S C. M' l+ G e8 Z0 [
// implementation
* ? I6 n, S' S$ v& Uprivate:/ O/ _/ m, ~% E. S P) p8 s5 J5 i
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
8 V4 n: V5 C: ` HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
4 B8 p8 [4 e: X4 Y$ ^. f/ u0 d4 i4 a/ ]. U/ E
$ M5 B+ e& h' C' k" p
private:0 o7 i0 z4 k: v" @( i( D
CUPnPImplWinServ& m_instance;" I7 n8 s; j8 B8 }6 {5 |4 f: l
LONG m_lRefCount;
7 Y& a8 s) o) }};
, D$ d- ]* N" F& z' g5 T1 _
' o Y- N1 O+ E" N7 K' b$ c4 a
////////////////////////////////////////////////// X1 ~: `" f. o8 ?5 q" c1 X
4 l4 I1 |# f, k+ ^2 ^: E9 I- k5 U
使用时只需要使用抽象类的接口。
+ n. o8 U2 J* j: z3 K( m* c; Q' \CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' ]- o: N) g6 t7 BCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.+ ?- z) P* y0 s
CUPnPImpl::StopAsyncFind停止设备查找.
1 q& d! E1 B: _" n6 D# ?CUPnPImpl::DeletePorts删除端口映射. |
|