-/*\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;
+}
+
+