From 3fb2905c37d97b92d5c9eec9afd820dfbf9b00dd Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Sat, 12 Jul 2025 15:16:38 +0200 Subject: [PATCH] [SHELL32] Don't get icon and label from AutoRun.inf on floppy drives (#7953) CORE-9881 (partial) --- dll/win32/shell32/dialogs/drvdefext.cpp | 21 +- dll/win32/shell32/folders/CDrivesFolder.cpp | 265 +++++++++++++------- 2 files changed, 180 insertions(+), 106 deletions(-) diff --git a/dll/win32/shell32/dialogs/drvdefext.cpp b/dll/win32/shell32/dialogs/drvdefext.cpp index 785de9daa1c..cf6d654eb0f 100644 --- a/dll/win32/shell32/dialogs/drvdefext.cpp +++ b/dll/win32/shell32/dialogs/drvdefext.cpp @@ -396,7 +396,7 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg) WCHAR wszVolumeName[MAX_PATH+1] = {0}; WCHAR wszFileSystem[MAX_PATH+1] = {0}; WCHAR wszBuf[128]; - BOOL bRet; + BOOL bRet, bFloppy = FALSE, bHasFS = FALSE; bRet = GetVolumeInformationW(m_wszDrive, wszVolumeName, _countof(wszVolumeName), NULL, NULL, NULL, wszFileSystem, _countof(wszFileSystem)); if (bRet) @@ -404,6 +404,7 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg) /* Set volume label and filesystem */ SetDlgItemTextW(hwndDlg, 14000, wszVolumeName); SetDlgItemTextW(hwndDlg, 14002, wszFileSystem); + bHasFS = *wszFileSystem != UNICODE_NULL; } else { @@ -412,15 +413,15 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg) } /* Set drive type and icon */ + // TODO: Call SHGetFileInfo to get this info UINT DriveType = GetDriveTypeW(m_wszDrive); - UINT IconId, TypeStrId = 0; + UINT IconId, TypeStrId; switch (DriveType) { case DRIVE_REMOVABLE: - if (IsDriveFloppyW(m_wszDrive)) - IconId = IDI_SHELL_3_14_FLOPPY; - else - IconId = IDI_SHELL_REMOVEABLE; + 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; @@ -428,10 +429,10 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg) default: IconId = IDI_SHELL_DRIVE; TypeStrId = IDS_DRIVE_FIXED; } - if (DriveType == DRIVE_CDROM || DriveType == DRIVE_REMOTE) + BOOL bCanSetLabel = bHasFS; + if (DriveType == DRIVE_CDROM || DriveType == DRIVE_REMOTE || bFloppy) { - /* volume label textbox */ - SendMessage(GetDlgItem(hwndDlg, 14000), EM_SETREADONLY, TRUE, 0); + bCanSetLabel = bFloppy && bHasFS; /* disk compression */ ShowWindow(GetDlgItem(hwndDlg, 14011), FALSE); @@ -439,6 +440,8 @@ CDrvDefExt::InitGeneralPage(HWND hwndDlg) /* 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) diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index fc6cb265cea..1111b502967 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -26,9 +26,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); -extern BOOL IsDriveFloppyA(LPCSTR pszDriveRoot); -extern BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot); - /* CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in the registry. The CRegFolder is aggregated by the CDrivesFolder. @@ -40,22 +37,22 @@ CDrivesFolderEnum is only responsible for returning the physical items. 3. The parsing name returned for my computer is incorrect. It should be "My Computer" */ -static int iDriveIconIds[7] = { IDI_SHELL_DRIVE, /* DRIVE_UNKNOWN */ - IDI_SHELL_CDROM, /* DRIVE_NO_ROOT_DIR*/ - IDI_SHELL_3_14_FLOPPY, /* DRIVE_REMOVABLE*/ - IDI_SHELL_DRIVE, /* DRIVE_FIXED*/ - IDI_SHELL_NETDRIVE, /* DRIVE_REMOTE*/ - IDI_SHELL_CDROM, /* DRIVE_CDROM*/ - IDI_SHELL_RAMDISK /* DRIVE_RAMDISK*/ +static int iDriveIconIds[7] = { IDI_SHELL_NOT_CONNECTED_HDD, /* DRIVE_UNKNOWN */ + IDI_SHELL_NOT_CONNECTED_HDD, /* DRIVE_NO_ROOT_DIR*/ + IDI_SHELL_REMOVEABLE, /* DRIVE_REMOVABLE*/ + IDI_SHELL_DRIVE, /* DRIVE_FIXED*/ + IDI_SHELL_NETDRIVE, /* DRIVE_REMOTE*/ + IDI_SHELL_CDROM, /* DRIVE_CDROM*/ + IDI_SHELL_RAMDISK /* DRIVE_RAMDISK*/ }; -static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED, /* DRIVE_UNKNOWN */ - IDS_DRIVE_FIXED, /* DRIVE_NO_ROOT_DIR*/ - IDS_DRIVE_FLOPPY, /* DRIVE_REMOVABLE*/ - IDS_DRIVE_FIXED, /* DRIVE_FIXED*/ - IDS_DRIVE_NETWORK, /* DRIVE_REMOTE*/ - IDS_DRIVE_CDROM, /* DRIVE_CDROM*/ - IDS_DRIVE_FIXED /* DRIVE_RAMDISK*/ +static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED, /* DRIVE_UNKNOWN */ + IDS_DRIVE_FIXED, /* DRIVE_NO_ROOT_DIR*/ + IDS_DRIVE_REMOVABLE, /* DRIVE_REMOVABLE*/ + IDS_DRIVE_FIXED, /* DRIVE_FIXED*/ + IDS_DRIVE_NETWORK, /* DRIVE_REMOTE*/ + IDS_DRIVE_CDROM, /* DRIVE_CDROM*/ + IDS_DRIVE_FIXED /* FIXME */ /* DRIVE_RAMDISK*/ }; static const REQUIREDREGITEM g_RequiredItems[] = @@ -96,27 +93,67 @@ static INT8 GetDriveNumber(PCUITEMID_CHILD pidl) return number < 26 ? number : -1; } -template static T* GetDrivePath(PCUITEMID_CHILD pidl, T *Path) +static INT8 GetDriveNumber(PCWSTR DrivePath) { - int number = GetDriveNumber(pidl); + WORD number = (DrivePath[0] | 32) - 'a'; + return number < 26 ? number : -1; +} + +UINT g_IsFloppyCache = 0; + +static UINT GetCachedDriveType(INT8 DrvNum) +{ + if (DrvNum < 0 || DrvNum >= 26) + return DRIVE_UNKNOWN; + if (g_IsFloppyCache & (1 << DrvNum)) + return DRIVE_REMOVABLE; + WCHAR DrvPath[] = { LOWORD('A' + DrvNum), ':', '\\', '\0' }; + return ::GetDriveTypeW(DrvPath); +} + +static inline UINT GetCachedDriveType(PCWSTR DrivePath) +{ + return GetCachedDriveType(GetDriveNumber(DrivePath)); +} + +static bool IsFloppyDrive(PCWSTR DrivePath) +{ + extern BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot); + INT8 DrvNum = GetDriveNumber(DrivePath); + if (DrvNum < 0) + return false; + if (g_IsFloppyCache & (1 << DrvNum)) + return true; + UINT Type = GetCachedDriveType(DrvNum); + if (Type == DRIVE_REMOVABLE && IsDriveFloppyW(DrivePath)) + { + g_IsFloppyCache |= (1 << DrvNum); + return true; + } + return false; +} + +INT8 GetDrivePath(PCUITEMID_CHILD pidl, PWSTR Path) +{ + INT8 number = GetDriveNumber(pidl); if (number < 0) - return NULL; + return number; Path[0] = 'A' + number; Path[1] = ':'; Path[2] = '\\'; Path[3] = '\0'; - return Path; + return number; } static inline UINT _ILGetRemovableTypeId(LPCITEMIDLIST pidl) { WCHAR buf[8]; - if (GetDrivePath(pidl, buf) && IsDriveFloppyW(buf)) + if (GetDrivePath(pidl, buf) >= 0 && IsFloppyDrive(buf)) return SHDID_COMPUTER_DRIVE35; // TODO: 3.5-inch vs 5.25-inch return SHDID_COMPUTER_REMOVABLE; } -BOOL _ILGetDriveType(LPCITEMIDLIST pidl) +UINT _ILGetDriveType(LPCITEMIDLIST pidl) { WCHAR szDrive[8]; if (!_ILGetDrive(pidl, szDrive, _countof(szDrive))) @@ -124,9 +161,31 @@ BOOL _ILGetDriveType(LPCITEMIDLIST pidl) ERR("pidl %p is not a drive\n", pidl); return DRIVE_UNKNOWN; } - return ::GetDriveTypeW(szDrive); + return GetCachedDriveType(GetDriveNumber(szDrive)); } +static UINT SHELL_GetAutoRunInfPath(PCWSTR DrvPath, PWSTR AriPath, BOOL ForInvoke = FALSE) +{ + INT8 DrvNum = GetDriveNumber(DrvPath); + if (DrvNum < 0 || DrvPath[1] != ':' || (DrvPath[2] && (DrvPath[2] != '\\' || DrvPath[3]))) + return 0; + if (!ForInvoke && IsFloppyDrive(DrvPath)) + return 0; // Don't read label nor icon from floppy + if (GetCachedDriveType(DrvNum) <= DRIVE_NO_ROOT_DIR) + return 0; + return wsprintfW(AriPath, L"%c:\\autorun.inf", DrvPath[0]); +} + +#if 0 // TODO: Call this when the shell is notified about insert disc events +bool SHELL_CanInvokeAutoRunOnDrive(PCWSTR DrvPath) +{ + INT8 DrvNum = GetDriveNumber(DrvPath); + if (DrvNum < 0 || (SHRestricted(REST_NODRIVEAUTORUN) & (1 << DrvNum))) + return false; + return !(SHRestricted(REST_NODRIVETYPEAUTORUN) & (1 << GetCachedDriveType(DrvNum))); +} +#endif + BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Clsid) { // If this function returns true, the item should be hidden in DefView but not in the Explorer folder tree. @@ -255,7 +314,6 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, PIDLIST_ABSOLUTE pidlFolder; PUITEMID_CHILD *apidl; UINT cidl; - UINT nDriveType; DWORD dwFlags; HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); if (FAILED_UNEXPECTEDLY(hr)) @@ -269,7 +327,7 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, _ILFreeaPidl(apidl, cidl); return E_FAIL; } - nDriveType = GetDriveTypeW(szDrive); + UINT nDriveType = GetCachedDriveType(szDrive); if (!GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0)) { if (nDriveType >= DRIVE_REMOTE) @@ -410,22 +468,20 @@ HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, } static HRESULT -getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags, - LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) +getIconLocationForDrive( + _In_ PCWSTR pszDrivePath, + _Out_writes_z_(cchMax) PWSTR szIconFile, + _In_ UINT cchMax, + _Out_ int *piIndex, + _Out_ UINT *pGilOut) { WCHAR wszPath[MAX_PATH]; WCHAR wszAutoRunInfPath[MAX_PATH]; WCHAR wszValue[MAX_PATH], wszTemp[MAX_PATH]; - // get path - if (!ILGetDisplayNameExW(psf, pidl, wszPath, 0)) + if (!SHELL_GetAutoRunInfPath(pszDrivePath, wszAutoRunInfPath)) return E_FAIL; - if (!PathIsDirectoryW(wszPath)) - return E_FAIL; - - // build the full path of autorun.inf - StringCchCopyW(wszAutoRunInfPath, _countof(wszAutoRunInfPath), wszPath); - PathAppendW(wszAutoRunInfPath, L"autorun.inf"); + wcscpy(wszPath, pszDrivePath); // autorun.inf --> wszValue if (GetPrivateProfileStringW(L"autorun", L"icon", NULL, wszValue, _countof(wszValue), @@ -434,7 +490,6 @@ getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags, // wszValue --> wszTemp ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp)); - // parse the icon location *piIndex = PathParseIconLocationW(wszTemp); // wszPath + wszTemp --> wszPath @@ -445,10 +500,8 @@ getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags, // wszPath --> szIconFile GetFullPathNameW(wszPath, cchMax, szIconFile, NULL); - return S_OK; } - return E_FAIL; } @@ -458,19 +511,14 @@ getLabelForDriveFromAutoRun(PCWSTR wszPath, LPWSTR szLabel, UINT cchMax) WCHAR wszAutoRunInfPath[MAX_PATH]; WCHAR wszTemp[MAX_PATH]; - if (!PathIsDirectoryW(wszPath)) + if (!SHELL_GetAutoRunInfPath(wszPath, wszAutoRunInfPath)) return E_FAIL; - StringCchCopyW(wszAutoRunInfPath, _countof(wszAutoRunInfPath), wszPath); - PathAppendW(wszAutoRunInfPath, L"autorun.inf"); - if (GetPrivateProfileStringW(L"autorun", L"label", NULL, wszTemp, _countof(wszTemp), wszAutoRunInfPath) && wszTemp[0] != 0) { - StringCchCopyW(szLabel, cchMax, wszTemp); - return S_OK; + return StringCchCopyW(szLabel, cchMax, wszTemp); } - return E_FAIL; } @@ -487,6 +535,29 @@ static HRESULT GetDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax) return hr == S_OK ? S_OK : GetRawDriveLabel(DrivePath, szLabel, cchMax); } +static bool GetRegCustomizedDriveIcon( + _In_ INT8 DriveNum, + _Out_writes_z_(cchMax) PWSTR szIconFile, + _In_ UINT cchMax, + _Out_ int *piIndex, + _Out_ UINT *pGilOut) +{ + WCHAR szKey[200], chDrv = 'A' + DriveNum; + wsprintfW(szKey, L"%s\\DriveIcons\\%c\\DefaultIcon", REGSTR_PATH_EXPLORER, chDrv); + DWORD cb = cchMax * sizeof(*szIconFile); + DWORD err = RegGetValueW(HKEY_LOCAL_MACHINE, szKey, NULL, RRF_RT_REG_SZ, NULL, szIconFile, &cb); + if (err != ERROR_SUCCESS) + { + cb = cchMax * sizeof(*szIconFile); + wsprintfW(szKey, L"Applications\\Explorer.exe\\Drives\\%c\\DefaultIcon", chDrv); + err = RegGetValueW(HKEY_CLASSES_ROOT, szKey, NULL, RRF_RT_REG_SZ, NULL, szIconFile, &cb); + } + if (err != ERROR_SUCCESS) + return false; + *piIndex = PathParseIconLocationW(szIconFile); + return *szIconFile != UNICODE_NULL; +} + HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) { CComPtr initIcon; @@ -494,67 +565,61 @@ HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl if (FAILED_UNEXPECTEDLY(hr)) return hr; - CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName; - UINT DriveType = GetDriveTypeA(pszDrive); + WCHAR wTemp[MAX_PATH], szDrive[8]; + int icon_idx, reg_idx = 0; + UINT GilOut = 0; + BOOL bFloppy = FALSE; + INT8 DriveNum = GetDrivePath(pidl, szDrive); + UINT DriveType = GetCachedDriveType(DriveNum); if (DriveType > DRIVE_RAMDISK) DriveType = DRIVE_FIXED; - WCHAR wTemp[MAX_PATH]; - int icon_idx, reg_idx; - UINT flags = 0; - switch (DriveType) { - case DRIVE_FIXED: - case DRIVE_UNKNOWN: - reg_idx = IDI_SHELL_DRIVE; + case DRIVE_REMOVABLE: + bFloppy = IsFloppyDrive(szDrive); + reg_idx = bFloppy ? IDI_SHELL_3_14_FLOPPY : IDI_SHELL_REMOVEABLE; break; - case DRIVE_CDROM: - reg_idx = IDI_SHELL_CDROM; + case DRIVE_FIXED: + reg_idx = IDI_SHELL_DRIVE; break; case DRIVE_REMOTE: reg_idx = IDI_SHELL_NETDRIVE; break; - case DRIVE_REMOVABLE: - if (!IsDriveFloppyA(pszDrive)) - reg_idx = IDI_SHELL_REMOVEABLE; - else - reg_idx = IDI_SHELL_3_14_FLOPPY; + case DRIVE_CDROM: + reg_idx = IDI_SHELL_CDROM; break; case DRIVE_RAMDISK: reg_idx = IDI_SHELL_RAMDISK; break; - case DRIVE_NO_ROOT_DIR: - default: - reg_idx = IDI_SHELL_DOCUMENT; - break; } - hr = getIconLocationForDrive(psf, pidl, 0, wTemp, _countof(wTemp), - &icon_idx, &flags); + hr = getIconLocationForDrive(szDrive, wTemp, _countof(wTemp), + &icon_idx, &GilOut); if (SUCCEEDED(hr)) { initIcon->SetNormalIcon(wTemp, icon_idx); } - else if (HLM_GetIconW(reg_idx - 1, wTemp, _countof(wTemp), &icon_idx)) + else if (DriveType > DRIVE_NO_ROOT_DIR && + GetRegCustomizedDriveIcon(DriveNum, wTemp, _countof(wTemp), &icon_idx, &GilOut)) { initIcon->SetNormalIcon(wTemp, icon_idx); } - else if ((DriveType == DRIVE_FIXED || DriveType == DRIVE_UNKNOWN) && - (HCR_GetIconW(L"Drive", wTemp, NULL, _countof(wTemp), &icon_idx))) + else if (reg_idx && HLM_GetIconW(reg_idx - 1, wTemp, _countof(wTemp), &icon_idx)) + { + initIcon->SetNormalIcon(wTemp, icon_idx); + } + else if (DriveType == DRIVE_FIXED && + HCR_GetIconW(L"Drive", wTemp, NULL, _countof(wTemp), &icon_idx)) { initIcon->SetNormalIcon(wTemp, icon_idx); } else { - if (DriveType == DRIVE_REMOVABLE && !IsDriveFloppyA(pszDrive)) - { - icon_idx = IDI_SHELL_REMOVEABLE; - } + if (DriveType == DRIVE_REMOVABLE && bFloppy) + icon_idx = IDI_SHELL_3_14_FLOPPY; else - { icon_idx = iDriveIconIds[DriveType]; - } initIcon->SetNormalIcon(swShell32Name, -icon_idx); } @@ -1016,7 +1081,7 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla { return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet); } - else if (!GetDrivePath(pidl, szDrive)) + else if (GetDrivePath(pidl, szDrive) < 0) { ERR("Wrong pidl type\n"); return E_INVALIDARG; @@ -1044,7 +1109,7 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla BOOL bAllFirst = m_DriveDisplayMode == 4; PWSTR pszLabel = pszPath; - if (!bNoLetter && (bAllFirst || (bRemoteFirst && GetDriveTypeW(szDrive) == DRIVE_REMOTE))) + if (!bNoLetter && (bAllFirst || (bRemoteFirst && GetCachedDriveType(szDrive) == DRIVE_REMOTE))) { bNoLetter = TRUE; // Handling the letter now, don't append it again later if (!bEditLabel) @@ -1053,17 +1118,15 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla if (GetDriveLabel(szDrive, pszLabel, MAX_PATH - 7) != S_OK && !bEditLabel) { - UINT ResourceId = 0; - switch (GetDriveTypeW(szDrive)) + UINT ResId = 0, DrvType = GetCachedDriveType(szDrive); + if (DrvType == DRIVE_REMOVABLE) + ResId = IsFloppyDrive(szDrive) ? IDS_DRIVE_FLOPPY : IDS_DRIVE_REMOVABLE; + else if (DrvType < _countof(iDriveTypeIds)) + ResId = iDriveTypeIds[DrvType]; + + if (ResId) { - case DRIVE_REMOVABLE: ResourceId = IDS_DRIVE_REMOVABLE; break; // TODO: Floppy (cached) - case DRIVE_FIXED: ResourceId = IDS_DRIVE_FIXED; break; - case DRIVE_REMOTE: ResourceId = IDS_DRIVE_NETWORK; break; - case DRIVE_CDROM: ResourceId = IDS_DRIVE_CDROM; break; - } - if (ResourceId) - { - UINT len = LoadStringW(shell32_hInstance, ResourceId, pszLabel, MAX_PATH - 7); + UINT len = LoadStringW(shell32_hInstance, ResId, pszLabel, MAX_PATH - 7); if (len > MAX_PATH - 7) pszLabel[MAX_PATH-7] = UNICODE_NULL; } @@ -1106,7 +1169,7 @@ HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, if (_ILIsDrive(pidl)) { WCHAR szDrive[8]; - HRESULT hr = GetDrivePath(pidl, szDrive) ? SetDriveLabel(hwndOwner, szDrive, lpName) : E_FAIL; + HRESULT hr = GetDrivePath(pidl, szDrive) >= 0 ? SetDriveLabel(hwndOwner, szDrive, lpName) : E_FAIL; if (pPidlOut) *pPidlOut = SUCCEEDED(hr) ? _ILCreateDrive(szDrive) : NULL; return hr; @@ -1220,8 +1283,9 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S else { ULARGE_INTEGER ulTotalBytes, ulFreeBytes; - CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName; - UINT DriveType = GetDriveTypeA(pszDrive); + WCHAR szDrive[8]; + INT8 DriveNum = GetDrivePath(pidl, szDrive); + UINT DriveType = GetCachedDriveType(DriveNum); if (DriveType > DRIVE_RAMDISK) DriveType = DRIVE_FIXED; @@ -1231,8 +1295,10 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str); break; case IDS_SHV_COLUMN_TYPE: - if (DriveType == DRIVE_REMOVABLE && !IsDriveFloppyA(pszDrive)) - hr = SHSetStrRet(&psd->str, IDS_DRIVE_REMOVABLE); + if (DriveType == DRIVE_UNKNOWN) + hr = SHSetStrRetEmpty(&psd->str); + else if (DriveType == DRIVE_REMOVABLE && IsFloppyDrive(szDrive)) + hr = SHSetStrRet(&psd->str, IDS_DRIVE_FLOPPY); else hr = SHSetStrRet(&psd->str, iDriveTypeIds[DriveType]); break; @@ -1240,9 +1306,9 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S case IDS_SHV_COLUMN_DISK_AVAILABLE: psd->str.cStr[0] = 0x00; psd->str.uType = STRRET_CSTR; - if (GetVolumeInformationA(pszDrive, NULL, 0, NULL, NULL, NULL, NULL, 0)) + if (GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, NULL, NULL, 0)) { - GetDiskFreeSpaceExA(pszDrive, &ulFreeBytes, &ulTotalBytes, NULL); + GetDiskFreeSpaceExW(szDrive, &ulFreeBytes, &ulTotalBytes, NULL); if (iColumn == 2) StrFormatByteSize64A(ulTotalBytes.QuadPart, psd->str.cStr, MAX_PATH); else @@ -1251,7 +1317,7 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S hr = S_OK; break; case IDS_SHV_COLUMN_COMMENTS: - hr = SHSetStrRet(&psd->str, ""); /* FIXME: comments */ + hr = SHSetStrRetEmpty(&psd->str); /* FIXME: comments */ break; DEFAULT_UNREACHABLE; } @@ -1329,10 +1395,15 @@ STDMETHODIMP CDrivesFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam case SFVM_FSNOTIFY: if (lParam == SHCNE_DRIVEADD && wParam) { + g_IsFloppyCache = 0; INT8 drive = GetDriveNumber(((PIDLIST_ABSOLUTE*)wParam)[0]); if (drive >= 0 && ((1UL << drive) & SHRestricted(REST_NODRIVES))) return S_FALSE; } + else if (lParam == SHCNE_DRIVEREMOVED) + { + g_IsFloppyCache = 0; + } break; } return E_NOTIMPL;