dialup.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,333 行 · 第 1/3 页
CPP
1,333 行
/////////////////////////////////////////////////////////////////////////////
// Name: msw/dialup.cpp
// Purpose: MSW implementation of network/dialup classes and functions
// Author: Vadim Zeitlin
// Modified by:
// Created: 07.07.99
// RCS-ID: $Id: dialup.cpp,v 1.54 2005/07/28 21:15:53 VZ Exp $
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_DIALUP_MANAGER
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/event.h"
#endif
#include "wx/timer.h"
#include "wx/app.h"
#include "wx/generic/choicdgg.h"
#include "wx/dynlib.h"
#include "wx/dialup.h"
#include "wx/module.h"
DEFINE_EVENT_TYPE(wxEVT_DIALUP_CONNECTED)
DEFINE_EVENT_TYPE(wxEVT_DIALUP_DISCONNECTED)
// Doesn't yet compile under VC++ 4, BC++, Watcom C++,
// Wine: no wininet.h
#if (!defined(__BORLANDC__) || (__BORLANDC__>=0x550)) && \
(!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION(0, 5)) && \
!defined(__GNUWIN32_OLD__) && \
!defined(__WINE__) && \
(!defined(__VISUALC__) || (__VISUALC__ >= 1020))
#include <ras.h>
#include <raserror.h>
#include <wininet.h>
// Not in VC++ 5
#ifndef INTERNET_CONNECTION_LAN
#define INTERNET_CONNECTION_LAN 2
#endif
#ifndef INTERNET_CONNECTION_PROXY
#define INTERNET_CONNECTION_PROXY 4
#endif
// implemented in utils.cpp
extern "C" WXDLLIMPEXP_BASE HWND
wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
static const wxChar *
wxMSWDIALUP_WNDCLASSNAME = wxT("_wxDialUpManager_Internal_Class");
static const wxChar *gs_classForDialUpWindow = NULL;
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// this message is sent by the secondary thread when RAS status changes
#define wxWM_RAS_STATUS_CHANGED (WM_USER + 10010)
#define wxWM_RAS_DIALING_PROGRESS (WM_USER + 10011)
// ----------------------------------------------------------------------------
// types
// ----------------------------------------------------------------------------
// the signatures of RAS functions: all this is quite heavy, but we must do it
// to allow running wxWin programs on machine which don't have RAS installed
// (this does exist) - if we link with rasapi32.lib, the program will fail on
// startup because of the missing DLL...
#ifndef UNICODE
typedef DWORD (APIENTRY * RASDIAL)( LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN );
typedef DWORD (APIENTRY * RASENUMCONNECTIONS)( LPRASCONNA, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASENUMENTRIES)( LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASGETCONNECTSTATUS)( HRASCONN, LPRASCONNSTATUSA );
typedef DWORD (APIENTRY * RASGETERRORSTRING)( UINT, LPSTR, DWORD );
typedef DWORD (APIENTRY * RASHANGUP)( HRASCONN );
typedef DWORD (APIENTRY * RASGETPROJECTIONINFO)( HRASCONN, RASPROJECTION, LPVOID, LPDWORD );
typedef DWORD (APIENTRY * RASCREATEPHONEBOOKENTRY)( HWND, LPCSTR );
typedef DWORD (APIENTRY * RASEDITPHONEBOOKENTRY)( HWND, LPCSTR, LPCSTR );
typedef DWORD (APIENTRY * RASSETENTRYDIALPARAMS)( LPCSTR, LPRASDIALPARAMSA, BOOL );
typedef DWORD (APIENTRY * RASGETENTRYDIALPARAMS)( LPCSTR, LPRASDIALPARAMSA, LPBOOL );
typedef DWORD (APIENTRY * RASENUMDEVICES)( LPRASDEVINFOA, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASGETCOUNTRYINFO)( LPRASCTRYINFOA, LPDWORD );
typedef DWORD (APIENTRY * RASGETENTRYPROPERTIES)( LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD );
typedef DWORD (APIENTRY * RASSETENTRYPROPERTIES)( LPCSTR, LPCSTR, LPRASENTRYA, DWORD, LPBYTE, DWORD );
typedef DWORD (APIENTRY * RASRENAMEENTRY)( LPCSTR, LPCSTR, LPCSTR );
typedef DWORD (APIENTRY * RASDELETEENTRY)( LPCSTR, LPCSTR );
typedef DWORD (APIENTRY * RASVALIDATEENTRYNAME)( LPCSTR, LPCSTR );
typedef DWORD (APIENTRY * RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
static const wxChar gs_funcSuffix = _T('A');
#else // Unicode
typedef DWORD (APIENTRY * RASDIAL)( LPRASDIALEXTENSIONS, LPCWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN );
typedef DWORD (APIENTRY * RASENUMCONNECTIONS)( LPRASCONNW, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASENUMENTRIES)( LPCWSTR, LPCWSTR, LPRASENTRYNAMEW, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASGETCONNECTSTATUS)( HRASCONN, LPRASCONNSTATUSW );
typedef DWORD (APIENTRY * RASGETERRORSTRING)( UINT, LPWSTR, DWORD );
typedef DWORD (APIENTRY * RASHANGUP)( HRASCONN );
typedef DWORD (APIENTRY * RASGETPROJECTIONINFO)( HRASCONN, RASPROJECTION, LPVOID, LPDWORD );
typedef DWORD (APIENTRY * RASCREATEPHONEBOOKENTRY)( HWND, LPCWSTR );
typedef DWORD (APIENTRY * RASEDITPHONEBOOKENTRY)( HWND, LPCWSTR, LPCWSTR );
typedef DWORD (APIENTRY * RASSETENTRYDIALPARAMS)( LPCWSTR, LPRASDIALPARAMSW, BOOL );
typedef DWORD (APIENTRY * RASGETENTRYDIALPARAMS)( LPCWSTR, LPRASDIALPARAMSW, LPBOOL );
typedef DWORD (APIENTRY * RASENUMDEVICES)( LPRASDEVINFOW, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASGETCOUNTRYINFO)( LPRASCTRYINFOW, LPDWORD );
typedef DWORD (APIENTRY * RASGETENTRYPROPERTIES)( LPCWSTR, LPCWSTR, LPRASENTRYW, LPDWORD, LPBYTE, LPDWORD );
typedef DWORD (APIENTRY * RASSETENTRYPROPERTIES)( LPCWSTR, LPCWSTR, LPRASENTRYW, DWORD, LPBYTE, DWORD );
typedef DWORD (APIENTRY * RASRENAMEENTRY)( LPCWSTR, LPCWSTR, LPCWSTR );
typedef DWORD (APIENTRY * RASDELETEENTRY)( LPCWSTR, LPCWSTR );
typedef DWORD (APIENTRY * RASVALIDATEENTRYNAME)( LPCWSTR, LPCWSTR );
typedef DWORD (APIENTRY * RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
static const wxChar gs_funcSuffix = _T('W');
#endif // ASCII/Unicode
// structure passed to the secondary thread
struct WXDLLEXPORT wxRasThreadData
{
wxRasThreadData()
{
hWnd = 0;
hEventRas =
hEventQuit = 0;
dialUpManager = NULL;
}
~wxRasThreadData()
{
if ( hWnd )
DestroyWindow(hWnd);
if ( hEventQuit )
CloseHandle(hEventQuit);
if ( hEventRas )
CloseHandle(hEventRas);
}
HWND hWnd; // window to send notifications to
HANDLE hEventRas, // automatic event which RAS signals when status changes
hEventQuit; // manual event which we signal when we terminate
class WXDLLEXPORT wxDialUpManagerMSW *dialUpManager; // the owner
};
// ----------------------------------------------------------------------------
// wxDialUpManager class for MSW
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxDialUpManagerMSW : public wxDialUpManager
{
public:
// ctor & dtor
wxDialUpManagerMSW();
virtual ~wxDialUpManagerMSW();
// implement base class pure virtuals
virtual bool IsOk() const;
virtual size_t GetISPNames(wxArrayString& names) const;
virtual bool Dial(const wxString& nameOfISP,
const wxString& username,
const wxString& password,
bool async);
virtual bool IsDialing() const;
virtual bool CancelDialing();
virtual bool HangUp();
virtual bool IsAlwaysOnline() const;
virtual bool IsOnline() const;
virtual void SetOnlineStatus(bool isOnline = true);
virtual bool EnableAutoCheckOnlineStatus(size_t nSeconds);
virtual void DisableAutoCheckOnlineStatus();
virtual void SetWellKnownHost(const wxString& hostname, int port);
virtual void SetConnectCommand(const wxString& commandDial,
const wxString& commandHangup);
// for RasTimer
void CheckRasStatus();
// for wxRasStatusWindowProc
void OnConnectStatusChange();
void OnDialProgress(RASCONNSTATE rasconnstate, DWORD dwError);
// for wxRasDialFunc
static HWND GetRasWindow() { return ms_hwndRas; }
static void ResetRasWindow() { ms_hwndRas = NULL; }
static wxDialUpManagerMSW *GetDialer() { return ms_dialer; }
private:
// return the error string for the given RAS error code
static wxString GetErrorString(DWORD error);
// find the (first) handle of the active connection
static HRASCONN FindActiveConnection();
// notify the application about status change
void NotifyApp(bool connected, bool fromOurselves = false) const;
// destroy the thread data and the thread itself
void CleanUpThreadData();
// number of times EnableAutoCheckOnlineStatus() had been called minus the
// number of times DisableAutoCheckOnlineStatus() had been called
int m_autoCheckLevel;
// timer used for polling RAS status
class WXDLLEXPORT RasTimer : public wxTimer
{
public:
RasTimer(wxDialUpManagerMSW *dialUpManager)
{ m_dialUpManager = dialUpManager; }
virtual void Notify() { m_dialUpManager->CheckRasStatus(); }
private:
wxDialUpManagerMSW *m_dialUpManager;
DECLARE_NO_COPY_CLASS(RasTimer)
} m_timerStatusPolling;
// thread handle for the thread sitting on connection change event
HANDLE m_hThread;
// data used by this thread and our hidden window to send messages between
// each other
wxRasThreadData *m_data;
// the handle of rasapi32.dll when it's loaded
wxDynamicLibrary m_dllRas;
// the hidden window we use for passing messages between threads
static HWND ms_hwndRas;
// the handle of the connection we initiated or 0 if none
static HRASCONN ms_hRasConnection;
// the pointers to RAS functions
static RASDIAL ms_pfnRasDial;
static RASENUMCONNECTIONS ms_pfnRasEnumConnections;
static RASENUMENTRIES ms_pfnRasEnumEntries;
static RASGETCONNECTSTATUS ms_pfnRasGetConnectStatus;
static RASGETERRORSTRING ms_pfnRasGetErrorString;
static RASHANGUP ms_pfnRasHangUp;
static RASGETPROJECTIONINFO ms_pfnRasGetProjectionInfo;
static RASCREATEPHONEBOOKENTRY ms_pfnRasCreatePhonebookEntry;
static RASEDITPHONEBOOKENTRY ms_pfnRasEditPhonebookEntry;
static RASSETENTRYDIALPARAMS ms_pfnRasSetEntryDialParams;
static RASGETENTRYDIALPARAMS ms_pfnRasGetEntryDialParams;
static RASENUMDEVICES ms_pfnRasEnumDevices;
static RASGETCOUNTRYINFO ms_pfnRasGetCountryInfo;
static RASGETENTRYPROPERTIES ms_pfnRasGetEntryProperties;
static RASSETENTRYPROPERTIES ms_pfnRasSetEntryProperties;
static RASRENAMEENTRY ms_pfnRasRenameEntry;
static RASDELETEENTRY ms_pfnRasDeleteEntry;
static RASVALIDATEENTRYNAME ms_pfnRasValidateEntryName;
// this function is not supported by Win95
static RASCONNECTIONNOTIFICATION ms_pfnRasConnectionNotification;
// if this flag is different from -1, it overrides IsOnline()
static int ms_userSpecifiedOnlineStatus;
// this flag tells us if we're online
static int ms_isConnected;
// this flag tells us whether a call to RasDial() is in progress
static wxDialUpManagerMSW *ms_dialer;
DECLARE_NO_COPY_CLASS(wxDialUpManagerMSW)
};
// module to destroy helper window created by wxDialUpManagerMSW
class wxDialUpManagerModule : public wxModule
{
public:
bool OnInit() { return true; }
void OnExit()
{
HWND hwnd = wxDialUpManagerMSW::GetRasWindow();
if ( hwnd )
{
::DestroyWindow(hwnd);
wxDialUpManagerMSW::ResetRasWindow();
}
if ( gs_classForDialUpWindow )
{
::UnregisterClass(wxMSWDIALUP_WNDCLASSNAME, wxGetInstance());
gs_classForDialUpWindow = NULL;
}
}
private:
DECLARE_DYNAMIC_CLASS(wxDialUpManagerModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxDialUpManagerModule, wxModule)
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
static LRESULT WINAPI wxRasStatusWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
static DWORD wxRasMonitorThread(wxRasThreadData *data);
static void WINAPI wxRasDialFunc(UINT unMsg,
RASCONNSTATE rasconnstate,
DWORD dwError);
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// init the static variables
// ----------------------------------------------------------------------------
HRASCONN wxDialUpManagerMSW::ms_hRasConnection = 0;
HWND wxDialUpManagerMSW::ms_hwndRas = 0;
RASDIAL wxDialUpManagerMSW::ms_pfnRasDial = 0;
RASENUMCONNECTIONS wxDialUpManagerMSW::ms_pfnRasEnumConnections = 0;
RASENUMENTRIES wxDialUpManagerMSW::ms_pfnRasEnumEntries = 0;
RASGETCONNECTSTATUS wxDialUpManagerMSW::ms_pfnRasGetConnectStatus = 0;
RASGETERRORSTRING wxDialUpManagerMSW::ms_pfnRasGetErrorString = 0;
RASHANGUP wxDialUpManagerMSW::ms_pfnRasHangUp = 0;
RASGETPROJECTIONINFO wxDialUpManagerMSW::ms_pfnRasGetProjectionInfo = 0;
RASCREATEPHONEBOOKENTRY wxDialUpManagerMSW::ms_pfnRasCreatePhonebookEntry = 0;
RASEDITPHONEBOOKENTRY wxDialUpManagerMSW::ms_pfnRasEditPhonebookEntry = 0;
RASSETENTRYDIALPARAMS wxDialUpManagerMSW::ms_pfnRasSetEntryDialParams = 0;
RASGETENTRYDIALPARAMS wxDialUpManagerMSW::ms_pfnRasGetEntryDialParams = 0;
RASENUMDEVICES wxDialUpManagerMSW::ms_pfnRasEnumDevices = 0;
RASGETCOUNTRYINFO wxDialUpManagerMSW::ms_pfnRasGetCountryInfo = 0;
RASGETENTRYPROPERTIES wxDialUpManagerMSW::ms_pfnRasGetEntryProperties = 0;
RASSETENTRYPROPERTIES wxDialUpManagerMSW::ms_pfnRasSetEntryProperties = 0;
RASRENAMEENTRY wxDialUpManagerMSW::ms_pfnRasRenameEntry = 0;
RASDELETEENTRY wxDialUpManagerMSW::ms_pfnRasDeleteEntry = 0;
RASVALIDATEENTRYNAME wxDialUpManagerMSW::ms_pfnRasValidateEntryName = 0;
RASCONNECTIONNOTIFICATION wxDialUpManagerMSW::ms_pfnRasConnectionNotification = 0;
int wxDialUpManagerMSW::ms_userSpecifiedOnlineStatus = -1;
int wxDialUpManagerMSW::ms_isConnected = -1;
wxDialUpManagerMSW *wxDialUpManagerMSW::ms_dialer = NULL;
// ----------------------------------------------------------------------------
// ctor and dtor: the dynamic linking happens here
// ----------------------------------------------------------------------------
// the static creator function is implemented here
wxDialUpManager *wxDialUpManager::Create()
{
return new wxDialUpManagerMSW;
}
#ifdef __VISUALC__
// warning about "'this' : used in base member initializer list" - so what?
#pragma warning(disable:4355)
#endif // VC++
wxDialUpManagerMSW::wxDialUpManagerMSW()
: m_timerStatusPolling(this),
m_dllRas(_T("RASAPI32"))
{
// initialize our data
m_autoCheckLevel = 0;
m_hThread = 0;
m_data = new wxRasThreadData;
if ( !m_dllRas.IsLoaded() )
{
wxLogError(_("Dial up functions are unavailable because the remote access service (RAS) is not installed on this machine. Please install it."));
}
else if ( !ms_pfnRasDial )
{
// resolve the functions we need
// this will contain the name of the function we failed to resolve
// if any at the end
const char *funcName = NULL;
// get the function from rasapi32.dll and abort if it's not found
#define RESOLVE_RAS_FUNCTION(type, name) \
ms_pfn##name = (type)m_dllRas.GetSymbol( wxString(_T(#name)) \
+ gs_funcSuffix); \
if ( !ms_pfn##name ) \
{ \
funcName = #name; \
goto exit; \
}
// a variant of above macro which doesn't abort if the function is
// not found in the DLL
#define RESOLVE_OPTIONAL_RAS_FUNCTION(type, name) \
ms_pfn##name = (type)m_dllRas.GetSymbol( wxString(_T(#name)) \
+ gs_funcSuffix);
RESOLVE_RAS_FUNCTION(RASDIAL, RasDial);
RESOLVE_RAS_FUNCTION(RASENUMCONNECTIONS, RasEnumConnections);
RESOLVE_RAS_FUNCTION(RASENUMENTRIES, RasEnumEntries);
RESOLVE_RAS_FUNCTION(RASGETCONNECTSTATUS, RasGetConnectStatus);
RESOLVE_RAS_FUNCTION(RASGETERRORSTRING, RasGetErrorString);
RESOLVE_RAS_FUNCTION(RASHANGUP, RasHangUp);
RESOLVE_RAS_FUNCTION(RASGETENTRYDIALPARAMS, RasGetEntryDialParams);
// suppress error messages about missing (non essential) functions
{
wxLogNull noLog;
RESOLVE_OPTIONAL_RAS_FUNCTION(RASGETPROJECTIONINFO, RasGetProjectionInfo);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASCREATEPHONEBOOKENTRY, RasCreatePhonebookEntry);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASEDITPHONEBOOKENTRY, RasEditPhonebookEntry);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASSETENTRYDIALPARAMS, RasSetEntryDialParams);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASGETENTRYPROPERTIES, RasGetEntryProperties);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASSETENTRYPROPERTIES, RasSetEntryProperties);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASRENAMEENTRY, RasRenameEntry);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASDELETEENTRY, RasDeleteEntry);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASVALIDATEENTRYNAME, RasValidateEntryName);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASGETCOUNTRYINFO, RasGetCountryInfo);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASENUMDEVICES, RasEnumDevices);
RESOLVE_OPTIONAL_RAS_FUNCTION(RASCONNECTIONNOTIFICATION, RasConnectionNotification);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?