|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
* I8 t) u3 @4 H& s; M$ U8 l3 t! O/ {! @9 O2 \6 [4 A
5 t/ e6 ^3 s0 i4 t///////////////////////////////////////////
. k1 I, \. J. l+ p# J//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.5 e% T S; s. u& V4 ]
) n: s6 C1 X; n* @$ C* j
7 F( J! a/ y* ~1 Y" D# o& J/ V* v#pragma once
* s! M. M B2 K# q; [) n#include <exception>% f1 G/ L B6 O1 p9 Z
& S8 g2 X8 B w# X
8 }( b- X1 D! V4 z' Q* Y enum TRISTATE{
( a1 |& Y; l+ a \: w6 Q7 l TRIS_FALSE,. z9 @/ [( W7 |8 I/ }4 E& L4 N- n
TRIS_UNKNOWN,
0 X2 j3 X& u0 `$ z) H* j. N TRIS_TRUE, d! f6 ~0 V+ h3 p7 u6 ~
};
( X' h& H. m4 v6 c, K2 ~: t
2 U7 T! n8 P! X+ \ _+ s
" F3 `& S0 F9 L) Genum UPNP_IMPLEMENTATION{7 b8 h4 B- ]6 Q3 F6 l8 k0 u
UPNP_IMPL_WINDOWSERVICE = 0,
4 r2 H+ ?, m" y( }. @9 D8 @ UPNP_IMPL_MINIUPNPLIB,' `9 B6 F) {: W5 q+ V! ^" H3 ]! ~
UPNP_IMPL_NONE /*last*/
3 U8 A2 Z, R5 A2 d8 ~" E};
) ~2 H2 X; o, z$ x% S* q9 X1 q; P4 L; ?
4 W' o7 s) | R7 ?: l/ \; r* L+ l6 `
0 }# E; d8 V! \! E) D3 _; k
) s) Y- m3 l. T6 lclass CUPnPImpl
2 g! ?: E- h+ ?{7 K( I0 B6 ?$ I2 l# R% N
public:& M& @5 `% m$ t3 d6 B# ?. O2 y4 h
CUPnPImpl();
( T+ L+ s1 j% L, I: ]% F* B virtual ~CUPnPImpl();
( j! ], r3 O1 |* V9 N struct UPnPError : std::exception {};
0 P# w8 ?* D: i3 q5 @& P enum {/ d# m- r ^- O/ ?* P7 W
UPNP_OK,
7 G) P; ~, T( G1 {+ Z2 \7 h UPNP_FAILED,
3 r! v) w/ [$ E: d UPNP_TIMEOUT
8 E4 d+ g3 b2 O2 @: J) e) ~ };
, W( C8 q% h& E$ f9 n; ~ b0 n4 Z4 k7 n) r
2 p5 n9 X8 N( |% }! R
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;9 U+ l" F4 N( D7 E
virtual bool CheckAndRefresh() = 0;. B6 ` }* ?. X8 u- x& f
virtual void StopAsyncFind() = 0;/ U- x3 j1 c; q* D" G0 h/ }' ` o
virtual void DeletePorts() = 0;8 {1 p6 r1 f" Y! P, D
virtual bool IsReady() = 0;
% c% s- P5 ~7 i0 t k$ } virtual int GetImplementationID() = 0;* v9 `. B; k/ q3 E, m. z4 Y
/ a- G/ f% C3 t7 l4 U4 G. @2 T void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
) @: l( o0 I4 M5 R2 {
# R# D/ T* v: D" C0 e2 l$ \; l4 j0 `" p5 v5 ^0 L9 E9 D8 W
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ Z; o& n0 N0 A& k+ _ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }3 q$ n, b2 H, a; c7 ~
uint16 GetUsedTCPPort() { return m_nTCPPort; }
. l* _6 i, x3 z3 m( | uint16 GetUsedUDPPort() { return m_nUDPPort; }
' T* s4 B: f( R
) J: k+ r4 P7 k3 D$ ?" H* C1 h8 f, T* C0 L- V0 K) ^
// Implementation" o% Q$ h/ j( |* D2 }7 C
protected:
2 m% e7 }: c- |" B. [2 e: m volatile TRISTATE m_bUPnPPortsForwarded;
, R, b* K% v0 a5 s2 a7 j4 n: J void SendResultMessage();
+ {& k! y5 d& X) S3 {0 b# o uint16 m_nUDPPort;3 E+ [' c2 c' Y6 R4 a- f- B* q
uint16 m_nTCPPort;
/ F* }) _0 A" ^/ }; w- j2 w+ I uint16 m_nTCPWebPort;: Z/ B2 V; J1 D" \) P/ i) ~: L
bool m_bCheckAndRefresh;
3 w3 B4 S4 v8 R4 e3 Q" Z- k7 l3 {" t
) k: P7 U+ x' c: S/ Q4 ]( [- L
private:
0 q- O& F9 O/ Z; l& z HWND m_hResultMessageWindow;
( ~+ Q8 m; |; T% F& G UINT m_nResultMessageID;9 w0 k/ g3 }2 N' U) a: D& u4 a
6 w3 @7 i: ?% ]
- V" I- q1 @0 s' g, s
};2 y. e% R+ u+ t% I1 K; Q( G
4 R8 r4 H2 D, w9 Y
, \" _+ I7 b3 ^6 q' j// Dummy Implementation to be used when no other implementation is available
, X; Y- R0 N' Rclass CUPnPImplNone: public CUPnPImpl% h% g& e, K( ]0 M$ b# b
{8 i2 O) {* t: d5 v* ]
public:
. a0 `* m" @: R! G virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
- r3 \; K0 w( R7 N8 F) H virtual bool CheckAndRefresh() { return false; }
* D& h# ]6 z7 g N0 C9 N virtual void StopAsyncFind() { }& k! a8 ?* z# d5 N% d6 ~
virtual void DeletePorts() { }7 L7 L- K* w- M& G
virtual bool IsReady() { return false; }
- r# \9 c3 O8 h+ R2 ~" P+ A virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
( u. X9 [ ]" i3 O$ @};1 Z, d5 g+ ^' o( ~: r
, ]: W4 _ i; _0 _/ {+ f
$ r; ?# i* j0 ?7 u' ], _/////////////////////////////////////2 n7 K# t. F7 E5 n" U
//下面是使用windows操作系统自带的UPNP功能的子类
) @# L) {6 p& N) @
" ?+ L( f/ i* {9 S0 I' A# s0 l# r+ j$ w) i; u$ U
#pragma once" e) w3 m, a6 a+ `6 X$ W
#pragma warning( disable: 4355 )% U& s7 t$ @# ^' T F* V7 a
# y f) U6 o; k' ~4 @
. w( y- y3 @; y/ l ]% K+ f
#include "UPnPImpl.h"
) e2 W+ Z' ^0 U; l# ]+ o#include <upnp.h>
- z9 P+ F; F% A: x, F- b' k% S#include <iphlpapi.h>
/ Y6 y0 m+ n6 ^& d: k" \#include <comdef.h>+ Q( S0 g0 W5 E
#include <winsvc.h>
' q% |; U7 F5 w# I, }. H1 Y. `8 \$ E5 f( S' ^+ L
$ I: ]% U G5 a! h/ ^
#include <vector>, F- x e2 O6 s) K% q
#include <exception>8 Q3 G+ K0 I2 t
#include <functional>! [8 e1 Z d. O! S
# P2 R$ J" a9 P( ~7 v0 K9 Q
: P8 p9 |9 s% W1 J) I: I( Q9 i1 O) H8 D
) T' W8 ]4 N$ R- Htypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
2 y* Y E8 P% _( B0 \typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( w( N( i: }9 j( i0 i2 e: q& ]3 x
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;' c, f# o; ]' Y Q6 B6 w, e
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 e0 t% W' Q) b/ X3 atypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;4 x5 G# v$ Q/ m0 L+ H7 l
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
" a- M0 ]5 |' ^typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' R' a/ t* Y9 D$ r# {: H& X* B
$ ~! D. L' [- l' @* B
! e& y' D3 f- Y7 P. Rtypedef DWORD (WINAPI* TGetBestInterface) (
2 c% m& _% u3 A1 }0 {2 u IPAddr dwDestAddr,
1 J4 A7 C' o3 X' c" z6 a PDWORD pdwBestIfIndex4 \$ M' p# `4 d' G( W# c) h
);+ S5 E0 F! d& n6 w# E+ q6 G
1 P! u6 E$ V# P' I" M3 H# q
) [1 m4 r8 _# Z9 n8 s6 itypedef DWORD (WINAPI* TGetIpAddrTable) (
- k* }# ]) m( }4 {5 U- a0 k PMIB_IPADDRTABLE pIpAddrTable,* c; C; k' M! n4 R
PULONG pdwSize,
: L" Z3 z. A* T% U BOOL bOrder
5 N7 J/ p: D5 [! h+ B);
7 T! j2 `& N% A' @2 Z6 v2 M! c0 H: w" U. J- C
6 h# \; ~# }# ?# Xtypedef DWORD (WINAPI* TGetIfEntry) (
7 B3 Z2 d- F8 k+ T. j2 ]" b PMIB_IFROW pIfRow+ j- i- \& e- U6 t+ k
);
- D5 U+ t! z/ |3 x7 ?6 H" v- [3 U W7 S' D5 L, \
' U, m6 O# {0 z% uCString translateUPnPResult(HRESULT hr);
( q0 A$ z" r# j' W0 V$ K+ D- r) |HRESULT UPnPMessage(HRESULT hr);- |( I' I8 [9 w: H! D- \4 E
6 f# `7 t1 k. I) g1 l' R* t/ J( {
1 q" Z# F/ z& U" ?2 W2 l; _class CUPnPImplWinServ: public CUPnPImpl9 q5 b O* f! }+ ^
{
, J& W% W" S0 X friend class CDeviceFinderCallback;
: m/ `: i5 R" | friend class CServiceCallback;
" E+ p+ _, ?: i( |// Construction
8 j! N, ^& L! v, gpublic:
" l. o9 q$ Q! z6 S$ l virtual ~CUPnPImplWinServ();
6 o* k5 T5 ^8 T. ^* t CUPnPImplWinServ();1 f/ ]+ V) p5 w9 `& C% p1 B
9 b( I, K1 S0 ^% \+ d( C' u- q' }1 O3 I7 O# ]9 }
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# v; d& D2 @6 Y% G M$ j virtual void StopAsyncFind();7 W8 I" Y! b# G0 m
virtual void DeletePorts();
; \' u# k5 ?' @: H& k+ f2 e virtual bool IsReady();9 K" j+ Y) ]) a l
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
( M" R+ j; [; [- a! l: _ ?
* K3 v! x- d5 V2 e0 O$ {3 n# C: g2 r8 n) t9 e
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)4 G" p$ l' p0 N: \8 \& o# @
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
% o7 i3 B0 j$ T; T* Y- r- B; D virtual bool CheckAndRefresh() { return false; };
1 z7 J( w* z$ V% H/ N1 K1 J% C/ G3 B
, c4 }% o6 O8 h- S5 }! G$ D, w3 K4 f+ ?- x4 c9 J
protected:
; q( e4 s; E1 g0 R7 L- T void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);9 H$ W7 W% E$ u/ d3 j" p
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
, b, h2 C; K" B. M void RemoveDevice(CComBSTR bsUDN);& O1 l w' C" M. N# K; [' {
bool OnSearchComplete();" W" s2 V8 j; U* N3 i" H
void Init();& B+ R- n8 Q- S: \3 M5 [6 ^/ H
4 z. ?9 w, X3 i( W5 J0 ~5 j% }" u! c, u3 @$ B; p; }$ Y8 _# j
inline bool IsAsyncFindRunning() r0 |+ Z6 j h7 K( \9 D2 ]8 i
{
3 g/ h# g, i5 b+ X6 A if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )$ z# \" @- y, _2 M
{5 }( M% M, D5 [$ [# j& T8 O+ O
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
$ c0 f R( `) W( r$ _5 G m_bAsyncFindRunning = false;/ |, |2 D/ D( [% d
}' x* m* j+ g8 `) `! b) Z
MSG msg;' b+ A3 i0 k) {4 J/ L) M4 E
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ): y e( V+ G( y
{
& Y5 t4 L" S: `6 A7 T$ W p TranslateMessage( &msg );
7 s: m( h: d( w0 L7 q+ y! F! h2 Q DispatchMessage( &msg );
/ N; d, @" _7 b5 p }6 P! d8 O5 U$ p' |7 v5 m4 f7 h& I
return m_bAsyncFindRunning;
2 t+ _0 a0 R9 P/ y* D! N7 z }
6 ^+ Q" e, F, R& M4 Z
' T+ w- L, X/ q3 |; `9 X; f4 m& f# e0 N1 a+ q+ C* `% L
TRISTATE m_bUPnPDeviceConnected;
$ ]9 P2 U" `- v' j& q. G6 Z3 }$ \
/ ~" S+ e) l- _+ E) u// Implementation' h) k% ~1 g) }) F/ o6 b( \
// API functions6 x$ X+ ^+ j2 g( g9 c8 R. I5 A; F
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);- J) x3 [ c. r5 g
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);1 t' ^# W2 {+ }8 k
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 r; w" c, \0 C# g) I) t3 q
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
- n- F9 d; s/ c! l% } BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
8 z: M/ c/ ~- _( L' ?( r, } BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
9 P) D* i+ G" n' q7 o9 T& s, S2 R9 M' N9 U( d8 B5 n! N } C
2 F" t$ }5 z2 s7 M" o2 N+ j8 }8 j TGetBestInterface m_pfGetBestInterface;
5 j( b# z- w' m. j' _ TGetIpAddrTable m_pfGetIpAddrTable;2 \: W2 c! D7 X7 V! I. e
TGetIfEntry m_pfGetIfEntry;
v0 m& m; k1 v# ^% G& ?4 k% B2 v: A* \0 Z$ L4 ?- H
3 A( y. A Z4 w static FinderPointer CreateFinderInstance();' W) v% Z/ H' t6 y8 f* V: h; e: l* @
struct FindDevice : std::unary_function< DevicePointer, bool >. |5 H: {! L$ Z! }/ H
{6 k. }. y- n2 \) i6 k# M9 A
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
, M: E; Z% Z) K0 X" V4 h8 O# N result_type operator()(argument_type device) const1 S, H# X4 m) i8 {8 @
{
$ @; V7 w) p* u6 V# ~. a5 Z CComBSTR deviceName;; Q* T) L# n) |) |8 b
HRESULT hr = device->get_UniqueDeviceName( &deviceName );0 S" P2 K9 ?2 [; Z' E1 }
' |/ r* {1 L5 s$ P6 h( o) Q, J2 W3 O8 e) _2 C: T k9 x- X( l1 V
if ( FAILED( hr ) )
5 G* W. @& a/ f9 Y# ` return UPnPMessage( hr ), false;% B Q) V6 L& u3 c- `
7 ]6 J6 s1 w) B9 f8 U8 U, h1 L, f3 f
return wcscmp( deviceName.m_str, m_udn ) == 0;- S) z5 J" L" r8 `$ q6 A% ~
}+ e* c$ N7 E1 {
CComBSTR m_udn;
; S! C# x1 [* [ };
# l7 U5 l$ E {& D 9 s- B& K) N! e' J% u
void ProcessAsyncFind(CComBSTR bsSearchType);$ M: _; |' P7 U7 |0 m
HRESULT GetDeviceServices(DevicePointer pDevice);+ G3 V- Y- V' p$ j) Q \
void StartPortMapping();: l. b: g7 e b# s! Y
HRESULT MapPort(const ServicePointer& service);
) ]* g( X L) P2 I$ D, q void DeleteExistingPortMappings(ServicePointer pService);9 C) I" g5 v8 B
void CreatePortMappings(ServicePointer pService);/ e! M9 b* y' o& U: l
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
[" A$ {/ J8 H0 |3 Y( x; S HRESULT InvokeAction(ServicePointer pService, CComBSTR action, % |% C9 ^" V5 O3 n& x
LPCTSTR pszInArgString, CString& strResult);
! @* ~' n4 I$ X8 [4 r void StopUPnPService();
$ c& i% b6 U( ]: k
: L4 I& a5 g$ b- j Y- s; n: p3 H% H0 a Y( r2 a2 u4 k+ e
// Utility functions
( [( m1 {4 z$ Y% w3 H( m3 a HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);7 _ W+ t: X& {1 N0 D8 C
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
; E* H, u6 ~& n8 L9 s( \6 M INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, X+ q. ^9 ^) x% r
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
! O \( Z$ V, H HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);3 ~" i5 }9 t9 I' X/ m
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);0 w5 P' |1 j" f$ Z* W+ f3 |
CString GetLocalRoutableIP(ServicePointer pService);
k# X. W4 p& Y8 X+ o# e9 F" v8 `) K! d- q" N# {( A
, O V2 L) n% O0 j. ?6 Z8 T- H// Private members
$ A0 i+ H% d( _/ z, Q! Z6 V" K% `private:5 Q7 Z0 L: }5 t3 i0 {9 s3 J
DWORD m_tLastEvent; // When the last event was received?
* u. n9 B" B& r: L4 r/ ?" w2 } std::vector< DevicePointer > m_pDevices;6 H! c' D6 q H
std::vector< ServicePointer > m_pServices;
2 u' \5 e7 ^, T) L1 w% ~ FinderPointer m_pDeviceFinder;& \9 s+ z8 [0 o8 ^- \
DeviceFinderCallback m_pDeviceFinderCallback;% I) R! ]) c1 K: V0 V
ServiceCallback m_pServiceCallback;5 m5 D# W( H! ~, J- G
" g) ?& p3 T4 z, l5 e: }
5 V& { I* p" A7 g+ C* \ LONG m_nAsyncFindHandle;# v& o5 C6 f3 }: W: k# E6 e5 E+ V
bool m_bCOM;
9 U5 L# w5 C4 }7 } bool m_bPortIsFree;
, w8 B- c4 g# x$ H CString m_sLocalIP;
: F0 W5 W: v" l5 ]9 c! c/ j CString m_sExternalIP;
! h; J* a, k% k0 ^; L bool m_bADSL; // Is the device ADSL?
- d+ a" T9 m+ d$ p( u& B bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
5 v9 q( R8 M5 `: ^3 m bool m_bInited;
: V" b) F. s; `2 b) Q( V1 u4 q2 ` bool m_bAsyncFindRunning;
. {* b. W1 k: ` HMODULE m_hADVAPI32_DLL;
5 K& p* X, @2 e0 D1 B7 Z# M HMODULE m_hIPHLPAPI_DLL;
2 c( g! A. V* q9 }( p' P# r ~. p' a bool m_bSecondTry;
9 H, V' j! ?4 D7 Z6 J! O4 |: q bool m_bServiceStartedByEmule;
( z) b9 U2 m6 i) ]& e3 ] bool m_bDisableWANIPSetup;
1 C. D5 o+ {2 G7 n( C2 x bool m_bDisableWANPPPSetup;* G! P: M9 F: e3 B f% k5 z7 D
- B% P! x% R2 A7 a- ~( t5 _; u2 |, K( y0 y' D( v/ b+ V6 R
};. Y0 _3 `. x8 K" |
8 t/ X% N9 h @! e, D- a3 U
9 Z" y/ U; @9 z: k$ u// DeviceFinder Callback
6 S E# V% h) [0 v+ Gclass CDeviceFinderCallback
6 B, H' _! q: V6 E7 { : public IUPnPDeviceFinderCallback7 T& I7 r2 `% s: A
{, N0 L! Q8 z2 f' _
public:
' A/ _! s$ d) k; Z CDeviceFinderCallback(CUPnPImplWinServ& instance)% z$ Q% w+ D0 k" \. p
: m_instance( instance )
$ E4 ^! C) z* J5 I/ K& { { m_lRefCount = 0; }% {+ u. V+ J! F: _
9 O. w7 F4 Z& P
0 e6 \# ~2 ^+ g. t7 ]$ {; @* Z6 h
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ r: L& n; P; Q- M- m* n" X0 n STDMETHODIMP_(ULONG) AddRef();0 O" `# O5 X: y: j/ |! h: X
STDMETHODIMP_(ULONG) Release();2 B4 a: l. c+ v! i o5 _% e$ Z$ L
5 d' v8 ~1 O, U/ f! L' y
* f$ Z, b+ @% x3 C7 F// implementation- P/ V: i) S _- [! a1 k
private:
5 j% M0 Q4 F7 h H5 z" i% ]& } HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);+ L4 N1 J; T' x b1 m$ E& s& e8 I
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);# c( z: M# U( J0 s6 w
HRESULT __stdcall SearchComplete(LONG nFindData);
+ ]3 E/ o8 ]4 Y
% s n1 B }: Q1 M- v. G! a4 n7 T/ x* F* l7 j7 _6 K1 ^6 H2 ?6 V
private:; m) y# P( V+ Q$ R Q, A" Y, N' \
CUPnPImplWinServ& m_instance;
0 E9 R3 N+ T' x, @- k3 i/ z( f( W LONG m_lRefCount;
9 t6 k% \, \2 u! o- H};
' |' E0 t. y {
7 _0 q* E0 a) O! ]" f9 g& H* b; M3 W$ N. o6 ?+ ]" z& H
// Service Callback
/ F& i% E: J9 r) Rclass CServiceCallback
# [! _+ W+ L/ i7 r- P* m( H : public IUPnPServiceCallback. p7 B% |9 g2 q# ~: ^# X/ D
{- ?4 @0 ?9 R6 U. D6 j
public:$ P+ Z$ A6 f. M" ^" x; p- ?9 }
CServiceCallback(CUPnPImplWinServ& instance)" T2 I6 x# }8 H
: m_instance( instance ), q5 G6 d+ s; i- p* s5 P. Z1 X
{ m_lRefCount = 0; }
0 f2 j, {+ k% n; |# s7 j " }; S O9 m O6 V, d' H$ ^* k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" Z* J! ?, O/ e STDMETHODIMP_(ULONG) AddRef();
5 k% X, {/ q0 @$ G9 G! ? STDMETHODIMP_(ULONG) Release();! [4 t1 I2 p. A7 H7 ] _
5 H/ W9 Z( ~& I4 G( I6 n- N* B4 Q& _# X
// implementation3 d9 Z4 }* ]* Z' N* l
private:
0 c/ R8 S6 t5 W# O HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);- ^ w+ R2 S& M2 q( V
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);* ^4 i$ m* S. X d) Q! r" @
) C9 E6 A3 I% @8 Y# ]: c& I
; C" S! c$ J: c: [1 e8 h3 Hprivate:
* j- W5 z4 Q6 i, x5 D2 j- G/ p CUPnPImplWinServ& m_instance; ^, e+ N3 b {2 n2 Q$ H
LONG m_lRefCount;
: _$ p/ e) u% v( V; D};+ `* X B2 l) k
; t6 Y* f$ f" ~! B) c" }" q. L# k" s0 a
/////////////////////////////////////////////////) l& U. ^7 c9 U; {" ~' ]7 t
& w+ P$ [$ ~( F2 b! }* ^
3 z; _2 d. A% i Q+ |+ D
使用时只需要使用抽象类的接口。
) Z( ]( ~) C+ A5 I8 ?; J) BCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: T2 f- T1 O7 ]4 u; V
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 R( n& o/ I0 t/ F1 D8 W
CUPnPImpl::StopAsyncFind停止设备查找.' T8 ^9 J+ N" m
CUPnPImpl::DeletePorts删除端口映射. |
|