|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
y/ o) V8 @8 L, q
. Y+ w# f" d$ a6 |, @5 T; W$ E; |6 a0 o9 C8 m% W
///////////////////////////////////////////
% a% |7 y2 N! p2 g* K//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能. ?* N g% u/ y6 G
6 Q d R% A. h5 C+ d2 j, V, F5 Y1 l
0 T @1 Z# {4 x k6 w2 D#pragma once9 a/ R$ u: X4 H3 ?# j% p
#include <exception>, |* N* b. p5 b. K' @
6 u k9 V: r% B; \5 u8 p+ B. t6 d6 U. f' N
enum TRISTATE{
- z4 y; r M2 } b F& @, d1 x TRIS_FALSE,
# L. L- u* K# ^8 x J# }/ } P$ x TRIS_UNKNOWN,0 p9 F3 `: _- I
TRIS_TRUE
( w& c5 T/ p6 v% N7 n9 n) V5 Q" G};. Z5 X6 X6 G# a* c! y' f5 p9 k6 X
! O* J* V; t+ c9 @9 n
: s# y0 D" j/ b* [6 z( `( f. Y
enum UPNP_IMPLEMENTATION{
# v; Z5 V' ~% F: K UPNP_IMPL_WINDOWSERVICE = 0,
* V0 o2 h! z8 r# Z+ p3 ^ UPNP_IMPL_MINIUPNPLIB,9 d t0 Q: z1 y' h: M* B. W
UPNP_IMPL_NONE /*last*/
5 y1 U1 C9 ^3 u) d& {! @};: G, m" k1 g; y" s3 [- ]
5 p d( a% s- _$ F M% D3 g+ ]! |6 {' K7 ^
+ x, J8 _: Y" ^. o( i' j! a; f4 G! Y6 f- ]7 N
class CUPnPImpl2 Y8 t: I& I* [
{! I* w; j" @' M9 K
public:
4 D! e! x6 i+ ]' Z& Y/ j! Q CUPnPImpl();9 J7 S' X0 P1 P
virtual ~CUPnPImpl();
0 k% a: S0 U# V/ Q- j struct UPnPError : std::exception {};1 @ x2 K9 _1 n6 o! i1 p
enum {5 @1 U; O. t) e) a- K
UPNP_OK,
9 [% L9 ~% ^0 t# F* { UPNP_FAILED,8 q4 i- `1 f& U$ L
UPNP_TIMEOUT
! ~! ^. }3 a/ O: k9 j" T };* R3 r4 x; F% f8 @* w
/ l% o1 q0 y5 s. A' U
1 T3 A+ t* K H+ p
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
X" s. K% [6 ~$ V% Z; h virtual bool CheckAndRefresh() = 0;
: A! a9 W& ?0 u# [ virtual void StopAsyncFind() = 0;
, S, V( O5 u+ N4 A virtual void DeletePorts() = 0;( O, ^5 a& r0 p# v, t
virtual bool IsReady() = 0;
9 ]" X" r/ p- U% E+ G/ N1 V virtual int GetImplementationID() = 0;
, ]8 M/ B8 ~0 N: @9 C* M' v 3 @5 b8 a. t! g6 p9 O
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping4 W$ q n; y6 ~
8 ]/ d% Y4 W5 Z3 w1 B) D
. _- R; j; q5 f6 J void SetMessageOnResult(HWND hWindow, UINT nMessageID);
) ?' u% [9 b ~) J( M TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, B; d& I- t" _9 @$ s5 {
uint16 GetUsedTCPPort() { return m_nTCPPort; }
) I* p' v' a( X4 q0 g uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 c+ q1 D# v8 ]( g$ _+ j
7 w( X2 i* q1 D) @0 G8 s) x' @
3 u/ M! L! {0 M! ^* G. B) l// Implementation
+ Y$ I8 c' o/ c: ]protected:* m8 \4 W e# j% ]
volatile TRISTATE m_bUPnPPortsForwarded;
, ~! m" z" \" @4 c. K3 R c void SendResultMessage();
2 Q7 \, O2 ^) u; a uint16 m_nUDPPort;
4 q3 Z! L/ h6 i! O% i# R: ` uint16 m_nTCPPort;$ a6 i3 x. Y( r
uint16 m_nTCPWebPort;
4 ?* A+ ^! O. ~5 o bool m_bCheckAndRefresh;
; A, R& C' U" D0 A; D
4 Y7 S, x( l3 {% \) t4 l. Y2 b- m& F! l9 K1 q: ^
private:
1 Y1 V/ d3 A, S6 @ HWND m_hResultMessageWindow;4 N0 u6 u7 T' R: e% c# W7 Y" p+ C( [
UINT m_nResultMessageID;
% ^. e- \/ A+ r+ J8 k5 j5 Z4 {/ m. o' ]5 d" k
( D! J7 c: E, O9 O8 G# A# |};6 w/ Z# K& |( d" f4 e3 t( z/ n+ L5 n7 H( r
9 W" r0 j7 @" K& b7 r9 f+ @: L( H3 t, I& [$ e" w2 P
// Dummy Implementation to be used when no other implementation is available- N0 [' T' o/ c9 U, y$ ^5 G& I; b
class CUPnPImplNone: public CUPnPImpl) u' _5 X. A6 }0 r& Y4 l j
{+ f6 k& b, @: Y \2 ~% {
public:5 h. Y. a a, `) E, ~2 @
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 l- \' m" T5 [ virtual bool CheckAndRefresh() { return false; }
& T/ V. ^( ~& f4 V' T* ? virtual void StopAsyncFind() { }
& h! R8 n: ?! v virtual void DeletePorts() { }
" K7 t3 d5 ]4 B4 m: F1 A+ q! R# ?' I virtual bool IsReady() { return false; }# g' T- f- d. e; t$ C' a. _: c! P
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
2 ?7 C/ @3 q9 d# |, X};, m' ^; `5 V: D+ P/ Y, h& n: z
6 ]6 w9 U _/ B7 ?( N
& I; l' p5 g" i# t- d8 c- O7 i( H/////////////////////////////////////' v0 }# k3 {8 `$ m4 U; ^6 D3 Z
//下面是使用windows操作系统自带的UPNP功能的子类
& a+ s' Z1 h& I5 [+ Z* V+ J. B0 N+ x$ y& t. m9 d4 G6 d
$ o$ O" n! A b& u0 c* k \/ H5 B
#pragma once& }1 f1 T% Y3 _& N. G# n+ l
#pragma warning( disable: 4355 )
% X/ [1 F. R$ c% Z: o; H! W
9 J2 F1 K+ i. M/ }
0 o' y' w: p" U9 u! b#include "UPnPImpl.h"4 x8 s2 [3 J; V I7 d! f
#include <upnp.h>0 u3 @& h* |# O; W- H
#include <iphlpapi.h>& v. V) l, l4 a2 p8 {
#include <comdef.h>
W0 s u$ t3 M, y#include <winsvc.h>
1 E& s) w9 m( t% U$ |) ]2 ^( \: }. Z5 E5 l- L* h
- X+ b9 N$ h S$ W
#include <vector>
, m4 I1 j8 U5 [/ F1 U. W#include <exception>' B% P5 e! o7 e H
#include <functional># g0 ~' T! Q; D3 s6 J8 m
$ Z2 e( U+ F# J5 |1 X: {0 ?6 @. d# X$ I) R5 \
4 u* p5 M5 P, J) ?6 Q
: b& q2 \) G0 ^8 M }
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
' E3 o& U) g$ D. G4 Wtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
2 f" X# d* M6 o4 Ptypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;+ N7 `8 n' W' }) O6 U$ L7 g. u/ T
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;/ O9 E1 p* f$ _+ z" w
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;% j- b# |: {; T- @: }/ k4 y
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
3 E, `+ X% L/ h$ h8 ?3 u+ d5 N5 f1 |typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;2 r7 h1 B" {9 @2 g5 x0 a/ ?
7 M- l/ z4 X {7 J. D4 u2 J
. W" \, G% D* e& V
typedef DWORD (WINAPI* TGetBestInterface) (
. U% J7 `) H* L. V' p8 I7 j IPAddr dwDestAddr,
" D1 {! V# D, B( ^ PDWORD pdwBestIfIndex
1 }/ {7 N5 L& K! x);8 S, n9 v* h9 ]" Z! Y
, Q+ x+ `& [7 Z& y( [( N9 \; u, P& ~
typedef DWORD (WINAPI* TGetIpAddrTable) (/ s4 ~( m( i0 c7 D
PMIB_IPADDRTABLE pIpAddrTable,
& R0 H, x; @+ U* @. J PULONG pdwSize,
9 \' _4 `1 {8 q2 v9 Z& z BOOL bOrder
* @( S! E% m3 f3 V# f7 D6 B);
: A: m$ w. R1 f1 v; e& f6 `, A+ h: x! V
$ T1 ~6 K( w1 d( E; K8 X
typedef DWORD (WINAPI* TGetIfEntry) (
( J& B h r( j6 H, I PMIB_IFROW pIfRow6 @1 ~" @ r2 m) C! O* B/ E6 U8 M
);. s- I9 T0 B9 w4 j& O( z- Y' @% Z
; U6 L& r' O/ q5 p! U6 k# b' {$ q* f* f, r2 d7 K. `
CString translateUPnPResult(HRESULT hr);
t" j0 l2 ^# L; ~9 ?HRESULT UPnPMessage(HRESULT hr);$ N# A1 D9 g5 O6 n: i1 Z2 C
* W g4 y* E, V' v7 a& R: y0 Y
class CUPnPImplWinServ: public CUPnPImpl
1 m4 @6 a4 B2 T* M0 E. y$ n{. @8 ~( ~4 a. q4 W. i
friend class CDeviceFinderCallback;' \3 N; g7 O& u! m K/ q0 ^5 u* m, r
friend class CServiceCallback;
8 d; L" v3 }, G1 f// Construction- ?, _- x" J! U( A- a* y
public:
+ w1 H8 Q, }8 E1 \. D8 I: U, L virtual ~CUPnPImplWinServ();
* H( w0 }' J* G6 y7 t% Z CUPnPImplWinServ();7 N l% P) y8 O: A
/ k5 L O1 G( R- ]" }& n
, r3 a1 z( o: R i% L" a! a
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }& [% y/ C; W" Z! K/ [' D* v
virtual void StopAsyncFind();
0 G! k' }/ K9 a. } virtual void DeletePorts();$ v; C/ O% y, r0 R- P$ s
virtual bool IsReady();
' ^# g2 t. \- h5 k1 A U virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }4 ]1 h" u% m$ S/ ], J
+ r( C4 r8 C* t5 r. n% j
& m5 A" j0 B5 M+ w) |2 N* F // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
# |" z- ~6 L) ?* v7 L0 s5 P // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later$ a8 w- O8 r7 Y7 v' V: G
virtual bool CheckAndRefresh() { return false; };: d% B2 S, w! `; M5 H4 j9 g
$ G6 s) n) H0 p: U* O. @3 } a. [3 q; D1 h# |; }, |
protected:
9 y9 ?6 L8 R H% Q4 `4 z* ]% k! s( k$ I void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);6 G/ P$ C8 K/ E" y# K1 n
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);- C/ A3 K, L1 F
void RemoveDevice(CComBSTR bsUDN);
4 M+ E( A, _# s bool OnSearchComplete();" U2 E7 |- u8 A
void Init(); Y9 V4 { m1 ?+ |) X: [9 P
6 h% A; n5 X' Z0 c" s+ m" M* @
g9 T: i& j1 |0 ]- e/ E
inline bool IsAsyncFindRunning() & z3 ]5 x2 A6 |- j; i' S* ~
{
9 u0 u% ?7 a' Q8 P if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )9 p9 S g: k# m/ x/ x6 J& d& Z1 O" ~
{
* ]: n% Z6 U* `+ Q0 g. n m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
8 x/ N& X7 ~1 V* d6 x+ k m_bAsyncFindRunning = false;* f/ m' F* ]) i: d6 w
}
) z) _) x3 m( s# ? MSG msg;( ^7 E" P# K& D7 y
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )+ T' E/ |8 {, _3 z2 k$ J- u
{
; a% g$ ~8 y5 E TranslateMessage( &msg );9 C Z1 z' G3 r
DispatchMessage( &msg );6 k5 ]9 ^( m8 M( A0 `2 h& h7 N
}6 Q: j- ^- I9 M& V/ {' G
return m_bAsyncFindRunning;% @ @* M5 n) j! \$ M
} x2 E8 F1 v! Q0 K
" h2 }* x- J' T0 S
( P: x; V( ]) b( @) \- t5 c
TRISTATE m_bUPnPDeviceConnected;8 k6 _, w7 w/ D2 B L
( Z3 z- _. n/ C$ N" {: u a1 d
' y M) M1 q9 z" c! @0 M+ w
// Implementation
$ s9 K, L; p2 A1 e: M3 R // API functions
# y3 h q1 G$ d6 R0 I( l! D- }1 \ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
8 [, M2 v7 M1 b3 O' H9 F SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
* ~, }3 E5 ]6 y0 V4 ^& W BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); [: a4 R8 W! P% `! w
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);1 {5 |/ U+ j; S8 o( u! o
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& z$ H7 y3 T8 D1 k% Y
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! X1 c" K$ K# H8 k: x- D$ j
+ k1 t4 Q6 d6 L# Q
; H2 R: B& M' z) V- q TGetBestInterface m_pfGetBestInterface;" |* k+ ~6 ?* o
TGetIpAddrTable m_pfGetIpAddrTable;3 T& T8 o$ J: {8 ~2 o' v2 Q9 [3 T
TGetIfEntry m_pfGetIfEntry;8 s" O' }3 n8 R% d
' a! S6 G) y. ^! j
) S4 K8 m- j( C; N0 R! _" b static FinderPointer CreateFinderInstance();
3 M. Y/ a2 B# E) e struct FindDevice : std::unary_function< DevicePointer, bool >
/ h, t* B8 t* Q, K" f" }, C {
7 Z: c4 i) C/ S FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
$ k* A+ h9 Z9 @& N% y result_type operator()(argument_type device) const! J. C9 b# L% R7 z c9 ^
{# k% Q; u9 R2 j9 @
CComBSTR deviceName;
* `/ U$ C- L2 Z* W& }& a/ m D HRESULT hr = device->get_UniqueDeviceName( &deviceName );% v2 Z$ k7 L D! Q- b# f: i5 ~
% M! P$ r% _0 w- K; _& a& U
, s& j, a# Y Q9 S if ( FAILED( hr ) )' V. [* o- M, C0 S/ a
return UPnPMessage( hr ), false;
* R/ [$ G7 E r5 y" k$ p! v9 v
/ I, T& Y9 ]& T6 u) W+ x
6 Z6 I ], z) }7 U& l& ?3 J" ]2 X return wcscmp( deviceName.m_str, m_udn ) == 0;6 v: F% g/ Z: M" _1 s: q
}
* L q2 q' M# ]1 g+ W& I. ` CComBSTR m_udn; O) @3 n, D3 J
};
/ Q7 B0 W" F0 P9 P. @7 | & @' ~7 W% j0 x2 R
void ProcessAsyncFind(CComBSTR bsSearchType);+ F1 Q) e" C, i
HRESULT GetDeviceServices(DevicePointer pDevice);
" ~9 z6 c S) e: U! o void StartPortMapping();- j) r9 v0 Y; G8 r& i
HRESULT MapPort(const ServicePointer& service);
! h4 \' a: k( I3 O void DeleteExistingPortMappings(ServicePointer pService);
* i+ \5 o/ ~# i$ t% t# N void CreatePortMappings(ServicePointer pService);1 r9 S. ]. g* ~0 T
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 h1 t! G& n2 h* B HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, b! \) p3 a( J: s( {1 y LPCTSTR pszInArgString, CString& strResult);9 W1 f7 I+ r: F' I
void StopUPnPService();
. ]/ T! X4 { _1 }7 C) z
8 F3 D. F: u3 o( {9 s* C
( A! h' i3 |& {* z2 f( K2 G1 N // Utility functions
$ P3 Q9 T9 e0 I; ~% `% x) w6 T HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
* S; u8 l7 l0 r INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);$ M# R" d% i3 Q# q; R. n
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);3 c6 s$ _( A4 O! y" N
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) a! z0 Q" {5 y: ?, ? HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 @6 _- {, N/ \- l. e1 ]: L. `- i6 q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- j7 k' Y* _& K3 A CString GetLocalRoutableIP(ServicePointer pService);
1 Y$ U$ u p7 _0 R. I2 N. x0 ?
. C9 L% V* i( Q8 H" c) @ v" Q
// Private members
5 k- ?4 t- O y! E# B) X& Iprivate:* Q$ K( B w" g9 A1 I6 w
DWORD m_tLastEvent; // When the last event was received?/ O8 k. l( T* |( i; M
std::vector< DevicePointer > m_pDevices;
* R6 z* |" d. j& s4 T" G+ S std::vector< ServicePointer > m_pServices;
% z! d9 P( @4 z: h/ ? FinderPointer m_pDeviceFinder;
1 u9 p& f6 O6 U DeviceFinderCallback m_pDeviceFinderCallback;
% y4 l Q s' A% b, ]4 r ServiceCallback m_pServiceCallback;
6 a0 [1 M4 F% G* m) V G% m* W6 B4 i4 s6 V2 ~ D2 z
9 L4 n% F" r% c& u$ @ LONG m_nAsyncFindHandle;
' | c. x y1 i bool m_bCOM;
- @/ @( C; c6 O) |2 x bool m_bPortIsFree;
5 @2 V% s8 }2 w! k5 d CString m_sLocalIP;
' `" D& l4 ?( L7 O CString m_sExternalIP;
0 p C" R5 Q$ \5 l6 R# R+ _ bool m_bADSL; // Is the device ADSL?
4 @' B6 ^0 O% Y9 A, G+ S bool m_ADSLFailed; // Did port mapping failed for the ADSL device?$ W+ O N2 e! V$ y4 ]+ p
bool m_bInited;
9 H8 k' O: D# e% P9 j; U bool m_bAsyncFindRunning;1 |9 K3 H9 u6 x1 T
HMODULE m_hADVAPI32_DLL; O& j: T1 {4 V- u- Z3 V
HMODULE m_hIPHLPAPI_DLL;" T% V6 G4 N: K; D' B7 m+ K
bool m_bSecondTry;
- |$ K! H$ q6 O) k; s* t bool m_bServiceStartedByEmule;
& Z; |: f1 \' C' y; {1 U3 @ bool m_bDisableWANIPSetup;" E5 B& W) x/ |! w
bool m_bDisableWANPPPSetup;
- x" n# S: p6 y3 ~# @/ g' H: \! B. r6 C; i/ S4 }
; M b# g1 W+ G1 E1 ]};
+ C7 `; z) q# e
% q0 ^8 q' p0 p# w# \
! A* r E0 E( p2 e// DeviceFinder Callback
: ]6 y0 x O" _% Mclass CDeviceFinderCallback. i% i4 R( {- J) u6 l( w
: public IUPnPDeviceFinderCallback" N1 t G2 [7 C$ U$ Q* t: b% ^
{
7 _+ { h8 x* Q& {public:' f7 p# V( ] b) h& }8 j; b& d
CDeviceFinderCallback(CUPnPImplWinServ& instance)4 |# G4 g7 E) v1 L8 a4 ]
: m_instance( instance )) m- q) U) Q, A- C+ F, S& O0 k
{ m_lRefCount = 0; }
, }+ `8 p" V8 @8 ]2 N9 a* M- A* m& \# h7 I. h3 S& q; ^
* B' f0 N" p% z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" x+ u E+ [( H# B& M
STDMETHODIMP_(ULONG) AddRef();) P6 ?" v0 N$ D
STDMETHODIMP_(ULONG) Release();
3 D* r( M& Z2 C% e& ~" q/ g) {9 g* T5 B
! F6 f7 o3 F8 Y# o
// implementation) q% k& I {3 M0 q0 `
private:
4 F& K; A! r; p. f) t HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);3 Z B5 D! n' A7 \9 k; {9 a
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
- p1 O0 W$ E9 M5 A% k HRESULT __stdcall SearchComplete(LONG nFindData);$ r' o! ? t+ m7 L' F9 k
! `' @* _! E+ t. I' v0 g, Y) X" R6 @( j B
private:
3 }0 n ~3 e- `1 O j4 P CUPnPImplWinServ& m_instance;
0 T/ p2 ~# a+ w, i! I! Q LONG m_lRefCount;
/ O! Y9 n1 d/ a1 d* F+ s1 |};
4 a1 s t# K' X! U6 W7 }) y1 ]2 {7 w |7 X
6 D) \1 |( V8 z5 m! S
// Service Callback ( T4 t: j! }4 l ]
class CServiceCallback2 Y' W' A- P p8 n( k- \
: public IUPnPServiceCallback# y- O0 |( @) N. ^+ u
{
0 [5 g" ]& g" T8 R/ a( I# ipublic:- a e6 I. Q) O# @+ U1 Y
CServiceCallback(CUPnPImplWinServ& instance)4 T1 q c: N- u* b4 J4 F8 Q
: m_instance( instance )
$ i$ h F2 B8 T0 a { m_lRefCount = 0; }
8 j+ [ M) _% @7 u1 g6 Y; } & T n0 q1 X% ?+ y% f
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& ?( B1 O8 ?+ d9 K
STDMETHODIMP_(ULONG) AddRef();
& k5 a$ v! c: p' o) V3 k# E STDMETHODIMP_(ULONG) Release();
! E# Y" k& _8 X$ C% t7 b) J( u3 a% Z' t
- H. w; D4 v) o( T+ ]% s// implementation C. V8 x W7 L' J# S7 D
private:+ \& g9 m \ G& x+ H' Q
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% j5 Q& Y6 l* a( y2 \- |
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
3 }5 l( d6 J$ q& O
9 N1 E7 W9 \0 F4 g( I1 \% ]: x0 W) r$ x/ ~( N* i
private:8 @) [$ s+ r. U' A! U# ^( z" @
CUPnPImplWinServ& m_instance;$ y! n2 |/ g( O$ `
LONG m_lRefCount;% }0 t. i) O7 B) [% Q8 q2 ]
};& I! M, |" ~$ T; g! E! J4 l
4 z5 _* W% I4 V) w0 m7 \- m
0 {: s, v4 k% C/////////////////////////////////////////////////7 \' ]" H* r+ O; ]: H: n
* b* M, R0 C% F& e# z1 |
% o$ T5 L( `: Z5 A
使用时只需要使用抽象类的接口。
; E" z+ z* k6 ~) L7 K1 i0 l0 RCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' c* p' a* _8 c! R* [CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.+ b8 K. C9 W( H' [3 [3 ?/ f
CUPnPImpl::StopAsyncFind停止设备查找.
5 \* k! _8 P0 P z l; y# ?0 ?$ ]. gCUPnPImpl::DeletePorts删除端口映射. |
|