|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' J/ M5 x1 k6 t% f7 ^. G4 @2 W7 R! O7 K; h
* D* X7 Y2 Z% u0 h/ O; F" |///////////////////////////////////////////
2 {9 k, v8 H; Y5 d* l//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
# L2 r. m$ @$ r$ X2 t$ Z$ m* l& \: E' p. H, m3 c. E2 \
! k( e' U0 _8 D' s! z
#pragma once7 j, E- o+ m3 P& g" R6 T# y# Q
#include <exception>
7 o) |2 `0 ~! c, X
! K% ?0 B A6 t3 Z
4 {) u- j& V* y6 C0 r8 I/ j' I enum TRISTATE{4 }6 d4 o; o( G: {- z
TRIS_FALSE, t- p$ }* p" a
TRIS_UNKNOWN,
% {9 Y/ m0 b5 r6 Z# I TRIS_TRUE
. E; r% n: m- @3 d};- ?2 M" Q5 } [, s6 N9 C
& C( u# T* o5 o! E/ z/ `' u" k6 ^% D. S3 w, I/ X
enum UPNP_IMPLEMENTATION{
/ B W0 N4 O- i4 J% h% n# t4 b UPNP_IMPL_WINDOWSERVICE = 0,
7 V- q- x. Z, j$ y UPNP_IMPL_MINIUPNPLIB,
. H) Z8 k) }& X$ `8 H UPNP_IMPL_NONE /*last*/
R4 ]% @, {8 N( C};! k a% t5 y4 C1 M
0 S% }2 E+ u. {8 I. S
2 @' G; ]1 M& o6 \; N
+ B$ {) ^! J4 [* D. O0 ~+ Y" \* M# U% u' I- |
class CUPnPImpl
. ~6 e3 ]& M6 J. s' s4 q{0 y- j1 P/ S! ?. }
public:
3 C- S9 H, V$ f. }% {! F CUPnPImpl();% u( o y; J4 G
virtual ~CUPnPImpl();+ ~, o8 O7 X8 H1 C4 e4 Y) o; x
struct UPnPError : std::exception {};, a, D$ L3 U: z( h; O
enum {
/ {! C+ ~6 a' u9 k+ u5 A UPNP_OK,
+ M9 X! [0 T( D. M3 a UPNP_FAILED,% z/ F" Z: [0 u$ B' y& F
UPNP_TIMEOUT
h, r4 U' n3 y% N6 N/ x7 ?* F };4 O9 N- N2 `7 H$ E
+ E4 h7 m! A5 A0 {, J. p7 E2 e
$ n1 e$ ?5 h u6 o/ e
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
m& W, G6 ^. r! Q0 R, y4 f; y% | virtual bool CheckAndRefresh() = 0;( F* V! s8 ?1 T5 L
virtual void StopAsyncFind() = 0;
& | f5 d- [6 S0 l: D, [7 F virtual void DeletePorts() = 0;1 l5 u; O0 M2 P! ^# p4 |
virtual bool IsReady() = 0;% M4 H7 M: q5 }1 J9 M
virtual int GetImplementationID() = 0;
3 E; g+ }& A; Y4 N
, P6 w' Q0 G& g' ?/ @ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
& i# {$ X0 e# k) _& ~4 a4 Z
# D3 q! M. R% U U; x% |
- T# h1 y! b* P; x void SetMessageOnResult(HWND hWindow, UINT nMessageID);
) j( x" r, ?* Q) J4 _; h3 }& z TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ ] o8 K- m9 ?& a. A5 p uint16 GetUsedTCPPort() { return m_nTCPPort; }5 q* e+ t% x& O$ T) u/ M
uint16 GetUsedUDPPort() { return m_nUDPPort; }
1 d: i, g4 g3 ~3 s) N
6 {+ z4 J! [7 J( G0 w/ c* T. w) X8 W: f1 f( s% P( c& G# ~9 |
// Implementation( u/ ?: u/ |, ]5 j" u# Q
protected:
& P" n: v, p- ]9 k volatile TRISTATE m_bUPnPPortsForwarded;& p8 D8 d' m' l3 ^. i( E
void SendResultMessage();
; a( ^3 v; T8 y. E6 x, \3 T- J uint16 m_nUDPPort;
1 S# \" b& k6 q* ?+ W5 { uint16 m_nTCPPort;
( `9 q/ [* K) m uint16 m_nTCPWebPort;
/ M* ?0 l0 J6 n& e) ]9 F5 [( a bool m_bCheckAndRefresh;
5 d0 Y7 f2 c0 H E3 I1 {: w
& R$ s% ?! ^) K: ?1 R' h
$ c1 Z3 L/ G$ X8 b) _private:
( z$ v0 ]+ }! ~6 j+ j& B HWND m_hResultMessageWindow;4 P4 k- S4 [1 @1 N+ Y
UINT m_nResultMessageID;
5 Q; E( B) B' w9 J* t! p4 P3 r
: a7 y6 _# h5 @: B( }, ~. o( |8 Z0 E8 O, H4 {+ ^2 s
};7 f+ G2 L2 r* f8 o# D
& X: y# E4 b3 G( V: `: ^% q8 J
/ C8 `! _ S6 ~3 ~// Dummy Implementation to be used when no other implementation is available$ P4 T7 _ B7 W. X! i9 O( d; q
class CUPnPImplNone: public CUPnPImpl% _3 ~7 y( j" ]4 X) Q& l0 D
{; b( _* q; O6 [) ]$ k
public:
; B* N: `! D" T virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
# j/ j) U( x" v/ S virtual bool CheckAndRefresh() { return false; }
1 [5 p' U; d" X6 }+ O, B& ^1 L virtual void StopAsyncFind() { }' Z0 j, G M: C+ j; F! a2 Y
virtual void DeletePorts() { }
* ^; O& ^- ~( T: c: P. J! Y virtual bool IsReady() { return false; }
, ?3 Y# Z' V, Y! K3 l virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
7 N$ {0 a$ l7 O' g8 }0 r8 k};/ E4 u2 l1 w% T: K
. g5 u% b1 a' ]% N) H. `) o
, J9 a% l; y# S/ F8 T, u" X& g! ^/////////////////////////////////////
w( K' k# y6 x0 L% ?//下面是使用windows操作系统自带的UPNP功能的子类
& Y- l% O8 J) U
U% D( s4 P: S3 m, M/ C, T
- ~, v& @8 E* [9 B ]0 o+ [# }#pragma once9 l) d. C( d. i% T, E6 y# m
#pragma warning( disable: 4355 )
" `$ n+ f) L* }6 [' _+ `6 L+ |" T" v& ^; u5 s6 X! E% \
( w+ K# J9 Q# z8 Q#include "UPnPImpl.h"2 }1 n" I, u5 h) w. D# Y
#include <upnp.h>$ L8 k2 u" c3 v9 d) h5 c
#include <iphlpapi.h>: i, l. P- g8 ?5 o9 s
#include <comdef.h>% b7 i4 i5 i9 H( A% d
#include <winsvc.h>
3 h0 `* W0 d: g+ p& x2 i( A
1 z2 M3 ]$ g! G2 W1 z& a
* q/ v( U8 Z! x5 Q# p! P#include <vector>) U |% ]3 ?1 E2 m0 f$ A2 A/ J: T
#include <exception>) v! l% E+ e; h+ {( D, d' L
#include <functional>
( ]+ s- T. |& a1 F* z
. K$ c: ~! }3 y7 `
- k j" y$ r* e' _8 Z. q4 ]% V7 Q& u
0 _9 N3 X. h! _& L4 h/ ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, N( T( R J1 S( P0 b, I
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;1 U ^8 T1 m2 ^5 }" @
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;' m! e8 T R; x" ]$ V/ X5 u! Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
* d' j! k$ @" [/ i j: ftypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;4 q; O/ F% |- n9 N' ~1 Z" }3 Z' c
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr; ?7 h8 g. Q; K/ O: h, R! w) a
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;- E/ o+ S6 B9 O$ D) {: ]% h4 M
" k( ?3 {2 Y5 [1 w: o) K) `6 X9 K4 a& i& ?) y, t. P
typedef DWORD (WINAPI* TGetBestInterface) (
8 c3 s3 z; q5 {1 p4 N IPAddr dwDestAddr,
# t* q7 X7 ~* i5 ^1 h6 b- H PDWORD pdwBestIfIndex; ?5 l' w/ v w8 w+ w. ]% H$ x4 u
);
8 |! E$ z& ]4 h" }% k& ~: j) {9 m
+ S0 Q) G- }2 g% r' Gtypedef DWORD (WINAPI* TGetIpAddrTable) (
" B8 i* g- }6 [- @ PMIB_IPADDRTABLE pIpAddrTable,
4 e6 M; F* ^9 q4 u+ r$ h; | PULONG pdwSize,/ |, Q4 Y/ `& v0 J: \8 L
BOOL bOrder0 @8 h m) j( Q3 ]# e8 a
);
c+ W" q6 X$ K" S7 k) M
# |9 e* K$ q3 }2 b
. w& y5 {" H1 s V7 Z' ~typedef DWORD (WINAPI* TGetIfEntry) (
. _+ J# }9 ?/ B3 H PMIB_IFROW pIfRow+ y1 Q7 m9 s5 D% V' [/ ?8 S" C
);
& \! c; N$ D& T; g0 {* U6 C; }0 V# b( D1 W. \2 _
1 V: m3 f, A! ACString translateUPnPResult(HRESULT hr);/ \8 ~. R7 W8 b' N {
HRESULT UPnPMessage(HRESULT hr);1 I8 k; ]3 W* b0 u4 T( K% Y4 k
6 J4 Y6 B: l3 g: a- ]7 b& o8 P
# x* O# b3 g2 W' X% p; }class CUPnPImplWinServ: public CUPnPImpl, |# p; Q! y' B! J
{
9 c( n$ f' }) a8 m% [) e. f friend class CDeviceFinderCallback;9 P9 \/ `8 ~' R: R0 f2 ]% ~9 O: c" t
friend class CServiceCallback;
: a! d, w% ]9 v w& T// Construction. Z4 {# f- L4 H3 E, A+ B4 S, Y x
public:" Y6 [ _: m1 g! _( d& N% r
virtual ~CUPnPImplWinServ();
. r% \6 T# c7 P$ ~4 m1 ~' R3 q CUPnPImplWinServ();
! q, z2 P( |, D C1 I/ _
/ Z( G0 k, |3 U2 [ a, r
3 F: O k4 {( D2 V5 r% D$ A" N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
" ^; w4 h& b- G! _6 f2 h virtual void StopAsyncFind();
8 D' u* g3 o* A* T9 @ virtual void DeletePorts();
, E# F I, u& ^1 B) ~7 H) C$ c virtual bool IsReady();6 K9 \, X" F" H7 r6 S+ T4 }
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }. C0 A/ y k8 \4 q) L
# Q1 [2 D4 y" U! {/ j2 C2 ^
- o* R* }# d: b/ n2 z6 g // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. S; C2 K4 s1 j, v, u( o {: f2 T // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
8 f, {3 T: F5 Y; c( @* T e- |3 k virtual bool CheckAndRefresh() { return false; };
* c. H! x5 ~# ]! x5 y. B
% S% ?, ?9 T$ D* G" {7 n* A: A4 }: ?0 m1 ?8 o
protected:! o2 g4 ?8 A' ]5 a8 I+ m
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 \. g' ~/ f. V$ j* c& ] void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
+ s( F2 n e- o2 l1 ^0 Y0 ?; Z void RemoveDevice(CComBSTR bsUDN);9 N0 P4 m. X3 J0 p! R: L. E9 V) O
bool OnSearchComplete();, C- p' a2 [4 R
void Init();
7 j% t& `1 `* {' G1 C1 M
2 f8 b+ z' b* ]" j* K4 _: Q; o: f- I7 ]6 i2 V
inline bool IsAsyncFindRunning()
4 q$ |/ j+ m6 \7 C5 q# w {
$ O2 w6 U. H& h' ]& { if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )+ {! h* [; } T- L, j% _
{/ {! j/ O: W7 s& W5 d/ V' C
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
4 b. S# M* ~* V4 j m_bAsyncFindRunning = false;
/ l0 ?( o1 o; E8 @# ]. r }
9 w( `( f% B: \' e MSG msg;. n4 D* L" v! Q
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
: C1 |" H) k- d+ E {
# z4 ~# u& o7 M9 Q: }: o0 l! h TranslateMessage( &msg );5 g3 b4 _2 i- p
DispatchMessage( &msg );; m" a: D& R1 S5 r/ ]% w& [
}
; _- E& X3 }/ t1 B- M& g return m_bAsyncFindRunning;# {! }5 S: e: P) O/ p! i
}7 `1 B' H6 B- ^
" Z$ A1 `% J$ f' j: _) X' k; X
. j$ e: ]* `: ~6 X& ^9 R9 o5 b TRISTATE m_bUPnPDeviceConnected;! A/ a9 S7 ^2 u! V, r
% M; _2 {6 t# w4 Q* t
/ \" f' F3 a7 c+ P8 v// Implementation
8 R a) L, R3 h4 ^ H2 N$ _+ h // API functions" g2 ^4 A1 Y0 v& Z0 e+ E2 K3 I
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 K! {1 d) y4 G. G: }( J( l% I ^2 { SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
# s, U* F' R7 E3 s BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);4 o$ N! q0 `6 |0 B4 o7 P; @
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);; t: @5 E+ k9 Z# g2 F# |* s
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
4 m7 [1 r; k+ F BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
9 n/ M+ y3 b0 {( n; P2 [! W. Q+ r5 G9 D" {, b; r, j( \" v
; s* ~" B( i- u; g6 v$ J
TGetBestInterface m_pfGetBestInterface;
* P, n* T7 T* B& N/ l0 ` TGetIpAddrTable m_pfGetIpAddrTable;9 `3 ?, h- d" Q. U
TGetIfEntry m_pfGetIfEntry;
. c$ m/ O; P2 Q
$ S4 j6 e1 K) M* I$ v% H; \& y2 @% [5 ?! \" V$ @
static FinderPointer CreateFinderInstance();
: z+ B8 x. f* h" x( |; Y! ~ struct FindDevice : std::unary_function< DevicePointer, bool >( \5 m4 e3 A' Q' n5 }) y
{
2 v# C! P( N. l/ f& A FindDevice(const CComBSTR& udn) : m_udn( udn ) {} n) D# Z3 {# q4 r- g
result_type operator()(argument_type device) const- _" o8 V7 I" W( Q* K, {& ~( R) i
{
% r) F$ w7 o% A1 t9 Y( l$ y CComBSTR deviceName;' R# j* ?+ t: M% @
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
9 X4 C. t- ]0 ~: Y% i
/ E* Z& f- O7 r4 [: ]+ c, p
3 A5 n% F3 l# P) M/ ~3 b% I9 O if ( FAILED( hr ) )
5 G! ~$ n. ^ \9 O9 t/ z5 N return UPnPMessage( hr ), false;
& M! |0 J9 l h! |
4 S4 [, Z Y/ S0 O: Z, }/ f1 d. a* S
return wcscmp( deviceName.m_str, m_udn ) == 0;
2 _ e* ?& v F1 `' @ }9 D* x( `* C M! f, S, k, Y
CComBSTR m_udn;
# w/ j1 r0 p t' R: M$ u };
2 h' {$ J$ z4 I6 Y- `7 t- L
7 H% T+ E7 w( _" R, U- c; @ void ProcessAsyncFind(CComBSTR bsSearchType);
o3 _3 u: i( N/ | HRESULT GetDeviceServices(DevicePointer pDevice);- Y7 t! t6 v% G8 A, R1 e
void StartPortMapping();
6 a: _, a! }, Y8 K HRESULT MapPort(const ServicePointer& service);
- \* p/ } E$ G3 K" g void DeleteExistingPortMappings(ServicePointer pService);
/ F' T3 ~( P. I- K- H& n& B void CreatePortMappings(ServicePointer pService);* n9 x5 C2 q h
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; E4 M* v8 t+ p. r% W8 b
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, @8 p8 ?# |* m" @ LPCTSTR pszInArgString, CString& strResult);. Q6 F0 z2 O g* x8 Q
void StopUPnPService();
1 t; A! M& _# k
& u; A& d) I+ J% H+ L4 c% m) J
4 M. \) {$ ?1 a: O7 Y$ Q4 t // Utility functions
1 v; z/ t2 A' k# B; m& ?# E3 M HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);0 \5 w" Y* F1 L9 d" A: u
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. t2 q& m, J& v l
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
$ A3 @ l7 I# q, ? void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
% J0 i3 O4 _: J" L. o) j ] HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);1 }# e. }0 u2 a
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
3 }* V" j g% L6 `- ?7 n, V( u CString GetLocalRoutableIP(ServicePointer pService);
3 d& l6 n$ q0 t' U! p0 f, d, h% u) _# C1 F+ [( G- x7 Y- Q9 w. y
# l; i( c) b5 a. T8 o+ \
// Private members. s$ `! P- w$ ~6 U4 K/ J
private:
9 D8 v2 b3 m7 ?1 W9 y) y4 K. e DWORD m_tLastEvent; // When the last event was received?
" m) R7 L9 V E$ ~6 x. a: i6 p std::vector< DevicePointer > m_pDevices;! N2 f3 W% s9 J7 F. Z
std::vector< ServicePointer > m_pServices;/ T/ S' W: K; x, f8 ]$ {
FinderPointer m_pDeviceFinder;' q! K2 b5 A. K, m2 ~) |1 z! B
DeviceFinderCallback m_pDeviceFinderCallback; L( B' ^9 G% S- j6 m
ServiceCallback m_pServiceCallback;$ F" H5 @* R! T4 r, G9 ?
: }6 h$ D4 G" _/ ^
9 @2 M! N. c) S' j0 {( d LONG m_nAsyncFindHandle;$ ]0 x. L( R: x) r/ P7 i
bool m_bCOM;; S+ a2 }9 f* f: N5 A
bool m_bPortIsFree;, m$ }2 s, l k! t3 T" k
CString m_sLocalIP;4 m- m( J7 ~% A0 r: x
CString m_sExternalIP;) z% |& m- S* S, d- F2 }7 d
bool m_bADSL; // Is the device ADSL?' U/ ^, J1 c& d4 g0 A5 E E
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 n. ?7 Q2 s! L I$ T bool m_bInited;& _9 H/ ?: d x7 v# E
bool m_bAsyncFindRunning;
4 J: G/ [% U' G1 ^ HMODULE m_hADVAPI32_DLL;. s* h- g( g( |7 n
HMODULE m_hIPHLPAPI_DLL; Y; ]( j1 U5 m; n6 F( H1 y
bool m_bSecondTry;
" k! h1 g4 [" j0 N* l9 [! y X bool m_bServiceStartedByEmule;
, G2 F4 k- z% O* L; \7 y) F- t bool m_bDisableWANIPSetup;
& z% d# g- Y- T9 O bool m_bDisableWANPPPSetup;2 O; L+ e; J5 @. U; C! t8 {- [* f* V' B
2 a! l6 Z' k; M& @# Y% T: F- P3 P+ z9 \
};
" H0 Z! t7 {$ E# K' t+ ?% f) q) P3 V& N0 U
) T) G; `9 L* Z a R5 R7 ?
// DeviceFinder Callback7 H4 u9 l8 G) C& g
class CDeviceFinderCallback
; e& f) P8 y# B" H" C7 Q : public IUPnPDeviceFinderCallback
. r, N$ l8 v6 E1 N- v{
# H, R a+ }4 |7 F% ^( Spublic:) ~2 X: H w, f0 E$ K1 x& J$ n# b
CDeviceFinderCallback(CUPnPImplWinServ& instance)! v# H5 W8 u# x5 w$ z; y, T
: m_instance( instance )) X' m- s) F; A: g4 }" Y5 R0 U+ @9 O
{ m_lRefCount = 0; }6 M' L* m& h5 P+ x" V/ h2 K
8 r0 t+ V h+ c; d9 L
: M( Z* I/ }6 W) e5 q2 e8 q* C- h STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 e/ L* }" T: q STDMETHODIMP_(ULONG) AddRef();
: a r) e1 N" K0 H STDMETHODIMP_(ULONG) Release();
$ z8 _4 w2 O6 y5 R6 K$ M1 g! O! o& R5 n
0 R0 v0 Z. L0 z1 n2 w. H
// implementation4 |9 z- w# \: G! t- R
private:
: n6 J) d, p1 H* O$ n! \; @ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);1 d6 U) S+ ]1 E' _
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);2 p! O! A" W) N( L. J3 T
HRESULT __stdcall SearchComplete(LONG nFindData);) a+ ~! \$ _7 V! w
/ h$ g3 |' e6 [! p' j7 b
! _! l" ?8 f, b" `6 j5 O$ Hprivate:
; @1 w/ u$ o8 u& x5 K CUPnPImplWinServ& m_instance;: J% G" w0 m# [. j% B; M9 T# R1 e e- `
LONG m_lRefCount;" B+ m' r' U% i+ G6 g0 E, |
};- ?( \- z+ @- M+ h: L6 S
8 d/ C K) z5 e8 A/ `& p/ f) D/ S" i+ K! U
// Service Callback ! }0 n1 ]' O0 t4 G1 J2 s
class CServiceCallback5 V4 Z* f0 A; R4 L) u0 k
: public IUPnPServiceCallback
* G7 A$ E9 k: n7 X+ T{' f; l2 n+ m( M5 @ s) f
public:
; R; Q* w2 N& w5 K1 K u8 W CServiceCallback(CUPnPImplWinServ& instance), ?' F- [7 Q, w& r$ W6 W' C& G
: m_instance( instance )
+ F; E" _8 O% h { m_lRefCount = 0; }
. m8 o! g) u% H4 Q2 K $ k+ p& {; v n& x1 g( S- Y9 r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
, `& J5 ~$ ?7 j2 e, F& m# z4 W STDMETHODIMP_(ULONG) AddRef();
( f# z- U7 M8 e8 Y- p+ v STDMETHODIMP_(ULONG) Release();
4 w, m: M2 N+ T: i6 n0 t$ F5 h2 p4 F/ f, b" w( L8 E
( D. v2 H f! y6 N* m$ f3 S// implementation2 ~& b! s1 L4 V* P
private:+ V) R- W' Z1 e' R4 q. U
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);3 }, d h7 ^- M- L# }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
/ V% v1 ~3 A! c
% d: d5 ]; p9 o- f0 v: _4 g1 A; j2 E C
private:
2 w0 v& B& F. }8 n' L' D CUPnPImplWinServ& m_instance;
4 d4 Z9 m% N. N, C8 G! M( O LONG m_lRefCount;' x6 s, f9 E, v/ F
};8 X b/ E! |" h+ R
. \: {, w$ y7 o
" s8 O# m6 X9 O( j3 b: a( D/////////////////////////////////////////////////
1 P O( }+ y1 d2 ^( M9 [
/ d, R- f! @* s- Y% w$ h8 l, d- z* T( e9 A: }' K( n* m
使用时只需要使用抽象类的接口。
& Z8 j: M8 \+ G/ L& S( P" @CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% N( Q5 D7 m$ c" k+ HCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
) e, k* }+ q0 z6 M5 n; L( YCUPnPImpl::StopAsyncFind停止设备查找.
0 q6 [- g8 T- H- x7 l! ~4 e9 yCUPnPImpl::DeletePorts删除端口映射. |
|