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