kernel: implement title mount path
This commit is contained in:
parent
c808cf2834
commit
8445a02998
|
@ -100,7 +100,7 @@ public:
|
|||
unsigned int FlagsLLE;
|
||||
DebugMode KrnlDebugMode;
|
||||
char szKrnlDebug[MAX_PATH] = "";
|
||||
char szStorageLocation[MAX_PATH] = "";
|
||||
char szStorageLocation[xbox::max_path] = "";
|
||||
unsigned int LoggedModules[NUM_INTEGERS_LOG];
|
||||
int LogLevel = 1;
|
||||
bool bUseLoaderExec;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "Mutex.h"
|
||||
#include "common\IPCHybrid.hpp"
|
||||
#include "common\input\Button.h"
|
||||
#include "common/xbox_types.h"
|
||||
#include "CxbxVersion.h"
|
||||
#include "core/common/imgui/settings.h"
|
||||
#include <memory.h>
|
||||
|
@ -245,8 +246,8 @@ class EmuShared : public Mutex
|
|||
// ******************************************************************
|
||||
// * File storage location
|
||||
// ******************************************************************
|
||||
void GetStorageLocation(char *path) { Lock(); strncpy(path, m_core.szStorageLocation, MAX_PATH); Unlock(); }
|
||||
void SetStorageLocation(const char *path) { Lock(); strncpy(m_core.szStorageLocation, path, MAX_PATH); Unlock(); }
|
||||
void GetStorageLocation(char *path) { Lock(); strncpy(path, m_core.szStorageLocation, xbox::max_path); Unlock(); }
|
||||
void SetStorageLocation(const char *path) { Lock(); strncpy(m_core.szStorageLocation, path, xbox::max_path); Unlock(); }
|
||||
|
||||
// ******************************************************************
|
||||
// * ClipCursor flag Accessors
|
||||
|
@ -301,6 +302,22 @@ class EmuShared : public Mutex
|
|||
Unlock();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * TitleMountPath Accessor
|
||||
// ******************************************************************
|
||||
void GetTitleMountPath(char *value)
|
||||
{
|
||||
Lock();
|
||||
std::strncpy(value, m_TitleMountPath, sizeof(m_TitleMountPath));
|
||||
Unlock();
|
||||
}
|
||||
void SetTitleMountPath(const char* value)
|
||||
{
|
||||
Lock();
|
||||
std::strncpy(m_TitleMountPath, value, sizeof(m_TitleMountPath) - 1);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * Reset specific variables to default for kernel mode.
|
||||
// ******************************************************************
|
||||
|
@ -351,6 +368,7 @@ class EmuShared : public Mutex
|
|||
int m_DeviceType[4];
|
||||
char m_DeviceControlNames[4][HIGHEST_NUM_BUTTONS][HOST_BUTTON_NAME_LENGTH];
|
||||
char m_DeviceName[4][50];
|
||||
char m_TitleMountPath[xbox::max_path];
|
||||
|
||||
// Settings class in memory should not be tampered by third-party.
|
||||
// Third-party program should only be allow to edit settings.ini file.
|
||||
|
|
|
@ -133,4 +133,9 @@ namespace xbox
|
|||
// ******************************************************************
|
||||
static_assert(CHAR_BIT == 8);
|
||||
static_assert(sizeof(char16_t) == 2);
|
||||
|
||||
// ******************************************************************
|
||||
// Defines
|
||||
// ******************************************************************
|
||||
constexpr uint_xt max_path{ 260 }; // Xbox file path max limitation
|
||||
}
|
||||
|
|
|
@ -958,7 +958,7 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XLaunchNewImageA)
|
|||
if (lpTitlePath == xbox::zeroptr)
|
||||
{
|
||||
// If no path is specified, then the xbe is rebooting to dashboard
|
||||
char szDashboardPath[MAX_PATH] = { 0 };
|
||||
char szDashboardPath[xbox::max_path] = { 0 };
|
||||
XboxDevice* rootDevice = CxbxDeviceByDevicePath(DeviceHarddisk0Partition2);
|
||||
if (rootDevice != nullptr)
|
||||
sprintf(szDashboardPath, "%s\\xboxdash.xbe", rootDevice->HostDevicePath.c_str());
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// ******************************************************************
|
||||
|
||||
#define LOG_PREFIX CXBXR_MODULE::HAL
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
#include <core\kernel\exports\xboxkrnl.h> // For HalReadSMCTrayState, etc.
|
||||
#include <Shlwapi.h> // For PathRemoveFileSpec()
|
||||
|
@ -540,7 +540,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
|||
|
||||
|
||||
std::string TitlePath = xbox::LaunchDataPage->Header.szLaunchPath;
|
||||
char szWorkingDirectoy[MAX_PATH];
|
||||
char szWorkingDirectoy[xbox::max_path];
|
||||
|
||||
// If the title path starts with a semicolon, remove it
|
||||
if (TitlePath.length() > 0 && TitlePath[0] == ';') {
|
||||
|
@ -552,30 +552,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
|||
TitlePath = DeviceHarddisk0Partition2 + "\\xboxdash.xbe";
|
||||
}
|
||||
|
||||
std::string XbePath = TitlePath;
|
||||
// Convert Xbox XBE Path to Windows Path
|
||||
{
|
||||
HANDLE rootDirectoryHandle = nullptr;
|
||||
std::wstring wXbePath;
|
||||
// We pretend to come from NtCreateFile to force symbolic link resolution
|
||||
CxbxConvertFilePath(TitlePath, wXbePath, &rootDirectoryHandle, "NtCreateFile");
|
||||
|
||||
// Convert Wide String as returned by above to a string, for XbePath
|
||||
XbePath = utf16_to_ascii(wXbePath.c_str());
|
||||
|
||||
// If the rootDirectoryHandle is not null, we have a relative path
|
||||
// We need to prepend the path of the root directory to get a full DOS path
|
||||
if (rootDirectoryHandle != nullptr) {
|
||||
char directoryPathBuffer[MAX_PATH];
|
||||
GetFinalPathNameByHandle(rootDirectoryHandle, directoryPathBuffer, MAX_PATH, VOLUME_NAME_DOS);
|
||||
XbePath = directoryPathBuffer + std::string("\\") + XbePath;
|
||||
|
||||
// Trim \\?\ from the output string, as we want the raw DOS path, not NT path
|
||||
// We can do this always because GetFinalPathNameByHandle ALWAYS returns this format
|
||||
// Without exception
|
||||
XbePath.erase(0, 4);
|
||||
}
|
||||
}
|
||||
std::string& XbePath = CxbxConvertXboxToHostPath(TitlePath);
|
||||
|
||||
// Determine Working Directory
|
||||
{
|
||||
|
|
|
@ -90,7 +90,7 @@ static std::vector<HANDLE> g_hThreads;
|
|||
char szFilePath_CxbxReloaded_Exe[MAX_PATH] = { 0 };
|
||||
char szFolder_CxbxReloadedData[MAX_PATH] = { 0 };
|
||||
char szFilePath_EEPROM_bin[MAX_PATH] = { 0 };
|
||||
char szFilePath_Xbe[MAX_PATH*2] = { 0 }; // NOTE: LAUNCH_DATA_HEADER's szLaunchPath is MAX_PATH*2 = 520
|
||||
char szFilePath_Xbe[xbox::max_path*2] = { 0 }; // NOTE: LAUNCH_DATA_HEADER's szLaunchPath is xbox::max_path*2 = 520
|
||||
|
||||
std::string CxbxBasePath;
|
||||
HANDLE CxbxBasePathHandle;
|
||||
|
@ -997,7 +997,7 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
|
|||
// Remove extra slashes.
|
||||
std::string slash_search[] = { "\\\\", "//" };
|
||||
std::string slash_str = "/";
|
||||
for (n = 0, i = 0; i < slash_search->size(); i++, n = 0) {
|
||||
for (n = 0, i = 1; i < slash_search->size(); i++, n = 0) {
|
||||
while ((n = xbePath.find(slash_search[i], n)) != std::string::npos) {
|
||||
xbePath.replace(n, slash_search[i].size(), slash_str);
|
||||
n += slash_str.size();
|
||||
|
@ -1005,7 +1005,7 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
|
|||
}
|
||||
|
||||
// Once clean up process is done, proceed set to global variable string.
|
||||
strncpy(szFilePath_Xbe, xbePath.c_str(), MAX_PATH - 1);
|
||||
strncpy(szFilePath_Xbe, xbePath.c_str(), xbox::max_path - 1);
|
||||
std::replace(xbePath.begin(), xbePath.end(), ';', '/');
|
||||
// Load Xbe (this one will reside above WinMain's virtual_memory_placeholder)
|
||||
CxbxKrnl_Xbe = new Xbe(xbePath.c_str(), false); // TODO : Instead of using the Xbe class, port Dxbx _ReadXbeBlock()
|
||||
|
@ -1230,7 +1230,7 @@ void LoadXboxKeys(std::string path)
|
|||
// If we didn't already exit the function, keys.bin could not be loaded
|
||||
EmuLog(LOG_LEVEL::WARNING, "Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox");
|
||||
}
|
||||
|
||||
#pragma optimize("", off)
|
||||
__declspec(noreturn) void CxbxKrnlInit
|
||||
(
|
||||
void *pTLSData,
|
||||
|
@ -1344,7 +1344,7 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
char szBuffer[sizeof(szFilePath_Xbe)];
|
||||
g_EmuShared->GetStorageLocation(szBuffer);
|
||||
|
||||
CxbxBasePath = std::string(szBuffer) + "\\EmuDisk\\";
|
||||
CxbxBasePath = std::filesystem::path(std::string(szBuffer) + "\\EmuDisk\\").make_preferred().string(); // Let filesystem library clean it up for us.
|
||||
|
||||
// Determine XBE Path
|
||||
strncpy(szBuffer, szFilePath_Xbe, sizeof(szBuffer)-1);
|
||||
|
@ -1352,23 +1352,45 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
|
||||
std::string xbePath(szBuffer);
|
||||
std::replace(xbePath.begin(), xbePath.end(), ';', '/');
|
||||
std::string xbeDirectory(szBuffer);
|
||||
size_t lastFind = xbeDirectory.find(';');
|
||||
xbePath = std::filesystem::path(xbePath).make_preferred().string(); // Let filesystem library clean it up for us.
|
||||
|
||||
std::string mount_d_dir(szBuffer);
|
||||
size_t lastFind = mount_d_dir.find(';');
|
||||
// First find if there is a semicolon when dashboard or title disc (such as demo disc) has it.
|
||||
// Then we must obey the current directory it asked for.
|
||||
if (lastFind != std::string::npos) {
|
||||
if (xbeDirectory.find(';', lastFind + 1) != std::string::npos) {
|
||||
if (mount_d_dir.find(';', lastFind + 1) != std::string::npos) {
|
||||
CxbxKrnlCleanupEx(LOG_PREFIX_INIT, "Cannot contain multiple of ; symbol.");
|
||||
}
|
||||
xbeDirectory = xbeDirectory.substr(0, lastFind);
|
||||
mount_d_dir = mount_d_dir.substr(0, lastFind);
|
||||
}
|
||||
else {
|
||||
xbeDirectory = xbeDirectory.substr(0, xbeDirectory.find_last_of("\\/"));
|
||||
mount_d_dir = mount_d_dir.substr(0, mount_d_dir.find_last_of("\\/"));
|
||||
}
|
||||
mount_d_dir = std::filesystem::path(mount_d_dir).make_preferred().string(); // Let filesystem library clean it up for us.
|
||||
|
||||
CxbxBasePathHandle = CreateFile(CxbxBasePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
// Titles may assume they are running from CdRom0/Mbfs :
|
||||
std::string_view titleDevice = g_bIsChihiro ? DriveMbfs : DeviceCdrom0;
|
||||
int CxbxTitleDeviceDriveIndex = -1;
|
||||
if (BootFlags == BOOT_NONE) {
|
||||
// Remember our first initialize mount path.
|
||||
if (_strnicmp(mount_d_dir.c_str(), CxbxBasePath.c_str(), CxbxBasePath.size()-1) != 0) {
|
||||
g_EmuShared->SetTitleMountPath(mount_d_dir.c_str());
|
||||
CxbxTitleDeviceDriveIndex = CxbxRegisterDeviceHostPath(titleDevice, mount_d_dir);
|
||||
}
|
||||
else {
|
||||
g_EmuShared->SetTitleMountPath("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_EmuShared->GetTitleMountPath(szBuffer);
|
||||
if (szBuffer[0] != '\0') {
|
||||
CxbxTitleDeviceDriveIndex = CxbxRegisterDeviceHostPath(titleDevice, szBuffer);
|
||||
}
|
||||
}
|
||||
memset(szBuffer, 0, sizeof(szBuffer));
|
||||
// Games may assume they are running from CdRom :
|
||||
CxbxDefaultXbeDriveIndex = CxbxRegisterDeviceHostPath(DeviceCdrom0, xbeDirectory);
|
||||
|
||||
// Partition 0 contains configuration data, and is accessed as a native file, instead as a folder :
|
||||
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition0, CxbxBasePath + "Partition0", /*IsFile=*/true);
|
||||
// The first two partitions are for Data and Shell files, respectively :
|
||||
|
@ -1384,14 +1406,22 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
// Create default symbolic links :
|
||||
EmuLogInit(LOG_LEVEL::DEBUG, "Creating default symbolic links.");
|
||||
{
|
||||
// TODO: DriveD should always point to the Xbe Path
|
||||
// TODO: DriveD should auto mount base on launchdata page's ; delimiter xbe path.
|
||||
// This is the only symbolic link the Xbox Kernel sets, the rest are set by the application, usually via XAPI.
|
||||
// If the Xbe is located outside of the emulated HDD, mounting it as DeviceCdrom0 is correct
|
||||
// If the Xbe is located inside the emulated HDD, the full path should be used, eg: "\\Harddisk0\\partition2\\xboxdash.xbe"
|
||||
CxbxCreateSymbolicLink(DriveD, DeviceCdrom0);
|
||||
// Arrange that the Xbe path can reside outside the partitions, and put it to g_hCurDir :
|
||||
EmuNtSymbolicLinkObject* xbePathSymbolicLinkObject = FindNtSymbolicLinkObjectByDriveLetter(CxbxDefaultXbeDriveLetter);
|
||||
g_hCurDir = xbePathSymbolicLinkObject->RootDirectoryHandle;
|
||||
#ifdef CXBX_KERNEL_REWORK_ENABLED
|
||||
if (lastFind != std::string::npos) {
|
||||
#else
|
||||
// HACK: It is a hack to override XDK's default mount to CdRom0 which may not exist when launch to dashboard directly.
|
||||
// Otherwise, titles may launch to dashboard, more specifically xbox live title, and back.
|
||||
if (CxbxTitleDeviceDriveIndex == -1 || lastFind != std::string::npos) {
|
||||
#endif
|
||||
CxbxCreateSymbolicLink(DriveD, mount_d_dir);
|
||||
// Arrange that the Xbe path can reside outside the partitions, and put it to g_hCurDir :
|
||||
EmuNtSymbolicLinkObject* xbePathSymbolicLinkObject = FindNtSymbolicLinkObjectByDriveLetter(CxbxDelimiterAutoMountDriveLetter);
|
||||
g_hCurDir = xbePathSymbolicLinkObject->RootDirectoryHandle;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine Xbox path to XBE and place it in XeImageFileName
|
||||
|
@ -1407,9 +1437,9 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
free(xbox::XeImageFileName.Buffer);
|
||||
|
||||
// Assign the running Xbe path, so it can be accessed via the kernel thunk 'XeImageFileName' :
|
||||
xbox::XeImageFileName.MaximumLength = MAX_PATH;
|
||||
xbox::XeImageFileName.Buffer = (PCHAR)xbox::ExAllocatePool(MAX_PATH);
|
||||
sprintf(xbox::XeImageFileName.Buffer, "%c:\\%s", CxbxDefaultXbeDriveLetter, fileName.c_str());
|
||||
xbox::XeImageFileName.MaximumLength = xbox::max_path;
|
||||
xbox::XeImageFileName.Buffer = (PCHAR)xbox::ExAllocatePool(xbox::max_path);
|
||||
sprintf(xbox::XeImageFileName.Buffer, "%c:\\%s", CxbxDelimiterAutoMountDriveLetter, fileName.c_str());
|
||||
xbox::XeImageFileName.Length = (USHORT)strlen(xbox::XeImageFileName.Buffer);
|
||||
EmuLogInit(LOG_LEVEL::INFO, "XeImageFileName = %s", xbox::XeImageFileName.Buffer);
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ extern std::string CxbxKrnl_DebugFileName;
|
|||
extern char szFilePath_CxbxReloaded_Exe[MAX_PATH];
|
||||
extern char szFolder_CxbxReloadedData[MAX_PATH];
|
||||
extern char szFilePath_EEPROM_bin[MAX_PATH];
|
||||
extern char szFilePath_Xbe[MAX_PATH*2];
|
||||
extern char szFilePath_Xbe[xbox::max_path*2];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
#pragma warning(default:4005)
|
||||
#include "core\kernel\init\CxbxKrnl.h"
|
||||
#include "Logging.h"
|
||||
#include "common/util/strConverter.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#pragma optimize("", off)
|
||||
// Default Xbox Partition Table
|
||||
#define PE_PARTFLAGS_IN_USE 0x80000000
|
||||
#define XBOX_SWAPPART1_LBA_START 0x400
|
||||
|
@ -273,9 +274,7 @@ const std::string DeviceHarddisk0Partition17 = DeviceHarddisk0PartitionPrefix +
|
|||
const std::string DeviceHarddisk0Partition18 = DeviceHarddisk0PartitionPrefix + "18";
|
||||
const std::string DeviceHarddisk0Partition19 = DeviceHarddisk0PartitionPrefix + "19";
|
||||
const std::string DeviceHarddisk0Partition20 = DeviceHarddisk0PartitionPrefix + "20"; // 20 = Largest possible partition number
|
||||
const char CxbxDefaultXbeDriveLetter = 'D';
|
||||
|
||||
int CxbxDefaultXbeDriveIndex = -1;
|
||||
EmuNtSymbolicLinkObject* NtSymbolicLinkObjects['Z' - 'A' + 1];
|
||||
std::vector<XboxDevice> Devices;
|
||||
|
||||
|
@ -446,6 +445,12 @@ NTSTATUS CxbxConvertFilePath(
|
|||
if (RelativePath.compare(0, 7, "serial:") == 0)
|
||||
return STATUS_UNRECOGNIZED_VOLUME;
|
||||
|
||||
// Raw handle access to the CDROM0:
|
||||
/*if (RelativePath.compare(0, 7, "CDROM0:") == 0) {
|
||||
RelativePath = DeviceCdrom0 + "\\CDROM0.bin";
|
||||
// we should have a return and likely forward to special handler function, including serial: above.
|
||||
}*/
|
||||
|
||||
// The path seems to be a device path, look it up :
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByDevice(RelativePath);
|
||||
// Fixup RelativePath path here
|
||||
|
@ -593,6 +598,15 @@ int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int CxbxDeviceIndexByHostPath(const char * HostDevicePath)
|
||||
{
|
||||
for (size_t i = 0; i < Devices.size(); i++)
|
||||
if (_strnicmp(HostDevicePath, Devices[i].HostDevicePath.c_str(), Devices[i].HostDevicePath.length()) == 0)
|
||||
return(i);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
XboxDevice *CxbxDeviceByDevicePath(const std::string XboxDevicePath)
|
||||
{
|
||||
int DeviceIndex = CxbxDeviceIndexByDevicePath(XboxDevicePath.c_str());
|
||||
|
@ -602,7 +616,44 @@ XboxDevice *CxbxDeviceByDevicePath(const std::string XboxDevicePath)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int CxbxRegisterDeviceHostPath(std::string XboxDevicePath, std::string HostDevicePath, bool IsFile)
|
||||
XboxDevice *CxbxDeviceByHostPath(const std::string HostDevicePath)
|
||||
{
|
||||
int DeviceIndex = CxbxDeviceIndexByHostPath(HostDevicePath.c_str());
|
||||
if (DeviceIndex >= 0)
|
||||
return &Devices[DeviceIndex];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string CxbxConvertXboxToHostPath(const std::string_view XboxDevicePath) {
|
||||
std::string XbePath;
|
||||
// Convert Xbox XBE Path to Host Path
|
||||
{
|
||||
HANDLE rootDirectoryHandle = nullptr;
|
||||
std::wstring wXbePath;
|
||||
// We pretend to come from NtCreateFile to force symbolic link resolution
|
||||
CxbxConvertFilePath(XboxDevicePath.data(), wXbePath, &rootDirectoryHandle, "NtCreateFile");
|
||||
|
||||
// Convert Wide String as returned by above to a string, for XbePath
|
||||
XbePath = utf16_to_ascii(wXbePath.c_str());
|
||||
|
||||
// If the rootDirectoryHandle is not null, we have a relative path
|
||||
// We need to prepend the path of the root directory to get a full DOS path
|
||||
if (rootDirectoryHandle != nullptr) {
|
||||
char directoryPathBuffer[MAX_PATH];
|
||||
GetFinalPathNameByHandle(rootDirectoryHandle, directoryPathBuffer, MAX_PATH, VOLUME_NAME_DOS);
|
||||
XbePath = directoryPathBuffer + std::string("\\") + XbePath;
|
||||
|
||||
// Trim \\?\ from the output string, as we want the raw DOS path, not NT path
|
||||
// We can do this always because GetFinalPathNameByHandle ALWAYS returns this format
|
||||
// Without exception
|
||||
XbePath.erase(0, 4);
|
||||
}
|
||||
}
|
||||
return XbePath;
|
||||
}
|
||||
|
||||
int CxbxRegisterDeviceHostPath(const std::string_view XboxDevicePath, std::string HostDevicePath, bool IsFile)
|
||||
{
|
||||
XboxDevice newDevice;
|
||||
newDevice.XboxDevicePath = XboxDevicePath;
|
||||
|
@ -611,7 +662,7 @@ int CxbxRegisterDeviceHostPath(std::string XboxDevicePath, std::string HostDevic
|
|||
bool succeeded{ false };
|
||||
|
||||
// All HDD partitions have a .bin file to allow direct file io on the partition info
|
||||
if (_strnicmp(XboxDevicePath.c_str(), DeviceHarddisk0PartitionPrefix.c_str(), DeviceHarddisk0PartitionPrefix.length()) == 0) {
|
||||
if (_strnicmp(XboxDevicePath.data(), DeviceHarddisk0PartitionPrefix.c_str(), DeviceHarddisk0PartitionPrefix.length()) == 0) {
|
||||
std::string partitionHeaderPath = HostDevicePath + ".bin";
|
||||
if (!std::filesystem::exists(partitionHeaderPath)) {
|
||||
CxbxCreatePartitionHeaderFile(partitionHeaderPath, XboxDevicePath == DeviceHarddisk0Partition0);
|
||||
|
@ -622,7 +673,8 @@ int CxbxRegisterDeviceHostPath(std::string XboxDevicePath, std::string HostDevic
|
|||
|
||||
// If this path is not a raw file partition, create the directory for it
|
||||
if (!IsFile) {
|
||||
succeeded = std::filesystem::exists(HostDevicePath) || std::filesystem::create_directory(HostDevicePath);
|
||||
std::error_code error;
|
||||
succeeded = std::filesystem::exists(HostDevicePath) || std::filesystem::create_directory(HostDevicePath, error);
|
||||
}
|
||||
|
||||
if (succeeded) {
|
||||
|
@ -636,14 +688,15 @@ int CxbxRegisterDeviceHostPath(std::string XboxDevicePath, std::string HostDevic
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath)
|
||||
xbox::ntstatus_xt CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath)
|
||||
{
|
||||
NTSTATUS result = 0;
|
||||
xbox::ntstatus_xt result = 0;
|
||||
EmuNtSymbolicLinkObject* SymbolicLinkObject = FindNtSymbolicLinkObjectByName(SymbolicLinkName);
|
||||
|
||||
if (SymbolicLinkObject != NULL)
|
||||
// In that case, close it (will also delete if reference count drops to zero)
|
||||
SymbolicLinkObject->NtClose();
|
||||
// If symbolic link exist, return object name collsion. Do NOT delete existing symlink object!
|
||||
if (SymbolicLinkObject != NULL) {
|
||||
return xbox::status_object_name_collision;
|
||||
}
|
||||
|
||||
// Now (re)create a symbolic link object, and initialize it with the new definition :
|
||||
SymbolicLinkObject = new EmuNtSymbolicLinkObject();
|
||||
|
@ -660,7 +713,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin
|
|||
{
|
||||
NTSTATUS result = STATUS_OBJECT_NAME_INVALID;
|
||||
int i = 0;
|
||||
int DeviceIndex = 0;
|
||||
int DeviceIndex = -1;
|
||||
|
||||
// If aFullPath is an empty string, set it to the CD-ROM drive
|
||||
// This should work for all titles, as CD-ROM is mapped to the current working directory
|
||||
|
@ -688,31 +741,37 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin
|
|||
|
||||
// Make a distinction between Xbox paths (starting with '\Device'...) and host paths :
|
||||
IsHostBasedPath = _strnicmp(aFullPath.c_str(), DevicePrefix.c_str(), DevicePrefix.length()) != 0;
|
||||
if (IsHostBasedPath)
|
||||
DeviceIndex = CxbxDefaultXbeDriveIndex;
|
||||
else
|
||||
if (IsHostBasedPath) {
|
||||
DeviceIndex = CxbxDeviceIndexByHostPath(aFullPath.c_str());
|
||||
}
|
||||
else {
|
||||
DeviceIndex = CxbxDeviceIndexByDevicePath(aFullPath.c_str());
|
||||
}
|
||||
|
||||
if (DeviceIndex >= 0)
|
||||
{
|
||||
result = xbox::status_success;
|
||||
SymbolicLinkName = aSymbolicLinkName;
|
||||
if (IsHostBasedPath)
|
||||
{
|
||||
XboxSymbolicLinkPath = "";
|
||||
if (IsHostBasedPath) {
|
||||
// Handle the case where a sub folder of the partition is mounted (instead of it's root) :
|
||||
std::string ExtraPath = aFullPath.substr(Devices[DeviceIndex].HostDevicePath.length(), std::string::npos);
|
||||
|
||||
XboxSymbolicLinkPath = Devices[DeviceIndex].XboxDevicePath + ExtraPath;
|
||||
HostSymbolicLinkPath = aFullPath;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
XboxSymbolicLinkPath = aFullPath;
|
||||
HostSymbolicLinkPath = Devices[DeviceIndex].HostDevicePath;
|
||||
// Handle the case where a sub folder of the partition is mounted (instead of it's root) :
|
||||
std::string ExtraPath = aFullPath.substr(Devices[DeviceIndex].XboxDevicePath.length(), std::string::npos);
|
||||
|
||||
if (!ExtraPath.empty())
|
||||
if (!ExtraPath.empty()) {
|
||||
HostSymbolicLinkPath = HostSymbolicLinkPath + ExtraPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RootDirectoryHandle = CreateFile(HostSymbolicLinkPath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (RootDirectoryHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
|
|
@ -91,8 +91,7 @@ extern const std::string DeviceHarddisk0Partition17;
|
|||
extern const std::string DeviceHarddisk0Partition18;
|
||||
extern const std::string DeviceHarddisk0Partition19;
|
||||
extern const std::string DeviceHarddisk0Partition20;
|
||||
extern const char CxbxDefaultXbeDriveLetter;
|
||||
extern int CxbxDefaultXbeDriveIndex;
|
||||
static constexpr char CxbxDelimiterAutoMountDriveLetter = 'D';
|
||||
|
||||
extern std::string CxbxBasePath;
|
||||
extern HANDLE CxbxBasePathHandle;
|
||||
|
@ -219,9 +218,11 @@ struct XboxDevice {
|
|||
|
||||
CHAR* NtStatusToString(IN NTSTATUS Status);
|
||||
|
||||
int CxbxRegisterDeviceHostPath(std::string XboxFullPath, std::string HostDevicePath, bool IsFile = false);
|
||||
int CxbxRegisterDeviceHostPath(std::string_view XboxFullPath, std::string HostDevicePath, bool IsFile = false);
|
||||
int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath);
|
||||
XboxDevice *CxbxDeviceByDevicePath(const std::string XboxDevicePath);
|
||||
XboxDevice* CxbxDeviceByHostPath(const std::string HostPath);
|
||||
std::string CxbxConvertXboxToHostPath(const std::string_view XboxDevicePath);
|
||||
|
||||
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDriveLetter(const char DriveLetter);
|
||||
|
@ -231,7 +232,7 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
|
|||
void CleanupSymbolicLinks();
|
||||
|
||||
HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath);
|
||||
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
|
||||
xbox::ntstatus_xt CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
|
||||
|
||||
std::wstring string_to_wstring(std::string const & src);
|
||||
std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src);
|
||||
|
|
Loading…
Reference in New Issue