|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
. W( w9 G9 L* \' z2 |
5 N X$ g5 _* |3 R" M! u9 N9 t, G M( V7 |( r' h% [ { n9 |( M- f
///////////////////////////////////////////
: q3 K# T2 ^8 i# m5 }/ M# C//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
7 j2 B$ I' j- [% f/ K) B
# z5 L' r1 V% n/ q% {- |; P, B; F: r3 Q' i% \5 U9 S
#pragma once: d1 b, H* ?$ R. C0 s+ x2 j' H
#include <exception>
7 a2 B: F' O; u# B* Z/ J
* t. @% c# _$ V* i- I" G# D1 q
$ n _5 M" S; E* K! V enum TRISTATE{8 [5 f1 L; g! G8 N8 {+ w1 ?
TRIS_FALSE,+ Q; r9 @" ^- Z
TRIS_UNKNOWN,: Y. [+ {$ p9 c& [6 Q
TRIS_TRUE
! S$ g- w9 [# a1 Q& O};- x' [3 b5 T1 N/ A; b I) f
5 T, o# Q0 { s( C; z
; M+ v4 ]* V, U4 _' P" Ienum UPNP_IMPLEMENTATION{0 k+ |+ a6 m3 x' L
UPNP_IMPL_WINDOWSERVICE = 0,
+ |6 z/ |- H' Y M UPNP_IMPL_MINIUPNPLIB,
$ t! q) R) C" y; b2 ~$ l8 y UPNP_IMPL_NONE /*last*/3 J& E: `" |( a) K% b8 `1 l
};! E/ W! `. p7 `; \ t$ `6 w
9 c6 c! m& y$ p) Y; X
$ w# o1 J9 b k S7 q' t$ Y7 a! g! n7 r7 o
4 L( U1 S% A2 \
class CUPnPImpl
2 n! Z2 }# R' }& f4 L7 [$ ^{0 q0 I, v6 d7 h+ k4 L7 H% k6 C
public:
" E) A' C+ o1 `( w( }* V* a( j7 Y CUPnPImpl();( J. b) l5 V @2 Q2 @
virtual ~CUPnPImpl();- o2 B( q4 E" e
struct UPnPError : std::exception {};
. L/ y' Y" W( X+ `2 k% B enum {
2 } N( K- U( E! d4 O, y UPNP_OK,1 C/ B) L2 p7 t+ ?
UPNP_FAILED,
2 w& P# j/ s) C5 ]4 ] UPNP_TIMEOUT, x) a0 T: K5 `2 h
};
. J: I9 w ? T& ~! H' J% [
7 e% u1 K% R# k9 q' d+ c# A
1 q |/ S; }: e virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;3 z; e% q A0 f
virtual bool CheckAndRefresh() = 0;
8 L/ g. p) M; C4 ?2 l# G7 k2 b virtual void StopAsyncFind() = 0;
5 \: _; D, v+ v, n3 Q9 h0 u virtual void DeletePorts() = 0;, [3 @$ y0 f# [0 C1 j6 A! p x$ n
virtual bool IsReady() = 0;' w! c+ i( I# X6 s2 H0 s1 I7 v- F) g: `
virtual int GetImplementationID() = 0;
8 T1 H" v5 j% Y6 E 8 j, E- v; T G5 e; B" A9 w
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, ]" z' e2 _% o2 p+ b
9 B, ?& P- D/ l2 P2 {' Q# l* O, P: G% p* P. C
void SetMessageOnResult(HWND hWindow, UINT nMessageID);9 l! b* ~7 h- ?! C5 E& E& n5 ~3 E# P
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, S3 [/ t0 j: A
uint16 GetUsedTCPPort() { return m_nTCPPort; }2 X( D3 x& f2 j: ~- k1 v: x
uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 s+ n( j& n N7 `8 l
" [5 M! M; K" ]& m
. Q) Y7 n' D r* `* ?/ @% p// Implementation
6 c3 l6 d3 B0 w3 Q( i) b' Xprotected:
# ]/ T' f" ~) C# F5 [) ^$ S volatile TRISTATE m_bUPnPPortsForwarded;
, H2 N, P2 S# Y3 \ void SendResultMessage();( W% u+ H1 H6 |) q5 C" Z" k
uint16 m_nUDPPort;
" ?6 y1 c8 A4 V6 {& I uint16 m_nTCPPort;! T" N* b1 @7 J! s! b" b+ @
uint16 m_nTCPWebPort;
* U9 m% s% O% z" B bool m_bCheckAndRefresh;4 J& p N5 E/ b* R, y9 Z8 @% S& a
6 S7 a \% m6 d
( F7 l2 {' E% V3 Gprivate:
2 O. e8 O/ R0 \2 A' ~6 U HWND m_hResultMessageWindow;
~6 }$ D4 e+ V" {1 Z3 } UINT m_nResultMessageID;
7 k& S" }+ v2 j. L8 g5 D) Q% E$ c0 s
- v6 r9 ^1 ~" F# F1 z+ q+ ]% M) m* J2 Q x, r; _
};% D# u2 U0 f V7 ^- y& @
3 h* A/ Y* ?# Z# M
$ o: B" |8 p: q* F, E# z( s; }
// Dummy Implementation to be used when no other implementation is available3 S0 F5 S& Z$ P! t& G6 @6 V6 m
class CUPnPImplNone: public CUPnPImpl5 @- [; g$ F j# N3 D( _
{+ z. f |* ~. h# W2 ^" X
public:; u7 Z$ k, n2 A
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
2 @! S+ t' g' n( p* }+ p, f virtual bool CheckAndRefresh() { return false; }
5 W/ u2 f# i$ A+ d virtual void StopAsyncFind() { }$ T7 ^; {0 K5 J9 c p- E% @
virtual void DeletePorts() { }
/ |* `: O0 U7 o2 q* ^ virtual bool IsReady() { return false; }
: F! B3 s/ q; M/ G0 f# B virtual int GetImplementationID() { return UPNP_IMPL_NONE; }0 _% u( a8 Q6 @" d8 d8 r4 F2 e
};' x" n9 ^) g- M( D8 W5 T1 W
2 }5 p. x z/ M |9 [$ q) r Z
+ u4 u; H8 z& W4 ^
/////////////////////////////////////
6 H% s; R5 I( X8 u3 p3 q% J//下面是使用windows操作系统自带的UPNP功能的子类
. y* n, X& a) G+ N* {1 p9 I
1 n8 z+ O1 ?- y- Z, F4 e
+ A+ i! F; U' q% f' V3 ^#pragma once8 }. ]+ a7 k, W9 w3 d* M8 _2 R) ~
#pragma warning( disable: 4355 )2 Y9 h0 s1 w; b
3 j2 F1 S8 M5 T; M9 z. N8 {
, ]( c9 d9 y. P; I1 S# S0 j#include "UPnPImpl.h"
. b; k ^+ H5 A: s( m#include <upnp.h>
7 j8 c* v7 k' k5 R; R2 v#include <iphlpapi.h>. B! t6 j, a1 ?' i- K$ b
#include <comdef.h>% r& G# h( ~9 Y' h9 N& I, T3 b0 v8 u
#include <winsvc.h>
6 T3 ^4 b) `1 ?0 F3 f9 O; R9 U9 H M0 W7 ~ @
- p4 h! v% \# ^: G4 l' R0 D) Z
#include <vector>2 J' V* g+ T" S1 q; r
#include <exception>6 ] ]; ?7 K* U' W
#include <functional>
5 I2 {* z) r% C5 \0 D. Z- @+ K! ?0 w2 y6 P8 _
y- A& B# \8 R- P' T
3 U* j' o, w3 P
" K6 J8 _% G+ s% Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;( _8 R! M( u7 P5 k* ?* _
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;7 M& U6 F. D9 F% h) ]
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;5 C g0 F2 |( b+ Z6 c
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
* S6 M3 G4 q9 q' u+ dtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 w& Z( ~ T8 ?% e6 W
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;# {8 `" W+ Q1 A* A6 T
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
- [' y. `* [ H: N* M: x2 K' E
P. h% Z" p8 ?$ j8 j: D! k: c% A8 B, W7 s$ x" d% K7 b7 d9 \
typedef DWORD (WINAPI* TGetBestInterface) (
$ E# q2 p+ R. S2 s$ g IPAddr dwDestAddr,
- l/ ?# z8 Z! x k6 u. F) Y5 d PDWORD pdwBestIfIndex
6 P2 {: i. A5 Q);- Z) |$ a; M0 q2 d" F
, k5 j7 f; Z$ y$ ]' h; l% d
* b. E% D/ Q5 H: {* X4 C, N) dtypedef DWORD (WINAPI* TGetIpAddrTable) (8 f+ `; O# `. _2 k6 _; y1 D
PMIB_IPADDRTABLE pIpAddrTable,, |) y2 F% O1 K4 L6 H
PULONG pdwSize,& H5 M4 U4 a- [ s
BOOL bOrder# L5 U1 ?! @" _, z) S$ k; w7 }
);# X X5 W' D& p7 q1 |
- ~# [$ z8 N0 g0 p0 t% e
( \( Q; Z+ ^" R$ L0 Q
typedef DWORD (WINAPI* TGetIfEntry) (7 J2 j' \( n5 V
PMIB_IFROW pIfRow
& e$ ?8 W" V) F9 ~3 \);( a4 a. i3 z# y) y8 x' |" N4 }2 K
8 [$ ~) W+ H+ h+ F
6 T" r; v3 ~, J% Y
CString translateUPnPResult(HRESULT hr);+ J# q+ E+ u5 Z+ }3 e6 w2 d0 l
HRESULT UPnPMessage(HRESULT hr);
7 x M2 r+ k8 \/ d; A
/ S4 S- t: x w* L, w+ G; r) Z1 c/ N% P1 k
class CUPnPImplWinServ: public CUPnPImpl& f/ S. Z) {$ ?" h/ g
{6 H0 ~1 l1 R# Q' f* C: R
friend class CDeviceFinderCallback;- h+ B: E' X2 O3 x, j. @* f
friend class CServiceCallback;$ v8 \, A9 z3 l# W2 m( ]- Q, h
// Construction
' M( G7 h# U& Z( E2 R+ wpublic:" e: Z0 l9 q2 U/ G! Q; _5 R0 j
virtual ~CUPnPImplWinServ(); P5 \, k1 H# b e% r5 n
CUPnPImplWinServ();% X) f, M9 J" _9 R# J: M) r# G% D- [
( B3 w/ x% f% D+ Q5 C
4 h/ X9 f3 ?; V! g7 p) U# ~
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }6 `7 E8 C' J1 ~9 Q/ L/ W- e3 a& n) v
virtual void StopAsyncFind();! k+ ~1 b' R% @) m" r
virtual void DeletePorts();6 I N0 c# l% Q
virtual bool IsReady();( c7 v' V }; w
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
" f4 o. N' V; m$ B
7 o. y. D) A& b1 t- Z+ u4 Q4 {0 [3 t3 P; m4 @4 M- I' T: _6 j
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
/ ^! [+ X# E. n) r7 J4 Z // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later! Q7 j' H* u$ p- _& y2 q
virtual bool CheckAndRefresh() { return false; };! E% r0 w: z5 l0 l. S
* \( }1 c9 A1 `4 w1 `, j: d. w+ D6 c3 I
protected:
% r+ O% f$ g; Y$ p* Y4 q void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);; l! r: b% Q+ k
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ P: V* @0 n* y7 s% S& f3 x. S void RemoveDevice(CComBSTR bsUDN);
% |" D4 f2 G- I* A, |$ Q; z, \ bool OnSearchComplete();
# \. W' t7 p" O5 A& M void Init();; n/ o! d9 U5 P( C: q @
" k% k+ K X* }) x" e
6 m+ Q6 N- C2 P inline bool IsAsyncFindRunning()
/ r; [8 ?9 k2 m {, \5 f' m+ n. t- o
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )+ b) C6 A- i! J" P0 E3 u9 w% F
{- U3 z( G s3 {9 J5 f. j% H& t% q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- P4 p# [4 e- }
m_bAsyncFindRunning = false;
) j1 R) T% }) n( y }
$ G( ?, a1 u- X3 F0 g# E MSG msg;
( c% w/ I2 N9 z; ?8 u3 n while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )/ A2 v9 @1 n @4 J0 V3 f6 m
{
" B1 j' j' |7 \) o TranslateMessage( &msg );8 i9 i; E- J; W8 Z% x
DispatchMessage( &msg );( ~& A& U+ C5 E0 C, U6 P) D. n$ i
}& e! j, d7 d8 \0 Y, K
return m_bAsyncFindRunning;
) t l/ U) ~1 @) { }1 W2 `$ _* N1 O
! v- o2 X0 N F& A
7 ~3 }5 \5 R# R) t% Q5 K TRISTATE m_bUPnPDeviceConnected;, g: y; m9 M9 y8 n _
. r- t# B) S3 c" f# z, u
* O) H w# r2 D1 F. r// Implementation" a W" K; ^: Q
// API functions
! T; c8 {/ h! C. r: t SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
8 X# b- M; w6 n: ?) s5 I* ?8 [ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
9 z, |4 K( g0 g BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
% K3 n) b1 L: q BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);+ L8 ]) n2 G% ~8 }
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);% c3 J2 B* d3 O5 K2 S
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ U# }+ a' e& N7 ^, z `9 ~/ K8 [3 |
* q. t) o9 ]3 G: t
TGetBestInterface m_pfGetBestInterface;
e k; b7 i2 A! b1 V: I TGetIpAddrTable m_pfGetIpAddrTable;2 h3 S1 W/ F w# p6 `
TGetIfEntry m_pfGetIfEntry;6 `" }& X+ Q+ t- m2 i
! A' C6 q+ Z+ j( m
- H+ g1 l/ h+ i2 E9 Y' w
static FinderPointer CreateFinderInstance();6 H( K: l+ {! q- P9 ~: \
struct FindDevice : std::unary_function< DevicePointer, bool >
9 K1 ]8 t% U) k {
) x$ _8 U. V9 a$ ?: B FindDevice(const CComBSTR& udn) : m_udn( udn ) {} p5 a# l( r t' W
result_type operator()(argument_type device) const
2 R& Q1 r4 m2 B+ o {
2 m, i3 `8 a2 D( w CComBSTR deviceName;2 ^& `, |) w3 H8 I5 s8 b1 L
HRESULT hr = device->get_UniqueDeviceName( &deviceName );" q1 H' w! ?. V2 G
* j: p0 t2 Y) `- z6 u& i8 s) i ?3 S7 g; W
if ( FAILED( hr ) )
. J1 I8 X. q" |4 | return UPnPMessage( hr ), false;
5 ^. h" y( T9 [2 Q! M' _- H/ ?" t* O) ^" c) X0 I9 k
8 [% A7 [; t" O% {, ~ return wcscmp( deviceName.m_str, m_udn ) == 0;# A4 O3 [& F1 L' M5 R% t
}& X! s% P# G/ \0 n. E, P" W% x0 ]
CComBSTR m_udn;
6 h. R; R0 r/ u9 r1 B0 t! o5 T };! a/ v H' z' U2 g" z6 {$ @
9 `2 U" X8 G. x O v: x+ p' P
void ProcessAsyncFind(CComBSTR bsSearchType);
( u# V3 ]9 b4 i" o$ Z' s) ]# y HRESULT GetDeviceServices(DevicePointer pDevice);4 y' W+ k: K- T) O. u7 M# o/ o
void StartPortMapping();
, t# T5 p$ V i6 P HRESULT MapPort(const ServicePointer& service);
4 z% \ Z; l% h; l2 V- X void DeleteExistingPortMappings(ServicePointer pService);, e6 }. b. k. [$ @
void CreatePortMappings(ServicePointer pService);5 ~! d N& M3 J- E
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
' x! H" m! Q* H. z. f- u+ M HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
! g5 K e' ~5 s* \ LPCTSTR pszInArgString, CString& strResult);
3 |4 ~0 V$ {" z# k8 i6 b. B! J9 C void StopUPnPService();9 o0 ~4 X0 v: O3 o+ p
6 R8 ^# V) n( `
% G# r- }7 q8 L7 B! J6 j // Utility functions
' ^) F6 k) I0 `1 y HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);9 ^- ]! L+ Z! l7 T7 Z' G* Y
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
2 B( _7 ?: Q/ k: L, e INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
+ o7 n/ A$ S) G1 C# U/ A! F void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; K* j& D& u" U1 p! C
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; U. Y/ p+ ^+ s+ }
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
; [; O9 o/ w' ]6 U* Y CString GetLocalRoutableIP(ServicePointer pService);, ]6 V* ~* p- u1 R* c
8 i( `# H- k4 T% V4 u5 \4 X6 `9 u
6 a$ A/ {+ x& x: e3 k2 G- ^" n// Private members
6 h) {: r" e7 m, t+ p1 ?$ xprivate:$ U8 _ L' f& h- G* l
DWORD m_tLastEvent; // When the last event was received?/ S7 u6 j0 E" A& d2 [# s; p/ N
std::vector< DevicePointer > m_pDevices;
9 Z- h5 S8 X& P std::vector< ServicePointer > m_pServices;
$ M% g7 J+ c; H; \ FinderPointer m_pDeviceFinder;2 m5 l1 G8 P! C! z4 [5 c3 Z6 `4 N
DeviceFinderCallback m_pDeviceFinderCallback;
( [0 E" N* a6 N; T6 A ~ k ServiceCallback m_pServiceCallback;! h6 a. ]' p7 I; a2 g
! s7 Z% d: ]) V/ a
% B, T# }) I1 M
LONG m_nAsyncFindHandle;
7 J6 y: L& a: p3 h bool m_bCOM;9 Y i5 @* I% m& ?8 p F/ S; J3 ~
bool m_bPortIsFree;1 F$ p- t8 k$ L
CString m_sLocalIP;
9 j! n9 U7 Y+ G9 i; Y0 d CString m_sExternalIP;7 i) ~1 I- V; x2 e0 l1 S$ s, f
bool m_bADSL; // Is the device ADSL?
V: w9 X" D+ z) N, r3 i bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
L* ~& ^4 U1 w3 @5 ]: C bool m_bInited;" A ^: f8 C5 i4 H0 I
bool m_bAsyncFindRunning;# w7 j8 ^5 t' `6 v; e4 d* H
HMODULE m_hADVAPI32_DLL;
- \0 I. I( G: e HMODULE m_hIPHLPAPI_DLL;* N$ q: s2 P {2 q
bool m_bSecondTry;6 _3 W; }5 H! Q) x& I! s- T3 Y
bool m_bServiceStartedByEmule;' o% g: }- z" S7 e( E+ u z& D: t5 D
bool m_bDisableWANIPSetup;, v% `* Y2 U4 R& o8 ?
bool m_bDisableWANPPPSetup;, k8 B! f0 W+ i0 L) c
( |; w+ l4 a3 d! u% S
3 @: V& ?2 b0 M0 _% l- Y};
# K! T7 ]2 u' s8 B/ b& V1 x5 F! A: q' ]- o
0 M4 b* [% u1 D5 k& p* e; v// DeviceFinder Callback. w) G) F6 M- O* g P. L- C
class CDeviceFinderCallback
5 T! g* Y5 `9 ^ u : public IUPnPDeviceFinderCallback6 `. U" C, B4 J5 p" V
{ i$ ?% M- a6 o1 b) X/ E& s3 I
public:. X+ `+ E2 n; s
CDeviceFinderCallback(CUPnPImplWinServ& instance)
! _: u1 Z& d: K1 u" p : m_instance( instance )7 \/ Q1 J$ K- B$ W3 y
{ m_lRefCount = 0; }8 ~& a! d! d/ O5 n' Y
5 B& h: z7 z; o( f
0 G; m- S! [. E2 p2 O
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" H) F( E9 {6 E- X/ Y
STDMETHODIMP_(ULONG) AddRef();
7 Q0 O, P& a3 S r2 K7 W STDMETHODIMP_(ULONG) Release();
; P, b7 ]5 {% L1 y6 Z0 Y9 w) i% \% ~* O% R
! [$ w0 C+ W+ H' j+ s% P
// implementation
8 w8 Y( ~0 E2 k! r8 J1 X/ N6 V5 b8 T+ eprivate:
& C7 s& J2 y% l4 M8 z9 e HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);2 E' w$ b! w1 u: W0 C+ s$ J
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);/ g% q* x6 A6 E' P: k( i, V; c
HRESULT __stdcall SearchComplete(LONG nFindData);
! ?$ T. [, H" T7 Q: G- ]. W
# `' s$ E; G/ Y# ~/ B/ A- g! c2 O S! u7 {2 G5 t
private:& U' O/ S8 D& J$ N6 v
CUPnPImplWinServ& m_instance;. ^! M8 j- R$ @# s8 ?# }( h2 g# q3 c
LONG m_lRefCount;
$ J( _; E- A& W- n6 \2 `};1 ^7 k0 ~( e2 s/ v* _! f1 j
! n2 S5 B( r+ y* W7 E( M/ D; _
- x' X+ x7 e+ w4 \
// Service Callback
: D) W8 P) M" t. Cclass CServiceCallback
* D: V! S- I4 y) E" R# D, \ }! t" A : public IUPnPServiceCallback. ]- c7 r1 [- \* W
{
4 c: E+ q! `5 Npublic:# h! u$ K! k6 L2 H+ f! K( U
CServiceCallback(CUPnPImplWinServ& instance)9 `; o+ F5 i. k- U
: m_instance( instance )
* p6 x; j4 R. s# ^' ? { m_lRefCount = 0; }
" R3 Q9 p) q. S: S) c6 v
3 Y5 D. c& `3 g& X5 D; W STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 O' @, O" u5 t% p# E D- y8 @* v6 v
STDMETHODIMP_(ULONG) AddRef();$ I; W8 x) {% @( K3 d
STDMETHODIMP_(ULONG) Release();+ Q1 d3 o5 n# F# A' [7 C
8 H1 P' @4 B2 z9 H0 Q* ^0 O3 A0 k
) W- h1 X1 V) [) \6 f
// implementation
: ~! \8 _" [7 I. x2 Gprivate:3 A, f3 ] }' h* t" j
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);+ b. O2 p$ K+ z, g( z
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);0 b" |6 z" F/ C% l! R
6 N1 K \: _' l. O
. m! m1 X9 G/ J# mprivate:
" y9 p( l3 O0 {& W% y9 \ CUPnPImplWinServ& m_instance;- d. O, _& v# G
LONG m_lRefCount;/ Q; s% e; h4 y4 |; D! p) v' ^! S
};' V* |; Y% M6 l% w: `
; N& | R* l; }" F0 E
: c' d3 H V+ Y: Y/ }2 g* Y) k3 T/////////////////////////////////////////////////4 b5 V: q, e$ f8 l5 }. Y
3 ^/ B; U8 x7 [+ h) v& a3 x
7 ~ \- i; X* w" ?4 k
使用时只需要使用抽象类的接口。
% Z, M6 N8 a( x: [' I: DCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ g* v' V& e" }& Q5 _# H/ kCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
1 @- i" [7 B' E& h1 cCUPnPImpl::StopAsyncFind停止设备查找.
6 ~0 a7 B, L! M% c9 Q" b9 H3 XCUPnPImpl::DeletePorts删除端口映射. |
|