[SHELL32] Add a warning dialog before starting a dialog as well as a format complete...
[reactos.git] / dll / win32 / shell32 / dialogs / drive.cpp
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