|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 \: V; `2 v/ k+ \9 D3 @0 s6 \
+ C% D: _( O- P' U- d2 E0 v
+ Q4 N' s) Q+ s3 g) F2 S
///////////////////////////////////////////
0 T4 T9 l& N9 C5 u7 F) C" h0 A: V//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.$ _) S2 }" J9 n+ }* a& {
4 S3 `; J* ~: o2 V7 K' p7 ?5 t+ H w" G
#pragma once
. v9 A, q; L, R! i#include <exception> z1 T9 x' g. K3 }, x& I3 u( N1 B; V
L0 ]7 Y3 w+ z
" O: ~8 N( f/ Z0 I; [; x enum TRISTATE{
& {: N# L, R, I- ]& ? TRIS_FALSE,
1 e( p7 x! u3 l TRIS_UNKNOWN,
7 ]! s) h+ b. E, Q TRIS_TRUE4 l. T/ J! Z: `8 @6 V
};+ b7 _* Q9 p- T1 O+ I: M
/ {: E& @) w- y' S# j1 U& x
. Z: U5 T/ H4 {; J) m9 \4 _9 eenum UPNP_IMPLEMENTATION{3 e; G5 |) d1 @2 {4 u5 N4 ^
UPNP_IMPL_WINDOWSERVICE = 0,
# ^& @" ^0 @. E7 Z! K UPNP_IMPL_MINIUPNPLIB,. v' b9 u' E4 E& F& |
UPNP_IMPL_NONE /*last*/- g. \) a- N1 d% _: A
};
1 O1 y$ {8 w$ q7 Y6 F5 ~* |7 w' @' N
7 l1 T& V' @. s) S3 W
+ ? W' p; Z. Y; ]$ _% I6 w; @. ]/ @
! b5 v0 F# q/ r" w5 tclass CUPnPImpl
! F, g: ~( N: K' h{
1 ~( O x$ m8 W; S" [) ^+ N% l qpublic:- M$ \7 ~1 q6 r$ J* s8 A
CUPnPImpl();
5 Z& W/ Z" W$ V+ g0 X9 n: P$ }$ o virtual ~CUPnPImpl();
' a" H! |' K+ ]$ {" Z struct UPnPError : std::exception {};
6 |1 \: N0 j) g% @! U9 {% s$ I. T enum {
& ?" D4 k/ m0 {2 F" j UPNP_OK,
' ?7 s- ]4 X" c* @1 I UPNP_FAILED,% b9 h, T4 S; \5 n* ]" i
UPNP_TIMEOUT5 n" I _6 c! c* g+ `) d
};
) t" D& `8 F q5 v
& c9 G2 h% y4 b9 M6 w* d
' Y+ q+ |6 J' G! G virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
& d( j# i1 u$ E virtual bool CheckAndRefresh() = 0;
" t& u7 W0 }% h virtual void StopAsyncFind() = 0;8 i& K2 O8 h# o/ x! ]' L8 T
virtual void DeletePorts() = 0;2 r3 Y; s2 c2 v1 o8 Y' a% u+ n- {( U
virtual bool IsReady() = 0;( a2 v# c. W7 G3 f4 v
virtual int GetImplementationID() = 0;2 J5 V+ g; A8 p9 b
( C3 ~3 b- ^' N( R0 f9 J3 ^, ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping" n# l; ~0 _+ B" L: f. T7 `
- I% V1 w1 ?; p. N) d; G; r8 T
8 f/ ~! {" F# H ^* }/ G. w9 @
void SetMessageOnResult(HWND hWindow, UINT nMessageID);" k" b* ~3 h. g
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* X e7 L) M* ?1 K" n Q1 r uint16 GetUsedTCPPort() { return m_nTCPPort; }
. E3 z% t8 p, k7 F5 w! s uint16 GetUsedUDPPort() { return m_nUDPPort; } * ]- y; y+ h `# r) b' i, i9 s
4 R! Z$ X2 `* ~" v6 i) Z @9 M6 U6 R# {! E% X' C
// Implementation" U, S i; w- Q: D( r' J1 i0 o0 M/ k
protected:
$ A5 R$ F% M) M( u2 N# }* Q volatile TRISTATE m_bUPnPPortsForwarded;5 v" p- S2 o* [0 v- N
void SendResultMessage();8 g% @9 p; e1 ?* c8 ?# U
uint16 m_nUDPPort; h5 X, H( c( p6 [
uint16 m_nTCPPort;! c `3 i7 C% {2 z' H3 m
uint16 m_nTCPWebPort;9 g8 d. ^4 f. f0 M8 D; @/ L
bool m_bCheckAndRefresh;
7 m$ ~' V2 h8 W5 O! {& B- s; F$ D6 F
% x6 O( V/ ?( v, g% p A: l. fprivate:
" B' u+ S8 d0 H9 Z HWND m_hResultMessageWindow;8 A. F9 W" X, [" b( t1 L8 n! {
UINT m_nResultMessageID;
* ^) a9 w. k' S& t. H) E$ r4 w/ P X4 a% R% n! S7 T! y
: Z, [- |% {3 ^7 B- ~};
3 x& B4 g" w8 Z _: r
- u8 @, T/ @1 n$ k$ E t Y: F
4 w5 S2 I: @" C8 E* S// Dummy Implementation to be used when no other implementation is available
" w; ^8 I( B$ F) I( Pclass CUPnPImplNone: public CUPnPImpl# t) f* M9 k* U `) [
{
* \# f' s4 J9 Lpublic:
- ?9 {( T. R$ U b0 }( W& t, z virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( W( {3 E; @# L( P- g! F0 ] virtual bool CheckAndRefresh() { return false; }. v2 f" e# e. l$ r6 ]
virtual void StopAsyncFind() { }
0 u- E) o' x; p6 k/ T- K virtual void DeletePorts() { }8 }1 X$ x% {6 `$ }
virtual bool IsReady() { return false; }4 U* B- [6 J* i
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 R1 |3 T2 C2 b* Y$ t$ v v};
$ G: u, L) I; U. H2 Z2 S4 [
& W- D3 a3 y/ s6 S f* Y& q) O8 D0 q" k7 @0 F6 [7 i& z
/////////////////////////////////////7 ^1 e: Z V* _% n4 K- g1 w# p+ q
//下面是使用windows操作系统自带的UPNP功能的子类- L- Y6 t8 Q) U$ r) q7 @
m9 O( {. ], N8 n" p( y/ r
& M O$ P: o% D& T: Y
#pragma once
$ N( Q) o2 x8 ~# Q- O#pragma warning( disable: 4355 ): `) S. n1 q5 K" u
1 s) N0 ~' K- s& q0 J( ^* F8 f7 [$ S% \" q
#include "UPnPImpl.h"
8 R# h g4 E- E# e#include <upnp.h>
% R" P5 G" S3 M7 e' v$ f3 I+ c#include <iphlpapi.h>
6 y2 D) \) V( ?: x; E#include <comdef.h>7 Z, p8 H' n" W; o; _9 N
#include <winsvc.h>
?( N, T: |# B3 R/ x
) \; R, T2 A6 Y& `
+ Q8 P k0 b6 b: m+ U- R#include <vector>
7 w, @6 P4 K) R/ ^1 \#include <exception>8 U2 k1 k3 Z8 N" X8 _' O/ N
#include <functional>, @; h9 h8 {% G8 A
$ n: { u6 L& c, ^/ ^# F. E8 T8 }2 K w0 g) }. f, ]* {
6 _* B9 c/ y1 w$ ~9 v$ @4 K- n- X
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
0 B1 t& `# b! Dtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( A6 i4 B" X# r/ W
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 N$ K" u* G6 v. `
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 @/ e% J: S, r$ H) Q9 e7 B2 itypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;0 U8 k1 L" ]# t% e5 G' h R2 ^+ L
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;$ U% h v- V/ _8 j
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;# S m8 z$ B: j. a9 B# `4 g5 J
1 W% E9 K- l+ h0 V2 } x4 x- `: n
' }2 m7 F. A& e/ S# Q: @
typedef DWORD (WINAPI* TGetBestInterface) (
% ^ _; i( I2 N K& A$ b3 ~ IPAddr dwDestAddr,+ {4 X R# H0 }& M/ E: [) ^, @
PDWORD pdwBestIfIndex& Q- s+ \5 X2 ?7 p5 ?- w& \: o% u& S
);9 I7 ^: q$ A+ g( z" s# n! E8 ^# L
$ D1 `& ]; ~ E' J2 l7 q# |5 H; h/ n- T. l" C5 S* W
typedef DWORD (WINAPI* TGetIpAddrTable) (% n; s, L$ I7 Z s( h
PMIB_IPADDRTABLE pIpAddrTable,
4 y4 `1 T( O5 p. b7 s' P PULONG pdwSize,; J; Z1 Q4 z% w5 s) Z" A$ ]( C" T
BOOL bOrder
5 d' Q7 c9 c* s' R; D);& Z$ I4 q- @2 h
& ~1 W3 D) ?! q* ^6 A
0 W+ S( u3 w' a1 \6 L. v
typedef DWORD (WINAPI* TGetIfEntry) (
9 ~$ k' x5 J1 C/ c) a; Q0 I5 w r$ R3 m PMIB_IFROW pIfRow
/ r: H& H' A% c8 Y% E);
0 [' f9 |. [1 U* W3 N2 ]( {
6 ^* I; q9 I7 l! D5 F: b- _1 ^* a5 b3 C( |
CString translateUPnPResult(HRESULT hr);: B& f2 ^' |3 T( X2 b4 N# t# d
HRESULT UPnPMessage(HRESULT hr);
2 {0 |% f! j8 x* l1 h/ Z
. K3 K: T5 P5 H: B7 W. l0 N1 Z: V' L7 F% G9 g, g, [+ W
class CUPnPImplWinServ: public CUPnPImpl
5 Q4 ?1 I0 T* {8 K{- J8 n" Z- k2 j, e$ a& a! d
friend class CDeviceFinderCallback;
" n2 C1 Z4 ^, U+ R friend class CServiceCallback;0 T; N- q4 L9 P" H5 i
// Construction* ]$ ^ K7 J6 m: m" L) G' A
public:
. l( b6 {! \- F& z virtual ~CUPnPImplWinServ();
1 a! p+ K+ ]8 U7 f; J- P CUPnPImplWinServ();
( q7 s) K M% ^3 d8 c" C# I4 v, B- y1 v8 u) K% i
- I6 k7 V. k- H9 }. A9 q; c virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }# z- ^8 G( w( H" {* C7 i1 ~! f
virtual void StopAsyncFind();, N! a4 }+ X% A" W
virtual void DeletePorts();
! |/ q6 C6 {8 i virtual bool IsReady();
1 R3 q( a/ g- ~) M2 v9 J1 `; ` virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( q |+ v7 P: ?$ \1 J$ `6 j/ L
, H# p b% y! V* i' I
+ M+ }2 O& c9 R // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)$ a9 ~2 Y/ {0 X
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later; f3 { W8 s: g3 z3 \2 b$ a- q0 O
virtual bool CheckAndRefresh() { return false; };6 b% q/ u. _# o5 T8 Y
; e, M/ u: o# H. Z3 `! ]0 e
' b6 `8 p* M: Yprotected:
) _; n. e# j! S) \6 g; W9 j void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);' g; ` @$ r% L# Z: `. Y- u
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
6 w& h, C9 G% I0 l; r! d# S5 H void RemoveDevice(CComBSTR bsUDN);8 b% c: ~3 g3 e$ D. s
bool OnSearchComplete();
N% P- M$ q& i# c z/ K+ u! [ void Init();, [. \ o; M8 J1 T$ z; R$ x
8 ]/ b- H0 z' i2 P _
7 s6 [9 z- T$ {$ V T/ T( x# J. B inline bool IsAsyncFindRunning()
+ U$ c" V: X, N) s; | {) c C+ R( {) S8 }" s$ M
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )1 B$ G8 {7 F7 U# l" m' Z
{) t3 I& ]- N5 N" o, {
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );2 a6 o* M4 z. W8 @* l
m_bAsyncFindRunning = false;
1 ?: k ?3 h6 M6 \# n/ | }
; S! n0 t- J. ?$ q MSG msg;
0 Y) }. a- R4 |# D while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ p; x0 u" d' n6 z( f% T3 a
{
# x: z% o1 M) F3 l0 c" _ TranslateMessage( &msg );3 Y. F* T$ O* g; G7 J8 u
DispatchMessage( &msg );
1 b% P5 ?" K& ~8 m |* f } Y9 q' G- P( j/ z2 ]* ^
return m_bAsyncFindRunning;: [' c3 ^" |3 _, K/ C6 C
}
* }) `. y9 }) F; R& M; C
1 {' ^; T, g. _8 r8 [
$ q% ~$ [ m( R TRISTATE m_bUPnPDeviceConnected;
: T8 e2 a0 v3 e% x4 @: E
4 y2 t/ T- r/ r- G4 U- e
- C& T& R) Y- V% e! S, M# e- b& g// Implementation
R* Z6 ` Y* a+ l) t // API functions
( |7 a8 ~1 x# Q& l SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( e5 o1 \" U( d4 X) L* [
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);3 g4 \$ L# y( u) a# s/ E3 W
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);4 Z: r- `6 _4 ?) W
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);+ \& x" l/ H3 J3 W
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 k3 n: E( X4 ~3 S# f7 Q% i
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) M9 G( C) y+ `" j( T% x: J! u& ]* G& z+ z# B$ }7 T: B6 s& {$ \
- p" x1 ]' L d# Y+ k8 G V3 h- _
TGetBestInterface m_pfGetBestInterface;
3 Z" `) j. z& ~ TGetIpAddrTable m_pfGetIpAddrTable;2 b% o' [$ V2 ?
TGetIfEntry m_pfGetIfEntry;
: Z) c: C/ q0 y9 e& @* R$ g- ^! ]1 I. ^7 a9 L2 N& w
1 u* [' R% T8 Z/ Y) Z7 z2 K X
static FinderPointer CreateFinderInstance();0 \# q1 ]) {& Y
struct FindDevice : std::unary_function< DevicePointer, bool > Y' H; o/ f5 L2 U3 l. s7 m, y
{9 N: P# K- u4 g
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& T2 o# O4 Q7 {- X/ F- h
result_type operator()(argument_type device) const: t& k, D0 G8 k* j$ u
{6 `, D6 l$ `2 O# K( D/ C( `
CComBSTR deviceName;
# D0 W- G' n C! M0 I" O" p HRESULT hr = device->get_UniqueDeviceName( &deviceName );
# S6 M, Y" y& {
9 c& z& j( |5 o! |' l9 d9 r/ n# e: I7 I* g* d1 P
if ( FAILED( hr ) )7 f3 Z1 `2 B$ A# ~/ o& ^$ |. Q
return UPnPMessage( hr ), false;( l9 R2 b% }" C* X+ R* x, ]0 E8 C
6 J, M: k5 @2 f: ?' K
" s- Z0 ?7 _* O" D0 v return wcscmp( deviceName.m_str, m_udn ) == 0;
, g) _. \7 c$ U+ w } ]( `2 |/ n3 R# G, `
CComBSTR m_udn;
6 G3 f4 p, ?; m& X+ B! L2 ` };
: M* v# i) U1 l3 I: I+ g$ U 8 d7 ~; R! p% w. r' D
void ProcessAsyncFind(CComBSTR bsSearchType);/ S2 t3 \9 { S5 K1 ^
HRESULT GetDeviceServices(DevicePointer pDevice);& J. e; g4 S- }7 n4 ]
void StartPortMapping();
+ h% x$ K1 z2 t4 V7 B HRESULT MapPort(const ServicePointer& service);& o5 j- m. u; ]6 S/ U; M
void DeleteExistingPortMappings(ServicePointer pService);6 E+ |3 H1 |# F: w' t
void CreatePortMappings(ServicePointer pService);1 F L& t& f: A: c( j! r
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
1 n2 ]! n0 D7 v9 Q HRESULT InvokeAction(ServicePointer pService, CComBSTR action, # H j* q, [6 J, `
LPCTSTR pszInArgString, CString& strResult);/ v, g4 Y: o/ _. K) G1 ~4 g k
void StopUPnPService();. S1 B9 b) ?7 v# A: |# R& B/ v3 Z
8 u i& v( t9 L( ~! ?
+ M; O- ^# _ w
// Utility functions
( X' a( a% ^' _. J, d HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
- {$ D9 ~+ [2 l. K" \1 y) Y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
9 f8 W! r/ s) x/ h$ ], C7 t INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
/ b7 B* @( ^; ^2 p3 m3 S/ R void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
4 }) m: ^3 O# h/ |; u HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 Q* ^2 d/ l X; [
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* h% y/ z! y5 H% m3 Z7 Y
CString GetLocalRoutableIP(ServicePointer pService);
0 G }$ u- ?& S8 v; ^" O$ r. w: l( I; z, l: L$ A- H: d
y' j: c3 B) B# D// Private members
: t& G p R$ M! `) wprivate:/ S$ c' ]2 O# A- G5 J
DWORD m_tLastEvent; // When the last event was received?
4 K( |: M3 [% c) |1 j std::vector< DevicePointer > m_pDevices;
+ |$ }" E! f. i* D4 ^ std::vector< ServicePointer > m_pServices;* V' f3 U( }0 g. ~3 b3 k5 \
FinderPointer m_pDeviceFinder;7 A* Q0 n5 j/ X9 F" ?
DeviceFinderCallback m_pDeviceFinderCallback;
" ?; ]1 R2 z# h4 s, t6 n) J ServiceCallback m_pServiceCallback;0 j. ?$ M' Z; U& T/ v ]3 }
: r. a- K, t( a
, y( x' {* ~! J9 q1 A LONG m_nAsyncFindHandle;( Y" c, z" y: A/ w
bool m_bCOM;; B/ ~' \7 l; V0 j
bool m_bPortIsFree;
( b& ]* f) I2 x' X% a+ O3 t* s CString m_sLocalIP;
4 r" f. D" h5 }6 x4 e+ v CString m_sExternalIP;
( K7 p; _- c5 c+ B! J bool m_bADSL; // Is the device ADSL?' t7 F- g* f h0 K1 x
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
" x) V9 V1 B6 C6 } bool m_bInited;
. t1 G6 f; b0 r R. q. F bool m_bAsyncFindRunning;0 p$ R5 q6 Z" k% i: f
HMODULE m_hADVAPI32_DLL;
) D# S1 G% e7 A, E# K0 @ HMODULE m_hIPHLPAPI_DLL;
8 _1 Y4 i& T$ | bool m_bSecondTry;
6 Q/ C6 t& H6 A# S bool m_bServiceStartedByEmule;; A( m3 {8 i* }# h
bool m_bDisableWANIPSetup;3 U" l i# I( C; D5 r; s9 j8 y
bool m_bDisableWANPPPSetup;
! i! L( K4 ~5 n; q* d6 F1 {0 q. O9 W2 I! n9 F# o$ x
' p5 u9 t) E* o& P
};
6 m/ r: h! L+ q3 x; R% W3 Z, G- h' M* U- ^- B
* \) F! G2 L1 p# @- G' f4 p0 |
// DeviceFinder Callback1 Z" Q/ u5 J) U5 e& H8 R" ?2 S; J
class CDeviceFinderCallback
* [6 W7 B; _' x* @ : public IUPnPDeviceFinderCallback: ~" B* h% d/ c( J; ~+ ]+ i3 T
{
5 {3 U' q! V f: r2 r. q1 ^public:, e6 K5 v, G7 |
CDeviceFinderCallback(CUPnPImplWinServ& instance)
# m6 D4 G. n# } : m_instance( instance )3 G6 H1 L; i1 P' F" O( ]0 s
{ m_lRefCount = 0; }
; l9 j1 q( _- _! I# v: f4 {* v: g/ D- B5 ]; d
! |4 O9 z" b" ^" {5 r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# T9 {) a# n5 i/ p2 S STDMETHODIMP_(ULONG) AddRef();
5 `) H* j7 P- q$ g ~9 \7 c7 i STDMETHODIMP_(ULONG) Release();
$ F; |- S; v% j" [) s8 c0 j1 o+ r) v/ T
# ]# g; }6 a9 `# P3 p) \, E
// implementation- f- v% x9 g& t6 L/ Y' ^
private:
1 q% Q v1 H3 o) }8 b5 d HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 C: H+ B; {5 a- W5 d, X HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
/ _2 h: y( _ e9 G1 b Y HRESULT __stdcall SearchComplete(LONG nFindData);
$ s9 ?5 I. P3 I
1 G5 g v( u. ~- x! I) p
/ a+ S# I0 s! g. r) d4 E' mprivate:5 f2 K) m. x+ z9 }) H" _
CUPnPImplWinServ& m_instance;/ `/ Q# ?( z6 z$ P+ x
LONG m_lRefCount;8 W" I. K" A3 o$ O w2 A, }
};
. w5 g; X; ?) W. R0 {
3 O- D0 r- [5 i4 g" ^) y& @+ q* o7 b$ ?# }# @# r$ j2 e
// Service Callback
, U' U8 R* h0 H5 fclass CServiceCallback
: l7 q/ G! L8 U8 h : public IUPnPServiceCallback$ L9 q& Y5 n# j B& C! t' b4 n, m( X
{) B& u8 g9 o' B) b5 I
public:5 m' F8 T; }# G5 m$ E
CServiceCallback(CUPnPImplWinServ& instance)
- C B2 D0 f; I : m_instance( instance )
& |% r1 A+ {+ ~ { m_lRefCount = 0; }+ r! n" \' u; R. O
: }) ]/ ?1 g! v* x
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- f7 L8 ]7 s5 z8 p$ [
STDMETHODIMP_(ULONG) AddRef();
9 K4 n4 t& }/ w0 D# }1 ^1 X1 q STDMETHODIMP_(ULONG) Release();3 o. ~( ~7 A) b% {
+ O: K i) I# R6 B/ t: _9 t7 U3 X" u
1 P8 O& J3 P3 K; _! X" v" j
// implementation* g! K% h" @% B
private:
6 H: W( m- T% N1 V HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" ~) J: \; ~. H3 g2 n
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);7 b* D) u3 i# N
3 R" h, P: v) t; N' V6 d" e" G& b N4 P( j K, k
private:3 J% [: W% c( f. U% O
CUPnPImplWinServ& m_instance;
5 |1 g# ]" M3 C2 { LONG m_lRefCount;
! ?- C- Q, c! H! B( x+ [# P};1 V3 u3 }% o- K) i0 v' p
8 p, a, Q6 S( u) a H1 _
2 h) b* b) @ \5 Y+ s& V+ R6 m
/////////////////////////////////////////////////
1 i S# m- w& H" G$ E* p3 p
. D" D$ \- O, t* m# H4 B' f% x9 |( q: k3 z
使用时只需要使用抽象类的接口。
3 s! z% r0 @8 F( PCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.) y. ]( S9 M( X8 w8 U2 B
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
0 W" T* M6 R) J- U5 P" a! u" ?) T2 [CUPnPImpl::StopAsyncFind停止设备查找.* y. T4 I" c3 g; N y& j
CUPnPImpl::DeletePorts删除端口映射. |
|