cff6a3e21b82b5305301c654a63631a6dbe0805f
[reactos.git] / dll / win32 / shell32 / dialogs / drvdefext.cpp
1 /*
2 * Provides default drive shell extension
3 *
4 * Copyright 2005 Johannes Anderwald
5 * Copyright 2012 Rafal Harabien
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 St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "precomp.h"
23
24 #define _USE_MATH_DEFINES
25 #include <math.h>
26
27 WINE_DEFAULT_DEBUG_CHANNEL(shell);
28
29 static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
30
31 typedef enum
32 {
33 HWPD_STANDARDLIST = 0,
34 HWPD_LARGELIST,
35 HWPD_MAX = HWPD_LARGELIST
36 } HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;
37
38 EXTERN_C HWND WINAPI
39 DeviceCreateHardwarePageEx(HWND hWndParent,
40 LPGUID lpGuids,
41 UINT uNumberOfGuids,
42 HWPAGE_DISPLAYMODE DisplayMode);
43 UINT SH_FormatByteSize(LONGLONG cbSize, LPWSTR pwszResult, UINT cchResultMax);
44
45 static VOID
46 GetDriveNameWithLetter(LPWSTR pwszText, UINT cchTextMax, LPCWSTR pwszDrive)
47 {
48 DWORD dwMaxComp, dwFileSys;
49 SIZE_T cchText = 0;
50
51 if (GetVolumeInformationW(pwszDrive, pwszText, cchTextMax, NULL, &dwMaxComp, &dwFileSys, NULL, 0))
52 {
53 cchText = wcslen(pwszText);
54 if (cchText == 0)
55 {
56 /* load default volume label */
57 cchText = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, pwszText, cchTextMax);
58 }
59 }
60
61 StringCchPrintfW(pwszText + cchText, cchTextMax - cchText, L" (%c:)", pwszDrive[0]);
62 }
63
64 static VOID
65 InitializeChkDskDialog(HWND hwndDlg, LPCWSTR pwszDrive)
66 {
67 WCHAR wszText[100];
68 UINT Length;
69 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pwszDrive);
70
71 Length = GetWindowTextW(hwndDlg, wszText, sizeof(wszText) / sizeof(WCHAR));
72 wszText[Length] = L' ';
73 GetDriveNameWithLetter(&wszText[Length + 1], (sizeof(wszText) / sizeof(WCHAR)) - Length - 1, pwszDrive);
74 SetWindowText(hwndDlg, wszText);
75 }
76
77 static HWND hChkdskDrvDialog = NULL;
78 static BOOLEAN bChkdskSuccess = FALSE;
79
80 static BOOLEAN NTAPI
81 ChkdskCallback(
82 IN CALLBACKCOMMAND Command,
83 IN ULONG SubAction,
84 IN PVOID ActionInfo)
85 {
86 PDWORD Progress;
87 PBOOLEAN pSuccess;
88 switch(Command)
89 {
90 case PROGRESS:
91 Progress = (PDWORD)ActionInfo;
92 SendDlgItemMessageW(hChkdskDrvDialog, 14002, PBM_SETPOS, (WPARAM)*Progress, 0);
93 break;
94 case DONE:
95 pSuccess = (PBOOLEAN)ActionInfo;
96 bChkdskSuccess = (*pSuccess);
97 break;
98
99 case VOLUMEINUSE:
100 case INSUFFICIENTRIGHTS:
101 case FSNOTSUPPORTED:
102 case CLUSTERSIZETOOSMALL:
103 bChkdskSuccess = FALSE;
104 FIXME("\n");
105 break;
106
107 default:
108 break;
109 }
110
111 return TRUE;
112 }
113
114 static VOID
115 ChkDskNow(HWND hwndDlg, LPCWSTR pwszDrive)
116 {
117 //DWORD ClusterSize = 0;
118 WCHAR wszFs[30];
119 ULARGE_INTEGER TotalNumberOfFreeBytes, FreeBytesAvailableUser;
120 BOOLEAN bCorrectErrors = FALSE, bScanDrive = FALSE;
121
122 if(!GetVolumeInformationW(pwszDrive, NULL, 0, NULL, NULL, NULL, wszFs, _countof(wszFs)))
123 {
124 FIXME("failed to get drive fs type\n");
125 return;
126 }
127
128 if (!GetDiskFreeSpaceExW(pwszDrive, &FreeBytesAvailableUser, &TotalNumberOfFreeBytes, NULL))
129 {
130 FIXME("failed to get drive space type\n");
131 return;
132 }
133
134 /*if (!GetDefaultClusterSize(wszFs, &ClusterSize, &TotalNumberOfFreeBytes))
135 {
136 FIXME("invalid cluster size\n");
137 return;
138 }*/
139
140 if (SendDlgItemMessageW(hwndDlg, 14000, BM_GETCHECK, 0, 0) == BST_CHECKED)
141 bCorrectErrors = TRUE;
142
143 if (SendDlgItemMessageW(hwndDlg, 14001, BM_GETCHECK, 0, 0) == BST_CHECKED)
144 bScanDrive = TRUE;
145
146 hChkdskDrvDialog = hwndDlg;
147 bChkdskSuccess = FALSE;
148 SendDlgItemMessageW(hwndDlg, 14002, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
149 Chkdsk((LPWSTR)pwszDrive, (LPWSTR)wszFs, bCorrectErrors, TRUE, FALSE, bScanDrive, NULL, NULL, ChkdskCallback); // FIXME: casts
150
151 hChkdskDrvDialog = NULL;
152 bChkdskSuccess = FALSE;
153 }
154
155 static INT_PTR CALLBACK
156 ChkDskDlg(
157 HWND hwndDlg,
158 UINT uMsg,
159 WPARAM wParam,
160 LPARAM lParam)
161 {
162 switch(uMsg)
163 {
164 case WM_INITDIALOG:
165 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
166 InitializeChkDskDialog(hwndDlg, (LPCWSTR)lParam);
167 return TRUE;
168 case WM_COMMAND:
169 switch(LOWORD(wParam))
170 {
171 case IDCANCEL:
172 EndDialog(hwndDlg, 0);
173 break;
174 case IDOK:
175 {
176 LPCWSTR pwszDrive = (LPCWSTR)GetWindowLongPtr(hwndDlg, DWLP_USER);
177 ChkDskNow(hwndDlg, pwszDrive);
178 break;
179 }
180 }
181 break;
182 }
183
184 return FALSE;
185 }
186
187 VOID
188 CDrvDefExt::PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT pDrawItem)
189 {
190 HBRUSH hBrush;
191
192 if (pDrawItem->CtlID == 14013)
193 {
194 hBrush = CreateSolidBrush(RGB(0, 0, 255));
195 if (hBrush)
196 {
197 FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush);
198 DeleteObject((HGDIOBJ)hBrush);
199 }
200 }
201 else if (pDrawItem->CtlID == 14014)
202 {
203 hBrush = CreateSolidBrush(RGB(255, 0, 255));
204 if (hBrush)
205 {
206 FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush);
207 DeleteObject((HGDIOBJ)hBrush);
208 }
209 }
210 else if (pDrawItem->CtlID == 14015)
211 {
212 HBRUSH hBlueBrush = CreateSolidBrush(RGB(0, 0, 255));
213 HBRUSH hMagBrush = CreateSolidBrush(RGB(255, 0, 255));
214 HBRUSH hbrOld;
215 HPEN hDarkBluePen = CreatePen(PS_SOLID, 1, RGB(0, 0, 128));
216 HPEN hDarkMagPen = CreatePen(PS_SOLID, 1, RGB(128, 0, 128));
217 HPEN hOldPen = (HPEN)SelectObject(pDrawItem->hDC, hDarkMagPen);
218 INT xCenter = (pDrawItem->rcItem.left + pDrawItem->rcItem.right) / 2;
219 INT yCenter = (pDrawItem->rcItem.top + pDrawItem->rcItem.bottom - 10) / 2;
220 INT cx = pDrawItem->rcItem.right - pDrawItem->rcItem.left;
221 INT cy = pDrawItem->rcItem.bottom - pDrawItem->rcItem.top - 10;
222 INT xRadial = xCenter + (INT)(cos(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cx / 2);
223 INT yRadial = yCenter - (INT)(sin(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cy / 2);
224
225 TRACE("FreeSpace %u a %f cx %d\n", m_FreeSpacePerc, M_PI+m_FreeSpacePerc / 100.0f * M_PI * 2.0f, cx);
226
227 for (INT x = pDrawItem->rcItem.left; x < pDrawItem->rcItem.right; ++x)
228 {
229 double cos_val = (x - xCenter) * 2.0f / cx;
230 INT y = yCenter + (INT)(sin(acos(cos_val)) * cy / 2) - 1;
231
232 if (m_FreeSpacePerc < 50 && x == xRadial)
233 SelectObject(pDrawItem->hDC, hDarkBluePen);
234
235 MoveToEx(pDrawItem->hDC, x, y, NULL);
236 LineTo(pDrawItem->hDC, x, y + 10);
237 }
238
239 SelectObject(pDrawItem->hDC, hOldPen);
240
241 if (m_FreeSpacePerc > 50)
242 {
243 hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hMagBrush);
244
245 Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top,
246 pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
247
248 SelectObject(pDrawItem->hDC, hBlueBrush);
249
250 if (m_FreeSpacePerc < 100)
251 {
252 Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right,
253 pDrawItem->rcItem.bottom - 10, xRadial, yRadial, pDrawItem->rcItem.left, yCenter);
254 }
255 }
256 else
257 {
258 hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hBlueBrush);
259
260 Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top,
261 pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
262
263 SelectObject(pDrawItem->hDC, hMagBrush);
264
265 if (m_FreeSpacePerc > 0)
266 {
267 Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right,
268 pDrawItem->rcItem.bottom - 10, pDrawItem->rcItem.left, yCenter, xRadial, yRadial);
269 }
270 }
271
272 SelectObject(pDrawItem->hDC, hbrOld);
273
274 DeleteObject(hBlueBrush);
275 DeleteObject(hMagBrush);
276 DeleteObject(hDarkBluePen);
277 DeleteObject(hDarkMagPen);
278 }
279 }
280
281 VOID
282 CDrvDefExt::InitGeneralPage(HWND hwndDlg)
283 {
284 WCHAR wszVolumeName[MAX_PATH+1] = {0};
285 WCHAR wszFileSystem[MAX_PATH+1] = {0};
286 WCHAR wszBuf[128];
287 BOOL bRet;
288
289 bRet = GetVolumeInformationW(m_wszDrive, wszVolumeName, _countof(wszVolumeName), NULL, NULL, NULL, wszFileSystem, _countof(wszFileSystem));
290 if (bRet)
291 {
292 /* Set volume label and filesystem */
293 SetDlgItemTextW(hwndDlg, 14000, wszVolumeName);
294 SetDlgItemTextW(hwndDlg, 14002, wszFileSystem);
295 }
296 else
297 {
298 LoadStringW(shell32_hInstance, IDS_FS_UNKNOWN, wszFileSystem, _countof(wszFileSystem));
299 SetDlgItemTextW(hwndDlg, 14002, wszFileSystem);
300 }
301
302 /* Set drive type and icon */
303 UINT DriveType = GetDriveTypeW(m_wszDrive);
304 UINT IconId, TypeStrId = 0;
305 switch (DriveType)
306 {
307 case DRIVE_REMOVABLE: IconId = IDI_SHELL_3_14_FLOPPY; break;
308 case DRIVE_CDROM: IconId = IDI_SHELL_CDROM; TypeStrId = IDS_DRIVE_CDROM; break;
309 case DRIVE_REMOTE: IconId = IDI_SHELL_NETDRIVE; TypeStrId = IDS_DRIVE_NETWORK; break;
310 case DRIVE_RAMDISK: IconId = IDI_SHELL_RAMDISK; break;
311 default: IconId = IDI_SHELL_DRIVE; TypeStrId = IDS_DRIVE_FIXED;
312 }
313
314 if (DriveType == DRIVE_CDROM || DriveType == DRIVE_REMOTE)
315 {
316 /* volume label textbox */
317 SendMessage(GetDlgItem(hwndDlg, 14000), EM_SETREADONLY, TRUE, 0);
318
319 /* disk compression */
320 ShowWindow(GetDlgItem(hwndDlg, 14011), FALSE);
321
322 /* index */
323 ShowWindow(GetDlgItem(hwndDlg, 14012), FALSE);
324 }
325
326 HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IconId), IMAGE_ICON, 32, 32, LR_SHARED);
327 if (hIcon)
328 SendDlgItemMessageW(hwndDlg, 14016, STM_SETICON, (WPARAM)hIcon, 0);
329 if (TypeStrId && LoadStringW(shell32_hInstance, TypeStrId, wszBuf, _countof(wszBuf)))
330 SetDlgItemTextW(hwndDlg, 14001, wszBuf);
331
332 ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes;
333 if(GetDiskFreeSpaceExW(m_wszDrive, &FreeBytesAvailable, &TotalNumberOfBytes, NULL))
334 {
335 /* Init free space percentage used for drawing piechart */
336 m_FreeSpacePerc = (UINT)(FreeBytesAvailable.QuadPart * 100ull / TotalNumberOfBytes.QuadPart);
337
338 /* Used space */
339 if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
340 SetDlgItemTextW(hwndDlg, 14003, wszBuf);
341
342 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
343 SetDlgItemTextW(hwndDlg, 14004, wszBuf);
344
345 /* Free space */
346 if (SH_FormatByteSize(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
347 SetDlgItemTextW(hwndDlg, 14005, wszBuf);
348
349 if (StrFormatByteSizeW(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf)))
350 SetDlgItemTextW(hwndDlg, 14006, wszBuf);
351
352 /* Total space */
353 if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
354 SetDlgItemTextW(hwndDlg, 14007, wszBuf);
355
356 if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
357 SetDlgItemTextW(hwndDlg, 14008, wszBuf);
358 }
359 else
360 {
361 m_FreeSpacePerc = 0;
362
363 if (SH_FormatByteSize(0, wszBuf, _countof(wszBuf)))
364 {
365 SetDlgItemTextW(hwndDlg, 14003, wszBuf);
366 SetDlgItemTextW(hwndDlg, 14005, wszBuf);
367 SetDlgItemTextW(hwndDlg, 14007, wszBuf);
368 }
369 if (StrFormatByteSizeW(0, wszBuf, _countof(wszBuf)))
370 {
371 SetDlgItemTextW(hwndDlg, 14004, wszBuf);
372 SetDlgItemTextW(hwndDlg, 14006, wszBuf);
373 SetDlgItemTextW(hwndDlg, 14008, wszBuf);
374 }
375 }
376
377 /* Set drive description */
378 WCHAR wszFormat[50];
379 GetDlgItemTextW(hwndDlg, 14009, wszFormat, _countof(wszFormat));
380 swprintf(wszBuf, wszFormat, m_wszDrive[0]);
381 SetDlgItemTextW(hwndDlg, 14009, wszBuf);
382
383 /* show disk cleanup button only for fixed drives */
384 ShowWindow(GetDlgItem(hwndDlg, 14010), DriveType == DRIVE_FIXED);
385 }
386
387 INT_PTR CALLBACK
388 CDrvDefExt::GeneralPageProc(
389 HWND hwndDlg,
390 UINT uMsg,
391 WPARAM wParam,
392 LPARAM lParam)
393 {
394 switch(uMsg)
395 {
396 case WM_INITDIALOG:
397 {
398 LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
399 if (ppsp == NULL)
400 break;
401
402 CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(ppsp->lParam);
403 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pDrvDefExt);
404 pDrvDefExt->InitGeneralPage(hwndDlg);
405 return TRUE;
406 }
407 case WM_DRAWITEM:
408 {
409 LPDRAWITEMSTRUCT pDrawItem = (LPDRAWITEMSTRUCT)lParam;
410
411 if (pDrawItem->CtlID >= 14013 && pDrawItem->CtlID <= 14015)
412 {
413 CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
414 pDrvDefExt->PaintStaticControls(hwndDlg, pDrawItem);
415 return TRUE;
416 }
417 break;
418 }
419 case WM_PAINT:
420 break;
421 case WM_COMMAND:
422 if (LOWORD(wParam) == 14010) /* Disk Cleanup */
423 {
424 CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
425 WCHAR wszBuf[256];
426 DWORD cbBuf = sizeof(wszBuf);
427
428 if (RegGetValueW(HKEY_LOCAL_MACHINE,
429 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\CleanupPath",
430 NULL,
431 RRF_RT_REG_SZ,
432 NULL,
433 (PVOID)wszBuf,
434 &cbBuf) == ERROR_SUCCESS)
435 {
436 WCHAR wszCmd[MAX_PATH];
437
438 StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]);
439
440 if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
441 ERR("Failed to create cleanup process %ls\n", wszCmd);
442 }
443 }
444 else if (LOWORD(wParam) == 14000) /* Label */
445 {
446 if (HIWORD(wParam) == EN_CHANGE)
447 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
448 }
449 break;
450 case WM_NOTIFY:
451 if (((LPNMHDR)lParam)->hwndFrom == GetParent(hwndDlg))
452 {
453 /* Property Sheet */
454 LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
455
456 if (lppsn->hdr.code == PSN_APPLY)
457 {
458 CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
459 WCHAR wszBuf[256];
460
461 if (GetDlgItemTextW(hwndDlg, 14000, wszBuf, _countof(wszBuf)))
462 SetVolumeLabelW(pDrvDefExt->m_wszDrive, wszBuf);
463 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
464 return TRUE;
465 }
466 }
467 break;
468
469 default:
470 break;
471 }
472
473 return FALSE;
474 }
475
476 INT_PTR CALLBACK
477 CDrvDefExt::ExtraPageProc(
478 HWND hwndDlg,
479 UINT uMsg,
480 WPARAM wParam,
481 LPARAM lParam)
482 {
483 switch (uMsg)
484 {
485 case WM_INITDIALOG:
486 {
487 LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
488 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)ppsp->lParam);
489 return TRUE;
490 }
491 case WM_COMMAND:
492 {
493 WCHAR wszBuf[MAX_PATH];
494 DWORD cbBuf = sizeof(wszBuf);
495 CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
496
497 switch(LOWORD(wParam))
498 {
499 case 14000:
500 DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_CHECK_DISK), hwndDlg, ChkDskDlg, (LPARAM)pDrvDefExt->m_wszDrive);
501 break;
502 case 14001:
503 if (RegGetValueW(HKEY_LOCAL_MACHINE,
504 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\DefragPath",
505 NULL,
506 RRF_RT_REG_SZ,
507 NULL,
508 (PVOID)wszBuf,
509 &cbBuf) == ERROR_SUCCESS)
510 {
511 WCHAR wszCmd[MAX_PATH];
512
513 StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]);
514
515 if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
516 ERR("Failed to create defrag process %ls\n", wszCmd);
517 }
518 break;
519 case 14002:
520 if (RegGetValueW(HKEY_LOCAL_MACHINE,
521 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\BackupPath",
522 NULL,
523 RRF_RT_REG_SZ,
524 NULL,
525 (PVOID)wszBuf,
526 &cbBuf) == ERROR_SUCCESS)
527 {
528 if (ShellExecuteW(hwndDlg, NULL, wszBuf, NULL, NULL, SW_SHOW) <= (HINSTANCE)32)
529 ERR("Failed to create backup process %ls\n", wszBuf);
530 }
531 }
532 break;
533 }
534 }
535 return FALSE;
536 }
537
538 INT_PTR CALLBACK
539 CDrvDefExt::HardwarePageProc(
540 HWND hwndDlg,
541 UINT uMsg,
542 WPARAM wParam,
543 LPARAM lParam)
544 {
545 UNREFERENCED_PARAMETER(lParam);
546 UNREFERENCED_PARAMETER(wParam);
547
548 switch(uMsg)
549 {
550 case WM_INITDIALOG:
551 {
552 GUID Guid = GUID_DEVCLASS_DISKDRIVE;
553
554 /* create the hardware page */
555 DeviceCreateHardwarePageEx(hwndDlg, &Guid, 1, HWPD_STANDARDLIST);
556 break;
557 }
558 }
559
560 return FALSE;
561 }
562
563 CDrvDefExt::CDrvDefExt()
564 {
565 m_wszDrive[0] = L'\0';
566 }
567
568 CDrvDefExt::~CDrvDefExt()
569 {
570
571 }
572
573 HRESULT WINAPI
574 CDrvDefExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID)
575 {
576 FORMATETC format;
577 STGMEDIUM stgm;
578 HRESULT hr;
579
580 TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID);
581
582 if (!pDataObj)
583 return E_FAIL;
584
585 format.cfFormat = CF_HDROP;
586 format.ptd = NULL;
587 format.dwAspect = DVASPECT_CONTENT;
588 format.lindex = -1;
589 format.tymed = TYMED_HGLOBAL;
590
591 hr = pDataObj->GetData(&format, &stgm);
592 if (FAILED(hr))
593 return hr;
594
595 if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszDrive, _countof(m_wszDrive)))
596 {
597 ERR("DragQueryFileW failed\n");
598 ReleaseStgMedium(&stgm);
599 return E_FAIL;
600 }
601
602 ReleaseStgMedium(&stgm);
603 TRACE("Drive properties %ls\n", m_wszDrive);
604
605 return S_OK;
606 }
607
608 HRESULT WINAPI
609 CDrvDefExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
610 {
611 UNIMPLEMENTED;
612 return E_NOTIMPL;
613 }
614
615 HRESULT WINAPI
616 CDrvDefExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
617 {
618 UNIMPLEMENTED;
619 return E_NOTIMPL;
620 }
621
622 HRESULT WINAPI
623 CDrvDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax)
624 {
625 UNIMPLEMENTED;
626 return E_NOTIMPL;
627 }
628
629 HRESULT WINAPI
630 CDrvDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam)
631 {
632 HPROPSHEETPAGE hPage;
633
634 hPage = SH_CreatePropertySheetPage(IDD_DRIVE_PROPERTIES,
635 GeneralPageProc,
636 (LPARAM)this,
637 NULL);
638 if (hPage)
639 pfnAddPage(hPage, lParam);
640
641 if (GetDriveTypeW(m_wszDrive) == DRIVE_FIXED)
642 {
643 hPage = SH_CreatePropertySheetPage(IDD_DRIVE_TOOLS,
644 ExtraPageProc,
645 (LPARAM)this,
646 NULL);
647 if (hPage)
648 pfnAddPage(hPage, lParam);
649 }
650
651 hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE,
652 HardwarePageProc,
653 (LPARAM)this,
654 NULL);
655 if (hPage)
656 pfnAddPage(hPage, lParam);
657
658 return S_OK;
659 }
660
661 HRESULT WINAPI
662 CDrvDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam)
663 {
664 UNIMPLEMENTED;
665 return E_NOTIMPL;
666 }
667
668 HRESULT WINAPI
669 CDrvDefExt::SetSite(IUnknown *punk)
670 {
671 UNIMPLEMENTED;
672 return E_NOTIMPL;
673 }
674
675 HRESULT WINAPI
676 CDrvDefExt::GetSite(REFIID iid, void **ppvSite)
677 {
678 UNIMPLEMENTED;
679 return E_NOTIMPL;
680 }