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 #include <process.h>
24
25 WINE_DEFAULT_DEBUG_CHANNEL(shell);
26
27 typedef struct
28 {
29 WCHAR Drive;
30 UINT Options;
31 UINT Result;
32 BOOL bFormattingNow;
33 } FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT;
34
35 /*
36 * TODO: In Windows the Shell doesn't know by itself if a drive is
37 * a system one or not but rather a packet message is being sent by
38 * FMIFS library code and further translated into specific packet
39 * status codes in the Shell, the packet being _FMIFS_PACKET_TYPE.
40 *
41 * With that being said, most of this code as well as FMIFS library code
42 * have to be refactored in order to comply with the way Windows works.
43 *
44 * See the enum definition for more details:
45 * https://github.com/microsoft/winfile/blob/master/src/fmifs.h#L23
46 */
47 static BOOL
IsSystemDrive(PFORMAT_DRIVE_CONTEXT pContext)48 IsSystemDrive(PFORMAT_DRIVE_CONTEXT pContext)
49 {
50 WCHAR wszDriveLetter[6], wszSystemDrv[6];
51
52 wszDriveLetter[0] = pContext->Drive + L'A';
53 StringCchCatW(wszDriveLetter, _countof(wszDriveLetter), L":");
54
55 if (!GetEnvironmentVariableW(L"SystemDrive", wszSystemDrv, _countof(wszSystemDrv)))
56 return FALSE;
57
58 if (!_wcsicmp(wszDriveLetter, wszSystemDrv))
59 return TRUE;
60
61 return FALSE;
62 }
63
64 static BOOL
GetDefaultClusterSize(LPWSTR szFs,PDWORD pClusterSize,PULARGE_INTEGER TotalNumberOfBytes)65 GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNumberOfBytes)
66 {
67 DWORD ClusterSize;
68
69 if (!_wcsicmp(szFs, L"FAT16") ||
70 !_wcsicmp(szFs, L"FAT")) // REACTOS HACK
71 {
72 if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024))
73 ClusterSize = 2048;
74 else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024))
75 ClusterSize = 512;
76 else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
77 ClusterSize = 1024;
78 else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
79 ClusterSize = 2048;
80 else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
81 ClusterSize = 4096;
82 else if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))
83 ClusterSize = 8192;
84 else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
85 ClusterSize = 16384;
86 else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
87 ClusterSize = 32768;
88 else if (TotalNumberOfBytes->QuadPart <= (4096LL * 1024LL * 1024LL))
89 ClusterSize = 8192;
90 else
91 return FALSE;
92 }
93 else if (!_wcsicmp(szFs, L"FAT32"))
94 {
95 if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
96 ClusterSize = 512;
97 else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
98 ClusterSize = 1024;
99 else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
100 ClusterSize = 2048;
101 else if (TotalNumberOfBytes->QuadPart <= (8192LL * 1024LL * 1024LL))
102 ClusterSize = 2048;
103 else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL))
104 ClusterSize = 8192;
105 else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL))
106 ClusterSize = 16384;
107 else
108 return FALSE;
109 }
110 else if (!_wcsicmp(szFs, L"FATX"))
111 {
112 if (TotalNumberOfBytes->QuadPart <= (16 * 1024 * 1024))
113 ClusterSize = 2048;
114 else if (TotalNumberOfBytes->QuadPart <= (32 * 1024 * 1024))
115 ClusterSize = 512;
116 else if (TotalNumberOfBytes->QuadPart <= (64 * 1024 * 1024))
117 ClusterSize = 1024;
118 else if (TotalNumberOfBytes->QuadPart <= (128 * 1024 * 1024))
119 ClusterSize = 2048;
120 else if (TotalNumberOfBytes->QuadPart <= (256 * 1024 * 1024))
121 ClusterSize = 4096;
122 else if (TotalNumberOfBytes->QuadPart <= (8192LL * 1024LL * 1024LL))
123 ClusterSize = 2048;
124 else if (TotalNumberOfBytes->QuadPart <= (16384LL * 1024LL * 1024LL))
125 ClusterSize = 8192;
126 else if (TotalNumberOfBytes->QuadPart <= (32768LL * 1024LL * 1024LL))
127 ClusterSize = 16384;
128 else
129 return FALSE;
130 }
131 else if (!_wcsicmp(szFs, L"NTFS"))
132 {
133 if (TotalNumberOfBytes->QuadPart <= (512 * 1024 * 1024))
134 ClusterSize = 512;
135 else if (TotalNumberOfBytes->QuadPart <= (1024 * 1024 * 1024))
136 ClusterSize = 1024;
137 else if (TotalNumberOfBytes->QuadPart <= (2048LL * 1024LL * 1024LL))
138 ClusterSize = 2048;
139 else
140 ClusterSize = 2048;
141 }
142 else if (!_wcsicmp(szFs, L"EXT2"))
143 {
144 // auto block size calculation
145 ClusterSize = 0;
146 }
147 else if (!_wcsicmp(szFs, L"BtrFS"))
148 {
149 // auto block size calculation
150 ClusterSize = 0;
151 }
152 else
153 return FALSE;
154
155 *pClusterSize = ClusterSize;
156 return TRUE;
157 }
158
159 static VOID
InsertDefaultClusterSizeForFs(HWND hwndDlg,PFORMAT_DRIVE_CONTEXT pContext)160 InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
161 {
162 WCHAR wszBuf[100] = {0};
163 WCHAR wszDefaultSize[100] = {0};
164 PCWSTR pwszFsSizeLimit;
165 WCHAR szDrive[] = L"C:\\";
166 INT iSelIndex;
167 ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
168 DWORD ClusterSize;
169 LRESULT lIndex;
170 HWND hDlgCtrl;
171
172 hDlgCtrl = GetDlgItem(hwndDlg, 28677);
173 iSelIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
174 if (iSelIndex == CB_ERR)
175 return;
176
177 if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)wszBuf) == CB_ERR)
178 return;
179
180 szDrive[0] = pContext->Drive + L'A';
181
182 if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
183 return;
184
185 if (!_wcsicmp(wszBuf, L"FAT16") ||
186 !_wcsicmp(wszBuf, L"FAT")) // REACTOS HACK
187 {
188 pwszFsSizeLimit = L"4GB";
189 }
190 else if (!_wcsicmp(wszBuf, L"FAT32"))
191 {
192 pwszFsSizeLimit = L"32GB";
193 }
194 else if (!_wcsicmp(wszBuf, L"FATX"))
195 {
196 pwszFsSizeLimit = L"1GB/32GB";
197 }
198 else if (!_wcsicmp(wszBuf, L"NTFS"))
199 {
200 pwszFsSizeLimit = L"256TB";
201 }
202 else if (!_wcsicmp(wszBuf, L"EXT2"))
203 {
204 pwszFsSizeLimit = L"32TB";
205 }
206 else
207 {
208 pwszFsSizeLimit = L"16EB";
209 }
210
211 if (!_wcsicmp(wszBuf, L"FAT16") ||
212 !_wcsicmp(wszBuf, L"FAT") || // REACTOS HACK
213 !_wcsicmp(wszBuf, L"FAT32") ||
214 !_wcsicmp(wszBuf, L"FATX") ||
215 !_wcsicmp(wszBuf, L"NTFS") ||
216 !_wcsicmp(wszBuf, L"EXT2") ||
217 !_wcsicmp(wszBuf, L"BtrFS"))
218 {
219 if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
220 {
221 TRACE("%S is not supported on drive larger than %S, current size: %lu\n", wszBuf, pwszFsSizeLimit, TotalNumberOfBytes.QuadPart);
222 SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
223 return;
224 }
225
226 if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszDefaultSize, _countof(wszDefaultSize)))
227 {
228 hDlgCtrl = GetDlgItem(hwndDlg, 28680); // Get the window handle of "allocation unit size" combobox
229 SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
230 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszDefaultSize);
231 if (lIndex != CB_ERR)
232 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
233 SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
234 }
235
236 if (!_wcsicmp(wszBuf, L"NTFS"))
237 {
238 ClusterSize = 512;
239 for (lIndex = 0; lIndex < 4; lIndex++)
240 {
241 TotalNumberOfBytes.QuadPart = ClusterSize;
242 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszDefaultSize, _countof(wszDefaultSize)))
243 {
244 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszDefaultSize);
245 if (lIndex != CB_ERR)
246 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
247 }
248 ClusterSize *= 2;
249 }
250 }
251
252 SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0);
253 if (!_wcsicmp(wszBuf, L"EXT2") ||
254 !_wcsicmp(wszBuf, L"BtrFS") ||
255 !_wcsicmp(wszBuf, L"NTFS"))
256 {
257 /* Enable the "Enable Compression" button */
258 EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
259 }
260 else
261 {
262 /* Disable the "Enable Compression" button */
263 EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE);
264 }
265 }
266 else
267 {
268 FIXME("Unknown filesystem: %ls\n", wszBuf);
269 SendDlgItemMessageW(hwndDlg, 28680, CB_RESETCONTENT, iSelIndex, 0);
270 return;
271 }
272 }
273
274 static VOID
InitializeFormatDriveDlg(HWND hwndDlg,PFORMAT_DRIVE_CONTEXT pContext)275 InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
276 {
277 WCHAR szText[120];
278 WCHAR szDrive[] = L"C:\\";
279 WCHAR szFs[30] = L"";
280 INT cchText;
281 ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes;
282 DWORD dwIndex, dwDefault;
283 UCHAR uMinor, uMajor;
284 BOOLEAN Latest;
285 HWND hwndFileSystems;
286
287 cchText = GetWindowTextW(hwndDlg, szText, _countof(szText) - 1);
288 if (cchText < 0)
289 cchText = 0;
290 szText[cchText++] = L' ';
291 szDrive[0] = pContext->Drive + L'A';
292 if (GetVolumeInformationW(szDrive, &szText[cchText], _countof(szText) - cchText, NULL, NULL, NULL, szFs, _countof(szFs)))
293 {
294 if (szText[cchText] == UNICODE_NULL)
295 {
296 /* load default volume label */
297 cchText += LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchText], _countof(szText) - cchText);
298 }
299 else
300 {
301 /* set volume label */
302 SetDlgItemTextW(hwndDlg, 28679, &szText[cchText]);
303 cchText += wcslen(&szText[cchText]);
304 }
305 }
306
307 StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c:)", szDrive[0]);
308
309 /* set window text */
310 SetWindowTextW(hwndDlg, szText);
311
312 if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
313 {
314 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, _countof(szText)))
315 {
316 /* add drive capacity */
317 SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText);
318 SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0);
319 }
320 }
321
322 if (pContext->Options & SHFMT_OPT_FULL)
323 {
324 /* check quick format button */
325 SendDlgItemMessageW(hwndDlg, 28674, BM_SETCHECK, BST_CHECKED, 0);
326 }
327
328 /* enumerate all available filesystems */
329 dwIndex = 0;
330 dwDefault = 0;
331 hwndFileSystems = GetDlgItem(hwndDlg, 28677);
332
333 while(QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest))
334 {
335 if (!_wcsicmp(szText, szFs))
336 dwDefault = dwIndex;
337
338 SendMessageW(hwndFileSystems, CB_ADDSTRING, 0, (LPARAM)szText);
339 dwIndex++;
340 }
341
342 if (!dwIndex)
343 {
344 ERR("no filesystem providers\n");
345 return;
346 }
347
348 /* select default filesys */
349 SendMessageW(hwndFileSystems, CB_SETCURSEL, dwDefault, 0);
350 /* setup cluster combo */
351 InsertDefaultClusterSizeForFs(hwndDlg, pContext);
352 }
353
354 static HWND FormatDrvDialog = NULL;
355 static BOOLEAN bSuccess = FALSE;
356
357 static BOOLEAN NTAPI
FormatExCB(IN CALLBACKCOMMAND Command,IN ULONG SubAction,IN PVOID ActionInfo)358 FormatExCB(
359 IN CALLBACKCOMMAND Command,
360 IN ULONG SubAction,
361 IN PVOID ActionInfo)
362 {
363 PDWORD Progress;
364 PBOOLEAN pSuccess;
365 switch(Command)
366 {
367 case PROGRESS:
368 Progress = (PDWORD)ActionInfo;
369 SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0);
370 break;
371 case DONE:
372 pSuccess = (PBOOLEAN)ActionInfo;
373 bSuccess = (*pSuccess);
374 ShellMessageBoxW(shell32_hInstance, FormatDrvDialog, MAKEINTRESOURCEW(IDS_FORMAT_COMPLETE), MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OK | MB_ICONINFORMATION);
375 SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, 0, 0);
376 break;
377
378 case VOLUMEINUSE:
379 case INSUFFICIENTRIGHTS:
380 case FSNOTSUPPORTED:
381 case CLUSTERSIZETOOSMALL:
382 bSuccess = FALSE;
383 FIXME("Unsupported command in FormatExCB\n");
384 break;
385
386 default:
387 break;
388 }
389
390 return TRUE;
391 }
392
393 VOID
FormatDrive(HWND hwndDlg,PFORMAT_DRIVE_CONTEXT pContext)394 FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
395 {
396 WCHAR szDrive[4] = { L'C', ':', '\\', 0 };
397 WCHAR szFileSys[40] = {0};
398 WCHAR szLabel[40] = {0};
399 INT iSelIndex;
400 UINT Length;
401 HWND hDlgCtrl;
402 BOOL QuickFormat;
403 DWORD ClusterSize;
404 DWORD DriveType;
405 FMIFS_MEDIA_FLAG MediaFlag = FMIFS_HARDDISK;
406
407 /* set volume path */
408 szDrive[0] = pContext->Drive + L'A';
409
410 /* get filesystem */
411 hDlgCtrl = GetDlgItem(hwndDlg, 28677);
412 iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
413 if (iSelIndex == CB_ERR)
414 {
415 ERR("Unable to get file system selection\n");
416 return;
417 }
418 Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0);
419 if ((int)Length == CB_ERR || Length + 1 > _countof(szFileSys))
420 {
421 ERR("Unable to get file system selection\n");
422 return;
423 }
424
425 /* retrieve the file system */
426 SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys);
427 szFileSys[_countof(szFileSys)-1] = L'\0';
428
429 /* retrieve the volume label */
430 hDlgCtrl = GetWindow(hwndDlg, 28679);
431 Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0);
432 if (Length + 1 > _countof(szLabel))
433 {
434 ERR("Unable to get volume label\n");
435 return;
436 }
437 SendMessageW(hDlgCtrl, WM_GETTEXT, _countof(szLabel), (LPARAM)szLabel);
438 szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0';
439
440 /* check for quickformat */
441 if (SendDlgItemMessageW(hwndDlg, 28674, BM_GETCHECK, 0, 0) == BST_CHECKED)
442 QuickFormat = TRUE;
443 else
444 QuickFormat = FALSE;
445
446 /* get the cluster size */
447 hDlgCtrl = GetDlgItem(hwndDlg, 28680);
448 iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0);
449 if (iSelIndex == CB_ERR)
450 {
451 FIXME("\n");
452 return;
453 }
454 ClusterSize = SendMessageW(hDlgCtrl, CB_GETITEMDATA, iSelIndex, 0);
455 if ((int)ClusterSize == CB_ERR)
456 {
457 FIXME("\n");
458 return;
459 }
460
461 hDlgCtrl = GetDlgItem(hwndDlg, 28680);
462 SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
463 bSuccess = FALSE;
464
465 /* FIXME
466 * will cause display problems
467 * when performing more than one format
468 */
469 FormatDrvDialog = hwndDlg;
470
471 /* See if the drive is removable or not */
472 DriveType = GetDriveTypeW(szDrive);
473 switch (DriveType)
474 {
475 case DRIVE_UNKNOWN:
476 case DRIVE_REMOTE:
477 case DRIVE_CDROM:
478 case DRIVE_NO_ROOT_DIR:
479 {
480 FIXME("\n");
481 return;
482 }
483
484 case DRIVE_REMOVABLE:
485 MediaFlag = FMIFS_FLOPPY;
486 break;
487
488 case DRIVE_FIXED:
489 case DRIVE_RAMDISK:
490 MediaFlag = FMIFS_HARDDISK;
491 break;
492 }
493
494 /* Format the drive */
495 FormatEx(szDrive,
496 MediaFlag,
497 szFileSys,
498 szLabel,
499 QuickFormat,
500 ClusterSize,
501 FormatExCB);
502
503 FormatDrvDialog = NULL;
504 if (!bSuccess)
505 {
506 pContext->Result = SHFMT_ERROR;
507 }
508 else if (QuickFormat)
509 {
510 pContext->Result = SHFMT_OPT_FULL;
511 }
512 else
513 {
514 pContext->Result = FALSE;
515 }
516 }
517
518 struct FORMAT_DRIVE_PARAMS
519 {
520 HWND hwndDlg;
521 PFORMAT_DRIVE_CONTEXT pContext;
522 };
523
DoFormatDrive(void * args)524 static unsigned __stdcall DoFormatDrive(void *args)
525 {
526 FORMAT_DRIVE_PARAMS *pParams = reinterpret_cast<FORMAT_DRIVE_PARAMS *>(args);
527 HWND hwndDlg = pParams->hwndDlg;
528 PFORMAT_DRIVE_CONTEXT pContext = pParams->pContext;
529
530 /* Disable controls during format */
531 HMENU hSysMenu = GetSystemMenu(hwndDlg, FALSE);
532 EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
533 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
534 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
535 EnableWindow(GetDlgItem(hwndDlg, 28673), FALSE);
536 EnableWindow(GetDlgItem(hwndDlg, 28677), FALSE);
537 EnableWindow(GetDlgItem(hwndDlg, 28680), FALSE);
538 EnableWindow(GetDlgItem(hwndDlg, 28679), FALSE);
539 EnableWindow(GetDlgItem(hwndDlg, 28674), FALSE);
540
541 FormatDrive(hwndDlg, pContext);
542
543 /* Re-enable controls after format */
544 EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
545 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), TRUE);
546 EnableWindow(GetDlgItem(hwndDlg, 28673), TRUE);
547 EnableWindow(GetDlgItem(hwndDlg, 28677), TRUE);
548 EnableWindow(GetDlgItem(hwndDlg, 28680), TRUE);
549 EnableWindow(GetDlgItem(hwndDlg, 28679), TRUE);
550 EnableWindow(GetDlgItem(hwndDlg, 28674), TRUE);
551 EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
552 pContext->bFormattingNow = FALSE;
553
554 delete pParams;
555 return 0;
556 }
557
558 static INT_PTR CALLBACK
FormatDriveDlg(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)559 FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
560 {
561 PFORMAT_DRIVE_CONTEXT pContext;
562
563 switch(uMsg)
564 {
565 case WM_INITDIALOG:
566 InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam);
567 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
568 return TRUE;
569 case WM_COMMAND:
570 switch(LOWORD(wParam))
571 {
572 case IDOK:
573 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
574 if (pContext->bFormattingNow)
575 break;
576
577 if (ShellMessageBoxW(shell32_hInstance, hwndDlg,
578 MAKEINTRESOURCEW(IDS_FORMAT_WARNING),
579 MAKEINTRESOURCEW(IDS_FORMAT_TITLE),
580 MB_OKCANCEL | MB_ICONWARNING) == IDOK)
581 {
582 pContext->bFormattingNow = TRUE;
583
584 FORMAT_DRIVE_PARAMS *pParams = new FORMAT_DRIVE_PARAMS;
585 pParams->hwndDlg = hwndDlg;
586 pParams->pContext = pContext;
587
588 unsigned tid;
589 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, DoFormatDrive, pParams, 0, &tid);
590 CloseHandle(hThread);
591 }
592 break;
593 case IDCANCEL:
594 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
595 if (pContext->bFormattingNow)
596 break;
597
598 EndDialog(hwndDlg, pContext->Result);
599 break;
600 case 28677: // filesystem combo
601 if (HIWORD(wParam) == CBN_SELENDOK)
602 {
603 pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
604 if (pContext->bFormattingNow)
605 break;
606
607 InsertDefaultClusterSizeForFs(hwndDlg, pContext);
608 }
609 break;
610 }
611 }
612 return FALSE;
613 }
614
615 /*************************************************************************
616 * SHFormatDrive (SHELL32.@)
617 */
618
619 DWORD
620 WINAPI
SHFormatDrive(HWND hwnd,UINT drive,UINT fmtID,UINT options)621 SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
622 {
623 FORMAT_DRIVE_CONTEXT Context;
624 int result;
625
626 TRACE("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options);
627
628 Context.Drive = drive;
629 Context.Options = options;
630 Context.Result = FALSE;
631 Context.bFormattingNow = FALSE;
632
633 if (!IsSystemDrive(&Context))
634 {
635 result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_FORMAT_DRIVE), hwnd, FormatDriveDlg, (LPARAM)&Context);
636 }
637 else
638 {
639 result = SHFMT_ERROR;
640 ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_NO_FORMAT), MAKEINTRESOURCEW(IDS_NO_FORMAT_TITLE), MB_OK | MB_ICONWARNING);
641 TRACE("SHFormatDrive(): The provided drive for format is a system volume! Aborting...\n");
642 }
643
644 return result;
645 }
646