|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,1 l' D" Q( f, D$ ]
3 `* K; q3 E b
& q. R) m1 K6 w# R: V. |///////////////////////////////////////////
( g; v; F, [7 e, _. O//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% Q* x& q+ G6 S& c" M+ @5 l
' S' \3 K8 A, b n6 o- x) \
* Q9 M4 g$ Q. f) b
#pragma once+ d6 u B' b# f: d* y2 k- T* p
#include <exception>+ L6 C6 E6 {+ l9 c" L3 w
( Z) a9 l& G2 r' O' G {, K, h- V6 F U0 Q. T" B+ j! |4 f3 ?- K
enum TRISTATE{
& Q/ @* s) Y5 O$ m( X6 Q' n8 U) i TRIS_FALSE,+ k; h: C6 a) v. M% f) G( m* o& v
TRIS_UNKNOWN,) c8 X. q1 Y0 j: n# H* X
TRIS_TRUE n: k/ n8 d( `# n
};
* G9 B x) R6 \: X
2 x2 a# d- j" _% _5 T/ y* D, f5 c( k4 F
enum UPNP_IMPLEMENTATION{2 J" I9 {$ x9 ?
UPNP_IMPL_WINDOWSERVICE = 0,' V+ @/ o: D, H% `3 I
UPNP_IMPL_MINIUPNPLIB,
. w. Y1 @. X2 [0 y4 V6 I. A- Q UPNP_IMPL_NONE /*last*/9 A: O8 p; ?6 f/ K0 g! y$ B- _+ N
};
- R4 @1 i0 s1 Y% k/ P
; H, k3 S3 z1 u- F) S, R$ n! u b7 |* i: ~" `' S$ ?( S
0 b% z, z; M1 E; `' @ D0 ~6 Z! h f: s- H; G
class CUPnPImpl
( f6 {! J! h5 d: i. C" u{
# C* w) O; f1 jpublic:
1 i; b) {: \3 t0 z0 H CUPnPImpl();" ^' L Q5 `+ [7 D" b' }
virtual ~CUPnPImpl();. E: w$ H* I; J- Q
struct UPnPError : std::exception {};+ Q% h! y" ]! U) T; T+ r$ U
enum {
" q/ ?6 p5 l3 N UPNP_OK, [$ S* u3 E, n0 [$ O
UPNP_FAILED,
+ k6 Q- e2 g: X- B UPNP_TIMEOUT& o5 q8 o9 W) @& {% l5 n1 [; Z
};% r9 ~3 R1 I! j7 l/ V/ r6 Q
" N1 ?3 C, S; K4 L8 H" m3 v& X& G
3 b& j4 c0 A% J; k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;7 f- ~! u" b; x- n, j
virtual bool CheckAndRefresh() = 0;' `$ z. h+ }0 E Z; B3 D
virtual void StopAsyncFind() = 0;. b0 M) ^& |/ r' z. L, s
virtual void DeletePorts() = 0;) r/ l) Z2 d: a# o
virtual bool IsReady() = 0;
8 A% d, M7 l6 Y' C8 `+ g virtual int GetImplementationID() = 0;
/ ^! n/ }5 R' |% |
( }4 v4 m) q. K) l void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping6 r: A/ @+ A$ h3 S$ A
: ~7 i. I( B) T" L& p; s5 [/ z F9 j4 F% \1 |
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
0 d Q8 Z4 N4 p* d$ |* x8 Q* e+ u TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
- s# v6 v/ R. r! | uint16 GetUsedTCPPort() { return m_nTCPPort; }2 C7 K& W- q' o. E
uint16 GetUsedUDPPort() { return m_nUDPPort; }
$ b' i9 Z: E# [1 K+ ^1 a9 y
5 N3 s. u' y4 e. w! C. G0 c. I' ?' m5 D1 t( z0 M
// Implementation2 d* w- g5 ~) `4 d, Z4 v, M
protected:$ T0 i$ b# W0 j6 ]9 ]
volatile TRISTATE m_bUPnPPortsForwarded;. k e; ?# _2 c( c1 R. H
void SendResultMessage();
4 P; H n7 @0 Q6 s2 B7 N uint16 m_nUDPPort;
- K I) w6 O1 ^' a/ g- @/ U uint16 m_nTCPPort;
3 [4 Q4 H9 Q: b; U) D$ }! r, U uint16 m_nTCPWebPort;& q$ d/ @+ ~; c) h
bool m_bCheckAndRefresh;7 p: ]2 c( Q B6 g3 R8 Z
0 o' {: k& H, X5 W9 y5 U v" i& s3 M" v1 D! y% `7 |
private:
7 D9 i- }4 E1 [) q HWND m_hResultMessageWindow;) l% N( R; k$ A' Y, G
UINT m_nResultMessageID;
# Y4 M. c) d+ ~" Z; V9 ]+ X. g- c0 e/ j! @; Q% x
# L% k5 s. |! F& s+ t};
% f& G. R$ L+ C; M- ~7 V# R6 g! \& c2 G* `; E3 b
$ h! I6 x, r7 {// Dummy Implementation to be used when no other implementation is available* X9 m$ D8 j1 m, A N* R+ ~
class CUPnPImplNone: public CUPnPImpl" E# g3 u2 S% F, j6 D* Q
{1 y/ [, n& O1 Y
public:
( G" B7 z5 S, f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }/ `+ {5 w7 H0 n7 S# m" j" |# K
virtual bool CheckAndRefresh() { return false; }
& m' ]# b, V! d: w virtual void StopAsyncFind() { }
. e$ ]6 I: A6 H9 i' L1 A, D4 M virtual void DeletePorts() { }" x, e5 T# {( k" ]- d, W
virtual bool IsReady() { return false; }* t$ V5 H1 F# V
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) D U4 I; W8 }' [};
5 V2 w- t" R3 R% B3 S8 p; j* F+ g& J5 p
i( I+ ?( h8 m/////////////////////////////////////
! \9 p7 }8 g; j2 q. D) P A+ {//下面是使用windows操作系统自带的UPNP功能的子类4 W* a7 i# [5 } L7 J
. q: U$ w+ b, s; x0 D5 u6 e7 z6 R# e4 n% ^
#pragma once g9 q3 m9 l5 m( r. w1 a
#pragma warning( disable: 4355 )
0 z/ ^" z7 a3 J5 \/ g
) f- i/ n- f8 ~# J% g5 Q1 e& ?0 D; B# ~* R* r/ n, k5 r
#include "UPnPImpl.h"! p, u2 k C6 ?( E) X- o0 r' ]
#include <upnp.h>( {% y/ N5 N% e: X& ]1 {* z
#include <iphlpapi.h>/ Q3 t7 T1 B; b0 E1 G' Q% C# y; E
#include <comdef.h>4 O, M9 t; N v' z
#include <winsvc.h>* n( H2 M# Y" ^ a
# ?$ u; d. J7 M8 D. Y, ~. Q
# Q' t: U% h, m* t$ G( _) v+ u) u; `6 l#include <vector>/ E8 H% M5 Z' B, C% y" t- f
#include <exception>
- B8 V& x! K$ K$ z( x#include <functional>) Q9 R1 ]9 v0 P; X; S
' u" J8 s$ f1 d* O- t4 r2 q% H' [/ ]3 p" ^& f
5 `9 h" k& T6 O2 ~4 V* i- j8 D% T
0 n' X# ?2 c; b: c9 P. K, f" ^5 c
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;2 x- Y0 y; c) ]4 I
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;3 R7 q/ y+ F. Q" W! M* f9 U
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;" e- D3 u, R( X; m, E1 g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
% U0 B$ J& v htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' m+ @; \5 H) D/ P& ^7 L9 X
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
: w( }) J5 ~5 X( ttypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
- m+ b) H- {' `5 g( \2 R: Q( U; f+ U
3 ?7 v( L2 R, R/ f3 d. Qtypedef DWORD (WINAPI* TGetBestInterface) (
5 X5 g$ {' Z" c& \8 r! X IPAddr dwDestAddr,
6 p. Q: s% D5 H PDWORD pdwBestIfIndex
1 {" y0 w0 n" P. R);6 Z. r w3 e# h7 k9 H6 w5 c% D
Y2 J* n6 |& I( v) i9 @. J! {) I1 L& _8 U. [+ a9 {" K
typedef DWORD (WINAPI* TGetIpAddrTable) (
% W# I& y2 {+ d# s! W PMIB_IPADDRTABLE pIpAddrTable,
/ k# g7 W9 `9 r2 {, J5 e0 j PULONG pdwSize,
' q% R* Y8 S7 ?$ m* H3 Z. a BOOL bOrder
; P2 y, j1 c4 K);- ?" X# p1 M0 q. m4 d ?# C
# h. Y1 v f/ ^$ T( T' e) m
6 ?, n, v% j2 t% ltypedef DWORD (WINAPI* TGetIfEntry) (
/ H) W( \' T( ~ d& h q PMIB_IFROW pIfRow0 e/ J6 ?- ^, \5 w4 p d
);
1 J# t3 G9 L& V$ L# z6 L/ \+ T: T p9 V
4 f+ {% m& r" L. k( t4 P/ {
, W( @ m9 Q- K' GCString translateUPnPResult(HRESULT hr);
4 O+ K/ ]( l, u, UHRESULT UPnPMessage(HRESULT hr);
( N+ m; N. L( m h0 ]9 `6 @6 P4 y& B0 G; `
4 R. R/ l9 I. aclass CUPnPImplWinServ: public CUPnPImpl: A+ B' L1 k) I4 b0 |9 f+ V
{
6 Y0 {% v4 P% S0 X! P friend class CDeviceFinderCallback;
' G' \+ n4 M( I0 J; \; }- _. p7 m friend class CServiceCallback;6 M8 e# b1 O; W6 x/ L% B% t
// Construction
' Q/ ~! v1 ^- l8 v" p4 y/ Mpublic: h M X' W* l; W% a" k& q/ T
virtual ~CUPnPImplWinServ();
5 C; e. q- I2 ]. j5 f8 U CUPnPImplWinServ();9 t1 ]6 x% r4 w/ u U
9 I. z' h3 t( P6 q7 f! o
1 o2 y# B4 z6 q+ }" Z' q
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }8 V1 f+ \: ~- g7 z
virtual void StopAsyncFind();
8 v, i( @' }3 h9 Q5 ?; P8 T virtual void DeletePorts();$ l. ]7 F' ^% b W- b
virtual bool IsReady();
5 r! ~. p; Y+ ~ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; k5 k+ {0 R9 I
- h- w0 |1 |% j U3 C9 k' ~
) t, H# z% }2 L8 m // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)7 ]- a& b$ |- t
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later. \7 A& w8 j3 D
virtual bool CheckAndRefresh() { return false; };
' a, J, J# K5 g9 w
; s. d; \6 E& O# [0 ?1 R3 Q* Z8 K% {# M
9 a5 ^: X; X! c& O9 a+ n+ [ mprotected:
' A& T/ m$ U4 ?+ k% o* B+ v void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
/ s+ ~4 z1 T' T void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
4 m2 `( @- ~5 A+ l; f! T4 ~2 M void RemoveDevice(CComBSTR bsUDN);' _7 K' q; l: W% Z. v( h
bool OnSearchComplete();
- J8 L# c. ]5 x; d# m2 V( o void Init();
! M3 b. ~9 e7 J
8 T8 I! N7 Z& w4 ]/ a6 m0 X: t3 O0 L1 e
inline bool IsAsyncFindRunning() # K. y) P* m9 r% H
{, G- p4 M. f" _3 w. ~/ a" d2 c7 F
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
5 w, T+ d/ j( P1 F4 M8 ? {
" C# y1 j0 q- { m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );" w3 k, A* O3 n6 }5 |2 V% v
m_bAsyncFindRunning = false;. T/ u) h* D+ j2 B# c
}
( y+ u& n \5 y# `' c MSG msg;7 l& F/ R; u; J! U5 B
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ N0 z5 k9 K& W# |2 M1 U { O+ D- f8 g% |7 F6 \; m; z
TranslateMessage( &msg );% x: k5 ?1 E! D) v
DispatchMessage( &msg );
5 V+ p) X. k: H- l3 y" ~ }" r; v5 o n" f$ O
return m_bAsyncFindRunning;
& I) n, i1 f& Z/ }- o) e/ q) N }. H+ \; f" L8 D0 A2 v
- [ A) e% t: e
! i2 J1 o. x+ Z7 J: l4 v
TRISTATE m_bUPnPDeviceConnected;5 o7 A4 I( s* c% O
9 j: p3 Q+ ?6 a
$ f* o, r, V/ W8 a* ~) J// Implementation
1 R0 f e( u* C/ M // API functions% X; H4 _$ f, M, d" n
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
# c# \; P3 k: ] G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
$ _0 _) P# N& K6 M7 S( O G BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
. B9 h* O. P9 X: Y# G. E9 s BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( J j9 i& q* g, z% h% n2 }
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);- `, u* u" A; G$ |3 C" n& S0 c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);. q! ^6 v, J8 X0 ^ l/ D
+ f- |' Y* Z- G7 i# d5 @# d
% E* S6 x7 N6 X TGetBestInterface m_pfGetBestInterface;
5 h I6 J# R' G5 U$ g+ N TGetIpAddrTable m_pfGetIpAddrTable;; r. e$ a- f+ b/ g& T
TGetIfEntry m_pfGetIfEntry;
8 g5 w( m- n' k$ q, ^( h& {# g7 I3 C
* E- S4 Q5 ^+ H- P' h) _$ z
static FinderPointer CreateFinderInstance();
9 c8 w: {/ }/ ], s struct FindDevice : std::unary_function< DevicePointer, bool >
2 ^% l }& } w( `2 ^* q, E {
* M0 }2 }( ^+ x; t! B, C FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
3 _. h) t* S) F/ }: ^+ D- Y result_type operator()(argument_type device) const/ M- h, e& h9 Z
{
8 H# [6 P$ M& Y: a9 {5 B4 G CComBSTR deviceName;) n# f6 x( r* l5 W; e
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
1 f% J+ ~/ Z% S: z$ \! u5 q4 K4 e4 n4 m# C3 G& g2 U% C! I3 z' h5 @
" `: s+ ]& F |3 W
if ( FAILED( hr ) )' m1 E2 Z. ]1 n! b9 q
return UPnPMessage( hr ), false;0 W+ j* G/ P) p, E/ U% P I9 E Z
$ ~- |1 t) u% p! `) z
7 \- x/ E/ k l' G. a: P return wcscmp( deviceName.m_str, m_udn ) == 0;; Z% D9 j- S1 N& q" h9 @) r- y
}
0 i- c; s: u$ c4 F) c n; L% r" t( @ CComBSTR m_udn;
1 e) r; j2 s5 {: I, l% w8 q; n };3 z+ T0 \& j6 D7 N
$ `8 o9 u# Y8 Z i w/ O8 d void ProcessAsyncFind(CComBSTR bsSearchType);
K$ |/ p3 G! F" d HRESULT GetDeviceServices(DevicePointer pDevice);
# |& j/ q! w: A void StartPortMapping();) a/ O5 y1 t- W& t* q
HRESULT MapPort(const ServicePointer& service);9 ~( |: t9 A! m* W; x
void DeleteExistingPortMappings(ServicePointer pService);
% s8 c Y* W% c/ k. B6 ? void CreatePortMappings(ServicePointer pService);
0 v+ o: |, s: W1 `- P! m- F# a* O1 S5 n0 k HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);% Q- |! a% F, E: t/ Y
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
. D+ A" v+ w6 o( |, U$ O LPCTSTR pszInArgString, CString& strResult);
1 q1 h; I" Z6 }6 W void StopUPnPService();2 n& e7 c4 [5 P* U4 @: q$ H- i3 r) \4 y
+ { |; \1 ^! @: S) Y( Q5 l5 F" c( f ~ K. z) @) l
// Utility functions" }$ q; e% j& s# e6 R- |/ i2 c4 B- z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);7 m: d$ q$ y" L
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);5 T) o& u. ]. g- K9 m" A
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 q" R* f* ^) U- Z1 i
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" d: k5 r! Z1 ?. d: G# f0 |2 G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);- ~4 v: s2 F! A7 X5 X' P- |( ~
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 s2 K8 a! M) | CString GetLocalRoutableIP(ServicePointer pService);/ y/ z' m5 V* k/ U _
0 {: w e/ L# j) q0 n- f$ n/ h0 S. j, D2 l: W3 M6 U
// Private members
4 K. _2 f- J) e0 Bprivate:- h7 ^% i5 b* F. U- X2 K2 F
DWORD m_tLastEvent; // When the last event was received?
& K9 b0 w1 F. v- R" a( `% w std::vector< DevicePointer > m_pDevices;$ f! U* S3 `1 t) C& w7 ^
std::vector< ServicePointer > m_pServices;
* q' r9 b' ?: k7 z, |/ @ FinderPointer m_pDeviceFinder;
( O/ h$ T6 V9 i6 w! c& l, ]+ m1 f DeviceFinderCallback m_pDeviceFinderCallback;
9 P3 z5 j" _; C% t& Z ServiceCallback m_pServiceCallback;
+ m" W! Q2 I+ M; U
5 Z7 U- R4 P+ C: s2 Q3 w5 N$ G
LONG m_nAsyncFindHandle;, |2 q! ^1 w7 ~% e* V
bool m_bCOM;; y( O% d6 i+ B1 v% ?# y0 D5 S
bool m_bPortIsFree;
6 i" I7 t0 m5 W9 H0 F% E CString m_sLocalIP;/ W) F: {) g! [8 u3 e: {% d
CString m_sExternalIP;
' }4 ]0 u+ T, @ L. c4 K1 | Z& O. A bool m_bADSL; // Is the device ADSL?
3 w6 Z. Z8 _6 {; L9 S bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 k: K$ H$ ~; E6 W
bool m_bInited;
1 F8 l5 _0 Q# l. x6 N/ {7 h bool m_bAsyncFindRunning;" F" G5 @* [& w- d
HMODULE m_hADVAPI32_DLL; ?# c4 O3 T3 j6 J- |; ^
HMODULE m_hIPHLPAPI_DLL;& M- i7 ^ I! _
bool m_bSecondTry;
8 y( q3 s& L1 v( G4 ? bool m_bServiceStartedByEmule;
* y" H* w( c% O/ R bool m_bDisableWANIPSetup;
3 t# ?" z; Y8 N; j( g bool m_bDisableWANPPPSetup;
& o$ V7 E6 i( E# Q. d, D9 ?- G* D6 ^7 y
# v) a* O( y b2 D; ~
8 T* s4 l9 r* I+ x};
/ t$ M+ _/ D9 A: N6 s! V/ z/ Y# o, H& K T2 ?) a( j8 H
) S2 C w+ `( d0 |, J) o) f// DeviceFinder Callback
: p' r0 s# Q9 Z4 z% Pclass CDeviceFinderCallback/ z* l! [# i# D" ]' H
: public IUPnPDeviceFinderCallback2 k0 S1 E! f) P' C
{
7 ]5 U7 _. K# S$ Y! @public:
" C; A9 n2 E6 E" w! V! W CDeviceFinderCallback(CUPnPImplWinServ& instance)6 ~, m& H0 \' N; H
: m_instance( instance )
; X9 d6 {) ]: x4 C' {! F* ~ { m_lRefCount = 0; }
K& N) ]. u7 P' q( O @( D% ~# o
) `7 t: q# R& m! i9 y5 e. D7 p# V6 b9 k, p$ T: Z& X) g
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
* I, t+ y4 n# w: i4 U( Z STDMETHODIMP_(ULONG) AddRef();
2 w* T5 h3 L+ p9 V STDMETHODIMP_(ULONG) Release();5 a1 q4 X4 }# c1 `3 t V
$ r8 w; s0 U: n. l' K3 w
" ^: K- [8 E9 i6 U u// implementation) c9 ?& I: p. O% j" }3 e
private:4 I! s* O, | I2 I& E& ~
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( u: q/ t' u* V; m3 c
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);+ R9 s2 X: ?- ?6 g& F
HRESULT __stdcall SearchComplete(LONG nFindData);( E; B% g. ^4 j) }+ c; V+ z
[6 i! u! l* ^: M& M' B9 j' E% h( Z( L: M: t6 R
private:
2 g, w& C( T$ M. ?/ w. p6 t CUPnPImplWinServ& m_instance;* k. U$ E# P3 r& N# z5 n
LONG m_lRefCount;( o* t3 @% \+ ] N, P9 ~
};7 R- s5 @. [ t* j3 A( \
3 G8 k- J3 o7 z; S* T8 ]1 c* ~' {) C- ]! e, u: c
// Service Callback % ?9 l1 _; y9 R
class CServiceCallback! M0 G$ j) ? v: u' @ J
: public IUPnPServiceCallback* H7 l" H6 F0 X( T# O
{
# |& c& k5 F. \+ U; lpublic:
# T9 p2 F; z8 C m& c2 T CServiceCallback(CUPnPImplWinServ& instance)4 Z6 T4 U" G9 a. I
: m_instance( instance )
( T0 @: T, F Q { m_lRefCount = 0; }" F ?( D- x8 A' N
7 a4 y% Z- K* G STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);- B' x6 q9 e3 z2 m0 y" @# H
STDMETHODIMP_(ULONG) AddRef();
0 e- r* K* ^- u3 I6 G STDMETHODIMP_(ULONG) Release();
) L H9 E5 |& Y" m* S' s- P r2 n. f& c( c$ h
& J5 q1 A& W% p! ?7 K9 k7 R! j// implementation
: N6 @% e3 F$ Q8 \" E6 G2 sprivate:3 |8 F) f( q5 B: H& c/ B( X( C
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);0 w+ k& u4 h4 ?0 X5 N& t$ U, [
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 ^6 x2 d6 H- o: V* e$ u a
( l0 D* i9 ?. b0 T7 P4 l! Z
' E# T7 O! f7 S% H& M' n1 {private:
) S7 m5 M! A M3 d- L0 c* J CUPnPImplWinServ& m_instance;
! \+ L. f Z" ~2 h% ^4 J& I LONG m_lRefCount;
( K, _& n! n, a2 ~! {};& U% a$ U* b) s5 ]
. S& {- r: q: t4 Y) Q
$ |9 K: F+ K- J U/////////////////////////////////////////////////
# F x7 A9 ?6 _& `) t5 P# y4 k6 k8 N2 i/ S' Q6 v# R5 p
4 _8 ?! D9 a# A7 T$ Z' l% j% j7 k+ O使用时只需要使用抽象类的接口。6 w% G: m c) B4 x- |" @
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.' a& n5 P5 K+ v* @9 O3 X1 w7 s+ X
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
* o0 @+ T/ h6 L% w. K! VCUPnPImpl::StopAsyncFind停止设备查找.5 v2 J2 N5 L( ?
CUPnPImpl::DeletePorts删除端口映射. |
|