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