Sync to trunk (r44371)
[reactos.git] / reactos / dll / win32 / shell32 / drive.c
index 44135c9..13cb89c 100644 (file)
-/*\r
- *                 Shell Library Functions\r
- *\r
- * Copyright 2005 Johannes Anderwald\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-#define LARGEINT_PROTOS\r
-#define LargeIntegerDivide RtlLargeIntegerDivide\r
-#define ExtendedIntegerMultiply RtlExtendedIntegerMultiply\r
-#define ConvertUlongToLargeInteger RtlConvertUlongToLargeInteger\r
-#define LargeIntegerSubtract RtlLargeIntegerSubtract\r
-#define MAX_PROPERTY_SHEET_PAGE 32\r
-\r
-#define WIN32_NO_STATUS\r
-#define NTOS_MODE_USER\r
-#define UNICODE\r
-#define _UNICODE\r
-#define COBJMACROS\r
-#include <windows.h>\r
-#include <ndk/ntndk.h>\r
-#include <fmifs/fmifs.h>\r
-#include <largeint.h>\r
-\r
-#include <precomp.h>\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(shell);\r
-\r
-typedef enum\r
-{\r
-    HWPD_STANDARDLIST = 0,\r
-    HWPD_LARGELIST,\r
-    HWPD_MAX = HWPD_LARGELIST\r
-} HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;\r
-\r
-typedef\r
-BOOLEAN \r
-(NTAPI *INITIALIZE_FMIFS)(\r
-       IN PVOID hinstDll,\r
-       IN DWORD dwReason,\r
-       IN PVOID reserved\r
-);\r
-typedef\r
-BOOLEAN\r
-(NTAPI *QUERY_AVAILABLEFSFORMAT)(\r
-       IN DWORD Index,\r
-       IN OUT PWCHAR FileSystem,\r
-       OUT UCHAR* Major,\r
-       OUT UCHAR* Minor,\r
-       OUT BOOLEAN* LastestVersion\r
-);\r
-typedef\r
-BOOLEAN\r
-(NTAPI *ENABLEVOLUMECOMPRESSION)(\r
-       IN PWCHAR DriveRoot,\r
-       IN USHORT Compression\r
-);\r
-\r
-typedef\r
-VOID \r
-(NTAPI *FORMAT_EX)(\r
-       IN PWCHAR DriveRoot,\r
-       IN FMIFS_MEDIA_FLAG MediaFlag,\r
-       IN PWCHAR Format,\r
-       IN PWCHAR Label,\r
-       IN BOOLEAN QuickFormat,\r
-       IN ULONG ClusterSize,\r
-       IN PFMIFSCALLBACK Callback\r
-);\r
-\r
-typedef\r
-VOID \r
-(NTAPI *CHKDSK)(\r
-       IN PWCHAR DriveRoot,\r
-       IN PWCHAR Format,\r
-       IN BOOLEAN CorrectErrors,\r
-       IN BOOLEAN Verbose,\r
-       IN BOOLEAN CheckOnlyIfDirty,\r
-       IN BOOLEAN ScanDrive,\r
-       IN PVOID Unused2,\r
-       IN PVOID Unused3,\r
-       IN PFMIFSCALLBACK Callback\r
-);\r
-\r
-\r
-typedef struct\r
-{\r
-    WCHAR   Drive;\r
-    UINT    Options;\r
-    HMODULE hLibrary;\r
-    QUERY_AVAILABLEFSFORMAT QueryAvailableFileSystemFormat;\r
-    FORMAT_EX FormatEx;\r
-    ENABLEVOLUMECOMPRESSION EnableVolumeCompression;\r
-    CHKDSK Chkdsk;\r
-    UINT Result;\r
-}FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT;\r
-\r
-BOOL InitializeFmifsLibrary(PFORMAT_DRIVE_CONTEXT pContext);\r
-BOOL GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNumberOfBytes);\r
-HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);\r
-HWND WINAPI\r
-DeviceCreateHardwarePageEx(HWND hWndParent,\r
-                           LPGUID lpGuids,\r
-                           UINT uNumberOfGuids,\r
-                           HWPAGE_DISPLAYMODE DisplayMode);\r
-\r
-HPROPSHEETPAGE SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle);\r
-\r
-#define DRIVE_PROPERTY_PAGES (3)\r
-\r
-static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};\r
-\r
-\r
-VOID\r
-GetDriveNameWithLetter(LPWSTR szText, UINT Length, WCHAR Drive)\r
-{\r
-   WCHAR szDrive[] = {'C',':','\\', 0};\r
-   DWORD dwMaxComp, dwFileSys, TempLength = 0;\r
-\r
-    szDrive[0] = Drive;\r
-    if (GetVolumeInformationW(szDrive, szText, Length, NULL, &dwMaxComp, &dwFileSys, NULL, 0))\r
-    {\r
-        szText[Length-1] = L'\0';\r
-        TempLength = wcslen(szText);\r
-        if (!TempLength)\r
-        {\r
-            /* load default volume label */\r
-            TempLength = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2);\r
-        }\r
-    }\r
-    if (TempLength + 4 < Length)\r
-    {\r
-        szText[TempLength] = L' ';\r
-        szText[TempLength+1] = L'(';\r
-        szText[TempLength+2] = szDrive[0];\r
-        szText[TempLength+3] = L')';\r
-        TempLength +=4;\r
-    }\r
-\r
-    if (TempLength < Length)\r
-        szText[TempLength] = L'\0';\r
-    else\r
-        szText[Length-1] = L'\0';\r
-}\r
-\r
-\r
-VOID\r
-InitializeChkDskDialog(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-    WCHAR szText[100];\r
-    UINT Length;\r
-    SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pContext);\r
-\r
-    Length = GetWindowTextW(hwndDlg, szText, sizeof(szText)/sizeof(WCHAR));\r
-\r
-    GetDriveNameWithLetter(&szText[Length +1], (sizeof(szText)/sizeof(WCHAR))-Length-1, pContext->Drive);\r
-    szText[Length] = L' ';\r
-    szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-    SetWindowText(hwndDlg, szText);\r
-}\r
-\r
-HWND ChkdskDrvDialog = NULL;\r
-BOOLEAN bChkdskSuccess = FALSE;\r
-\r
-BOOLEAN\r
-NTAPI\r
-ChkdskCallback(\r
-       IN CALLBACKCOMMAND Command,\r
-       IN ULONG SubAction,\r
-       IN PVOID ActionInfo)\r
-{\r
-    PDWORD Progress;\r
-    PBOOLEAN pSuccess;\r
-    switch(Command)\r
-    {\r
-        case PROGRESS:\r
-            Progress = (PDWORD)ActionInfo;\r
-            SendDlgItemMessageW(ChkdskDrvDialog, 14002, PBM_SETPOS, (WPARAM)*Progress, 0);\r
-            break;\r
-        case DONE:\r
-            pSuccess = (PBOOLEAN)ActionInfo;\r
-            bChkdskSuccess = (*pSuccess);\r
-            break;\r
-\r
-        case VOLUMEINUSE:\r
-        case INSUFFICIENTRIGHTS:\r
-        case FSNOTSUPPORTED:\r
-        case CLUSTERSIZETOOSMALL:\r
-            bChkdskSuccess = FALSE;\r
-            FIXME("\n");\r
-            break;\r
-\r
-        default:\r
-            break;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-VOID\r
-ChkDskNow(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-    DWORD ClusterSize = 0, dwMaxComponentLength, FileSystemFlags;\r
-    WCHAR szFs[30];\r
-    WCHAR szDrive[] = {'C',':','\\', 0};\r
-    WCHAR szVolumeLabel[40];\r
-    ULARGE_INTEGER TotalNumberOfFreeBytes, FreeBytesAvailableUser;\r
-    BOOLEAN bCorrectErrors = FALSE, bScanDrive = FALSE;\r
-\r
-    szDrive[0] = pContext->Drive;\r
-    if(!GetVolumeInformationW(szDrive, szVolumeLabel, sizeof(szVolumeLabel)/sizeof(WCHAR), NULL, &dwMaxComponentLength, &FileSystemFlags, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-    {\r
-        FIXME("failed to get drive fs type\n");\r
-        return;\r
-    }\r
-\r
-    if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfFreeBytes, NULL))\r
-    {\r
-        FIXME("failed to get drive space type\n");\r
-        return;\r
-    }\r
-\r
-    if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfFreeBytes))\r
-    {\r
-        FIXME("invalid cluster size\n");\r
-        return;\r
-    }\r
-\r
-    if (SendDlgItemMessageW(hwndDlg, 14000, BM_GETCHECK, 0, 0) == BST_CHECKED)\r
-        bCorrectErrors = TRUE;\r
-\r
-    if (SendDlgItemMessageW(hwndDlg, 14001, BM_GETCHECK, 0, 0) == BST_CHECKED)\r
-        bScanDrive = TRUE;\r
-\r
-    ChkdskDrvDialog = hwndDlg;\r
-    bChkdskSuccess = FALSE;\r
-    SendDlgItemMessageW(hwndDlg, 14002, PBM_SETRANGE, 0, MAKELPARAM(0, 100));\r
-    pContext->Chkdsk(szDrive, szFs, bCorrectErrors, TRUE, FALSE, bScanDrive, NULL, NULL, ChkdskCallback);\r
-    \r
-    ChkdskDrvDialog = NULL;\r
-    pContext->Result = bChkdskSuccess;\r
-    bChkdskSuccess = FALSE;\r
-\r
-}\r
-\r
-INT_PTR\r
-CALLBACK\r
-ChkDskDlg(\r
-    HWND hwndDlg,\r
-    UINT uMsg,\r
-    WPARAM wParam,\r
-    LPARAM lParam\r
-)\r
-{\r
-    PFORMAT_DRIVE_CONTEXT pContext;\r
-    switch(uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);\r
-            InitializeChkDskDialog(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);\r
-            return TRUE;\r
-       case WM_COMMAND:\r
-            switch(LOWORD(wParam))\r
-            {\r
-                case IDCANCEL:\r
-                    EndDialog(hwndDlg, 0);\r
-                    break;\r
-                case IDOK:\r
-                    pContext = (PFORMAT_DRIVE_CONTEXT) GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-                    ChkDskNow(hwndDlg, pContext);\r
-                    break;\r
-            }\r
-            break;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
-\r
-\r
-static\r
-LARGE_INTEGER\r
-GetFreeBytesShare(LARGE_INTEGER TotalNumberOfFreeBytes, LARGE_INTEGER TotalNumberOfBytes)\r
-{\r
-   LARGE_INTEGER Temp, Result, Remainder;\r
-\r
-   Temp = LargeIntegerDivide(TotalNumberOfBytes, ConvertUlongToLargeInteger(100), &Remainder);\r
-   if (Temp.QuadPart >= TotalNumberOfFreeBytes.QuadPart)\r
-   {\r
-      Result = ConvertUlongToLargeInteger(1);\r
-   }else\r
-   {\r
-      Result = LargeIntegerDivide(TotalNumberOfFreeBytes, Temp, &Remainder);\r
-   }\r
-\r
-   return Result;\r
-}\r
-\r
-static\r
-void\r
-PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT drawItem)\r
-{\r
-   HBRUSH hBrush;\r
-\r
-   if (drawItem->CtlID == 14013)\r
-   {\r
-      hBrush = CreateSolidBrush(RGB(0, 0, 255));\r
-      if (hBrush)\r
-      {\r
-         FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);\r
-         DeleteObject((HGDIOBJ)hBrush);\r
-      }\r
-   }else if (drawItem->CtlID == 14014)\r
-   {\r
-      hBrush = CreateSolidBrush(RGB(255, 0, 255));\r
-      if (hBrush)\r
-      {\r
-         FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);\r
-         DeleteObject((HGDIOBJ)hBrush);\r
-      }\r
-   }\r
-   else if (drawItem->CtlID == 14015)\r
-   {\r
-      HBRUSH hBlueBrush;\r
-      HBRUSH hMagBrush;\r
-      RECT rect;\r
-      LONG horzsize;\r
-      LARGE_INTEGER Result;\r
-      WCHAR szBuffer[20];\r
-\r
-      hBlueBrush = CreateSolidBrush(RGB(0, 0, 255));\r
-      hMagBrush = CreateSolidBrush(RGB(255, 0, 255));\r
-\r
-      SendDlgItemMessageW(hwndDlg, 14007, WM_GETTEXT, 20, (LPARAM)szBuffer);\r
-      Result.QuadPart = _wtoi(szBuffer);\r
-\r
-      CopyRect(&rect, &drawItem->rcItem);\r
-      horzsize = rect.right - rect.left;\r
-      Result.QuadPart = (Result.QuadPart * horzsize) / 100;\r
-\r
-      rect.right = rect.left + Result.QuadPart;\r
-      FillRect(drawItem->hDC, &rect, hMagBrush);\r
-      rect.left = rect.right;\r
-      rect.right = drawItem->rcItem.right;\r
-      FillRect(drawItem->hDC, &rect, hBlueBrush);\r
-      DeleteObject(hBlueBrush);\r
-      DeleteObject(hMagBrush);\r
-   }\r
-}\r
-\r
-static\r
-void\r
-InitializeGeneralDriveDialog(HWND hwndDlg, WCHAR * szDrive)\r
-{\r
-   WCHAR szVolumeName[MAX_PATH+1] = {0};\r
-   DWORD MaxComponentLength = 0;\r
-   DWORD FileSystemFlags = 0;\r
-   WCHAR FileSystemName[MAX_PATH+1] = {0};\r
-   WCHAR szFormat[50];\r
-   WCHAR szBuffer[128];\r
-   BOOL ret;\r
-   UINT DriveType;\r
-   ULARGE_INTEGER FreeBytesAvailable;\r
-   LARGE_INTEGER TotalNumberOfFreeBytes;\r
-   LARGE_INTEGER TotalNumberOfBytes;\r
-\r
-   ret = GetVolumeInformationW(szDrive, szVolumeName, MAX_PATH+1, NULL, &MaxComponentLength, &FileSystemFlags, FileSystemName, MAX_PATH+1);\r
-   if (ret)\r
-   {\r
-      /* set volume label */\r
-      SendDlgItemMessageW(hwndDlg, 14001, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szVolumeName);\r
-\r
-      /* set filesystem type */\r
-      SendDlgItemMessageW(hwndDlg, 14003, WM_SETTEXT, (WPARAM)NULL, (LPARAM)FileSystemName);\r
-\r
-   }\r
-\r
-   DriveType = GetDriveTypeW(szDrive);\r
-   if (DriveType == DRIVE_FIXED)\r
-   {\r
-\r
-      if(GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailable, (PULARGE_INTEGER)&TotalNumberOfBytes, (PULARGE_INTEGER)&TotalNumberOfFreeBytes))\r
-      {\r
-         WCHAR szResult[128];\r
-         LARGE_INTEGER Result;\r
-#ifdef IOCTL_DISK_GET_LENGTH_INFO_IMPLEMENTED\r
-         HANDLE hVolume;\r
-         DWORD BytesReturned = 0;\r
-\r
-         swprintf(szResult, L"\\\\.\\%c:", towupper(szDrive[0]));\r
-         hVolume = CreateFileW(szResult, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);\r
-         if (hVolume != INVALID_HANDLE_VALUE)\r
-         {\r
-            ret = DeviceIoControl(hVolume, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, (LPVOID)&TotalNumberOfBytes, sizeof(ULARGE_INTEGER), &BytesReturned, NULL);\r
-            if (ret && StrFormatByteSizeW(LengthInformation.Length.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))\r
-               SendDlgItemMessageW(hwndDlg, 14008, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);\r
-\r
-            CloseHandle(hVolume);\r
-         }\r
-         TRACE("szResult %s hVOlume %p ret %d LengthInformation %ul Bytesreturned %d\n", debugstr_w(szResult), hVolume, ret, LengthInformation.Length.QuadPart, BytesReturned);\r
-#else\r
-            if (ret && StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))\r
-               SendDlgItemMessageW(hwndDlg, 14008, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);\r
-#endif\r
-\r
-         if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))\r
-             SendDlgItemMessageW(hwndDlg, 14004, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);\r
-\r
-         if (StrFormatByteSizeW(FreeBytesAvailable.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))\r
-             SendDlgItemMessageW(hwndDlg, 14006, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);\r
-\r
-         Result = GetFreeBytesShare(TotalNumberOfFreeBytes, TotalNumberOfBytes);\r
-         /* set free bytes percentage */\r
-         swprintf(szResult, L"%02d%%", Result.QuadPart);\r
-         SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, (WPARAM)0, (LPARAM)szResult);\r
-         /* store used share amount */\r
-         Result = LargeIntegerSubtract(ConvertUlongToLargeInteger(100), Result);\r
-         swprintf(szResult, L"%02d%%", Result.QuadPart);\r
-         SendDlgItemMessageW(hwndDlg, 14005, WM_SETTEXT, (WPARAM)0, (LPARAM)szResult);\r
-         if (LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))\r
-             SendDlgItemMessageW(hwndDlg, 14002, WM_SETTEXT, (WPARAM)0, (LPARAM)szBuffer);\r
-\r
-      }\r
-   }\r
-   /* set drive description */\r
-   SendDlgItemMessageW(hwndDlg, 14010, WM_GETTEXT, (WPARAM)50, (LPARAM)szFormat);\r
-   swprintf(szBuffer, szFormat, szDrive);\r
-   SendDlgItemMessageW(hwndDlg, 14010, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szBuffer);\r
-}\r
-\r
-\r
-INT_PTR\r
-CALLBACK\r
-DriveGeneralDlg(\r
-    HWND hwndDlg,\r
-    UINT uMsg,\r
-    WPARAM wParam,\r
-    LPARAM lParam\r
-)\r
-{\r
-    LPPROPSHEETPAGEW ppsp;\r
-    LPDRAWITEMSTRUCT drawItem;\r
-    STARTUPINFOW si;\r
-    PROCESS_INFORMATION pi;\r
-    WCHAR * lpstr;\r
-    WCHAR szPath[MAX_PATH];\r
-    UINT length;\r
-    LPPSHNOTIFY lppsn;\r
-\r
-    switch(uMsg)\r
-    {\r
-    case WM_INITDIALOG:\r
-        ppsp = (LPPROPSHEETPAGEW)lParam;\r
-        if (ppsp == NULL)\r
-            break;\r
-        lpstr = (WCHAR *)ppsp->lParam;\r
-        SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lpstr);\r
-        InitializeGeneralDriveDialog(hwndDlg, lpstr);\r
-        return TRUE;\r
-    case WM_DRAWITEM:\r
-        drawItem = (LPDRAWITEMSTRUCT)lParam;\r
-        if (drawItem->CtlID >= 14013 && drawItem->CtlID <= 14015)\r
-        {\r
-            PaintStaticControls(hwndDlg, drawItem);\r
-            return TRUE;\r
-        }\r
-        break;\r
-    case WM_COMMAND:\r
-        if (LOWORD(wParam) == 14011)\r
-        {\r
-           lpstr = (WCHAR*)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-           ZeroMemory( &si, sizeof(si) );\r
-           si.cb = sizeof(si);\r
-           ZeroMemory( &pi, sizeof(pi) );\r
-           if (!GetSystemDirectoryW(szPath, MAX_PATH))\r
-              break;\r
-           wcscat(szPath, L"\\cleanmgr.exe /D ");\r
-           length = wcslen(szPath);\r
-           szPath[length] = lpstr[0];\r
-           szPath[length+1] = L'\0';\r
-           if (CreateProcessW(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
-           {\r
-              CloseHandle(pi.hProcess);\r
-              CloseHandle(pi.hThread);\r
-           }\r
-           break;\r
-        }\r
-    case WM_NOTIFY:\r
-        lppsn = (LPPSHNOTIFY) lParam;\r
-        if (LOWORD(wParam) == 14001)\r
-        {\r
-           if (HIWORD(wParam) == EN_CHANGE)\r
-           {\r
-              PropSheet_Changed(GetParent(hwndDlg), hwndDlg);\r
-           }\r
-           break;\r
-        }\r
-        if (lppsn->hdr.code == PSN_APPLY)\r
-        {\r
-           lpstr = (LPWSTR)GetWindowLong(hwndDlg, DWLP_USER);\r
-           if (lpstr && SendDlgItemMessageW(hwndDlg, 14001, WM_GETTEXT, sizeof(szPath)/sizeof(WCHAR), (LPARAM)szPath))\r
-           {\r
-              szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0';\r
-              SetVolumeLabelW(lpstr, szPath);\r
-           }\r
-           SetWindowLong( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );\r
-           return TRUE;\r
-        }\r
-        break;\r
-\r
-    default:\r
-        break;\r
-   }\r
-\r
-\r
-   return FALSE;\r
-}\r
-\r
-INT_PTR\r
-CALLBACK\r
-DriveExtraDlg(\r
-    HWND hwndDlg,\r
-    UINT uMsg,\r
-    WPARAM wParam,\r
-    LPARAM lParam\r
-)\r
-{\r
-   STARTUPINFOW si;\r
-   PROCESS_INFORMATION pi;\r
-   WCHAR szPath[MAX_PATH + 10];\r
-   WCHAR szArg[MAX_PATH];\r
-   WCHAR * szDrive;\r
-   LPPROPSHEETPAGEW ppsp;\r
-   DWORD dwSize;\r
-   FORMAT_DRIVE_CONTEXT Context;\r
-\r
-   switch (uMsg)\r
-   {\r
-   case WM_INITDIALOG:\r
-      ppsp = (LPPROPSHEETPAGEW)lParam;\r
-      SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)ppsp->lParam);\r
-      return TRUE;\r
-   case WM_COMMAND:\r
-      ZeroMemory( &si, sizeof(si) );\r
-      si.cb = sizeof(si);\r
-      ZeroMemory( &pi, sizeof(pi) );\r
-\r
-      szDrive = (WCHAR*)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-      switch(LOWORD(wParam))\r
-      {\r
-         case 14000:\r
-            if (InitializeFmifsLibrary(&Context))\r
-            {\r
-                Context.Drive = szDrive[0];\r
-                DialogBoxParamW(shell32_hInstance, L"CHKDSK_DLG", hwndDlg, ChkDskDlg, (LPARAM)&Context);\r
-                FreeLibrary(Context.hLibrary);\r
-            }\r
-            break;\r
-         case 14001:\r
-            dwSize = sizeof(szPath);\r
-            if (RegGetValueW(HKEY_LOCAL_MACHINE, \r
-                             L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\DefragPath",\r
-                             NULL,\r
-                             RRF_RT_REG_EXPAND_SZ,\r
-                             NULL,\r
-                             (PVOID)szPath,\r
-                             &dwSize) == S_OK)\r
-            {\r
-                swprintf(szArg, szPath, szDrive[0]);\r
-               if (!GetSystemDirectoryW(szPath, MAX_PATH))\r
-                   break;\r
-               szDrive = PathAddBackslashW(szPath);\r
-               if (!szDrive)\r
-                   break;\r
-\r
-               wcscat(szDrive, L"mmc.exe");\r
-               if (CreateProcessW(szPath, szArg, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
-               {\r
-                  CloseHandle(pi.hProcess);\r
-                  CloseHandle(pi.hThread);\r
-               }\r
-            }\r
-            break;\r
-         case 14002:\r
-            dwSize = sizeof(szPath);\r
-            if (RegGetValueW(HKEY_LOCAL_MACHINE, \r
-                             L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\BackupPath",\r
-                             NULL,\r
-                             RRF_RT_REG_EXPAND_SZ,\r
-                             NULL,\r
-                             (PVOID)szPath,\r
-                             &dwSize) == S_OK)\r
-            {\r
-               if (CreateProcessW(szPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
-               {\r
-                  CloseHandle(pi.hProcess);\r
-                  CloseHandle(pi.hThread);\r
-               }\r
-            }\r
-      }\r
-      break;\r
-   }\r
-   return FALSE;\r
-}\r
-\r
-INT_PTR\r
-CALLBACK\r
-DriveHardwareDlg(\r
-    HWND hwndDlg,\r
-    UINT uMsg,\r
-    WPARAM wParam,\r
-    LPARAM lParam\r
-)\r
-{\r
-    GUID Guids[1];\r
-    Guids[0] = GUID_DEVCLASS_DISKDRIVE;\r
-\r
-    UNREFERENCED_PARAMETER(lParam);\r
-    UNREFERENCED_PARAMETER(wParam);\r
-\r
-    switch(uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            /* create the hardware page */\r
-            DeviceCreateHardwarePageEx(hwndDlg,\r
-                                       Guids,\r
-                                       sizeof(Guids) / sizeof(Guids[0]),\r
-                                       0);\r
-            break;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
-\r
-static\r
-const\r
-struct\r
-{\r
-   LPSTR resname;\r
-   DLGPROC dlgproc;\r
-} PropPages[] =\r
-{\r
-    { "DRIVE_GENERAL_DLG", DriveGeneralDlg },\r
-    { "DRIVE_EXTRA_DLG", DriveExtraDlg },\r
-    { "DRIVE_HARDWARE_DLG", DriveHardwareDlg },\r
-};\r
-\r
-HRESULT\r
-CALLBACK\r
-AddPropSheetPageProc(HPROPSHEETPAGE hpage, LPARAM lParam)\r
-{\r
-    PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;\r
-    if (ppsh != NULL && ppsh->nPages < MAX_PROPERTY_SHEET_PAGE)\r
-    {\r
-        ppsh->phpage[ppsh->nPages++] = hpage;\r
-        return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-\r
-BOOL\r
-SH_ShowDriveProperties(WCHAR * drive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl)\r
-{\r
-   HPSXA hpsx = NULL;\r
-   HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];\r
-   PROPSHEETHEADERW psh;\r
-   BOOL ret;\r
-   UINT i;\r
-   WCHAR szName[MAX_PATH];\r
-   DWORD dwMaxComponent, dwFileSysFlags;\r
-   IDataObject * pDataObj = NULL;\r
-\r
-   ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));\r
-   psh.dwSize = sizeof(PROPSHEETHEADERW);\r
-   //psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;\r
-   psh.hwndParent = NULL;\r
-   psh.nStartPage = 0;\r
-   psh.phpage = hpsp;\r
-\r
-\r
-   if (GetVolumeInformationW(drive, szName, sizeof(szName)/sizeof(WCHAR), NULL, &dwMaxComponent,\r
-                             &dwFileSysFlags, NULL, 0))\r
-   {\r
-      psh.pszCaption = szName;\r
-      psh.dwFlags |= PSH_PROPTITLE;\r
-      if (!wcslen(szName))\r
-      {\r
-          /* FIXME\r
-           * check if disk is a really a local hdd \r
-           */\r
-          i = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, szName, sizeof(szName)/sizeof(WCHAR));\r
-          if (i > 0 && i < (sizeof(szName)/sizeof(WCHAR)) + 6)\r
-          {\r
-              szName[i] = L' ';\r
-              szName[i+1] = L'(';\r
-              wcscpy(&szName[i+2], drive);\r
-              szName[i+4] = L')';\r
-              szName[i+5] = L'\0';\r
-          }\r
-      }\r
-   }\r
-\r
-   for (i = 0; i < DRIVE_PROPERTY_PAGES; i++)\r
-   {\r
-       HPROPSHEETPAGE hprop = SH_CreatePropertySheetPage(PropPages[i].resname, PropPages[i].dlgproc, (LPARAM)drive, NULL);\r
-       if (hprop)\r
-       {\r
-          hpsp[psh.nPages] = hprop;\r
-          psh.nPages++;\r
-       }\r
-   }\r
-   if (SHCreateDataObject(pidlFolder, 1, apidl, NULL, &IID_IDataObject, (void**)&pDataObj) == S_OK)\r
-   {\r
-       hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE-DRIVE_PROPERTY_PAGES, pDataObj);\r
-       if (hpsx)\r
-       {\r
-           SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageProc, (LPARAM)&psh);\r
-       }\r
-   }\r
-\r
-   ret = PropertySheetW(&psh);\r
-   if (pDataObj)\r
-       IDataObject_Release(pDataObj);\r
-\r
-   if (hpsx)\r
-       SHDestroyPropSheetExtArray(hpsx);\r
-\r
-   if (ret < 0)\r
-       return FALSE;\r
-   else\r
-       return TRUE;\r
-}\r
-\r
-BOOL\r
-GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNumberOfBytes)\r
-{\r
-    DWORD ClusterSize;\r
-\r
-    if (!wcsicmp(szFs, L"FAT16") ||\r
-        !wcsicmp(szFs, L"FAT")) //REACTOS HACK\r
-    {\r
-        if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024))\r
-            ClusterSize = 2048;\r
-        else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024))\r
-            ClusterSize = 512;\r
-        else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))\r
-            ClusterSize = 1024;\r
-        else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))\r
-            ClusterSize = 2048;\r
-        else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))\r
-            ClusterSize = 4096;\r
-        else if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))\r
-            ClusterSize = 8192;\r
-        else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))\r
-            ClusterSize = 16384;\r
-        else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))\r
-            ClusterSize = 32768;\r
-        else if (TotalNumberOfBytes->QuadPart <= (4096LL * 1024LL * 1024LL))\r
-            ClusterSize = 8192;\r
-        else \r
-            return FALSE;\r
-    }\r
-    else if (!wcsicmp(szFs, L"FAT32"))\r
-    {\r
-        if (TotalNumberOfBytes->QuadPart <=(64 * 1024 * 1024))\r
-            ClusterSize = 512;\r
-        else if (TotalNumberOfBytes->QuadPart <= (128   * 1024 * 1024))\r
-            ClusterSize = 1024;\r
-        else if (TotalNumberOfBytes->QuadPart <= (256   * 1024 * 1024))\r
-            ClusterSize = 2048;\r
-        else if (TotalNumberOfBytes->QuadPart <= (8192LL  * 1024LL * 1024LL))\r
-            ClusterSize = 2048;\r
-        else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL))\r
-            ClusterSize = 8192;\r
-        else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL))\r
-            ClusterSize = 16384;\r
-        else \r
-            return FALSE;\r
-   }\r
-    else if (!wcsicmp(szFs, L"NTFS"))\r
-    {\r
-        if (TotalNumberOfBytes->QuadPart <=(512 * 1024 * 1024))\r
-            ClusterSize = 512;\r
-        else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))\r
-            ClusterSize = 1024;\r
-        else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))\r
-            ClusterSize = 2048;\r
-        else\r
-            ClusterSize = 2048;\r
-   }\r
-   else\r
-        return FALSE;\r
-\r
-   *pClusterSize = ClusterSize;\r
-   return TRUE;\r
-}\r
-\r
-\r
-VOID\r
-InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-    WCHAR szFs[100] = {0};\r
-    WCHAR szDrive[4] = { L'C', ':', '\\', 0 };\r
-    INT iSelIndex;\r
-    ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;\r
-    DWORD ClusterSize;\r
-    LRESULT lIndex;\r
-    HWND hDlgCtrl;\r
-\r
-    hDlgCtrl = GetDlgItem(hwndDlg, 28677);\r
-    iSelIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);\r
-    if (iSelIndex == CB_ERR)\r
-        return;\r
-\r
-    if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFs) == CB_ERR)\r
-        return;\r
-\r
-    szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';\r
-    szDrive[0] = pContext->Drive + 'A';\r
-\r
-    if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))\r
-        return;\r
-\r
-    if (!wcsicmp(szFs, L"FAT16") ||\r
-        !wcsicmp(szFs, L"FAT")) //REACTOS HACK\r
-    {\r
-        if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))\r
-        {\r
-            TRACE("FAT16 is not supported on hdd larger than 4G current %lu\n", TotalNumberOfBytes.QuadPart);\r
-            SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);\r
-            return;\r
-        }\r
-\r
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-        {\r
-            hDlgCtrl = GetDlgItem(hwndDlg, 28680);\r
-            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';\r
-            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);\r
-            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);\r
-            if (lIndex != CB_ERR)\r
-                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);\r
-            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);\r
-        }\r
-    }\r
-    else if (!wcsicmp(szFs, L"FAT32"))\r
-    {\r
-        if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))\r
-        {\r
-            TRACE("FAT32 is not supported on hdd larger than 32G current %lu\n", TotalNumberOfBytes.QuadPart);\r
-            SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);\r
-            return;\r
-        }\r
-\r
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-        {\r
-            hDlgCtrl = GetDlgItem(hwndDlg, 28680);\r
-            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';\r
-            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);\r
-            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);\r
-            if (lIndex != CB_ERR)\r
-                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);\r
-            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);\r
-        }\r
-    }\r
-    else if (!wcsicmp(szFs, L"NTFS"))\r
-    {\r
-        if (!GetDefaultClusterSize(szFs, &ClusterSize, &TotalNumberOfBytes))\r
-        {\r
-            TRACE("NTFS is not supported on hdd larger than 2TB current %lu\n", TotalNumberOfBytes.QuadPart);\r
-            SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);\r
-            return;\r
-        }\r
-\r
-        hDlgCtrl = GetDlgItem(hwndDlg, 28680);\r
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-        {\r
-            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';\r
-            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);\r
-            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);\r
-            if (lIndex != CB_ERR)\r
-                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);\r
-            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);\r
-        }\r
-        ClusterSize = 512;\r
-        for (lIndex = 0; lIndex < 4; lIndex++)\r
-        {\r
-            TotalNumberOfBytes.QuadPart = ClusterSize;\r
-            if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-            {\r
-                lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);\r
-                if (lIndex != CB_ERR)\r
-                    SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);\r
-            }\r
-            ClusterSize *= 2;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        FIXME("unknown fs\n");\r
-        SendDlgItemMessageW(hwndDlg, 28680, CB_RESETCONTENT, iSelIndex, 0);\r
-        return;\r
-    }\r
-}\r
-\r
-VOID\r
-InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-    WCHAR szText[120];\r
-    WCHAR szDrive[4] = { L'C', ':', '\\', 0 };\r
-    WCHAR szFs[30] = {0};\r
-    INT Length, TempLength;\r
-    DWORD dwSerial, dwMaxComp, dwFileSys;\r
-    ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;\r
-    DWORD dwIndex, dwDefault;\r
-    UCHAR uMinor, uMajor;\r
-    BOOLEAN Latest;\r
-    HWND hDlgCtrl;\r
-\r
-    Length = GetWindowTextW(hwndDlg, szText, sizeof(szText)/sizeof(WCHAR));\r
-    szDrive[0] = pContext->Drive + L'A';\r
-    if (GetVolumeInformationW(szDrive, &szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2, &dwSerial, &dwMaxComp, &dwFileSys, szFs, sizeof(szFs)/sizeof(WCHAR)))\r
-    {\r
-        szText[Length] = L' ';\r
-        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-        TempLength = wcslen(&szText[Length+1]);\r
-        if (!TempLength)\r
-        {\r
-            /* load default volume label */\r
-            TempLength = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2);\r
-        }\r
-        else\r
-        {\r
-            /* set volume label */\r
-            szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-            SendDlgItemMessageW(hwndDlg, 28679, WM_SETTEXT, 0, (LPARAM)&szText[Length+1]);\r
-        }\r
-        Length += TempLength + 1;\r
-    }\r
-\r
-    if (Length + 4 < (sizeof(szText)/sizeof(WCHAR)))\r
-    {\r
-        szText[Length] = L' ';\r
-        szText[Length+1] = L'(';\r
-        szText[Length+2] = szDrive[0];\r
-        szText[Length+3] = L')';\r
-        Length +=4;\r
-    }\r
-\r
-    if (Length < (sizeof(szText)/sizeof(WCHAR)))\r
-        szText[Length] = L'\0';\r
-    else\r
-        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-\r
-    /* set window text */\r
-    SetWindowTextW(hwndDlg, szText);\r
-\r
-    if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))\r
-    {\r
-        if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, sizeof(szText)/sizeof(WCHAR)))\r
-        {\r
-            /* add drive capacity */\r
-            szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-            SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText);\r
-            SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0);\r
-        }\r
-    }\r
-\r
-    if (pContext->Options & SHFMT_OPT_FULL)\r
-    {\r
-        /* check quick format button */\r
-        SendDlgItemMessageW(hwndDlg, 28674, BM_SETCHECK, BST_CHECKED, 0);\r
-    }\r
-\r
-    /* enumerate all available filesystems */\r
-    dwIndex = 0;\r
-    dwDefault = 0;\r
-    hDlgCtrl = GetDlgItem(hwndDlg, 28677);\r
-\r
-    while(pContext->QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest))\r
-    {\r
-        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';\r
-        if (!wcsicmp(szText, szFs))\r
-            dwDefault = dwIndex;\r
-\r
-         SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szText);\r
-         dwIndex++;\r
-    }\r
-\r
-    if (!dwIndex)\r
-    {\r
-        ERR("no filesystem providers\n");\r
-        return;\r
-    }\r
-\r
-    /* select default filesys */\r
-    SendMessageW(hDlgCtrl, CB_SETCURSEL, dwDefault, 0);\r
-    /* setup cluster combo */\r
-    InsertDefaultClusterSizeForFs(hwndDlg, pContext);\r
-    /* hide progress control */\r
-    ShowWindow(GetDlgItem(hwndDlg, 28678), SW_HIDE);\r
-}\r
-\r
-HWND FormatDrvDialog = NULL;\r
-BOOLEAN bSuccess = FALSE;\r
-\r
-\r
-BOOLEAN\r
-NTAPI\r
-FormatExCB(\r
-       IN CALLBACKCOMMAND Command,\r
-       IN ULONG SubAction,\r
-       IN PVOID ActionInfo)\r
-{\r
-    PDWORD Progress;\r
-    PBOOLEAN pSuccess;\r
-    switch(Command)\r
-    {\r
-        case PROGRESS:\r
-            Progress = (PDWORD)ActionInfo;\r
-            SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0);\r
-            break;\r
-        case DONE:\r
-            pSuccess = (PBOOLEAN)ActionInfo;\r
-            bSuccess = (*pSuccess);\r
-            break;\r
-\r
-        case VOLUMEINUSE:\r
-        case INSUFFICIENTRIGHTS:\r
-        case FSNOTSUPPORTED:\r
-        case CLUSTERSIZETOOSMALL:\r
-            bSuccess = FALSE;\r
-            FIXME("\n");\r
-            break;\r
-\r
-        default:\r
-            break;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-VOID\r
-FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-       WCHAR szDrive[4] = { L'C', ':', '\\', 0 };\r
-    WCHAR szFileSys[40] = {0};\r
-    WCHAR szLabel[40] = {0};\r
-    INT iSelIndex;\r
-    UINT Length;\r
-    HWND hDlgCtrl;\r
-    BOOL QuickFormat;\r
-    DWORD ClusterSize;\r
-\r
-    /* set volume path */\r
-    szDrive[0] = pContext->Drive;\r
-\r
-    /* get filesystem */\r
-    hDlgCtrl = GetDlgItem(hwndDlg, 28677);\r
-    iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);\r
-    if (iSelIndex == CB_ERR)\r
-    {\r
-        FIXME("\n");\r
-        return;\r
-    }\r
-    Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0);\r
-    if (Length == CB_ERR || Length + 1> sizeof(szFileSys)/sizeof(WCHAR))\r
-    {\r
-        FIXME("\n");\r
-        return;\r
-    }\r
-\r
-    /* retrieve the file system */\r
-    SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys);\r
-    szFileSys[(sizeof(szFileSys)/sizeof(WCHAR))-1] = L'\0';\r
-\r
-    /* retrieve the volume label */\r
-    hDlgCtrl = GetWindow(hwndDlg, 28679);\r
-    Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0);\r
-    if (Length + 1 > sizeof(szLabel)/sizeof(WCHAR))\r
-    {\r
-        FIXME("\n");\r
-        return;\r
-    }\r
-    SendMessageW(hDlgCtrl, WM_GETTEXT, sizeof(szLabel)/sizeof(WCHAR), (LPARAM)szLabel);\r
-    szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0';\r
-\r
-    /* check for quickformat */\r
-    if (SendDlgItemMessageW(hwndDlg, 28674, BM_GETCHECK, 0, 0) == BST_CHECKED)\r
-        QuickFormat = TRUE;\r
-    else\r
-        QuickFormat = FALSE;\r
-\r
-    /* get the cluster size */\r
-    hDlgCtrl = GetDlgItem(hwndDlg, 28680);\r
-    iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);\r
-    if (iSelIndex == CB_ERR)\r
-    {\r
-        FIXME("\n");\r
-        return;\r
-    }\r
-    ClusterSize = SendMessageW(hDlgCtrl, CB_GETITEMDATA, iSelIndex, 0);\r
-    if (ClusterSize == CB_ERR)\r
-    {\r
-        FIXME("\n");\r
-        return;\r
-    }\r
-\r
-    hDlgCtrl = GetDlgItem(hwndDlg, 28680);\r
-    ShowWindow(hDlgCtrl, SW_SHOW);\r
-    SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100));\r
-    bSuccess = FALSE;\r
-\r
-    /* FIXME\r
-     * will cause display problems\r
-     * when performing more than one format\r
-     */\r
-    FormatDrvDialog = hwndDlg;\r
-\r
-    pContext->FormatEx(szDrive,\r
-                       FMIFS_HARDDISK, /* FIXME */\r
-                       szFileSys,\r
-                       szLabel,\r
-                       QuickFormat,\r
-                       ClusterSize,\r
-                       FormatExCB);\r
-\r
-    ShowWindow(hDlgCtrl, SW_HIDE);\r
-    FormatDrvDialog = NULL;\r
-    if (!bSuccess)\r
-    {\r
-        pContext->Result = SHFMT_ERROR;\r
-    }\r
-    else if (QuickFormat)\r
-    {\r
-        pContext->Result = SHFMT_OPT_FULL;\r
-    }\r
-    else\r
-    {\r
-        pContext->Result =  FALSE;\r
-    }\r
-}\r
-\r
-\r
-BOOL \r
-CALLBACK \r
-FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    PFORMAT_DRIVE_CONTEXT pContext;\r
-\r
-    switch(uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);\r
-            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);\r
-            return TRUE;\r
-        case WM_COMMAND:\r
-            switch(LOWORD(wParam))\r
-            {\r
-                case IDOK:\r
-                    pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-                    FormatDrive(hwndDlg, pContext);\r
-                    break;\r
-                case IDCANCEL:\r
-                    pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-                    EndDialog(hwndDlg, pContext->Result);\r
-                    break;\r
-                case 28677: // filesystem combo\r
-                    if (HIWORD(wParam) == CBN_SELENDOK)\r
-                    {\r
-                        pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-                        InsertDefaultClusterSizeForFs(hwndDlg, pContext);\r
-                    }\r
-                    break;\r
-            }\r
-    }\r
-    return FALSE;\r
-}\r
-\r
-\r
-BOOL\r
-InitializeFmifsLibrary(PFORMAT_DRIVE_CONTEXT pContext)\r
-{\r
-    INITIALIZE_FMIFS InitFmifs;\r
-    BOOLEAN ret;\r
-    HMODULE hLibrary;\r
-\r
-    hLibrary = pContext->hLibrary = LoadLibraryW(L"fmifs.dll");\r
-    if(!hLibrary)\r
-    {\r
-        ERR("failed to load fmifs.dll\n");\r
-        return FALSE;\r
-    }\r
-\r
-    InitFmifs = (INITIALIZE_FMIFS)GetProcAddress(hLibrary, "InitializeFmIfs");\r
-    if (!InitFmifs)\r
-    {\r
-        ERR("InitializeFmIfs export is missing\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    ret = (*InitFmifs)(NULL, DLL_PROCESS_ATTACH, NULL);\r
-    if (!ret)\r
-    {\r
-        ERR("fmifs failed to initialize\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    pContext->QueryAvailableFileSystemFormat = (QUERY_AVAILABLEFSFORMAT)GetProcAddress(hLibrary, "QueryAvailableFileSystemFormat");\r
-    if (!pContext->QueryAvailableFileSystemFormat)\r
-    {\r
-        ERR("QueryAvailableFileSystemFormat export is missing\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    pContext->FormatEx = (FORMAT_EX) GetProcAddress(hLibrary, "FormatEx");\r
-    if (!pContext->FormatEx)\r
-    {\r
-        ERR("FormatEx export is missing\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    pContext->EnableVolumeCompression = (ENABLEVOLUMECOMPRESSION) GetProcAddress(hLibrary, "EnableVolumeCompression");\r
-    if (!pContext->FormatEx)\r
-    {\r
-        ERR("EnableVolumeCompression export is missing\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    pContext->Chkdsk = (CHKDSK) GetProcAddress(hLibrary, "Chkdsk");\r
-    if (!pContext->Chkdsk)\r
-    {\r
-        ERR("Chkdsk export is missing\n");\r
-        FreeLibrary(hLibrary);\r
-        return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-/*************************************************************************\r
- *              SHFormatDrive (SHELL32.@)\r
- */\r
-\r
-DWORD \r
-WINAPI\r
-SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)\r
-{\r
-    FORMAT_DRIVE_CONTEXT Context;\r
-    int result;\r
-\r
-    TRACE("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options);\r
-\r
-    if (!InitializeFmifsLibrary(&Context))\r
-    {\r
-        ERR("failed to initialize fmifs\n");\r
-        return SHFMT_NOFORMAT;\r
-    }\r
-\r
-    Context.Drive = drive;\r
-    Context.Options = options;\r
-\r
-    result = DialogBoxParamW(shell32_hInstance, L"FORMAT_DLG", hwnd, FormatDriveDlg, (LPARAM)&Context);\r
-\r
-    FreeLibrary(Context.hLibrary);\r
-    return result;\r
-}\r
-\r
-\r
+/*
+ *                 Shell Library Functions
+ *
+ * Copyright 2005 Johannes Anderwald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LARGEINT_PROTOS
+#define LargeIntegerDivide RtlLargeIntegerDivide
+#define ExtendedIntegerMultiply RtlExtendedIntegerMultiply
+#define ConvertUlongToLargeInteger RtlConvertUlongToLargeInteger
+#define LargeIntegerSubtract RtlLargeIntegerSubtract
+#define MAX_PROPERTY_SHEET_PAGE 32
+
+#define WIN32_NO_STATUS
+#define NTOS_MODE_USER
+#define UNICODE
+#define _UNICODE
+#define COBJMACROS
+#include <windows.h>
+#include <ndk/ntndk.h>
+#include <fmifs/fmifs.h>
+#include <largeint.h>
+
+#include <precomp.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+typedef enum
+{
+    HWPD_STANDARDLIST = 0,
+    HWPD_LARGELIST,
+    HWPD_MAX = HWPD_LARGELIST
+} HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;
+
+typedef
+BOOLEAN 
+(NTAPI *INITIALIZE_FMIFS)(
+       IN PVOID hinstDll,
+       IN DWORD dwReason,
+       IN PVOID reserved
+);
+typedef
+BOOLEAN
+(NTAPI *QUERY_AVAILABLEFSFORMAT)(
+       IN DWORD Index,
+       IN OUT PWCHAR FileSystem,
+       OUT UCHAR* Major,
+       OUT UCHAR* Minor,
+       OUT BOOLEAN* LastestVersion
+);
+typedef
+BOOLEAN
+(NTAPI *ENABLEVOLUMECOMPRESSION)(
+       IN PWCHAR DriveRoot,
+       IN USHORT Compression
+);
+
+typedef
+VOID 
+(NTAPI *FORMAT_EX)(
+       IN PWCHAR DriveRoot,
+       IN FMIFS_MEDIA_FLAG MediaFlag,
+       IN PWCHAR Format,
+       IN PWCHAR Label,
+       IN BOOLEAN QuickFormat,
+       IN ULONG ClusterSize,
+       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
+{
+    WCHAR   Drive;
+    UINT    Options;
+    HMODULE hLibrary;
+    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);
+HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
+HWND WINAPI
+DeviceCreateHardwarePageEx(HWND hWndParent,
+                           LPGUID lpGuids,
+                           UINT uNumberOfGuids,
+                           HWPAGE_DISPLAYMODE DisplayMode);
+
+HPROPSHEETPAGE SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle);
+
+#define DRIVE_PROPERTY_PAGES (3)
+
+static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
+
+
+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
+GetFreeBytesShare(LARGE_INTEGER TotalNumberOfFreeBytes, LARGE_INTEGER TotalNumberOfBytes)
+{
+   LARGE_INTEGER Temp, Result, Remainder;
+
+   if (TotalNumberOfFreeBytes.QuadPart == 0LL)
+   {
+      return ConvertUlongToLargeInteger(0);
+   }
+
+   Temp = LargeIntegerDivide(TotalNumberOfBytes, ConvertUlongToLargeInteger(100), &Remainder);
+   if (Temp.QuadPart >= TotalNumberOfFreeBytes.QuadPart)
+   {
+      Result = ConvertUlongToLargeInteger(1);
+   }else
+   {
+      Result = LargeIntegerDivide(TotalNumberOfFreeBytes, Temp, &Remainder);
+   }
+
+   return Result;
+}
+
+static
+void
+PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT drawItem)
+{
+   HBRUSH hBrush;
+
+   if (drawItem->CtlID == 14013)
+   {
+      hBrush = CreateSolidBrush(RGB(0, 0, 255));
+      if (hBrush)
+      {
+         FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
+         DeleteObject((HGDIOBJ)hBrush);
+      }
+   }
+   else if (drawItem->CtlID == 14014)
+   {
+      hBrush = CreateSolidBrush(RGB(255, 0, 255));
+      if (hBrush)
+      {
+         FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
+         DeleteObject((HGDIOBJ)hBrush);
+      }
+   }
+   else if (drawItem->CtlID == 14015)
+   {
+      HBRUSH hBlueBrush;
+      HBRUSH hMagBrush;
+      RECT rect;
+      LONG horzsize;
+      LARGE_INTEGER Result;
+      WCHAR szBuffer[20];
+
+      hBlueBrush = CreateSolidBrush(RGB(0, 0, 255));
+      hMagBrush = CreateSolidBrush(RGB(255, 0, 255));
+
+      SendDlgItemMessageW(hwndDlg, 14006, WM_GETTEXT, 20, (LPARAM)szBuffer);
+      Result.QuadPart = _wtoi(szBuffer);
+
+      CopyRect(&rect, &drawItem->rcItem);
+      horzsize = rect.right - rect.left;
+      Result.QuadPart = (Result.QuadPart * horzsize) / 100;
+
+      rect.right = drawItem->rcItem.right - Result.QuadPart;
+      FillRect(drawItem->hDC, &rect, hBlueBrush);
+      rect.left = rect.right;
+      rect.right = drawItem->rcItem.right;
+      FillRect(drawItem->hDC, &rect, hMagBrush);
+      DeleteObject(hBlueBrush);
+      DeleteObject(hMagBrush);
+   }
+}
+
+static
+void
+InitializeGeneralDriveDialog(HWND hwndDlg, WCHAR * szDrive)
+{
+   WCHAR szVolumeName[MAX_PATH+1] = {0};
+   DWORD MaxComponentLength = 0;
+   DWORD FileSystemFlags = 0;
+   WCHAR FileSystemName[MAX_PATH+1] = {0};
+   WCHAR szFormat[50];
+   WCHAR szBuffer[128];
+   BOOL ret;
+   UINT DriveType;
+   ULARGE_INTEGER FreeBytesAvailable;
+   LARGE_INTEGER TotalNumberOfFreeBytes;
+   LARGE_INTEGER TotalNumberOfBytes;
+
+   ret = GetVolumeInformationW(szDrive, szVolumeName, MAX_PATH+1, NULL, &MaxComponentLength, &FileSystemFlags, FileSystemName, MAX_PATH+1);
+   if (ret)
+   {
+      /* set volume label */
+      SendDlgItemMessageW(hwndDlg, 14000, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szVolumeName);
+
+      /* set filesystem type */
+      SendDlgItemMessageW(hwndDlg, 14002, WM_SETTEXT, (WPARAM)NULL, (LPARAM)FileSystemName);
+
+   }
+
+   DriveType = GetDriveTypeW(szDrive);
+   if (DriveType == DRIVE_FIXED || DriveType == DRIVE_CDROM)
+   {
+
+      if(GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailable, (PULARGE_INTEGER)&TotalNumberOfBytes, (PULARGE_INTEGER)&TotalNumberOfFreeBytes))
+      {
+         WCHAR szResult[128];
+         LARGE_INTEGER Result;
+#ifdef IOCTL_DISK_GET_LENGTH_INFO_IMPLEMENTED
+         HANDLE hVolume;
+         DWORD BytesReturned = 0;
+
+         swprintf(szResult, L"\\\\.\\%c:", towupper(szDrive[0]));
+         hVolume = CreateFileW(szResult, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+         if (hVolume != INVALID_HANDLE_VALUE)
+         {
+            ret = DeviceIoControl(hVolume, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, (LPVOID)&TotalNumberOfBytes, sizeof(ULARGE_INTEGER), &BytesReturned, NULL);
+            if (ret && StrFormatByteSizeW(LengthInformation.Length.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
+               SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
+
+            CloseHandle(hVolume);
+         }
+         TRACE("szResult %s hVOlume %p ret %d LengthInformation %ul Bytesreturned %d\n", debugstr_w(szResult), hVolume, ret, LengthInformation.Length.QuadPart, BytesReturned);
+#else
+            if (ret && StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
+               SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
+#endif
+
+         if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
+             SendDlgItemMessageW(hwndDlg, 14003, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
+
+         if (StrFormatByteSizeW(FreeBytesAvailable.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
+             SendDlgItemMessageW(hwndDlg, 14005, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
+
+         Result = GetFreeBytesShare(TotalNumberOfFreeBytes, TotalNumberOfBytes);
+         /* set free bytes percentage */
+         swprintf(szResult, L"%02d%%", Result.QuadPart);
+         SendDlgItemMessageW(hwndDlg, 14006, WM_SETTEXT, (WPARAM)0, (LPARAM)szResult);
+         /* store used share amount */
+         Result = LargeIntegerSubtract(ConvertUlongToLargeInteger(100), Result);
+         swprintf(szResult, L"%02d%%", Result.QuadPart);
+         SendDlgItemMessageW(hwndDlg, 14004, WM_SETTEXT, (WPARAM)0, (LPARAM)szResult);
+         if (DriveType == DRIVE_FIXED)
+         {
+            if (LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+               SendDlgItemMessageW(hwndDlg, 14001, WM_SETTEXT, (WPARAM)0, (LPARAM)szBuffer);
+         }
+         else /* DriveType == DRIVE_CDROM) */
+         {
+            if (LoadStringW(shell32_hInstance, IDS_DRIVE_CDROM, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+               SendDlgItemMessageW(hwndDlg, 14001, WM_SETTEXT, (WPARAM)0, (LPARAM)szBuffer);
+         }
+      }
+   }
+   /* set drive description */
+   SendDlgItemMessageW(hwndDlg, 14009, WM_GETTEXT, (WPARAM)50, (LPARAM)szFormat);
+   swprintf(szBuffer, szFormat, szDrive);
+   SendDlgItemMessageW(hwndDlg, 14009, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szBuffer);
+}
+
+
+INT_PTR
+CALLBACK
+DriveGeneralDlg(
+    HWND hwndDlg,
+    UINT uMsg,
+    WPARAM wParam,
+    LPARAM lParam
+)
+{
+    LPPROPSHEETPAGEW ppsp;
+    LPDRAWITEMSTRUCT drawItem;
+    STARTUPINFOW si;
+    PROCESS_INFORMATION pi;
+    WCHAR * lpstr;
+    WCHAR szPath[MAX_PATH];
+    UINT length;
+    LPPSHNOTIFY lppsn;
+
+    switch(uMsg)
+    {
+    case WM_INITDIALOG:
+        ppsp = (LPPROPSHEETPAGEW)lParam;
+        if (ppsp == NULL)
+            break;
+        lpstr = (WCHAR *)ppsp->lParam;
+        SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lpstr);
+        InitializeGeneralDriveDialog(hwndDlg, lpstr);
+        return TRUE;
+    case WM_DRAWITEM:
+        drawItem = (LPDRAWITEMSTRUCT)lParam;
+        if (drawItem->CtlID >= 14013 && drawItem->CtlID <= 14015)
+        {
+            PaintStaticControls(hwndDlg, drawItem);
+            return TRUE;
+        }
+        break;
+    case WM_COMMAND:
+        if (LOWORD(wParam) == 14010) /* Disk Cleanup */
+        {
+           lpstr = (WCHAR*)GetWindowLongPtr(hwndDlg, DWLP_USER);
+           ZeroMemory( &si, sizeof(si) );
+           si.cb = sizeof(si);
+           ZeroMemory( &pi, sizeof(pi) );
+           if (!GetSystemDirectoryW(szPath, MAX_PATH))
+              break;
+           wcscat(szPath, L"\\cleanmgr.exe /D ");
+           length = wcslen(szPath);
+           szPath[length] = lpstr[0];
+           szPath[length+1] = L'\0';
+           if (CreateProcessW(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+           {
+              CloseHandle(pi.hProcess);
+              CloseHandle(pi.hThread);
+           }
+           break;
+        }
+    case WM_NOTIFY:
+        lppsn = (LPPSHNOTIFY) lParam;
+        if (LOWORD(wParam) == 14000)
+        {
+           if (HIWORD(wParam) == EN_CHANGE)
+           {
+              PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+           }
+           break;
+        }
+        if (lppsn->hdr.code == PSN_APPLY)
+        {
+           lpstr = (LPWSTR)GetWindowLongPtr(hwndDlg, DWLP_USER);
+           if (lpstr && SendDlgItemMessageW(hwndDlg, 14000, WM_GETTEXT, sizeof(szPath)/sizeof(WCHAR), (LPARAM)szPath))
+           {
+              szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0';
+              SetVolumeLabelW(lpstr, szPath);
+           }
+           SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
+           return TRUE;
+        }
+        break;
+
+    default:
+        break;
+   }
+
+
+   return FALSE;
+}
+
+INT_PTR
+CALLBACK
+DriveExtraDlg(
+    HWND hwndDlg,
+    UINT uMsg,
+    WPARAM wParam,
+    LPARAM lParam
+)
+{
+   STARTUPINFOW si;
+   PROCESS_INFORMATION pi;
+   WCHAR szPath[MAX_PATH + 10];
+   WCHAR szArg[MAX_PATH];
+   WCHAR * szDrive;
+   LPPROPSHEETPAGEW ppsp;
+   DWORD dwSize;
+   FORMAT_DRIVE_CONTEXT Context;
+
+   switch (uMsg)
+   {
+   case WM_INITDIALOG:
+      ppsp = (LPPROPSHEETPAGEW)lParam;
+      SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)ppsp->lParam);
+      return TRUE;
+   case WM_COMMAND:
+      ZeroMemory( &si, sizeof(si) );
+      si.cb = sizeof(si);
+      ZeroMemory( &pi, sizeof(pi) );
+
+      szDrive = (WCHAR*)GetWindowLongPtr(hwndDlg, DWLP_USER);
+      switch(LOWORD(wParam))
+      {
+         case 14000:
+            if (InitializeFmifsLibrary(&Context))
+            {
+                Context.Drive = szDrive[0];
+                DialogBoxParamW(shell32_hInstance, L"CHKDSK_DLG", hwndDlg, ChkDskDlg, (LPARAM)&Context);
+                FreeLibrary(Context.hLibrary);
+            }
+            break;
+         case 14001:
+            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)
+            {
+                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:
+            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)
+            {
+               if (CreateProcessW(szPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+               {
+                  CloseHandle(pi.hProcess);
+                  CloseHandle(pi.hThread);
+               }
+            }
+      }
+      break;
+   }
+   return FALSE;
+}
+
+INT_PTR
+CALLBACK
+DriveHardwareDlg(
+    HWND hwndDlg,
+    UINT uMsg,
+    WPARAM wParam,
+    LPARAM lParam
+)
+{
+    GUID Guids[1];
+    Guids[0] = GUID_DEVCLASS_DISKDRIVE;
+
+    UNREFERENCED_PARAMETER(lParam);
+    UNREFERENCED_PARAMETER(wParam);
+
+    switch(uMsg)
+    {
+        case WM_INITDIALOG:
+            /* create the hardware page */
+            DeviceCreateHardwarePageEx(hwndDlg,
+                                       Guids,
+                                       sizeof(Guids) / sizeof(Guids[0]),
+                                       0);
+            break;
+    }
+
+    return FALSE;
+}
+
+static
+const
+struct
+{
+   LPSTR resname;
+   DLGPROC dlgproc;
+   UINT DriveType;
+} PropPages[] =
+{
+    { "DRIVE_GENERAL_DLG", DriveGeneralDlg, -1},
+    { "DRIVE_EXTRA_DLG", DriveExtraDlg, DRIVE_FIXED},
+    { "DRIVE_HARDWARE_DLG", DriveHardwareDlg, -1},
+};
+
+HRESULT
+CALLBACK
+AddPropSheetPageProc(HPROPSHEETPAGE hpage, LPARAM lParam)
+{
+    PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
+    if (ppsh != NULL && ppsh->nPages < MAX_PROPERTY_SHEET_PAGE)
+    {
+        ppsh->phpage[ppsh->nPages++] = hpage;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL
+SH_ShowDriveProperties(WCHAR * drive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl)
+{
+   HPSXA hpsx = NULL;
+   HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];
+   PROPSHEETHEADERW psh;
+   BOOL ret;
+   UINT i;
+   WCHAR szName[MAX_PATH+6];
+   DWORD dwMaxComponent, dwFileSysFlags;
+   IDataObject * pDataObj = NULL;
+   UINT DriveType;
+
+   ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
+   psh.dwSize = sizeof(PROPSHEETHEADERW);
+   //psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
+   psh.hwndParent = NULL;
+   psh.nStartPage = 0;
+   psh.phpage = hpsp;
+
+   if (GetVolumeInformationW(drive, szName, sizeof(szName)/sizeof(WCHAR), NULL, &dwMaxComponent,
+                             &dwFileSysFlags, NULL, 0))
+   {
+      psh.pszCaption = szName;
+      psh.dwFlags |= PSH_PROPTITLE;
+      if (!wcslen(szName))
+      {
+          /* FIXME
+           * check if disk is a really a local hdd 
+           */
+          i = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, szName, sizeof(szName)/sizeof(WCHAR)-6);
+          if (i > 0 && i < (sizeof(szName)/sizeof(WCHAR)) - 6)
+          {
+              szName[i] = L' ';
+              szName[i+1] = L'(';
+              wcscpy(&szName[i+2], drive);
+              szName[i+4] = L')';
+              szName[i+5] = L'\0';
+          }
+      }
+   }
+
+   DriveType = GetDriveTypeW(drive);
+   for (i = 0; i < DRIVE_PROPERTY_PAGES; i++)
+   {
+       if (PropPages[i].DriveType == (UINT)-1 || (PropPages[i].DriveType != (UINT)-1 &&  PropPages[i].DriveType == DriveType))
+       {
+           HPROPSHEETPAGE hprop = SH_CreatePropertySheetPage(PropPages[i].resname, PropPages[i].dlgproc, (LPARAM)drive, NULL);
+           if (hprop)
+           {
+              hpsp[psh.nPages] = hprop;
+              psh.nPages++;
+           }
+       }
+   }
+
+   if (SHCreateDataObject(pidlFolder, 1, apidl, NULL, &IID_IDataObject, (void**)&pDataObj) == S_OK)
+   {
+       hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE-DRIVE_PROPERTY_PAGES, pDataObj);
+       if (hpsx)
+       {
+           SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageProc, (LPARAM)&psh);
+       }
+   }
+
+   ret = PropertySheetW(&psh);
+   if (pDataObj)
+       IDataObject_Release(pDataObj);
+
+   if (hpsx)
+       SHDestroyPropSheetExtArray(hpsx);
+
+   if (ret < 0)
+       return FALSE;
+   else
+       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 };
+    INT iSelIndex;
+    ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
+    DWORD ClusterSize;
+    LRESULT lIndex;
+    HWND hDlgCtrl;
+
+    hDlgCtrl = GetDlgItem(hwndDlg, 28677);
+    iSelIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
+    if (iSelIndex == CB_ERR)
+        return;
+
+    if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFs) == CB_ERR)
+        return;
+
+    szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';
+    szDrive[0] = pContext->Drive + 'A';
+
+    if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
+        return;
+
+    if (!wcsicmp(szFs, L"FAT16") ||
+        !wcsicmp(szFs, L"FAT")) //REACTOS HACK
+    {
+        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);
+            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';
+            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
+            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);
+            if (lIndex != CB_ERR)
+                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
+        }
+    }
+    else if (!wcsicmp(szFs, L"FAT32"))
+    {
+        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);
+            return;
+        }
+
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, szFs, sizeof(szFs)/sizeof(WCHAR)))
+        {
+            hDlgCtrl = GetDlgItem(hwndDlg, 28680);
+            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';
+            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
+            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);
+            if (lIndex != CB_ERR)
+                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
+        }
+    }
+    else if (!wcsicmp(szFs, L"NTFS"))
+    {
+        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)))
+        {
+            szFs[(sizeof(szFs)/sizeof(WCHAR))-1] = L'\0';
+            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
+            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);
+            if (lIndex != CB_ERR)
+                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
+        }
+        ClusterSize = 512;
+        for (lIndex = 0; lIndex < 4; lIndex++)
+        {
+            TotalNumberOfBytes.QuadPart = ClusterSize;
+            if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szFs, sizeof(szFs)/sizeof(WCHAR)))
+            {
+                lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szFs);
+                if (lIndex != CB_ERR)
+                    SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            }
+            ClusterSize *= 2;
+        }
+    }
+    else
+    {
+        FIXME("unknown fs\n");
+        SendDlgItemMessageW(hwndDlg, 28680, CB_RESETCONTENT, iSelIndex, 0);
+        return;
+    }
+}
+
+VOID
+InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
+{
+    WCHAR szText[120];
+    WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
+    WCHAR szFs[30] = {0};
+    INT Length, TempLength;
+    DWORD dwSerial, dwMaxComp, dwFileSys;
+    ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
+    DWORD dwIndex, dwDefault;
+    UCHAR uMinor, uMajor;
+    BOOLEAN Latest;
+    HWND hDlgCtrl;
+
+    Length = GetWindowTextW(hwndDlg, szText, sizeof(szText)/sizeof(WCHAR));
+    if (Length < 0)
+        Length = 0;
+    szDrive[0] = pContext->Drive + L'A';
+    if (GetVolumeInformationW(szDrive, &szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2, &dwSerial, &dwMaxComp, &dwFileSys, szFs, sizeof(szFs)/sizeof(WCHAR)))
+    {
+        szText[Length] = L' ';
+        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+        TempLength = wcslen(&szText[Length+1]);
+        if (!TempLength)
+        {
+            /* load default volume label */
+            TempLength = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[Length+1], (sizeof(szText)/sizeof(WCHAR))- Length - 2);
+        }
+        else
+        {
+            /* set volume label */
+            szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+            SendDlgItemMessageW(hwndDlg, 28679, WM_SETTEXT, 0, (LPARAM)&szText[Length+1]);
+        }
+        Length += TempLength + 1;
+    }
+
+    if (Length + 4 < (sizeof(szText)/sizeof(WCHAR)))
+    {
+        szText[Length] = L' ';
+        szText[Length+1] = L'(';
+        szText[Length+2] = szDrive[0];
+        szText[Length+3] = L')';
+        Length +=4;
+    }
+
+    if (Length < (sizeof(szText)/sizeof(WCHAR)))
+        szText[Length] = L'\0';
+    else
+        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+
+    /* set window text */
+    SetWindowTextW(hwndDlg, szText);
+
+    if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
+    {
+        if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, sizeof(szText)/sizeof(WCHAR)))
+        {
+            /* add drive capacity */
+            szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+            SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText);
+            SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0);
+        }
+    }
+
+    if (pContext->Options & SHFMT_OPT_FULL)
+    {
+        /* check quick format button */
+        SendDlgItemMessageW(hwndDlg, 28674, BM_SETCHECK, BST_CHECKED, 0);
+    }
+
+    /* enumerate all available filesystems */
+    dwIndex = 0;
+    dwDefault = 0;
+    hDlgCtrl = GetDlgItem(hwndDlg, 28677);
+
+    while(pContext->QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest))
+    {
+        szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
+        if (!wcsicmp(szText, szFs))
+            dwDefault = dwIndex;
+
+         SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)szText);
+         dwIndex++;
+    }
+
+    if (!dwIndex)
+    {
+        ERR("no filesystem providers\n");
+        return;
+    }
+
+    /* select default filesys */
+    SendMessageW(hDlgCtrl, CB_SETCURSEL, dwDefault, 0);
+    /* setup cluster combo */
+    InsertDefaultClusterSizeForFs(hwndDlg, pContext);
+    /* hide progress control */
+    ShowWindow(GetDlgItem(hwndDlg, 28678), SW_HIDE);
+}
+
+HWND FormatDrvDialog = NULL;
+BOOLEAN bSuccess = FALSE;
+
+
+BOOLEAN
+NTAPI
+FormatExCB(
+       IN CALLBACKCOMMAND Command,
+       IN ULONG SubAction,
+       IN PVOID ActionInfo)
+{
+    PDWORD Progress;
+    PBOOLEAN pSuccess;
+    switch(Command)
+    {
+        case PROGRESS:
+            Progress = (PDWORD)ActionInfo;
+            SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0);
+            break;
+        case DONE:
+            pSuccess = (PBOOLEAN)ActionInfo;
+            bSuccess = (*pSuccess);
+            break;
+
+        case VOLUMEINUSE:
+        case INSUFFICIENTRIGHTS:
+        case FSNOTSUPPORTED:
+        case CLUSTERSIZETOOSMALL:
+            bSuccess = FALSE;
+            FIXME("\n");
+            break;
+
+        default:
+            break;
+    }
+
+    return TRUE;
+}
+
+
+
+
+
+VOID
+FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
+{
+       WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
+    WCHAR szFileSys[40] = {0};
+    WCHAR szLabel[40] = {0};
+    INT iSelIndex;
+    UINT Length;
+    HWND hDlgCtrl;
+    BOOL QuickFormat;
+    DWORD ClusterSize;
+
+    /* set volume path */
+    szDrive[0] = pContext->Drive;
+
+    /* get filesystem */
+    hDlgCtrl = GetDlgItem(hwndDlg, 28677);
+    iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
+    if (iSelIndex == CB_ERR)
+    {
+        FIXME("\n");
+        return;
+    }
+    Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0);
+    if (Length == CB_ERR || Length + 1> sizeof(szFileSys)/sizeof(WCHAR))
+    {
+        FIXME("\n");
+        return;
+    }
+
+    /* retrieve the file system */
+    SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys);
+    szFileSys[(sizeof(szFileSys)/sizeof(WCHAR))-1] = L'\0';
+
+    /* retrieve the volume label */
+    hDlgCtrl = GetWindow(hwndDlg, 28679);
+    Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0);
+    if (Length + 1 > sizeof(szLabel)/sizeof(WCHAR))
+    {
+        FIXME("\n");
+        return;
+    }
+    SendMessageW(hDlgCtrl, WM_GETTEXT, sizeof(szLabel)/sizeof(WCHAR), (LPARAM)szLabel);
+    szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0';
+
+    /* check for quickformat */
+    if (SendDlgItemMessageW(hwndDlg, 28674, BM_GETCHECK, 0, 0) == BST_CHECKED)
+        QuickFormat = TRUE;
+    else
+        QuickFormat = FALSE;
+
+    /* get the cluster size */
+    hDlgCtrl = GetDlgItem(hwndDlg, 28680);
+    iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
+    if (iSelIndex == CB_ERR)
+    {
+        FIXME("\n");
+        return;
+    }
+    ClusterSize = SendMessageW(hDlgCtrl, CB_GETITEMDATA, iSelIndex, 0);
+    if (ClusterSize == CB_ERR)
+    {
+        FIXME("\n");
+        return;
+    }
+
+    hDlgCtrl = GetDlgItem(hwndDlg, 28680);
+    ShowWindow(hDlgCtrl, SW_SHOW);
+    SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+    bSuccess = FALSE;
+
+    /* FIXME
+     * will cause display problems
+     * when performing more than one format
+     */
+    FormatDrvDialog = hwndDlg;
+
+    pContext->FormatEx(szDrive,
+                       FMIFS_HARDDISK, /* FIXME */
+                       szFileSys,
+                       szLabel,
+                       QuickFormat,
+                       ClusterSize,
+                       FormatExCB);
+
+    ShowWindow(hDlgCtrl, SW_HIDE);
+    FormatDrvDialog = NULL;
+    if (!bSuccess)
+    {
+        pContext->Result = SHFMT_ERROR;
+    }
+    else if (QuickFormat)
+    {
+        pContext->Result = SHFMT_OPT_FULL;
+    }
+    else
+    {
+        pContext->Result =  FALSE;
+    }
+}
+
+
+INT_PTR 
+CALLBACK 
+FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    PFORMAT_DRIVE_CONTEXT pContext;
+
+    switch(uMsg)
+    {
+        case WM_INITDIALOG:
+            InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);
+            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
+            return TRUE;
+        case WM_COMMAND:
+            switch(LOWORD(wParam))
+            {
+                case IDOK:
+                    pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                    FormatDrive(hwndDlg, pContext);
+                    break;
+                case IDCANCEL:
+                    pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                    EndDialog(hwndDlg, pContext->Result);
+                    break;
+                case 28677: // filesystem combo
+                    if (HIWORD(wParam) == CBN_SELENDOK)
+                    {
+                        pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                        InsertDefaultClusterSizeForFs(hwndDlg, pContext);
+                    }
+                    break;
+            }
+    }
+    return FALSE;
+}
+
+
+BOOL
+InitializeFmifsLibrary(PFORMAT_DRIVE_CONTEXT pContext)
+{
+    INITIALIZE_FMIFS InitFmifs;
+    BOOLEAN ret;
+    HMODULE hLibrary;
+
+    hLibrary = pContext->hLibrary = LoadLibraryW(L"fmifs.dll");
+    if(!hLibrary)
+    {
+        ERR("failed to load fmifs.dll\n");
+        return FALSE;
+    }
+
+    InitFmifs = (INITIALIZE_FMIFS)GetProcAddress(hLibrary, "InitializeFmIfs");
+    if (!InitFmifs)
+    {
+        ERR("InitializeFmIfs export is missing\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    ret = (*InitFmifs)(NULL, DLL_PROCESS_ATTACH, NULL);
+    if (!ret)
+    {
+        ERR("fmifs failed to initialize\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    pContext->QueryAvailableFileSystemFormat = (QUERY_AVAILABLEFSFORMAT)GetProcAddress(hLibrary, "QueryAvailableFileSystemFormat");
+    if (!pContext->QueryAvailableFileSystemFormat)
+    {
+        ERR("QueryAvailableFileSystemFormat export is missing\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    pContext->FormatEx = (FORMAT_EX) GetProcAddress(hLibrary, "FormatEx");
+    if (!pContext->FormatEx)
+    {
+        ERR("FormatEx export is missing\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    pContext->EnableVolumeCompression = (ENABLEVOLUMECOMPRESSION) GetProcAddress(hLibrary, "EnableVolumeCompression");
+    if (!pContext->FormatEx)
+    {
+        ERR("EnableVolumeCompression export is missing\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    pContext->Chkdsk = (CHKDSK) GetProcAddress(hLibrary, "Chkdsk");
+    if (!pContext->Chkdsk)
+    {
+        ERR("Chkdsk export is missing\n");
+        FreeLibrary(hLibrary);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*************************************************************************
+ *              SHFormatDrive (SHELL32.@)
+ */
+
+DWORD 
+WINAPI
+SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
+{
+    FORMAT_DRIVE_CONTEXT Context;
+    int result;
+
+    TRACE("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options);
+
+    if (!InitializeFmifsLibrary(&Context))
+    {
+        ERR("failed to initialize fmifs\n");
+        return SHFMT_NOFORMAT;
+    }
+
+    Context.Drive = drive;
+    Context.Options = options;
+
+    result = DialogBoxParamW(shell32_hInstance, L"FORMAT_DLG", hwnd, FormatDriveDlg, (LPARAM)&Context);
+
+    FreeLibrary(Context.hLibrary);
+    return result;
+}
+
+