|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,' h/ ^" h" j: Z# I& K
, R- ~% o; V* \# z% Z6 W9 r8 ~
* L* @$ s% T7 r( ^8 P$ C
///////////////////////////////////////////1 n/ d. c0 r: j" N* O6 g% A
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
: c. F5 U/ y F
" M5 W5 h s1 b: o4 D8 R4 @3 ^9 o; O5 g( C
#pragma once
# ]. e! @9 ?" n5 F |8 j; f#include <exception>
5 s; r/ w4 Q6 Y) d1 A( N( E6 Y# U1 u4 z! ? G; W
) E: D8 E5 ]# B+ A enum TRISTATE{
4 l- J& v E$ o# p& ` TRIS_FALSE,
' w# q4 d z6 Y# C TRIS_UNKNOWN,0 x0 P- s4 B0 c V" f
TRIS_TRUE
3 `2 H1 ]6 k( @1 Y3 l};( R; a3 z) F: N# \
4 t0 I& `- a' _1 P' K# x6 w$ T
4 U, i- y' \2 T7 [; x7 eenum UPNP_IMPLEMENTATION{! d& J0 x- j. z/ ~$ n9 j, r
UPNP_IMPL_WINDOWSERVICE = 0,
4 X; ~& Y) _ s6 h* k6 f UPNP_IMPL_MINIUPNPLIB,
0 O* d% [7 T9 l0 U" q* s% g" j UPNP_IMPL_NONE /*last*/
5 Q4 q) e- c: a5 z6 Z};$ _7 X- {* {8 T/ X
; Q9 _4 _ {, j8 e/ U
g5 q( n( ?' F% w$ j
! ?1 E F! _2 D. G: e+ S" Z0 c/ _1 \. F; I$ X
class CUPnPImpl1 O1 J @3 Q& k- q# N
{
3 s+ S8 }" r2 L& @public:
0 o4 v2 Q q# N5 U CUPnPImpl();6 \6 L" e) [* ~. T" k$ Y1 Z) d6 z
virtual ~CUPnPImpl();
( F- U. L; v$ V9 W. @0 g struct UPnPError : std::exception {};; n+ [4 {: [+ w( L7 h- l
enum {) A/ u, b& ]2 f1 l) W
UPNP_OK,; ~; h4 w: O; L- r+ m. g
UPNP_FAILED,) t' W* \) s" t
UPNP_TIMEOUT* f3 F% E1 Y! g+ h' ~
};3 k2 Y# V+ }& b# P& w
/ m6 c' d# a' ?6 \+ A) u. S) X; n' J' G8 ]
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;5 |, L" C) I; H
virtual bool CheckAndRefresh() = 0;7 h" `' G, t' p5 [" o& ^3 y
virtual void StopAsyncFind() = 0;
- f& s4 w0 J: l( @( u% [ virtual void DeletePorts() = 0;; U8 X0 S0 C* i3 W. t7 v
virtual bool IsReady() = 0;
" X7 m, k/ P/ s( x& F6 ? virtual int GetImplementationID() = 0;( j- e6 u: D' }+ O$ Y7 O3 a9 {
% h1 k# j7 X) P7 e8 ~0 e/ }
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping$ c; l* a! Q/ T6 s1 m
; @$ U$ Q$ Z5 H9 B# Q
! I% m0 L3 [5 n2 b2 x+ R% `
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
8 |: Q& N& b9 e TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
# f; b" K0 r' h4 E uint16 GetUsedTCPPort() { return m_nTCPPort; }$ R, o) |6 }7 P% \% O9 W6 R9 z
uint16 GetUsedUDPPort() { return m_nUDPPort; } . D5 f, H7 J# S- v* w6 W( `
* w; q& v! Z% D! n
; V8 G1 ]' O# v
// Implementation
! c5 I" |' [5 D! o# B4 F, ~protected:
& V: G; o2 X% ` N; o4 u0 s* n volatile TRISTATE m_bUPnPPortsForwarded;0 G3 E& u0 Y( M- j [' Z5 d
void SendResultMessage();( F7 U+ F5 W3 ~) Z) T
uint16 m_nUDPPort;
% G2 P2 t9 ?/ Z1 g2 ^& a& J uint16 m_nTCPPort;
. V9 i, d; h4 H8 n# {# N/ u uint16 m_nTCPWebPort;
! D; c2 [+ f# l- E bool m_bCheckAndRefresh;
1 k8 B$ ]2 ^4 b1 a r5 F
" D! Q0 v# t0 |' K, l b% V" n+ O0 p9 ~8 M2 d) v$ j
private:
# M$ W7 J7 {) o4 ~4 s HWND m_hResultMessageWindow;9 A( ~' B" O) Y: W* Z. e
UINT m_nResultMessageID;
" w* Y+ _- ^# N% k9 }" H; h9 |& g! a1 s
( T9 ~2 _' y5 w
};+ Z9 H, d$ F' u9 P& X6 \
% R/ G; k( f6 Q& {
5 \2 C+ S. I4 K
// Dummy Implementation to be used when no other implementation is available2 T: J7 w' r" H( H8 u- B
class CUPnPImplNone: public CUPnPImpl7 O o! i3 a+ Z9 A8 Z0 {( ?
{9 [7 H+ d+ x9 a' `
public:2 T& {9 j- z" {7 \
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 L, r" _# w$ ~0 A
virtual bool CheckAndRefresh() { return false; }" n0 Z9 A9 f9 g; n1 B
virtual void StopAsyncFind() { }
+ m* ?6 J5 e0 c0 U3 | virtual void DeletePorts() { }
% |* w8 a% L+ x! P% N* d" N* e virtual bool IsReady() { return false; }3 k O( G5 L: ?% I6 @
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }( k O8 A) l) ^% H1 Q
};& x8 d O J7 H0 w& {6 s
0 R# \4 Y, V$ g0 l5 C8 |6 T
, {& C- [4 o7 h9 ?- Y///////////////////////////////////// k- f" u3 D( |2 q- G
//下面是使用windows操作系统自带的UPNP功能的子类
% B0 {) P$ W: J: B1 Z; J! u; q F+ g" b8 t. P, Q$ `3 ^
9 g* C2 B* z3 t2 g4 O& o/ c
#pragma once( ^( V! W; v! C2 B' y# [0 x
#pragma warning( disable: 4355 ); X$ A. a( r5 a5 j; [2 }
4 d$ @/ Z4 `, P( O" k+ B1 v
# p- \; q: l; m% S, }- e
#include "UPnPImpl.h"- W; C$ N8 j7 N# K5 Y* P$ O
#include <upnp.h>8 v0 Q" a; g6 n; C
#include <iphlpapi.h>& C5 L: e6 D* V& W& s Y
#include <comdef.h>
7 J( X. o. S9 v, @! Y! ^; Q: O1 T+ J#include <winsvc.h>
: H, V0 P+ e5 ]6 x! I0 x, B, |( G, C) G' ~4 @" ?5 @" \" D
5 L+ C' f* H# A2 N0 { n#include <vector>
" B i) K+ p, \7 F' n#include <exception>8 j- P( l& x% s3 x! B6 g' ~
#include <functional>
. J1 [! n/ R, a* n6 V" i) D1 o1 k) q" J
, m2 k4 z' X' |! R2 x5 o
! a, c/ P, A6 Z/ Z2 y4 `
7 V% Q8 Y7 C# Y( h {# @3 R0 R5 U6 k/ x9 ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
2 @* s k. ]1 ^# s; Q) ?) Btypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" U$ N' r' t! O. {2 s+ H3 b$ Q( Ztypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
F! W, Q7 A: j6 _) e- L$ F. |9 S6 ztypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
6 y+ Y5 G ]8 y( Z4 ~typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; r! N6 q8 O$ p1 y
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;6 j# q- u1 H5 \: u- u' D/ O
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;; {8 x5 B3 [; y6 i8 l
7 J/ e6 Y( e6 s V# o" U( Z# m- ^
; n- {; v% ]) Mtypedef DWORD (WINAPI* TGetBestInterface) (
" @2 O% K/ Z5 b$ x3 d( p: b' _5 @$ h' N IPAddr dwDestAddr,% i) h! @$ x \" A$ X( p! @& J( p- Z1 E
PDWORD pdwBestIfIndex
0 ?/ T( C6 K, {! i& s+ u);) P+ @& `$ `# X0 c K: U9 [7 v
; D4 c1 J8 s* t
* p. Z$ G- K, e
typedef DWORD (WINAPI* TGetIpAddrTable) (4 T4 y9 _9 a( \+ E
PMIB_IPADDRTABLE pIpAddrTable,
: k( R2 M0 q) h- H& j# q! _( K3 o2 ] PULONG pdwSize,5 Y C. ?9 o7 \3 Q3 `/ s6 ]
BOOL bOrder4 w3 g+ V9 G3 Z* \ ?! c7 B( a
);
@/ g. u$ i0 d/ j+ ?, q3 k5 e% O% b/ k, Z9 L* t2 n" W
9 i$ X8 l: [" A5 F4 Z' V9 S
typedef DWORD (WINAPI* TGetIfEntry) (
1 |# O' e d& {! p PMIB_IFROW pIfRow! z- d/ E& G6 F4 t2 t7 \
);
& n/ g0 ~6 q, r+ x' W: i
( h7 r/ W8 ?. }2 M, d: K3 }7 d
& d6 t; ~9 r" C! ?7 t Y5 _6 LCString translateUPnPResult(HRESULT hr);
" h7 y9 }3 ?/ |- j3 B5 cHRESULT UPnPMessage(HRESULT hr);1 ^+ j* _" R+ U0 a% b) q) T
# y/ r, l8 S* d n, q) e
$ ]# _. | D8 K: Pclass CUPnPImplWinServ: public CUPnPImpl
6 W( F' O5 Z4 u8 [{
( u" G" K+ |( v+ P; F friend class CDeviceFinderCallback;
! \. g" J& j) G% }4 p friend class CServiceCallback;* q* a5 j: W) g7 S4 ?, l) ?
// Construction
" W2 ^; v+ j) Q$ a2 R Ipublic:
5 `6 E* c# E4 `& B9 a$ Z2 n) f virtual ~CUPnPImplWinServ();! \+ E: |; `$ ~
CUPnPImplWinServ();; L+ G) V9 f; T3 T
" k1 B$ I0 s4 v* I. h8 n2 J. i+ F p
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); } z2 c: z- ^& ^0 Z7 n9 o8 {" w0 @
virtual void StopAsyncFind(); ~5 D" h+ B8 G( a+ Q& [
virtual void DeletePorts();! l( ]5 Q3 T. Q
virtual bool IsReady();( b$ ?" P- _* _) f3 D `
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
$ S6 t8 p3 \. N/ q8 H
1 E6 z9 |- o. X5 `# U' B& R9 f3 w5 X
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)1 w: i% O' F' T
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later8 g6 u- F/ i$ R$ Y
virtual bool CheckAndRefresh() { return false; };( \0 L3 V! C8 ]/ S( x6 C, U: O, R
* f# O* J$ N7 O! @! D
5 Y/ o: R# h" z7 D
protected:
1 x9 a, f" F* P y! e8 H% H z3 s void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
\) a3 l' `' j% l" ` void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);! D- V3 w9 x' h6 N
void RemoveDevice(CComBSTR bsUDN);: \% [3 b' V% S8 \
bool OnSearchComplete();
7 ~- ]% L# h) \" e' F void Init();
# x B0 c$ i& }! Z" o; Z& o
9 \. |% a) M8 j- l
; G, d4 n# g' V( F; G$ u inline bool IsAsyncFindRunning()
3 _% N: b" G+ I) f& f {
: O+ m. a4 a. ` U- G! N+ e if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 k$ O% z- D' f7 H* b3 {( b
{9 y2 W& n# J& E; q* I& t: q# b
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( g/ T8 ^' a6 C$ U) C5 U& Q m_bAsyncFindRunning = false;
% |. @! s! C0 Y } q8 u H5 t. |$ N: A0 w8 S1 ~# a: z" e
MSG msg;- S9 W4 c4 V$ c Y7 o! o
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
9 D" {- v0 j* M {' [ z% `0 a- u; U/ _3 l
TranslateMessage( &msg );
, S% b, x4 C& U( f$ Z @, _ DispatchMessage( &msg );
- V% i7 T4 O8 _: J% Z! {3 p1 } }/ y3 F) |- F! A- J4 u
return m_bAsyncFindRunning;
5 k6 b: _+ g" x0 Y+ T0 @2 R }
- l% S0 k0 ^8 a+ c0 }3 \1 P: h1 M: ^9 H: ]) q. v. H( f4 M/ k
: I) m2 _% J2 n& \ TRISTATE m_bUPnPDeviceConnected;/ w j, k3 L; ?( D
$ k5 p8 X( Z: j. {* r/ ^1 y |
. M: e/ h9 |2 G7 c) D// Implementation2 H0 L( q$ l3 [' }9 [& c
// API functions: w0 E; r/ ~, k# O+ v7 l7 C
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);0 V, x! L z4 ]* p3 w
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);# I( @7 H# c0 }5 C8 V
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
0 c. F6 f' a$ E# j# S% P BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
( G# ?( v: v, H0 t' Q4 X, ^' m, Y BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
! n/ w5 E& x; a4 D BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
: i! c& ~6 |$ ]0 n1 a5 Z9 ]) b; ? Z
. s+ }# Z3 Z" }: B6 F. S* ?# c9 T; H& Y! l
TGetBestInterface m_pfGetBestInterface;% [* A$ V. A# {, Q0 T# Q. x* r
TGetIpAddrTable m_pfGetIpAddrTable;
% O0 ^5 A3 f; l( g% u+ q TGetIfEntry m_pfGetIfEntry;# E- a4 S' r# F/ B, J
. A w3 W5 m( r$ {: I# H, a+ |' o2 i
5 w2 G6 i7 A& v. M static FinderPointer CreateFinderInstance();, o- F. B6 ^' f
struct FindDevice : std::unary_function< DevicePointer, bool >3 L4 }; u! L" V2 O
{
' g' E) G# v6 N8 |* j7 w4 a! g FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ u; }- z, Q) \0 e: s% Y, `; J result_type operator()(argument_type device) const J/ u F+ q8 a2 L/ W& v
{( J6 `$ [. a, B) w1 f
CComBSTR deviceName;9 @. `, B$ o& x! j6 {# t. Z5 K
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
4 F7 J+ Y2 q! H" U' Y6 J9 U8 E; e" i1 b
5 f; y3 b7 P: m2 U
if ( FAILED( hr ) )8 v& P; X$ X. m/ F
return UPnPMessage( hr ), false;6 T7 c* U4 l6 h1 {: r: A
. ^- F7 M' G, p3 j" P5 @% v7 Q2 r; Z
return wcscmp( deviceName.m_str, m_udn ) == 0;
+ ^; ?$ v; s1 w( a: [ }
2 }. a( y @6 D) m3 _2 u5 N CComBSTR m_udn;1 U# \% |6 K7 v G/ t. F" j6 R
};1 p( @& j8 H' x* w
2 Y) ?5 M: ]) }) x+ W" K! ^" h N void ProcessAsyncFind(CComBSTR bsSearchType);. e& b% e! O* x7 n
HRESULT GetDeviceServices(DevicePointer pDevice);$ u4 G3 p1 L5 }( J
void StartPortMapping();
6 x6 l; z5 E9 T* ~; P" T HRESULT MapPort(const ServicePointer& service);
8 L* i) j# z; }) N+ e9 Y3 y. g void DeleteExistingPortMappings(ServicePointer pService);
# x- W1 \ D8 f) ]8 m void CreatePortMappings(ServicePointer pService);% `7 R& x0 B4 H# H5 V! N9 ~# {
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
0 v' c/ A! b( u6 k HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
/ f* l( L0 X: S, T6 R+ t LPCTSTR pszInArgString, CString& strResult);
" n F3 r& f2 a& Y7 n2 T- k void StopUPnPService();1 C2 f* Y3 [3 R& x
+ h/ F, c1 d' d: v! B
4 G9 _5 |. W6 u. G- [6 N( i
// Utility functions
# g) t3 L T1 f3 B3 c) j0 t HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 _8 m' m- L$ \4 q0 d, q3 {5 f2 i INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
8 B- t2 }2 U. `$ y; ] INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 o/ [) ^ X ?& S
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);! R9 h9 Z: j3 V1 j$ I; E* U; {
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);( F' v$ V! U8 x! V/ _% [/ a
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar); k7 F3 b7 L2 m- M% ]7 n( u$ j
CString GetLocalRoutableIP(ServicePointer pService);
: t1 b8 K! f; x; X0 [5 h4 k' a. y0 m7 H! R7 C- t& c
1 p! k t- c! H8 P. D+ d// Private members& ?) x8 Z% X f% x2 Y- j
private:
2 P$ F0 W1 J' p DWORD m_tLastEvent; // When the last event was received?
+ s2 m- x- J$ r* e std::vector< DevicePointer > m_pDevices;
4 B/ I" H7 p! l/ x' J std::vector< ServicePointer > m_pServices;7 { f4 f* u3 F
FinderPointer m_pDeviceFinder;
/ m1 }% ]) n! ~& K DeviceFinderCallback m_pDeviceFinderCallback;
* j, C T; z) z- c9 K, X) n: n. u" m ServiceCallback m_pServiceCallback;: F- r% \6 q' U/ A" N& h
$ J2 g! c8 H: _, m
! Z! ]& j+ ^# r$ h# m! P8 Q LONG m_nAsyncFindHandle;5 R! N; F4 K2 {( e
bool m_bCOM;
/ E2 g( O1 ?3 p( h0 [' c bool m_bPortIsFree;* K* q8 j8 [3 X6 e! o7 ~2 P
CString m_sLocalIP;' i9 ` ?6 n. R' i4 Z _
CString m_sExternalIP;& e2 R7 H" O% G0 g y, V) }2 f4 B
bool m_bADSL; // Is the device ADSL?
! y, J: `* q) ~9 x, ]7 l) S bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
; h0 S% i9 w5 ]" A, y& A bool m_bInited;' i: N) O' z8 L0 b8 ~
bool m_bAsyncFindRunning;
& S, h& v- o/ p2 X4 u HMODULE m_hADVAPI32_DLL;* p9 m4 R1 C/ D, D6 k8 R( A
HMODULE m_hIPHLPAPI_DLL;9 a) ?' l9 J% c- }9 r
bool m_bSecondTry;: l" k+ m& ~) |! N* G; @
bool m_bServiceStartedByEmule;7 O$ J, r1 p2 Z U
bool m_bDisableWANIPSetup;
( a v' P! f2 m8 S$ d( ^: c bool m_bDisableWANPPPSetup;
5 x _! c& V. ]* \6 R* A4 `% O
( q* l3 s( g0 d4 s7 P8 E$ q
: h$ h( v% |% t3 g" c j4 E};$ U; Y, G- |3 e- `
* _; P- @6 X) a1 |( w
: x6 f- ~' y& t$ z// DeviceFinder Callback' d' a6 t. @) ^* ?. u
class CDeviceFinderCallback
. _2 G6 R! U; {( R : public IUPnPDeviceFinderCallback
7 @5 ~9 `9 S( E. t, p8 N5 H/ r{
' h& x0 ^% ?* \& M. o+ Spublic:, P1 h1 A" C- ?
CDeviceFinderCallback(CUPnPImplWinServ& instance)
/ t2 {7 ^5 e, S" p8 e : m_instance( instance ); y$ G( F7 ~2 }
{ m_lRefCount = 0; }$ h6 A c0 S- g/ p8 }2 s
. W6 F2 L5 V# f5 Y- n
" t5 _* _8 U/ l' t1 y! f! M, j
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);' m# Y4 g Z! L. _
STDMETHODIMP_(ULONG) AddRef();, H. p2 ?* y: V( _& U8 [
STDMETHODIMP_(ULONG) Release();
9 \0 A' i5 y2 d% n7 F, m% ]" |
! M! m7 a/ P% D2 N. h+ Q. e
3 t4 w4 T9 v! @// implementation
7 t" w. c- \6 v, d" nprivate:; H) k/ G. j' |
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 F% }8 t5 z3 ^, h
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 Z/ p8 {8 E3 j* y, w% f HRESULT __stdcall SearchComplete(LONG nFindData);% ? |! L+ B! d
% p. W5 }' X% X: u, J5 Y( \
! o) F* y4 I* c V; i D
private:
+ Y: g @% s; _" Z5 w2 a( z CUPnPImplWinServ& m_instance;
- @& t3 L' s/ P9 H6 g+ {( P9 k c LONG m_lRefCount;7 T, b1 c E; ^! i E% Z
};4 E$ W' R1 n8 f/ S9 E* |. a/ Z* a9 N. A
/ D$ W& p" S6 P# D! Y
: m- \* r6 o! m# i7 m/ t0 z; o
// Service Callback 8 P4 p" {2 v O4 N( d0 d
class CServiceCallback
5 f# u' P, j8 A% ~" z : public IUPnPServiceCallback
+ {4 J0 F5 T( A( p m% `8 z9 b2 o. e( Z{
$ R% j: G* i, y5 i) cpublic:
. K: g% `& I. P CServiceCallback(CUPnPImplWinServ& instance)# ?- k. M# y" r- @5 N& f9 v0 k0 B# Z
: m_instance( instance )
3 g$ { B9 D! x' \7 h0 D { m_lRefCount = 0; }! v9 D; v3 |# e( C8 |6 B( z
8 O; N: J+ f3 F- a& J/ M) w STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
' Q' w7 g; `8 p \+ ^' D STDMETHODIMP_(ULONG) AddRef();
% Q8 k8 P9 c2 J6 @& u STDMETHODIMP_(ULONG) Release();3 v0 H7 j. b" j; d. ^
: G8 [) W# @- W4 m
* h- b6 l7 j1 O* q// implementation7 A# j0 f2 X* c1 L' `
private:1 r* ?8 @( \0 J- @8 P- k1 `( o
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
! G" c6 d# [( X& }+ j HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
: s3 e: H* S' O: ~2 H
: o) ]" L6 e$ q0 b( Z# p% U8 Q' @
2 ~- J. w. U- ^: Y) m. Sprivate:
6 G9 o/ E5 t$ f7 l* m! q CUPnPImplWinServ& m_instance;0 s# I: }9 w( H
LONG m_lRefCount;/ E$ |1 a% q. p" |! @0 v
};- h$ D# X1 d+ @ ]# C4 j6 p2 {. n
6 f6 F1 R! _% o, G! o1 r3 ~9 A* ~/ z6 M' N; C6 E, d5 j! X
/////////////////////////////////////////////////( ?/ }0 _, Y" x& r6 A
- {0 |5 p1 l1 U' A. ]
/ G# ^! G1 ^4 K" K7 V4 j; g使用时只需要使用抽象类的接口。
. M8 P# v) F' v3 ^) D9 [/ ?CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
" t* ~# F9 S1 J+ V" pCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口." R/ W: a/ ?) J" q6 a5 z" [
CUPnPImpl::StopAsyncFind停止设备查找.
; G4 ?# ?* m2 E+ e OCUPnPImpl::DeletePorts删除端口映射. |
|