|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
+ j. z: ]* N4 H1 i; o* o/ `, t$ Z; N% L+ H: X, P# z1 F" C- J
. l! b9 t9 j% L& o, t- {' V///////////////////////////////////////////
7 j5 Y0 n3 A& Q, {$ I a& m//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
, F5 T( w" z) }+ A& H9 P- Q; H! ~# f5 i& q
% g: N& ^: W1 \8 V% `#pragma once# [! V$ L, V5 N# u6 ?5 H
#include <exception>
7 x) \4 W# d$ t/ o& M/ D# d" l+ R) X4 P6 Q( w8 x( s
$ f( | H9 b5 N7 ~
enum TRISTATE{
! ]7 X/ T2 N* Y TRIS_FALSE,
3 G% H" L, k9 S9 t; t TRIS_UNKNOWN,
2 f$ F: e3 f2 ?4 _6 D$ _ TRIS_TRUE
2 |4 s4 W4 p8 ^) [' B+ K};
$ `( B) p3 h$ q) s4 g8 y3 S
Q$ p' m* i; m2 S
/ z& N. y$ q4 ^enum UPNP_IMPLEMENTATION{
, B$ w D y6 |8 L/ } UPNP_IMPL_WINDOWSERVICE = 0,
$ V9 W" S3 z% P! | UPNP_IMPL_MINIUPNPLIB,
9 H1 s- q; ~& {2 g( H+ ? UPNP_IMPL_NONE /*last*/( K, }1 G. L: ?+ A
};
: j8 M7 ?, x* F' i" x# C, h5 h! Y& v' A5 d2 S
: F( b- L4 b/ h* ~' m$ @% k+ g
) d v8 `% \% a4 e8 i% R5 K; w
+ |# d" M( B1 N; Oclass CUPnPImpl
% |: H# U% R" \" k! q ]; Y{0 d0 t5 K, l# n* } ^
public:1 v) Q5 }$ T% x* A/ t
CUPnPImpl();
0 {; [; \" M; B virtual ~CUPnPImpl();9 k# S" V7 q% ~7 O
struct UPnPError : std::exception {};' O- W: S `+ G3 l2 I' z
enum {" z3 V( J, X2 h& {6 {* q% c
UPNP_OK,
o' k7 S9 w7 w UPNP_FAILED,
$ m/ ^" N. ^: h; F: S/ v UPNP_TIMEOUT
- I* h6 |; ]; k+ j# Y% x& o };
' `* [3 O6 i3 [$ H" H& D
# _6 n# n3 y% a0 H2 J6 w' E8 X2 |( P0 U1 b
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
& C; e1 K T* a$ p) x virtual bool CheckAndRefresh() = 0;3 N* Q8 G: y; y! X6 |+ \0 Z* [
virtual void StopAsyncFind() = 0;
1 C0 v7 Q& {5 O+ ]; U virtual void DeletePorts() = 0;
2 m; R9 W2 q$ J& r+ `' ?; s7 E9 V virtual bool IsReady() = 0;% B! G! d' e! ], L$ k2 a
virtual int GetImplementationID() = 0;/ l5 I9 d. _5 q: k; f
0 E; b; S" ?2 ~$ r. _4 f: p: C- p. e" D
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
1 I9 ^4 Q: y1 P! t5 O: U ]
# t9 Q3 G: j% B3 O, f1 N
- `, Z1 Q L0 J, p2 Q9 h void SetMessageOnResult(HWND hWindow, UINT nMessageID); }, K! X5 ?1 R6 _# u, Y( p
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }7 h; T8 ~$ z* D, e
uint16 GetUsedTCPPort() { return m_nTCPPort; }
, d1 `# H( t7 D: T+ x uint16 GetUsedUDPPort() { return m_nUDPPort; }
2 B& y' }, d. a, [4 N i3 s+ b W+ E
- w$ \2 s" X- J; c. I0 i$ _- ]// Implementation9 b2 j* D% n! K& n8 R2 J* Y
protected:. ]- m3 i+ k& `8 [* l
volatile TRISTATE m_bUPnPPortsForwarded;- O3 y( P& ~8 Q7 {6 _/ R/ k, C
void SendResultMessage();% |: c2 t9 {1 H; b) N: t p" `
uint16 m_nUDPPort;
- G' U" b( d+ l1 O uint16 m_nTCPPort;
7 G* Z1 S2 g' U6 w' q, d uint16 m_nTCPWebPort;) y: ?7 ]/ f9 F
bool m_bCheckAndRefresh;' t9 q: w( `3 ~# i- F! m( Y# u
- [, T# ~9 w" `) n1 V* ?
, E' I8 ~+ z. ]3 o" ~private:
4 F5 P, @( d* _/ o, w. p& y1 B2 h) I HWND m_hResultMessageWindow;3 i p2 P3 P* X5 U$ a; ^( d& _4 A
UINT m_nResultMessageID;
8 f# Z p: Y4 N
- ~% k. V0 f8 J- x$ O1 L( F/ c; x# R! ^" m2 Y
};! G7 k+ b0 \& M6 T M, [3 |
Z- @% q% B$ [- ?; g
, u: e7 b4 `% e9 g: A// Dummy Implementation to be used when no other implementation is available4 F C& B( n* z% U3 [
class CUPnPImplNone: public CUPnPImpl3 n- Z; j6 E: F. J8 P9 r' W
{
) H c8 J7 H; \/ kpublic:& J2 M3 w+ U/ F. F) [8 G/ M
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; E1 L& _+ e' R! q
virtual bool CheckAndRefresh() { return false; }
: x( m- x) W x! x virtual void StopAsyncFind() { }
9 Z* d' E/ j- Q. H virtual void DeletePorts() { }
6 o; v8 u/ ]3 H% b G virtual bool IsReady() { return false; }3 P4 _6 d5 u3 p, J1 E0 D
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
1 ?& }7 X C. r, L$ g% V: w- l};" ~9 H% S- E$ B% y& t( d/ }
) M. q9 @* Q; }! a/ Y& T* `; E0 z* B* g" C- |( M6 o
/////////////////////////////////////
, A* v7 d; y: F3 ^6 \) P3 ^7 n//下面是使用windows操作系统自带的UPNP功能的子类% n+ a, }! F6 _3 O; }4 b' V
# ^' l* x5 }' n7 H. b3 f; }
8 V8 j* s3 {$ Z. Z3 J
#pragma once0 g( |0 m% |+ d" H9 @
#pragma warning( disable: 4355 )
, n3 Q; w9 B: g0 f5 E. q) }& t4 _) P: ]( j; n/ ~" ^) E
' l* |% N4 c; `& z Z! ?#include "UPnPImpl.h"+ u- H) W. o) p0 |2 a5 X6 ?" C* z* r, {
#include <upnp.h>
7 q4 Q# A/ } e; |. a& d5 w#include <iphlpapi.h>
1 Z5 k. p8 [2 I- { W6 b* X#include <comdef.h>
& ]- D/ o0 O/ d4 E#include <winsvc.h>
9 E& ~$ v1 K( w8 p
# R# |5 K4 G, v/ n2 O3 @4 v* h& G" Q
#include <vector>- Q4 o8 D& c! K+ E6 t5 O
#include <exception>: i& I5 Z7 x( c' |1 ]
#include <functional>" L( f+ c# e: D# b: O0 ]& Q2 ]
3 U& b& w3 r8 l
( n/ c+ k& X! l! d% H
& q# H& ~' w+ T+ ]& u- }& L. z/ W- t A7 X
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
. f1 O2 z6 R- W: Y2 {& @6 ztypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;7 a, R. h" o6 D
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;* X2 \$ e9 ]6 t: Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) I. N2 o: O# K% v- r2 t; ?5 C9 ?& u. j
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
' r; I5 Y. l+ utypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;& G( w( J+ v- q9 `1 x3 Y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* X2 r" j8 z1 s5 H! [( ~% F0 J2 a2 B% n$ c6 Y
/ ]6 i' w& ?! `% {1 P- Otypedef DWORD (WINAPI* TGetBestInterface) (# `9 p3 H: D. L
IPAddr dwDestAddr,
% m* @5 l! l1 H PDWORD pdwBestIfIndex
+ f4 e; K0 e" l' U0 {2 T);
& L' X; d: Q) p
. P7 A# D$ m. Z6 [( R& ~' C
9 k& ]% i+ t' a Q4 itypedef DWORD (WINAPI* TGetIpAddrTable) (8 N u0 q, i' f- ` J$ @
PMIB_IPADDRTABLE pIpAddrTable,* s6 [8 } Z0 M8 B
PULONG pdwSize,; m2 ^9 H/ v! w: F" T
BOOL bOrder/ B" c; E2 s! Q+ R1 U
);
2 C2 f1 B( k7 N2 m. a
O/ @5 _. b9 N7 R; i/ M7 u7 h; D& C* v% t" I8 E
typedef DWORD (WINAPI* TGetIfEntry) (
$ Y# U" A' Q; [) c$ _: U PMIB_IFROW pIfRow
$ N) C! [6 ]6 a n" I); j; O" w* p; D) y$ M) a
- q4 r# }( Y5 h2 o" j9 H0 `5 N# u
) O. }( f& j! j! E: ?. gCString translateUPnPResult(HRESULT hr);" F! m+ N: D) a% M& R* c
HRESULT UPnPMessage(HRESULT hr);
t0 ~8 U, N1 p* i8 q+ v0 k9 j; U( |4 u9 @$ c) C8 D: L- ?
, ], m9 y: u# f& e3 Yclass CUPnPImplWinServ: public CUPnPImpl0 k* \2 l0 d/ y
{2 b$ Z& ]) a# R& ]0 \, A
friend class CDeviceFinderCallback;/ p+ S7 ?6 P _' p! t ~5 Y \
friend class CServiceCallback;2 E! @+ i! z2 ^; D8 Y$ e( s
// Construction0 g' Y' y6 ?6 d& P6 U4 ?
public:3 R6 F0 N) m1 [" X1 S. o; Y, k5 J
virtual ~CUPnPImplWinServ();8 _7 N; s9 O0 p. u
CUPnPImplWinServ();
( G6 u' F O* Y) C. e5 F- W* B5 [6 K' X7 u7 X) K
3 l# d( E. A- i5 w virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; e' M# x* W; b6 _! k; V% F virtual void StopAsyncFind();
a; C6 u# k7 d# S5 v6 ~ virtual void DeletePorts();" G2 h, v o+ ]+ H& F& ?
virtual bool IsReady();
! Y! A2 i4 o$ ^+ j virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }& _" H) E# `3 @; u0 }
; }: T9 J8 ~! G, e+ \% U2 h4 t2 w3 x* G% r% d- Y+ J
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 V5 ]! \# t0 ~+ w // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later* V; p1 w2 B$ }
virtual bool CheckAndRefresh() { return false; };# j" `8 ~% ^; F1 S# E& [2 B8 u5 J3 ~
. k! g6 h' s% k! b
# i, R6 O/ n/ e3 s) E9 Yprotected:7 f( ^2 n! S+ Y* J" L
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);0 h4 o- m1 D: R' w# J$ I
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ R& y Y; L+ F void RemoveDevice(CComBSTR bsUDN);; t/ F2 F1 y$ {% q5 ?( g
bool OnSearchComplete();$ o- q3 b. O- Z, V* L/ j5 @0 y, c
void Init();
5 R4 f# ]5 C% {4 @" s3 u% [1 p; z4 r4 Z$ Z
! Y. ?% N5 g7 w, c# x* B/ y inline bool IsAsyncFindRunning()
: r# W1 ^; E7 d8 [; }) t {
( W; L" i& Y; { _: s$ C% w if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )" s2 d O N# o" x
{( n3 O1 r: U' L8 e0 K! |6 K
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 k& a6 j2 k n6 f0 ]( \
m_bAsyncFindRunning = false;) ?/ V; O7 G) H- p3 A2 ~& J
}
, Z) t. u1 J: g& t. K/ H MSG msg;9 O8 w( l# [9 B7 V
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )" n4 r4 U# H# a
{
- j- I& ?! h; E- C. \ TranslateMessage( &msg );
' h- D: }% R$ z) ^$ S/ x* u DispatchMessage( &msg );
2 B' r6 ^8 ~! `( c+ \" v }
7 c0 R) {' {* L+ s7 s return m_bAsyncFindRunning;# D2 }1 J/ p$ C& d6 g! L+ y$ M
}8 k" \. A1 X& s6 |8 B8 {! \9 @8 s
p$ t+ F8 O, O) d" J2 R
2 L6 m$ f1 d7 `* D& ~' [
TRISTATE m_bUPnPDeviceConnected;
5 ]) } n' p( d( ?- v
) j \, {1 L4 a" R$ q
1 n# m4 G+ e+ |4 W" ^/ m8 d// Implementation! [% M9 I/ X7 j6 Q5 J# p k' ?
// API functions/ b% Z8 U8 _4 G* i& _* d3 C4 U0 k
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
$ |1 D) C% |3 W! s% [+ y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 q9 {- X$ t7 w# Q( t) I BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); ]# W. H9 J; ?, u/ L
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
3 O7 S0 F! F( C0 `" V BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);, U) O7 `7 ]4 c& }% J% Y
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);2 ]' }' U7 S7 P: z
/ h# [, Y- m% C9 f; D, U
& G$ C* @9 J$ e TGetBestInterface m_pfGetBestInterface;0 s6 i' F' L _/ ]7 s3 p
TGetIpAddrTable m_pfGetIpAddrTable;3 s* g5 P8 Q. E y
TGetIfEntry m_pfGetIfEntry;0 y8 R& t; E; z5 P
4 m7 o5 _0 a/ U: |- Q: k
. V; }, `: B. b static FinderPointer CreateFinderInstance();4 r! i% Z* |4 ~
struct FindDevice : std::unary_function< DevicePointer, bool >
. |/ e# n3 k3 `) W {
E6 ~6 J7 S- [) G9 e! a" a FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
+ P. r# p B+ F$ C7 A0 N/ ]% p result_type operator()(argument_type device) const
/ v2 T$ h, a( G8 x {2 m" e7 J! t8 J
CComBSTR deviceName;
+ u( N( k% }3 w5 d2 T0 B+ d$ d HRESULT hr = device->get_UniqueDeviceName( &deviceName );6 }0 Z5 d* Z* V. y1 a# r/ p
% h: h: t- ^) L5 U
1 ~8 Q, y- p1 m; I+ E if ( FAILED( hr ) )
# w2 L. j! x8 R0 J' [4 C return UPnPMessage( hr ), false;
/ R2 F9 A3 n* |; {2 e/ h! W) S& L7 [ B G4 r' h
+ i+ z0 W+ x. A7 W
return wcscmp( deviceName.m_str, m_udn ) == 0;+ a6 J; V9 q$ u5 {8 S4 R3 ], k
}
3 c- ]! r4 x+ c, H CComBSTR m_udn;
. t7 j+ u8 k2 w$ e };& v6 }# t: a( [% l
+ ?( }# E, n5 D
void ProcessAsyncFind(CComBSTR bsSearchType);
1 `5 [' y1 U4 G6 g4 V HRESULT GetDeviceServices(DevicePointer pDevice);. ~: E1 F \7 N s
void StartPortMapping();) z! S0 ]" I0 m* P
HRESULT MapPort(const ServicePointer& service);
. K5 N" a4 N5 z, O0 ]5 U y { void DeleteExistingPortMappings(ServicePointer pService);
6 M2 [ e7 V* O+ r2 S void CreatePortMappings(ServicePointer pService);6 u4 b4 [; @% x9 k+ Y
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 Q! m/ w6 B9 U* L
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ! c$ M5 g: e! U+ c3 k
LPCTSTR pszInArgString, CString& strResult);
# g; ~6 j2 Q; _! o& ~( j void StopUPnPService();
7 A3 Z! ~& h2 \* ?2 I& Q/ P7 m& B. v# K- ^
% f' X6 a+ L" g V9 W2 k$ c // Utility functions, s, I/ F' X( z+ g5 P! v8 g
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
, E0 v2 {7 u, e* v+ R% s% ]/ E* o INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);% o8 y8 D1 v& E3 u: }+ C( p
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
% U2 B; ]; z1 ]# {2 v void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
; b7 T+ L. t( V HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
' _. Z; m$ d& e6 P HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
' T: o- o! g2 F" d2 J CString GetLocalRoutableIP(ServicePointer pService);
- U2 w# i; k- W1 `9 O+ Y0 L# ?% E* d7 r
$ V) f5 h4 U5 S) e" ]0 J- W3 S
3 ]5 l* ~( F# a# J7 ]" R: z5 v0 s8 K// Private members% V/ m: \0 v6 T( [/ L# F% w4 l. B3 i
private:
5 N q3 l& {- I( l! J& H DWORD m_tLastEvent; // When the last event was received?$ q, e5 P! ], v" Y4 g7 {3 J3 A8 W4 b7 ~/ k
std::vector< DevicePointer > m_pDevices;; O: z0 a4 m1 ?% {8 d& S4 z# J, X; P9 I2 [
std::vector< ServicePointer > m_pServices;
4 A; P2 K5 N3 {( I3 V FinderPointer m_pDeviceFinder;* s6 P7 ~3 r; D4 n+ e+ c
DeviceFinderCallback m_pDeviceFinderCallback;0 h: w0 R2 U1 @" L8 ^5 ^( V
ServiceCallback m_pServiceCallback;
. ~6 ]5 N" {/ ]/ B( s9 o
8 b) s3 l- R, Z$ \% ?7 g D$ _$ a$ e5 V
LONG m_nAsyncFindHandle;7 U" F( {7 I, {3 f+ L* R t
bool m_bCOM;' \/ Q2 d, L& D& I# r
bool m_bPortIsFree;
$ y# ]8 h/ }$ P- H1 y9 ]2 V+ \9 _ CString m_sLocalIP;3 i+ O6 E7 A1 y+ R! X( i
CString m_sExternalIP;( a5 |% W6 j$ F
bool m_bADSL; // Is the device ADSL?3 `! E+ R' C8 L& q8 u3 n- V: U
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
5 ]! K0 ] ]; C5 a0 V+ t bool m_bInited;0 G) f* y, s1 F* N
bool m_bAsyncFindRunning; O' I7 E' E& {( V
HMODULE m_hADVAPI32_DLL;0 i$ t9 `: K) U% ? |: x
HMODULE m_hIPHLPAPI_DLL;+ j* h; _" f* k! w( {* m& V
bool m_bSecondTry;
& O* d2 ~! V% h2 H E, i* A bool m_bServiceStartedByEmule;, c) F' a b' t
bool m_bDisableWANIPSetup;
3 d% p0 b; B" z4 ]4 E9 [ bool m_bDisableWANPPPSetup;" o$ C r8 `" W0 x
& j; @2 h- l8 @" A5 G5 h
* [9 O5 [$ o' n3 u5 Q
};
' U8 Z; O; Y& P- k# |; S5 F
0 ]" p7 j2 C; a2 ~4 a$ K; W$ i9 h5 U/ V+ n6 b l4 [
// DeviceFinder Callback8 _' d$ E- q4 q# W7 D1 [& m# s# F" Y
class CDeviceFinderCallback# z0 {" v# N: H/ D% R; ^* {4 }7 i9 D
: public IUPnPDeviceFinderCallback
, R! o, ?0 ^. h- U9 f$ T{
1 j' t6 {2 }- r3 J3 z0 m' k! Ppublic:# O; h/ h, l5 B% a: l4 s3 }
CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ e/ l4 @' i! Q- ] : m_instance( instance )8 n' W& @$ f) T+ U# M3 _
{ m_lRefCount = 0; }
: |9 f5 o4 t/ `6 F9 |0 H5 B% h+ Q1 v4 `" ]1 X8 m6 ]
# y& k3 @8 p5 ^( k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);) n# |. H2 K! l" o9 W
STDMETHODIMP_(ULONG) AddRef();$ f$ q; J7 `) C2 f$ ^
STDMETHODIMP_(ULONG) Release();
2 N2 A9 s: r, T* w4 x
- i+ ~* r5 ~6 m9 h/ f5 q7 q5 `) A9 }$ w5 Q9 g2 @
// implementation+ K$ T' q" z$ I$ H
private:
( v+ n# _, y- u HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
8 G- F5 T% l/ o) ] f HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
6 h$ N+ C$ D/ W% i& a1 d# ?# J2 Q& D, P HRESULT __stdcall SearchComplete(LONG nFindData);6 V& Y! c( S6 k" m: g
3 A+ j! @. d. N! H; T. d2 Q
3 T0 n3 d( E) j( X7 ~( Dprivate:# K5 i2 X% y& p2 \; e
CUPnPImplWinServ& m_instance;
6 H' j# ^* N7 x1 ?# p& p/ C/ K h LONG m_lRefCount;
9 L' n0 }! z- g5 ?9 e};
8 O$ A( G8 ~, V% j9 A, N: p% ]! P+ {( I. _$ e4 p" S, w2 Y- Z/ {
3 S4 z7 T) C* F4 g* M% v3 T// Service Callback
3 V& V5 o, J2 O0 j eclass CServiceCallback4 H& ~' c- V/ p2 o9 j) C: r
: public IUPnPServiceCallback" p# O2 ^9 g0 o' p# A# S
{6 I* M& F! [8 ]4 U. Z
public:: T, O3 f* h3 @+ Y/ h# I# i
CServiceCallback(CUPnPImplWinServ& instance)
& L, \! V! h0 v- X : m_instance( instance )' s& y: i6 @# C- d
{ m_lRefCount = 0; }4 w) e, l6 J0 l* ~. y' @5 T
5 \! @$ k/ H4 ?( a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( f# I g; U; a3 o% [
STDMETHODIMP_(ULONG) AddRef();% N* w3 w7 E4 D* a
STDMETHODIMP_(ULONG) Release();! ^- j# {7 g1 i
3 u# R! u/ M8 l; u& j. B, X) N
# `$ a/ P$ E. ?; I% J$ z4 b8 ~. U// implementation. S, H$ O# H% e
private:8 B& O9 `* G1 s0 f3 H) z
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- c$ K5 d8 [+ ?' N$ j0 {0 w HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
5 X3 u6 A" ^) V, S# j2 e% s1 m
1 A! i8 e/ s7 t4 H' @" @; R: `) U; y
4 D; q/ @. @4 G) F/ s/ [+ D. ^8 @private:0 U( e- \: Y$ c# ~' J) r2 |
CUPnPImplWinServ& m_instance;
5 e5 x" n) g7 [0 a LONG m_lRefCount;
6 n/ c" s' V/ w. z% H) x};
# u& I! u5 N3 ?" s4 P& p* f7 u' q( K7 U" Y! b+ B* b$ U. Q
5 l) ^0 D' y- l/ c. v& ^5 e
/////////////////////////////////////////////////
* ^4 b# \/ U `/ `) o
: t+ p, E- q' v2 h# k+ A! t" R6 J, h0 i" ~: n
使用时只需要使用抽象类的接口。
( W: `5 c' E; h+ O& tCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.8 j9 M. g" p" D8 I/ N8 _& l
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! e) j' }+ |4 n) r4 c, K+ ACUPnPImpl::StopAsyncFind停止设备查找.
# g* e5 _" t; V1 RCUPnPImpl::DeletePorts删除端口映射. |
|