|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
: C4 c( c ^5 {
" V( L* r# W4 W, r5 _' L
0 Q7 g% ]9 A. S3 S- d5 ]( l///////////////////////////////////////////
; s3 _$ M9 Y0 L4 C, z; K//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% }% A; C4 q+ ?
- {. m0 |( f- ?( O5 |$ t' O8 T
1 P; P/ `( }; o- l; }; H. S+ s#pragma once
' \; K8 ?1 p- y* d/ [6 y, y) z#include <exception>
3 i" L7 X* n. }. t+ b. ]$ r9 I Q3 _! @2 u6 I( M" V, L
, V& p* V/ k# ` ^
enum TRISTATE{* t z/ N5 G/ s
TRIS_FALSE,% d' Z2 o% H+ i6 h
TRIS_UNKNOWN,
- Z" I* T6 Z3 d( u TRIS_TRUE
" L- H0 z5 d. U( L};
1 j+ S- V: c: N3 p: G, f% o/ o- p8 N; k) e. m
' {1 m* D1 h, c, w8 u0 [enum UPNP_IMPLEMENTATION{
" N( m5 ?$ L( Z, A; S UPNP_IMPL_WINDOWSERVICE = 0,; y" N/ m- `" v D& u: e
UPNP_IMPL_MINIUPNPLIB,
" j( R2 ?2 c! t UPNP_IMPL_NONE /*last*/' G' W, [& W$ l6 `2 |
};
7 J( j: @+ W) _) T t- ^: O0 }; W, B3 C+ A3 O
# ~' _1 S+ R& Z9 w; x5 A
' c5 I& d7 J) C7 D4 q0 d* ]9 N
3 A& t$ e6 {1 fclass CUPnPImpl
6 w% Y* k9 Y [7 w{
0 r4 b3 S; Y) J+ M4 I3 f+ H5 y0 s: ]$ qpublic:
f$ }$ B8 I- P5 f CUPnPImpl();
$ D# `( C/ K0 f+ c virtual ~CUPnPImpl();' Z6 k8 f6 l5 V. F
struct UPnPError : std::exception {};. m+ V/ r% u3 w: o6 A
enum {2 v/ x( e& i7 g4 j
UPNP_OK,
# d7 m/ `4 E9 k& a6 z UPNP_FAILED,* i# o" U/ A, M7 h) }
UPNP_TIMEOUT
, ?2 D' [- r/ i( X };3 K, F( O' M" m: v& U3 @4 P
% v1 `3 E' ^- ] n& V& T8 J; F
" |0 T- o* k6 k# B7 h3 Y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;# ~6 \& D& \& b F* U
virtual bool CheckAndRefresh() = 0;" N1 V6 g1 P6 ^
virtual void StopAsyncFind() = 0;
2 F& e( Z& L% @ virtual void DeletePorts() = 0;3 l+ J' _: j g6 \7 _+ ]4 w
virtual bool IsReady() = 0;
# X- \6 N/ N( h& J virtual int GetImplementationID() = 0;
1 s0 @" f+ D& E' F1 s
" w, f# C! g9 r2 ?" p+ W. e( P7 [ Z void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
# @$ I! e5 s1 o0 o$ C: ~
3 @1 m( B+ B# f/ a+ j1 f& u/ s
4 Y- {+ c# h& a* g ~ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
2 | Z* f; g( m. j7 X TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }6 D- l) Z3 x& | Y# p
uint16 GetUsedTCPPort() { return m_nTCPPort; }$ b* }0 d& `2 j0 v# \2 s* o2 E) \
uint16 GetUsedUDPPort() { return m_nUDPPort; } 3 n) A: \3 s4 c: Q6 I
1 G( C# P3 W2 X4 v5 p9 N |4 `4 }
: g6 [4 }& {' c// Implementation. A L% w) G$ @# V7 `
protected:
8 J% `7 d, z" s5 ?5 ?& ^; u. b! i volatile TRISTATE m_bUPnPPortsForwarded;7 v) t2 }( V9 R$ B, _8 p6 S
void SendResultMessage();
" W5 E5 o. f+ p8 Z( q: c# w& C uint16 m_nUDPPort;4 {* K, d3 S0 k* Q
uint16 m_nTCPPort;2 j; y7 M: q( X: k- m7 w
uint16 m_nTCPWebPort;
# k! h' f; @9 [: a bool m_bCheckAndRefresh;& b" _0 ?0 g# p7 m7 a3 Y* N
8 m! T7 L8 q' q3 k8 V0 i2 B- C6 X1 D, @
private:* I& F' q% ^2 E7 }* G8 C
HWND m_hResultMessageWindow;
: z" s' ]$ [ p5 l$ V9 P UINT m_nResultMessageID;1 K [# N( D' i" t9 I, t) Q
) m$ d! g6 q1 r! L* D+ R% c7 H* U& ?: D- ~& b; J
};
$ ~; ?5 E- E) u, w
: v: K; _6 @0 H. ~( l8 R/ M: K& h4 P9 d4 \3 V* i7 p
// Dummy Implementation to be used when no other implementation is available
( p! C! A; f% Iclass CUPnPImplNone: public CUPnPImpl
% m! m; m& c& [: T4 k3 ]1 \# z{0 U5 D0 p1 `" h: f$ ~1 w" d9 Z# r, g
public:% ?: h+ s1 {7 A3 Q/ L* ?+ @1 A
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ `1 S) v2 N$ A0 q virtual bool CheckAndRefresh() { return false; }/ @# r1 D8 k% w. K8 [4 T' b3 ?% l
virtual void StopAsyncFind() { } z5 q- U, c1 r8 I8 a
virtual void DeletePorts() { }
3 O/ K- t$ h! {* v1 E virtual bool IsReady() { return false; }
! t2 [6 t3 {) K1 ~; L- y# s virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
1 w! a$ Y' u6 l( ?) p" E};* K; p% L* g7 G" d1 E3 [
9 W5 {. v& S0 d' k% }# H3 S/ ]% x2 ]* k1 r" R
////////////////////////////////////// ^; t$ q8 z$ b
//下面是使用windows操作系统自带的UPNP功能的子类
5 d3 x G$ v7 V( F1 o2 J! S) c1 X5 L/ }7 x( e, @
! \+ n; r. a1 r8 m, I
#pragma once
/ f0 W" P0 A0 o* @& j% f#pragma warning( disable: 4355 )
8 ?8 h- ^9 Y) `( E; M" f* D5 p
, F6 @% W- x3 q) J
2 M, o( l% q* ]9 ^; w0 c; z; x#include "UPnPImpl.h"
0 w8 U, }9 [8 A2 C9 V2 N6 c#include <upnp.h>
+ l3 o% @% p8 M; D1 \! [$ V#include <iphlpapi.h>
( ?+ Z6 `9 ?) H* e5 E3 W$ T8 K W: }#include <comdef.h>
8 n7 u8 y' J5 u% `" [#include <winsvc.h>
N y5 i! H% w1 }- e- y5 O0 C- r( O
. `' ~* ^! M8 x- ~ ^# S
#include <vector>* X' k7 H/ Y4 y+ _
#include <exception>$ o+ r w5 Z3 Y/ {4 C' G
#include <functional>
4 ^5 ~) h8 \- e% w$ z9 k: J1 _3 O( u# L9 {
8 I* g: f s% K g
& E. n. r* g- y5 _/ O
% I/ A( V7 i1 D9 Y' Ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 D& k# l3 k5 Ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( @1 F: G( S Y' }2 ]7 O' t: N
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;0 Z$ g! {/ [. x7 Q! m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
% I4 y$ D4 r; L5 E% u1 b8 Atypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 D- i( O. h0 r; z6 n( }" z- itypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;! Y4 j: f( T9 A
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;6 @- k) Q# u4 P
" S2 r# w9 S4 q; M2 v) }# b: c& T$ |# _' P
typedef DWORD (WINAPI* TGetBestInterface) ($ s) B; h0 z% Z/ d
IPAddr dwDestAddr,1 Y5 _8 X' ? f) S6 c# E
PDWORD pdwBestIfIndex( R7 N0 @# ]0 P$ s J; f
);
9 D8 n8 d7 g) S* X; g2 V( Y2 H; M
4 [9 j4 Q3 ?9 I' i+ r! |1 m, Y6 p" W/ D; m
typedef DWORD (WINAPI* TGetIpAddrTable) (
2 {' L' K7 C! _* x% i! j PMIB_IPADDRTABLE pIpAddrTable,
) U) a) a" M( V8 y! c& [ PULONG pdwSize,
+ ]3 ]: m' S# `9 J" ~& v BOOL bOrder
; i6 u5 v7 U8 W);
4 a# F% t# q- j9 W& ^
; K. o0 G' i; @5 y4 r7 Z2 ~) S/ z$ {8 ?
typedef DWORD (WINAPI* TGetIfEntry) (
3 J4 z7 u1 K5 q) p$ {7 E) c% U PMIB_IFROW pIfRow! j+ E; o, p/ m
);
# P4 D6 V+ |3 `; @$ Q, }" i+ }) u! s
7 K* R# Q7 C- g0 D9 K( t* ]
CString translateUPnPResult(HRESULT hr);
1 h8 U4 u5 }% i& M9 `8 e$ PHRESULT UPnPMessage(HRESULT hr);
9 Y, C; p! g: h! I0 O& K! e* T
* B+ F0 z. z- x* e" J1 s2 Q, a, c) D
class CUPnPImplWinServ: public CUPnPImpl/ ]1 N6 ^4 k) Z- J7 `! U
{
2 [, y# R3 Q) `8 U" S2 v friend class CDeviceFinderCallback;
9 S: g y/ |' \; r friend class CServiceCallback;
% j3 o2 _1 [8 Z( b+ l" }; R. E// Construction
& n# j: a# u( }- n+ G* f+ Tpublic:
$ B/ n0 Z' q0 F- P) T virtual ~CUPnPImplWinServ();
4 t+ A7 G+ l" e$ z2 ^$ \: n CUPnPImplWinServ();1 B+ T% W' u9 p
' z! T) S: z4 W; I! x4 N" T' v
5 V5 J( H/ s3 w; B" o virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& Y9 I0 Z: ^/ A! f: }2 x k virtual void StopAsyncFind();( _) d% v; Q$ J- Q0 U; J
virtual void DeletePorts();
" Q: i* X: u4 }+ n virtual bool IsReady();$ h# V7 ]; l9 P5 ~1 R0 E% ~4 o
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; ~! x( n8 K, B( M$ c' B7 Q/ K& Y
! t5 P# F# a2 D+ H7 ^+ [% i j
/ b4 m8 X2 s2 y+ L( w // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc); r$ X! S$ J ^( f
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later7 V8 d x* _4 o r+ z. O) z% s
virtual bool CheckAndRefresh() { return false; };9 {0 x9 G! R9 D6 L
0 r X4 ^# m7 j% u- r4 U
& c% F. B& t6 Fprotected:, w1 x1 ]' c8 W( s& R7 i3 b
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
7 t4 E2 R1 X0 }: ^, W2 ]1 j3 E void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& {# }& P4 w. s7 P8 \7 U; n- x
void RemoveDevice(CComBSTR bsUDN);. K+ O+ d: ^6 o( E
bool OnSearchComplete();
/ \1 Y& Y* O$ r" \ void Init();
# I5 w) B$ m! i% `6 Y' V. G# j' Y9 f' l7 X0 j
& I6 p5 Q$ ]1 Q1 {" b- c) ~" O
inline bool IsAsyncFindRunning()
7 c* Q( l# N8 h# r( d {
5 A9 Z2 v3 T; @, d- p/ v if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )) A- | A) W! \ S: q1 j& n
{5 K7 Q& G) R, u# E0 _. H/ Z) E
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( d9 b E& z7 h( `+ k m_bAsyncFindRunning = false;$ T: Q" i! [; H' i4 m0 R
}
8 T1 M. \" ]$ P1 x' C MSG msg;; \1 R2 h) l9 ]
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )$ M# @' i5 f' u* ^( g% y; [5 V
{
4 s" V- J8 O8 M! {) i7 q% o8 x TranslateMessage( &msg );
2 @8 b* h- X; ?% B* _2 g" G, ~. O DispatchMessage( &msg );
" a) v7 G/ n! i5 I; |5 n; R. {" _ }+ \* ?" L+ i! i% @) [
return m_bAsyncFindRunning;, ~ X0 p4 h4 G1 n9 v5 {& o- r
}
" P) ]4 ~+ \/ s+ H- {6 o l: B
/ l" b7 E4 x3 p+ v7 k
( _( X, E7 j: p TRISTATE m_bUPnPDeviceConnected;
7 X# R+ X7 p0 R/ s9 z
" w$ N. |4 \ o0 x8 r- M8 \) I! J, v* j% d& d
// Implementation
8 ]/ ]$ J) p7 ?) L // API functions
% c7 g; @% b4 }, n( N6 T SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);! G5 r# s/ Y( ?
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
! ?8 `4 @& u2 e2 c BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);+ Q& `7 K7 M1 z
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
7 a0 a' o! ?1 @5 F- K+ d+ I BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
* p% ?5 P5 X! X p BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
2 p% C; [5 s6 [ ]7 t0 W) H! }+ s5 s! S
4 u' a" V3 `2 U" d/ s3 g- ?* I; L
TGetBestInterface m_pfGetBestInterface;9 x5 I2 m4 `; _1 C
TGetIpAddrTable m_pfGetIpAddrTable;" G: [8 Y; Q9 ?$ E$ J' e7 l3 U1 B2 N
TGetIfEntry m_pfGetIfEntry;
# [0 x5 X- x2 ~5 ?3 z+ ^# | |, w( ?& }6 E3 h* Y) a
3 o) ~ ]4 e, k
static FinderPointer CreateFinderInstance();
U" _7 t0 O( N( B struct FindDevice : std::unary_function< DevicePointer, bool ># `$ D3 }8 T' k! Q
{
S5 V5 M7 p9 |4 e, k. o FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
0 f: B& t) N) b" P result_type operator()(argument_type device) const
0 V, t" [( `) Y8 C; D: r {
3 \- A5 ?- U/ T: w' z8 X CComBSTR deviceName;1 W) ?- W9 X4 y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' C9 e- e* S& G; ~4 k/ {% q% P& G
3 H/ }* I6 W9 M Q: I/ |* G, }6 ]( J o
if ( FAILED( hr ) )
. H0 K2 W. C6 C$ P- R return UPnPMessage( hr ), false;; y: p2 b2 _- {" ~- W, O2 e6 M
: h, W7 A m! ]( \- z1 a/ I
6 c! U) v! w: t: v return wcscmp( deviceName.m_str, m_udn ) == 0;9 s8 O( F: n E6 i1 U" N
}& S& V4 q h1 w" v- H5 b( R ]
CComBSTR m_udn;* V. g. [: P4 S: C: M
};
& k) a7 p1 s% M p: I+ k7 O# ] + x) x9 j/ o$ X. ]9 M
void ProcessAsyncFind(CComBSTR bsSearchType);& o7 D2 x) ^; o
HRESULT GetDeviceServices(DevicePointer pDevice);+ J% l& ]0 f* |! l+ V6 O) p. ~
void StartPortMapping();" L% {8 x) Z& [" S. j# j M
HRESULT MapPort(const ServicePointer& service);
. w5 j: K7 o) J6 v8 ~ void DeleteExistingPortMappings(ServicePointer pService);
/ [5 H7 B7 w6 G" Z9 ]; z void CreatePortMappings(ServicePointer pService);
- d. Y: q0 X9 R0 ? HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 k1 w- b2 ^) ], F; ` HRESULT InvokeAction(ServicePointer pService, CComBSTR action, . D9 t) o9 e( m4 A7 D. S
LPCTSTR pszInArgString, CString& strResult);& \' o' X; Q" }/ W3 Y: m$ R
void StopUPnPService(); ^2 b+ l6 u! Z! Q/ A( E5 n% x
% V; W$ |9 y5 U0 U, D% V( Q
: ` q, Q& Z( ^, a5 \( y- F // Utility functions1 i8 Q {" i6 R! e9 o) M4 B/ F
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
! E" [# q2 Q9 A# p/ j INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
0 r S5 ~* F; j9 b5 R0 N INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
2 U5 ^8 m2 u% @ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
W. E- _7 G+ w3 F! d8 w HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* d |; M* ?* d# ]2 h- _4 j+ d- w/ s HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
6 Z- z% M7 _$ l! U- } L. P CString GetLocalRoutableIP(ServicePointer pService);
- `' X- Y3 L; t" Y7 k* e0 w9 {& y$ g: g- V4 y, j! C
9 I9 o" {1 Z/ L( t, ~
// Private members
5 r" ?% L1 |7 v5 l7 wprivate:3 b: G3 J* V" d( H y3 k* B$ p1 K
DWORD m_tLastEvent; // When the last event was received?. o3 Z$ o" z: g" h! z0 p; e
std::vector< DevicePointer > m_pDevices;) ~. u( C- D; H8 H1 b5 I v; ~
std::vector< ServicePointer > m_pServices;1 a9 L7 }1 u1 T* b/ z
FinderPointer m_pDeviceFinder;( F' K+ o( y0 m4 I
DeviceFinderCallback m_pDeviceFinderCallback;. l# I0 t/ W# K8 i- W1 V& h! z
ServiceCallback m_pServiceCallback;- w9 @9 p6 [" ^ J1 W
& R3 \; c) b4 P! `8 s' g# ]/ t' C, j5 B
LONG m_nAsyncFindHandle;" N: y2 ?) q! p9 o3 }
bool m_bCOM;5 s7 v; m W7 H# }2 p4 I3 S
bool m_bPortIsFree;
1 I# O0 l5 E3 c# c3 `" e% X CString m_sLocalIP;
! c Z2 C3 {% m- z- }( Y/ P CString m_sExternalIP;
& P0 W$ { A- R9 w) }4 u bool m_bADSL; // Is the device ADSL?' I! U# B& I8 i2 O* m
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
( h) r& ?9 Z9 x( @, i# F( O/ @ bool m_bInited;
+ W$ N% ]+ t9 W bool m_bAsyncFindRunning;
, A p+ N8 |2 ^% n1 @ HMODULE m_hADVAPI32_DLL;# [0 V7 _6 P. R+ D; H# ]+ p# | _. t! b
HMODULE m_hIPHLPAPI_DLL;
- Z! O' R- d; w9 U% U bool m_bSecondTry;
1 J9 I7 P$ ] z- F) U' n bool m_bServiceStartedByEmule;" E2 F" ?6 d* {9 j' V6 g7 A
bool m_bDisableWANIPSetup;
8 V/ t! L6 G. D' a8 Y3 U2 q bool m_bDisableWANPPPSetup;# h1 q! ]) M5 W, v% N
3 N% K% N& S4 g" s
2 p' ^& C( J9 v};: ]7 Y, ]6 v/ e
k! W+ g% B7 K0 U7 a
I+ G5 h+ s5 K! Q+ p7 `& W* g; E// DeviceFinder Callback
/ s, R9 m O/ t9 H: Jclass CDeviceFinderCallback; Z, W% K+ O% V0 K# c
: public IUPnPDeviceFinderCallback
# w/ c* K( e" \5 |6 c{ x7 c" c4 p% V1 T- Y
public:+ j# V' ~0 p( i0 h$ S' }! R; F
CDeviceFinderCallback(CUPnPImplWinServ& instance), L' Q4 Z3 s! m# ^. J
: m_instance( instance )6 K& {7 Y7 y( { V- c" n
{ m_lRefCount = 0; }/ _0 U4 k- ~9 I# x3 V. I7 q
. F1 p1 e i. T. R" x9 ]/ ]0 S5 } e1 S9 O0 r. p% G2 A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: s' _! x- s% K. @# K7 o6 j( o STDMETHODIMP_(ULONG) AddRef();
: {. n- [- @8 u# d* c) t; a STDMETHODIMP_(ULONG) Release();6 c6 n. O+ ~9 L
0 p& `( p" I$ R% x) }3 b# V. I; X
% ]2 N# D3 s/ Z9 C0 P
// implementation: @" ~1 T0 H, D% X2 i
private:
( z8 s5 S: |1 m6 o7 q0 X9 g$ [* h HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
{, o4 H6 j8 a8 L HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);; ?6 k b* T4 {$ D+ V2 `2 o
HRESULT __stdcall SearchComplete(LONG nFindData);
. `+ H5 p: U5 B/ {2 ?% `) r$ z. g+ N; C- P0 O1 ]5 }. O- q
' v7 N$ D x/ p. l" `private:
?' C8 m9 @3 e' m CUPnPImplWinServ& m_instance;
; }: x( ~& M5 J0 S/ b LONG m_lRefCount;0 c% K) Y# B: ]2 B0 P
};9 j, x9 z/ R2 `; p l' B
; T8 M7 S1 K7 w( }8 t& W5 V# }
7 p* E0 H- t- _
// Service Callback
1 Z5 @2 N6 p. }' i4 B+ R% |class CServiceCallback; ] Y3 q, B2 Y- z: |$ q( v
: public IUPnPServiceCallback
, _3 h8 n' p7 b{) o+ l+ F5 Z# K7 `, h
public:
( s5 P, H% A% |+ u! h CServiceCallback(CUPnPImplWinServ& instance)
5 B9 u- {; O0 V7 C- ?( M4 o : m_instance( instance )2 Z( Y4 ~" F) d# V
{ m_lRefCount = 0; }; C# m1 ]; N+ [4 g9 N: g/ N% G% i8 m b5 v* t
4 g1 x' T. S8 a; q( r8 D4 R8 T
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ d. C$ O: X- {1 x STDMETHODIMP_(ULONG) AddRef();
; }% O* D" }1 ]. T& a STDMETHODIMP_(ULONG) Release();
; t* d* c6 i- O$ C3 p' R
: N0 G. i& N: h+ D4 N: s8 _
( @7 Z: _% }, d4 u" ?// implementation
' L1 n2 g* u7 B! f# sprivate:
- {1 F2 U4 j, P( q HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);! l k/ }* Z) N, y! e3 y. \* b
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
. f( u. Z: c. }5 l3 ^6 e$ ?
; x" \! ^7 F; f d/ \. l4 a1 Y% E
6 \, C4 {- E$ k' A* A0 c7 nprivate:
% x/ s6 g$ Y/ c9 i+ R CUPnPImplWinServ& m_instance;
B1 f/ a2 O3 [1 A9 V LONG m_lRefCount;+ T0 G1 |2 ~ n/ c% F
};
' [4 x1 N3 O1 k! e; c
* v# D1 h e2 A- e) @% f* v2 J3 ~5 p- l/ l9 ~) J# Y8 _3 V
/////////////////////////////////////////////////
9 l* X; x8 D, c$ I+ k) a- Z- p( Y% m, F
9 n/ \9 T0 ]7 |8 ~# d
使用时只需要使用抽象类的接口。
! j3 z6 O* z, p& ACUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
) y- k8 n" {" g) x1 n( z- F9 RCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
9 U/ i7 B8 y! g+ P; ECUPnPImpl::StopAsyncFind停止设备查找.
8 }* H2 a; V0 H M! P, }# p# \1 gCUPnPImpl::DeletePorts删除端口映射. |
|