352 lines
9.4 KiB
C++
352 lines
9.4 KiB
C++
//--------------------------------------------------------------------------
|
|
// Repair.cpp
|
|
//--------------------------------------------------------------------------
|
|
#include "pch.hxx"
|
|
#include "repair.h"
|
|
#include "strconst.h"
|
|
#include <commctrl.h>
|
|
#include "utility.h"
|
|
#include "resource.h"
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Custom Messages
|
|
//--------------------------------------------------------------------------
|
|
#define WM_UPDATESTATUS (WM_USER + 1)
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::CDatabaseRepairUI
|
|
//--------------------------------------------------------------------------
|
|
CDatabaseRepairUI::CDatabaseRepairUI(void)
|
|
{
|
|
TraceCall("CDatabaseRepairUI::CDatabaseRepairUI");
|
|
m_cRef = 1;
|
|
m_pszFile = NULL;
|
|
m_cMax = 0;
|
|
m_cCurrent = 0;
|
|
m_hThread = NULL;
|
|
m_dwThreadId = 0;
|
|
m_cPercent = 0;
|
|
m_hwnd = NULL;
|
|
m_tyState = REPAIR_VERIFYING;
|
|
m_hrResult = S_OK;
|
|
m_hEvent = NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::~CDatabaseRepairUI
|
|
//--------------------------------------------------------------------------
|
|
CDatabaseRepairUI::~CDatabaseRepairUI(void)
|
|
{
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::~CDatabaseRepairUI");
|
|
|
|
// Free the file..
|
|
SafeMemFree(m_pszFile);
|
|
|
|
// Thread has not been closed yet ?
|
|
if (m_hThread)
|
|
{
|
|
// Must have threadid
|
|
Assert(m_dwThreadId);
|
|
|
|
// Post quit message
|
|
if (0 != PostThreadMessage(m_dwThreadId, WM_QUIT, 0, 0))
|
|
{
|
|
// Wait for event to become signaled
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hThread, 2000))
|
|
TerminateThread(m_hThread, 0); // opie made me put this code in!
|
|
}
|
|
|
|
// Otherwise, error
|
|
else
|
|
TraceResult(E_FAIL);
|
|
|
|
// Close the thread handle
|
|
CloseHandle(m_hThread);
|
|
}
|
|
|
|
// Close m_hEvent
|
|
SafeCloseHandle(m_hEvent);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::AddRef
|
|
//--------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG) CDatabaseRepairUI::AddRef(void)
|
|
{
|
|
TraceCall("CDatabaseRepairUI::AddRef");
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::Release
|
|
//--------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG) CDatabaseRepairUI::Release(void)
|
|
{
|
|
TraceCall("CDatabaseRepairUI::Release");
|
|
LONG cRef = InterlockedDecrement(&m_cRef);
|
|
if (0 == cRef)
|
|
delete this;
|
|
return (ULONG)cRef;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::Initialize
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CDatabaseRepairUI::Initialize(LPCSTR pszFilePath, DWORD cMax)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::Initialize");
|
|
|
|
// Get the filename
|
|
IF_NULLEXIT(m_pszFile = DuplicateString(PathFindFileName(pszFilePath)));
|
|
|
|
// Save cMax
|
|
m_cMax = cMax;
|
|
|
|
// Create an Event to Wait On
|
|
IF_NULLEXIT(m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL));
|
|
|
|
// Create a thread to display the actual dialog box on...
|
|
IF_NULLEXIT(m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CDatabaseRepairUI::ThreadEntry, this, 0, &m_dwThreadId));
|
|
|
|
// Wait for StoreCleanupThreadEntry to signal the event
|
|
WaitForSingleObject(m_hEvent, INFINITE);
|
|
|
|
// Failure
|
|
if (FAILED(m_hrResult))
|
|
{
|
|
// Close
|
|
SafeCloseHandle(m_hThread);
|
|
|
|
// Reset Globals
|
|
m_dwThreadId = 0;
|
|
|
|
// Null Window
|
|
m_hwnd = NULL;
|
|
|
|
// Return
|
|
hr = TraceResult(m_hrResult);
|
|
|
|
// Done
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
// Done
|
|
return(hr);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::IncrementProgress
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CDatabaseRepairUI::IncrementProgress(REPAIRSTATE tyState, DWORD cIncrement)
|
|
{
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::IncrementProgress");
|
|
|
|
// Increment Progress
|
|
m_cCurrent += cIncrement;
|
|
|
|
// Update
|
|
_Update(tyState);
|
|
|
|
// Done
|
|
return(S_OK);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::SetProgress
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CDatabaseRepairUI::SetProgress(REPAIRSTATE tyState, DWORD cCurrent)
|
|
{
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::SetProgress");
|
|
|
|
// Increment Progress
|
|
m_cCurrent = cCurrent;
|
|
|
|
// Update
|
|
_Update(tyState);
|
|
|
|
// Done
|
|
return(S_OK);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::SetProgress
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CDatabaseRepairUI::Reset(REPAIRSTATE tyState, DWORD cMax)
|
|
{
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::SetProgress");
|
|
|
|
// Increment Progress
|
|
m_cCurrent = 0;
|
|
|
|
// Reset max
|
|
m_cMax = cMax;
|
|
|
|
// Update
|
|
_Update(tyState);
|
|
|
|
// Done
|
|
return(S_OK);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::_Update
|
|
//--------------------------------------------------------------------------
|
|
void CDatabaseRepairUI::_Update(REPAIRSTATE tyState)
|
|
{
|
|
// Locals
|
|
DWORD cPercent;
|
|
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::_Update");
|
|
|
|
// Max
|
|
if (0 == m_cMax)
|
|
m_cCurrent = cPercent = 0;
|
|
else
|
|
cPercent = (DWORD)((m_cCurrent) * 100 / m_cMax);
|
|
|
|
// Difference
|
|
if (cPercent != m_cPercent || 0 == m_cCurrent || tyState != m_tyState)
|
|
{
|
|
// Save State
|
|
m_tyState = tyState;
|
|
|
|
// Save It
|
|
m_cPercent = cPercent;
|
|
|
|
// Update status
|
|
SendMessage(m_hwnd, WM_UPDATESTATUS, 0, 0);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::ThreadEntry
|
|
//--------------------------------------------------------------------------
|
|
DWORD CDatabaseRepairUI::ThreadEntry(LPDWORD pdwParam)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
MSG msg;
|
|
CDatabaseRepairUI *pThis = (CDatabaseRepairUI *)pdwParam;
|
|
|
|
// Validate
|
|
Assert(pThis);
|
|
|
|
// Create the modeless dialog window
|
|
IF_NULLEXIT(pThis->m_hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_REPAIR), NULL, CDatabaseRepairUI::ProgressDlgProc, (LPARAM)pThis));
|
|
|
|
// Set Event
|
|
SetEvent(pThis->m_hEvent);
|
|
|
|
// Success
|
|
pThis->m_hrResult = S_OK;
|
|
|
|
// Pump Messages
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
// Translate the Message
|
|
TranslateMessage(&msg);
|
|
|
|
// Dispatch the Message
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
// Nuke the Window
|
|
DestroyWindow(pThis->m_hwnd);
|
|
|
|
exit:
|
|
// Failure
|
|
if (FAILED(hr))
|
|
{
|
|
// Nuke the Window
|
|
if (pThis->m_hwnd)
|
|
DestroyWindow(pThis->m_hwnd);
|
|
|
|
// Set the Failure Code
|
|
pThis->m_hrResult = hr;
|
|
|
|
// Trigger the Event
|
|
SetEvent(pThis->m_hEvent);
|
|
}
|
|
|
|
// Success
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
// Done
|
|
return(1);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CDatabaseRepairUI::ProgressDlgProc
|
|
//--------------------------------------------------------------------------
|
|
INT_PTR CALLBACK CDatabaseRepairUI::ProgressDlgProc(HWND hwnd, UINT uMsg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// Locals
|
|
CHAR szRes[255];
|
|
CHAR szMsg[255 + MAX_PATH];
|
|
CDatabaseRepairUI *pThis = (CDatabaseRepairUI *)GetWndThisPtr(hwnd);
|
|
static HWND s_hwndProgress=NULL;
|
|
|
|
// Trace
|
|
TraceCall("CDatabaseRepairUI::ProgressDlgProc");
|
|
|
|
// Handle Window Message
|
|
switch(uMsg)
|
|
{
|
|
// Initialize
|
|
case WM_INITDIALOG:
|
|
|
|
// Get pThis
|
|
pThis = (CDatabaseRepairUI *)lParam;
|
|
|
|
// Save pThis
|
|
SetWndThisPtr(hwnd, pThis);
|
|
|
|
// Get Progress
|
|
s_hwndProgress = GetDlgItem(hwnd, IDC_REPAIR_PROGRESS);
|
|
|
|
// Set the Message...
|
|
SendMessage(hwnd, WM_UPDATESTATUS, 0, 0);
|
|
|
|
// Show the Window
|
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
|
|
|
// Set to foreground
|
|
SetForegroundWindow(hwnd);
|
|
|
|
// Done
|
|
return(1);
|
|
|
|
case WM_UPDATESTATUS:
|
|
|
|
// Verifying '%s' - 95% Complete
|
|
LoadString(g_hInst, (REPAIR_VERIFYING == pThis->m_tyState) ? IDS_VERIFYING_FILE : IDS_REPAIRING_FILE, szRes, ARRAYSIZE(szRes));
|
|
|
|
// Format the string
|
|
wsprintf(szMsg, szRes, pThis->m_cPercent, pThis->m_pszFile ? pThis->m_pszFile : c_szEmpty);
|
|
|
|
// Set the Status
|
|
SetDlgItemText(hwnd, IDC_REPAIR_STATUS, szMsg);
|
|
|
|
// Update the Progress
|
|
SendMessage(s_hwndProgress, PBM_SETPOS, pThis->m_cPercent, 0);
|
|
|
|
// Done
|
|
return(1);
|
|
}
|
|
|
|
// Not Handled
|
|
return(0);
|
|
}
|
|
|