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, DWLP_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(PCIDLIST_ABSOLUTE 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 if (GetDriveTypeW(m_wszDrive) != DRIVE_REMOTE) 652 { 653 hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE, 654 HardwarePageProc, 655 (LPARAM)this, 656 NULL); 657 if (hPage) 658 pfnAddPage(hPage, lParam); 659 } 660 661 return S_OK; 662 } 663 664 HRESULT WINAPI 665 CDrvDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam) 666 { 667 UNIMPLEMENTED; 668 return E_NOTIMPL; 669 } 670 671 HRESULT WINAPI 672 CDrvDefExt::SetSite(IUnknown *punk) 673 { 674 UNIMPLEMENTED; 675 return E_NOTIMPL; 676 } 677 678 HRESULT WINAPI 679 CDrvDefExt::GetSite(REFIID iid, void **ppvSite) 680 { 681 UNIMPLEMENTED; 682 return E_NOTIMPL; 683 } 684