[SHELL32] Distinguish floppy and removable drives (#2645)

Distinguish floppy drive and non-floppy removable drive in icon and description. CORE-10221
This commit is contained in:
Katayama Hirofumi MZ 2020-05-06 00:35:01 +09:00 committed by GitHub
parent 0461de33c5
commit 1f3cb13fb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 3 deletions

View file

@ -3,6 +3,7 @@
*
* 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
@ -24,6 +25,10 @@
#define _USE_MATH_DEFINES
#include <math.h>
#define NTOS_MODE_USER
#include <ndk/iofuncs.h>
#include <ndk/obfuncs.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
@ -278,6 +283,100 @@ CDrvDefExt::PaintStaticControls(HWND hwndDlg, LPDRAWITEMSTRUCT pDrawItem)
}
}
// https://stackoverflow.com/questions/3098696/get-information-about-disk-drives-result-on-windows7-32-bit-system/3100268#3100268
static BOOL
GetDriveTypeAndCharacteristics(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);
}
VOID
CDrvDefExt::InitGeneralPage(HWND hwndDlg)
{
@ -304,7 +403,12 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg)
UINT IconId, TypeStrId = 0;
switch (DriveType)
{
case DRIVE_REMOVABLE: IconId = IDI_SHELL_3_14_FLOPPY; break;
case DRIVE_REMOVABLE:
if (IsDriveFloppyW(m_wszDrive))
IconId = IDI_SHELL_3_14_FLOPPY;
else
IconId = IDI_SHELL_REMOVEABLE;
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;

View file

@ -449,6 +449,8 @@ getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags,
return E_FAIL;
}
BOOL IsDriveFloppyA(LPCSTR pszDriveRoot);
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;
@ -476,7 +478,14 @@ HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl
}
else
{
icon_idx = iDriveIconIds[DriveType];
if (DriveType == DRIVE_REMOVABLE && !IsDriveFloppyA(pszDrive))
{
icon_idx = IDI_SHELL_REMOVEABLE;
}
else
{
icon_idx = iDriveIconIds[DriveType];
}
initIcon->SetNormalIcon(swShell32Name, -icon_idx);
}
@ -1117,7 +1126,10 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S
hr = SHSetStrRet(&psd->str, "");
break;
case 2: /* type */
hr = SHSetStrRet(&psd->str, iDriveTypeIds[DriveType]);
if (DriveType == DRIVE_REMOVABLE && !IsDriveFloppyA(pszDrive))
hr = SHSetStrRet(&psd->str, IDS_DRIVE_REMOVABLE);
else
hr = SHSetStrRet(&psd->str, iDriveTypeIds[DriveType]);
break;
case 3: /* total size */
case 4: /* free size */