1 /* 2 * Shell Library Functions 3 * 4 * Copyright 2005 Johannes Anderwald 5 * Copyright 2017 Katayama Hirofumi MZ 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 #include "precomp.h" 23 24 WINE_DEFAULT_DEBUG_CHANNEL(shell); 25 26 typedef struct 27 { 28 WCHAR Drive; 29 UINT Options; 30 UINT Result; 31 } FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT; 32 33 EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj); 34 HPROPSHEETPAGE SH_CreatePropertySheetPage(LPCSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle); 35 36 static BOOL 37 GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNumberOfBytes) 38 { 39 DWORD ClusterSize; 40 41 if (!wcsicmp(szFs, L"FAT16") || 42 !wcsicmp(szFs, L"FAT")) //REACTOS HACK 43 { 44 if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024)) 45 ClusterSize = 2048; 46 else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024)) 47 ClusterSize = 512; 48 else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024)) 49 ClusterSize = 1024; 50 else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024)) 51 ClusterSize = 2048; 52 else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024)) 53 ClusterSize = 4096; 54 else if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024)) 55 ClusterSize = 8192; 56 else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024)) 57 ClusterSize = 16384; 58 else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL)) 59 ClusterSize = 32768; 60 else if (TotalNumberOfBytes->QuadPart <= (4096LL * 1024LL * 1024LL)) 61 ClusterSize = 8192; 62 else 63 return FALSE; 64 } 65 else if (!wcsicmp(szFs, L"FAT32")) 66 { 67 if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024)) 68 ClusterSize = 512; 69 else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024)) 70 ClusterSize = 1024; 71 else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024)) 72 ClusterSize = 2048; 73 else if (TotalNumberOfBytes->QuadPart <= (8192LL * 1024LL * 1024LL)) 74 ClusterSize = 2048; 75 else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL)) 76 ClusterSize = 8192; 77 else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL)) 78 ClusterSize = 16384; 79 else 80 return FALSE; 81 } 82 else if (!wcsicmp(szFs, L"NTFS")) 83 { 84 if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024)) 85 ClusterSize = 512; 86 else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024)) 87 ClusterSize = 1024; 88 else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL)) 89 ClusterSize = 2048; 90 else 91 ClusterSize = 2048; 92 } 93 else if (!wcsicmp(szFs, L"EXT2")) 94 { 95 // auto block size calculation 96 ClusterSize = 0; 97 } 98 else if (!wcsicmp(szFs, L"BtrFS")) 99 { 100 // auto block size calculation 101 ClusterSize = 0; 102 } 103 else 104 return FALSE; 105 106 *pClusterSize = ClusterSize; 107 return TRUE; 108 } 109 110 typedef struct _DRIVE_PROP_PAGE 111 { 112 LPCSTR resname; 113 DLGPROC dlgproc; 114 UINT DriveType; 115 } DRIVE_PROP_PAGE; 116 117 HRESULT 118 SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) 119 { 120 HPSXA hpsx = NULL; 121 HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; 122 PROPSHEETHEADERW psh; 123 CComObject<CDrvDefExt> *pDrvDefExt = NULL; 124 WCHAR wszName[256]; 125 126 ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); 127 psh.dwSize = sizeof(PROPSHEETHEADERW); 128 psh.dwFlags = 0; // FIXME: make it modeless 129 psh.hwndParent = NULL; 130 psh.nStartPage = 0; 131 psh.phpage = hpsp; 132 133 LPITEMIDLIST completePidl = ILCombine(pidlFolder, apidl[0]); 134 if (!completePidl) 135 return E_OUTOFMEMORY; 136 137 if (ILGetDisplayNameExW(NULL, completePidl, wszName, ILGDN_NORMAL)) 138 { 139 psh.pszCaption = wszName; 140 psh.dwFlags |= PSH_PROPTITLE; 141 } 142 143 ILFree(completePidl); 144 145 CComPtr<IDataObject> pDataObj; 146 HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); 147 148 if (SUCCEEDED(hr)) 149 { 150 hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt); 151 if (SUCCEEDED(hr)) 152 { 153 pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count 154 hr = pDrvDefExt->Initialize(pidlFolder, pDataObj, NULL); 155 if (SUCCEEDED(hr)) 156 { 157 hr = pDrvDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh); 158 if (FAILED(hr)) 159 ERR("AddPages failed\n"); 160 } else 161 ERR("Initialize failed\n"); 162 } 163 164 hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE, pDataObj); 165 if (hpsx) 166 SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh); 167 } 168 169 // NOTE: Currently property sheet is modal. If we make it modeless, then it returns HWND. 170 INT_PTR ret = PropertySheetW(&psh); 171 172 if (hpsx) 173 SHDestroyPropSheetExtArray(hpsx); 174 if (pDrvDefExt) 175 pDrvDefExt->Release(); 176 177 if (ret > 0) 178 return S_OK; 179 if (ret == 0) 180 return S_FALSE; 181 return E_FAIL; 182 } 183 184 static VOID 185 InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) 186 { 187 WCHAR wszBuf[100] = {0}; 188 WCHAR szDrive[] = L"C:\\"; 189 INT iSelIndex; 190 ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes; 191 DWORD ClusterSize; 192 LRESULT lIndex; 193 HWND hDlgCtrl; 194 195 hDlgCtrl = GetDlgItem(hwndDlg, 28677); 196 iSelIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0); 197 if (iSelIndex == CB_ERR) 198 return; 199 200 if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)wszBuf) == CB_ERR) 201 return; 202 203 szDrive[0] = pContext->Drive + L'A'; 204 205 if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL)) 206 return; 207 208 if (!wcsicmp(wszBuf, L"FAT16") || 209 !wcsicmp(wszBuf, L"FAT")) //REACTOS HACK 210 { 211 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes)) 212 { 213 TRACE("FAT16 is not supported on hdd larger than 4G current %lu\n", TotalNumberOfBytes.QuadPart); 214 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0); 215 return; 216 } 217 218 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf))) 219 { 220 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 221 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0); 222 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 223 if (lIndex != CB_ERR) 224 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 225 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0); 226 } 227 228 SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0); 229 EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE); 230 } 231 else if (!wcsicmp(wszBuf, L"FAT32")) 232 { 233 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes)) 234 { 235 TRACE("FAT32 is not supported on hdd larger than 32G current %lu\n", TotalNumberOfBytes.QuadPart); 236 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0); 237 return; 238 } 239 240 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf))) 241 { 242 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 243 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0); 244 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 245 if (lIndex != CB_ERR) 246 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 247 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0); 248 } 249 250 SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0); 251 EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE); 252 } 253 else if (!wcsicmp(wszBuf, L"NTFS")) 254 { 255 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes)) 256 { 257 TRACE("NTFS is not supported on hdd larger than 2TB current %lu\n", TotalNumberOfBytes.QuadPart); 258 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0); 259 return; 260 } 261 262 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 263 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf))) 264 { 265 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0); 266 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 267 if (lIndex != CB_ERR) 268 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 269 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0); 270 } 271 ClusterSize = 512; 272 for (lIndex = 0; lIndex < 4; lIndex++) 273 { 274 TotalNumberOfBytes.QuadPart = ClusterSize; 275 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf))) 276 { 277 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 278 if (lIndex != CB_ERR) 279 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 280 } 281 ClusterSize *= 2; 282 } 283 284 EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE); 285 } 286 else if (!wcsicmp(wszBuf, L"EXT2")) 287 { 288 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes)) 289 { 290 TRACE("EXT2 is not supported on hdd larger than 32T current %lu\n", TotalNumberOfBytes.QuadPart); 291 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0); 292 return; 293 } 294 295 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf))) 296 { 297 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 298 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0); 299 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 300 if (lIndex != CB_ERR) 301 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 302 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0); 303 } 304 305 EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE); 306 } 307 else if (!wcsicmp(wszBuf, L"BtrFS")) 308 { 309 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes)) 310 { 311 TRACE("BtrFS is not supported on hdd larger than 16E current %lu\n", TotalNumberOfBytes.QuadPart); 312 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0); 313 return; 314 } 315 316 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf))) 317 { 318 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 319 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0); 320 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf); 321 if (lIndex != CB_ERR) 322 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize); 323 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0); 324 } 325 326 EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE); 327 } 328 else 329 { 330 FIXME("unknown fs\n"); 331 SendDlgItemMessageW(hwndDlg, 28680, CB_RESETCONTENT, iSelIndex, 0); 332 return; 333 } 334 } 335 336 static VOID 337 InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) 338 { 339 WCHAR szText[120]; 340 WCHAR szDrive[] = L"C:\\"; 341 WCHAR szFs[30] = L""; 342 INT cchText; 343 ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes; 344 DWORD dwIndex, dwDefault; 345 UCHAR uMinor, uMajor; 346 BOOLEAN Latest; 347 HWND hwndFileSystems; 348 349 cchText = GetWindowTextW(hwndDlg, szText, _countof(szText) - 1); 350 if (cchText < 0) 351 cchText = 0; 352 szText[cchText++] = L' '; 353 szDrive[0] = pContext->Drive + L'A'; 354 if (GetVolumeInformationW(szDrive, &szText[cchText], _countof(szText) - cchText, NULL, NULL, NULL, szFs, _countof(szFs))) 355 { 356 if (szText[cchText] == UNICODE_NULL) 357 { 358 /* load default volume label */ 359 cchText += LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchText], _countof(szText) - cchText); 360 } 361 else 362 { 363 /* set volume label */ 364 SetDlgItemTextW(hwndDlg, 28679, &szText[cchText]); 365 cchText += wcslen(&szText[cchText]); 366 } 367 } 368 369 StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c:)", szDrive[0]); 370 371 /* set window text */ 372 SetWindowTextW(hwndDlg, szText); 373 374 if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL)) 375 { 376 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, _countof(szText))) 377 { 378 /* add drive capacity */ 379 SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText); 380 SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0); 381 } 382 } 383 384 if (pContext->Options & SHFMT_OPT_FULL) 385 { 386 /* check quick format button */ 387 SendDlgItemMessageW(hwndDlg, 28674, BM_SETCHECK, BST_CHECKED, 0); 388 } 389 390 /* enumerate all available filesystems */ 391 dwIndex = 0; 392 dwDefault = 0; 393 hwndFileSystems = GetDlgItem(hwndDlg, 28677); 394 395 while(QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest)) 396 { 397 if (!wcsicmp(szText, szFs)) 398 dwDefault = dwIndex; 399 400 SendMessageW(hwndFileSystems, CB_ADDSTRING, 0, (LPARAM)szText); 401 dwIndex++; 402 } 403 404 if (!dwIndex) 405 { 406 ERR("no filesystem providers\n"); 407 return; 408 } 409 410 /* select default filesys */ 411 SendMessageW(hwndFileSystems, CB_SETCURSEL, dwDefault, 0); 412 /* setup cluster combo */ 413 InsertDefaultClusterSizeForFs(hwndDlg, pContext); 414 } 415 416 static HWND FormatDrvDialog = NULL; 417 static BOOLEAN bSuccess = FALSE; 418 419 static BOOLEAN NTAPI 420 FormatExCB( 421 IN CALLBACKCOMMAND Command, 422 IN ULONG SubAction, 423 IN PVOID ActionInfo) 424 { 425 PDWORD Progress; 426 PBOOLEAN pSuccess; 427 switch(Command) 428 { 429 case PROGRESS: 430 Progress = (PDWORD)ActionInfo; 431 SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0); 432 break; 433 case DONE: 434 pSuccess = (PBOOLEAN)ActionInfo; 435 bSuccess = (*pSuccess); 436 ShellMessageBoxW(shell32_hInstance, FormatDrvDialog, MAKEINTRESOURCEW(IDS_FORMAT_COMPLETE), MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OK | MB_ICONINFORMATION); 437 SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, 0, 0); 438 break; 439 440 case VOLUMEINUSE: 441 case INSUFFICIENTRIGHTS: 442 case FSNOTSUPPORTED: 443 case CLUSTERSIZETOOSMALL: 444 bSuccess = FALSE; 445 FIXME("\n"); 446 break; 447 448 default: 449 break; 450 } 451 452 return TRUE; 453 } 454 455 VOID 456 FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) 457 { 458 WCHAR szDrive[4] = { L'C', ':', '\\', 0 }; 459 WCHAR szFileSys[40] = {0}; 460 WCHAR szLabel[40] = {0}; 461 INT iSelIndex; 462 UINT Length; 463 HWND hDlgCtrl; 464 BOOL QuickFormat; 465 DWORD ClusterSize; 466 DWORD DriveType; 467 FMIFS_MEDIA_FLAG MediaFlag = FMIFS_HARDDISK; 468 469 /* set volume path */ 470 szDrive[0] = pContext->Drive + L'A'; 471 472 /* get filesystem */ 473 hDlgCtrl = GetDlgItem(hwndDlg, 28677); 474 iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0); 475 if (iSelIndex == CB_ERR) 476 { 477 FIXME("\n"); 478 return; 479 } 480 Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0); 481 if ((int)Length == CB_ERR || Length + 1 > _countof(szFileSys)) 482 { 483 FIXME("\n"); 484 return; 485 } 486 487 /* retrieve the file system */ 488 SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys); 489 szFileSys[_countof(szFileSys)-1] = L'\0'; 490 491 /* retrieve the volume label */ 492 hDlgCtrl = GetWindow(hwndDlg, 28679); 493 Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0); 494 if (Length + 1 > _countof(szLabel)) 495 { 496 FIXME("\n"); 497 return; 498 } 499 SendMessageW(hDlgCtrl, WM_GETTEXT, _countof(szLabel), (LPARAM)szLabel); 500 szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0'; 501 502 /* check for quickformat */ 503 if (SendDlgItemMessageW(hwndDlg, 28674, BM_GETCHECK, 0, 0) == BST_CHECKED) 504 QuickFormat = TRUE; 505 else 506 QuickFormat = FALSE; 507 508 /* get the cluster size */ 509 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 510 iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0); 511 if (iSelIndex == CB_ERR) 512 { 513 FIXME("\n"); 514 return; 515 } 516 ClusterSize = SendMessageW(hDlgCtrl, CB_GETITEMDATA, iSelIndex, 0); 517 if ((int)ClusterSize == CB_ERR) 518 { 519 FIXME("\n"); 520 return; 521 } 522 523 hDlgCtrl = GetDlgItem(hwndDlg, 28680); 524 SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); 525 bSuccess = FALSE; 526 527 /* FIXME 528 * will cause display problems 529 * when performing more than one format 530 */ 531 FormatDrvDialog = hwndDlg; 532 533 /* See if the drive is removable or not */ 534 DriveType = GetDriveTypeW(szDrive); 535 switch (DriveType) 536 { 537 case DRIVE_UNKNOWN: 538 case DRIVE_REMOTE: 539 case DRIVE_CDROM: 540 case DRIVE_NO_ROOT_DIR: 541 { 542 FIXME("\n"); 543 return; 544 } 545 546 case DRIVE_REMOVABLE: 547 MediaFlag = FMIFS_FLOPPY; 548 break; 549 550 case DRIVE_FIXED: 551 case DRIVE_RAMDISK: 552 MediaFlag = FMIFS_HARDDISK; 553 break; 554 } 555 556 /* Format the drive */ 557 FormatEx(szDrive, 558 MediaFlag, 559 szFileSys, 560 szLabel, 561 QuickFormat, 562 ClusterSize, 563 FormatExCB); 564 565 FormatDrvDialog = NULL; 566 if (!bSuccess) 567 { 568 pContext->Result = SHFMT_ERROR; 569 } 570 else if (QuickFormat) 571 { 572 pContext->Result = SHFMT_OPT_FULL; 573 } 574 else 575 { 576 pContext->Result = FALSE; 577 } 578 } 579 580 static INT_PTR CALLBACK 581 FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 582 { 583 PFORMAT_DRIVE_CONTEXT pContext; 584 585 switch(uMsg) 586 { 587 case WM_INITDIALOG: 588 InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam); 589 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); 590 return TRUE; 591 case WM_COMMAND: 592 switch(LOWORD(wParam)) 593 { 594 case IDOK: 595 if (ShellMessageBoxW(shell32_hInstance, hwndDlg, MAKEINTRESOURCEW(IDS_FORMAT_WARNING), MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OKCANCEL | MB_ICONWARNING) == IDOK) 596 { 597 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); 598 FormatDrive(hwndDlg, pContext); 599 } 600 break; 601 case IDCANCEL: 602 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); 603 EndDialog(hwndDlg, pContext->Result); 604 break; 605 case 28677: // filesystem combo 606 if (HIWORD(wParam) == CBN_SELENDOK) 607 { 608 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); 609 InsertDefaultClusterSizeForFs(hwndDlg, pContext); 610 } 611 break; 612 } 613 } 614 return FALSE; 615 } 616 617 /************************************************************************* 618 * SHFormatDrive (SHELL32.@) 619 */ 620 621 DWORD 622 WINAPI 623 SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options) 624 { 625 FORMAT_DRIVE_CONTEXT Context; 626 int result; 627 628 TRACE("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options); 629 630 Context.Drive = drive; 631 Context.Options = options; 632 633 result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_FORMAT_DRIVE), hwnd, FormatDriveDlg, (LPARAM)&Context); 634 635 return result; 636 } 637 638 639