|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
7 n1 U& _8 `0 e ^- [( M! X& V$ a( R# j# ?
* |3 l9 c+ R" G///////////////////////////////////////////! ?7 m+ h8 n }& h4 Z' c
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
@4 j1 B5 c4 c- Q5 D- P1 y# N/ X# K
! g" o. ?* b0 D$ N& D$ E& A#pragma once$ A( c) C2 Z2 a1 U6 t. s
#include <exception>* J9 T h; C% W7 Q( v/ r& \. f
0 p) ]6 v* H3 [; o
) R' @0 `! D* E/ v0 w: [ enum TRISTATE{* N; p; W3 ^$ ^. q/ A
TRIS_FALSE,3 C$ p" @; }8 L6 d& J/ [4 C
TRIS_UNKNOWN,
# p5 @0 ~$ S- ~; w. b/ W$ ` TRIS_TRUE* d8 N4 C9 n. [* V7 c3 {5 \
};- o) M7 d6 b+ A( s" X
7 b, }6 R, z6 t" L
% I _; U# Y8 [8 Q3 t& xenum UPNP_IMPLEMENTATION{& H! L2 o/ G5 x$ u
UPNP_IMPL_WINDOWSERVICE = 0,* n6 c% U0 T: ~" \$ z3 t5 j
UPNP_IMPL_MINIUPNPLIB,
/ c; U$ x" e5 q; ^ UPNP_IMPL_NONE /*last*/
0 m) f, [0 ?4 P( ^2 \};& [9 V8 S+ w) e! y
& V3 k$ B- g9 h: F/ D# Y0 a8 P# E5 t9 W2 L0 g6 n( j* M+ ~
7 s* J. f0 m; O! ]9 ?) X
- y N1 b" s# _6 P; M9 k- `
class CUPnPImpl
# u' _. c; K1 n/ \7 _5 f{
4 d. n& m/ O3 I, `4 hpublic:
4 x- V; T2 x+ R7 S CUPnPImpl();2 u0 q# C. P- _; ~# M
virtual ~CUPnPImpl();" U1 Y; j- Y2 i( F3 \. C: B" Y* c3 u& F
struct UPnPError : std::exception {};
. Z7 X0 y+ H A$ G! g$ n enum {
9 {/ l$ e3 L0 w; g9 ]* e/ d9 i, u7 [ UPNP_OK,
. F$ P/ M4 b; b. w0 j6 o2 ? UPNP_FAILED,7 r8 V, |8 ^3 q4 _
UPNP_TIMEOUT
4 v6 d, J. H0 D$ O };8 p- R C Q2 A; S! n6 R/ w2 M
. A7 W; Y C) W& K) F: R" J
! J# \& q; X( Q) W% ` virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;/ M: r$ I& r, `0 |' Y: k7 k
virtual bool CheckAndRefresh() = 0;2 l2 ~- A9 `$ h4 r
virtual void StopAsyncFind() = 0;. x1 }$ s- ?' \1 F/ K+ o
virtual void DeletePorts() = 0;
# g1 _6 q6 q6 h+ {* f" k' e virtual bool IsReady() = 0;; f5 y9 L* Z! L H6 Q) g+ Y
virtual int GetImplementationID() = 0;" J# a/ ~ I; T) M# l
- r( t/ u# l' H9 B- a void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, N* Z9 c8 m/ J4 w! I) D, ~
v7 i# ^. A& I- O5 F7 c" R6 W' R0 R, D- ]+ `6 w6 q4 z
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
) F( Y5 Z a3 X8 \# Y) H TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }4 J. c1 f' a( [* e
uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ d5 m- O( i. P; m$ P8 S9 C uint16 GetUsedUDPPort() { return m_nUDPPort; } * n6 \/ j& v6 {8 b8 _$ X& F, w
! T2 G" F/ P2 ?, g
* V/ m5 \9 D; _) N// Implementation
# E4 b5 ~4 x* e$ w: E: |7 t1 t2 bprotected:
( y$ F" k9 c8 ~, |/ `. ~$ A* e% w4 K6 R volatile TRISTATE m_bUPnPPortsForwarded;7 W3 i6 I5 C. w6 O/ H6 O
void SendResultMessage();
/ A3 |! e+ K& N1 x: m uint16 m_nUDPPort;' p" |; n) N2 m6 D0 k
uint16 m_nTCPPort;2 o' a6 ^$ ?4 D
uint16 m_nTCPWebPort; u5 v7 t L# ?- g
bool m_bCheckAndRefresh;
Z" m4 L3 F; o- c4 V+ c1 y' @- [; `$ B4 h
/ n j$ @2 Z( D, Y$ P; Gprivate:* A4 {. }$ q' T `2 Q) C9 @4 H
HWND m_hResultMessageWindow;
& v+ G7 U2 q8 h, q% z0 n UINT m_nResultMessageID;
+ t2 _$ q( n1 U. R2 Z- t2 K0 D
% T- o, ^( |) x; U* M
, j6 S+ A' t. ]$ B};
8 r" _. n& W+ b) O v- R, s. H o
+ V- _* `& D/ o$ F/ ]
, q# D9 w3 r' K% v2 X3 y( {3 E// Dummy Implementation to be used when no other implementation is available
2 G s; D( r6 o. Nclass CUPnPImplNone: public CUPnPImpl3 H5 M( `8 S R. B
{6 D7 j! n% z3 |7 u1 e6 a. U
public:- V. e; q: o$ d5 w
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 V% B# M% O3 B3 f virtual bool CheckAndRefresh() { return false; }
6 T% s0 G# B& t8 D \ virtual void StopAsyncFind() { }
7 D* T' v% v" K: o& w- o virtual void DeletePorts() { }' o* |1 t H# r1 U
virtual bool IsReady() { return false; } E, X2 O( Q6 y9 o w# A- d
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }( G* J. E; t. b5 I( Y
};. N& ^7 O: c) ?! L4 R$ P r3 [4 |/ J
" O( X1 K! b& v" h4 g X$ B+ R9 N D7 g3 ^/ y# |* l
/////////////////////////////////////
, Z( M' U i+ w* a i0 O+ G6 J: X% t//下面是使用windows操作系统自带的UPNP功能的子类
/ @4 B9 c( }! l) r; T5 Q9 u/ u) h3 K1 e% z1 s- G
: Y) |; w0 o" N7 k4 R$ {! `#pragma once
7 f8 b: h" r( B& m; t/ ]#pragma warning( disable: 4355 )+ Y3 f. Z1 ]* a* D8 s
7 y" d, X9 @4 P* }
& Q- {8 i# |" N% t0 F6 i5 l
#include "UPnPImpl.h"
4 f3 v, i2 U ~2 p1 M6 Y& T#include <upnp.h>
: y% L& h' L7 L' J#include <iphlpapi.h>
% Q0 l2 |3 y4 ]+ \#include <comdef.h>. h% j- l$ s6 `9 Q
#include <winsvc.h>
% e4 ~ F G* N W( F% ]5 O" ~# R" s8 B
$ o2 }7 |+ c% X: {% j, |
#include <vector>
b5 ~7 u+ |6 ~; D' I#include <exception>$ F" j& \. H/ b/ x, }6 h" T
#include <functional>
% N; Y# k$ L" z1 I$ u/ J* Y$ I! i2 g, V! x& ]
: x- V# L2 b- o! q6 s- L6 l4 |* } H
9 }! @* T/ Y: s
$ o- J+ b0 X- w8 Z: R1 qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;- e! v# q# z3 ~; O" U
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;( b& Y( _+ P* f( o5 \- m
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; h9 v& a" I3 H7 G0 g& `, ^
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
; x7 d- z/ z+ _typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
0 e2 B$ _0 Q% Mtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;9 z+ G. f5 e% `4 w) N3 R* V4 A! ]
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
2 e% G: ]' [) I) B+ c7 E& u* h E/ ] ]4 f# _) K7 T4 ]
0 L8 N7 X& l ?* [. ?1 Q+ S1 u1 m6 p
typedef DWORD (WINAPI* TGetBestInterface) (! I7 _/ d- }8 x5 s: B
IPAddr dwDestAddr,4 W# Q5 u* j- I( S
PDWORD pdwBestIfIndex
3 Y, s% D/ ]7 b, G: r$ W);5 r" ~9 O. s, C' B$ p! h+ k' l
5 X8 J0 e9 u, w, b
6 n1 m% X6 _' d* n
typedef DWORD (WINAPI* TGetIpAddrTable) (9 A3 \% R% u" T) M
PMIB_IPADDRTABLE pIpAddrTable,/ L" w& T' N6 L- }. p& s/ ]" B. G
PULONG pdwSize,( \( A& k" c' p/ }4 l# q
BOOL bOrder# D2 v3 ?( W1 M$ v! b& r
);+ F$ |$ @& r- [
1 |5 k1 q+ d, S9 }% t6 V" w8 x6 D- y/ \9 W7 d% |1 s G
typedef DWORD (WINAPI* TGetIfEntry) (8 {9 C( m2 E4 @2 b# C. D: y' X
PMIB_IFROW pIfRow: L, f4 F6 E/ W) d/ d
);7 J' f+ M3 `( W7 x s8 W8 W% K" U
+ u3 [( [9 F: [8 ]! a; x9 {% |. ~
" b+ f- D1 X# A) b# \5 i
CString translateUPnPResult(HRESULT hr);4 `! p2 ?, e$ Q s2 E# N
HRESULT UPnPMessage(HRESULT hr);% o+ e& u* N; U2 [' T; ^
9 h6 t K$ v( ~9 [8 R. }% c& Y6 |6 D
class CUPnPImplWinServ: public CUPnPImpl4 Y" h) z! v9 c/ Y
{& g; h9 w' ]( G( _8 i3 n" n
friend class CDeviceFinderCallback;" y% |5 F" S- o7 }0 f
friend class CServiceCallback;
9 t0 v' v9 x+ a+ p7 T// Construction
3 O: v3 g! a1 q) B7 Zpublic:: U: m! K- q' |: } w7 w
virtual ~CUPnPImplWinServ();
& \" y+ P) O% K8 m+ \3 I9 I* M5 n, k CUPnPImplWinServ();3 d' p" f5 Y/ T# X, i; z: Z* \
$ M) m2 |! o3 |' n% C
, L9 T* {( w: y3 R% R: `
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }) D/ V2 x7 e, s/ g' Q( n6 X! ^7 ]
virtual void StopAsyncFind();% k5 g [+ ` n: r& l# ]8 M7 @9 J/ m2 P
virtual void DeletePorts();' [/ X z" W" [6 h b5 J9 N
virtual bool IsReady();* `+ V |5 W# j# e
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }, z7 X, P9 Y2 J, Q, @- i
, h5 S5 ^; e+ H. j( y( }
" U/ H5 a' y# a! O, o5 X: ?1 t- ]
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- E! G6 r" Y: L3 B# w& Z) T // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later H) N# K- o' h( ^" [
virtual bool CheckAndRefresh() { return false; };
% V5 e! n; W. k0 P
% q* ]$ S1 _, _* l7 {9 Y/ p7 z5 V" ?, _) ?
protected:" b; k6 P3 O% B M
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
5 `5 V8 i$ L1 n8 z! ~ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& \. A l/ X. Y4 d' |- d
void RemoveDevice(CComBSTR bsUDN);
( w, S' @ U6 Z8 [0 M" `4 G( B. d bool OnSearchComplete();: \+ n, i3 b) p' a. r
void Init();- @% b4 H+ v. b& W- O6 A
, w$ w& Y2 o8 e
$ D% D( n" ~5 u# ]* K# `. D; O inline bool IsAsyncFindRunning()
" K' f4 u! J/ {8 g; y3 F {( J8 p2 q; K+ v2 _! H6 ~5 q; U
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
1 A) ]* D" ?+ F3 n {2 z7 a6 l- w$ _7 C/ A8 j9 m+ t
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
: c, y3 G! w U- i. B m_bAsyncFindRunning = false;
1 j+ ~8 Y8 p; N- L5 o" E3 z" V' M& w q }
% r+ H3 a3 n( U. ]- F MSG msg;* Z4 @2 A6 T4 n, K7 v
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
7 g% ]! C# N6 c4 P {
: I7 q" ^6 ^% K4 L1 f TranslateMessage( &msg );
/ K, |2 d' j. d- M# T! r* Y DispatchMessage( &msg );& M0 \: j/ e. _: ^ P& Z6 Q
}
) x) \- k6 M$ Y( t% V0 F9 F# w return m_bAsyncFindRunning;
$ o. A5 }9 z% c3 W7 I, R. S }
; v! f) M& M' {6 i3 w1 ?+ ? w( v, ?
5 L( L. L8 L0 W2 ]9 G. Z
TRISTATE m_bUPnPDeviceConnected;0 w# u3 V5 M% ?* c
0 B+ Z2 x7 r6 ?) M, y* Y
5 ] V, u! ]# j8 U
// Implementation
. d& x! @2 s7 O% i! |, U // API functions
2 K3 U/ }. X, U t8 e- G2 v( E/ y2 P SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);0 x6 A* ]) ~( b1 F6 |
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
& r! `+ w2 c5 Z3 K BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
8 V8 b% h& T. f$ D; b BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
$ w( {2 G/ _" d3 W: _ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
& Y" `" a0 }1 ?! `8 Y! C, z$ K BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
; X( Z" U* A5 c+ M
. ^: o) x- H# x, b$ i/ z3 d; r
4 j2 y. J6 S( A! J TGetBestInterface m_pfGetBestInterface;: Q% R7 ^- s2 R1 e, G, \0 [* x3 `
TGetIpAddrTable m_pfGetIpAddrTable;
6 Q Z4 z1 ~: N4 @8 `) H, e2 U TGetIfEntry m_pfGetIfEntry;
. b) b5 T9 A* f
/ @- N# X0 _% _% m; x, v1 t- Q
; E c0 T% u$ X+ w static FinderPointer CreateFinderInstance();, q! K2 j0 }; H0 S& |+ D4 W. f
struct FindDevice : std::unary_function< DevicePointer, bool >
4 ~! `# N" U- R3 ^; Z$ f {
5 O3 c3 h0 t: T& E FindDevice(const CComBSTR& udn) : m_udn( udn ) {}" z0 N# B& N& M0 g. l
result_type operator()(argument_type device) const
1 y$ V6 ~ |" A- E6 h3 n5 r, d {
) k8 t% j6 B% v$ S. x CComBSTR deviceName;+ C* Y# n& _" B- c- m
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' v" j: S5 r b: n$ P& J
2 x3 I5 e3 V4 d4 C2 ]' @; j2 C- p# `' E
if ( FAILED( hr ) )5 }4 { c% x- ?! v! E
return UPnPMessage( hr ), false;+ k5 i+ [9 x% k, T1 Z' E
, D, U, o5 Q9 q9 r) f
" m: Z, A$ v7 |$ G
return wcscmp( deviceName.m_str, m_udn ) == 0;$ C$ r* L/ J: v! e
}
; |" D; r5 g) L, ]( B CComBSTR m_udn;
0 T' P0 ]+ {. i* b( ] };: W4 r) }( ^" W! _7 P* b, u) T
2 ~ c" A c8 ~2 t( `
void ProcessAsyncFind(CComBSTR bsSearchType);, i. x( u+ k, I8 d A h" y
HRESULT GetDeviceServices(DevicePointer pDevice);$ B+ P9 i' Q) z* \
void StartPortMapping();
3 M4 [2 f" j5 |" ` HRESULT MapPort(const ServicePointer& service);
1 x* S; f! y" o% u/ S void DeleteExistingPortMappings(ServicePointer pService);
+ _/ W2 C/ ^# C3 G. f void CreatePortMappings(ServicePointer pService);
. Y# P# u; t h& x% U" b HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
, C" `0 D" T' e ?' i/ J HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 6 L+ _. D8 O- a5 T: F
LPCTSTR pszInArgString, CString& strResult);
- C" b2 u% |" Z# _ y( B void StopUPnPService();# ?7 x6 B! L) ]+ Z* z# B& ~
# j. C; |8 | v5 q
4 T8 r7 y4 p8 u9 `; v // Utility functions) W: e9 M. y" t4 H, t
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);' @( n& h9 v+ [) y1 k* V: S
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ a `. R* K' o& D s8 Y0 W. x
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, a$ I+ q" D4 N' k9 R8 O& Z
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);" f( s i" [4 Q( N9 O6 p
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);, C( U4 S" {) b0 N Q1 R% T0 w
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ m2 X2 M$ s+ x) a$ J6 l
CString GetLocalRoutableIP(ServicePointer pService);
& ], ^ X8 N$ `' [9 e# g; m& ^: k9 F6 E
0 C$ F) Y: C, W: g/ \! S1 L
// Private members
, `8 X9 u6 W/ i7 ^$ N$ Eprivate:
% d- `+ I" }; A4 e+ f DWORD m_tLastEvent; // When the last event was received?
# M: j: I/ A- ]( A7 `6 S std::vector< DevicePointer > m_pDevices;
3 [( q1 R/ P ^, B std::vector< ServicePointer > m_pServices;. K( W, {+ y M8 N, N
FinderPointer m_pDeviceFinder;8 C9 v( T9 f# L/ l1 h+ B! u
DeviceFinderCallback m_pDeviceFinderCallback;
9 i' h9 m4 T5 q' _( `' m+ Z, y ServiceCallback m_pServiceCallback;
, V! Y9 A r* }9 h% M3 Q, l+ H
5 X! a% T, @3 ?! l, m
# [& m4 A3 L9 G: B& q! f7 F$ O LONG m_nAsyncFindHandle;
7 S* M: L1 A9 [: [: ~! l2 V) d bool m_bCOM;
+ T8 h2 H# I* Z9 H8 N/ X A bool m_bPortIsFree;5 G- g. B" z% l( o2 q! x
CString m_sLocalIP;/ A6 i' t$ F8 e2 f
CString m_sExternalIP;* d" S$ I% X! F5 C4 L' `( _( ?
bool m_bADSL; // Is the device ADSL?
. O/ [- J7 h' I7 p0 O# [; ^ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
' I( k, C0 g" c bool m_bInited;
% B/ S$ O$ T$ `- _ bool m_bAsyncFindRunning;' _* u3 r+ _3 v0 J1 \
HMODULE m_hADVAPI32_DLL;2 U$ G' J" z5 [ W, h3 M% z/ Y8 ^
HMODULE m_hIPHLPAPI_DLL;' W1 }) [$ _6 \* `* u+ U, r
bool m_bSecondTry;
# e, ^5 [8 n k( e bool m_bServiceStartedByEmule;4 H! S4 O( |, p
bool m_bDisableWANIPSetup;
! C' t* E' v) t) w' G: K6 W bool m_bDisableWANPPPSetup;! n/ q* F( @; M* A* ~
: [7 W6 k: a ^' P
( [5 P. v: e* U r5 ]: w
};2 M( h& O% E4 c5 \" \
9 t9 v& S7 D& I
- Q6 Z R4 F) l. L0 {& O& E// DeviceFinder Callback( b5 d" j+ X) a: A: R' N
class CDeviceFinderCallback$ c) P- V' `. ?# u8 n( w$ g
: public IUPnPDeviceFinderCallback1 P( Q: W- W) C; D! k6 c, X! P
{
/ ~8 y7 t; F' @& Tpublic:
8 b0 P+ p; J) F CDeviceFinderCallback(CUPnPImplWinServ& instance)
7 t1 b9 a6 n! v: h4 ~7 _5 u : m_instance( instance )
. }3 W$ W. a4 K% S7 K" s$ B F- Q { m_lRefCount = 0; }
; w- u! |8 @. A6 {- T8 c7 E" p5 a1 q. f& \
3 _7 F' W6 x$ K7 _ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( o7 L/ U; b" r) _) \0 H2 s x
STDMETHODIMP_(ULONG) AddRef();
! T; K+ r. I+ E8 V7 H v F STDMETHODIMP_(ULONG) Release();8 p I" O% m+ I9 p
& H7 m) n7 u a1 `
: {1 I2 X' j! b4 l( V9 S8 ~// implementation( e7 [* I( \/ i( ]% v' u2 a
private:, r! j/ V$ r! X0 m1 k
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 g/ |% g( K# _8 L* `$ E; ^+ ` HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
* C, _. d& O2 v HRESULT __stdcall SearchComplete(LONG nFindData);1 c$ U% J) L* u: ^
* j R/ i% ~ S. u
$ @& k+ A X) V& b; W
private:9 l/ u: @6 [- O, [7 E
CUPnPImplWinServ& m_instance;
& @0 D$ `7 b: x& v- |! D LONG m_lRefCount;# q( ~( [+ Z8 ]8 d: k5 _, z
};
5 T' U8 [3 `9 f
4 Q7 l5 ^* t8 w, o4 o; v' ^
$ p5 _* q$ `6 ?6 D! F0 u- m// Service Callback
7 N- w1 P4 \$ |3 k1 Uclass CServiceCallback
8 q a. k6 S8 u" a; ]2 q : public IUPnPServiceCallback
; m& I. P" U$ e- [2 M. o{- t; Z. x2 |& `# {
public:
3 r: m2 x1 Y4 z. a# D0 L' G/ {$ q& j CServiceCallback(CUPnPImplWinServ& instance)
7 j' N# N! o# N( ^$ x+ \7 E/ t : m_instance( instance )" b1 _1 }* E% k7 I, ?
{ m_lRefCount = 0; }
4 p/ q- T" L6 `" V- W % d( C# R0 C4 ?( U0 b
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);7 d5 ?+ D# T4 ^# w
STDMETHODIMP_(ULONG) AddRef();2 R. v3 ^( S, d, A& L3 q' t% Z
STDMETHODIMP_(ULONG) Release();; n. R5 Q4 `& C2 z. q
+ y1 h3 E$ @% E1 I- Z6 l; ]: [
6 g& A. ?* Y# [% w! J8 c
// implementation6 B; d! R+ q8 w# E2 I
private:
+ X* k! L8 _, \3 U' J HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
, ~- g: D& ?7 p" I* M HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
- S7 V; ^9 Z& w( S, Y
& ]9 L" W) w8 J- ~ W- |/ d* {
4 D( H% L+ Q( @: E/ N1 i0 a8 J- J/ hprivate:
2 C+ g- k$ ]9 r5 ~1 u9 X CUPnPImplWinServ& m_instance;- X1 q' C+ e0 Q- p& t
LONG m_lRefCount;; L" b3 m. X+ o( a6 e
};# D4 }0 [7 G# V: l1 Q- D) w+ F
9 f" Z5 B) n5 L& A$ z, i2 E! t% u& f8 [/ w. V
/////////////////////////////////////////////////9 k0 g! z. w9 Y% y$ {$ M
. @+ k$ I# \; f: W0 `* n8 i6 y8 {
7 Z# H! F6 S) p, t4 z D
使用时只需要使用抽象类的接口。1 B4 x2 }4 r o+ p9 C
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
, I: {9 [; C+ q, x9 a! n% iCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
/ @* i6 I0 [6 ^6 M* ]" a5 uCUPnPImpl::StopAsyncFind停止设备查找.% q) q6 U. f3 y9 B m
CUPnPImpl::DeletePorts删除端口映射. |
|