Author: janderwald
Date: Thu Aug 14 09:47:31 2008
New Revision: 35337
URL:
http://svn.reactos.org/svn/reactos?rev=35337&view=rev
Log:
* Implement drive checking dialog with fmifs library
Modified:
trunk/reactos/dll/win32/shell32/drive.c
Modified: trunk/reactos/dll/win32/shell32/drive.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/drive.c?…
==============================================================================
--- trunk/reactos/dll/win32/shell32/drive.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/drive.c [iso-8859-1] Thu Aug 14 09:47:31 2008
@@ -92,6 +92,20 @@
IN PFMIFSCALLBACK Callback
);
+typedef
+VOID
+(NTAPI *CHKDSK)(
+ IN PWCHAR DriveRoot,
+ IN PWCHAR Format,
+ IN BOOLEAN CorrectErrors,
+ IN BOOLEAN Verbose,
+ IN BOOLEAN CheckOnlyIfDirty,
+ IN BOOLEAN ScanDrive,
+ IN PVOID Unused2,
+ IN PVOID Unused3,
+ IN PFMIFSCALLBACK Callback
+);
+
typedef struct
{
@@ -101,8 +115,12 @@
QUERY_AVAILABLEFSFORMAT QueryAvailableFileSystemFormat;
FORMAT_EX FormatEx;
ENABLEVOLUMECOMPRESSION EnableVolumeCompression;
+ CHKDSK Chkdsk;
UINT Result;
}FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT;
+
+BOOL InitializeFmifsLibrary(PFORMAT_DRIVE_CONTEXT pContext);
+BOOL GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER
TotalNumberOfBytes);
HWND WINAPI
DeviceCreateHardwarePageEx(HWND hWndParent,
@@ -115,6 +133,172 @@
#define DRIVE_PROPERTY_PAGES (3)
extern HINSTANCE shell32_hInstance;
+
+VOID
+GetDriveNameWithLetter(LPWSTR szText, UINT Length, WCHAR Drive)
+{
+ WCHAR szDrive[] = {'C',':','\\', 0};
+ DWORD dwMaxComp, dwFileSys, TempLength = 0;
+
+ szDrive[0] = Drive;
+ if (GetVolumeInformationW(szDrive, szText, Length, NULL, &dwMaxComp,
&dwFileSys, NULL, 0))
+ {
+ szText[Length-1] = L'\0';
+ TempLength = wcslen(szText);
+ if (!TempLength)
+ {
+ /* load default volume label */
+ TempLength = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED,
&szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2);
+ }
+ }
+ if (TempLength + 4 < Length)
+ {
+ szText[TempLength] = L' ';
+ szText[TempLength+1] = L'(';
+ szText[TempLength+2] = szDrive[0];
+ szText[TempLength+3] = L')';
+ TempLength +=4;
+ }
+
+ if (TempLength < Length)
+ szText[TempLength] = L'\0';
+ else
+ szText[Length-1] = L'\0';
+}
+
+
+VOID
+InitializeChkDskDialog(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
+{
+ WCHAR szText[100];
+ UINT Length;
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pContext);
+
+ Length = GetWindowTextW(hwndDlg, szText, sizeof(szText)/sizeof(WCHAR));
+
+ GetDriveNameWithLetter(&szText[Length +1],
(sizeof(szText)/sizeof(WCHAR))-Length-1, pContext->Drive);
+ szText[Length] = L' ';
+ szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+ SetWindowText(hwndDlg, szText);
+}
+
+HWND ChkdskDrvDialog = NULL;
+BOOLEAN bChkdskSuccess = FALSE;
+
+BOOLEAN
+NTAPI
+ChkdskCallback(
+ IN CALLBACKCOMMAND Command,
+ IN ULONG SubAction,
+ IN PVOID ActionInfo)
+{
+ PDWORD Progress;
+ PBOOLEAN pSuccess;
+ switch(Command)
+ {
+ case PROGRESS:
+ Progress = (PDWORD)ActionInfo;
+ SendDlgItemMessageW(ChkdskDrvDialog, 14002, PBM_SETPOS, (WPARAM)*Progress,
0);
+ break;
+ case DONE:
+ pSuccess = (PBOOLEAN)ActionInfo;
+ bChkdskSuccess = (*pSuccess);
+ break;
+
+ case VOLUMEINUSE:
+ case INSUFFICIENTRIGHTS:
+ case FSNOTSUPPORTED:
+ case CLUSTERSIZETOOSMALL:
+ bChkdskSuccess = FALSE;
+ FIXME("\n");
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+VOID
+ChkDskNow(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
+{
+ DWORD ClusterSize = 0, dwMaxComponentLength, FileSystemFlags;
+ WCHAR szFs[30];
+ WCHAR szDrive[] = {'C',':','\\', 0};
+ WCHAR szVolumeLabel[40];
+ ULARGE_INTEGER TotalNumberOfFreeBytes, FreeBytesAvailableUser;
+ BOOLEAN bCorrectErrors = FALSE, bScanDrive = FALSE;
+
+ szDrive[0] = pContext->Drive;
+ if(!GetVolumeInformationW(szDrive, szVolumeLabel,
sizeof(szVolumeLabel)/sizeof(WCHAR), NULL, &dwMaxComponentLength,
&FileSystemFlags, szFs, sizeof(szFs)/sizeof(WCHAR)))
+ {
+ FIXME("failed to get drive fs type\n");
+ return;
+ }
+
+ if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser,
&TotalNumberOfFreeBytes, NULL))
+ {
+ FIXME("failed to get drive space type\n");
+ return;
+ }
+
+ if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfFreeBytes))
+ {
+ FIXME("invalid cluster size\n");
+ return;
+ }
+
+ if (SendDlgItemMessageW(hwndDlg, 14000, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ bCorrectErrors = TRUE;
+
+ if (SendDlgItemMessageW(hwndDlg, 14001, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ bScanDrive = TRUE;
+
+ ChkdskDrvDialog = hwndDlg;
+ bChkdskSuccess = FALSE;
+ SendDlgItemMessageW(hwndDlg, 14002, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+ pContext->Chkdsk(szDrive, szFs, bCorrectErrors, TRUE, FALSE, bScanDrive, NULL,
NULL, ChkdskCallback);
+
+ ChkdskDrvDialog = NULL;
+ pContext->Result = bChkdskSuccess;
+ bChkdskSuccess = FALSE;
+
+}
+
+INT_PTR
+CALLBACK
+ChkDskDlg(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+)
+{
+ PFORMAT_DRIVE_CONTEXT pContext;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
+ InitializeChkDskDialog(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDCANCEL:
+ EndDialog(hwndDlg, 0);
+ break;
+ case IDOK:
+ pContext = (PFORMAT_DRIVE_CONTEXT) GetWindowLongPtr(hwndDlg,
DWLP_USER);
+ ChkDskNow(hwndDlg, pContext);
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
static
LARGE_INTEGER
@@ -365,11 +549,12 @@
{
STARTUPINFOW si;
PROCESS_INFORMATION pi;
- WCHAR szPath[MAX_PATH];
+ WCHAR szPath[MAX_PATH + 10];
WCHAR szArg[MAX_PATH];
WCHAR * szDrive;
- UINT length;
LPPROPSHEETPAGEW ppsp;
+ DWORD dwSize;
+ FORMAT_DRIVE_CONTEXT Context;
switch (uMsg)
{
@@ -381,38 +566,58 @@
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
- if (!GetSystemDirectoryW(szPath, MAX_PATH))
- break;
+
szDrive = (WCHAR*)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch(LOWORD(wParam))
{
case 14000:
- ///
- /// FIXME
- /// show checkdsk dialog
- ///
+ if (InitializeFmifsLibrary(&Context))
+ {
+ Context.Drive = szDrive[0];
+ DialogBoxParamW(shell32_hInstance, L"CHKDSK_DLG", hwndDlg,
ChkDskDlg, (LPARAM)&Context);
+ FreeLibrary(Context.hLibrary);
+ }
break;
case 14001:
- szArg[0] = L'"';
- wcscpy(&szArg[1], szPath);
- wcscat(szPath, L"\\mmc.exe");
- wcscat(szArg, L"\\dfrg.msc\" ");
- length = wcslen(szArg);
- szArg[length] = szDrive[0];
- szArg[length+1] = L':';
- szArg[length+2] = L'\0';
- if (CreateProcessW(szPath, szArg, NULL, NULL, FALSE, 0, NULL, NULL, &si,
&pi))
+ dwSize = sizeof(szPath);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE,
+
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\DefragPath",
+ NULL,
+ RRF_RT_REG_EXPAND_SZ,
+ NULL,
+ (PVOID)szPath,
+ &dwSize) == S_OK)
{
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ swprintf(szArg, szPath, szDrive[0]);
+ if (!GetSystemDirectoryW(szPath, MAX_PATH))
+ break;
+ szDrive = PathAddBackslashW(szPath);
+ if (!szDrive)
+ break;
+
+ wcscat(szDrive, L"mmc.exe");
+ if (CreateProcessW(szPath, szArg, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi))
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
}
break;
case 14002:
- wcscat(szPath, L"\\ntbackup.exe");
- if (CreateProcessW(szPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si,
&pi))
+ dwSize = sizeof(szPath);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE,
+
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\BackupPath",
+ NULL,
+ RRF_RT_REG_EXPAND_SZ,
+ NULL,
+ (PVOID)szPath,
+ &dwSize) == S_OK)
{
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ if (CreateProcessW(szPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi))
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
}
}
break;
@@ -542,15 +747,76 @@
return TRUE;
}
-
-
+BOOL
+GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER
TotalNumberOfBytes)
+{
+ DWORD ClusterSize;
+
+ if (!wcsicmp(szFs, L"FAT16") ||
+ !wcsicmp(szFs, L"FAT")) //REACTOS HACK
+ {
+ if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024))
+ ClusterSize = 2048;
+ else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024))
+ ClusterSize = 512;
+ else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
+ ClusterSize = 1024;
+ else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
+ ClusterSize = 2048;
+ else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
+ ClusterSize = 4096;
+ else if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))
+ ClusterSize = 8192;
+ else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
+ ClusterSize = 16384;
+ else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
+ ClusterSize = 32768;
+ else if (TotalNumberOfBytes->QuadPart <= (4096LL * 1024LL * 1024LL))
+ ClusterSize = 8192;
+ else
+ return FALSE;
+ }
+ else if (!wcsicmp(szFs, L"FAT32"))
+ {
+ if (TotalNumberOfBytes->QuadPart <=(64 * 1024 * 1024))
+ ClusterSize = 512;
+ else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
+ ClusterSize = 1024;
+ else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
+ ClusterSize = 2048;
+ else if (TotalNumberOfBytes->QuadPart <= (8192LL * 1024LL * 1024LL))
+ ClusterSize = 2048;
+ else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL))
+ ClusterSize = 8192;
+ else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL))
+ ClusterSize = 16384;
+ else
+ return FALSE;
+ }
+ else if (!wcsicmp(szFs, L"NTFS"))
+ {
+ if (TotalNumberOfBytes->QuadPart <=(512 * 1024 * 1024))
+ ClusterSize = 512;
+ else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
+ ClusterSize = 1024;
+ else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
+ ClusterSize = 2048;
+ else
+ ClusterSize = 2048;
+ }
+ else
+ return FALSE;
+
+ *pClusterSize = ClusterSize;
+ return TRUE;
+}
VOID
InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
{
WCHAR szFs[100] = {0};
- WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
+ WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
INT iSelIndex;
ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
DWORD ClusterSize;
@@ -574,30 +840,13 @@
if (!wcsicmp(szFs, L"FAT16") ||
!wcsicmp(szFs, L"FAT")) //REACTOS HACK
{
- if (TotalNumberOfBytes.QuadPart <= (16 * 1024 * 1024))
- ClusterSize = 2048;
- else if (TotalNumberOfBytes.QuadPart <= (32 * 1024 * 1024))
- ClusterSize = 512;
- else if (TotalNumberOfBytes.QuadPart <= (64 * 1024 * 1024))
- ClusterSize = 1024;
- else if (TotalNumberOfBytes.QuadPart <= (128 * 1024 * 1024))
- ClusterSize = 2048;
- else if (TotalNumberOfBytes.QuadPart <= (256 * 1024 * 1024))
- ClusterSize = 4096;
- else if (TotalNumberOfBytes.QuadPart <= (512 * 1024 * 1024))
- ClusterSize = 8192;
- else if (TotalNumberOfBytes.QuadPart <= (1024 * 1024 * 1024))
- ClusterSize = 16384;
- else if (TotalNumberOfBytes.QuadPart <= (2048LL * 1024LL * 1024LL))
- ClusterSize = 32768;
- else if (TotalNumberOfBytes.QuadPart <= (4096LL * 1024LL * 1024LL))
- ClusterSize = 8192;
- else
+ if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("FAT16 is not supported on hdd larger than 4G current %lu\n",
TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
return;
}
+
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs,
sizeof(szFs)/sizeof(WCHAR)))
{
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
@@ -611,19 +860,7 @@
}
else if (!wcsicmp(szFs, L"FAT32"))
{
- if (TotalNumberOfBytes.QuadPart <=(64 * 1024 * 1024))
- ClusterSize = 512;
- else if (TotalNumberOfBytes.QuadPart <= (128 * 1024 * 1024))
- ClusterSize = 1024;
- else if (TotalNumberOfBytes.QuadPart <= (256 * 1024 * 1024))
- ClusterSize = 2048;
- else if (TotalNumberOfBytes.QuadPart <= (8192LL * 1024LL * 1024LL))
- ClusterSize = 2048;
- else if (TotalNumberOfBytes.QuadPart <= (16384LL * 1024LL * 1024LL))
- ClusterSize = 8192;
- else if (TotalNumberOfBytes.QuadPart <= (32768LL * 1024LL * 1024LL))
- ClusterSize = 16384;
- else
+ if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))
{
TRACE("FAT32 is not supported on hdd larger than 32G current
%lu\n", TotalNumberOfBytes.QuadPart);
SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
@@ -643,14 +880,12 @@
}
else if (!wcsicmp(szFs, L"NTFS"))
{
- if (TotalNumberOfBytes.QuadPart <=(512 * 1024 * 1024))
- ClusterSize = 512;
- else if (TotalNumberOfBytes.QuadPart <= (1024 * 1024 * 1024))
- ClusterSize = 1024;
- else if (TotalNumberOfBytes.QuadPart <= (2048LL * 1024LL * 1024LL))
- ClusterSize = 2048;
- else
- ClusterSize = 2048;
+ if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))
+ {
+ TRACE("NTFS is not supported on hdd larger than 2TB current %lu\n",
TotalNumberOfBytes.QuadPart);
+ SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
+ return;
+ }
hDlgCtrl = GetDlgItem(hwndDlg, 28680);
if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs,
sizeof(szFs)/sizeof(WCHAR)))
@@ -1016,6 +1251,14 @@
return FALSE;
}
+ pContext->Chkdsk = (CHKDSK) GetProcAddress(hLibrary, "Chkdsk");
+ if (!pContext->Chkdsk)
+ {
+ ERR("Chkdsk export is missing\n");
+ FreeLibrary(hLibrary);
+ return FALSE;
+ }
+
return TRUE;
}