|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
% E+ H& `) i4 M, b0 E7 ~* r a+ |2 u& D- B; ?8 [( b
/ a8 A5 S5 \3 J: Q% V///////////////////////////////////////////) b5 ~: {' x# l5 J3 e2 p" ^0 S- \
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# E; a: k+ X. c6 w2 C
4 q, O- x0 w' A1 s+ Z# b4 ~4 k3 x) r# L5 t* {1 U0 o/ C
#pragma once
. f; j$ E6 A2 W7 A: @/ [' X#include <exception>
3 d/ s4 Z& B4 v4 o/ h
5 w6 |0 y7 J3 X2 M2 D3 c3 _; C
, r$ Y) l& ~6 m; _* G6 w enum TRISTATE{
/ D* |. I+ d* j- t* A TRIS_FALSE,2 r/ _% g% E: y+ B
TRIS_UNKNOWN,) {6 E) q6 S5 M# c: V- P% n
TRIS_TRUE( S8 W! J6 @. C( z7 \# n
};
- ^7 z' L7 l/ o" {( T+ d% e& N, z( V+ ^! _6 M
. n/ g: s- P( Q7 t
enum UPNP_IMPLEMENTATION{3 q) P3 X) s; }+ H' |7 B* i
UPNP_IMPL_WINDOWSERVICE = 0,
4 _5 Y8 j0 B: r UPNP_IMPL_MINIUPNPLIB,: X7 x- D, @0 U% I% v6 ]! |0 r
UPNP_IMPL_NONE /*last*/
5 ?' I7 a. ?- v- [$ _/ G};/ D/ R' H; n! N# J! L; y3 J
4 i, q% Q. W6 d# \- F, g) A6 ~
7 P- i% R6 S! G& w4 w$ p6 [/ V0 g
8 v8 r% s4 X$ i& a# k
3 Z% j& x; n' A5 A4 V+ p
class CUPnPImpl
- C7 G6 I8 Z' H" N) Z7 Z0 ^1 ?{
7 a, t" [" e. F6 Lpublic:
" h0 e3 f8 c1 u- I' {% | CUPnPImpl();- V6 H# B& k, ?- v# C- ]+ ?2 b
virtual ~CUPnPImpl();
! C+ Q9 k, @( d( {9 U* Q2 w3 K struct UPnPError : std::exception {};3 l/ G/ j; ]# u6 W
enum {0 h) I# N0 a, v; K! [
UPNP_OK,
: f/ `7 p& k9 e% D6 M K" A8 h, B UPNP_FAILED,
# G2 n/ {, z+ w1 `7 } UPNP_TIMEOUT6 ~! W' K6 N! K, u- f* D
};# M" m0 C; Z+ k" O# U( T3 b! Q
; t+ Y% {& ~1 r8 U
' r% o: j: ?+ W* m4 b Z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;5 p2 k/ D2 H$ j3 F( \/ m
virtual bool CheckAndRefresh() = 0;
5 f8 K/ m6 ?+ ^2 O7 h- b/ l2 f/ n, ^ virtual void StopAsyncFind() = 0;$ ?9 u3 u% K! Y5 A) ^
virtual void DeletePorts() = 0;
8 r! i) S; M* t% m9 F! { virtual bool IsReady() = 0;/ N& B, G4 \' x' g
virtual int GetImplementationID() = 0;$ a" [0 Y# ?% o9 |9 r
4 T5 ]1 F" I# |$ \
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping- a3 O# S! ]8 q
; k" o v" L9 G5 R' T2 A# F2 o9 G
( w8 {* W* @6 z6 h2 [' u1 E8 z! l void SetMessageOnResult(HWND hWindow, UINT nMessageID);
, N' N) X0 p% b6 x TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
3 x3 M3 v5 Z7 i uint16 GetUsedTCPPort() { return m_nTCPPort; }# |! k5 C. N( E! E
uint16 GetUsedUDPPort() { return m_nUDPPort; }
! {' C- J4 [7 \; N$ A# A" J
% X! A u2 F2 N% w2 |) Q. }3 L7 T- |) q9 m
// Implementation
" S& P6 v# b$ n. h1 [protected:1 E* H' b- e' d. \- K2 `9 R
volatile TRISTATE m_bUPnPPortsForwarded;: \ K9 i/ v b& S, p3 Z6 U( q7 G
void SendResultMessage();0 @" }3 z3 ?6 n& ?6 p" p
uint16 m_nUDPPort;
5 @) b6 N! w" w/ ? uint16 m_nTCPPort;
0 c; z- ?; K$ t; H7 s* B* ] uint16 m_nTCPWebPort;
4 C8 k+ o% s2 g, u bool m_bCheckAndRefresh;' i2 P7 |7 ^* I' I+ c- W2 _% N
$ I& Z( y* o. H7 U2 E( M i9 k7 A. e5 N5 {5 N' ~, ?# @ _9 O
private:
) N( P }, [" |9 m' T% U HWND m_hResultMessageWindow;
" y0 {" }% ^) ]+ h0 q9 d% u5 q+ z UINT m_nResultMessageID;0 u0 @6 P5 i4 T/ D3 }( k
; L! N i% s/ X1 _8 H) Q; L( m2 q: O1 F' |- |
};; L$ I: k2 V. p$ |% e" H
! d, T/ [( t: x4 m+ c1 h
, v3 f) X2 i: j/ K// Dummy Implementation to be used when no other implementation is available# T( _9 z- X3 M1 E, \+ J+ n
class CUPnPImplNone: public CUPnPImpl( h; T4 ]( X, M5 n: a+ t; U$ w. y/ H
{/ I# c% j0 F+ `" T5 ^* _
public:: v, {0 \: M7 s+ V/ v
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }4 H1 H1 o$ e7 I/ R$ n4 t; }. w3 [7 ?
virtual bool CheckAndRefresh() { return false; }1 Y, b! `) z/ s% p# [, ~
virtual void StopAsyncFind() { }
- i2 u0 @2 C3 `9 }3 E1 x, G virtual void DeletePorts() { }+ ]6 u S. B+ z/ P1 S6 l `/ \
virtual bool IsReady() { return false; }% ^& }7 }. T& o- a: O8 o6 E! k
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }* S7 m4 H0 d. X; k5 T
};' Q! g+ S" M& K+ q y# I) }
5 @' B+ H0 o- v" n0 [
0 Z7 A1 r- G4 d4 w/////////////////////////////////////
% U s- Y! \ @6 c( m//下面是使用windows操作系统自带的UPNP功能的子类+ H+ n1 U# s4 h# t" c2 c; F. W
' N, K! L$ k P% Y; ?
/ A: H( n, p9 J0 N: G#pragma once
8 j4 H1 s" o5 V3 P#pragma warning( disable: 4355 )' A+ B* H# H$ i! t
* {2 i8 r7 u0 W
- a, v1 l) W( e. }+ M#include "UPnPImpl.h"2 u0 r) q1 Y% G) a V
#include <upnp.h>
+ C. f% @8 O! p6 _1 m% y8 T#include <iphlpapi.h>
' F8 R2 t- Z- k7 \' J8 p5 W#include <comdef.h>
7 J% ?# q0 S3 L#include <winsvc.h>; T: _/ }1 M- R0 k, ~1 U$ A
' Q6 y8 J* G" @$ l1 N
& U2 W0 |3 j( E#include <vector>
: O3 h% _( x) l$ M#include <exception>7 F4 M" t# m n% i
#include <functional>
3 m- p4 A+ x& E4 e$ u" b2 A; X/ o/ S) A" R( P0 O' p z/ m, X: }* [
3 }, x6 I9 Z/ j0 O( K5 r' L: P" }! O
8 X9 H& v4 J& V0 S
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
3 W8 o; E* Y9 Xtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: ]! p2 D* S' l( r& ?4 A
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;4 b8 n1 I& A0 n# w0 L
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
$ s, j- b: p3 q: ~* L6 l( htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 E& {& h! g' E- z/ ]typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 S7 o. a1 Q6 y7 I' k, V$ Ntypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;5 I( X$ A; X5 i8 @9 \
$ s% C3 b5 q! t M( y; e K" R4 _8 O# N- r
typedef DWORD (WINAPI* TGetBestInterface) (
7 T( y% h0 t) y! U7 u IPAddr dwDestAddr,
, u3 t. u9 A4 `1 O PDWORD pdwBestIfIndex
q7 t5 K, w9 W, _# R1 w);/ d, J) a8 b6 J N6 q
) i6 K/ D' u2 K
+ g2 k7 y/ x( n) ~' R
typedef DWORD (WINAPI* TGetIpAddrTable) (
$ H% F% R; H9 c PMIB_IPADDRTABLE pIpAddrTable,
' H; ^7 p9 S9 m' z, r2 x, Y# W PULONG pdwSize,3 |/ Z0 k1 ^- E( k
BOOL bOrder
$ Y I+ ^+ X" B. e0 G% t% h);0 X" j( H) Y9 ]* T/ K
7 H0 D1 C: B5 C& a% F) n! c' H6 Q$ o$ Y
typedef DWORD (WINAPI* TGetIfEntry) (. ^; T# _. q% P- x" c/ T+ @# m
PMIB_IFROW pIfRow0 J% t/ ~4 J3 ^) x. z
);3 a6 {6 `) a2 s
4 }# S8 f# k; A, \+ j, M$ X) Y" M
7 A e" r5 g2 g' U* i8 y) f" uCString translateUPnPResult(HRESULT hr); ~; `+ O' V, k( p" r, e
HRESULT UPnPMessage(HRESULT hr);
& k" y8 k: M% z V- C9 b5 g+ M( p. S2 m$ k: r
1 w; N1 k% j# Z. j5 V
class CUPnPImplWinServ: public CUPnPImpl
/ o( g: z! H. a# V# q$ p{& z0 _3 w' H. g
friend class CDeviceFinderCallback;
; A9 u- F5 P @- i+ i! m: v friend class CServiceCallback;
' I4 f2 m/ S% @# N: ]$ R# s$ H1 O6 u// Construction
1 |( T( N3 ]1 g& e: {& d" F/ j+ _public:! ~. M/ ^/ K6 ~. @, d* ]
virtual ~CUPnPImplWinServ();
" J6 N+ j! X1 E' { CUPnPImplWinServ();' w7 o3 c* H% m: j
+ n# B4 Q: R( |2 H$ }# o) h
* M$ E* B% R \+ S7 ~ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
6 M r" A" H9 t3 @; [+ a virtual void StopAsyncFind();, I: l D1 j9 ^# f
virtual void DeletePorts();8 R5 ~3 a; y" {# R: F! I% G
virtual bool IsReady();: z: i. H$ Q0 L- j& m
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }$ L6 R! Y0 k7 ~
# ~& \5 B1 N; ~! Z) F; a+ Z
5 a1 {, `" F: w m% y t( e // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)+ | A" ^" j" s# X1 p5 `1 ^7 l
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 ^0 C2 o1 w9 Q8 ]% ^
virtual bool CheckAndRefresh() { return false; };
) _2 [6 i/ _. a1 H6 f
# S& H ~7 [6 Q% y
" D1 n" C1 o/ r6 \3 bprotected:
' N/ O' g& v/ E void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 [" l, J9 ?8 L# v% z, l! i2 c void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);6 z* G, d8 X* R" i
void RemoveDevice(CComBSTR bsUDN);" m, N# n0 s& G, C
bool OnSearchComplete();
9 J; K7 J) M' G4 m/ } void Init();! @4 d7 H' H5 t3 q
3 T( k5 i" W0 U: D3 ?* K' I/ W+ o6 c Y9 Z, ?1 v8 M( u: B+ t
inline bool IsAsyncFindRunning()
) E2 f9 ~, z: r# O- f {: X2 o" M8 Q* F6 |
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
$ ?4 M7 N6 {! ?& E0 R: }" v {
5 C5 h6 Y1 Z" D) x! c0 M m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
H5 L8 J! Z" R) P& \8 J* V$ j# O7 a m_bAsyncFindRunning = false;
8 I3 U* d1 U1 k6 B1 g! J7 w }
6 W& X0 x# i( J( U MSG msg;
7 D: }) b$ V' Q- q while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ); p$ F3 V+ _7 W$ X
{
. ]$ f) p8 }/ S% K O( ^# S TranslateMessage( &msg );5 d* K# N" z& G9 p6 z, G9 c
DispatchMessage( &msg );& A! X( t& H% [
}) F, }& D1 a, k
return m_bAsyncFindRunning;
& z% t$ K4 N/ A! U6 C }
4 X7 K) X+ G4 H: R/ ~3 k0 |( r# R( _2 ^7 p, c# l. g
V8 x; N, j" f* b( } TRISTATE m_bUPnPDeviceConnected;
) ?9 Z* H- W$ v7 |$ {8 W) {/ t
9 y; b; T$ } }% u* ~
' ~' C2 k: y6 D) S// Implementation
, C6 L3 B( I {- \' S* L // API functions% p" I) `4 G7 S& ?+ T
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);) I% D9 r. a# Z7 ~9 U; v+ ~0 E9 F
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
& n# y9 _( M8 n" }% e8 e! u$ h BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);+ d& n! M0 z0 F0 ]. U
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
3 ]9 v9 N! ~% s$ F- K; B; H BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
0 N6 ]. L3 a: A$ \1 d/ z/ D BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
4 j7 a2 y. @! K+ R9 F5 C
6 y! p8 T9 V7 a3 K. A6 Z/ c# K- Z$ P4 g: v
TGetBestInterface m_pfGetBestInterface;
+ B, `+ L3 N2 y# Q) K: j TGetIpAddrTable m_pfGetIpAddrTable;" c0 h4 R+ _! z( Y1 j
TGetIfEntry m_pfGetIfEntry;
- q* B* v( C3 ^9 c
X" V- b1 |& M: v* f2 ]# x5 N
* v \' n. u5 d. X static FinderPointer CreateFinderInstance();+ j% ?# j$ R8 S% U. o* V( o
struct FindDevice : std::unary_function< DevicePointer, bool >' A0 Y: @, H) b+ x% X
{
0 ^( Y$ L5 X) Z; I3 j FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
4 z6 e8 Q# a/ P3 z/ ^! j+ Q result_type operator()(argument_type device) const
: Y4 g8 g) n2 S u2 I6 t {
9 S" h2 g, R8 h6 V# f5 ~- x CComBSTR deviceName; m: i& w2 [6 q4 Y# N: u" E& J
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
$ ~3 L/ S8 e) m$ U* ^; @
/ _- G( g' U& J8 _) K6 w, S" n- |9 U9 ^5 ]9 K% R) O2 r! A8 _
if ( FAILED( hr ) )3 T' T5 o) S( _2 q. C3 I
return UPnPMessage( hr ), false;# A5 i6 M. B" m1 `( _% E
5 C3 W$ a+ N7 K! V# K
9 ~7 b- r% _+ T9 D- m2 F# T# c* c return wcscmp( deviceName.m_str, m_udn ) == 0;6 n) Q/ [3 U! V7 R+ v: a4 W4 V
}+ O, g1 J$ b0 a% l4 F( P* D
CComBSTR m_udn;
~3 z5 L! |7 ^0 z3 Z: A };
6 M$ X: T$ O! W: @1 s# s& f , T6 s5 ` V/ Q6 W
void ProcessAsyncFind(CComBSTR bsSearchType);
: _2 f( p+ r k, M/ S# P" ? HRESULT GetDeviceServices(DevicePointer pDevice);9 E0 A c4 D9 l
void StartPortMapping();, U# A" ^( c& v( j
HRESULT MapPort(const ServicePointer& service);2 j+ f8 Z; { T, J( K7 `
void DeleteExistingPortMappings(ServicePointer pService);6 d( r, M' h) }/ s. j
void CreatePortMappings(ServicePointer pService); X& g- V: }) T# A, Q5 t4 G
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( S+ d: l7 g* ~0 Q HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 5 Q, l1 u K, c9 |7 [( L* R4 A
LPCTSTR pszInArgString, CString& strResult);; v1 E# F4 F) O
void StopUPnPService();5 d+ d' [( E. u6 u
- ~ g8 a# L$ d
4 ]6 @# Z7 j- ~9 Z: t1 l N // Utility functions
/ U% S1 ?' D5 u HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 R- T( O% w( U& t5 r, i+ ?) q* c INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);6 R! o: F/ c" `+ s/ m; M7 a
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
+ R- M" L* G4 r; F7 `+ ]6 y3 k void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ O7 K6 p( s7 y8 H0 H* D6 J# f; ^
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
6 p9 n) u1 [, H' T3 w HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);2 A$ H) [$ e* s0 [/ ~) r
CString GetLocalRoutableIP(ServicePointer pService);& h3 r- K2 `8 K) @6 @: v( X
( t9 ~. f$ K; ?7 z; r* v8 N0 \3 h
6 v/ k3 `+ s& m X// Private members0 K, Y. x8 y M/ v: s- n1 X1 t
private:1 ?1 y9 A& \! M
DWORD m_tLastEvent; // When the last event was received?
; \& M# u I) C2 M std::vector< DevicePointer > m_pDevices; ~; W R+ T7 b$ q: C
std::vector< ServicePointer > m_pServices;
1 ]/ j }5 @' W& Q, d$ R7 X4 x9 u FinderPointer m_pDeviceFinder;; i$ `# x8 k0 x: e' W8 S
DeviceFinderCallback m_pDeviceFinderCallback;
8 _6 h. o2 q7 }6 V" @3 f ServiceCallback m_pServiceCallback;( d" T& ~# `1 G
+ m% A/ o; j) C- I5 W' g O5 }6 F9 `: V/ a8 r& A
LONG m_nAsyncFindHandle;
) S7 z' c5 d+ q0 R+ \% B+ k: n bool m_bCOM;
0 M! w- K( ?/ [4 `8 D2 ^) ^ bool m_bPortIsFree;
) i2 n5 d7 Q9 |$ D CString m_sLocalIP;, B: _% |. u: u/ B+ g) I% Y4 B7 X
CString m_sExternalIP;
% o, A- S! D' X, Z9 x/ E, w bool m_bADSL; // Is the device ADSL?
W2 A9 V b8 t/ u' T0 } bool m_ADSLFailed; // Did port mapping failed for the ADSL device?1 l. L! ~% t% `
bool m_bInited; E3 ]( Q2 ?$ W2 Z r
bool m_bAsyncFindRunning;% g( R/ a+ j5 {; B# u/ p# d
HMODULE m_hADVAPI32_DLL;7 ^2 y8 M2 x4 W8 k- D
HMODULE m_hIPHLPAPI_DLL;0 Y8 N2 p. W0 y7 M# V3 }6 J
bool m_bSecondTry;/ K/ W( F, i! q2 W5 t* z& T; R
bool m_bServiceStartedByEmule;
6 g4 z3 ^! z* p' f; Z5 m bool m_bDisableWANIPSetup;0 y2 e2 A9 ^- X: ~+ B+ a
bool m_bDisableWANPPPSetup;" ^# P/ _1 [ y9 Z: r. k. z% z* l0 y
3 h$ Q- ]. x& y) |) l2 l. n; ^/ I0 }* z& q" |
};( T; E: t5 F& {( s3 D" U" i# W G
7 p+ j0 _: }+ p5 H9 C* |6 }
6 H" I9 W' J9 P* Q# Y. f// DeviceFinder Callback3 `. D. D! I. V4 R* K: e
class CDeviceFinderCallback' Y1 p8 x# n0 I& @% w$ Q
: public IUPnPDeviceFinderCallback0 c5 q' b) B" n8 f/ Z1 o0 ] D6 w3 d
{( a5 L4 W: J/ k1 V k) d7 |
public:
( u0 Y6 ^7 I# z! k0 x. V# V CDeviceFinderCallback(CUPnPImplWinServ& instance)
) \* A" v1 n# F; y( t6 d- l1 y1 z : m_instance( instance )
* l4 a9 E" N5 }/ u8 e { m_lRefCount = 0; }
# t R* A! G( P/ C+ b7 D. h& U. P6 |- W
" ~$ K A3 V/ w
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. T5 v+ U" P }$ ]: D STDMETHODIMP_(ULONG) AddRef();+ j: u: a/ |8 E) o: ~
STDMETHODIMP_(ULONG) Release();
7 ^. D) d6 Z$ _ Y
& _# T; H8 s1 G# U
+ R, h7 | G2 r( n& `. \$ H// implementation
% @4 W+ q. H# z( t" xprivate:( J+ S! U" w: f% `7 i k
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);# b* W0 g# w# w0 p+ C
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);/ z9 g. I; h9 ^; o9 h2 N
HRESULT __stdcall SearchComplete(LONG nFindData);
& f' k! G+ M' j4 z
4 E7 B( D- U D6 y3 C
. z+ r- q3 {$ r7 Aprivate:2 p% [% g/ e+ j" N
CUPnPImplWinServ& m_instance;/ q& b$ b" L1 y$ x' \
LONG m_lRefCount;
3 R9 {. i% r5 i" ^. M' ?" q# [};: k$ w8 `3 }: A; l
& h7 i- _ d5 @( @0 z& v7 V- J8 W
# b5 ^& k/ F( g
// Service Callback . Q4 b9 V/ A: c/ R+ C
class CServiceCallback; X3 U0 Y! q! G( U) I
: public IUPnPServiceCallback% g7 u) k: N$ E' [& T% P5 c
{
# P) V5 @( m8 i0 p u$ e9 Tpublic:& W: l) J1 C, s: V1 |/ r
CServiceCallback(CUPnPImplWinServ& instance)
9 v1 X* }; n4 G1 C, o' q0 ] : m_instance( instance )
' k+ o K7 V! Z. _* J. M { m_lRefCount = 0; }( ~5 {' v5 m. ]; I
3 @. n E0 ^/ [: C: ~$ k6 r) Q
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
! [- I" M6 {& v q, s+ C STDMETHODIMP_(ULONG) AddRef();
$ @5 h; D& ^5 z3 A. e$ |. {, J) m STDMETHODIMP_(ULONG) Release();: m# `& M$ g( f4 b
8 I l3 S& N, j' s3 A% m0 R
; e/ V8 T' D/ c* h& q3 |" h
// implementation$ F. s& l3 T# w( ` K$ i" D
private:) h' ]8 N( [3 I- p
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 _1 y% x+ r+ @+ u: e, s HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);9 C$ _& a+ g) q& e+ u' `+ K
4 s; ]. ^" x% e# |) V& ]
; o* k; W; a1 l- t+ D2 u* Y& I3 B
private:! n/ t, o! F b5 W% c
CUPnPImplWinServ& m_instance;
* R# {- `) M K5 R- v LONG m_lRefCount;
9 O* v9 D3 X7 x$ f- k' V};
4 Z" a G$ |/ y/ B7 W) B6 n* k( d
9 g" `2 T* ~# O1 E# b6 \( L, v& G
/////////////////////////////////////////////////6 F' O* V, \! e- A8 Y
5 y* Y, h K8 {1 [7 y. W& Q
; ~: V' N# c9 b" m7 C( f% W
使用时只需要使用抽象类的接口。" ?: J2 i+ n* q% S& B6 w
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
" y+ Z2 Z6 w( Y' s8 Y% yCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.# o8 n4 Z8 o1 G" m) E. @, H$ y8 {0 B
CUPnPImpl::StopAsyncFind停止设备查找.& C/ Y! U# h$ C
CUPnPImpl::DeletePorts删除端口映射. |
|