|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,/ B+ l# y* O- ~, G/ [6 d% ^- ?
, p4 s: [3 C3 H5 X% o8 h
' E) z( P9 E6 C: B///////////////////////////////////////////: x$ e: P! l( V0 x8 F; t2 w
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.' Y$ ^# k& ?7 W* o+ [
. {2 P! L0 q! L" @
/ |& F8 H$ c( l5 y
#pragma once
) J5 K$ y5 @0 Y% ]5 g8 g3 I( h#include <exception>1 P% O5 h) a3 w) Y# N7 C* |
( o0 X1 o# Q( `; ^; a' m1 g2 U
; y1 G1 a- ~2 h0 G' x( A$ h" `0 |
enum TRISTATE{
6 ]- B. j1 P$ E o* f+ Q TRIS_FALSE,6 Z2 o/ R/ @' E+ j' k3 f: Q% P
TRIS_UNKNOWN,
6 c$ d9 `# N7 R$ \ TRIS_TRUE0 |: ]3 R. \6 y2 I8 T/ y. r
};5 x+ e/ L. T; f. _/ O
+ L/ N( _' C; B5 |
* s' S" ^. ~: ?
enum UPNP_IMPLEMENTATION{4 }& ]$ L* a/ F3 H6 U7 Z4 n6 c( I
UPNP_IMPL_WINDOWSERVICE = 0,
5 x' [$ N6 i0 I- z$ u0 I UPNP_IMPL_MINIUPNPLIB,, e$ d4 H% H9 r* C2 w; P4 |/ N
UPNP_IMPL_NONE /*last*/; P! y( k/ A. A) x
};4 J8 Y U6 Q1 }+ ^4 V$ X
5 n* e! K3 B/ Q2 S5 }
6 w9 p/ t0 H" \ h2 c5 v
1 ]8 w1 `, g ^7 G3 T6 ^4 M9 z" {
/ G* _5 ?/ o# j: E" W6 m
class CUPnPImpl/ U: @7 e" r' i5 m$ d3 o$ I J
{
$ w/ F' f( X( U6 ipublic:7 T5 P3 }- F) ~3 `
CUPnPImpl();! S, i* i8 X3 a
virtual ~CUPnPImpl();
& @! H1 Y( }; g# c0 Y struct UPnPError : std::exception {};4 K! a! s& S! l
enum {& Z$ B7 [% V5 D* ?5 }+ [
UPNP_OK,
9 \% Z% a4 h% f7 w! h/ L; m UPNP_FAILED,
) K& D# F' b; V8 }$ j4 r9 G UPNP_TIMEOUT" j" i+ z' v2 n
};1 V- z/ x0 t* s
" b! M* y' w( v; D) N7 P2 w
. T7 h' p! J" x2 [: n% m) a
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;; j; g/ ~) c: ^; O* W7 y+ W
virtual bool CheckAndRefresh() = 0;( d% s' \1 G7 z D& ?, E+ ]
virtual void StopAsyncFind() = 0;
9 v2 j. X2 h& A- h& \; y1 z virtual void DeletePorts() = 0;
8 S3 @: s+ O! F1 K5 O/ k+ B: s" Y virtual bool IsReady() = 0;
! r- E% d$ K0 J# \ virtual int GetImplementationID() = 0;; ~9 x5 {( {+ q& N ~4 n4 B; y% B5 g
2 ?# b. L( j. i* }% H7 g/ L void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 Q8 l3 f2 I4 {5 i
3 r. W% H. q# G/ H% R+ L
2 V j# c7 y6 b' L void SetMessageOnResult(HWND hWindow, UINT nMessageID);4 V+ a1 l! P. u- F
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
6 g1 @+ [" m: p( D C6 B uint16 GetUsedTCPPort() { return m_nTCPPort; }' u# c+ @8 p! L1 r2 K' j- b. f
uint16 GetUsedUDPPort() { return m_nUDPPort; } 8 b4 i, d9 V/ ?8 Q- R
( z L7 x5 C" p( a- I' m% K, D9 J- |$ y" t |- t# c
// Implementation0 c/ s- V4 j! t' K
protected:3 K" z& K) B% ?- \
volatile TRISTATE m_bUPnPPortsForwarded;
* A( i" U' I. i# {0 P void SendResultMessage();9 K' j$ v+ C* d' K" p
uint16 m_nUDPPort;
5 m V/ t( C2 c( t+ v6 U Z( X( f uint16 m_nTCPPort;+ s; z( v) m5 d$ S
uint16 m_nTCPWebPort; k. C& Q1 a+ L) s, G+ C
bool m_bCheckAndRefresh;# c! s) g9 M v$ Q1 ~
W3 j( \# I5 P" o
n8 K& I8 ^: l& |3 {private:
7 M& k3 \# l H; \5 E6 {- g6 l% Q! r HWND m_hResultMessageWindow; v1 W6 g/ {4 l9 ^
UINT m_nResultMessageID;( V. w& Y% e& P, `) A! f3 y! s
2 U3 ^8 j( Y, w& D/ Z! p- \
) M/ P, C2 c) C4 \" }& P
};% D; F. m+ \; B Z+ h" v: h8 u
. }' S _' o3 K U) s
0 b0 }0 \, U2 c, _, k* M& k// Dummy Implementation to be used when no other implementation is available; L3 _' Z" I) m% g5 v: R( J \: t4 o- _
class CUPnPImplNone: public CUPnPImpl
# p6 w' R0 B6 F0 U! t+ k{
^5 P# Y# f. \; z0 Z9 z9 E/ T* W/ K- Mpublic:: E- h, ?! g- X7 P0 v: Q
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
% H2 `/ H7 u5 | p( J1 Y- c+ E- F virtual bool CheckAndRefresh() { return false; }
* b. v4 t3 O# [3 ` virtual void StopAsyncFind() { }+ U" c+ ~) A+ I
virtual void DeletePorts() { }
8 Q2 L! c- v! N7 W% @- \3 _ virtual bool IsReady() { return false; }( V. N$ N% {9 h X0 w
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
- a$ Y/ a2 z8 {2 U/ [& a};: V/ ?4 M* j3 k5 k
, ]% p- M- G+ u
- [2 R+ D# c0 z4 l0 Z* W, q/////////////////////////////////////4 L& M" J& E9 E+ A
//下面是使用windows操作系统自带的UPNP功能的子类3 I2 @, }* I) t4 l0 p
1 x5 H9 V. R/ |4 B( }8 e6 L; v. O' h0 V w; Z8 U/ F
#pragma once
. s8 F9 @+ Z. E Q+ a#pragma warning( disable: 4355 )
" x# t* h( d, \0 h; j7 q' Q
3 F5 y. W8 @, m7 Z
/ I, c9 O, ?) d1 @: c; L" [#include "UPnPImpl.h"
+ c5 U9 j! s+ U#include <upnp.h>
' y$ a' I p9 {" B# v9 H3 K#include <iphlpapi.h>" i' c' @3 N3 t. B& u
#include <comdef.h>7 t& k) z' j$ u8 |5 v
#include <winsvc.h>
1 Z+ \+ j( y9 V( S
$ b$ L3 g9 W) z6 y9 A& P& C' M9 O+ e- w j
#include <vector>
9 l2 T( \9 _4 y+ R#include <exception>
4 N" t* p) s( }$ U8 A#include <functional>) s& P, t4 |9 e
: E& f: I! x! |# @
: p$ B/ ^9 B- w4 p
5 _! j4 j& A* l9 ]9 A5 a/ n& ?/ ~' y' c; I4 j
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, l+ y* T' j, y- P
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
. h1 U$ ?# z- o' E; htypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
" R6 F8 Z0 _8 X2 s+ \$ O; u+ I0 N: ltypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
" b$ |; g: l+ Jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
: I9 f0 B1 ^4 `/ Ktypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;8 G. t! H5 s- c' W, d
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* O9 j) W# f: ?7 e1 V9 H k8 b' C$ V" y% z) x7 f! d
9 e& y$ k: Q* l& ?8 t4 |/ k% ?
typedef DWORD (WINAPI* TGetBestInterface) (4 w* [- s: U/ l* i
IPAddr dwDestAddr,* Z! ^3 j) Z+ v; Z4 l
PDWORD pdwBestIfIndex
* c4 _4 i0 R# T0 P: a);
( o4 r; d: j5 J8 D
% V" x+ U) t" J% a7 X0 v* Y% Q+ n" O0 u# f/ M
typedef DWORD (WINAPI* TGetIpAddrTable) (; Q W- b1 T2 L: D, h$ U+ _5 g* L
PMIB_IPADDRTABLE pIpAddrTable,0 t; g) j' m+ }: j- F6 s; a
PULONG pdwSize,9 }4 }6 p( V v/ k7 m
BOOL bOrder4 N- G, R" H1 k m& q
);! s I# S- F5 c2 y _
! z+ \, C. V3 L. i; v- \
# D8 A4 Z! V7 R/ c. J$ e
typedef DWORD (WINAPI* TGetIfEntry) (
p4 N# y$ d4 @& u PMIB_IFROW pIfRow% P2 C7 P$ h! y5 m" L" i
);
# Z' Y( G$ Y' i; L! U$ {9 O) z9 M7 B3 @4 M! s
* B# r j$ M' C0 v2 }: M& ]
CString translateUPnPResult(HRESULT hr);- P% M5 Y, P, _
HRESULT UPnPMessage(HRESULT hr);
7 i' W; D% R h' T' M; j' o. a! @ `1 D/ a2 v2 X7 N0 R1 t
( v$ a5 D% P2 E, b% G3 @& m- Rclass CUPnPImplWinServ: public CUPnPImpl
8 v- n I) O3 r4 v{
# g# \1 o; J. j) M friend class CDeviceFinderCallback;3 R T% O7 \" x& _5 x% a, {8 X
friend class CServiceCallback;
% d- g& M* Z# z+ G2 I) Q( m// Construction
! K0 A! w$ ^0 c( ~) @8 _- Opublic:
# E" q4 D* B( | virtual ~CUPnPImplWinServ();" b* [" O' h; \& C" Q1 |% N
CUPnPImplWinServ();8 @7 Z! q( f" Y' Z
) J l3 c5 i( w! t5 a/ K" e/ [- a3 X% ]# t7 k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
4 d1 n7 V0 N8 a2 {- e _ virtual void StopAsyncFind();
4 R1 ~: U+ v# x5 g, a. @, w6 _ virtual void DeletePorts();( H7 r3 G3 Q2 S8 U
virtual bool IsReady();. v8 B, I" Q' Q' r, d) z
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
* \" P3 n \" s
' A& w- t6 P0 O5 s2 e3 W# n# H% |( p- e3 q
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)4 ~0 l5 y7 L3 L" o9 W e
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
4 a# z2 L. _0 L" i9 L$ z2 o2 d. s virtual bool CheckAndRefresh() { return false; };
+ l; T! m* V( [ M# }8 X4 E6 M8 V, [- D6 L, S8 O8 \, p% _
2 e& }) d4 U/ ?5 z
protected:
9 q( ?0 Y5 @3 a0 n9 D' i1 q void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
% J D" D3 D% J8 b: J" ~6 r# { void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
/ h- X* `- ~6 y& T void RemoveDevice(CComBSTR bsUDN);
3 j+ q$ h1 ?3 C. M bool OnSearchComplete();6 Z" M& z' X. _# }1 k; `. y8 O4 n
void Init();' t' d3 e$ }# b5 ]
- s1 Q. o4 H: @. h8 I' R& G+ I
5 H" ]- y' V9 e5 _4 f+ a& G& t, V
inline bool IsAsyncFindRunning()
8 L8 y: E) E! }. A! F7 r) {9 D {
: c& y! s* r; p; u$ ~" v$ Y8 l if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
d- g- ]8 Q7 d: ^7 ^" W {/ ^9 H4 ]7 p, l! S
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
$ c; G0 Z6 i. s5 T m_bAsyncFindRunning = false;
* ?; ^% y2 K* y' I4 {0 L }1 P" @" B% V0 J+ H& A$ w# }; j. t, G
MSG msg;
6 C5 a) l9 C- Y, U7 x6 G3 n while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" I- r3 k0 V- l7 | {9 |! }, U: `8 R8 {4 E
TranslateMessage( &msg );
0 ?+ F6 C% a1 \% a1 O: e l DispatchMessage( &msg );
" g8 T: {& B ?4 I }
, L& q; t ~, T2 ]% E return m_bAsyncFindRunning;, ]8 |: H g7 a5 n0 e- @2 f& P
}
) H# _9 [" k: g7 k# [5 s; b0 Y! ~; w1 L7 [0 J X
# Y3 R7 @. t9 [+ ? TRISTATE m_bUPnPDeviceConnected;' {6 `- u a* M" G8 d- T
0 T3 o9 J# X1 T; h; K" N& y& \+ O
" d% p4 E. h, g8 E( ^3 V# @) R// Implementation
2 J; m/ d& K9 N // API functions9 ]8 O) J. L; P, T; W* n& s
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( f* e$ I) b7 s3 z! n
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);2 i0 @/ o6 H$ ^- t4 Q& D1 d- o
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);. ]- }, s* x/ ]( e2 i
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
9 {5 T# l% H" p, K BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
) C- l" d7 }) ?6 k9 s, I BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ w" M+ _8 m1 Z& W0 D. ]7 Z3 ~/ f( h# V) Z3 ~" a
6 K6 A; D1 w0 |1 n% @
TGetBestInterface m_pfGetBestInterface;
5 `2 T6 a9 ^) b' P& { TGetIpAddrTable m_pfGetIpAddrTable;
4 P3 ]5 L- ?3 _* h: ]* o TGetIfEntry m_pfGetIfEntry;8 G# B' ~9 r+ b8 D* |
1 H7 {' l" X; }* f$ I9 a- u' j8 Q1 C# \6 C: Q
static FinderPointer CreateFinderInstance();
( }8 k& I, u% I; n struct FindDevice : std::unary_function< DevicePointer, bool >9 N: ]5 g$ g7 w# _! {) e9 S5 \1 e6 }
{% d6 n- A8 i% s
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 J0 T8 ~: Y8 z
result_type operator()(argument_type device) const
5 v% p' ?% T7 w% d' ]& m$ Z1 Y {
) y/ x% K; o M9 |/ n CComBSTR deviceName;
% g6 z, }% x Y; A! Q/ c s HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& Z0 U: ?0 V$ S
9 \3 V+ i& k# s9 `' X* h5 c9 G+ O+ Q( Q, R( c0 M2 t
if ( FAILED( hr ) )
) p5 l- I2 a+ m7 { return UPnPMessage( hr ), false;
* c9 s( a$ w/ H, J! w' w' T7 E( A2 ]1 R- W, ^* o$ R& G
+ B# l6 g' [3 r ? return wcscmp( deviceName.m_str, m_udn ) == 0;$ b) ~7 g' D$ k
}
1 F7 j" {4 Q9 H/ @: d5 S CComBSTR m_udn;( M! L& J* c( H
};' j B) Y ^+ g2 `. h' h' N
) b6 t6 \5 \ U( P
void ProcessAsyncFind(CComBSTR bsSearchType);2 {* y$ s( z+ s& T7 }8 v
HRESULT GetDeviceServices(DevicePointer pDevice);: `( C2 }5 Z& u% [: q3 Y3 ]& j
void StartPortMapping();4 w1 I* f& x$ `; I
HRESULT MapPort(const ServicePointer& service);
( }8 ^5 \; U& n( } void DeleteExistingPortMappings(ServicePointer pService);
% r) W0 s, m+ {7 J void CreatePortMappings(ServicePointer pService);
+ y) F0 d* E% B# i$ ?, J0 n+ @ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);2 N8 q0 W; _; v! D& R. T( p0 @
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
" t7 C' P: N6 T LPCTSTR pszInArgString, CString& strResult);1 M8 h) u. Z# Q1 \( L ~
void StopUPnPService();) E5 u: O! y& l9 y( r
* ?5 r" k% g$ z* I8 X1 x# ~( W! D
# r! p C/ X% j0 }+ D) l/ ^ // Utility functions
* }3 a) {. G) v3 P3 c$ i HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
6 X5 {; x/ i/ b; F9 V+ U9 ?$ ^( f INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
; g7 }5 K8 }1 j! {. V INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
7 X* t4 m4 W L! j3 ?% e void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
( M/ G$ a$ w9 i% ]& \ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; @3 A/ ?) ^; X0 E S, _6 q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
# ~' n9 v" E1 b7 X1 e, |% g' N& _ CString GetLocalRoutableIP(ServicePointer pService);
& q7 B7 e$ j4 N. V% Y0 Y
% X$ ] i5 P* L6 n0 _! ~5 u Q7 p) t# |* M$ U
// Private members
- u; r! ^+ V+ o- ^6 Fprivate:5 R4 \ o# U0 ]2 I
DWORD m_tLastEvent; // When the last event was received?
) u Z! ^5 S0 _( c8 X$ s) a; I std::vector< DevicePointer > m_pDevices;
* I* r# H3 i% _: ~9 m std::vector< ServicePointer > m_pServices;9 k8 S5 |7 T0 I
FinderPointer m_pDeviceFinder;* |# n& T: `% i/ h9 Q& Z
DeviceFinderCallback m_pDeviceFinderCallback;
6 ^3 \/ t5 p9 ~+ }" M3 [ R ServiceCallback m_pServiceCallback;
4 `' Y, o* p1 [$ c& n2 i% }5 s
* I' J- `* v( E& {
. ^+ z+ N9 |+ D! e! \ LONG m_nAsyncFindHandle;
% R) a( X; z8 v) c* K# O7 w) ` bool m_bCOM;
% u2 T$ R( D7 ^# H' w7 b4 M bool m_bPortIsFree;" V d5 A% h, a8 N; L; J: A2 i/ r
CString m_sLocalIP;4 m, I3 [/ a2 m$ ?" p- S/ F5 ^
CString m_sExternalIP;' n, a! {: W2 q+ {; x; S" Y
bool m_bADSL; // Is the device ADSL?
8 p0 r2 K U3 X, l bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 K$ i! m" b' B bool m_bInited;0 u: \2 [ K/ [
bool m_bAsyncFindRunning;
2 A' @1 }6 e/ a0 i HMODULE m_hADVAPI32_DLL;
% G2 M* P+ p. q% V3 A6 t* D HMODULE m_hIPHLPAPI_DLL;# L) R# u. J- t' B
bool m_bSecondTry;
' l$ `' c: ~6 A3 L1 B; v9 m; t9 o bool m_bServiceStartedByEmule;
, x- y6 h2 W. @* C- H bool m_bDisableWANIPSetup;
0 W# p: w& k0 ^6 g( w" ~5 u bool m_bDisableWANPPPSetup;
4 ]% b6 w4 [5 y0 ~. u) H+ X5 E# s3 Y4 Y3 B
2 Q G2 F, ~/ r( e7 ] u0 i};( _: ^! k& b: z( m; B( G6 ^" r. w
$ X2 P" _9 ^$ o4 ?6 g& s
" E$ ^8 O; J( I' T
// DeviceFinder Callback
H3 p, n5 }3 q5 P0 J" Yclass CDeviceFinderCallback
* R' Z( y3 f" D1 V4 H! k : public IUPnPDeviceFinderCallback. O2 z- r7 I4 u" J
{0 ~7 v |4 p( ?2 G
public:- [" V- l' t- \, T, g: r$ T" q! X9 g
CDeviceFinderCallback(CUPnPImplWinServ& instance)0 I& @: O, @6 u$ z+ x# ~% I0 k9 L
: m_instance( instance )8 g& [$ a2 t4 Q( B* u: g- u
{ m_lRefCount = 0; }* d7 _" C# s2 |) G4 `# L
; A1 r) P# B9 f% W, P1 S8 t4 q' _6 I+ q9 A
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
" v( L7 j6 g/ M# U) N0 i9 h STDMETHODIMP_(ULONG) AddRef();
9 w& d1 C$ u# { STDMETHODIMP_(ULONG) Release();0 s4 H% u) x; n6 Q4 j
( v+ Z% ~$ ~" O a7 n8 H3 L0 f* `" `% j/ Z+ l
// implementation
6 D/ O, y( f v* d- `8 ?private:
& L: z: B8 m) ~. F; K) x HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
* P4 D) t, ?) f6 q HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
1 A- p. S: e( [9 e2 ` HRESULT __stdcall SearchComplete(LONG nFindData);
9 D7 B5 s9 i& U7 l7 Y* r5 i, O* U8 X
+ f- h, s1 _; {/ S7 X4 ^( ]& f
private:4 ]7 \! \) N3 O7 i6 f& W
CUPnPImplWinServ& m_instance;
$ i4 D) y! h1 m& {/ x2 v LONG m_lRefCount;* k4 s7 X9 }5 s4 J- s
};2 K; U; |8 ~4 J
* F( C1 c6 j) I3 ?8 c. ~- V* ~: ~7 L q; s- H
// Service Callback
: l( \9 b0 `$ ^class CServiceCallback( d: t- d: v$ Z- |8 C
: public IUPnPServiceCallback0 M0 [/ f. k* o$ H/ n
{6 G/ g; w H. [
public:# Z" M& D6 D8 J4 B
CServiceCallback(CUPnPImplWinServ& instance)
# d5 L: m5 k0 o$ h : m_instance( instance )
* u% i" L/ M+ c5 l4 X3 p1 _ { m_lRefCount = 0; }
; P, t. O7 t8 o3 d+ a" E5 m6 N
/ _5 ?! p7 Y) [6 C" X$ q: U' t& d STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% ^/ Y. s6 y# a3 @8 F
STDMETHODIMP_(ULONG) AddRef();
, h; _ J( o; G! L" q STDMETHODIMP_(ULONG) Release();
1 H3 { q( s8 j5 b- `/ |0 l0 h9 K
" w) }! D, U% X, P4 Z$ s
$ n4 ]& Q. q+ a% ]8 k// implementation) X& N% n9 t% t' P5 e3 I3 v
private:9 O7 i$ _* ]& f6 [0 ? o3 B- C# E) P
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
, r7 D( g+ a" V2 v$ a" X HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
1 A5 J+ _7 a% i X: k7 r5 d6 S2 T/ {( q8 M) s
% F7 W+ E R5 N8 f5 Q7 Hprivate:
$ W4 y; r2 w2 z/ u; k. }$ M. ~ CUPnPImplWinServ& m_instance;
+ q8 B/ M) n+ B' r8 X# z1 a( h LONG m_lRefCount;) p1 c. k2 G& V3 h$ U" g" A! K
};9 |1 y0 f. x' c/ V- R4 X% v
4 b& I+ i; `2 h
5 c- J0 w/ u; B0 j
/////////////////////////////////////////////////
8 F# r3 o3 [- y3 A- v3 J' U" S/ r5 H: {! m' ^& L6 k, H
# R% R' c8 ?' r3 ]使用时只需要使用抽象类的接口。 ?0 @% u* C7 J8 E* J
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.% W" f8 @8 u! p p; t
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.5 }: i, X' a2 o) d
CUPnPImpl::StopAsyncFind停止设备查找.5 g9 a2 E2 s( v2 K
CUPnPImpl::DeletePorts删除端口映射. |
|