|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
5 O: W: a6 @/ ^& d4 a6 k
( S( Q, P! R6 n' M" ?; s
; v2 ]4 T3 d" `, q///////////////////////////////////////////, E7 z8 C& f0 t! B2 I7 X `3 E
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
* H& j3 S! o! a+ \2 m* I; Y0 z- D% o. v: O
, c" U. R# p8 w- _8 z/ A& ^#pragma once
+ _. {% T0 Y& W9 P6 G#include <exception>0 Z( C' G, }+ R) M3 _- N% }
- h7 m- D5 y z3 \9 |" R B( h( V6 Q+ K3 C1 l5 n
enum TRISTATE{
0 `; S6 I# V' \ TRIS_FALSE,
2 C9 o2 G( t$ @ TRIS_UNKNOWN,
# S$ N8 a" K, a1 |: K% Q3 x TRIS_TRUE' _+ P/ e# p/ p$ p2 n* q
};; }, u% X$ Z/ e) h! `, G
T* Q% v& `2 W7 N
! K. _# x/ I V. h& q
enum UPNP_IMPLEMENTATION{
7 S9 C1 P- a0 M& ~5 h- u( m% b5 ] UPNP_IMPL_WINDOWSERVICE = 0,
0 s0 C% Y2 a4 x1 u% G6 _ UPNP_IMPL_MINIUPNPLIB,
n( \& R8 a9 k UPNP_IMPL_NONE /*last*/
7 h- `/ x$ I) k0 Q};( S5 P$ g( h4 y% h* }+ a: c
. ~, [1 a8 H9 \% ?0 [6 d1 ` l' `' B! L. M" g% F
3 ?4 Z$ q1 O1 G7 I3 x( ^+ n
+ [# K& O1 f9 {0 s* y1 x7 Yclass CUPnPImpl0 O8 ~: }# M. h8 O: W
{3 L ~+ t: u: O6 U# O
public:& s! G1 i2 \5 q8 R6 ?
CUPnPImpl();
3 R$ d3 b0 j; w& F3 h virtual ~CUPnPImpl();; B0 C+ [2 e7 i7 E+ D
struct UPnPError : std::exception {};
! Q5 b% e; K& W8 l: s5 p7 M enum {
1 p3 c" ^) r3 w% E7 p UPNP_OK,
8 ~! u7 U9 B: k$ G9 o \4 l$ T UPNP_FAILED,) r4 E' ]1 k5 s, Z
UPNP_TIMEOUT
+ y& x5 A H0 a3 G$ B9 M };
0 t- V, t3 Y% N: B9 |5 f) J" ?5 _) Y- k( u$ V$ N
0 Q$ i. [. ?& n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
_! |) t" A4 t% J! ]+ c0 n, [8 | virtual bool CheckAndRefresh() = 0;& r3 u) M: _: i' j# [; b" a0 d3 X
virtual void StopAsyncFind() = 0;" h8 @! t5 i4 h7 U$ o6 P
virtual void DeletePorts() = 0;
+ C! t: E5 S, g2 i" J virtual bool IsReady() = 0;
6 F, c @+ {( H6 F1 F0 k virtual int GetImplementationID() = 0;. q+ b2 O1 a; z/ o8 ^# V9 n3 z: a
3 z( f1 \& u: l1 C* N( d" ` void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: H. |4 h5 y$ T; d1 H
j& C5 f, ^, N2 v
: F4 ~+ [' G, J, [+ r void SetMessageOnResult(HWND hWindow, UINT nMessageID);
* G# A! f3 a+ G8 D$ H7 C TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }: i) D! {6 y4 ?+ K3 _) \" y% v7 v
uint16 GetUsedTCPPort() { return m_nTCPPort; }: `% }3 ?7 f9 ]) X& V' W; e6 C7 }
uint16 GetUsedUDPPort() { return m_nUDPPort; } 1 [, M+ @% `0 Y0 Q8 J& y
7 S0 P/ T, [. Z: P- d6 P0 {4 k. |% g! W! [$ J6 q
// Implementation+ X# V& r9 C2 [
protected:" b2 H' I/ c; E) S: f! l
volatile TRISTATE m_bUPnPPortsForwarded;: T, J/ _# f* a! {
void SendResultMessage();
" l7 ]. u3 p q! r, } uint16 m_nUDPPort;
1 T4 o7 V( g+ i3 d uint16 m_nTCPPort;2 J& d) r( i/ ]$ F8 p! g
uint16 m_nTCPWebPort;
5 V, X: S8 |7 ~, s- p bool m_bCheckAndRefresh;
) [" G. v+ J: h/ E2 [- @6 Z) H7 z! w B
3 O# s8 A5 p6 _3 c- d
% V" z2 x! h9 E- h9 Qprivate:8 x; _% R1 ]6 \, P" n
HWND m_hResultMessageWindow;$ d' r6 r' |$ E# R# c
UINT m_nResultMessageID;$ d4 [7 y0 B( S
* X& |9 A a/ A' a/ y3 Y X% H3 Y
};/ w# @% K& ?7 p3 N3 X" {
! q+ x% K9 O* S% n( b- M4 e# a4 D
: s* q+ o/ [3 e2 ~
// Dummy Implementation to be used when no other implementation is available
' v" m% o" ?0 D% X1 j2 Vclass CUPnPImplNone: public CUPnPImpl
; ]' d9 E* ?4 l* C# `{
6 e, W* m* n! R( b6 e9 n6 Opublic:
3 g0 x" P! W" M! |( \ _9 d) s virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }: N6 i! L- e2 |
virtual bool CheckAndRefresh() { return false; }8 M5 k. S3 r" x+ p6 p9 b8 `( j6 O7 a
virtual void StopAsyncFind() { }7 t5 T. X, q+ }; s6 [% L
virtual void DeletePorts() { }2 o( `: x) a6 }1 ?. A5 v
virtual bool IsReady() { return false; }
4 f5 t* ]" ?7 r9 x4 o virtual int GetImplementationID() { return UPNP_IMPL_NONE; }$ r$ j. j; R9 D1 o, H9 F5 q
};
) _$ q# w; n: T# @6 d
7 N5 q& [7 J, j8 S7 G$ x( V* T/ _
" r3 U: q; F( n3 Q) U: @: b, N/////////////////////////////////////
b8 C- l4 m% f//下面是使用windows操作系统自带的UPNP功能的子类
' N) M' G- _2 t* c
- k! H8 y: J) s% y, f( K+ K- m, c% B7 O8 ]
#pragma once/ S2 y7 f4 |$ A+ D; A; Q
#pragma warning( disable: 4355 )
& K$ {2 r( A$ d6 g; v6 j3 q
+ a4 G% q, E1 x& ^8 s% S) _, U& {
/ z6 [0 n7 P* r# s#include "UPnPImpl.h"9 M7 y/ F' u( v& b2 W" u
#include <upnp.h>
3 D/ ?% Y% ]0 C) h* \0 t#include <iphlpapi.h>
% N; {9 H, W' _ }#include <comdef.h>
# W. Z# L6 ?3 d6 C8 d- _; D1 d#include <winsvc.h>
. q2 `: s* {9 T. X9 f0 D8 T1 S
$ B5 [6 G3 u1 g3 y( R* X) ?. ?
/ R% }9 D% C) Z#include <vector>
- e2 V2 ?" t& p8 E. s#include <exception>
: i( U4 F$ j# D3 I6 l* \* ~9 Q* d#include <functional>
2 A- w( s( B1 `! X1 P: V; K4 ~
$ ]: a! ?7 D7 s7 V8 H# g2 p
* r! F4 m" I! i& t3 q5 h# q' P: v h8 }' y* N
; h3 [3 [( Q8 ]; ?5 A; j+ R" }typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;3 P. q0 V' J9 {% o
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
1 A7 H4 f6 A; m/ V. L9 }( q) W1 {typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
. R7 C n3 l# C/ | wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
& d9 V5 L( N( E: _! \0 F% Stypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" t* {' D; t- M. \" @typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
7 X, O5 B% [7 _, x* ltypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;2 f# ?- k3 V, b
' C+ q5 u' ]% j& r2 {% m
8 X' A. v' v; \4 k0 t; U9 P- M
typedef DWORD (WINAPI* TGetBestInterface) () D# S: _& W, T& J1 {3 i% n
IPAddr dwDestAddr,5 z2 R0 g% |+ A1 d8 B1 ^8 O0 e8 \
PDWORD pdwBestIfIndex
+ m& d0 m- M$ H L8 B); D+ B* ^( }: |+ k, A( ?2 K. `& |9 `
. b. m9 k+ ~$ Q+ s
7 Z, p$ b p6 D$ g
typedef DWORD (WINAPI* TGetIpAddrTable) (
K6 y* t! x: ?+ j PMIB_IPADDRTABLE pIpAddrTable,
0 a4 Z q, |% S9 J& B! b PULONG pdwSize,
5 L2 T% d* @0 J3 r' f6 H/ s BOOL bOrder8 Z; _: f! u+ N0 c3 E( O( o5 k
);( J- K. f3 s z' J0 B$ Q: p+ R
( P/ K, Y8 r0 K5 y
, S8 t9 K( R3 j
typedef DWORD (WINAPI* TGetIfEntry) (7 E2 e! r! X; `, b
PMIB_IFROW pIfRow( ^5 v$ f; |9 x5 F
);2 n! O/ [" D2 T0 n
) v3 V8 Y* f) E
; B2 m# f7 }+ Q" \0 z2 v" t0 TCString translateUPnPResult(HRESULT hr);
5 {" m3 ` i; p$ x M3 T$ w. G- u& yHRESULT UPnPMessage(HRESULT hr);& n9 E. y0 T8 E' e8 U
5 L1 g+ K0 ^0 z0 y3 O% Q
0 O, n# d! k8 `) i# g" jclass CUPnPImplWinServ: public CUPnPImpl
6 } U5 t! |# ^" H+ G* G. M{
, f- i9 I" o' y0 `3 v5 T( B friend class CDeviceFinderCallback;7 ~9 Y n0 E% j/ Q
friend class CServiceCallback;8 W* _ D" r& H
// Construction
, g8 U3 b+ V8 h& `0 L9 Bpublic:7 M' c) P3 M7 @ m2 t- i
virtual ~CUPnPImplWinServ();8 H, y" i' f9 I4 Z# }' O! y% R
CUPnPImplWinServ();
* s4 V( i% N8 Y/ G) g
( C( `3 i, U. h, E" }9 t" S g4 E. G
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }, I1 {: s/ U# z# C
virtual void StopAsyncFind();/ x, T* l8 g+ C) _4 Q! J
virtual void DeletePorts();3 r7 {2 w/ l$ z, M) }5 D' l, `
virtual bool IsReady();
9 W: G+ W/ C+ y @; T) l virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }$ O3 G- Z5 b# a, n: | I
& _) I4 G9 w0 O( N* P4 s
+ k& ?+ K$ p- v" }6 i3 [8 o6 o: v // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)' c) j( N- @2 G; g+ d4 E9 k
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later1 Z/ k7 `- V7 I$ l' H- }9 @2 d
virtual bool CheckAndRefresh() { return false; };
, O7 K& X, k9 l+ y; Q; b
8 C) ?5 {6 f! z% L0 n* S
3 h& A+ h* t/ f8 K2 m1 Zprotected:
6 P) G$ ?; \. q2 A8 a void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);4 \- A2 V& p7 H
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
M" L; R3 W; I8 v3 ^ void RemoveDevice(CComBSTR bsUDN);
7 O5 [2 J9 l0 B3 b1 ] bool OnSearchComplete(); U' J. S' C9 n( L, A
void Init();
1 f1 I5 }) x% b; z: P7 }( G
2 l+ L ^+ \# w9 a2 ^9 a0 { v8 x$ R% |4 l7 c, {- ~2 a4 P1 c/ a
inline bool IsAsyncFindRunning() ( a0 h* k1 S4 |& P1 I
{. C1 W7 j; g K" g! H
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ): z' F7 W. ] x, N4 w" w
{0 E# g+ L/ K$ p; h' ~ M2 k
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
2 _- m/ ?, J8 V* d m_bAsyncFindRunning = false;* ]9 V9 Z+ Y. [/ k$ x" D
} Q: z* B5 g# j3 I' Y
MSG msg;
, t# c7 B# z& H% D* e while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ). r* k. }" P) g1 V* L/ v J/ U
{0 ^) g7 e5 o! J: E
TranslateMessage( &msg );& z3 m6 {2 _; j
DispatchMessage( &msg );" [5 G& \0 B& w* A e
}5 w" Z$ M, o" W' j0 w) P4 L4 Y
return m_bAsyncFindRunning;
8 p9 `" T' G+ |$ f1 l. }2 L2 a }
/ x u' J- n* r# b2 _, S. `4 N
5 x1 o6 o3 I) t6 n% D9 k/ |* c
' D' n0 z5 S" k( ]1 z0 j TRISTATE m_bUPnPDeviceConnected;: z7 E7 B f; a
, ^# A1 k2 g$ w; J4 }
& ]: J! l, @8 s
// Implementation& G- O: X! O' M& o0 E2 ^
// API functions5 K* J7 n0 U% M* b
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
$ c5 ^3 S* A, X9 ^) U8 g$ O2 w6 G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);; p6 X: B/ y3 Y, W P1 t
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);# o0 @$ P, u+ o8 W# C5 N8 @0 i
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);: a `7 |* T9 I6 ?: W
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* I4 c! H& X/ v5 T
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
& X+ G. Q* n* o% W: _0 [' i; S) w1 e
' G p; v) h9 i
TGetBestInterface m_pfGetBestInterface;& g8 ]+ ^$ r5 i) Q/ w! z+ L
TGetIpAddrTable m_pfGetIpAddrTable;
9 X7 g* w+ d. l5 H! } TGetIfEntry m_pfGetIfEntry;" I2 F' I) |2 s, x) T/ S0 j0 m; Q
6 u H0 I9 w* t: v1 j( N$ {
* I9 X# E5 Y# ?! d- ]4 M: _/ q$ J, m static FinderPointer CreateFinderInstance();, Z1 L: c3 V! @4 f) ?( h
struct FindDevice : std::unary_function< DevicePointer, bool >
, [' R. c" q% J U: o {$ v' O4 G T6 x5 m
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}7 F3 @/ R: b& R$ u
result_type operator()(argument_type device) const
3 f/ f3 @0 i" k8 q7 e- g {7 ]; Q. d+ H3 ~7 h
CComBSTR deviceName;6 J1 E: W8 n! P. x' W5 w7 \
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- R2 X. R7 B- V
, G% W: e3 o. G# @ I& f: q- e$ h6 k V: K: M1 R
if ( FAILED( hr ) )/ t2 B! g8 J6 `: y1 K4 F \6 f
return UPnPMessage( hr ), false;
/ ~% q2 a" `6 x$ H
' @; ]7 g) \. Q2 V5 F7 S5 s- A; P8 b4 |
return wcscmp( deviceName.m_str, m_udn ) == 0;) k) P* Q# C4 Q& p n( }+ p1 y
}
2 V$ b# M+ c5 w CComBSTR m_udn;
& V. }( P" l* p& `3 B* l };
" Q! q5 j+ F; O7 Y2 V) t/ I' y8 g / M; p- Q9 |4 Z$ ?; }+ I- E$ B3 t
void ProcessAsyncFind(CComBSTR bsSearchType);
' z% e* K7 D8 s9 R% }! M5 q4 h1 A HRESULT GetDeviceServices(DevicePointer pDevice);
* _5 O0 U) b2 Q4 A3 n void StartPortMapping();8 ]9 a/ [6 k; o
HRESULT MapPort(const ServicePointer& service);) ]5 u8 N Y* K# |" V" x, ]
void DeleteExistingPortMappings(ServicePointer pService);
: ^6 b5 T1 @! X8 _ void CreatePortMappings(ServicePointer pService);8 z' |) T" M' P- X8 q
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);& i$ N" n8 W( D5 V5 U: R3 Q
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, U5 C1 ]3 X+ R0 F- Y6 a+ }6 k LPCTSTR pszInArgString, CString& strResult);
$ _1 e9 P. w* j2 k) A void StopUPnPService();& Z' S' c& z1 v# F
, s; [: W2 Q- c* x- E9 C" P$ D
0 Q" A' w k4 [; V! R3 t- J
// Utility functions
6 y! b7 Q/ ~6 P* h$ @( }# a HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
- D3 ~8 k9 V. |1 t" H1 b8 [ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
/ f5 c2 o0 Z/ ]- s9 P, p INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);. @+ w& k0 [: D6 J' P; f( |
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);, N( o; h ~, [& ^6 d) V
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);! J+ F- f* ]( t! a
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);& Q( [0 O$ e: z, W+ y% U
CString GetLocalRoutableIP(ServicePointer pService);
+ a; ^$ ]/ t0 j9 [( q( O, ^5 d: q' e/ V% \ {! Q7 |
8 M4 C& _: E2 v. ~) |9 v// Private members
) o" P7 R6 M" Nprivate:" r6 m: r* b6 h9 m/ q
DWORD m_tLastEvent; // When the last event was received?0 b' E0 S9 U3 C
std::vector< DevicePointer > m_pDevices;
6 B# k6 d4 \/ Q9 t! [ std::vector< ServicePointer > m_pServices;) i. |5 R$ x7 Q
FinderPointer m_pDeviceFinder;( w- Q. q; V9 b" y/ ^
DeviceFinderCallback m_pDeviceFinderCallback;
, Y Q; M' s! ] } ServiceCallback m_pServiceCallback;
% C1 s% W- r* r/ y% N$ O4 M
; a0 w8 q% M8 G5 U4 ]5 p# q( t: W* S
LONG m_nAsyncFindHandle;. g5 U) ^: K( T3 C$ U* j+ j8 }5 i) ^
bool m_bCOM;- V& [3 `; n* }9 u1 U1 P3 C, Y
bool m_bPortIsFree;
0 l7 _- R! q. }+ K* n B% e CString m_sLocalIP;2 d# C/ W) s) F7 E# ^
CString m_sExternalIP;1 b# J- N8 _ {* \1 @3 G" f$ ?
bool m_bADSL; // Is the device ADSL?
: g2 t1 Y7 |/ \. } t bool m_ADSLFailed; // Did port mapping failed for the ADSL device?2 l: ?5 c+ w2 L; w! ?
bool m_bInited;3 b. x1 L2 X& P/ A+ N/ P9 ?0 Q
bool m_bAsyncFindRunning;
) H' L1 |- @% C( P3 I HMODULE m_hADVAPI32_DLL;# Y/ C6 v m* j! h4 \3 @
HMODULE m_hIPHLPAPI_DLL;
3 s$ r2 C" ~) G6 \$ s+ I$ z3 {* C! C bool m_bSecondTry;
; ^2 N- X: s( ? bool m_bServiceStartedByEmule;
9 P& f& ^- C+ V/ Q5 ^ bool m_bDisableWANIPSetup;
( y/ f0 U! L% Y bool m_bDisableWANPPPSetup;* Z3 g9 O- a, T" k1 B: ?5 k8 E
; {- ~! T" J3 D* t' e
2 p8 j+ l( S8 J5 V+ ?$ d! g};
( K( \5 U/ f. T; P6 h9 ^" Q! N, M3 A2 [( F% S7 X
& p! U3 @; k5 B// DeviceFinder Callback
7 ?# N+ \3 T# U+ l, [class CDeviceFinderCallback
$ H# G9 j) k8 A" |0 v : public IUPnPDeviceFinderCallback
3 ]( a! ?) K7 ]4 w6 i* [{5 o7 V1 K1 h5 {% ~9 V V
public:( Q* b5 x" n, x. |* u) F, X
CDeviceFinderCallback(CUPnPImplWinServ& instance)
6 D; m8 J. t$ H- d : m_instance( instance )( I# [3 \% E+ \6 z
{ m_lRefCount = 0; }
# ]( {7 j2 ~9 Z5 l$ u3 f. k+ N$ i1 o/ b8 R
; }" N, s6 P" B/ \ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; i- K; e( X) R, A6 O STDMETHODIMP_(ULONG) AddRef();
- g, R' P$ E+ s3 |7 } STDMETHODIMP_(ULONG) Release();) u/ `8 |8 g1 \2 S: c' U" B5 `, f& y
0 y3 k( T1 g* C9 O9 P7 C2 m2 j! l% e% C. C& S
// implementation
Z9 v( s! p6 G* z; Y" W0 p, Gprivate:
& r# ]9 d8 B, r6 h! N% y9 a" ~3 I HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( D7 m$ {7 X$ [' X4 i4 v
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
$ Q8 v& \2 q2 ]' E% M" u2 Z HRESULT __stdcall SearchComplete(LONG nFindData);
/ F7 Z' t, k7 K) `# }7 r( Y4 l" e5 Y
$ B# F3 d3 E/ i7 A
private:' C* u: w5 l3 T" U' K. e
CUPnPImplWinServ& m_instance;
* W1 \8 d/ }$ S, ` LONG m_lRefCount;
9 x8 ~# Q( b& H};
3 `* t- W) b: Y
- b, R+ s, H( @1 u
4 y$ | x% B+ ^& O// Service Callback
! X* R$ w4 L2 v% jclass CServiceCallback$ ^% }$ K' p7 B( y
: public IUPnPServiceCallback6 b: @( w5 ]# P1 C4 G0 e4 q: W
{
- x }' A& l6 K K: apublic:
$ R' Y, I9 N, d, F# g( Z3 [ CServiceCallback(CUPnPImplWinServ& instance)
. H$ D- H, t1 j: F2 h: H : m_instance( instance )3 d# ]& {$ m: C& J8 n0 p1 R
{ m_lRefCount = 0; }5 ^% @+ Q, i+ `
9 E) C' A1 K* h* a. U
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 [+ n* @+ A) R J$ q; C STDMETHODIMP_(ULONG) AddRef();7 E- L p3 l2 P. g
STDMETHODIMP_(ULONG) Release();
9 S) n/ |% [% O( _/ }4 s! d% j N* R/ _
& \9 l& ?) z0 y0 I// implementation: a1 Y z" i/ |
private:" @! R& p% M3 t0 D+ F
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
. u! ] ?! p* l8 s+ N& P6 P HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
# y& v! b" a+ [8 c7 f0 w
' ]: o4 K7 J4 e7 |
7 t9 G$ D; {) oprivate:
+ D7 S8 a- P s2 \% N+ m0 B$ X CUPnPImplWinServ& m_instance;( U7 g+ O5 {0 X$ U; D
LONG m_lRefCount;) P+ K, e$ S+ F, i
};; {7 G. Y/ j) k. ^
, ?! r q# v& b- v
* X" \. I6 |( T( ]0 P% \
/////////////////////////////////////////////////
& z# N, k% E2 F% n
( I2 s5 A3 o+ F1 |- n. t" [, n) A0 o; }7 W4 M0 L" C
使用时只需要使用抽象类的接口。
5 t4 q' Y, v( Q; p; @& M2 M$ wCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID., g& ^, o& M4 `# g
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 k/ E: i1 c4 ~4 F6 i2 N2 N: L
CUPnPImpl::StopAsyncFind停止设备查找.
: m7 z5 h4 f& Y" k YCUPnPImpl::DeletePorts删除端口映射. |
|