|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
9 Q+ a& I0 v7 }6 S8 f( }, e( O
& I5 _2 I7 V% f' G7 F* ?
' \, ~. H! s3 w: S9 B///////////////////////////////////////////
+ g' K* D$ d0 `//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
2 D3 |9 J7 F/ n7 d$ ^5 i+ _! K$ F
, Z+ ?, | P: y7 T) h: y5 P: E/ `3 {9 r4 T6 s7 H5 J
#pragma once& ] U) I6 E8 Z
#include <exception>
2 {$ d! h: C8 N
! L1 T* p6 W# s! T6 |2 P5 _0 H2 E
enum TRISTATE{
4 v7 W. D/ s1 E5 s; R TRIS_FALSE,
. P8 @9 Y. H) @6 e2 K TRIS_UNKNOWN,
; q; z) D) I: \ c6 R TRIS_TRUE* e8 K% l M1 y! |0 ~
};1 f3 y$ ] Z! C6 v
- @& y' R+ C( r7 N) y+ v* J8 p: i* X$ }
1 I& G+ Y1 t" \3 P/ y3 Z, Denum UPNP_IMPLEMENTATION{9 f l- F6 @6 T5 @# G. t
UPNP_IMPL_WINDOWSERVICE = 0,
2 ?- G' G3 ~: b. I, h UPNP_IMPL_MINIUPNPLIB,5 _2 [1 I+ n# l" C+ y0 o: D4 f& [
UPNP_IMPL_NONE /*last*/
4 [+ C8 F6 R2 U0 g, S8 N' S5 @+ W" ?( c5 H};
. k1 C/ Y' B# T3 B; w
, }' U% J" c6 m' ? K( h4 R; B2 B8 n0 R8 u+ ^4 E7 d
+ N& ]4 R- e4 Z: A6 @4 _
# K/ t7 p# \- H6 Q$ ~5 \2 q; Y2 d2 yclass CUPnPImpl) i+ G% ^* ^1 H! [/ ^ E! y
{
+ h" D- V' l1 h. ~$ p& P- ]public:
; Z! |, B, z8 w CUPnPImpl();3 ^8 b7 W, k! `+ J" u0 V9 W
virtual ~CUPnPImpl();
4 o% m/ o- Y$ d! d& J6 { struct UPnPError : std::exception {};) e( B5 h# X- u4 G
enum {8 t: |; p* p. G$ r/ ^$ `& r8 u
UPNP_OK," y0 L% ^* h. Y% ~8 ]2 Y/ w
UPNP_FAILED,
5 e v6 o5 W8 j! c+ j9 c9 \" d UPNP_TIMEOUT4 V/ {; P5 K1 D) t) w' K p t8 n1 J
};
8 O" a# B2 V4 g2 v w3 a& ^
( e! V8 N9 r( Z V& {( ^+ Z% K8 A0 Q; z, H. ~% r7 l; N
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
i( E* n% A \ q: H% m virtual bool CheckAndRefresh() = 0;2 F, |3 S x+ K4 a+ W j, Z/ ]
virtual void StopAsyncFind() = 0;
( l* M8 z# M6 y1 m virtual void DeletePorts() = 0;' V6 G) b, Z3 I" ~, J* O6 X9 d
virtual bool IsReady() = 0;
) G) W1 Z: x- p, |" [/ B5 Z3 J virtual int GetImplementationID() = 0;/ O" H1 s) |! d. m1 D' T+ [
1 h# p% E# V3 M; Z void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
, R: C# C8 m$ L9 j- Y. k9 b
" D4 P" Z* f: `& t+ b [; U6 ]9 @
$ D; o- l! p6 J4 L2 ` void SetMessageOnResult(HWND hWindow, UINT nMessageID); }2 l% T1 v; ^" B1 F3 s) T
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
" G. w$ ?* k+ U" b( I/ } uint16 GetUsedTCPPort() { return m_nTCPPort; }0 ]: I% |6 E. z) I
uint16 GetUsedUDPPort() { return m_nUDPPort; }
, k1 d# i, r: f( ~+ l" S; ]$ ~1 D# J [6 w8 x6 p' L
1 E/ A7 m6 @2 q, F2 D
// Implementation
+ a/ j, Y0 }. }5 I, l7 Hprotected:
, T1 e" u. h) G0 f& E4 d volatile TRISTATE m_bUPnPPortsForwarded;) [4 B" C( @1 y
void SendResultMessage();
# ], S' d& a- Y' ? uint16 m_nUDPPort;
+ v* z6 f7 O2 A z6 D5 a+ o uint16 m_nTCPPort;
1 g3 a5 z B( m2 A, ~! w uint16 m_nTCPWebPort;2 G; B; e6 ]1 t5 v: O7 E
bool m_bCheckAndRefresh;1 D* L% C+ }, R- d+ G
2 V% h A+ E# P4 y7 ~
) h4 z% }2 O( o( Q6 p
private:
: q `8 `6 u+ Q+ c, c/ u, m+ I, H5 f- k HWND m_hResultMessageWindow;0 Z- {: W4 R: U6 b5 U9 i
UINT m_nResultMessageID;
4 x! d3 Q! D7 H+ r# u2 M# ^$ S- D K- o& z# {
& H. W( O( s% F, w1 [$ I: \2 x, T2 m7 D
};" [! t+ H) J$ c/ l+ l
1 m n' S. l+ y0 Q4 z6 F7 T
8 r, l5 T6 ^6 k8 K" l/ a
// Dummy Implementation to be used when no other implementation is available
}8 P+ J. ~) ?; q5 H" I o6 wclass CUPnPImplNone: public CUPnPImpl
& e# I" x! h6 F* B0 I# B6 _{5 ]' K" ]: `+ I; S& a5 T
public:
3 h9 M8 c' U8 M8 \ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
; C. g' o* T. o) L0 V8 a3 d virtual bool CheckAndRefresh() { return false; }
( v* Y1 H- l. ~( G+ x% d$ [7 H virtual void StopAsyncFind() { }
- o/ h* o# o7 m/ `: M" X virtual void DeletePorts() { }6 R3 r$ v ]4 ^' W
virtual bool IsReady() { return false; }' ~8 L! W: e6 j$ f
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
- o- _) g; \% n; K3 ]};, m( e2 p/ ^& V% O8 P. ]
w8 |3 X1 {. M+ ~0 t, q( |: S8 R
/////////////////////////////////////
# J( ^6 j( h8 j//下面是使用windows操作系统自带的UPNP功能的子类6 |- d( w+ ^) d x' T, `
e4 l: ^# [# {( A4 X6 R- s
4 O: {' l: C: F#pragma once
4 o$ a8 ]& W6 X# {. q' m; E+ U#pragma warning( disable: 4355 )
# x, {- {$ \& J* |# ~' c3 S9 G l5 Q4 Y# O( \6 R; {" [- r
' a) d1 ~: D* D+ ^#include "UPnPImpl.h"5 d, C" I8 n& }1 i& y
#include <upnp.h>
- b5 t9 G+ ]: w- M3 N#include <iphlpapi.h>. A% ?/ q: f4 [3 A, K9 `" b3 h
#include <comdef.h>% X: b( |) d4 l3 a
#include <winsvc.h>
" i) n5 W% Z0 u2 F
8 w' a" u, n' l2 p+ T) n' X6 D. f" {' H: U
#include <vector>
, u4 C* ]! p' P3 q: X. ~#include <exception>
. R% ]6 A9 N4 i4 p#include <functional>! c/ H* H6 t j5 _6 {1 P
' |5 }/ P* X2 e+ [! M+ w
0 t& E9 D' g! @: K+ _. i) ]9 H: {/ t$ a
* c1 Y( i( V" ltypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
8 `( j! I4 @! K; ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
& e6 }( v( _; y( Dtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
8 s7 N- a4 Y2 x& Ftypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
& s1 X7 M+ z8 c3 z b7 gtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
+ G. g4 K8 Y5 V9 `: i- v" O* ]3 ~typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;+ `4 K' k5 h; B( ?) X' k
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 |+ V+ F4 l4 j/ I" u# ^
% q( B/ \ C& K$ y
8 X9 _$ B0 n w( E7 Ctypedef DWORD (WINAPI* TGetBestInterface) (- d& I. \& V; U, f3 s3 Q
IPAddr dwDestAddr,
% F% {" O# W0 ~, G x: o0 R2 s PDWORD pdwBestIfIndex
5 I, [4 Y) t8 W: J1 G% o);
" u. t" [' z4 t4 H, o0 b. L" D! y4 P
2 |% P/ I; j) c) p2 U- htypedef DWORD (WINAPI* TGetIpAddrTable) (
; Q' O3 c( |4 N s; d$ v PMIB_IPADDRTABLE pIpAddrTable,0 w% M2 v4 Z2 o6 Y1 D; s/ G+ [
PULONG pdwSize,% ^& ]( n$ A$ b& q9 V
BOOL bOrder
6 C g i- R; F& w: o);
2 r, h) T1 B9 b5 q% D) Q* H( m
5 R! f3 d1 ~0 Y+ h: r. ~# q" m5 J. i) t
typedef DWORD (WINAPI* TGetIfEntry) (
! L6 z: ?. ], \0 Z$ N2 Z% J$ e, i PMIB_IFROW pIfRow0 N: V& ?( o/ s5 y6 a+ n% b# Q7 m
);0 y# I! W+ _9 a% z; g' Z
( {5 t* _" S6 f. m; W `5 D' n* M! m- R& {5 N. J
CString translateUPnPResult(HRESULT hr);
d4 n6 p s' [& |) |HRESULT UPnPMessage(HRESULT hr);5 E: c% g# W& ^; B8 a: {
4 Q5 }& C5 h6 q- V' K! U+ q7 s5 \
1 }6 n7 |# b+ q/ jclass CUPnPImplWinServ: public CUPnPImpl' \4 A* n/ ^+ y1 S/ ]
{
' x& g! y5 B! s9 |! }) P: u friend class CDeviceFinderCallback;' X ]* }' }$ L6 j9 H/ p7 N
friend class CServiceCallback;* [$ S% j& n8 M3 s( U" `/ A* D* a
// Construction
4 l2 q* z3 h' W3 j6 k Epublic:
/ y( m8 G% F8 ~4 g# e virtual ~CUPnPImplWinServ(); c( u3 x- k, V( t) M
CUPnPImplWinServ();0 V/ ^. V! Y8 h/ e& S
' A1 e H% X1 b
7 W' u6 }" U$ Y# c7 v
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
2 f' w( l# x$ N( h virtual void StopAsyncFind();2 s, w! J) q, r+ X# ?. F
virtual void DeletePorts();& s% n' E5 W1 [# O8 {$ L, v2 I
virtual bool IsReady();
" h7 [+ S2 A% t2 |% X virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
, M% U- T# U J' |8 e# G _7 H* n% f( }5 r5 X
% M: Q C, `& Z% T // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
7 B( z. d6 f8 c/ M1 n- y! ^ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 H& U7 i1 X( f8 q4 J8 g) S virtual bool CheckAndRefresh() { return false; };0 o w1 g% k% `" s! w* e! I$ ~: N
: r. q* E. Z, ` ~4 E( k! a" b
9 \4 C( T/ k6 A. A) `; }8 {protected:
+ x8 K+ z j' B void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry); ]7 I- F' S% v `) m
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);8 c- P" W) x/ ^1 _; F) {' j% g. z
void RemoveDevice(CComBSTR bsUDN);
( G' ^5 E* d8 H# [% g. I bool OnSearchComplete();- A! g4 j1 N; ?- V0 ^1 e0 W& ]; c
void Init();# d: i& f5 V8 x4 V' @' k- m
: f; v w: Z) ?) Z" d n$ ]
% B2 H0 _/ A0 E) G+ R" ^1 M m inline bool IsAsyncFindRunning()
/ J% Q2 a+ {: l6 K4 r8 P {
o) N J- I; A4 F+ `2 k if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ) X P- D+ J6 g8 K3 r3 J
{& I( o! Z* f2 }1 ~& Q J
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 t1 {! J' ~) {/ F" j m_bAsyncFindRunning = false;
, \* p# Z% ]" j# k g }3 a t- w' w7 o8 b3 u
MSG msg;
- d& B2 W* Y9 C! V1 M! O N2 p7 T# H& c while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )/ ~, ^: r9 g! p
{
' o* p& s9 R& D6 o$ p( ?$ J' x TranslateMessage( &msg );
7 u' D# \+ z" [ [# t; k DispatchMessage( &msg );
* i$ n$ R, @7 c0 \- B8 ~ }
7 F$ C! W$ c! j return m_bAsyncFindRunning;0 _4 {$ n5 X6 {1 X# O8 O
}
* n. r* x. k$ _6 N* K; O) [9 b. }2 \5 U+ x% j
4 x, ?+ q% D) z5 F. ]5 o) B
TRISTATE m_bUPnPDeviceConnected;9 |5 q/ q3 ?! n S
6 ~8 d f' \) g1 a; z
2 a4 v/ F8 T9 I& Z5 w// Implementation
1 h% b+ J( N' C7 C+ [3 H5 K. r // API functions
5 r" P8 m. W0 x& c4 H# v SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
% \% h f- s6 i; N) @4 W SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: I( w; M3 h5 }7 V7 |8 j& p BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
3 O Y1 o, t, H0 ?6 d, \2 @, W9 ` BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);8 F: D6 j1 A; @! x
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);7 r, @/ I! m: w1 c
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);/ k8 R- N, Q5 ^) m- Q; F2 O
' z) M( v6 W; o* i ]9 F
( f: d* A" U9 P0 Q TGetBestInterface m_pfGetBestInterface;
" _" T/ d% z% i! r3 h A0 H3 J TGetIpAddrTable m_pfGetIpAddrTable;
~# w& z ]' m- W- M# x TGetIfEntry m_pfGetIfEntry;
5 B* S8 o0 d( B
2 S& N( [0 w* O1 a2 j. `1 o$ n4 S* P9 Q
static FinderPointer CreateFinderInstance();
% D4 m% a1 b! c. ^- f+ ]/ K& C struct FindDevice : std::unary_function< DevicePointer, bool >6 L. Y7 [% H( e; F( J
{& G2 t3 y4 D6 _ b% Q, Q
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}' J3 [$ ?/ ?% x7 I/ G
result_type operator()(argument_type device) const
. y0 Q( U3 U( W' W0 C+ Z( h- M {: w q; E% ^, B2 |& y
CComBSTR deviceName;
& F4 f0 L' A5 ?+ J HRESULT hr = device->get_UniqueDeviceName( &deviceName );
* s Z6 [' V( ~
- q& {+ L+ j; ^& _" ?
$ o' R) M# u2 l, S: ` if ( FAILED( hr ) )( ]( T& z* ]1 m
return UPnPMessage( hr ), false;& p/ M0 Z9 ~0 h
& K4 M% W* F! r
, f( S& w2 W3 i/ i" a return wcscmp( deviceName.m_str, m_udn ) == 0;; f" u7 o; `3 w
}
% X# A' O/ Q: c- l' E CComBSTR m_udn;" n; u S4 {2 r2 U. |; K
};' H% y( X2 z7 M+ H5 n
! H4 K# @5 b- c1 C, U3 L: Y
void ProcessAsyncFind(CComBSTR bsSearchType);. P! p+ e* O9 D
HRESULT GetDeviceServices(DevicePointer pDevice);
% @ D) ~" v N void StartPortMapping();! y! x7 n+ W) L' \
HRESULT MapPort(const ServicePointer& service);. S# T2 x+ F( J* D# m# J
void DeleteExistingPortMappings(ServicePointer pService);
& Q! Z: `. ]- i void CreatePortMappings(ServicePointer pService);
" V1 y% Y7 J! }& @ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* X% n& d* ^% L# r/ s Q& O HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ' i" O* _4 s9 P. }( A, b% r. z
LPCTSTR pszInArgString, CString& strResult);
- q! o$ O: g: L/ j' E void StopUPnPService();
4 Y2 i0 j1 Z+ o+ H3 a: Q1 D" h
( G( @2 j. m+ J& w
4 X: r2 S' N4 j" U. ^5 ] // Utility functions
. A. S2 C! k# N) @) |. ~ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
7 }) F% a" t, n! q3 n; i4 l INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
# N3 |9 K! L/ c/ }; M4 X" q2 H INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
2 w/ |1 K. y& R. p1 a void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars); [" i) e' |" e7 ^; h
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);) o3 J. d/ D6 V; X
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);- r3 w5 { N! Z5 m9 @; z
CString GetLocalRoutableIP(ServicePointer pService);" Y5 {% E: b% W/ w# O
8 f" p/ b! F2 p \
! w7 D& ^9 z _0 n% Q4 g! j// Private members
9 Z2 u) E* b: a8 t5 A# j6 U! iprivate:
+ c8 V) C" o, V0 w DWORD m_tLastEvent; // When the last event was received?
3 l3 e/ H5 }; | std::vector< DevicePointer > m_pDevices;, G% Y3 W/ D! s" p6 J0 M
std::vector< ServicePointer > m_pServices;+ p. i. e- [0 F3 ~
FinderPointer m_pDeviceFinder;/ w: ]' p4 d4 U" h& y0 \
DeviceFinderCallback m_pDeviceFinderCallback;
' w. A5 ^$ Q5 g' Q# Z ServiceCallback m_pServiceCallback;
! ^) Y: C/ j* C8 ~) e
( x R0 P- u- O) n4 c V- x0 ~3 I
LONG m_nAsyncFindHandle;
8 W. V' X5 I# h bool m_bCOM;! b! j; f4 i% O7 }& u1 p' N0 x
bool m_bPortIsFree;1 b4 V3 B# r- p& Q$ l
CString m_sLocalIP;! G8 C" q6 X; [
CString m_sExternalIP;# [! b# ~' z1 _, w7 {
bool m_bADSL; // Is the device ADSL?
5 K0 w( Y5 {! D# x: @; w n bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
1 q% b5 s, _- Q0 |6 b bool m_bInited;
4 T) `& w! b J/ G+ ~1 o9 c bool m_bAsyncFindRunning;
9 N( |- U% I, r$ Q' R3 v- v+ f HMODULE m_hADVAPI32_DLL;* }; p* a' D1 y& N4 v* o
HMODULE m_hIPHLPAPI_DLL;3 X' e+ j3 O2 g) L
bool m_bSecondTry;& B# q' f6 j2 }+ o+ t
bool m_bServiceStartedByEmule;
; v2 C/ \- ^- i/ P" \, X bool m_bDisableWANIPSetup;
, x$ U' K+ p! Z1 [1 _4 d bool m_bDisableWANPPPSetup;3 Y5 M1 @( I" \- }7 c8 B7 Z& G
; E- w; O- L' t# k- \9 V: b
2 a" }) e) G8 p( n% I
};
9 \6 O/ L% l. d5 [4 r' i% a# X
7 W% d, b# i) t* I0 F% V+ _4 u* X6 T5 S8 n
// DeviceFinder Callback- ^, N# v% Y; n- s' o* N% G. X# H& K
class CDeviceFinderCallback
: [, p- b% }1 b! V$ ]4 r0 e( T4 p : public IUPnPDeviceFinderCallback
% g4 e3 T' k. ^; j0 N, o{9 c9 P8 Q) u+ ~9 I5 y
public:) ?, N- ~) R% V8 y2 d4 A
CDeviceFinderCallback(CUPnPImplWinServ& instance)
* J- z* G: P( B6 f/ w5 q : m_instance( instance )- a3 N6 t9 O* n9 M. ?) G L4 y
{ m_lRefCount = 0; }6 c {- q8 C/ R- D5 I
- h' C+ b o* Z8 q3 u+ }# Z$ ^3 e k! A6 { n& G$ k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);: S5 p4 ^2 ]7 ~5 t6 ?! ^
STDMETHODIMP_(ULONG) AddRef();
( @3 R# K' p N+ |, w STDMETHODIMP_(ULONG) Release();0 l) Y1 a' T7 ?9 i
3 A% D* f( v8 d0 s* `
) u$ v& [, j) |2 a' c( X! o2 r" y5 V
// implementation& s* t$ }& w3 }4 `: q
private:
/ u! i Z N/ q8 i. O HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);' p- ~" Y" y( _/ o# H7 H% a; |
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);. Z6 Y9 w# V! v$ I b X7 {
HRESULT __stdcall SearchComplete(LONG nFindData);
# _7 _# S1 m/ S/ F2 v$ u
& l, d( t! g7 X7 w8 G" ^3 _4 _
8 ^) z$ @2 T. h* T9 [ wprivate:
! w- g: p& V- O1 i( S CUPnPImplWinServ& m_instance;. g' G9 O7 P, T( ?3 \% ]5 w
LONG m_lRefCount;% E4 c" Q- m5 x; p
};' R4 w# T' [. W* K: G) F3 g7 j0 q+ @
; ]+ o: z7 Q7 y3 m' D' V* k
" Y8 N) ~( H8 y
// Service Callback
( P0 f3 K: a$ `- ~class CServiceCallback
, J# s' Q: B+ I ? : public IUPnPServiceCallback/ T1 E* i) y+ h1 r8 |/ C
{
* b. M5 \8 N' `: n* |9 I( }8 W# @( @public:
2 x7 m: t! S G CServiceCallback(CUPnPImplWinServ& instance)
& U( [/ J5 Y( E& D : m_instance( instance ). I- p" v7 W1 x p1 w
{ m_lRefCount = 0; }+ Z* ?6 g2 t, P6 i# H1 j
% J6 |6 S! X0 g) m
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. k$ M4 p- R2 V STDMETHODIMP_(ULONG) AddRef();
- U4 w( M; @' N: B STDMETHODIMP_(ULONG) Release();; i# V( D/ @" c) v t1 v4 g
0 K' l1 F2 A: w2 Y! A" @0 ^) B' B9 ?" |) C; X' h2 N. k
// implementation
, r2 K6 N. Y4 Q: W0 R) `private:
* X& o0 F; j: C) w9 ~/ r HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
J+ X% X" f8 |: s HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);+ g6 k" S' @7 L9 \+ ?; e! U
; e N. H0 g8 _ W
* a# g# q) E1 ] s jprivate:) K( e4 v, {* ^& G! n
CUPnPImplWinServ& m_instance;
. ?* U4 R% @- r2 o LONG m_lRefCount;4 F# {! U9 E/ m! I& A2 u2 ]
};9 C8 Z4 W4 \, f; i3 t% A7 w
! B& k% w+ Y& m0 e4 C& N. J) ]
+ V; w. X" M9 W; z1 }: k/////////////////////////////////////////////////% h% f v/ A, G
! l2 N* D# k/ m
/ G9 V' X- E" J. {4 C0 s% R: f
使用时只需要使用抽象类的接口。" s0 F/ b: w5 s& o- C
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% {' J: O9 \2 s7 V' h/ H' q4 Z* ?/ |CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口., s8 e! f5 U3 y2 G& s; G
CUPnPImpl::StopAsyncFind停止设备查找.5 M1 z6 l u( t. X4 q: I8 U3 K& \
CUPnPImpl::DeletePorts删除端口映射. |
|