|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) Y/ D- p" n3 `7 k% Q
6 Q! y' U9 ~) `; m5 l' D, T
8 b4 S: L" D l) B6 V
///////////////////////////////////////////
0 x' ]6 N2 V$ w. }3 ]//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
: Q4 v% t3 \) {" u/ T: `7 m2 ^: z' d
$ Z7 o% f7 x$ N' `3 G, H% M; w9 U4 @) A+ l
#pragma once
- L1 \% k+ O+ J& T# D8 \2 L& i: q#include <exception>
! t. G- I4 B8 k; o$ C) T0 q/ F) Y9 Q1 ?
8 y' \7 D2 v; l) t' @6 d7 r! v |% b+ B: y
enum TRISTATE{! ]1 W" ?* V# B
TRIS_FALSE,, J) L' D( @% n9 r3 A x
TRIS_UNKNOWN,6 d3 u3 Z! p r7 Y- G3 q7 q
TRIS_TRUE: L/ b2 Z( k- U |' ^9 S
};( V0 {: K2 r" u: _! S
6 b; e5 O. r) n, }- w3 u: e* G% f
5 n0 E" a+ A% D4 q/ Genum UPNP_IMPLEMENTATION{
" C$ Z3 H7 o6 O+ E/ e4 }# v' w UPNP_IMPL_WINDOWSERVICE = 0,
0 X: B- c8 w4 j9 [( G9 b UPNP_IMPL_MINIUPNPLIB,: w( b0 L7 R5 g7 P2 x5 \3 S
UPNP_IMPL_NONE /*last*/5 q" R) i, [* Y* O3 ?
};
" ^' a; @2 e9 z4 v, O; k* c7 ^% L, J+ r' X# h. Q0 D% ~" f* S( \0 \9 |
! w# z, d) f9 w$ V6 V$ z3 H: ?. V+ x* M
s ~3 g: D( b% {8 o( A' n4 oclass CUPnPImpl( o, e) G7 }2 k9 H2 w* V
{" q) l0 u) q" u& ]
public:' @8 D% |8 g. _. r4 w+ x
CUPnPImpl();
7 w2 c" {; S$ S6 L7 @4 \# p2 [ virtual ~CUPnPImpl();
, a. j6 A% T& u9 }6 c& j' W struct UPnPError : std::exception {};; @# b. S# O. Z% c4 y; T& n3 n+ M9 U
enum {
$ a1 O) A1 Y# s. F7 M UPNP_OK,
% E( y2 v$ o9 @ UPNP_FAILED,
) N. b5 y1 a2 e5 U) ~; ]6 f$ } UPNP_TIMEOUT
; o7 E( r. H: j( y [; X };+ }% h/ k0 W- v
/ c7 x2 t- ]" I7 _' T$ u9 T& ]0 O
' |) O5 U9 Z% k. Y, ]0 F" o/ S1 i* S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
1 y' B4 V; i0 c# l" W, X virtual bool CheckAndRefresh() = 0;
! s7 I. \: S9 ]3 Q virtual void StopAsyncFind() = 0;# @. N0 L5 x7 q2 c% O3 c
virtual void DeletePorts() = 0;
4 X2 q6 Z7 F) m& L virtual bool IsReady() = 0;" S( K: D2 ~* n5 Y
virtual int GetImplementationID() = 0;, [# I5 F2 G1 v4 h
* P, u$ b; E4 e' l6 v8 X( h
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
" P8 d. \1 E/ H8 n" T' V7 `6 G
" p! b( l4 S2 V
: j U' w' Q+ u- O% k8 B- k void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 \/ W$ x8 h/ N7 l1 E4 ^: S' o% V TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
! J! r2 _; ^- k! `/ k( [ uint16 GetUsedTCPPort() { return m_nTCPPort; }
( _! T' W" J! \. F uint16 GetUsedUDPPort() { return m_nUDPPort; } ! J) I/ {0 @4 V5 v$ ]
; _1 d3 S j* o+ p* \( o
# j7 b N: U2 z. `5 p
// Implementation7 b! r2 f7 n7 u7 {9 L
protected:. {, S3 M) ^. ]$ m
volatile TRISTATE m_bUPnPPortsForwarded;
8 |: `% c5 f4 I2 F% u( _ void SendResultMessage();' M: r4 u! g9 ~
uint16 m_nUDPPort;
5 X: \+ [$ v, y8 t3 J: t- @/ d uint16 m_nTCPPort;
7 m. q( @5 J/ _' \% t) r1 M uint16 m_nTCPWebPort;" L1 r& t* a% L: n/ s; v5 n) a
bool m_bCheckAndRefresh;
, q3 ]" w! W* R: a% R# ?
+ k9 L; G. U- `$ E+ I2 A+ `
4 d; y* @0 f. d( |) c2 I$ Hprivate:
) n5 _9 L5 M0 r7 N HWND m_hResultMessageWindow;# q$ z( n+ ^% U
UINT m_nResultMessageID;
9 d% m \+ l3 V. @6 o2 [& x, B
^# E K, U% g3 d4 Z* |4 @5 P
6 T1 V' a8 Y( C) y6 O; R7 e1 E' r};
5 A; m4 d9 o8 k; k' s; }
& n% ^' N2 V+ r$ C P( Y1 U
* p; v. } x! {" ^4 s// Dummy Implementation to be used when no other implementation is available ^4 F: p8 z4 O
class CUPnPImplNone: public CUPnPImpl
# X, L* g% v) J' o& q* N{
9 _/ f& @4 W1 h0 P) m9 \& L2 q( fpublic: k* r. ?! Z! g! ?' Z
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }. K$ d0 Z. ? Y" i' l- O* M
virtual bool CheckAndRefresh() { return false; }% `& u. }) h" [) S. o( x
virtual void StopAsyncFind() { }' P8 X& `/ f& q7 ]5 F
virtual void DeletePorts() { }
* b K9 \' K/ a0 h/ A9 R virtual bool IsReady() { return false; }/ |( U' b4 r0 H& d4 Z
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
9 H0 H. m% s- [6 G2 N};
0 R( D8 s& D& a: R: a$ S: `- q S: W$ Y5 j( d; f& f
3 O) Z' g5 \% e" m/ [9 t
/////////////////////////////////////
' X" q# S( K2 e; j1 {% d% X//下面是使用windows操作系统自带的UPNP功能的子类& j) R% ]7 v; N: W5 F/ k9 \
" ~7 L* B; `; w1 v' u8 ~3 b3 x: w R V
& `! ?6 X J" D- q#pragma once7 ~3 O6 N! \# j* o: I
#pragma warning( disable: 4355 )
1 | D' s9 b8 U8 l" P' J: A' ?, w% H( p
/ [" Q& w' B* M6 }1 ~8 M#include "UPnPImpl.h"
/ h7 ^2 P- v) w. v#include <upnp.h>. L: c% D l$ \) _& N% p R5 C) h
#include <iphlpapi.h>
?( l$ T+ K* L( l7 D1 [! h& A; T#include <comdef.h>! |) p( |6 K. p% b4 L/ i$ s/ @+ X
#include <winsvc.h>
5 F& \: t8 A- V3 s* Z1 p" i8 R) ?, S% x/ I5 T+ u
9 ?) r* B Z( E6 p
#include <vector>
" Q% R6 q3 B- T+ l) d. ] Z#include <exception>- H; f, ^2 t# F$ p0 U
#include <functional>8 Y- c+ d9 F! O7 ^, x& X0 b+ S
; {' c+ ~* j8 @! c
1 g* ^* X3 B8 \; H4 n" Z0 l; q1 M1 q0 g8 \2 c0 e
+ h# F+ O1 }% c* i9 X- f
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
1 w/ R P4 @9 ` z+ i: ntypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;% c& D/ ~5 m4 U+ q- {
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
8 l9 W+ M/ q3 T7 K ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
% |1 ^, m- n2 j) P, C7 ?/ htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;+ D3 e2 n! [' m. @1 {. [7 l5 m# g
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;9 y T0 {7 E0 h" _# R
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;$ X* H$ ]* D+ V4 ?, @
* R% D+ e8 Y& f9 E; Z$ U
: {8 v) s' c/ l/ ^9 v
typedef DWORD (WINAPI* TGetBestInterface) (. }: b; M" I5 N1 O7 n
IPAddr dwDestAddr,
, C5 L) C. l; r Y' E; j PDWORD pdwBestIfIndex
1 @4 ]8 J6 e' d$ A& z);; t! T; W' e: {5 O
) |, U1 c5 u/ \, Z' h
9 n6 x7 b* g. [4 `- P4 L/ ]% F% ?
typedef DWORD (WINAPI* TGetIpAddrTable) (
$ f% P; r9 z9 b$ ] PMIB_IPADDRTABLE pIpAddrTable,
# v. K" D) w$ g' W PULONG pdwSize,9 ~' [2 w- Z5 `! z5 t
BOOL bOrder" a" I! T" ]; y; |6 L9 ?2 L% x: ?! e
);
1 c: B' R4 i* |4 w, X9 A8 v) r; L* K' ^- L
+ s/ ?+ ]3 n: C8 V& xtypedef DWORD (WINAPI* TGetIfEntry) (
( Q: ]$ e6 D0 {4 r PMIB_IFROW pIfRow
4 |2 z. U3 C1 Q, k);
& z3 H4 C2 u9 B/ G# s1 E0 `7 q% V n, q( t: @: L( n ?1 z
- L6 h U- |# ]3 ?CString translateUPnPResult(HRESULT hr);
$ e) [% ]: S8 p( R7 @8 bHRESULT UPnPMessage(HRESULT hr);
0 F& o' l+ |6 A5 a# N& o4 Z c! }+ @ J7 y( A+ L; d" `
% M' s- A I% @
class CUPnPImplWinServ: public CUPnPImpl+ h: U2 @6 L" n9 l7 V
{. V% J/ @* I; l9 v/ B2 y% |1 v
friend class CDeviceFinderCallback;2 b& W6 ~* Q" M, x
friend class CServiceCallback;
$ S, d3 A, ]9 }# P q/ s. Q+ o// Construction+ ]5 c3 L6 k' l; h6 A
public:
- ?& X9 p1 G) H/ R. _ virtual ~CUPnPImplWinServ();
* L) M5 G; U* Q CUPnPImplWinServ();
% x8 l) U: c" J1 f9 \" E% _2 A0 Z$ Y
* }: }" R- A+ W1 d0 i
2 {; n4 Q3 S) E. `# |$ ] virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
! m: ^, C- `5 U) K virtual void StopAsyncFind();* C1 O/ Z% w: j. S0 ^4 P3 _) r: ?
virtual void DeletePorts();1 O0 ^/ S. P& I4 J: F
virtual bool IsReady();" G3 @+ J6 \0 G0 o6 _8 \9 M
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: P) l* m. P, |) H9 Z
. R7 S& g* a- g- s( Q9 c0 R6 m
& t9 F; I" A P# }7 c. L // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
) `; { R( z7 X% q // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; }0 A3 x1 c8 ?- }& H8 Y3 M, q virtual bool CheckAndRefresh() { return false; };" u. K3 T `- t' P% p% \5 M2 e5 T
: @; k) o$ E4 J8 p+ ?" l
0 C* I5 a& i) cprotected:
5 I4 S$ Z: g& X$ [$ `/ Y( e" g void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; }5 `/ z2 S) f1 x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ M8 K* |- M% s; M/ I/ } void RemoveDevice(CComBSTR bsUDN);* Y2 E5 B* ^- f4 J. }
bool OnSearchComplete();
2 S, @# s6 o- n void Init();
( g: V& G0 }) o) |1 [
& S ^" |5 ^- ?5 E- ~6 I8 P6 y
+ ~. S. I! ~( G L* I8 ^5 w5 o1 } inline bool IsAsyncFindRunning() 5 I ~. X' m" ]% L7 i$ f
{
0 K" `0 R7 ^: O, F: X if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )4 ~, E8 ~- M+ r8 D2 O- d# e
{
/ P0 N& U+ N: ^! j7 \4 _3 O m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
% [- A* s. G) h3 @1 c, V4 I0 Q m_bAsyncFindRunning = false;
, U. C1 |5 d) G2 ^% n }: ^; L. a1 e7 _8 W
MSG msg;) s4 h' \: ?) x; D: }" C
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 r/ T; K/ d& _5 c8 S
{
; A# ^5 n3 X+ L& ~2 P TranslateMessage( &msg );
. }7 I- m- Y& j. |1 c+ l( n DispatchMessage( &msg );# w+ S$ W$ |2 @7 h
}' g8 K9 g+ D% J, [5 u
return m_bAsyncFindRunning;7 q+ |- f+ M/ C+ h4 t
}
+ F8 K$ ~/ K! _3 ~# w v( H5 A5 T$ V1 \& E7 S2 }5 u
m4 B" P& C' Y% r, `) H4 j d, t
TRISTATE m_bUPnPDeviceConnected;! S4 e: ]' N# Z% M t- _$ L
4 B/ n( _% p7 N3 x6 H s
# G) _2 h* e) d+ c// Implementation5 g- w2 c4 h3 f6 g# T
// API functions) J# h; a6 L1 e- ^: M
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD); q0 p" b2 K; z4 X5 j
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
+ F, N+ { K. C9 M' ?' t BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
: C3 x& d$ B6 S BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
, \ i: S5 r7 ?3 s! s: `' K4 ?' l BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& R8 f9 q9 u, ~ f& O1 j
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);8 }4 R/ o/ E( m
3 A- Z+ a0 w z+ A$ _" B
, R- J" n) q, x5 } TGetBestInterface m_pfGetBestInterface;
9 A0 r7 ~% w% s6 I; R9 ^ TGetIpAddrTable m_pfGetIpAddrTable;& Z$ c. x" G) _2 T) r
TGetIfEntry m_pfGetIfEntry;
' d' ? f# [: g4 M" f6 P/ ?; M1 \! w: i0 U% Y$ p
% o9 W; o. R3 U) }! X' l static FinderPointer CreateFinderInstance();
7 B5 p1 T7 C0 s0 L$ ~ struct FindDevice : std::unary_function< DevicePointer, bool >
/ K6 |5 M8 o) C# `4 i {3 F: o* B6 C3 R; v
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
B6 @' x5 U! @9 B result_type operator()(argument_type device) const
, C% A* _3 W4 \ {/ y8 {7 F8 a' d( I( h
CComBSTR deviceName;/ V/ n. z \3 ^( Y, ?) ?* T$ y+ S/ Q* y( [
HRESULT hr = device->get_UniqueDeviceName( &deviceName );1 n$ C: F5 g; m; h! |- G
# L- q% q' ?) [* ~
0 I# D- L' P8 A
if ( FAILED( hr ) )5 j2 w- e Y i- v8 O" {. k: v
return UPnPMessage( hr ), false;
r. b# i' }$ _& u9 r3 q
8 t% ~* R- {( D+ ], \ u$ k; f
" |% \8 k/ v4 Z; O9 @ return wcscmp( deviceName.m_str, m_udn ) == 0;
: K' R" m$ c; F$ m8 l }
: O: J2 y8 s$ W7 X$ B CComBSTR m_udn;
8 @( H4 E; F/ S; T };
5 ]0 \! Y. n* {7 K/ O8 Q
6 l9 f! M* {/ }7 C6 P4 h# y void ProcessAsyncFind(CComBSTR bsSearchType);' ^$ {7 o7 ?( t7 [* r: x
HRESULT GetDeviceServices(DevicePointer pDevice);
6 F2 H" u/ U) U- F1 L; w& t void StartPortMapping();$ @0 U7 p! R9 M
HRESULT MapPort(const ServicePointer& service);2 S, w6 l# J. r( S) a
void DeleteExistingPortMappings(ServicePointer pService);" T0 K% K& Y0 K+ N% w
void CreatePortMappings(ServicePointer pService);
/ O$ R2 V8 X/ u/ @' o, q: V9 L% y8 V8 c HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
4 P0 n/ u* B$ r9 L HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
" M, ]2 Y2 [, v; s& {! E4 B LPCTSTR pszInArgString, CString& strResult);
/ b0 W* M& f8 n" \( ? void StopUPnPService();( x6 X) F6 O, F) I+ ]1 |3 }
* }: N! z7 e o1 `
; g9 k! [/ y2 S* R' B3 E1 v; S // Utility functions6 X z3 D% z6 y- ~
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
) A" G, d/ q/ j8 a$ A: C9 j8 g INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);+ v) J# K' f, M* ^8 H* ?
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
3 m+ E2 L1 w! c) C7 e: u' G% y7 S# j void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
6 n' j6 E$ k, E# v* {! X HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
+ R* {- A7 J5 G3 K HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ [- \: D5 [5 v# H* k CString GetLocalRoutableIP(ServicePointer pService);
5 F" X8 Z7 D- O; [& O3 A" ~8 p. J0 U5 y
6 |1 \% w) H5 ^ l" |1 h3 W7 ?. |2 U+ F
// Private members
: B5 p) d- k% hprivate:7 z" D- _7 w3 V) r4 i* v7 _
DWORD m_tLastEvent; // When the last event was received?7 F) W1 m7 `4 K2 b% K6 ^$ X5 m9 `8 L
std::vector< DevicePointer > m_pDevices;6 s( X4 [9 p. i- ~; ]& O
std::vector< ServicePointer > m_pServices;' i! M$ p: u# u/ t/ D9 C, I
FinderPointer m_pDeviceFinder;
& C" m, x' S/ J b3 K# p1 I DeviceFinderCallback m_pDeviceFinderCallback;/ o; n( \, n3 T0 h
ServiceCallback m_pServiceCallback;
3 N+ L; P Q6 T4 j! l" b# i$ R5 H0 z: T. }+ `, ~7 D: M0 K
' Z) J! L7 A' N7 n7 q
LONG m_nAsyncFindHandle;
- c8 n9 o' L5 }# E bool m_bCOM;
# }& {* c+ J6 l8 m7 _0 R5 P bool m_bPortIsFree;
* ~2 O: D* x- Z0 v CString m_sLocalIP;* }7 C( m; L# T4 H
CString m_sExternalIP;8 G0 r/ L& v0 p: J$ o% @, y
bool m_bADSL; // Is the device ADSL?9 x2 c4 W3 }( ?: B7 }
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?" x# o6 P" }, g9 E
bool m_bInited;
! K& ` B" M+ X6 V bool m_bAsyncFindRunning;' j# j/ @# i* C3 d
HMODULE m_hADVAPI32_DLL;
5 A- }% Z# r% M2 _ HMODULE m_hIPHLPAPI_DLL;: U9 W9 A, m8 M" j9 }
bool m_bSecondTry;
/ Q- q E, c G" [ bool m_bServiceStartedByEmule; N. A4 k# e1 I& e+ d$ v
bool m_bDisableWANIPSetup;" L9 _. y" f4 F2 Q3 I* L" ]
bool m_bDisableWANPPPSetup;7 C+ x3 L7 s/ ~: H& ?( p
8 [. B$ y4 p# _( @/ b, _( n
9 @+ X) R: n* {
};) y! f5 T, ?+ n3 e/ B1 }5 J- ?
, I/ V6 [' ~3 x
* t3 u$ `* p. l8 h# m8 L// DeviceFinder Callback3 j2 o4 S& o! Q c% ]: q$ p
class CDeviceFinderCallback! p5 }; W$ K" Z; _4 u
: public IUPnPDeviceFinderCallback
- o4 j( P% n5 J0 ]* a, [" e1 s{
/ F: S" a8 r# ^# b! i [% Jpublic:
0 ^$ E; B. X, Y CDeviceFinderCallback(CUPnPImplWinServ& instance)/ b; a$ Z( a' d. R4 M* K: x
: m_instance( instance )
& k1 |# m6 R8 k* S/ b8 Z, T- U2 {, g9 S6 w { m_lRefCount = 0; }
4 ?) J3 {5 S8 C1 o
( Z; Q; t8 t' j
( ?4 b' i, n" ~" d p' C! p STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# [, U& G- O {. y5 T7 B
STDMETHODIMP_(ULONG) AddRef();
8 p$ C" W& @, o# X STDMETHODIMP_(ULONG) Release();
. b7 Q' R1 K) M! c$ @4 p. r8 R
8 ~) h: p/ Q3 S3 i# W0 v
+ R3 |1 u9 J' Z4 G// implementation Y9 W" l* c9 G+ g: c6 U
private:: [: L" w ~! K' ]
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
5 b; {+ Q6 K2 g, ^" W6 y0 W. C: U HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, ^4 G7 C/ s% f& V
HRESULT __stdcall SearchComplete(LONG nFindData);) v( P* {' [$ E3 f, }! _( f
7 ]6 A8 _& W& z) y/ b& `' O: P( ~# `/ @" | {7 t
private:
/ m1 A1 T. F- q m4 c! E# a CUPnPImplWinServ& m_instance;
: Y x4 i/ x4 g2 b LONG m_lRefCount;1 P5 B. L" G* C/ _) t
};+ l3 A8 W' `1 l
9 T# E% L/ I! G; e3 `' Q z! Q: Z, S8 I% G& _4 g8 w
// Service Callback 5 K$ N9 o: U6 R0 A
class CServiceCallback
6 N7 F. O+ @; E8 L : public IUPnPServiceCallback
% V6 S. Q4 f8 @{
( m3 N8 Z8 ~9 A6 U: @/ A. Spublic:9 g/ y4 \: M- o( {
CServiceCallback(CUPnPImplWinServ& instance); h# {; p3 }5 ?
: m_instance( instance )4 S9 o6 t3 `; y4 P! L
{ m_lRefCount = 0; }
1 h0 b, n3 W$ D$ k
% j7 S" H3 r3 ^( z! S! D+ \ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& \/ z7 @0 S6 \8 K STDMETHODIMP_(ULONG) AddRef();
. k& v) H, N h0 X1 ], g STDMETHODIMP_(ULONG) Release();7 u0 f$ B% h% d3 n/ P8 e5 s
9 ^ u" E3 I, Y' G
' \, U: X& W- C# l. D. [// implementation
! ^& m! J4 s, p3 r8 mprivate:
0 j5 t8 Z: l! c/ | HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);" m! j# O. s' |) w
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
- d6 m4 W, \0 X" e- t( Z ~! E
- Q: K8 S0 q7 i/ P' v( i& F" P' S7 y. M/ u* S
private:9 x5 |" m. C' v+ b/ G' l m6 x
CUPnPImplWinServ& m_instance;9 z+ O& h* ?1 U5 J: m# c
LONG m_lRefCount;
4 x. n7 Q y! Z: I4 |8 E}; i9 w& E- y( E9 C# l7 U0 N
- T! K& Y3 h# L! s
7 z$ m5 d' X9 ^4 B6 b/////////////////////////////////////////////////
& f' o9 X- `( G/ s/ {; B! f ^: @) a4 G: P F- _. ^* z
6 b. h9 }# V1 p& ~- f1 D, h( r使用时只需要使用抽象类的接口。
; e5 [& {1 I9 X! yCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' i6 s7 p& K- C6 @: _0 A1 SCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
5 s1 H! X# |# k0 O8 D/ i8 ACUPnPImpl::StopAsyncFind停止设备查找.& a u: U+ ?4 f& N
CUPnPImpl::DeletePorts删除端口映射. |
|