|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 L9 @. i* I) [0 f- f3 e
& A: G' [, s0 I! p6 U! L* u+ ~& C5 j# I& B6 a
///////////////////////////////////////////6 @4 p" X* Q7 ~5 B) d& \+ J1 l- {
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
5 [ ]+ L! j0 {7 Z9 r& s: q/ F0 K8 E4 ?) K/ B9 H+ }% Y8 U! p
4 o: U$ u' o5 v2 ?
#pragma once0 x2 W3 a! P" V, f" v
#include <exception>$ H: ^) a8 r' _3 |9 c+ T
8 O0 O# ^/ T+ w- `* H @; O# m5 e' Z
! q% D% `3 _3 M6 }9 e7 e enum TRISTATE{
' l# S+ T& ~# ?: E3 H TRIS_FALSE,7 Y: r# j0 K, |, f
TRIS_UNKNOWN,
; }7 d7 A, i" o* r6 l9 c+ c% u TRIS_TRUE
1 K' u" h5 x, `( C};
/ O2 q4 x" n8 f0 N* y, u
9 {* V: S9 l: M# Y9 [) Z- i* z* P* ~; k8 B, k J; _: `6 n
enum UPNP_IMPLEMENTATION{ m. i* f- l0 v1 U" ^
UPNP_IMPL_WINDOWSERVICE = 0,
$ C; A" C8 D$ ^8 t UPNP_IMPL_MINIUPNPLIB,
9 p7 R: M& O4 N) f UPNP_IMPL_NONE /*last*/
4 d2 ?. f8 }3 j( K};
' n$ X3 L) T3 V6 e
& x( q2 e a0 g! D( C
Q6 C8 b# N5 @: b4 ]+ [4 e& j8 ]
0 Z2 q( x( y7 A4 M' g5 S8 f4 [
+ e8 p. O% U v9 t4 wclass CUPnPImpl" e" F/ }) V0 u; P' s
{+ \, B) p2 ?+ e2 j/ l) w) t7 \
public:! l9 i) B- Y+ h6 B6 V
CUPnPImpl();
3 o4 H% g; C4 F) _ |" N virtual ~CUPnPImpl();- j( H- A6 Y, p6 t y* V: H! [
struct UPnPError : std::exception {};6 K5 H7 G; ^* k7 N" Z5 B
enum {
2 W0 y% ? b1 G; m& ?5 z B: s% | UPNP_OK,
- \5 v( K5 ]& }+ W% |. q UPNP_FAILED,
" k- O3 @' @9 T4 k- { UPNP_TIMEOUT6 z- Z; @7 D2 z; K: m
};
1 g1 k0 D. [ k
; M, K9 K2 X* ~& s/ u V5 U* ~% M8 k. q
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. [4 N$ s j, U- `/ p
virtual bool CheckAndRefresh() = 0;) L- I9 d- e; o% `6 J
virtual void StopAsyncFind() = 0;* ?+ X' D- _9 {0 [( q; r- a
virtual void DeletePorts() = 0;
/ j9 F" m$ ]6 ~; v3 y) t- _+ `6 G virtual bool IsReady() = 0;# @+ X7 Q/ j8 }. x5 B; C
virtual int GetImplementationID() = 0;
{5 K: `9 L7 Z$ U % F& k* y! m' H$ M7 }& s% q+ M! u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping! W$ P% o/ T; r
Y8 U: }: B* H% N t" g0 K9 n
: o9 N' \8 u* `: u void SetMessageOnResult(HWND hWindow, UINT nMessageID);% g" ?# Z3 r) t# V4 j
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }9 o# ^1 _, ^5 A
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- {# U1 B3 q& z* z8 j1 @ uint16 GetUsedUDPPort() { return m_nUDPPort; } $ u2 d7 k2 L! t3 p7 X+ I+ ]1 _
2 Y7 \7 H0 ~6 p6 u! }/ C- ?7 a4 q) d* ?! N1 L5 a6 Q
// Implementation
0 N- }# j# w% j+ }2 Rprotected:
+ o- y0 E, f- | volatile TRISTATE m_bUPnPPortsForwarded;2 A, @% {+ b& j9 z( P
void SendResultMessage();
/ I) u( e; x7 r" k uint16 m_nUDPPort;
' W/ W. I7 \6 S, l2 i uint16 m_nTCPPort; b0 X0 J" r8 G- f) G- s
uint16 m_nTCPWebPort;$ k6 J6 C; a8 \5 q% z! {0 P
bool m_bCheckAndRefresh;" E" ?6 D9 \2 R. C+ N8 J1 k; ~
) f, q3 X5 u+ D" J+ Q2 ]5 [+ S! t- I
$ w& R5 _4 H8 X6 `( L. nprivate:
# p, h! ~+ X0 {; j) P HWND m_hResultMessageWindow;, M# Y, z1 S* X9 z; i( e: l; \- D
UINT m_nResultMessageID;" m2 m$ K8 d! _5 |% K
$ }2 k/ A" Y* p1 H: z9 s- A+ x# w! k( n! ]6 x/ m. s$ O6 E
};" ]% _# v+ b" M; Q. {! j7 |! z
. S/ Y/ y& G0 \$ `/ P/ [ D- P7 A$ v* U2 R0 |- u
// Dummy Implementation to be used when no other implementation is available. T! O7 F" P+ b
class CUPnPImplNone: public CUPnPImpl
9 B/ F1 N4 W2 U+ F{
" `9 q: P5 L$ [" y$ Tpublic:
5 p1 j4 \5 S- _3 |! U; p- v& f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
" X# l. l; ]) J- i6 W* F K h virtual bool CheckAndRefresh() { return false; }
6 H' W/ O4 o% x0 O9 w- [- s* E0 \ virtual void StopAsyncFind() { }
; C6 L2 ?, L9 A5 d: w! j7 P G virtual void DeletePorts() { }, h( K& Z# c8 U6 B7 h: w2 b w6 A, l
virtual bool IsReady() { return false; }
; C8 j# {- b M8 k7 G1 F virtual int GetImplementationID() { return UPNP_IMPL_NONE; }8 y0 g3 ~3 X$ G1 g4 h; N
};+ I$ [% \8 o1 g2 s
$ G! B3 r0 J4 I6 m3 l" \, {" v
9 f7 k2 g% M1 i/////////////////////////////////////& p7 U( k( P6 J# O: H
//下面是使用windows操作系统自带的UPNP功能的子类0 B' A$ F6 q; q. S4 p4 u" H
5 v, h1 n+ L8 ]# H" i
* `( n- ^$ j. a8 J3 a( O; N, T
#pragma once
/ ~0 x+ `% x: M1 h2 s- H+ b* x#pragma warning( disable: 4355 )' G+ Z2 R* g6 L/ k) x! }
3 V! E$ f' o& w0 C
9 B& Q; f5 J! c: F, O
#include "UPnPImpl.h"
( o0 y4 [% J' w# R- t; P$ _. |#include <upnp.h>
) R/ T! _5 A6 [. ^8 C#include <iphlpapi.h>' u. X/ z6 z! \ r& T+ [
#include <comdef.h>( N0 F9 N9 R, C- s
#include <winsvc.h>" S' V! v/ m7 z0 G' Y3 u
* j/ F9 c8 ~& A9 w
+ v& S8 A0 Z3 F#include <vector>
* c5 B2 C( K6 C* W1 t# `& g#include <exception>' c$ T$ G8 v& y" _* z3 P
#include <functional>5 E3 m* o2 I' y6 B7 I
4 O/ A; c" T4 J( [. `7 x( {; w5 z! a- y" \. I p( D% ]9 C# s
& l. |1 x& V3 H/ y# T
6 \& `3 L" G- ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;& B4 y: [5 ]$ b8 D
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 K/ b* d, R' T
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;8 C) i: m& D8 t' N' \ `
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;3 O$ i, X. K ~" G
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
: g: \, R% ` C; p y- f, D9 qtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
; X" N* s8 a2 l3 W9 }typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
1 ^, K2 p( g, v/ D9 h1 ?+ S
% G; u2 } x6 u" N% K. u/ L
3 F1 H0 U" I" r5 i/ Z4 ytypedef DWORD (WINAPI* TGetBestInterface) (# d& A$ `& t% m! L* a
IPAddr dwDestAddr,
; G1 w8 y' r9 H/ K$ w) y$ t PDWORD pdwBestIfIndex, H* a" V" J# l. @3 J8 w
);
- S6 {6 j. Q( }4 r* u: B, J3 O( u' ]$ U
z5 e9 ~2 H5 R- ?5 f9 gtypedef DWORD (WINAPI* TGetIpAddrTable) (' n0 x6 n, g% z: k" v
PMIB_IPADDRTABLE pIpAddrTable,
" h( o: F4 A8 {9 F6 L% O. q, N PULONG pdwSize,
7 U% ~$ z- c/ c$ d& \$ ?' R; h BOOL bOrder
, E$ b O# C G( {);
x" M `; N3 s1 P* O: R% @! J9 t! j5 H, f, W: Y- h
/ X+ K# {2 A' X7 `- { @( atypedef DWORD (WINAPI* TGetIfEntry) (
: S; ^, G- ? w4 s6 o$ d" J' b0 Y8 k PMIB_IFROW pIfRow
9 j6 X: o! ^& q4 J. F);
# @3 f' d! z5 T8 q( T
; @6 j; v; v1 S# _, Z2 U$ x3 f1 y1 F5 o3 T ] c
CString translateUPnPResult(HRESULT hr);2 f/ w, o2 g' m$ c! F
HRESULT UPnPMessage(HRESULT hr);
2 Z1 B: b2 h' N2 \* I1 i7 [2 `
4 Z/ a( V+ h3 |" }7 t" U: s; h- ]$ E6 L" }; J+ e
class CUPnPImplWinServ: public CUPnPImpl
. D9 H1 Q& q' ?{
% ~! B6 F6 F. p. ^' } friend class CDeviceFinderCallback;
' t1 ?; h9 u8 g friend class CServiceCallback;
9 M: Y: [' g: U% C& B" m6 Z0 h// Construction. b) _( F) g4 T9 K
public:8 F6 E2 T7 @; k- O
virtual ~CUPnPImplWinServ();! w1 R5 r, x$ _/ a( E; a& f
CUPnPImplWinServ();, `, m5 g$ Z1 c4 }
( V( j. Y3 f" N% i- L" W7 I
0 z5 a, @) B$ U, e$ X4 u. @ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } _' g1 L Y9 D6 R
virtual void StopAsyncFind();
9 l* u8 i) i G4 c- u5 D virtual void DeletePorts();! n4 ]2 h8 R, K
virtual bool IsReady();
X: E5 O' e( y, G6 n virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
G6 C- [, ? }- T2 Q, I1 D* n2 D+ e( W. l$ k: g3 A
# R1 Y$ o9 ^# y. }8 S
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
# d* ?5 h2 \- \* X- }" N! a2 F8 n // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later& t L! N* Q9 ~( n# Z, b
virtual bool CheckAndRefresh() { return false; };- u8 C3 ^2 ?) y; X7 `
' f; o8 n1 C* N) {. I8 K
I6 \* r. s. y! A, dprotected:. I3 X4 C- f; A( h1 Z
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& w4 Y0 @. U% u' e* } void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);& `3 B; I5 q$ `3 H6 s8 K
void RemoveDevice(CComBSTR bsUDN);
1 T9 y1 g" a+ C' B bool OnSearchComplete();- M* A9 l A6 X8 i2 l( t t3 U
void Init();
6 W: Y, ^' x$ V, s9 \0 ?; g: b( u" C l& R+ S; e, q
3 g" N/ d, a( u$ ~- v7 Q
inline bool IsAsyncFindRunning() y0 o: x+ n& q
{
- V1 Y& P8 b) G2 |' W5 B if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
3 S5 d& f% f0 I9 L x {
' V3 d$ j2 t0 k) v! X& e m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
; z6 N$ s+ K K! m2 Y m_bAsyncFindRunning = false;
4 [ O4 G: c( {+ S9 {9 S. V( Q$ M }: s! t" J3 f5 `' V& W
MSG msg;
# `2 D6 X5 \' W* t- B2 Y while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ C/ I8 j1 q* e' `! R
{
4 `) k" X& t- m8 K7 N$ ? TranslateMessage( &msg );
2 f8 \3 B/ B; x DispatchMessage( &msg );) q+ e6 u5 c$ {. c0 J4 o+ n( c
}2 G9 @; |. _. [0 w. A+ N% c
return m_bAsyncFindRunning;
B9 j" _8 B; E- d3 _# p }
4 T8 u0 C; y, V1 i+ h' D& z1 @' H* n6 ?/ L# g9 \& j7 _/ x
& s8 x4 Z( m! l+ B5 { TRISTATE m_bUPnPDeviceConnected;. x9 d# v# n# i+ Z+ O+ D
5 y5 f' i) J( D1 y
0 Q4 n! E7 {" t- x& D. z
// Implementation
+ [, K3 B4 q* a- O$ |6 p // API functions
4 Q8 J' `) G& l3 J( C SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
, E9 o6 f; ]3 U% ~1 X8 m) S0 a SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);* _3 k4 f6 }, V4 Y! P) B# o! Q
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
( s* r+ ~9 L/ M5 D4 ?$ c* l BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);4 Z( k1 I: g4 K6 [) i
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); W4 l9 Z0 H- T: j- n
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' V% g0 G$ ^) c& U2 o
# q( I9 Q, k8 l; A% [8 K
8 s6 u+ k* C, A8 ^
TGetBestInterface m_pfGetBestInterface;
8 s' a" z" E+ ?, \3 j0 r TGetIpAddrTable m_pfGetIpAddrTable;/ Z2 Q5 {* f& Q2 [
TGetIfEntry m_pfGetIfEntry;
m8 R& v/ B% [( f) Y$ w
, ~* f) q+ v8 Z5 v& k, O7 e0 E% ~) g- B7 J
static FinderPointer CreateFinderInstance();
4 R# [0 J& r9 m; W$ ^( V }# P struct FindDevice : std::unary_function< DevicePointer, bool >( V3 E U. {7 [3 `8 ^
{
5 E- R$ @# q( u! y' e FindDevice(const CComBSTR& udn) : m_udn( udn ) {}5 Z p* k, S( ~
result_type operator()(argument_type device) const
3 Z6 m0 y9 G- r4 ?! J' M {( o# {! q5 r$ n& p$ `
CComBSTR deviceName;4 H) F7 D3 ^" Z v: |2 W0 K
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
2 ?( r$ B) o4 ?$ [6 a0 L; K' J; Q0 G% K2 x g
% J* E1 t8 M) D# b6 E. q" l3 d8 [6 G* g6 d7 c& d5 K0 i% C9 S9 ?; Z
if ( FAILED( hr ) )6 ^- k9 N3 g! C4 P
return UPnPMessage( hr ), false;
}. P- h5 r! S. d& {% y0 x- x- U; @" P, a3 f6 I/ a+ w. c3 g9 e+ i: o5 l
& A* R, Y2 x& o1 K" V
return wcscmp( deviceName.m_str, m_udn ) == 0; y+ i. _7 _& g- Y, g2 W0 {
}6 ?+ \ Z1 B( B+ ~7 q
CComBSTR m_udn;
% ]& X& d# f/ E, @! v };
# F' m9 |! H% x; ` ) o+ ^, u5 [/ x# r) Z, \
void ProcessAsyncFind(CComBSTR bsSearchType);$ E* j( R& n6 E" A: U0 H
HRESULT GetDeviceServices(DevicePointer pDevice);2 {& C% t1 f0 a' t3 {; r6 {
void StartPortMapping();8 W0 R/ I7 @0 h3 d; q9 a1 ^
HRESULT MapPort(const ServicePointer& service);9 N4 S) i% H2 Z }0 _
void DeleteExistingPortMappings(ServicePointer pService);/ p0 F$ `' X4 o0 S2 T2 E
void CreatePortMappings(ServicePointer pService);
. ~0 C5 D: |3 s; }0 {% y HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);% P/ G$ S' b9 y4 S, t# P
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
6 l" V" l; R& U" c! Z LPCTSTR pszInArgString, CString& strResult);% \3 l# F; R) Z. F1 C: v+ {; K
void StopUPnPService();
) H$ g* M6 f2 N, a" r
& k6 p; M5 r, X0 o; N$ E5 }' J
" d3 \. k9 A% Z( G1 z // Utility functions
( N9 _ _7 L& k$ ]$ v' H8 I2 w HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
! S. R- _5 j- C' V8 e$ M INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);6 y# _- z1 A( W% e
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);: ^. R4 {1 h2 \/ e, E6 y) t; B: B
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
6 o W3 b; I0 K% _ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);% \& ^( g, ?9 u: V* B; X+ U
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);' c2 U3 }4 v6 b* ?, }) I
CString GetLocalRoutableIP(ServicePointer pService);4 c; e& ~. }0 A& Y5 X& a
& N9 x9 j: L4 a" t
, b; G4 K& p4 S9 @9 k1 v0 H1 N4 T// Private members
6 z/ {% w$ V% O1 s5 Cprivate:" h4 U W# ?# k
DWORD m_tLastEvent; // When the last event was received?5 }! b. ~" h6 N; _
std::vector< DevicePointer > m_pDevices;$ x; |( {9 k& {( Z
std::vector< ServicePointer > m_pServices;
/ V$ Y! D* h2 w2 _ N. ~4 d FinderPointer m_pDeviceFinder;3 s o/ O% Q% o& E0 q9 W
DeviceFinderCallback m_pDeviceFinderCallback;- B6 Z. o$ {( `# b' Q) y) r
ServiceCallback m_pServiceCallback;
" h* x( k6 \$ E+ ^8 j9 _
" B! \$ V, F* k0 q
: g; j% n. i8 G/ E1 i/ \5 b" ]2 w o LONG m_nAsyncFindHandle;
) d3 y i$ b, ^7 x; T! e bool m_bCOM;
. O7 z; F" b O o% t. f: P6 {- f bool m_bPortIsFree;% @; k# k3 z( {2 I1 u$ C' E& n
CString m_sLocalIP;, u+ u$ @: w% g( a j
CString m_sExternalIP;
& K$ @/ D) X1 F bool m_bADSL; // Is the device ADSL?
/ k5 C, A1 t4 W0 x | bool m_ADSLFailed; // Did port mapping failed for the ADSL device?3 s X: u) ]. `! _) `: q; d' j
bool m_bInited;7 t* F. F6 W' X; S% D# o3 t& }. K) z
bool m_bAsyncFindRunning;
9 F, Y6 U, t# i, Z9 v7 k) m2 O HMODULE m_hADVAPI32_DLL;( G1 ~% k' K+ \$ {% H
HMODULE m_hIPHLPAPI_DLL;
/ r0 U9 X; f$ L3 U9 N2 t( | bool m_bSecondTry;, T0 _& U+ b, f* Q1 K8 K
bool m_bServiceStartedByEmule;" d5 X8 H; A. \/ U% V+ A+ s
bool m_bDisableWANIPSetup;# D# L* s1 X& S: k- B5 s# ^
bool m_bDisableWANPPPSetup;# T/ `# z& Y6 ^6 a, u4 e
, ?: t' c* ^4 M4 s
: Z' j/ ~6 o: l$ P) j$ R
};# y0 V/ F$ X, T4 M6 o
# H. s2 n+ T- ~$ L: x' F) J/ N9 e" z/ i, s- d
// DeviceFinder Callback
. O& B; H. w; P7 ] [/ Hclass CDeviceFinderCallback i9 |. j9 j- N
: public IUPnPDeviceFinderCallback
% W2 a( {5 p) y: ?- w{
5 B' S( l' r+ |/ k) h9 upublic:
. a2 z& L7 C, D2 G CDeviceFinderCallback(CUPnPImplWinServ& instance)
- g/ V0 S3 X2 [0 G" j) E) u : m_instance( instance )
' x2 b1 e( r, x5 K { m_lRefCount = 0; }4 W2 S+ h. d: v, S- ~
7 A% q- d3 I/ F% T9 w
8 r6 Z# y& f5 b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% d; K; x, L5 b+ P/ e8 E
STDMETHODIMP_(ULONG) AddRef(); N! L ]& s# U8 p4 R6 @
STDMETHODIMP_(ULONG) Release();/ n/ c/ `- ~( L( b9 U
% v- K" [: F" U% X
9 }$ S8 R g' n- @1 H# Q// implementation7 N9 R0 y6 P3 F6 B" v
private:+ z- S/ a. ?- g8 y# I
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
! i, G/ P' T4 U: I6 O, O: Q% I7 C HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 @+ W+ ~- c* d% f8 M HRESULT __stdcall SearchComplete(LONG nFindData);
. k" s% x _4 `
+ }; X( W% C" `0 y' e$ o7 x7 d$ I9 Q5 Z2 N' S9 a* \
private:
* P7 l a3 X( r3 c6 k$ W: _( M8 q CUPnPImplWinServ& m_instance;
( |2 o: i/ f# k( H' a" r2 m LONG m_lRefCount;
. ?9 s4 E% K1 n5 x9 D4 t: v};& F5 o& J: a: L: a9 I
* t4 O) f. B4 [& I
8 N/ ]3 Y* o% a! B// Service Callback
9 L) q( Y; u8 C) b+ o: }& S7 \5 bclass CServiceCallback: Q5 ]% ?+ L: G. n$ ~4 `
: public IUPnPServiceCallback
2 a. S4 F; O' c/ p7 z! q{
% g$ x, s) T. Y* r0 t [ Ypublic:( ?9 \" {( ^3 W
CServiceCallback(CUPnPImplWinServ& instance)/ n }9 E. b0 K; e$ q
: m_instance( instance )
8 s+ {$ Z1 \6 |! X { m_lRefCount = 0; }
5 `: B0 b" ^! Z& Q* p# Z 0 y+ r& l, L8 _/ l( j( R+ H1 x$ `
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);) m( e. h& u( ?2 P; o4 h
STDMETHODIMP_(ULONG) AddRef();- H) ?# Q9 t* m0 `/ {
STDMETHODIMP_(ULONG) Release();3 _: Y! s1 y3 N. \6 {
8 r, o! p- `3 U8 j* o2 _4 U5 {/ U, B0 x
// implementation0 \1 I5 T1 h$ ~
private:1 ]4 }# p ^$ M7 o* o
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
" U, o( g! Y6 B, [+ v6 S! M HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
& V8 O* L g7 R5 u* O- X2 [2 \7 k; A7 g5 c9 l$ M( \& b% L
2 S& h9 W% P9 k1 F; ~$ E# S$ nprivate:! n8 @$ G K) U
CUPnPImplWinServ& m_instance;
3 ]# {6 Q) G3 E LONG m_lRefCount;
+ Y+ | V+ g4 b" y6 ^1 s% w5 z% }4 S* q};
9 Q) x4 `) A3 l+ s$ p8 \7 k9 u1 ^% [8 o b' X1 `, N$ A
1 K4 _5 p) ~' O; [3 O
/////////////////////////////////////////////////5 C k1 M, f7 N* L! V8 p
# _- j$ w( u. M. g" c) B
$ s, i; W; y) N2 y: L* y- q/ ^使用时只需要使用抽象类的接口。
0 z S" O& C% m" qCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
0 Z* D7 I! e* R1 C- A5 p% K7 c9 HCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
' e! [6 \! P2 u( \3 wCUPnPImpl::StopAsyncFind停止设备查找.' s5 I7 H# W+ G( k w( n# M
CUPnPImpl::DeletePorts删除端口映射. |
|