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