|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule," v# y8 d" L: E c& v2 f
3 ^6 i0 I, b, k9 C6 Z$ p
3 h; G( F7 c0 l( [) k///////////////////////////////////////////& B& e$ u6 g i, O7 T
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
1 g3 `! F7 u3 X2 E/ ~1 }# T4 J. K( ~+ W5 I" h/ y
1 S; A) `/ G5 D
#pragma once+ m% q6 m& I! J1 l3 ~ ]
#include <exception>! _+ l. z8 E- i1 ~
" Z4 t. a4 w, x9 t/ Z" n' X0 h- h" D3 \, c i: i5 v6 P
enum TRISTATE{* k. C# z6 u( A5 w+ u
TRIS_FALSE,
: u" j5 Y9 Y4 t C. B3 S TRIS_UNKNOWN,
) ?0 k4 M7 {' P+ H TRIS_TRUE
: P& ?6 S P. C$ q};6 D$ Y2 k: z/ \1 _+ Q
1 { E0 D! k2 V
7 q9 Z9 q; k( p5 d/ v' N
enum UPNP_IMPLEMENTATION{5 H7 Z( l/ G4 x, }
UPNP_IMPL_WINDOWSERVICE = 0,: J0 g& k/ d# L8 h" g
UPNP_IMPL_MINIUPNPLIB,
- U5 D8 u ^& M% N UPNP_IMPL_NONE /*last*/& r+ W' ]8 z* a: }
};+ H# M8 R4 \; ]/ g, a6 [
) G: s* w; U- e) Y7 Y
0 I! Q0 [1 B3 q/ T' B# b3 \0 P4 b* x% I8 l8 C- N
% ^; ` u% v: I- @% p# c
class CUPnPImpl( G' U1 e9 y! d5 s
{$ X5 P$ m( Z, G' ]
public:# O+ u5 q# p5 G' {! X
CUPnPImpl();' G6 x' e9 C d$ ^. i4 z; q
virtual ~CUPnPImpl();
N {8 |2 Q1 W) E- X% w, w1 a struct UPnPError : std::exception {};; r' }( f1 D) M" r0 W: ?* x
enum {( x! ~( D; A2 a% A0 A# k
UPNP_OK,! ^7 @6 o1 t( O& i! h; y6 i
UPNP_FAILED,
( P% n8 a0 L( X% P& u6 x0 U2 D UPNP_TIMEOUT
) Q; W; h2 l$ j2 S1 { };
: b) e" n0 f1 d8 @. S/ E/ g% b; G2 k8 j9 v, H- X4 q
7 }" q4 b- C* W+ w0 W$ y* N# x& M; R
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
9 ^2 Y# f% E2 m virtual bool CheckAndRefresh() = 0;
3 b X9 h% p. ~9 ~1 t! [ virtual void StopAsyncFind() = 0;% g+ R6 n( q7 ^2 x
virtual void DeletePorts() = 0;5 v. u5 |! Z6 |2 b) I2 s9 Y
virtual bool IsReady() = 0;
% P; k! @' j3 P$ F# N) B ?/ p virtual int GetImplementationID() = 0;
( z: s. {% n! m& f
8 `, {. n% e q H void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 S/ t4 m8 K; X1 \' e" p. ?4 o4 K% E: G1 m) m
% j) o1 ]3 ?# L8 i- G& B' A
void SetMessageOnResult(HWND hWindow, UINT nMessageID);6 p. n3 ]" E8 i0 |, U
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
- V$ v, D L) z uint16 GetUsedTCPPort() { return m_nTCPPort; }; ~9 C3 T; B2 @& C ?8 c& R4 `
uint16 GetUsedUDPPort() { return m_nUDPPort; } # y/ R6 N2 Z3 Q; ]; U+ n/ q) R* ]
1 z7 W! r' H% i0 c. `$ ]% T1 t, ~
# q& C& I# v& P5 Q! w// Implementation7 c" b5 Y9 G; i7 ]
protected:$ K$ p* E) q8 M
volatile TRISTATE m_bUPnPPortsForwarded;
* C' ?' b; H2 W& \5 z( L void SendResultMessage();
0 S4 O# ?! b$ }2 m% Z7 [: h uint16 m_nUDPPort;
: F+ I& q6 ^4 ^" ?. p# ]& Z uint16 m_nTCPPort;* j( C7 r5 o( W2 w7 h
uint16 m_nTCPWebPort;
* C9 @2 Q5 B% A5 y# Z2 I- v bool m_bCheckAndRefresh;
. `" _/ G6 ?1 w5 P; |3 c0 i
& ?% K/ c4 |, l6 K' h/ m$ {+ A
7 E7 b* a7 @5 U7 G+ E1 Oprivate:
, e3 t% s G- p" s HWND m_hResultMessageWindow;$ t, W$ G; _$ E" b; C1 C: }$ j% Y7 Q
UINT m_nResultMessageID;
7 b+ v- _' g% W' P. @9 Y* B, g! w; m' N- K
( s4 ?/ J7 |" l$ m/ x& ~& Z. Y: h};
- Z9 j5 I; j( w- a4 p
" l. ]) [& ~: B* \
+ x& M# H- S7 M& U- {; u& V7 k// Dummy Implementation to be used when no other implementation is available
% ~$ f7 Z1 X6 \+ Rclass CUPnPImplNone: public CUPnPImpl1 y0 Z7 t5 T) o/ @0 q4 E' j1 b v
{. q! J9 f& U/ M e) u, q
public:
9 z2 J) y& ?2 z7 P& g virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
8 l' e. [+ m: S* H# ]" V virtual bool CheckAndRefresh() { return false; }. S2 E* l% p* B+ k Q; @% e
virtual void StopAsyncFind() { }
8 y7 J. d3 H/ n5 q0 z9 B virtual void DeletePorts() { }
: B8 F, K- i( u6 D2 m3 A virtual bool IsReady() { return false; }) O6 g, r+ v, n1 |8 F ^
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
9 r4 j6 s! l) G4 z};) K" r' D, B2 H! G0 b/ p9 E( V
6 D9 V# l8 n: v7 P8 B
7 d9 v1 T/ g- @4 ?+ ?& B4 F1 p/////////////////////////////////////# d! U- w3 G ]3 z) `+ }' U: m, R y" R
//下面是使用windows操作系统自带的UPNP功能的子类( l! h9 m7 g" M& s4 s( z4 L
3 k. P5 T. x7 r0 [8 j+ v0 o+ E; [3 `2 ], @; {
#pragma once
0 `$ n% a5 h/ j0 p, A#pragma warning( disable: 4355 )" Z' W0 i, D0 z9 w; x/ d" O
7 x$ ^: v/ C4 Z( ? V
4 B( [, s. G9 c4 H) W( w- ^( J#include "UPnPImpl.h" F% S6 ?7 m, E7 \" B
#include <upnp.h>
( v, z1 n7 n/ a* K8 z0 S#include <iphlpapi.h>
: Y, n- l5 B! X: x0 Z. u8 q#include <comdef.h>
' D8 M2 A V4 s) w K( H; S3 Q#include <winsvc.h>
: L0 r$ x: v7 H2 [ Y% u$ L6 Y. p l1 n* l$ ?
3 ?- F" x2 r7 M) u5 z. L
#include <vector>0 z9 P: w' U/ N
#include <exception>8 v& j5 A( q% A. M' }& c) K
#include <functional>; G' \3 O1 q% x' e: B! i* q$ f
$ u. w2 x0 @( _2 c2 \9 }# ]2 d
A% A0 ^% z* |
1 x! M' l6 k1 ^; Z3 V
9 t% r7 Q- v' A# S3 Y% n2 @- Y4 m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
$ x1 X& d; q: l8 d4 _7 t, G. k1 y6 Ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
0 [$ k$ p! u- I. N+ B1 } Btypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ j3 J8 {1 W+ V' Dtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 S3 ~% T! d& G1 b& T M! z9 K) @typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: r* E# ~% u1 j
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 y5 P2 q+ s. o1 o
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ ? h# Q$ L6 _
; v' ^: C# W3 Z5 \) k8 V; E
1 _$ @- r9 [2 J$ w/ _2 n
typedef DWORD (WINAPI* TGetBestInterface) (. W+ b& j- a; j- A
IPAddr dwDestAddr,
, M" r t( q, V/ l6 A4 ~) s" L PDWORD pdwBestIfIndex2 R% t9 |# S |8 @! S3 ]' i
);
* H) p0 t' ^5 I& m0 z* N
) y3 d2 a" |$ @# e/ U/ ], n
4 ?$ y5 ?! I e2 t9 stypedef DWORD (WINAPI* TGetIpAddrTable) (/ u& ]0 i9 ^# }# `) m
PMIB_IPADDRTABLE pIpAddrTable,
+ f6 z% h$ M5 ~0 s% Z PULONG pdwSize,
& T& q- j$ Y0 A' v BOOL bOrder; }. l( W2 D' Q% B/ U0 T* b
);
4 d3 M: E4 `( l9 F
6 U! h( n E$ ^7 N9 w8 C0 g" y% K. n& z8 M4 d/ X4 I4 _/ }. t
typedef DWORD (WINAPI* TGetIfEntry) (
3 C& N- S: F: t PMIB_IFROW pIfRow$ {6 ^2 `! O& {- w- M
);
" E5 v0 M4 @: K* q% E; G) y1 f. S9 p5 H2 r. |
2 |( }7 W; e8 i. ~
CString translateUPnPResult(HRESULT hr);5 _4 b% F1 ]7 N- x
HRESULT UPnPMessage(HRESULT hr);
+ R1 o0 g7 v4 R' h1 a0 X# \ C
: {0 _ l. p: E4 @% g1 [+ |) e) x4 ^+ d$ p
class CUPnPImplWinServ: public CUPnPImpl
, h7 R9 j9 T% o8 q9 W# t6 P{
0 V: A3 b! F% [ friend class CDeviceFinderCallback;
) ~) R2 p) m4 q2 d1 x friend class CServiceCallback;! F+ o/ T% X' k7 Q/ H+ g) [! Z, x
// Construction
$ p- m. v! t+ G: W7 Bpublic:! _% i- G+ ^& Z/ N; K0 d$ j
virtual ~CUPnPImplWinServ();5 J' o. u3 p# u/ B3 {& L
CUPnPImplWinServ();& j& o. a0 A/ H
0 r' z9 H! D$ T6 M& u$ A4 O
1 R7 d- c! Z7 @7 x virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
5 J; {3 `9 |+ M6 I P/ d* G9 S virtual void StopAsyncFind();0 n9 L& E/ W& Z- a& T
virtual void DeletePorts();% _; o+ e- c# f2 U/ u6 o9 @. m
virtual bool IsReady();
6 J" c1 P, L( e# x: M virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: l, s$ I) {5 T1 t; |
* ~. D9 M2 P. w% u7 k
! A2 I* L8 R6 M4 o1 Z6 R7 }. e // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)" s$ U# `. u' E* p) s, J0 o' f
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
" S- {) {0 Z, }1 k( d6 ] virtual bool CheckAndRefresh() { return false; };
& |! n. ~3 V: t; W+ o; p i4 |
3 e8 r- n; A- [/ z. W# _! W3 c& i( b, a$ i# ?* P) T7 L1 }+ c
protected:
g) u+ o6 i |8 C void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);/ R9 W0 p4 y+ E6 x, `% R
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ Q5 ?; e/ A2 T4 F4 E. ~ void RemoveDevice(CComBSTR bsUDN);) `% o' t8 j" S& c$ r
bool OnSearchComplete();# x4 m5 F& _' F0 y4 K, `- ?4 Q
void Init();$ b# }8 s3 A5 G2 S* v. I# C
9 v1 E5 w7 n+ {& t' i# u& o8 `7 l( \- n4 _; `0 r7 b. L: X
inline bool IsAsyncFindRunning()
4 o8 F F- {- P+ J7 d7 V {: E5 L$ K6 V6 k8 P C2 N
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )4 t N% ^0 @2 G6 ~7 O( y$ [' [( q9 ]
{
: ]4 ?5 V9 y3 W6 \* A+ j% H m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 }1 p `" X( o3 Y" \8 j6 M% j
m_bAsyncFindRunning = false;" L. ?# ?: u1 s2 Q3 e/ T9 A' B
}& t* \3 |9 K9 O; M( b
MSG msg;
; z) ]2 H3 f5 d9 p# D while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
' b' d% Q/ f+ m) ~* n {
' `/ I9 X {3 m& M9 [% X$ t( _( J TranslateMessage( &msg );3 y' u5 |. c/ B( d( o# i6 q
DispatchMessage( &msg );
- b) u4 O" K- y/ O; q) M, J! n }' V& I5 p4 g8 C6 X( Z0 B- l$ t
return m_bAsyncFindRunning;1 |4 D9 l" _' b. f' Z* {2 r2 V+ L8 C
}
1 O$ F9 {" {3 F$ b q q! S8 t4 f9 f" n
i W+ a0 c- b% h: j0 m8 W/ d
TRISTATE m_bUPnPDeviceConnected;
* Y! E9 P- }; T3 U# z! H3 [/ @3 T* _4 {( N$ ?) q$ o
4 {5 j- C# y. b// Implementation
- c4 {7 U- H7 O; B" ?6 K8 l // API functions
: @6 x- S9 ?$ J! W3 I SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);) [& L1 {7 i3 i( R
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
, f2 x$ Z+ h& g5 C9 b/ A BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);# D; z) h. l' H: o8 ^! ]% O
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! z- S* s8 u4 V* b) p7 |* G) W BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
3 x, L! Y5 s- R0 z5 [ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
0 |" R! m7 K g1 b: Z4 C4 I, ^! Z
# ?9 O0 Z0 _4 }- D1 l- D+ G6 p8 H, {6 B& s7 H# ]
TGetBestInterface m_pfGetBestInterface;
. E& J3 N! k9 R S) J6 k% j TGetIpAddrTable m_pfGetIpAddrTable;
* x* Z6 C! z) A% X4 D0 a TGetIfEntry m_pfGetIfEntry;) o- Z) a; h8 }7 I5 X) n, f* g
: ?% } V- x' t. {' h
2 X; S/ k: R9 V* H n) ~$ C9 C static FinderPointer CreateFinderInstance();( h! b( f' [! ~5 ], L
struct FindDevice : std::unary_function< DevicePointer, bool >8 Z! {- @1 _6 O7 e3 Q% Z
{
& R" K, r% m6 M$ H. ]& t: S3 K2 Q/ j FindDevice(const CComBSTR& udn) : m_udn( udn ) {}5 B4 w& |# W/ O
result_type operator()(argument_type device) const5 j; [. d4 r4 q. q( T" T6 W
{
; A; }5 Y, f, w* S9 B CComBSTR deviceName;2 P. L! C: U& e7 V
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( R; j1 V# n2 m/ J; z8 N
2 |2 E; X, B2 i' S. ^
. v. g: F9 N) q if ( FAILED( hr ) )
) j! F" c" ~6 n return UPnPMessage( hr ), false;9 i e! ?0 Y( Z3 g) o# z2 u$ e9 S% k- s
$ a& t8 T( Z9 ~( _
- f5 r! H" `6 v' | return wcscmp( deviceName.m_str, m_udn ) == 0;
5 `- X9 L& [" S6 ?# Z }5 P$ b3 M0 h# ~1 O! O, ?+ r
CComBSTR m_udn;
' V$ V' T' i8 N };3 K2 y2 t" t, W' `+ K2 W
5 l- g: w+ W+ @ void ProcessAsyncFind(CComBSTR bsSearchType);" P" V! t6 E* x+ g* N
HRESULT GetDeviceServices(DevicePointer pDevice);
" g+ I- D+ Y0 \7 U- t; c void StartPortMapping();# w P3 u4 N3 X9 ]/ }# \
HRESULT MapPort(const ServicePointer& service);/ O/ y q+ M s3 w& G' w
void DeleteExistingPortMappings(ServicePointer pService);4 W! U1 S$ K& j, ^6 ^; X
void CreatePortMappings(ServicePointer pService);8 f1 h s g3 j, `% i
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ V( V4 u2 O" K% j HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 _; m2 F- Z c1 ~$ p5 I
LPCTSTR pszInArgString, CString& strResult);: y' U, W2 x4 l3 g% g7 v! F
void StopUPnPService();) L& s# ^ y4 g( g! p( q+ f3 X
" W3 r4 B; J# e
& w9 s, R& S( M5 K" b7 U/ P4 t3 ]( r // Utility functions
" E' K( U$ A/ b0 Z" p* f+ j HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
2 I4 \; M7 X9 o; r& W3 u6 P* a INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 {4 t g, k" I# \" F9 g, N
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);& J. Y! ]. _8 P
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
, S4 R! m9 g2 u' Y/ s HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! G3 F2 T3 M7 C* K% E HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);- T: b" c9 M# U$ w2 t* i
CString GetLocalRoutableIP(ServicePointer pService);' O% j; u; s/ Y: R0 M' `# F# _# f
3 {( C- f# e' h Q5 U9 z# r7 x" h: Y0 h! R
// Private members
" q- D7 t9 X& C, z+ n: [private:
2 k6 n$ x2 y/ m DWORD m_tLastEvent; // When the last event was received?% h8 Z4 |6 F- C: I( W% y+ A
std::vector< DevicePointer > m_pDevices;/ \& ~ [5 ?9 g
std::vector< ServicePointer > m_pServices; z+ f4 [; J+ Y
FinderPointer m_pDeviceFinder;
" T, g! g$ k6 K: L Y DeviceFinderCallback m_pDeviceFinderCallback;$ e3 c3 z1 B" [( t1 d
ServiceCallback m_pServiceCallback;
+ F: s% e* ~0 S7 O: E; }7 c I4 S# X! D) X! B* M
; K! ~* s0 w1 m8 j
LONG m_nAsyncFindHandle;5 L8 r& ?* y0 ~
bool m_bCOM;
3 u( f) T1 x% k* F! B bool m_bPortIsFree;
; N0 n3 t) b( z; X CString m_sLocalIP;
: Q& H, H/ f/ Q CString m_sExternalIP;
5 _. p4 v1 q+ N bool m_bADSL; // Is the device ADSL?3 w( E6 U' b3 G! O' p4 ~
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
, a6 `5 l9 a. [ bool m_bInited;' k. R4 m8 c" z5 N2 ?; X" w
bool m_bAsyncFindRunning;5 {& W/ Y# y" _$ U! N
HMODULE m_hADVAPI32_DLL;
8 s6 B) x; z/ ^ HMODULE m_hIPHLPAPI_DLL;4 h9 L* [" C6 m& B* V" b
bool m_bSecondTry;; ~, j3 u: i3 n( F; a% G3 m0 }
bool m_bServiceStartedByEmule;
$ Z: l# G4 @4 j9 @! m: ~# g/ y bool m_bDisableWANIPSetup;4 K7 l% A' G k1 Y( L- s1 X1 F( H J
bool m_bDisableWANPPPSetup;
7 x( `( v3 Q5 M E/ |4 r4 R6 v, \; N9 U' L$ h$ P
" d) N. o" `1 q
};# r2 G2 ?$ }% O4 e; T! e8 J- D6 Z
, e. I7 c; s' @7 }! q9 P
* ` a9 C. I; ?; |3 `. v# z// DeviceFinder Callback
0 ?. P& U' K: c ]% [' Uclass CDeviceFinderCallback
4 E- L# r! t+ Z; Z* J5 C : public IUPnPDeviceFinderCallback
' v1 D' c7 n: D' ^# R0 `3 e5 |{
1 \8 [3 [9 r) E- e% Dpublic:
9 e4 y6 b* v4 q! P4 u! H CDeviceFinderCallback(CUPnPImplWinServ& instance)% H, X( u0 a% u4 L) r
: m_instance( instance )
}4 q; Y1 d- l. s& ?- | { m_lRefCount = 0; }
' C8 F1 H" t: R- e$ C+ H0 X& x0 k5 [% u- f7 S
, \/ R% I. h' z2 Z# | STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 m4 N2 v# l% g9 K- D }' k% _. e/ [ STDMETHODIMP_(ULONG) AddRef();0 X* i+ `; C7 M H) Z
STDMETHODIMP_(ULONG) Release(); W0 m2 H. f) }, O) u7 n; h9 m3 r: B
7 g$ n# b' `: l" A3 K
8 Q. p' e/ p. ]' e// implementation
3 e/ \: T. t' v( D$ Kprivate:
: ^9 }4 j2 f) _. J& ?* A6 S J HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 F- I, t) t7 m/ T3 y HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 t) X* o1 D! |5 `$ Y
HRESULT __stdcall SearchComplete(LONG nFindData);
) C' J) s. o, P2 R! ]% s- {3 C7 J
4 W6 y. ?( v( Z0 x4 N' `% Z' e. |9 U/ f: o2 `& n& X
private:2 o* P: m6 r) W4 t* y2 ?9 x
CUPnPImplWinServ& m_instance;" `4 c# A$ r$ y
LONG m_lRefCount;/ C; K& P" I2 _/ u
};
* \' u- k5 r) ? K8 N( S' S2 S* O$ ^9 O9 l
; H8 M# [8 {6 s8 ~2 [// Service Callback , H8 v% w& d7 O- y. u2 B
class CServiceCallback
8 B& U) c! Y4 ~& R7 [: y+ q : public IUPnPServiceCallback. O+ B% Z. q8 Q
{
4 ~9 w L ]! E, Npublic:
& v$ A+ ]$ ^1 o' b N CServiceCallback(CUPnPImplWinServ& instance)$ Z1 R( |0 N& X' X: ]) r* d
: m_instance( instance )
$ {, I0 G8 ~6 y# Q7 E- B! U { m_lRefCount = 0; }3 h, V, o% c' S, H2 c% W" k5 W( i% g
, I" G. g& u( A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: l) f! |; E: P6 o4 O- N STDMETHODIMP_(ULONG) AddRef();+ {) W8 @5 P: R+ N9 }
STDMETHODIMP_(ULONG) Release();
8 r$ H- u0 v1 ]5 X# Y) t0 w$ V$ g. e+ Z' n! v
* N/ }) Z; u1 d9 A3 C
// implementation
( O9 l# d8 F/ E; c+ y7 s6 Iprivate:. N" m( K5 d" a5 z3 b% v
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);5 V. Y5 x9 q3 x! e* C$ V
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 I8 r6 E5 O6 e
5 o0 d4 j" q/ E9 X
( \/ i; S; A9 f9 @) U: Z; U/ kprivate:, I4 l: ]' C; b8 _
CUPnPImplWinServ& m_instance;* Y0 n+ N: i7 h% F" Z" j2 i- i: R
LONG m_lRefCount;
9 X" p0 \, m w+ m};
) j/ D/ m8 t& s
$ X$ W. m' n6 H4 a e/ b
# k% _$ k9 e$ D, U1 z/////////////////////////////////////////////////# L! [/ L6 K/ J3 S
6 `( A( n; D$ x; @- L) L% R+ u
. X& _+ A0 A. Y6 u; J+ v/ e0 z3 u, s使用时只需要使用抽象类的接口。
$ ^5 y! j* C$ @4 |6 P5 LCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.( P' I8 C& w" g$ ^% K& o
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.: x6 {3 t4 _7 {" `5 }$ S
CUPnPImpl::StopAsyncFind停止设备查找.& p+ C) S2 C/ T& Y
CUPnPImpl::DeletePorts删除端口映射. |
|