dialup.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,333 行 · 第 1/3 页
CPP
1,333 行
ms_dialer = NULL;
return false;
}
// for async dialing, we're not yet connected
if ( !async )
{
ms_isConnected = true;
}
return true;
}
bool wxDialUpManagerMSW::IsDialing() const
{
return GetDialer() != NULL;
}
bool wxDialUpManagerMSW::CancelDialing()
{
if ( !GetDialer() )
{
// silently ignore
return false;
}
wxASSERT_MSG( ms_hRasConnection, wxT("dialing but no connection?") );
ms_dialer = NULL;
return HangUp();
}
bool wxDialUpManagerMSW::HangUp()
{
wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
// we may terminate either the connection we initiated or another one which
// is active now
HRASCONN hRasConn;
if ( ms_hRasConnection )
{
hRasConn = ms_hRasConnection;
ms_hRasConnection = 0;
}
else
{
hRasConn = FindActiveConnection();
}
if ( !hRasConn )
{
wxLogError(_("Cannot hang up - no active dialup connection."));
return false;
}
// 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;
return true;
}
bool wxDialUpManagerMSW::IsAlwaysOnline() const
{
// assume no permanent connection by default
bool isAlwaysOnline = false;
// try to use WinInet functions
// 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.
wxDynamicLibrary 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
isAlwaysOnline = (flags & (INTERNET_CONNECTION_LAN |
INTERNET_CONNECTION_PROXY)) != 0;
}
//else: no Internet connection at all
}
}
return isAlwaysOnline;
}
bool wxDialUpManagerMSW::IsOnline() const
{
wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
if ( IsAlwaysOnline() )
{
// always => now
return true;
}
if ( ms_userSpecifiedOnlineStatus != -1 )
{
// user specified flag overrides our logic
return ms_userSpecifiedOnlineStatus != 0;
}
else
{
// return true if there is at least one active connection
return FindActiveConnection() != 0;
}
}
void wxDialUpManagerMSW::SetOnlineStatus(bool isOnline)
{
wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
ms_userSpecifiedOnlineStatus = isOnline;
}
bool wxDialUpManagerMSW::EnableAutoCheckOnlineStatus(size_t nSeconds)
{
wxCHECK_MSG( IsOk(), false, wxT("using uninitialized wxDialUpManager") );
if ( m_autoCheckLevel++ )
{
// already checking
return true;
}
bool ok = ms_pfnRasConnectionNotification != 0;
if ( ok )
{
// we're running under NT 4.0, Windows 98 or later and can use
// RasConnectionNotification() to be notified by a secondary thread
// first, see if we don't have this thread already running
if ( m_hThread != 0 )
{
if ( ::ResumeThread(m_hThread) != (DWORD)-1 )
return true;
// we're leaving a zombie thread... but what else can we do?
wxLogLastError(wxT("ResumeThread(RasThread)"));
ok = false;
}
}
// create all the stuff we need to be notified about RAS connection
// status change
if ( ok )
{
// first create an event to wait on
m_data->hEventRas = ::CreateEvent
(
NULL, // security attribute (default)
FALSE, // manual reset (no, it is automatic)
FALSE, // initial state (not signaled)
NULL // name (no)
);
if ( !m_data->hEventRas )
{
wxLogLastError(wxT("CreateEvent(RasStatus)"));
ok = false;
}
}
if ( ok )
{
// create the event we use to quit the thread: using a manual event
// 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
(
NULL, // default security
TRUE, // manual event
FALSE, // initially non signalled
NULL // nameless
);
if ( !m_data->hEventQuit )
{
wxLogLastError(wxT("CreateEvent(RasThreadQuit)"));
CleanUpThreadData();
ok = false;
}
}
if ( ok && !ms_hwndRas )
{
// create a hidden window to receive notification about connections
// status change
ms_hwndRas = wxCreateHiddenWindow
(
&gs_classForDialUpWindow,
wxMSWDIALUP_WNDCLASSNAME,
wxRasStatusWindowProc
);
if ( !ms_hwndRas )
{
wxLogLastError(wxT("CreateWindow(RasHiddenWindow)"));
CleanUpThreadData();
ok = false;
}
}
m_data->hWnd = ms_hwndRas;
if ( ok )
{
// start the secondary thread
m_data->dialUpManager = this;
DWORD tid;
m_hThread = CreateThread
(
NULL,
0,
(LPTHREAD_START_ROUTINE)wxRasMonitorThread,
(void *)m_data,
0,
&tid
);
if ( !m_hThread )
{
wxLogLastError(wxT("CreateThread(RasStatusThread)"));
CleanUpThreadData();
}
}
if ( ok )
{
// start receiving RAS notifications
DWORD dwRet = ms_pfnRasConnectionNotification
(
(HRASCONN)INVALID_HANDLE_VALUE,
m_data->hEventRas,
3 /* RASCN_Connection | RASCN_Disconnection */
);
if ( dwRet != 0 )
{
wxLogDebug(wxT("RasConnectionNotification() failed: %s"),
GetErrorString(dwRet).c_str());
CleanUpThreadData();
}
else
{
return true;
}
}
// we're running under Windows 95 and have to poll ourselves
// (or, alternatively, the code above for NT/98 failed)
m_timerStatusPolling.Stop();
if ( nSeconds == 0 )
{
// default value
nSeconds = 60;
}
m_timerStatusPolling.Start(nSeconds * 1000);
return true;
}
void wxDialUpManagerMSW::DisableAutoCheckOnlineStatus()
{
wxCHECK_RET( IsOk(), wxT("using uninitialized wxDialUpManager") );
if ( --m_autoCheckLevel )
{
// still checking
return;
}
if ( m_hThread )
{
// we have running secondary thread, it's just enough to suspend it
if ( SuspendThread(m_hThread) == (DWORD)-1 )
{
wxLogLastError(wxT("SuspendThread(RasThread)"));
}
}
else
{
// even simpler - just stop the timer
m_timerStatusPolling.Stop();
}
}
// ----------------------------------------------------------------------------
// stubs which don't do anything in MSW version
// ----------------------------------------------------------------------------
void wxDialUpManagerMSW::SetWellKnownHost(const wxString& WXUNUSED(hostname),
int WXUNUSED(port))
{
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(), wxT("using uninitialized wxDialUpManager") );
// nothing to do - we don't use this
}
// ----------------------------------------------------------------------------
// callbacks
// ----------------------------------------------------------------------------
static DWORD wxRasMonitorThread(wxRasThreadData *data)
{
HANDLE handles[2];
handles[0] = data->hEventRas;
handles[1] = data->hEventQuit;
bool cont = true;
while ( cont )
{
DWORD dwRet = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
switch ( dwRet )
{
case WAIT_OBJECT_0:
// RAS connection status changed
SendMessage(data->hWnd, wxWM_RAS_STATUS_CHANGED,
0, (LPARAM)data);
break;
case WAIT_OBJECT_0 + 1:
cont = false;
break;
default:
wxFAIL_MSG( _T("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 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...
return (DWORD)-1;
}
}
// we don't need it any more now and if this thread ran, it is our
// responsability to free the data
delete data;
return 0;
}
static LRESULT APIENTRY wxRasStatusWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch ( message )
{
case wxWM_RAS_STATUS_CHANGED:
{
wxRasThreadData *data = (wxRasThreadData *)lParam;
data->dialUpManager->OnConnectStatusChange();
}
break;
case wxWM_RAS_DIALING_PROGRESS:
{
wxDialUpManagerMSW *dialMan = wxDialUpManagerMSW::GetDialer();
dialMan->OnDialProgress((RASCONNSTATE)wParam, lParam);
}
break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
static void WINAPI wxRasDialFunc(UINT WXUNUSED(unMsg),
RASCONNSTATE rasconnstate,
DWORD dwError)
{
wxDialUpManagerMSW *dialUpManager = wxDialUpManagerMSW::GetDialer();
wxCHECK_RET( dialUpManager, wxT("who started to dial then?") );
SendMessage(wxDialUpManagerMSW::GetRasWindow(), wxWM_RAS_DIALING_PROGRESS,
rasconnstate, dwError);
}
#endif // __BORLANDC__
#endif // wxUSE_DIALUP_MANAGER
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?