/////////////////////////////////////////////////////////////////////////////
-// Name: msw/dialup.cpp
+// Name: src/msw/dialup.cpp
// Purpose: MSW implementation of network/dialup classes and functions
// Author: Vadim Zeitlin
// Modified by:
#if wxUSE_DIALUP_MANAGER
+#include "wx/dialup.h"
+
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/event.h"
+ #include "wx/app.h"
+ #include "wx/timer.h"
+ #include "wx/module.h"
#endif
-#include "wx/timer.h"
-#include "wx/app.h"
#include "wx/generic/choicdgg.h"
+#include "wx/msw/private.h"
+#include "wx/msw/private/hiddenwin.h"
#include "wx/dynlib.h"
-#include "wx/dialup.h"
-DEFINE_EVENT_TYPE(wxEVT_DIALUP_CONNECTED)
-DEFINE_EVENT_TYPE(wxEVT_DIALUP_DISCONNECTED)
+wxDEFINE_EVENT( wxEVT_DIALUP_CONNECTED, wxDialUpEvent );
+wxDEFINE_EVENT( wxEVT_DIALUP_DISCONNECTED, wxDialUpEvent );
// Doesn't yet compile under VC++ 4, BC++, Watcom C++,
// Wine: no wininet.h
#define INTERNET_CONNECTION_PROXY 4
#endif
+static const wxChar *
+ wxMSWDIALUP_WNDCLASSNAME = wxT("_wxDialUpManager_Internal_Class");
+static const wxChar *gs_classForDialUpWindow = NULL;
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
typedef DWORD (APIENTRY * RASVALIDATEENTRYNAME)( LPCSTR, LPCSTR );
typedef DWORD (APIENTRY * RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
- static const wxChar gs_funcSuffix = _T('A');
+ static const wxChar gs_funcSuffix = wxT('A');
#else // Unicode
typedef DWORD (APIENTRY * RASDIAL)( LPRASDIALEXTENSIONS, LPCWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN );
typedef DWORD (APIENTRY * RASENUMCONNECTIONS)( LPRASCONNW, LPDWORD, LPDWORD );
typedef DWORD (APIENTRY * RASVALIDATEENTRYNAME)( LPCWSTR, LPCWSTR );
typedef DWORD (APIENTRY * RASCONNECTIONNOTIFICATION)( HRASCONN, HANDLE, DWORD );
- static const wxChar gs_funcSuffix = _T('W');
+ static const wxChar gs_funcSuffix = wxT('W');
#endif // ASCII/Unicode
// structure passed to the secondary thread
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
+ class WXDLLIMPEXP_FWD_CORE wxDialUpManagerMSW *dialUpManager; // the owner
};
// ----------------------------------------------------------------------------
virtual bool HangUp();
virtual bool IsAlwaysOnline() const;
virtual bool IsOnline() const;
- virtual void SetOnlineStatus(bool isOnline = TRUE);
+ virtual void SetOnlineStatus(bool isOnline = true);
virtual bool EnableAutoCheckOnlineStatus(size_t nSeconds);
virtual void DisableAutoCheckOnlineStatus();
virtual void SetWellKnownHost(const wxString& hostname, int port);
// for wxRasDialFunc
static HWND GetRasWindow() { return ms_hwndRas; }
+ static void ResetRasWindow() { ms_hwndRas = NULL; }
static wxDialUpManagerMSW *GetDialer() { return ms_dialer; }
private:
static HRASCONN FindActiveConnection();
// notify the application about status change
- void NotifyApp(bool connected, bool fromOurselves = FALSE) const;
+ void NotifyApp(bool connected, bool fromOurselves = false) const;
// destroy the thread data and the thread itself
void CleanUpThreadData();
private:
wxDialUpManagerMSW *m_dialUpManager;
- DECLARE_NO_COPY_CLASS(RasTimer)
+ wxDECLARE_NO_COPY_CLASS(RasTimer);
} m_timerStatusPolling;
// thread handle for the thread sitting on connection change event
// this flag tells us whether a call to RasDial() is in progress
static wxDialUpManagerMSW *ms_dialer;
- DECLARE_NO_COPY_CLASS(wxDialUpManagerMSW)
+ wxDECLARE_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
// ----------------------------------------------------------------------------
wxDialUpManagerMSW::wxDialUpManagerMSW()
: m_timerStatusPolling(this),
- m_dllRas(_T("RASAPI32"))
+ m_dllRas(wxT("RASAPI32"))
{
// initialize our data
m_autoCheckLevel = 0;
// 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)) \
+ ms_pfn##name = (type)m_dllRas.GetSymbol( wxString(wxT(#name)) \
+ gs_funcSuffix); \
if ( !ms_pfn##name ) \
{ \
// 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)) \
+ ms_pfn##name = (type)m_dllRas.GetSymbol( wxString(wxT(#name)) \
+ gs_funcSuffix);
RESOLVE_RAS_FUNCTION(RASDIAL, RasDial);
exit:
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);
+ 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);
m_dllRas.Unload();
return;
}
case 0:
// we want the error message to start from a lower case letter
- buffer[0] = wxTolower(buffer[0]);
+ buffer[0] = (wxChar)wxTolower(buffer[0]);
return wxString(buffer);
}
}
else
{
- // an error occured
+ // an error occurred
wxLogError(_("Cannot find active dialup connection: %s"),
GetErrorString(dwRet).c_str());
return 0;
{
if ( !SetEvent(m_data->hEventQuit) )
{
- wxLogLastError(_T("SetEvent(RasThreadQuit)"));
+ wxLogLastError(wxT("SetEvent(RasThreadQuit)"));
}
else // sent quit request to the background thread
{
m_hThread = 0;
}
- if ( m_data )
- {
- delete m_data;
- m_data = NULL;
- }
+ wxDELETE(m_data);
}
// ----------------------------------------------------------------------------
ms_dialer = NULL;
- NotifyApp(FALSE /* !connected */, TRUE /* we dialed ourselves */);
+ NotifyApp(false /* !connected */, true /* we dialed ourselves */);
}
else if ( rasconnstate == RASCS_Connected )
{
- ms_isConnected = TRUE;
+ ms_isConnected = true;
ms_dialer = NULL;
- NotifyApp(TRUE /* connected */, TRUE /* we dialed ourselves */);
+ NotifyApp(true /* connected */, true /* we dialed ourselves */);
}
}
if ( dwRet == ERROR_BUFFER_TOO_SMALL )
{
// reallocate the buffer
- rasEntries = (RASENTRYNAME *)realloc(rasEntries, size);
+ void *n = realloc(rasEntries, size);
+ if (n == NULL)
+ {
+ free(rasEntries);
+ return 0;
+ }
+ rasEntries = (RASENTRYNAME *)n;
}
else if ( dwRet != 0 )
{
bool async)
{
// check preconditions
- wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
if ( ms_hRasConnection )
{
wxFAIL_MSG(wxT("there is already an active connection"));
- return TRUE;
+ return true;
}
// get the default ISP if none given
// no known ISPs, abort
wxLogError(_("Failed to connect: no ISP to dial."));
- return FALSE;
+ return false;
case 1:
// only one ISP, choose it
if ( !entryName )
{
// cancelled by user
- return FALSE;
+ return false;
}
}
}
RASDIALPARAMS rasDialParams;
rasDialParams.dwSize = sizeof(rasDialParams);
- wxStrncpy(rasDialParams.szEntryName, entryName, RAS_MaxEntryName);
+ wxStrlcpy(rasDialParams.szEntryName, entryName.c_str(), RAS_MaxEntryName);
// do we have the username and password?
if ( !username || !password )
{
wxLogError(_("Failed to connect: missing username/password."));
- return FALSE;
+ return false;
}
}
else
{
- wxStrncpy(rasDialParams.szUserName, username, UNLEN);
- wxStrncpy(rasDialParams.szPassword, password, PWLEN);
+ wxStrlcpy(rasDialParams.szUserName, username.c_str(), UNLEN);
+ wxStrlcpy(rasDialParams.szPassword, password.c_str(), PWLEN);
}
// default values for other fields
if ( dwRet != 0 )
{
// can't pass a wxWCharBuffer through ( ... )
- wxLogError(_("Failed to %s dialup connection: %s"),
- wxString(async ? _("initiate") : _("establish")).c_str(),
- GetErrorString(dwRet).c_str());
+ if ( async )
+ {
+ wxLogError(_("Failed to initiate dialup connection: %s"),
+ GetErrorString(dwRet).c_str());
+ }
+ else
+ {
+ wxLogError(_("Failed to establish dialup connection: %s"),
+ GetErrorString(dwRet).c_str());
+ }
// we should still call RasHangUp() if we got a non 0 connection
if ( ms_hRasConnection )
ms_dialer = NULL;
- return FALSE;
+ return false;
}
// for async dialing, we're not yet connected
if ( !async )
{
- ms_isConnected = TRUE;
+ ms_isConnected = true;
}
- return TRUE;
+ return true;
}
bool wxDialUpManagerMSW::IsDialing() const
if ( !GetDialer() )
{
// silently ignore
- return FALSE;
+ return false;
}
wxASSERT_MSG( ms_hRasConnection, wxT("dialing but no connection?") );
bool wxDialUpManagerMSW::HangUp()
{
- wxCHECK_MSG( IsOk(), FALSE, wxT("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
{
wxLogError(_("Cannot hang up - no active dialup connection."));
- return FALSE;
+ return false;
}
- DWORD dwRet = ms_pfnRasHangUp(hRasConn);
- if ( dwRet != 0 )
+ // note that it's not an error if the connection had been already
+ // terminated
+ const DWORD dwRet = ms_pfnRasHangUp(hRasConn);
+ if ( dwRet != 0 && dwRet != ERROR_NO_CONNECTION )
{
wxLogError(_("Failed to terminate the dialup connection: %s"),
GetErrorString(dwRet).c_str());
}
- ms_isConnected = FALSE;
+ ms_isConnected = false;
- return TRUE;
+ return true;
}
bool wxDialUpManagerMSW::IsAlwaysOnline() const
{
// assume no permanent connection by default
- bool isAlwaysOnline = FALSE;
+ bool isAlwaysOnline = false;
// try to use WinInet functions
// but we allow multiple instances of wxDialUpManagerMSW so
// we might as well use the ref counted version here too.
- wxDynamicLibrary hDll(_T("WININET"));
+ wxDynamicLibrary hDll(wxT("WININET"));
if ( hDll.IsLoaded() )
{
typedef BOOL (WINAPI *INTERNETGETCONNECTEDSTATE)(LPDWORD, DWORD);
INTERNETGETCONNECTEDSTATE pfnInternetGetConnectedState;
#define RESOLVE_FUNCTION(type, name) \
- pfn##name = (type)hDll.GetSymbol(_T(#name))
+ pfn##name = (type)hDll.GetSymbol(wxT(#name))
RESOLVE_FUNCTION(INTERNETGETCONNECTEDSTATE, InternetGetConnectedState);
bool wxDialUpManagerMSW::IsOnline() const
{
- wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
if ( IsAlwaysOnline() )
{
}
else
{
- // return TRUE if there is at least one active connection
+ // return true if there is at least one active connection
return FindActiveConnection() != 0;
}
}
bool wxDialUpManagerMSW::EnableAutoCheckOnlineStatus(size_t nSeconds)
{
- wxCHECK_MSG( IsOk(), FALSE, wxT("using uninitialized wxDialUpManager") );
+ wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
if ( m_autoCheckLevel++ )
{
// already checking
- return TRUE;
+ return true;
}
bool ok = ms_pfnRasConnectionNotification != 0;
if ( m_hThread != 0 )
{
if ( ::ResumeThread(m_hThread) != (DWORD)-1 )
- return TRUE;
+ return true;
// we're leaving a zombie thread... but what else can we do?
wxLogLastError(wxT("ResumeThread(RasThread)"));
- ok = FALSE;
+ ok = false;
}
}
if ( ok )
{
// first create an event to wait on
- m_data->hEventRas = CreateEvent
+ m_data->hEventRas = ::CreateEvent
(
NULL, // security attribute (default)
FALSE, // manual reset (no, it is automatic)
{
wxLogLastError(wxT("CreateEvent(RasStatus)"));
- ok = FALSE;
+ ok = false;
}
}
// here avoids problems with missing the event if wxDialUpManagerMSW
// is created and destroyed immediately, before wxRasStatusWindowProc
// starts waiting on the event
- m_data->hEventQuit = CreateEvent
+ m_data->hEventQuit = ::CreateEvent
(
NULL, // default security
TRUE, // manual event
CleanUpThreadData();
- ok = FALSE;
+ ok = false;
}
}
{
// create a hidden window to receive notification about connections
// status change
- extern const wxChar *wxCanvasClassName;
- ms_hwndRas = ::CreateWindow(wxCanvasClassName, NULL,
- 0, 0, 0, 0,
- 0, NULL,
- (HMENU)NULL, wxGetInstance(), 0);
+ ms_hwndRas = wxCreateHiddenWindow
+ (
+ &gs_classForDialUpWindow,
+ wxMSWDIALUP_WNDCLASSNAME,
+ wxRasStatusWindowProc
+ );
if ( !ms_hwndRas )
{
wxLogLastError(wxT("CreateWindow(RasHiddenWindow)"));
CleanUpThreadData();
- ok = FALSE;
+ ok = false;
}
-
- // and subclass it
- wxSetWindowProc(ms_hwndRas, wxRasStatusWindowProc);
}
m_data->hWnd = ms_hwndRas;
}
else
{
- return TRUE;
+ return true;
}
}
}
m_timerStatusPolling.Start(nSeconds * 1000);
- return TRUE;
+ return true;
}
void wxDialUpManagerMSW::DisableAutoCheckOnlineStatus()
{
wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
- if ( --m_autoCheckLevel )
+ if ( --m_autoCheckLevel != 0 )
{
// still checking
return;
handles[0] = data->hEventRas;
handles[1] = data->hEventQuit;
- bool cont = TRUE;
+ bool cont = true;
while ( cont )
{
- DWORD dwRet = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+ DWORD dwRet = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
switch ( dwRet )
{
break;
case WAIT_OBJECT_0 + 1:
- cont = FALSE;
+ cont = false;
break;
default:
- wxFAIL_MSG( _T("unexpected return of WaitForMultipleObjects()") );
+ wxFAIL_MSG( wxT("unexpected return of WaitForMultipleObjects()") );
// fall through
case WAIT_FAILED:
-#ifdef __WXDEBUG__
// using wxLogLastError() from here is dangerous: we risk to
// deadlock the main thread if wxLog sends output to GUI
DWORD err = GetLastError();
- wxMessageOutputDebug().Printf
+ wxMessageOutputDebug dbg;
+ dbg.Printf
(
wxT("WaitForMultipleObjects(RasMonitor) failed: 0x%08lx (%s)"),
err,
wxSysErrorMsg(err)
);
-#endif // __WXDEBUG__
// no sense in continuing, who knows if the handles we're
// waiting for even exist yet...
wxCHECK_RET( dialUpManager, wxT("who started to dial then?") );
- SendMessage(dialUpManager->GetRasWindow(), wxWM_RAS_DIALING_PROGRESS,
+ SendMessage(wxDialUpManagerMSW::GetRasWindow(), wxWM_RAS_DIALING_PROGRESS,
rasconnstate, dwError);
}
#endif // __BORLANDC__
#endif // wxUSE_DIALUP_MANAGER
-