Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878/* * Provides default drive shell extension * * Copyright 2005 Johannes Anderwald * Copyright 2012 Rafal Harabien * Copyright 2020 Katayama Hirofumi MZ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include "precomp.h"
#define _USE_MATH_DEFINES#include <math.h>#include <devguid.h>
#define NTOS_MODE_USER#include <ndk/iofuncs.h>#include <ndk/obfuncs.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef enum{ HWPD_STANDARDLIST = 0, HWPD_LARGELIST, HWPD_MAX = HWPD_LARGELIST} HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;
EXTERN_C HWND WINAPIDeviceCreateHardwarePageEx(HWND hWndParent, LPGUID lpGuids, UINT uNumberOfGuids, HWPAGE_DISPLAYMODE DisplayMode);UINT SH_FormatByteSize(LONGLONG cbSize, LPWSTR pwszResult, UINT cchResultMax);
static VOIDGetDriveNameWithLetter(LPWSTR pwszText, UINT cchTextMax, LPCWSTR pwszDrive){ DWORD dwMaxComp, dwFileSys; SIZE_T cchText = 0;
if (GetVolumeInformationW(pwszDrive, pwszText, cchTextMax, NULL, &dwMaxComp, &dwFileSys, NULL, 0)) { cchText = wcslen(pwszText); if (cchText == 0) { /* load default volume label */ cchText = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, pwszText, cchTextMax); } }
StringCchPrintfW(pwszText + cchText, cchTextMax - cchText, L" (%c:)", pwszDrive[0]);}
static VOIDInitializeChkDskDialog(HWND hwndDlg, LPCWSTR pwszDrive){ WCHAR wszText[100]; UINT Length; SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pwszDrive);
Length = GetWindowTextW(hwndDlg, wszText, sizeof(wszText) / sizeof(WCHAR)); wszText[Length] = L' '; GetDriveNameWithLetter(&wszText[Length + 1], (sizeof(wszText) / sizeof(WCHAR)) - Length - 1, pwszDrive); SetWindowText(hwndDlg, wszText);}
static HWND hChkdskDrvDialog = NULL;static BOOLEAN bChkdskSuccess = FALSE;
static BOOLEAN NTAPIChkdskCallback( IN CALLBACKCOMMAND Command, IN ULONG SubAction, IN PVOID ActionInfo){ PDWORD Progress; PBOOLEAN pSuccess; switch(Command) { case PROGRESS: Progress = (PDWORD)ActionInfo; SendDlgItemMessageW(hChkdskDrvDialog, 14002, PBM_SETPOS, (WPARAM)*Progress, 0); break; case DONE: pSuccess = (PBOOLEAN)ActionInfo; bChkdskSuccess = (*pSuccess); break;
case VOLUMEINUSE: case INSUFFICIENTRIGHTS: case FSNOTSUPPORTED: case CLUSTERSIZETOOSMALL: bChkdskSuccess = FALSE; FIXME("\n"); break;
default: break; }
return TRUE;}
static VOIDChkDskNow(HWND hwndDlg, LPCWSTR pwszDrive){ //DWORD ClusterSize = 0; WCHAR wszFs[30]; ULARGE_INTEGER TotalNumberOfFreeBytes, FreeBytesAvailableUser; BOOLEAN bCorrectErrors = FALSE, bScanDrive = FALSE;
if(!GetVolumeInformationW(pwszDrive, NULL, 0, NULL, NULL, NULL, wszFs, _countof(wszFs))) { FIXME("failed to get drive fs type\n"); return; }
if (!GetDiskFreeSpaceExW(pwszDrive, &FreeBytesAvailableUser, &TotalNumberOfFreeBytes, NULL)) { FIXME("failed to get drive space type\n"); return; }
/*if (!GetDefaultClusterSize(wszFs, &ClusterSize, &TotalNumberOfFreeBytes)) { FIXME("invalid cluster size\n"); return; }*/
if (SendDlgItemMessageW(hwndDlg, 14000, BM_GETCHECK, 0, 0) == BST_CHECKED) bCorrectErrors = TRUE;
if (SendDlgItemMessageW(hwndDlg, 14001, BM_GETCHECK, 0, 0) == BST_CHECKED) bScanDrive = TRUE;
hChkdskDrvDialog = hwndDlg; bChkdskSuccess = FALSE; SendDlgItemMessageW(hwndDlg, 14002, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); Chkdsk((LPWSTR)pwszDrive, (LPWSTR)wszFs, bCorrectErrors, TRUE, FALSE, bScanDrive, NULL, NULL, ChkdskCallback); // FIXME: casts
hChkdskDrvDialog = NULL; bChkdskSuccess = FALSE;}
static INT_PTR CALLBACKChkDskDlg( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch(uMsg) { case WM_INITDIALOG: SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); InitializeChkDskDialog(hwndDlg, (LPCWSTR)lParam); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, 0); break; case IDOK: { LPCWSTR pwszDrive = (LPCWSTR)GetWindowLongPtr(hwndDlg, DWLP_USER); ChkDskNow(hwndDlg, pwszDrive); break; } } break; }
return FALSE;}
VOIDCDrvDefExt::PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT pDrawItem){ HBRUSH hBrush;
if (pDrawItem->CtlID == 14013) { hBrush = CreateSolidBrush(RGB(0, 0, 255)); if (hBrush) { FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush); DeleteObject((HGDIOBJ)hBrush); } } else if (pDrawItem->CtlID == 14014) { hBrush = CreateSolidBrush(RGB(255, 0, 255)); if (hBrush) { FillRect(pDrawItem->hDC, &pDrawItem->rcItem, hBrush); DeleteObject((HGDIOBJ)hBrush); } } else if (pDrawItem->CtlID == 14015) { HBRUSH hBlueBrush = CreateSolidBrush(RGB(0, 0, 255)); HBRUSH hMagBrush = CreateSolidBrush(RGB(255, 0, 255)); HBRUSH hbrOld; HPEN hBlackPen = (HPEN)GetStockObject(BLACK_PEN); HPEN hDarkBluePen = CreatePen(PS_SOLID, 1, RGB(0, 0, 128)); HPEN hDarkMagPen = CreatePen(PS_SOLID, 1, RGB(128, 0, 128)); HPEN hOldPen = (HPEN)SelectObject(pDrawItem->hDC, hDarkMagPen); INT xCenter = (pDrawItem->rcItem.left + pDrawItem->rcItem.right) / 2; INT yCenter = (pDrawItem->rcItem.top + pDrawItem->rcItem.bottom - 10) / 2; INT cx = pDrawItem->rcItem.right - pDrawItem->rcItem.left; INT cy = pDrawItem->rcItem.bottom - pDrawItem->rcItem.top - 10; INT xRadial = xCenter + (INT)(cos(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cx / 2); INT yRadial = yCenter - (INT)(sin(M_PI + m_FreeSpacePerc / 100.0f * M_PI * 2.0f) * cy / 2);
TRACE("FreeSpace %u a %f cx %d\n", m_FreeSpacePerc, M_PI+m_FreeSpacePerc / 100.0f * M_PI * 2.0f, cx);
for (INT x = pDrawItem->rcItem.left; x < pDrawItem->rcItem.right; ++x) { double cos_val = (x - xCenter) * 2.0f / cx; INT y = yCenter + (INT)(sin(acos(cos_val)) * cy / 2) - 1; HPEN hCenterPen;
if (m_FreeSpacePerc < 50 && x == xRadial) SelectObject(pDrawItem->hDC, hDarkBluePen); /* Temporarily change pens to draw edges */ if (x == pDrawItem->rcItem.left) hCenterPen = (HPEN)SelectObject(pDrawItem->hDC, hBlackPen); else if (x == pDrawItem->rcItem.right - 1) SelectObject(pDrawItem->hDC, hBlackPen);
MoveToEx(pDrawItem->hDC, x, y, NULL); LineTo(pDrawItem->hDC, x, y + 10); SetPixel(pDrawItem->hDC, x, y + 10, RGB(0, 0, 0)); /* Restore fill section pens */ if (x == pDrawItem->rcItem.left) SelectObject(pDrawItem->hDC, hCenterPen); }
SelectObject(pDrawItem->hDC, hBlackPen);
if (m_FreeSpacePerc > 50) { hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hMagBrush);
Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
SelectObject(pDrawItem->hDC, hBlueBrush);
if (m_FreeSpacePerc < 100) { Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10, xRadial, yRadial, pDrawItem->rcItem.left, yCenter); } } else { hbrOld = (HBRUSH)SelectObject(pDrawItem->hDC, hBlueBrush);
Ellipse(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10);
SelectObject(pDrawItem->hDC, hMagBrush);
if (m_FreeSpacePerc > 0) { Pie(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, pDrawItem->rcItem.right, pDrawItem->rcItem.bottom - 10, pDrawItem->rcItem.left, yCenter, xRadial, yRadial); } }
SelectObject(pDrawItem->hDC, hbrOld); SelectObject(pDrawItem->hDC, hOldPen);
DeleteObject(hBlueBrush); DeleteObject(hMagBrush); DeleteObject(hDarkBluePen); DeleteObject(hDarkMagPen); }}
// https://stackoverflow.com/questions/3098696/get-information-about-disk-drives-result-on-windows7-32-bit-system/3100268#3100268static BOOLGetDriveTypeAndCharacteristics(HANDLE hDevice, DEVICE_TYPE *pDeviceType, ULONG *pCharacteristics){ NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; FILE_FS_DEVICE_INFORMATION DeviceInfo;
Status = NtQueryVolumeInformationFile(hDevice, &IoStatusBlock, &DeviceInfo, sizeof(DeviceInfo), FileFsDeviceInformation); if (Status == NO_ERROR) { *pDeviceType = DeviceInfo.DeviceType; *pCharacteristics = DeviceInfo.Characteristics; return TRUE; }
return FALSE;}
BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot){ LPCWSTR RootPath = pszDriveRoot; WCHAR szRoot[16], szDeviceName[16]; UINT uType; HANDLE hDevice; DEVICE_TYPE DeviceType; ULONG ulCharacteristics; BOOL ret;
lstrcpynW(szRoot, RootPath, _countof(szRoot));
if (L'a' <= szRoot[0] && szRoot[0] <= 'z') { szRoot[0] += ('A' - 'a'); }
if ('A' <= szRoot[0] && szRoot[0] <= L'Z' && szRoot[1] == L':' && szRoot[2] == 0) { // 'C:' --> 'C:\' szRoot[2] = L'\\'; szRoot[3] = 0; }
if (!PathIsRootW(szRoot)) { return FALSE; }
uType = GetDriveTypeW(szRoot); if (uType == DRIVE_REMOVABLE) { if (szRoot[0] == L'A' || szRoot[0] == L'B') return TRUE; } else { return FALSE; }
lstrcpynW(szDeviceName, L"\\\\.\\", _countof(szDeviceName)); szDeviceName[4] = szRoot[0]; szDeviceName[5] = L':'; szDeviceName[6] = UNICODE_NULL;
hDevice = CreateFileW(szDeviceName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) { return FALSE; }
ret = FALSE; if (GetDriveTypeAndCharacteristics(hDevice, &DeviceType, &ulCharacteristics)) { if ((ulCharacteristics & FILE_FLOPPY_DISKETTE) == FILE_FLOPPY_DISKETTE) ret = TRUE; }
CloseHandle(hDevice);
return ret;}
BOOL IsDriveFloppyA(LPCSTR pszDriveRoot){ WCHAR szRoot[8]; MultiByteToWideChar(CP_ACP, 0, pszDriveRoot, -1, szRoot, _countof(szRoot)); return IsDriveFloppyW(szRoot);}
VOIDCDrvDefExt::InitGeneralPage(HWND hwndDlg){ WCHAR wszVolumeName[MAX_PATH+1] = {0}; WCHAR wszFileSystem[MAX_PATH+1] = {0}; WCHAR wszBuf[128]; BOOL bRet, bFloppy = FALSE, bHasFS = FALSE;
bRet = GetVolumeInformationW(m_wszDrive, wszVolumeName, _countof(wszVolumeName), NULL, NULL, NULL, wszFileSystem, _countof(wszFileSystem)); if (bRet) { /* Set volume label and filesystem */ SetDlgItemTextW(hwndDlg, 14000, wszVolumeName); SetDlgItemTextW(hwndDlg, 14002, wszFileSystem); bHasFS = *wszFileSystem != UNICODE_NULL; } else { LoadStringW(shell32_hInstance, IDS_FS_UNKNOWN, wszFileSystem, _countof(wszFileSystem)); SetDlgItemTextW(hwndDlg, 14002, wszFileSystem); }
/* Set drive type and icon */ // TODO: Call SHGetFileInfo to get this info UINT DriveType = GetDriveTypeW(m_wszDrive); UINT IconId, TypeStrId; switch (DriveType) { case DRIVE_REMOVABLE: bFloppy = IsDriveFloppyW(m_wszDrive); IconId = bFloppy ? IDI_SHELL_3_14_FLOPPY : IDI_SHELL_REMOVEABLE; TypeStrId = bFloppy ? IDS_DRIVE_FLOPPY : IDS_DRIVE_REMOVABLE; break; case DRIVE_CDROM: IconId = IDI_SHELL_CDROM; TypeStrId = IDS_DRIVE_CDROM; break; case DRIVE_REMOTE: IconId = IDI_SHELL_NETDRIVE; TypeStrId = IDS_DRIVE_NETWORK; break; case DRIVE_RAMDISK: IconId = IDI_SHELL_RAMDISK; break; default: IconId = IDI_SHELL_DRIVE; TypeStrId = IDS_DRIVE_FIXED; }
BOOL bCanSetLabel = bHasFS; if (DriveType == DRIVE_CDROM || DriveType == DRIVE_REMOTE || bFloppy) { bCanSetLabel = bFloppy && bHasFS;
/* disk compression */ ShowWindow(GetDlgItem(hwndDlg, 14011), FALSE);
/* index */ ShowWindow(GetDlgItem(hwndDlg, 14012), FALSE); } /* volume label textbox */ SendMessage(GetDlgItem(hwndDlg, 14000), EM_SETREADONLY, !bCanSetLabel, 0);
HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IconId), IMAGE_ICON, 32, 32, LR_SHARED); if (hIcon) SendDlgItemMessageW(hwndDlg, 14016, STM_SETICON, (WPARAM)hIcon, 0); if (TypeStrId && LoadStringW(shell32_hInstance, TypeStrId, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14001, wszBuf);
ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes; if(GetDiskFreeSpaceExW(m_wszDrive, &FreeBytesAvailable, &TotalNumberOfBytes, NULL)) { /* Init free space percentage used for drawing piechart */ m_FreeSpacePerc = (UINT)(FreeBytesAvailable.QuadPart * 100ull / TotalNumberOfBytes.QuadPart);
/* Used space */ if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14003, wszBuf);
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14004, wszBuf);
/* Free space */ if (SH_FormatByteSize(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14005, wszBuf);
if (StrFormatByteSizeW(FreeBytesAvailable.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14006, wszBuf);
/* Total space */ if (SH_FormatByteSize(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14007, wszBuf);
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14008, wszBuf); } else { m_FreeSpacePerc = 0;
if (SH_FormatByteSize(0, wszBuf, _countof(wszBuf))) { SetDlgItemTextW(hwndDlg, 14003, wszBuf); SetDlgItemTextW(hwndDlg, 14005, wszBuf); SetDlgItemTextW(hwndDlg, 14007, wszBuf); } if (StrFormatByteSizeW(0, wszBuf, _countof(wszBuf))) { SetDlgItemTextW(hwndDlg, 14004, wszBuf); SetDlgItemTextW(hwndDlg, 14006, wszBuf); SetDlgItemTextW(hwndDlg, 14008, wszBuf); } }
/* Set drive description */ WCHAR wszFormat[50]; GetDlgItemTextW(hwndDlg, 14009, wszFormat, _countof(wszFormat)); swprintf(wszBuf, wszFormat, m_wszDrive[0]); SetDlgItemTextW(hwndDlg, 14009, wszBuf);
/* show disk cleanup button only for fixed drives */ ShowWindow(GetDlgItem(hwndDlg, 14010), DriveType == DRIVE_FIXED);}
INT_PTR CALLBACKCDrvDefExt::GeneralPageProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch(uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam; if (ppsp == NULL) break;
CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(ppsp->lParam); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pDrvDefExt); pDrvDefExt->InitGeneralPage(hwndDlg); return TRUE; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT pDrawItem = (LPDRAWITEMSTRUCT)lParam;
if (pDrawItem->CtlID >= 14013 && pDrawItem->CtlID <= 14015) { CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER)); pDrvDefExt->PaintStaticControls(hwndDlg, pDrawItem); return TRUE; } break; } case WM_PAINT: break; case WM_COMMAND: if (LOWORD(wParam) == 14010) /* Disk Cleanup */ { CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER)); WCHAR wszBuf[256]; DWORD cbBuf = sizeof(wszBuf);
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\CleanupPath", NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszBuf, &cbBuf) == ERROR_SUCCESS) { WCHAR wszCmd[MAX_PATH];
StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]); WCHAR* wszArgs = PathGetArgsW(wszCmd); if (wszArgs && *wszArgs && wszArgs != wszCmd) wszArgs[-1] = UNICODE_NULL; else wszArgs = NULL;
if (ShellExecuteW(hwndDlg, NULL, wszCmd, wszArgs, NULL, SW_SHOW) <= (HINSTANCE)32) ERR("Failed to create cleanup process %ls\n", wszCmd); } } else if (LOWORD(wParam) == 14000) /* Label */ { if (HIWORD(wParam) == EN_CHANGE) PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break; case WM_NOTIFY: if (((LPNMHDR)lParam)->hwndFrom == GetParent(hwndDlg)) { /* Property Sheet */ LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
if (lppsn->hdr.code == PSN_APPLY) { CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
HRESULT hr = E_FAIL; HWND hLabel = GetDlgItem(hwndDlg, 14000); WCHAR wszBuf[256]; *wszBuf = UNICODE_NULL; if (GetWindowTextW(hLabel, wszBuf, _countof(wszBuf)) || GetWindowTextLengthW(hLabel) == 0) hr = CDrivesFolder::SetDriveLabel(hwndDlg, pDrvDefExt->m_wszDrive, wszBuf);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FAILED(hr) ? PSNRET_INVALID : PSNRET_NOERROR); return TRUE; } } break;
default: break; }
return FALSE;}
INT_PTR CALLBACKCDrvDefExt::ExtraPageProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)ppsp->lParam); return TRUE; } case WM_COMMAND: { WCHAR wszBuf[MAX_PATH]; DWORD cbBuf = sizeof(wszBuf); CDrvDefExt *pDrvDefExt = reinterpret_cast<CDrvDefExt *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
switch(LOWORD(wParam)) { case 14000: DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_CHECK_DISK), hwndDlg, ChkDskDlg, (LPARAM)pDrvDefExt->m_wszDrive); break; case 14001: if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\DefragPath", NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszBuf, &cbBuf) == ERROR_SUCCESS) { WCHAR wszCmd[MAX_PATH];
StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]);
if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32) ERR("Failed to create defrag process %ls\n", wszCmd); } break; case 14002: if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\BackupPath", NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszBuf, &cbBuf) == ERROR_SUCCESS) { if (ShellExecuteW(hwndDlg, NULL, wszBuf, NULL, NULL, SW_SHOW) <= (HINSTANCE)32) ERR("Failed to create backup process %ls\n", wszBuf); } } break; } } return FALSE;}
INT_PTR CALLBACKCDrvDefExt::HardwarePageProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam);
switch(uMsg) { case WM_INITDIALOG: { GUID Guids[2]; Guids[0] = GUID_DEVCLASS_DISKDRIVE; Guids[1] = GUID_DEVCLASS_CDROM;
/* create the hardware page */ DeviceCreateHardwarePageEx(hwndDlg, Guids, _countof(Guids), HWPD_STANDARDLIST); break; } }
return FALSE;}
CDrvDefExt::CDrvDefExt(){ m_wszDrive[0] = L'\0';}
CDrvDefExt::~CDrvDefExt(){
}
struct CDrop{ HRESULT hr; STGMEDIUM stgm; HDROP hDrop;
explicit CDrop(IDataObject *pDO) { FORMATETC format = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hDrop = SUCCEEDED(hr = pDO->GetData(&format, &stgm)) ? (HDROP)stgm.hGlobal : NULL; }
~CDrop() { if (hDrop) ReleaseStgMedium(&stgm); }
UINT GetCount() { return DragQueryFileW(hDrop, -1, NULL, 0); }};
static inline boolIsValidDrivePath(PCWSTR Path){ return GetDriveTypeW(Path) > DRIVE_NO_ROOT_DIR;}
HRESULT WINAPICDrvDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID){ HRESULT hr;
TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID);
if (!pDataObj) return E_FAIL;
CDrop drop(pDataObj); if (FAILED_UNEXPECTEDLY(hr = drop.hr)) return hr;
if (!DragQueryFileW(drop.hDrop, 0, m_wszDrive, _countof(m_wszDrive))) { ERR("DragQueryFileW failed\n"); return E_FAIL; }
if (drop.GetCount() > 1) m_Multiple = pDataObj;
TRACE("Drive properties %ls\n", m_wszDrive);
return S_OK;}
HRESULT WINAPICDrvDefExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags){ UNIMPLEMENTED; return E_NOTIMPL;}
HRESULT WINAPICDrvDefExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici){ UNIMPLEMENTED; return E_NOTIMPL;}
HRESULT WINAPICDrvDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax){ UNIMPLEMENTED; return E_NOTIMPL;}
HRESULTCDrvDefExt::AddMainPage(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam){ WCHAR szTitle[MAX_PATH], *pszTitle = NULL; if (m_Multiple) { CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidl(SHSimpleIDListFromPathW(m_wszDrive)); if (SUCCEEDED(SHGetNameAndFlagsW(pidl, SHGDN_INFOLDER, szTitle, _countof(szTitle), NULL))) pszTitle = szTitle; }
HPROPSHEETPAGE hPage; hPage = SH_CreatePropertySheetPageEx(IDD_DRIVE_PROPERTIES, GeneralPageProc, (LPARAM)this, pszTitle, &PropSheetPageLifetimeCallback<CDrvDefExt>); HRESULT hr = AddPropSheetPage(hPage, pfnAddPage, lParam); if (FAILED_UNEXPECTEDLY(hr)) return hr; else AddRef(); // For PropSheetPageLifetimeCallback return hr;}
HRESULT WINAPICDrvDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam){ HRESULT hr = AddMainPage(pfnAddPage, lParam); if (FAILED_UNEXPECTEDLY(hr)) return hr;
if (m_Multiple) { CDrop drop(m_Multiple); UINT count = SUCCEEDED(drop.hr) ? drop.GetCount() : 0; for (UINT i = 0; ++i < count;) // Skipping the first drive since it already has a page { CComPtr<CDrvDefExt> SheetExt; if (FAILED_UNEXPECTEDLY(hr = ShellObjectCreator(SheetExt))) continue; if (!DragQueryFileW(drop.hDrop, i, SheetExt->m_wszDrive, _countof(SheetExt->m_wszDrive))) continue; if (!IsValidDrivePath(SheetExt->m_wszDrive)) continue;
SheetExt->m_Multiple = m_Multiple; SheetExt->AddMainPage(pfnAddPage, lParam); } } else { HPROPSHEETPAGE hPage; if (GetDriveTypeW(m_wszDrive) == DRIVE_FIXED) { hPage = SH_CreatePropertySheetPage(IDD_DRIVE_TOOLS, ExtraPageProc, (LPARAM)this, NULL); if (hPage) pfnAddPage(hPage, lParam); }
if (GetDriveTypeW(m_wszDrive) != DRIVE_REMOTE) { hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE, HardwarePageProc, (LPARAM)this, NULL); if (hPage) pfnAddPage(hPage, lParam); } }
return S_OK;}
HRESULT WINAPICDrvDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam){ UNIMPLEMENTED; return E_NOTIMPL;}
HRESULT WINAPICDrvDefExt::SetSite(IUnknown *punk){ UNIMPLEMENTED; return E_NOTIMPL;}
HRESULT WINAPICDrvDefExt::GetSite(REFIID iid, void **ppvSite){ UNIMPLEMENTED; return E_NOTIMPL;}