[win32] Fix handling of CD-ROM drives.

RomDataFactory::T_create(): Check if the filename is a drive letter.

IRpFile: Move IsDriveLetter*() and related from RpFile_win32.cpp to
IRpFile.hpp, #ifdef'd for Windows only.

CD-ROM drive volume roots can now be handled by rom-properties again.

This broke when support for Wii U Packages was added, since devices are
also considered root directories, so the directory check was done instead
of the device check.

Affects: v2.4 - v2.4.1
This commit is contained in:
David Korth 2025-03-13 19:31:24 -04:00
parent 41409a5de5
commit be23ac0dc4
4 changed files with 42 additions and 17 deletions

View File

@ -32,7 +32,7 @@
* Also fix a bad bounds check that broke the Exports table on these DLLs.
* Pull request: #438
* Submitted by @DankRank.
* Windows: Properly rescale the icon and banner sizes.
* Windows: Properly rescale the icon and banner sizes.
* PSP Minis would show a giant banner that messes up the tab display.
* Fixes #433: [Bug Report] The ROM type is not displayed correctly for some PSP Mini ROMs
* Reported by @xxmichibxx.
@ -52,6 +52,11 @@
* Xbox360_STFS: Fix reading XEXes that overlap a hash block boundary.
* NOTE: The entire XEX is now read into memory, which may cause slowdown.
This will be improved later.
* Windows: Fix handling of CD-ROM drives.
* This broke when support for Wii U Packages was added, since devices are
also considered root directories, so the directory check was done instead
of the device check.
* Affects: v2.4 - v2.4.1
* Other changes:
* CMake: Added an ENABLE_NETWORKING option to control whether or not

View File

@ -991,12 +991,29 @@ RomDataPtr create(const IRpFilePtr &file, unsigned int attrs)
template<typename CharType>
static RomDataPtr T_create(const CharType *filename, unsigned int attrs)
{
#ifdef _WIN32
// If this is a drive letter, try handling it as a file first.
if (T_IsDriveLetter(filename[0]) && filename[1] == L':' &&
(filename[2] == '\0' || (filename[2] == '\\' && filename[3] == '\0')))
{
// It's a drive letter. (volume root)
const CharType drvfilename[4] = {filename[0], ':', '\\', '\0'};
IRpFilePtr file = std::make_shared<RpFile>(filename, RpFile::FM_OPEN_READ_GZ);
if (file->isOpen()) {
RomDataPtr romData = create(file, attrs);
if (romData) {
return romData;
}
}
}
#endif /* _WIN32 */
// Check if this is a file or a directory.
// If it's a file, we'll create an RpFile and then
// call create(IRpFile*,unsigned int).
if (likely(!FileSystem::is_directory(filename))) {
// Not a directory.
shared_ptr<RpFile> file = std::make_shared<RpFile>(filename, RpFile::FM_OPEN_READ_GZ);
IRpFilePtr file = std::make_shared<RpFile>(filename, RpFile::FM_OPEN_READ_GZ);
if (file->isOpen()) {
return create(file, attrs);
}

View File

@ -27,6 +27,23 @@
namespace LibRpFile {
#ifdef _WIN32
template<typename CharType>
static inline constexpr bool T_IsDriveLetter(CharType letter)
{
return (letter >= (CharType)'A') && (letter <= (CharType)'Z');
}
static inline constexpr bool IsDriveLetterA(char letter)
{
return T_IsDriveLetter(letter);
}
static inline constexpr bool IsDriveLetterW(wchar_t letter)
{
return T_IsDriveLetter(letter);
}
#endif /* _WIN32 */
class RP_LIBROMDATA_PUBLIC NOVTABLE IRpFile
{
protected:

View File

@ -2,7 +2,7 @@
* ROM Properties Page shell extension. (librpfile) *
* RpFile_win32.cpp: Standard file object. (Win32 implementation) *
* *
* Copyright (c) 2016-2024 by David Korth. *
* Copyright (c) 2016-2025 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
@ -33,20 +33,6 @@ using std::wstring;
#include "libwin32common/DelayLoadHelper.h"
#endif /* _MSC_VER */
static inline constexpr bool IsDriveLetterA(char letter)
{
return (letter >= 'A') && (letter <= 'Z');
}
static inline constexpr bool IsDriveLetterW(wchar_t letter)
{
return (letter >= L'A') && (letter <= L'Z');
}
#ifdef _UNICODE
# define IsDriveLetter(x) IsDriveLetterW(x)
#else /* !_UNICODE */
# define IsDriveLetter(x) IsDriveLetterA(x)
#endif /* _UNICODE */
namespace LibRpFile {
#ifdef _MSC_VER