|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,% _( a4 x! r3 L$ C
s [5 N# g- k
8 u% c4 ]1 y0 @2 F* G///////////////////////////////////////////
4 R: {; F& d8 m q6 u; J3 R//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.. Q n, X) x" [: D0 ~% w
9 Q. [; j% a0 s( _4 A# I' k0 h
: W8 j6 N# F" B: T#pragma once
6 Y" S6 r4 [% B5 j* b; O- M0 _$ p#include <exception>
4 y* z* |( T) _5 V; l1 }! A. j
# L" |2 S: i: m2 a
+ G6 f+ }- n( O4 o enum TRISTATE{& F9 A/ Z3 b* \& X- f, w
TRIS_FALSE,
/ _7 v3 q2 U" u) E5 v TRIS_UNKNOWN,5 K' S4 ~$ B$ j
TRIS_TRUE- R6 n4 x4 a$ |6 S+ z- o4 R4 b
};
' U1 Z, T0 y! [9 B' P. P) `. ^
- ~, j. w9 ]8 C: Y
: H9 \0 f1 y+ V+ l" A1 Renum UPNP_IMPLEMENTATION{( }) A& M- C- T0 O/ S; K
UPNP_IMPL_WINDOWSERVICE = 0,
+ d! X& Z( P1 a& @) D6 ] UPNP_IMPL_MINIUPNPLIB,& o' b' }% \' Z5 g$ b0 D
UPNP_IMPL_NONE /*last*/( @$ i+ V2 p0 F1 Q
};
+ ?/ w, T0 ^5 p/ L+ n
) T* K4 C" R' j5 e. U' w0 m, q! \* c" \5 l& l5 Q9 D% M1 j. \
5 d2 F( i/ w% k& |9 ?; A) A* j" u1 ?: K% P
class CUPnPImpl' S, f8 v) ?# }9 x! y. K( `
{
. v# s. ]! X+ Epublic:, s! S- G9 @6 ?( y: b; n
CUPnPImpl();$ V2 I8 c) h* _2 L& a! g
virtual ~CUPnPImpl();- _* c. Q7 x6 O6 k
struct UPnPError : std::exception {};8 I9 g# F( D, y1 J" }/ s
enum {
7 d z* j" |4 C/ v; _' l UPNP_OK,
" @5 ?& L8 v# x2 v/ K. g UPNP_FAILED,
r1 p, F |5 T" o$ r6 G: D1 | UPNP_TIMEOUT; G! _8 x1 T! i& m6 W
};. ]' S& B/ @) @( _
& Z# w4 O! c8 a
# L, [0 }* E6 T( u( l/ z, h virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;/ d! E7 S& d" |0 Z, _/ f
virtual bool CheckAndRefresh() = 0;
2 B2 s8 Y; X3 @0 C virtual void StopAsyncFind() = 0;& H: A7 S. ?8 V7 T) Z6 \/ E
virtual void DeletePorts() = 0;
z8 T9 k. T0 k) _, k# k( n7 [: Y virtual bool IsReady() = 0;: p) b8 Z$ ]- E% A- X3 `
virtual int GetImplementationID() = 0;7 O: `# K3 b8 x3 q" `, [4 I
) u( Z# d. {3 T& k" k$ g( S# J2 A" d( }7 o void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping6 K" _$ N5 ^3 k# T4 n
. ` D. E$ Z+ u$ y0 }! {
) ~7 I2 E& K$ @2 m" i/ b3 r
void SetMessageOnResult(HWND hWindow, UINT nMessageID);& q9 ^) A6 D6 _; b( q# j4 ^1 _
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }/ k8 L1 |) A$ |" _. }1 j
uint16 GetUsedTCPPort() { return m_nTCPPort; }
$ A5 b2 k) y, q x# j* a' O uint16 GetUsedUDPPort() { return m_nUDPPort; }
6 y: b; N5 y `1 L- ]2 h9 C1 a! h$ D- P! |) G
5 h5 H1 \2 p) {& e [& B" r
// Implementation
: k% [9 P* K3 ]" |5 b3 s1 ?9 hprotected:" R* ^$ B9 l2 n' ]9 l
volatile TRISTATE m_bUPnPPortsForwarded;& c3 z7 m( J7 a0 w5 H
void SendResultMessage();
- V3 H6 _4 r6 s& U. X$ L uint16 m_nUDPPort;
3 Q! v/ p' p3 U) C/ ^" g+ w, G uint16 m_nTCPPort;: D9 |" S H5 w6 V- w$ t$ g! r
uint16 m_nTCPWebPort;
7 G! ]6 J- a1 ]$ d: f5 e" Z bool m_bCheckAndRefresh;( X1 C& ^& ]5 [9 N
6 N2 I" A- U3 d; Q( q! `& X; ?) W
/ ~5 \# ^% ?& G/ q. t' Mprivate:9 h4 F% z3 o8 V5 ^! F
HWND m_hResultMessageWindow;. {7 f& g( N& g% W
UINT m_nResultMessageID;$ p3 k! x5 i4 y! A+ P" ^9 O
5 I% C8 ?5 C2 h% k& r) [9 e+ F- M1 p
* G$ ]. }& Z$ ?: L/ ^" A9 z! r};" t% u2 A' x, u7 O
; R$ n$ g# {) X ~( J* ?- n
' ^7 d( ~+ ]' W) u
// Dummy Implementation to be used when no other implementation is available8 Z; ~, {( A) Y2 T! z1 j0 \3 U0 Y
class CUPnPImplNone: public CUPnPImpl$ ^$ W1 z& d5 S
{" H2 A( A' g& P: T2 e
public:# t2 W2 P+ I9 P, o' H; \
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
6 w5 E6 M D/ C/ `; X5 f% R+ w virtual bool CheckAndRefresh() { return false; }
) B( e$ W' j6 W4 s+ N3 z0 R b virtual void StopAsyncFind() { }- W$ `" M6 G0 m' X8 j/ k
virtual void DeletePorts() { }
9 d: q, S* d5 q5 m0 k virtual bool IsReady() { return false; }& {5 q' T9 X( K c: ^0 R$ w7 J
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
. b* w3 U) Y: t; z( [" A( z};; [$ v0 K. K3 N& l$ ?) I& Z
2 q7 z9 L8 _1 A& Y7 r) \+ o
, @& v1 |/ t8 q* d6 T, b/////////////////////////////////////
. _, ?; i I; W" G7 o; g& L; s3 N//下面是使用windows操作系统自带的UPNP功能的子类/ Q6 J8 D( Y3 p& `
/ @% N/ ~3 i2 M
4 H- ^1 V4 t5 t4 y! _#pragma once
) f! h+ m) N$ b& I#pragma warning( disable: 4355 )
2 ~+ E1 X2 [; B6 B+ d3 ?3 c4 J7 }7 m
1 ?8 [8 R( ]- I; ?#include "UPnPImpl.h"- [* f* u/ \( `8 {5 a0 i
#include <upnp.h>
& N. c, U* A7 G#include <iphlpapi.h>
], w9 T7 _! W#include <comdef.h>
5 p" Y/ j; Z6 V* q- s9 H/ U3 h( `#include <winsvc.h>( c) Y1 K3 f) G; g$ V+ [
4 O2 O% T, Z: S0 s% o& a! Q. i7 E8 } [+ p0 |, [
#include <vector>
: k/ p& o) s# Q0 S) w T#include <exception>
& h, b) B. ? k/ P# v#include <functional>
. y- @/ ]+ p" q
( ?1 G" M+ D, _( e4 X5 b5 ?, K; t+ P! D$ A2 J) p3 ^1 w) J
2 K% F( I8 \" d$ ]
2 X: I9 F5 F2 [6 K$ D: P7 A
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
; F. A# \* b3 q+ {9 Rtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: y1 O6 _# w3 d+ Y1 m! Z- V# @0 z# S
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
# @2 C3 g$ X, V Z4 a) d- E3 X9 btypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ L4 W6 Y1 R; E. V; O. Q
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
8 E- Y) w! {' g! W1 Stypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
/ O# {0 r' |8 _5 W9 Y- ?$ F/ itypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 ^( u5 R+ t/ H- i5 R R
' w0 H9 s- Z0 D: c3 J! o
9 j( O* r3 \9 w$ B7 l
typedef DWORD (WINAPI* TGetBestInterface) (
. D3 M& z' [* O1 z$ }, B IPAddr dwDestAddr,
1 G E& n' U a6 k PDWORD pdwBestIfIndex
& z! N+ s3 g! I9 T6 f" J5 L3 L);
+ `1 I" `! p& A8 F9 B" M
2 v. W+ I7 ?8 P( M% u
- G* J6 O# r3 k0 p' f% J2 s Stypedef DWORD (WINAPI* TGetIpAddrTable) ($ {6 K; a9 w) Q3 X, K, t
PMIB_IPADDRTABLE pIpAddrTable,
2 U- r( Z5 v L0 R, r9 N( q& l* ` PULONG pdwSize,
- ]$ c# z+ y" e4 H; s BOOL bOrder
7 n/ [% a5 m/ h9 W% \# `% y$ C4 S);. c& _) t* c7 g1 C# E2 [8 Q' ^$ W& ^
, s$ W: h r! s% g9 W- p F* p: T
& V- Q. P3 i: y1 Jtypedef DWORD (WINAPI* TGetIfEntry) ( ?4 Q) ~5 U% b1 B% h0 e$ @( n
PMIB_IFROW pIfRow
" Z u' Y0 w& _( F( E);
" j M% g, o2 m) O6 F
- U7 Y: N3 X) f3 V0 g) D' A0 G1 c/ W/ n7 y* P& K, G9 {% i% c
CString translateUPnPResult(HRESULT hr);# C, G; S! z3 n; g4 q; _+ Y' |- x
HRESULT UPnPMessage(HRESULT hr);5 w* L* ], X& G
: k9 z* B. h, Y+ z1 {
, ]3 v& r% H3 n( i \1 c1 m# Vclass CUPnPImplWinServ: public CUPnPImpl
' Z+ P5 ?) }8 t* c' z4 l# v# S{2 |+ C- S* S+ }& { K
friend class CDeviceFinderCallback;# g( T% v7 x3 o. r
friend class CServiceCallback;% d8 ~0 e- \4 g, L+ k
// Construction! R" L7 [- O# Y6 y( E! F
public:
) d" w# |5 t s# z$ J- E% S virtual ~CUPnPImplWinServ();7 N% ^# N" W% |7 Z& u: n
CUPnPImplWinServ();
" Z% V/ d" E# R+ h2 O# J2 z. \; I3 Q# r* h: ?1 _6 ]( G
6 w( m$ f9 L4 q! B0 |. l
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& ] H: p, Z; Y virtual void StopAsyncFind();+ Y; B( }* }* x2 M5 `! c# ?
virtual void DeletePorts();
( A3 x$ k- a8 u5 X" f virtual bool IsReady();, u2 I, m7 X- Z4 ~' T G( |
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
2 ~; ], t/ }$ d# ?! O" K% y# W4 ]0 r2 l8 s. ?
" N0 G8 V) D: d
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc): j6 Y9 b2 D8 P: V! `4 k
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 b! l- b& b I! p
virtual bool CheckAndRefresh() { return false; };" y# B- W. f, B) Z
/ B; W H) e" f: Q' j6 w
/ N" U$ j% F% V; P* oprotected:4 c) [! z9 W; n* H' @
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);: F; c# v2 [2 A
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);. K1 Z8 A8 k! a$ c8 A
void RemoveDevice(CComBSTR bsUDN);
1 \& n( D1 r& H( d J bool OnSearchComplete();
" w! }& T6 `' l void Init();
0 P* U+ \' F9 V# O' z% s
3 \0 w5 g5 J* f3 R/ f& E9 g6 {1 q% l. \
inline bool IsAsyncFindRunning()
4 {3 }7 l. H; O: @5 j {
3 v+ S" D& Y- m& q; q if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )! w+ U& r' }+ t# i i7 Q
{9 }* c: w. q: ~, ?% G8 E) K" B
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- j/ X1 s; Y- A- i [9 U* ` m_bAsyncFindRunning = false;# L2 u# h! z6 |2 U% V
}
* P6 L5 D! V' n3 j& s) V MSG msg;
( K& q9 @0 f; |4 s* f3 m while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )& L0 V8 {" x- o7 z. G# F
{6 v8 D7 M: k2 W0 f F S9 r* V
TranslateMessage( &msg );* e. I3 d$ V+ v7 B
DispatchMessage( &msg );
- s0 Y6 t; m5 ] }4 R3 ]6 v* k' s7 q" y7 O% R% G
return m_bAsyncFindRunning;0 D! ^, P: O# h, B, A
}4 U1 e4 ~6 |; E. C7 l
9 z. m2 r: E' c+ \$ s9 X2 D, S: W$ ]* U
TRISTATE m_bUPnPDeviceConnected;
+ z9 j. Y% `* M/ i, j" W1 d U! }. @* V9 u( g) Y
6 V( u3 L, t) ~( {// Implementation$ }3 e0 i+ G: Y" j1 @4 b: o' ~ j) q
// API functions
3 _0 r q& ^) T% G- ~ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
8 E( L3 Y& M# s+ O SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 f6 d! X, S- X. w BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);) p% j! T `2 X$ m6 _5 f
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! x8 R* @' s- i7 a7 h BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 Q/ G2 H9 u& y6 n# V* \ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! {" n( t, @7 _" n. Y5 F1 D/ n/ q$ H
. l7 J$ e4 Q' `0 I! W2 U TGetBestInterface m_pfGetBestInterface;
9 F5 w( y2 n2 } TGetIpAddrTable m_pfGetIpAddrTable;3 w# @# D6 I( f
TGetIfEntry m_pfGetIfEntry;
0 m9 I0 ~- Z' M0 y* m, {& \! W0 P1 v4 @
g/ o; D) s# l* L
static FinderPointer CreateFinderInstance();
e# U; M. ~' s0 C struct FindDevice : std::unary_function< DevicePointer, bool ># ?& t1 u6 H5 r$ r1 }7 R' o
{; l# m, c; s8 I5 T# |* U& h* C
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
5 O* T, y" i4 k) A: K result_type operator()(argument_type device) const+ ~3 G! d Z( a( q
{
2 T v- D9 X! }4 q' M CComBSTR deviceName;
: P$ i& B; x/ y$ D) _ z9 n# m HRESULT hr = device->get_UniqueDeviceName( &deviceName );! r X6 m% x5 ^9 i
9 K7 a, ?9 u! T; K
, J* U' d4 C2 l' k: a. F
if ( FAILED( hr ) )
- L2 k& J: Z/ } I( r* e return UPnPMessage( hr ), false;. X- ?3 K5 E4 U' w
5 \% I5 l8 Z# Q2 z7 q2 V6 w" R
return wcscmp( deviceName.m_str, m_udn ) == 0;! t) h# H. ^: ] v) v
}
: B" Z7 T7 Z' V; H5 ~& w- t CComBSTR m_udn;. x* Y1 r; z% U: }2 H
};
" A/ @4 k0 W8 |# U7 x, O . M. c- A/ n3 @) L" x" u( r" Z
void ProcessAsyncFind(CComBSTR bsSearchType);: W' m: t/ x5 |
HRESULT GetDeviceServices(DevicePointer pDevice);
7 _# {& \& f% j: a- @ void StartPortMapping();
+ _" `/ B2 h7 W! n0 \ HRESULT MapPort(const ServicePointer& service);
$ S7 H: C8 `7 ^: |) g+ V. H/ d: K void DeleteExistingPortMappings(ServicePointer pService);
5 E# J# a8 v# }- b: y; I1 k void CreatePortMappings(ServicePointer pService);7 [% F$ X- g& ? r2 {
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);9 Y! o3 R3 j; h5 S+ q0 s5 o
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
; x5 L$ W( L3 q9 B LPCTSTR pszInArgString, CString& strResult);
1 [& m" l) ^7 ~! w% y& @* b void StopUPnPService();* s, L7 n9 ~) i/ M7 C+ x/ m& O: M3 o
/ Z4 \. A( t* J4 p ?$ w
' M0 ?# M9 g" H5 T
// Utility functions
6 `1 [- V, F$ l- ?( H HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);! E4 H: N$ m: l
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);2 G- S( ~+ r) f9 l$ H& ^
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);$ N5 c2 V4 n+ s& q
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);; P" y3 f* m: b( f# G; v
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);/ G5 b5 V3 L. g C
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ `* N! p7 r& F9 _- u
CString GetLocalRoutableIP(ServicePointer pService);
' U9 D5 `' _% ]3 w& }* l. x
4 j) |7 `4 F/ _; I) s }. d$ J! ~& e2 F6 W: a j; D* D6 y3 S
// Private members! B2 u9 e d$ j6 E$ E' Q
private: B: l1 p8 Y- H. H8 k" g4 l
DWORD m_tLastEvent; // When the last event was received?
: z. t+ G+ {0 I" z std::vector< DevicePointer > m_pDevices;# o' Q# V; a: L4 o' |- K0 l
std::vector< ServicePointer > m_pServices;
8 ~( y# J; e' k5 t F$ i! ? FinderPointer m_pDeviceFinder;
- k U* h7 i# S1 R DeviceFinderCallback m_pDeviceFinderCallback;
+ X6 h1 Q& T: @8 x/ j# O ServiceCallback m_pServiceCallback;
q' @" c9 l( `3 N6 l* U0 Q' w6 c+ |4 i7 R" H T, N0 z
7 |2 `0 ^6 V) a& k T" v: Y( w
LONG m_nAsyncFindHandle;
1 k, e; L& h* @4 K# H bool m_bCOM;8 \. x8 J/ D* C) u: x; F1 J8 e A
bool m_bPortIsFree;
. x8 X9 e% x' d( U$ U0 u CString m_sLocalIP;
" u: [( _3 I, X& N" S CString m_sExternalIP;
- u6 U- M, Y( s4 X0 M4 f' H bool m_bADSL; // Is the device ADSL?
, K# D" r" G2 c9 o bool m_ADSLFailed; // Did port mapping failed for the ADSL device?5 m, d' c3 j6 M1 S" X
bool m_bInited;
e* i1 w' r" L6 V2 v9 ] ]3 ?( \ bool m_bAsyncFindRunning;
& H' R- X* ^. V1 n1 ~' D8 Y HMODULE m_hADVAPI32_DLL;& u8 ]% Z+ I* }$ g. [' o
HMODULE m_hIPHLPAPI_DLL;
6 E2 G) ?5 i$ G/ i2 Q bool m_bSecondTry;. C7 }2 X, q8 i6 L; ~, u( Q7 [
bool m_bServiceStartedByEmule;
, ]0 T, b9 ?3 a( q) y6 X# q bool m_bDisableWANIPSetup;
& y8 |+ M" M) R% x$ s1 G bool m_bDisableWANPPPSetup;
* V0 _! @! i- @0 w( Y v6 V1 @; X2 c, S
) m( f4 `- J. R. f};
+ D; {5 i- A+ \6 j! m
3 ?9 z+ N1 a( p' \1 e( N2 W
4 z% H+ w- g3 s& R. x8 |// DeviceFinder Callback; Q: p- B9 I" t# |; A. l/ |8 T
class CDeviceFinderCallback
5 p% M( P# ]' ]4 r : public IUPnPDeviceFinderCallback
$ {8 k% H9 k& O: @+ O+ M C t% Z{) z7 {# Y% l' ^, B& Z4 W; N1 G
public:" m1 s1 C+ z" O* m
CDeviceFinderCallback(CUPnPImplWinServ& instance)
& n4 Q( K9 s) q# s. k : m_instance( instance )/ V. V4 i! Q( k
{ m_lRefCount = 0; }' ~2 q" W3 \( h* }9 A
a7 k# O8 ^$ A; N# ~: }5 O' U8 q% |4 H
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. G% q1 q5 J* A2 X7 S$ h/ n% C& F STDMETHODIMP_(ULONG) AddRef();
" j! F8 D( x$ w8 i/ _# E( N7 p STDMETHODIMP_(ULONG) Release();
8 {; x! y C7 q
$ H0 W4 H; ?: S' e1 C9 _* e9 b! H$ J- ?' E
// implementation1 K, E7 c g3 T& x
private:6 [/ g4 i* j' {3 }6 k8 |# |2 s# Z" E8 n
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);! b4 Q7 D; P# T3 l
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
! y% L$ M% N+ |5 y, ~ HRESULT __stdcall SearchComplete(LONG nFindData);2 C) p, S. i- l, w
( t! v9 M4 F6 ^- R, W
: ^7 D' l$ y2 L t( j& nprivate:
. G. S) R6 {/ g S CUPnPImplWinServ& m_instance;5 i B2 t0 I' x7 N7 x# s
LONG m_lRefCount;
' h" s ?$ t7 E};
- v9 a" I- ?8 d/ c0 i
2 j0 U4 I& [/ A" y% z+ u
& I8 q4 `4 P. ?// Service Callback ) n4 k. Z% h2 C% B5 b, L/ z
class CServiceCallback$ L) D; j* g6 s/ n9 g7 Y* B- z
: public IUPnPServiceCallback
( ^8 B$ I2 F# u, L3 a{* \) h( _, R7 Z
public:
- k4 G2 T& t: | CServiceCallback(CUPnPImplWinServ& instance)) H' D" j! |) b8 p! J5 `- |1 q9 ?1 F
: m_instance( instance )- X- Q* ^- y- [ {) n6 o
{ m_lRefCount = 0; }
( b4 Z4 y" ^9 f% E9 `1 _
. |% g+ e5 u m2 Z6 f# n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. F& l/ n9 o6 n STDMETHODIMP_(ULONG) AddRef();
/ S4 b( A8 ^' ?- [ O) K( b" r; l STDMETHODIMP_(ULONG) Release();
. l7 V; D1 D+ g/ c1 u6 e
: Y% N8 J+ F" ~0 f+ ~$ Z, Q3 P: R/ E d! Z: B: b
// implementation
! v( j. T; P& E$ h% pprivate:6 N9 ~3 j9 o- h3 z
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 n1 f0 ` Y' B+ G- {1 i3 J HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
- g& Q6 Y3 l9 o! _# N& t! q5 R6 c' B1 U4 h6 R
$ v: w3 P3 z1 W2 Y4 kprivate:
+ P# l8 L' b5 [7 V- o CUPnPImplWinServ& m_instance;0 u/ g/ |) a, s* n
LONG m_lRefCount;
`9 Z( F) F5 P1 p, ~- D! N};* G/ ]; j: s, ?; R2 S
& v, g ^. A/ i5 W( b: X b2 u
3 |* H v4 X, X- @/////////////////////////////////////////////////& S* r3 o# L* P: Y
+ C0 m) Q; s, W1 i5 R+ |* G: Z3 Z" G
$ N+ t6 P, v' ?% t: c$ L5 B; t% q使用时只需要使用抽象类的接口。
( l) C: A% }6 F* y! T& cCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
, h F" a& t1 d) z$ c$ Z) [3 |CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 S7 s* {' d9 S* O4 d, j6 { mCUPnPImpl::StopAsyncFind停止设备查找.
1 @ {, `# ]* K2 fCUPnPImpl::DeletePorts删除端口映射. |
|