313 lines
7.6 KiB
C++
313 lines
7.6 KiB
C++
//
|
|
// Driver Verifier UI
|
|
// Copyright (c) Microsoft Corporation, 1999
|
|
//
|
|
//
|
|
//
|
|
// module: SlowDlg.cpp
|
|
// author: DMihai
|
|
// created: 11/1/00
|
|
//
|
|
// Description:
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "verifier.h"
|
|
|
|
#include "SlowDlg.h"
|
|
#include "VrfUtil.h"
|
|
#include "VGlobal.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSlowProgressDlg dialog
|
|
|
|
|
|
CSlowProgressDlg::CSlowProgressDlg( CWnd* pParent /*=NULL*/ )
|
|
: CDialog(CSlowProgressDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CSlowProgressDlg)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_hWorkerThread = NULL;
|
|
|
|
//
|
|
// Create the event used for killing the worker thread
|
|
//
|
|
|
|
m_hKillThreadEvent = CreateEvent(
|
|
NULL,
|
|
TRUE,
|
|
FALSE,
|
|
NULL );
|
|
}
|
|
|
|
CSlowProgressDlg::~CSlowProgressDlg()
|
|
{
|
|
if( NULL != m_hKillThreadEvent )
|
|
{
|
|
CloseHandle( m_hKillThreadEvent );
|
|
}
|
|
}
|
|
|
|
void CSlowProgressDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CSlowProgressDlg)
|
|
DDX_Control(pDX, IDC_UNSIGNED_PROGRESS, m_ProgressCtl);
|
|
DDX_Control(pDX, IDC_UNSIGNED_STATIC, m_CurrentActionStatic);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CSlowProgressDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CSlowProgressDlg)
|
|
ON_BN_CLICKED(IDC_UNSIGNED_CANCEL_BUTTON, OnCancelButton)
|
|
ON_WM_SHOWWINDOW()
|
|
ON_WM_HELPINFO()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD WINAPI CSlowProgressDlg::LoadDriverDataWorkerThread( PVOID p )
|
|
{
|
|
CSlowProgressDlg *pThis;
|
|
|
|
pThis = (CSlowProgressDlg *)p;
|
|
|
|
//
|
|
// Cannot ASSERT_VALID for a CWnd from a thread that didn't create the window in MFC...
|
|
//
|
|
|
|
ASSERT( NULL != pThis );
|
|
|
|
//
|
|
// Load all the drivers information (name, version, etc.)
|
|
// if we haven't don that already
|
|
//
|
|
|
|
g_NewVerifierSettings.m_DriversSet.LoadAllDriversData( pThis->m_hKillThreadEvent,
|
|
pThis->m_ProgressCtl );
|
|
|
|
//
|
|
// Done - hide the "slow progress" dialog and press the wizard "next" button
|
|
//
|
|
|
|
pThis->ShowWindow( SW_HIDE );
|
|
|
|
if( g_NewVerifierSettings.m_DriversSet.m_bDriverDataInitialized )
|
|
{
|
|
AfxGetMainWnd()->PostMessage(PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0) ;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD WINAPI CSlowProgressDlg::SearchUnsignedDriversWorkerThread( PVOID p )
|
|
{
|
|
CSlowProgressDlg *pThis;
|
|
|
|
pThis = (CSlowProgressDlg *)p;
|
|
|
|
//
|
|
// Cannot ASSERT_VALID for a CWnd from a thread that didn't create the window in MFC...
|
|
//
|
|
|
|
ASSERT( NULL != pThis );
|
|
|
|
//
|
|
// Find out the unsigned drivers if we didn't do that already
|
|
//
|
|
|
|
g_NewVerifierSettings.m_DriversSet.FindUnsignedDrivers( pThis->m_hKillThreadEvent,
|
|
pThis->m_ProgressCtl );
|
|
|
|
//
|
|
// Done - hide the "slow progress" dialog and press the wizard "next" button
|
|
//
|
|
|
|
pThis->ShowWindow( SW_HIDE );
|
|
|
|
if( g_NewVerifierSettings.m_DriversSet.m_bUnsignedDriverDataInitialized )
|
|
{
|
|
AfxGetMainWnd()->PostMessage(PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0) ;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CSlowProgressDlg::StartWorkerThread( LPTHREAD_START_ROUTINE pThreadStart,
|
|
ULONG uMessageResourceId )
|
|
{
|
|
DWORD dwThreadId;
|
|
CString strWorkMessage;
|
|
|
|
//
|
|
// Load a description of the current "work item"
|
|
// and show it to the user
|
|
//
|
|
|
|
VERIFY( strWorkMessage.LoadString( uMessageResourceId ) );
|
|
m_CurrentActionStatic.SetWindowText( strWorkMessage );
|
|
m_CurrentActionStatic.RedrawWindow();
|
|
|
|
//
|
|
// Kill a possible currently running worker thread
|
|
//
|
|
|
|
KillWorkerThread();
|
|
|
|
ASSERT( NULL == m_hWorkerThread );
|
|
|
|
//
|
|
// Make sure the "kill thread" event is not signaled
|
|
//
|
|
|
|
if( NULL != m_hKillThreadEvent )
|
|
{
|
|
ResetEvent( m_hKillThreadEvent );
|
|
}
|
|
|
|
//
|
|
// Create the new worker thread
|
|
//
|
|
|
|
m_hWorkerThread = CreateThread(
|
|
NULL,
|
|
0,
|
|
pThreadStart,
|
|
this,
|
|
0,
|
|
&dwThreadId );
|
|
|
|
if( NULL == m_hWorkerThread )
|
|
{
|
|
//
|
|
// Could not create the worker thread - bail out
|
|
//
|
|
|
|
VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
|
|
|
|
PostMessage( WM_COMMAND,
|
|
IDC_UNSIGNED_CANCEL_BUTTON );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
VOID CSlowProgressDlg::KillWorkerThread()
|
|
{
|
|
DWORD dwWaitResult;
|
|
MSG msg;
|
|
|
|
if( NULL != m_hWorkerThread )
|
|
{
|
|
if( NULL != m_hKillThreadEvent )
|
|
{
|
|
//
|
|
// Ask the worker thread to die asap
|
|
//
|
|
|
|
SetEvent( m_hKillThreadEvent );
|
|
}
|
|
|
|
//
|
|
// Wait forever for a decent death from the worker thread.
|
|
//
|
|
// We cannot TerminateThread on our worker thread because
|
|
// it could be killed while holding locks (e.g. the heap lock)
|
|
// and that would deadlock our whole process.
|
|
//
|
|
|
|
while( m_hWorkerThread != NULL )
|
|
{
|
|
dwWaitResult = MsgWaitForMultipleObjects( 1,
|
|
&m_hWorkerThread,
|
|
FALSE,
|
|
INFINITE,
|
|
QS_ALLINPUT );
|
|
|
|
ASSERT( NULL != WAIT_FAILED );
|
|
|
|
if( WAIT_OBJECT_0 != dwWaitResult )
|
|
{
|
|
//
|
|
// Our thread didn't exit but we have some messages to dispatch.
|
|
//
|
|
|
|
while( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) )
|
|
{
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
|
|
//
|
|
// During the DispatchMessage above we could process another
|
|
// click of the Cancel button or the Back button of the wizard.
|
|
// The KillWorkerThread recursive call will wait until the worker
|
|
// thread dies then will sets m_hWorkerThread to NULL.
|
|
// So we need to check for m_hWorkerThread != NULL before each new
|
|
// MsgWaitForMultipleObjects.
|
|
//
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The worker thread finished execution.
|
|
//
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( m_hWorkerThread != NULL )
|
|
{
|
|
//
|
|
// Close the thread handle
|
|
//
|
|
|
|
CloseHandle( m_hWorkerThread );
|
|
|
|
m_hWorkerThread = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSlowProgressDlg message handlers
|
|
|
|
void CSlowProgressDlg::OnCancelButton()
|
|
{
|
|
KillWorkerThread();
|
|
|
|
ShowWindow( SW_HIDE );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CSlowProgressDlg::OnShowWindow(BOOL bShow, UINT nStatus)
|
|
{
|
|
CDialog::OnShowWindow(bShow, nStatus);
|
|
|
|
if( TRUE == bShow )
|
|
{
|
|
CenterWindow();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CSlowProgressDlg::OnHelpInfo(HELPINFO* pHelpInfo)
|
|
{
|
|
return TRUE;
|
|
}
|