Merge pull request #2254 from RadWolfie/cleanup-emufile

Small Clean Up Portion of EmuFile Usage
This commit is contained in:
ergo720 2021-07-05 11:25:01 +02:00 committed by GitHub
commit 6e68433dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 72 deletions

View File

@ -95,9 +95,6 @@ char szFolder_CxbxReloadedData[MAX_PATH] = { 0 };
char szFilePath_EEPROM_bin[MAX_PATH] = { 0 };
char szFilePath_Xbe[xbox::max_path*2] = { 0 }; // NOTE: LAUNCH_DATA_HEADER's szLaunchPath is xbox::max_path*2 = 520
std::string CxbxBasePath;
std::string MuBasePath;
HANDLE CxbxBasePathHandle;
Xbe* CxbxKrnl_Xbe = NULL;
bool g_bIsChihiro = false;
bool g_bIsDebug = false;
@ -1431,17 +1428,18 @@ __declspec(noreturn) void CxbxKrnlInit
// Initialize devices :
{
char szBuffer[sizeof(szFilePath_Xbe)];
g_EmuShared->GetStorageLocation(szBuffer);
char cxbxr_data_path[sizeof(szFilePath_Xbe)];
g_EmuShared->GetStorageLocation(cxbxr_data_path);
MuBasePath = std::string(szBuffer) + "\\EmuMu";
CxbxBasePath = std::string(szBuffer) + "\\EmuDisk";
CxbxResolveHostToFullPath(CxbxBasePath, "Cxbx-Reloaded's EmuDisk directory");
CxbxResolveHostToFullPath(MuBasePath, "Cxbx-Reloaded's EmuMu directory");
g_DiskBasePath = std::string(cxbxr_data_path) + "\\EmuDisk";
g_MuBasePath = std::string(cxbxr_data_path) + "\\EmuMu";
CxbxResolveHostToFullPath(g_DiskBasePath, "Cxbx-Reloaded's EmuDisk directory");
CxbxResolveHostToFullPath(g_MuBasePath, "Cxbx-Reloaded's EmuMu directory");
// Since canonical always remove the extra slash, we need to manually add it back.
// TODO: Once CxbxBasePath is filesystem::path, replace CxbxBasePath's + operators to / for include path separator internally.
CxbxBasePath = std::filesystem::path(CxbxBasePath).append("").string();
MuBasePath = std::filesystem::path(MuBasePath).append("").string();
// TODO: Once g_DiskBasePath is filesystem::path, replace g_DiskBasePath's + operators to / for include path separator internally.
g_DiskBasePath = std::filesystem::path(g_DiskBasePath).append("").string();
g_MuBasePath = std::filesystem::path(g_MuBasePath).append("").string();
// NOTE: Do NOT modify global variables above after this point!
}
// Determine xbe path
@ -1471,9 +1469,9 @@ __declspec(noreturn) void CxbxKrnlInit
}
CxbxResolveHostToFullPath(relative_path, "xbe's directory");
CxbxBasePathHandle = CreateFile(CxbxBasePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
g_DiskBasePathHandle = CreateFile(g_DiskBasePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
int CxbxCdrom0DeviceIndex = -1;
bool isEmuDisk = _strnicmp(relative_path.c_str(), CxbxBasePath.c_str(), CxbxBasePath.size() - 1) == 0;
bool isEmuDisk = CxbxrIsPathInsideEmuDisk(relative_path);
// Check if title mounth path is already set. This may occur from early boot of Chihiro title.
char title_mount_path[sizeof(szFilePath_Xbe)];
const char* p_default_mount_path = title_mount_path;
@ -1489,6 +1487,7 @@ __declspec(noreturn) void CxbxKrnlInit
// TODO: Find a place to make permanent placement for DeviceCdrom0 that does not have disc loaded.
if (p_default_mount_path[0] != '\0') {
// NOTE: Don't need to perform CxbxResolveHostToFullPath again for p_default_mount_path.
CxbxCdrom0DeviceIndex = CxbxRegisterDeviceHostPath(DeviceCdrom0, p_default_mount_path);
// Since Chihiro also map Mbfs to the same path as Cdrom0, we'll map it the same way.
if (g_bIsChihiro) {
@ -1497,31 +1496,31 @@ __declspec(noreturn) void CxbxKrnlInit
}
// Partition 0 contains configuration data, and is accessed as a native file, instead as a folder :
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition0, CxbxBasePath + "Partition0", /*IsFile=*/true);
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition0, g_DiskBasePath + "Partition0", /*IsFile=*/true);
// The first two partitions are for Data and Shell files, respectively :
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition1, CxbxBasePath + "Partition1");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition2, CxbxBasePath + "Partition2");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition1, g_DiskBasePath + "Partition1");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition2, g_DiskBasePath + "Partition2");
// The following partitions are for caching purposes - for now we allocate up to 7 (as xbmp needs that many) :
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition3, CxbxBasePath + "Partition3");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition4, CxbxBasePath + "Partition4");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition5, CxbxBasePath + "Partition5");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition6, CxbxBasePath + "Partition6");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition7, CxbxBasePath + "Partition7");
CxbxRegisterDeviceHostPath(DevicePrefix + "\\Chihiro", CxbxBasePath + "Chihiro");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition3, g_DiskBasePath + "Partition3");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition4, g_DiskBasePath + "Partition4");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition5, g_DiskBasePath + "Partition5");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition6, g_DiskBasePath + "Partition6");
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition7, g_DiskBasePath + "Partition7");
CxbxRegisterDeviceHostPath(DevicePrefix + "\\Chihiro", g_DiskBasePath + "Chihiro");
// Create the MU directories and the bin files
CxbxRegisterDeviceHostPath(DeviceMU0, MuBasePath + "F", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU1, MuBasePath + "G", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU2, MuBasePath + "H", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU3, MuBasePath + "I", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU4, MuBasePath + "J", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU5, MuBasePath + "K", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU6, MuBasePath + "L", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU7, MuBasePath + "M", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU0, g_MuBasePath + "F", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU1, g_MuBasePath + "G", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU2, g_MuBasePath + "H", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU3, g_MuBasePath + "I", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU4, g_MuBasePath + "J", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU5, g_MuBasePath + "K", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU6, g_MuBasePath + "L", false, sizeof(FATX_SUPERBLOCK));
CxbxRegisterDeviceHostPath(DeviceMU7, g_MuBasePath + "M", false, sizeof(FATX_SUPERBLOCK));
std::mbstate_t ps = std::mbstate_t();
const char *src = MuBasePath.c_str();
std::wstring wMuBasePath(MuBasePath.size(), L'0');
const char *src = g_MuBasePath.c_str();
std::wstring wMuBasePath(g_MuBasePath.size(), L'0');
std::mbsrtowcs(wMuBasePath.data(), &src, wMuBasePath.size(), &ps);
g_io_mu_metadata = new io_mu_metadata(wMuBasePath);

View File

@ -49,6 +49,10 @@
// partition emulation directory handles
HANDLE g_hCurDir_hack = NULL; // HACK: We should not be depending on this variable. Instead, we should fix/implement Ob/Io objects such as IoCreateDevice.
HANDLE g_DiskBasePathHandle;
std::string g_DiskBasePath;
std::string g_MuBasePath;
// Default Xbox Partition Table
#define PE_PARTFLAGS_IN_USE 0x80000000
#define XBOX_SWAPPART1_LBA_START 0x400
@ -157,23 +161,44 @@ void io_mu_metadata::flush(const wchar_t lett)
ofs.flush();
}
// NOTE: root_path input must already had called canonical function for optimization purpose.
static bool CxbxrIsPathInsideRootPath(const std::filesystem::path& path, const std::filesystem::path& root_path)
{
std::error_code rootError, finalError;
const std::filesystem::path rootPath = std::filesystem::canonical(root_path, rootError); // TODO: Replace rootPath to root_path when possible.
const std::filesystem::path finalPath = std::filesystem::canonical(path, finalError);
if (rootError || finalError) {
return false;
}
auto match = std::mismatch(rootPath.begin(), rootPath.end(), finalPath.begin(), finalPath.end());
return match.first == rootPath.end();
}
bool CxbxrIsPathInsideEmuDisk(const std::filesystem::path& path)
{
return CxbxrIsPathInsideRootPath(path, g_DiskBasePath);
}
static bool CxbxrIsPathInsideEmuMu(const std::filesystem::path& path)
{
return CxbxrIsPathInsideRootPath(path, g_MuBasePath);
}
DeviceType CxbxrGetDeviceTypeFromHandle(HANDLE hFile)
{
const std::wstring path = CxbxGetFinalPathNameByHandle(hFile);
const std::filesystem::path path = CxbxGetFinalPathNameByHandle(hFile);
size_t pos = path.rfind(L"\\EmuDisk\\Partition");
if (pos != std::string::npos) {
if (CxbxrIsPathInsideEmuDisk(path)) {
return DeviceType::Harddisk0;
}
pos = path.rfind(L"\\EmuMu");
if (pos != std::string::npos) {
if (CxbxrIsPathInsideEmuMu(path)) {
return DeviceType::MU;
}
EmuDirPath hybrid_path;
FindEmuDirPathByDevice(DeviceCdrom0, hybrid_path);
if (hybrid_path.HostDirPath != "") {
if (!hybrid_path.HostDirPath.empty() && CxbxrIsPathInsideRootPath(path, hybrid_path.HostDirPath)) {
return DeviceType::Cdrom0;
}
@ -202,9 +227,9 @@ void CxbxCreatePartitionHeaderFile(std::string filename, bool partition0 = false
XboxPartitionTable CxbxGetPartitionTable()
{
XboxPartitionTable table;
FILE* fp = fopen((CxbxBasePath + "Partition0.bin").c_str(), "rb");
FILE* fp = fopen((g_DiskBasePath + "Partition0.bin").c_str(), "rb");
if (fp == nullptr) {
CxbxKrnlCleanup("CxbxGetPartitionTable Failed:\nUnable to open file: %s", (CxbxBasePath + "Partition0.bin").c_str());
CxbxKrnlCleanup("CxbxGetPartitionTable Failed:\nUnable to open file: %s", (g_DiskBasePath + "Partition0.bin").c_str());
}
fread(&table, sizeof(XboxPartitionTable), 1, fp);
@ -215,8 +240,8 @@ XboxPartitionTable CxbxGetPartitionTable()
// Or invalid partition tables left behind from previous versions
// of Cxbx-Reloaded
if (memcmp(table.Magic, BackupPartTbl.Magic, 16) != 0) {
DeleteFile((CxbxBasePath + "Partition0.bin").c_str());
CxbxCreatePartitionHeaderFile(CxbxBasePath + "Partition0.bin", true);
DeleteFile((g_DiskBasePath + "Partition0.bin").c_str());
CxbxCreatePartitionHeaderFile(g_DiskBasePath + "Partition0.bin", true);
memcpy(&table, &BackupPartTbl, sizeof(XboxPartitionTable));
}
@ -228,7 +253,7 @@ FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber)
FATX_SUPERBLOCK superblock;
std::stringstream ss;
ss << CxbxBasePath << "Partition" << partitionNumber << ".bin";
ss << g_DiskBasePath << "Partition" << partitionNumber << ".bin";
FILE* fp = fopen(ss.str().c_str(), "rb");
fread(&superblock, sizeof(FATX_SUPERBLOCK), 1, fp);
fclose(fp);
@ -256,19 +281,6 @@ std::wstring CxbxGetFinalPathNameByHandle(HANDLE hFile)
return path;
}
static bool CxbxIsPathInsideEmuDisk(const std::filesystem::path& path)
{
std::error_code rootError, finalError;
const std::filesystem::path rootPath = std::filesystem::canonical(CxbxBasePath, rootError);
const std::filesystem::path finalPath = std::filesystem::canonical(path, finalError);
if (rootError || finalError) {
return false;
}
auto match = std::mismatch(rootPath.begin(), rootPath.end(), finalPath.begin(), finalPath.end());
return match.first == rootPath.end();
}
static int CxbxGetPartitionNumber(const std::wstring_view path)
{
const std::wstring_view partitionString = L"\\EmuDisk\\Partition";
@ -314,7 +326,7 @@ void CxbxFormatPartitionByHandle(HANDLE hFile)
const std::filesystem::path partitionPath = CxbxGetPartitionDataPathFromHandle(hFile);
// Sanity check, make sure we are actually deleting something within the Cxbx-Reloaded folder
if (!CxbxIsPathInsideEmuDisk(partitionPath)) {
if (!CxbxrIsPathInsideEmuDisk(partitionPath)) {
EmuLog(LOG_LEVEL::WARNING, "Attempting to format a path that is not within a Cxbx-Reloaded data folder... Ignoring!\n");
return;
}
@ -539,16 +551,16 @@ NTSTATUS CxbxConvertFilePath(
if (RelativePath.compare(0, DrivePrefix.length(), DrivePrefix.c_str()) == 0)
RelativePath.erase(0, 4);
// Check if we where called from a File-handling API :
// Check if we were called from a File-handling API :
if (!aFileAPIName.empty()) {
if (RelativePath.compare(DriveMbrom0) == 0) {
*RootDirectory = CxbxBasePathHandle;
HostPath = CxbxBasePath;
*RootDirectory = g_DiskBasePathHandle;
HostPath = g_DiskBasePath;
RelativePath = MediaBoardSegaBoot0;
}
else if (RelativePath.compare(DriveMbrom1) == 0) {
*RootDirectory = CxbxBasePathHandle;
HostPath = CxbxBasePath;
*RootDirectory = g_DiskBasePathHandle;
HostPath = g_DiskBasePath;
RelativePath = MediaBoardSegaBoot1;
}
else if (!partitionHeader) {
@ -607,8 +619,8 @@ NTSTATUS CxbxConvertFilePath(
// Remove Harddisk0 prefix, in the hope that the remaining path might work :
RelativePath.erase(0, DeviceHarddisk0.length() + 1);
// And set Root to the folder containing the partition-folders :
*RootDirectory = CxbxBasePathHandle;
HostPath = CxbxBasePath;
*RootDirectory = g_DiskBasePathHandle;
HostPath = g_DiskBasePath;
}
// NOTE: RootDirectory cannot be ignored.
// Any special handling for it should be done below.
@ -650,8 +662,8 @@ NTSTATUS CxbxConvertFilePath(
*RootDirectory = find_path.HostDirHandle;
}
} else {
*RootDirectory = CxbxBasePathHandle;
HostPath = CxbxBasePath;
*RootDirectory = g_DiskBasePathHandle;
HostPath = g_DiskBasePath;
RelativePath = RelativeXboxPath.substr(DeviceHarddisk0.length()) + ".bin";
}
@ -669,8 +681,8 @@ NTSTATUS CxbxConvertFilePath(
if (g_bPrintfOn) {
EmuLog(LOG_LEVEL::DEBUG, "%s Corrected path...", aFileAPIName.c_str());
EmuLog(LOG_LEVEL::DEBUG, " Org:\"%s\"", OriginalPath.c_str());
if (_strnicmp(HostPath.c_str(), CxbxBasePath.c_str(), CxbxBasePath.length()) == 0) {
EmuLog(LOG_LEVEL::DEBUG, " New:\"$CxbxPath\\%s%s\"", (HostPath.substr(CxbxBasePath.length(), std::string::npos)).c_str(), RelativePath.c_str());
if (_strnicmp(HostPath.c_str(), g_DiskBasePath.c_str(), g_DiskBasePath.length()) == 0) {
EmuLog(LOG_LEVEL::DEBUG, " New:\"$CxbxPath\\%s%s\"", (HostPath.substr(g_DiskBasePath.length(), std::string::npos)).c_str(), RelativePath.c_str());
}
else
EmuLog(LOG_LEVEL::DEBUG, " New:\"$XbePath\\%s\"", RelativePath.c_str());

View File

@ -119,8 +119,9 @@ inline constexpr xbox::ulong_xt fsctl_read_fatx_metadata = 0x0009411C;
inline constexpr xbox::ulong_xt fsctl_write_fatx_metadata = 0x00098120;
inline constexpr std::size_t mu_max_name_lenght = 32 * sizeof(xbox::wchar_xt); // MU names are in wide chars
extern std::string CxbxBasePath;
extern HANDLE CxbxBasePathHandle;
extern std::string g_DiskBasePath;
extern std::string g_MuBasePath;
extern HANDLE g_DiskBasePathHandle;
const size_t XboxFileInfoStructSizes[xbox::FileMaximumInformation] = {
0, // (index 0)
@ -277,6 +278,7 @@ int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath);
XboxDevice* CxbxDeviceByDevicePath(const std::string_view XboxDevicePath);
XboxDevice* CxbxDeviceByHostPath(const std::string_view HostPath);
std::string CxbxConvertXboxToHostPath(const std::string_view XboxDevicePath);
bool CxbxrIsPathInsideEmuDisk(const std::filesystem::path& path);
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDriveLetter(const char DriveLetter);