#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"
+
+DEFINE_EVENT_TYPE(wxEVT_DIALUP_CONNECTED)
+DEFINE_EVENT_TYPE(wxEVT_DIALUP_DISCONNECTED)
-#include "wx/net.h"
+// Doesn't yet compile under VC++ 4, BC++, Watcom C++: no wininet.h
+#if !defined(__BORLANDC__) && \
+ (!defined(__GNUWIN32__) || wxCHECK_W32API_VERSION(0, 5)) && \
+ !defined(__GNUWIN32_OLD__) && \
+ !defined(__WATCOMC__) && \
+ (!defined(__VISUALC__) || (__VISUALC__ >= 1020))
#include <ras.h>
#include <raserror.h>
-#include "wx/msw/private.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
// ----------------------------------------------------------------------------
// 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
// startup because of the missing DLL...
#ifndef UNICODE
- typedef DWORD (* RASDIAL)( LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN );
- typedef DWORD (* RASENUMCONNECTIONS)( LPRASCONNA, LPDWORD, LPDWORD );
- typedef DWORD (* RASENUMENTRIES)( LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD );
- typedef DWORD (* RASGETCONNECTSTATUS)( HRASCONN, LPRASCONNSTATUSA );
- typedef DWORD (* RASGETERRORSTRING)( UINT, LPSTR, DWORD );
- typedef DWORD (* RASHANGUP)( HRASCONN );
- typedef DWORD (* RASGETPROJECTIONINFO)( HRASCONN, RASPROJECTION, LPVOID, LPDWORD );
- typedef DWORD (* RASCREATEPHONEBOOKENTRY)( HWND, LPCSTR );
- typedef DWORD (* RASEDITPHONEBOOKENTRY)( HWND, LPCSTR, LPCSTR );
- typedef DWORD (* RASSETENTRYDIALPARAMS)( LPCSTR, LPRASDIALPARAMSA, BOOL );
- typedef DWORD (* RASGETENTRYDIALPARAMS)( LPCSTR, LPRASDIALPARAMSA, LPBOOL );
- typedef DWORD (* RASENUMDEVICES)( LPRASDEVINFOA, LPDWORD, LPDWORD );
- typedef DWORD (* RASGETCOUNTRYINFO)( LPRASCTRYINFOA, LPDWORD );
- typedef DWORD (* RASGETENTRYPROPERTIES)( LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD );
- typedef DWORD (* RASSETENTRYPROPERTIES)( LPCSTR, LPCSTR, LPRASENTRYA, DWORD, LPBYTE, DWORD );
- typedef DWORD (* RASRENAMEENTRY)( LPCSTR, LPCSTR, LPCSTR );
- typedef DWORD (* RASDELETEENTRY)( LPCSTR, LPCSTR );
- typedef DWORD (* RASVALIDATEENTRYNAME)( LPCSTR, LPCSTR );
- typedef DWORD (* RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
-
- static const char gs_funcSuffix = 'A';
+ 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 (* RASDIAL)( LPRASDIALEXTENSIONS, LPCWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN );
- typedef DWORD (* RASENUMCONNECTIONS)( LPRASCONNW, LPDWORD, LPDWORD );
- typedef DWORD (* RASENUMENTRIES)( LPCWSTR, LPCWSTR, LPRASENTRYNAMEW, LPDWORD, LPDWORD );
- typedef DWORD (* RASGETCONNECTSTATUS)( HRASCONN, LPRASCONNSTATUSW );
- typedef DWORD (* RASGETERRORSTRING)( UINT, LPWSTR, DWORD );
- typedef DWORD (* RASHANGUP)( HRASCONN );
- typedef DWORD (* RASGETPROJECTIONINFO)( HRASCONN, RASPROJECTION, LPVOID, LPDWORD );
- typedef DWORD (* RASCREATEPHONEBOOKENTRY)( HWND, LPCWSTR );
- typedef DWORD (* RASEDITPHONEBOOKENTRY)( HWND, LPCWSTR, LPCWSTR );
- typedef DWORD (* RASSETENTRYDIALPARAMS)( LPCWSTR, LPRASDIALPARAMSW, BOOL );
- typedef DWORD (* RASGETENTRYDIALPARAMS)( LPCWSTR, LPRASDIALPARAMSW, LPBOOL );
- typedef DWORD (* RASENUMDEVICES)( LPRASDEVINFOW, LPDWORD, LPDWORD );
- typedef DWORD (* RASGETCOUNTRYINFO)( LPRASCTRYINFOW, LPDWORD );
- typedef DWORD (* RASGETENTRYPROPERTIES)( LPCWSTR, LPCWSTR, LPRASENTRYW, LPDWORD, LPBYTE, LPDWORD );
- typedef DWORD (* RASSETENTRYPROPERTIES)( LPCWSTR, LPCWSTR, LPRASENTRYW, DWORD, LPBYTE, DWORD );
- typedef DWORD (* RASRENAMEENTRY)( LPCWSTR, LPCWSTR, LPCWSTR );
- typedef DWORD (* RASDELETEENTRY)( LPCWSTR, LPCWSTR );
- typedef DWORD (* RASVALIDATEENTRYNAME)( LPCWSTR, LPCWSTR );
- typedef DWORD (* RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
-
- static const char gs_funcSuffix = 'W';
+ 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 wxRasThreadData
+struct WXDLLEXPORT wxRasThreadData
{
wxRasThreadData()
{
// 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,
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);
// for wxRasStatusWindowProc
void OnConnectStatusChange();
+ void OnDialProgress(RASCONNSTATE rasconnstate, DWORD dwError);
// for wxRasDialFunc
- void OnDialProgress(RASCONNSTATE rasconnstate, DWORD dwError);
+ static HWND GetRasWindow() { return ms_hwndRas; }
static wxDialUpManagerMSW *GetDialer() { return ms_dialer; }
private:
void CleanUpThreadData();
// timer used for polling RAS status
- class RasTimer : public wxTimer
+ class WXDLLEXPORT RasTimer : public wxTimer
{
public:
RasTimer(wxDialUpManagerMSW *dialUpManager)
// each other
wxRasThreadData m_data;
+ // the handle of rasapi32.dll when it's loaded
+ wxPluginManager 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 use count of rasapi32.dll
- static int ms_nDllCount;
-
- // the handle of rasapi32.dll when it's loaded
- static wxDllType ms_dllRas;
+ // FIXME: There is probably no reason these really need to
+ // be static anymore since the dll refcounting is
+ // handled by wxPluginManager now. Whether or not
+ // we still _want_ them to be static is another
+ // issue entirely..
// the pointers to RAS functions
static RASDIAL ms_pfnRasDial;
// this flag tells us if we're online
static int ms_isConnected;
+ // this flag is the result of the call to IsAlwaysOnline() (-1 if not
+ // called yet)
+ static int ms_isAlwaysOnline;
+
// this flag tells us whether a call to RasDial() is in progress
static wxDialUpManagerMSW *ms_dialer;
};
HRASCONN wxDialUpManagerMSW::ms_hRasConnection = 0;
-int wxDialUpManagerMSW::ms_nDllCount = 0;
-wxDllType wxDialUpManagerMSW::ms_dllRas = 0;
+HWND wxDialUpManagerMSW::ms_hwndRas = 0;
RASDIAL wxDialUpManagerMSW::ms_pfnRasDial = 0;
RASENUMCONNECTIONS wxDialUpManagerMSW::ms_pfnRasEnumConnections = 0;
int wxDialUpManagerMSW::ms_userSpecifiedOnlineStatus = -1;
int wxDialUpManagerMSW::ms_isConnected = -1;
+int wxDialUpManagerMSW::ms_isAlwaysOnline = -1;
wxDialUpManagerMSW *wxDialUpManagerMSW::ms_dialer = NULL;
// ----------------------------------------------------------------------------
wxDialUpManagerMSW::wxDialUpManagerMSW()
: m_timerStatusPolling(this)
+ , m_dllRas(_T("RASAPI32"))
{
// initialize our data
m_hThread = 0;
- if ( !ms_nDllCount++ )
+ 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 )
{
- // load the RAS library
- ms_dllRas = wxDllLoader::LoadLibrary("RASAPI32");
- if ( !ms_dllRas )
+ // 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
{
- wxLogError(_("Dial up functions are unavailable because the "
- "remote access service (RAS) is not installed "
- "on this machine. Please install it."));
+ 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);
}
- else
- {
- // 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)wxDllLoader::GetSymbol(ms_dllRas, \
- wxString(#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)wxDllLoader::GetSymbol(ms_dllRas, \
- wxString(#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);
-
- // suppress wxDllLoader 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(RASGETENTRYDIALPARAMS, RasGetEntryDialParams);
- 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);
- }
- // keep your preprocessor name space clean
- #undef RESOLVE_RAS_FUNCTION
- #undef RESOLVE_OPTIONAL_RAS_FUNCTION
+ // keep your preprocessor name space clean
+ #undef RESOLVE_RAS_FUNCTION
+ #undef RESOLVE_OPTIONAL_RAS_FUNCTION
exit:
- if ( funcName )
- {
- wxLogError(_("The version of remote access service (RAS) "
- "installed on this machine is too old, please "
- "upgrade (the following required function is "
- "missing: %s)."), funcName);
-
- wxDllLoader::UnloadLibrary(ms_dllRas);
- ms_dllRas = 0;
- ms_nDllCount = 0;
-
- return;
- }
+ if ( funcName )
+ {
+ static const wxChar *msg = wxTRANSLATE(
+"The version of remote access service (RAS) installed on this machine is too\
+old, please upgrade (the following required function is missing: %s)."
+ );
+
+ wxLogError(wxGetTranslation(msg), funcName);
+ m_dllRas.Unload();
+ return;
}
}
wxDialUpManagerMSW::~wxDialUpManagerMSW()
{
CleanUpThreadData();
-
- if ( !--ms_nDllCount )
- {
- // unload the RAS library
- wxDllLoader::UnloadLibrary(ms_dllRas);
- ms_dllRas = 0;
- }
}
// ----------------------------------------------------------------------------
default:
{
- wxLogSysError(dwRet, _("Failed to retrieve text of RAS "
- "error message"));
+ wxLogSysError(dwRet,
+ _("Failed to retrieve text of RAS error message"));
wxString msg;
msg.Printf(_("unknown error (error code %08x)."), error);
{
// an error occured
wxLogError(_("Cannot find active dialup connection: %s"),
- GetErrorString(dwRet));
+ GetErrorString(dwRet).c_str());
return 0;
}
}
// connection) - the warning is really needed because this function
// is used, for example, to select the connection to hang up and so
// we may hang up the wrong connection here...
- wxLogWarning(_("Several active dialup connections found, "
- "choosing one randomly."));
+ wxLogWarning(_("Several active dialup connections found, choosing one randomly."));
// fall through
case 1:
{
if ( !SetEvent(m_data.hEventQuit) )
{
- wxLogLastError("SetEvent(RasThreadQuit)");
+ wxLogLastError(_T("SetEvent(RasThreadQuit)"));
}
CloseHandle(m_hThread);
if ( dwError )
{
wxLogError(_("Failed to establish dialup connection: %s"),
- GetErrorString(dwError));
+ GetErrorString(dwError).c_str());
// we should still call RasHangUp() if we got a non 0 connection
if ( ms_hRasConnection )
bool wxDialUpManagerMSW::IsOk() const
{
- return ms_dllRas != 0;
+ return m_dllRas.IsLoaded();
+}
+
+size_t wxDialUpManagerMSW::GetISPNames(wxArrayString& names) const
+{
+ // fetch the entries
+ DWORD size = sizeof(RASENTRYNAME);
+ RASENTRYNAME *rasEntries = (RASENTRYNAME *)malloc(size);
+ rasEntries->dwSize = sizeof(RASENTRYNAME);
+
+ DWORD nEntries;
+ DWORD dwRet;
+ do
+ {
+ dwRet = ms_pfnRasEnumEntries
+ (
+ NULL, // reserved
+ NULL, // default phone book (or all)
+ rasEntries, // [out] buffer for the entries
+ &size, // [in/out] size of the buffer
+ &nEntries // [out] number of entries fetched
+ );
+
+ if ( dwRet == ERROR_BUFFER_TOO_SMALL )
+ {
+ // reallocate the buffer
+ rasEntries = (RASENTRYNAME *)realloc(rasEntries, size);
+ }
+ else if ( dwRet != 0 )
+ {
+ // some other error - abort
+ wxLogError(_("Failed to get ISP names: %s"),
+ GetErrorString(dwRet).c_str());
+
+ free(rasEntries);
+
+ return 0u;
+ }
+ }
+ while ( dwRet != 0 );
+
+ // process them
+ names.Empty();
+ for ( size_t n = 0; n < (size_t)nEntries; n++ )
+ {
+ names.Add(rasEntries[n].szEntryName);
+ }
+
+ free(rasEntries);
+
+ // return the number of entries
+ return names.GetCount();
}
bool wxDialUpManagerMSW::Dial(const wxString& nameOfISP,
const wxString& password,
bool async)
{
- wxCHECK_MSG( IsOk(), FALSE, T("using uninitialized wxDialUpManager") );
+ // check preconditions
+ wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
if ( ms_hRasConnection )
{
- wxFAIL_MSG(T("there is already an active connection"));
+ wxFAIL_MSG(wxT("there is already an active connection"));
return TRUE;
}
+ // get the default ISP if none given
+ wxString entryName(nameOfISP);
+ if ( !entryName )
+ {
+ wxArrayString names;
+ size_t count = GetISPNames(names);
+ switch ( count )
+ {
+ case 0:
+ // no known ISPs, abort
+ wxLogError(_("Failed to connect: no ISP to dial."));
+
+ return FALSE;
+
+ case 1:
+ // only one ISP, choose it
+ entryName = names[0u];
+ break;
+
+ default:
+ // several ISPs, let the user choose
+ {
+ wxString *strings = new wxString[count];
+ for ( size_t i = 0; i < count; i++ )
+ {
+ strings[i] = names[i];
+ }
+
+ entryName = wxGetSingleChoice
+ (
+ _("Choose ISP to dial"),
+ _("Please choose which ISP do you want to connect to"),
+ count,
+ strings
+ );
+
+ delete [] strings;
+
+ if ( !entryName )
+ {
+ // cancelled by user
+ return FALSE;
+ }
+ }
+ }
+ }
+
RASDIALPARAMS rasDialParams;
rasDialParams.dwSize = sizeof(rasDialParams);
- strncpy(rasDialParams.szEntryName, nameOfISP, RAS_MaxEntryName);
+ wxStrncpy(rasDialParams.szEntryName, entryName, RAS_MaxEntryName);
+
+ // do we have the username and password?
+ if ( !username || !password )
+ {
+ BOOL gotPassword;
+ DWORD dwRet = ms_pfnRasGetEntryDialParams
+ (
+ NULL, // default phonebook
+ &rasDialParams, // [in/out] the params of this entry
+ &gotPassword // [out] did we get password?
+ );
+
+ if ( dwRet != 0 )
+ {
+ wxLogError(_("Failed to connect: missing username/password."));
+
+ return FALSE;
+ }
+ }
+ else
+ {
+ wxStrncpy(rasDialParams.szUserName, username, UNLEN);
+ wxStrncpy(rasDialParams.szPassword, password, PWLEN);
+ }
+
+ // default values for other fields
rasDialParams.szPhoneNumber[0] = '\0';
rasDialParams.szCallbackNumber[0] = '\0';
rasDialParams.szCallbackNumber[0] = '\0';
- strncpy(rasDialParams.szUserName, username, UNLEN);
- strncpy(rasDialParams.szPassword, password, PWLEN);
-
rasDialParams.szDomain[0] = '*';
rasDialParams.szDomain[1] = '\0';
DWORD dwRet = ms_pfnRasDial
(
- (LPRASDIALEXTENSIONS)NULL, // no extended features
- NULL, // default phone book file (NT only)
+ NULL, // no extended features
+ NULL, // default phone book file (NT only)
&rasDialParams,
- 0, // use callback for notifications
- async ? wxRasDialFunc // the callback
- : 0, // no notifications - sync operation
+ 0, // use callback for notifications
+ async ? (void *)wxRasDialFunc // cast needed for gcc 3.1
+ : 0, // no notifications, sync operation
&ms_hRasConnection
);
if ( dwRet != 0 )
{
+ // can't pass a wxWCharBuffer through ( ... )
wxLogError(_("Failed to %s dialup connection: %s"),
- async ? _("initiate") : _("establish"),
- GetErrorString(dwRet));
+ wxString(async ? _("initiate") : _("establish")).c_str(),
+ GetErrorString(dwRet).c_str());
// we should still call RasHangUp() if we got a non 0 connection
if ( ms_hRasConnection )
return FALSE;
}
- wxASSERT_MSG( ms_hRasConnection, T("dialing but no connection?") );
+ wxASSERT_MSG( ms_hRasConnection, wxT("dialing but no connection?") );
ms_dialer = NULL;
bool wxDialUpManagerMSW::HangUp()
{
- wxCHECK_MSG( IsOk(), FALSE, T("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
// we may terminate either the connection we initiated or another one which
// is active now
if ( dwRet != 0 )
{
wxLogError(_("Failed to terminate the dialup connection: %s"),
- GetErrorString(dwRet));
+ GetErrorString(dwRet).c_str());
}
ms_isConnected = FALSE;
return TRUE;
}
+bool wxDialUpManagerMSW::IsAlwaysOnline() const
+{
+ // we cache the result (presumably this won't change while the program is
+ // running!)
+ if ( ms_isAlwaysOnline != -1 )
+ {
+ return ms_isAlwaysOnline != 0;
+ }
+
+ // try to use WinInet function first
+
+ // NB: we could probably use wxDynamicLibrary here just as well,
+ // but we allow multiple instances of wxDialUpManagerMSW so
+ // we might as well use the ref counted version here too.
+
+ wxPluginManager hDll(_T("WININET"));
+ if ( hDll.IsLoaded() )
+ {
+ typedef BOOL (WINAPI *INTERNETGETCONNECTEDSTATE)(LPDWORD, DWORD);
+ INTERNETGETCONNECTEDSTATE pfnInternetGetConnectedState;
+
+ #define RESOLVE_FUNCTION(type, name) \
+ pfn##name = (type)hDll.GetSymbol(_T(#name))
+
+ RESOLVE_FUNCTION(INTERNETGETCONNECTEDSTATE, InternetGetConnectedState);
+
+ if ( pfnInternetGetConnectedState )
+ {
+ DWORD flags = 0;
+ if ( pfnInternetGetConnectedState(&flags, 0 /* reserved */) )
+ {
+ // there is some connection to the net, see of which type
+ ms_isAlwaysOnline = ((flags & INTERNET_CONNECTION_LAN) != 0)
+ || ((flags & INTERNET_CONNECTION_PROXY) != 0);
+ }
+ else
+ {
+ // no Internet connection at all
+ ms_isAlwaysOnline = FALSE;
+ }
+ }
+ }
+
+ // did we succeed with WinInet? if not, try something else
+ if ( ms_isAlwaysOnline == -1 )
+ {
+ if ( !IsOnline() )
+ {
+ // definitely no permanent connection because we are not connected
+ // now
+ ms_isAlwaysOnline = FALSE;
+ }
+ else
+ {
+ // of course, having a modem doesn't prevent us from having a
+ // permanent connection as well, but we have to guess somehow and
+ // it's probably more common that a system connected via a modem
+ // doesn't have any other net access, so:
+ ms_isAlwaysOnline = FALSE;
+ }
+ }
+
+ wxASSERT_MSG( ms_isAlwaysOnline != -1, wxT("logic error") );
+
+ return ms_isAlwaysOnline != 0;
+}
+
bool wxDialUpManagerMSW::IsOnline() const
{
- wxCHECK_MSG( IsOk(), FALSE, T("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
if ( ms_userSpecifiedOnlineStatus != -1 )
{
void wxDialUpManagerMSW::SetOnlineStatus(bool isOnline)
{
- wxCHECK_RET( IsOk(), T("using uninitialized wxDialUpManager") );
+ wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
ms_userSpecifiedOnlineStatus = isOnline;
}
bool wxDialUpManagerMSW::EnableAutoCheckOnlineStatus(size_t nSeconds)
{
- wxCHECK_MSG( IsOk(), FALSE, T("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
bool ok = ms_pfnRasConnectionNotification != 0;
dwSuspendCount = ResumeThread(m_hThread);
if ( dwSuspendCount == (DWORD)-1 )
{
- wxLogLastError("ResumeThread(RasThread)");
+ wxLogLastError(wxT("ResumeThread(RasThread)"));
ok = FALSE;
}
);
if ( !m_data.hEventRas )
{
- wxLogLastError("CreateEvent(RasStatus)");
+ wxLogLastError(wxT("CreateEvent(RasStatus)"));
ok = FALSE;
}
m_data.hEventQuit = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( !m_data.hEventQuit )
{
- wxLogLastError("CreateEvent(RasThreadQuit)");
+ wxLogLastError(wxT("CreateEvent(RasThreadQuit)"));
CleanUpThreadData();
}
}
- if ( ok )
+ if ( ok && !ms_hwndRas )
{
// create a hidden window to receive notification about connections
// status change
- extern wxChar wxPanelClassName[];
- m_data.hWnd = ::CreateWindow(wxPanelClassName, NULL,
- 0, 0, 0, 0,
- 0, NULL,
- (HMENU)NULL, wxGetInstance(), 0);
- if ( !m_data.hWnd )
+ extern const wxChar *wxCanvasClassName;
+ ms_hwndRas = ::CreateWindow(wxCanvasClassName, NULL,
+ 0, 0, 0, 0,
+ 0, NULL,
+ (HMENU)NULL, wxGetInstance(), 0);
+ if ( !ms_hwndRas )
{
- wxLogLastError("CreateWindow(RasHiddenWindow)");
+ wxLogLastError(wxT("CreateWindow(RasHiddenWindow)"));
CleanUpThreadData();
wxGetInstance()
);
- ::SetWindowLong(m_data.hWnd, GWL_WNDPROC, (LONG) windowProc);
+ ::SetWindowLong(ms_hwndRas, GWL_WNDPROC, (LONG) windowProc);
}
+ m_data.hWnd = ms_hwndRas;
+
if ( ok )
{
// start the secondary thread
if ( !m_hThread )
{
- wxLogLastError("CreateThread(RasStatusThread)");
+ wxLogLastError(wxT("CreateThread(RasStatusThread)"));
CleanUpThreadData();
}
if ( dwRet != 0 )
{
- wxLogDebug(T("RasConnectionNotification() failed: %s"),
- GetErrorString(dwRet));
+ wxLogDebug(wxT("RasConnectionNotification() failed: %s"),
+ GetErrorString(dwRet).c_str());
CleanUpThreadData();
}
void wxDialUpManagerMSW::DisableAutoCheckOnlineStatus()
{
- wxCHECK_RET( IsOk(), T("using uninitialized wxDialUpManager") );
+ wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
if ( m_hThread )
{
// we have running secondary thread, it's just enough to suspend it
if ( SuspendThread(m_hThread) == (DWORD)-1 )
{
- wxLogLastError("SuspendThread(RasThread)");
+ wxLogLastError(wxT("SuspendThread(RasThread)"));
}
}
else
void wxDialUpManagerMSW::SetWellKnownHost(const wxString& WXUNUSED(hostname),
int WXUNUSED(port))
{
- wxCHECK_RET( IsOk(), T("using uninitialized wxDialUpManager") );
+ wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
// nothing to do - we don't use this
}
void wxDialUpManagerMSW::SetConnectCommand(const wxString& WXUNUSED(dial),
const wxString& WXUNUSED(hangup))
{
- wxCHECK_RET( IsOk(), T("using uninitialized wxDialUpManager") );
+ wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
// nothing to do - we don't use this
}
break;
case WAIT_FAILED:
- wxLogLastError("WaitForMultipleObjects(RasMonitor)");
+ wxLogLastError(wxT("WaitForMultipleObjects(RasMonitor)"));
break;
}
}
wxRasThreadData *data = (wxRasThreadData *)lParam;
data->dialUpManager->OnConnectStatusChange();
}
+ else if ( message == wxWM_RAS_DIALING_PROGRESS )
+ {
+ wxDialUpManagerMSW *dialUpManager = wxDialUpManagerMSW::GetDialer();
+
+ dialUpManager->OnDialProgress((RASCONNSTATE)wParam, lParam);
+ }
return 0;
}
{
wxDialUpManagerMSW *dialUpManager = wxDialUpManagerMSW::GetDialer();
- wxCHECK_RET( dialUpManager, T("who started to dial then?") );
+ wxCHECK_RET( dialUpManager, wxT("who started to dial then?") );
- dialUpManager->OnDialProgress(rasconnstate, dwError);
+ SendMessage(dialUpManager->GetRasWindow(), wxWM_RAS_DIALING_PROGRESS,
+ rasconnstate, dwError);
}
+#endif // __BORLANDC__
+
#endif // wxUSE_DIALUP_MANAGER
+