WIN32: Make Win32AudioCDManager UNICODE compatible

This commit is contained in:
sluicebox 2021-06-02 13:58:18 -06:00
parent eda2cc6b71
commit d9df1919d5
4 changed files with 39 additions and 26 deletions

View File

@ -52,6 +52,7 @@
#include "audio/audiostream.h"
#include "backends/audiocd/audiocd-stream.h"
#include "backends/audiocd/default/default-audiocd.h"
#include "backends/platform/sdl/win32/win32_wrapper.h"
#include "common/array.h"
#include "common/config-manager.h"
#include "common/debug.h"
@ -197,7 +198,9 @@ bool Win32AudioCDManager::openCD(int drive) {
// Construct the drive path and try to open it
Common::String drivePath = Common::String::format("\\\\.\\%c:", drives[drive]);
_driveHandle = CreateFileA(drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
TCHAR *tDrivePath = Win32::stringToTchar(drivePath);
_driveHandle = CreateFile(tDrivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
free(tDrivePath);
if (_driveHandle == INVALID_HANDLE_VALUE) {
warning("Failed to open drive %c:\\, error %d", drives[drive], (int)GetLastError());
return false;
@ -228,7 +231,9 @@ bool Win32AudioCDManager::openCD(const Common::String &drive) {
// Construct the drive path and try to open it
Common::String drivePath = Common::String::format("\\\\.\\%c:", drives[0]);
_driveHandle = CreateFileA(drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
TCHAR *tDrivePath = Win32::stringToTchar(drivePath);
_driveHandle = CreateFile(tDrivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
free(tDrivePath);
if (_driveHandle == INVALID_HANDLE_VALUE) {
warning("Failed to open drive %c:\\, error %d", drives[0], (int)GetLastError());
return false;
@ -355,8 +360,10 @@ Win32AudioCDManager::DriveList Win32AudioCDManager::detectDrives() {
char gameDrive = 0;
if (ConfMan.hasKey("path")) {
Common::String gamePath = ConfMan.get("path");
char fullPath[MAX_PATH];
DWORD result = GetFullPathNameA(gamePath.c_str(), sizeof(fullPath), fullPath, 0);
TCHAR *tGamePath = Win32::stringToTchar(gamePath);
TCHAR fullPath[MAX_PATH];
DWORD result = GetFullPathName(tGamePath, MAX_PATH, fullPath, 0);
free(tGamePath);
if (result > 0 && result < sizeof(fullPath) && Common::isAlpha(fullPath[0]) && fullPath[1] == ':' && tryAddDrive(toupper(fullPath[0]), drives))
gameDrive = drives[0];
@ -371,11 +378,9 @@ Win32AudioCDManager::DriveList Win32AudioCDManager::detectDrives() {
}
bool Win32AudioCDManager::tryAddDrive(char drive, DriveList &drives) {
Common::String drivePath = Common::String::format("%c:\\", drive);
// Ensure it's an actual CD drive
if (GetDriveTypeA(drivePath.c_str()) != DRIVE_CDROM)
if (!Win32::isDriveCD(drive)) {
return false;
}
debug(2, "Detected drive %c:\\ as a CD drive", drive);
drives.push_back(drive);

View File

@ -86,6 +86,13 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion) {
return VerifyVersionInfoFunc(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
}
bool isDriveCD(char driveLetter) {
TCHAR drivePath[] = TEXT("x:\\");
drivePath[0] = (TCHAR)driveLetter;
return (GetDriveType(drivePath) == DRIVE_CDROM);
}
wchar_t *ansiToUnicode(const char *s) {
#ifndef UNICODE
uint codePage = CP_ACP;

View File

@ -39,6 +39,14 @@ namespace Win32 {
* @param minorVersion The minor version number (0.x)
*/
bool confirmWindowsVersion(int majorVersion, int minorVersion);
/**
* Returns true if the drive letter is a CDROM
*
* @param driveLetter The drive letter to test
*/
bool isDriveCD(char driveLetter);
/**
* Converts a C string into a Windows wide-character string.
* Used to interact with Win32 Unicode APIs with no ANSI fallback.

View File

@ -20,12 +20,10 @@
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_getcwd
#if defined(WIN32) && !defined(__SYMBIAN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <direct.h>
#include "backends/platform/sdl/win32/win32_wrapper.h"
#endif
#include "engines/engine.h"
@ -483,26 +481,21 @@ void Engine::checkCD() {
// If we can find a compressed audio track, then it should be ok even
// if it's running from CD.
char buffer[MAX_PATH];
int i;
char driveLetter;
const Common::FSNode gameDataDir(ConfMan.get("path"));
if (gameDataDir.getPath().empty()) {
if (!gameDataDir.getPath().empty()) {
driveLetter = gameDataDir.getPath()[0];
} else {
// That's it! I give up!
if (getcwd(buffer, MAX_PATH) == NULL)
Common::FSNode currentDir(".");
if (!currentDir.getPath().empty()) {
driveLetter = currentDir.getPath()[0];
} else {
return;
} else
Common::strlcpy(buffer, gameDataDir.getPath().c_str(), sizeof(buffer));
for (i = 0; i < MAX_PATH - 1; i++) {
if (buffer[i] == '\\')
break;
}
}
buffer[i + 1] = 0;
if (GetDriveType(buffer) == DRIVE_CDROM) {
if (Win32::isDriveCD(driveLetter)) {
GUI::MessageDialog dialog(
_("You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"