kernel: fix chihiro support
This commit is contained in:
parent
9eadb8d393
commit
d8eb26fbda
|
@ -796,6 +796,9 @@ void Settings::SyncToEmulator()
|
|||
|
||||
// register data location setting
|
||||
g_EmuShared->SetStorageLocation(GetDataLocation().c_str());
|
||||
|
||||
// reset title mount path
|
||||
g_EmuShared->SetTitleMountPath("");
|
||||
}
|
||||
|
||||
void verifyDebugFilePath(DebugMode& debug_mode, std::string& file_path)
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
#include "devices\SMCDevice.h" // For SMC_COMMAND_SCRATCH
|
||||
#include "common/util/strConverter.hpp" // for utf16_to_ascii
|
||||
#include "core\kernel\memory-manager\VMManager.h"
|
||||
#include "common/util/cliConfig.hpp"
|
||||
#include "common/CxbxDebugger.h"
|
||||
|
||||
#include <algorithm> // for std::replace
|
||||
#include <locale>
|
||||
|
@ -565,49 +563,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
|||
// Some titles (Xbox Dashboard and retail/demo discs) use ";" as a current directory path seperator
|
||||
// This process is handled during initialization. No special handling here required.
|
||||
|
||||
cli_config::SetLoad(XbePath);
|
||||
|
||||
bool Debugging{ false };
|
||||
g_EmuShared->GetDebuggingFlag(&Debugging);
|
||||
|
||||
if (Debugging)
|
||||
{
|
||||
std::string cliCommands;
|
||||
if (!cli_config::GenCMD(cliCommands))
|
||||
{
|
||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||
}
|
||||
|
||||
CxbxDebugger::ReportNewTarget(cliCommands.c_str());
|
||||
|
||||
// The debugger will execute this process
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CxbxExec(false, nullptr, false))
|
||||
{
|
||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// This is a requirement to have shared memory buffers remain alive and transfer to new emulation process.
|
||||
unsigned int retryAttempt = 0;
|
||||
unsigned int curProcID = 0;
|
||||
unsigned int oldProcID = GetCurrentProcessId();
|
||||
while(true) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
g_EmuShared->GetKrnlProcID(&curProcID);
|
||||
// Break when new emulation process has take over.
|
||||
if (curProcID != oldProcID) {
|
||||
break;
|
||||
}
|
||||
retryAttempt++;
|
||||
// Terminate after 5 seconds of failure.
|
||||
if (retryAttempt >= (5 * (1000 / 100))) {
|
||||
PopupError(nullptr, "Could not reboot; New emulation process did not take over.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
CxbxLaunchNewXbe(XbePath);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -624,10 +580,7 @@ XBSYSAPI EXPORTNUM(49) xbox::void_xt DECLSPEC_NORETURN NTAPI xbox::HalReturnToFi
|
|||
|
||||
g_VMManager.SavePersistentMemory();
|
||||
|
||||
cli_config::SetLoad(szFilePath_Xbe);
|
||||
if (!CxbxExec(false, nullptr, false)) {
|
||||
CxbxKrnlCleanup("Could not launch %s", szFilePath_Xbe);
|
||||
}
|
||||
CxbxLaunchNewXbe(szFilePath_Xbe);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1398,25 +1398,26 @@ __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);
|
||||
// Titles may assume they are running from CdRom0/Mbfs :
|
||||
std::string_view titleDevice = g_bIsChihiro ? DriveMbfs : DeviceCdrom0;
|
||||
int CxbxTitleDeviceDriveIndex = -1;
|
||||
bool isEmuDisk = _strnicmp(relative_path.c_str(), CxbxBasePath.c_str(), CxbxBasePath.size() - 1) == 0;
|
||||
if (BootFlags == BOOT_NONE) {
|
||||
// Remember our first initialize mount path for CdRom0/Mbfs.
|
||||
// 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* tmp_buffer = title_mount_path;
|
||||
g_EmuShared->GetTitleMountPath(title_mount_path);
|
||||
|
||||
if (tmp_buffer[0] == '\0' && BootFlags == BOOT_NONE) {
|
||||
// Remember our first initialize mount path for CdRom0 and Mbfs.
|
||||
if (!isEmuDisk) {
|
||||
g_EmuShared->SetTitleMountPath(relative_path.c_str());
|
||||
CxbxTitleDeviceDriveIndex = CxbxRegisterDeviceHostPath(titleDevice, relative_path);
|
||||
}
|
||||
else {
|
||||
g_EmuShared->SetTitleMountPath("");
|
||||
tmp_buffer = relative_path.c_str();
|
||||
}
|
||||
}
|
||||
else {
|
||||
char szBuffer[sizeof(szFilePath_Xbe)];
|
||||
g_EmuShared->GetTitleMountPath(szBuffer);
|
||||
if (szBuffer[0] != '\0') {
|
||||
CxbxTitleDeviceDriveIndex = CxbxRegisterDeviceHostPath(titleDevice, szBuffer);
|
||||
|
||||
// TODO: Find a place to make permanent placement for DeviceCdrom0 that does not have disc loaded.
|
||||
if (tmp_buffer[0] != '\0') {
|
||||
CxbxTitleDeviceDriveIndex = CxbxRegisterDeviceHostPath(DeviceCdrom0, tmp_buffer);
|
||||
if (g_bIsChihiro) {
|
||||
CxbxRegisterDeviceHostPath(DriveMbfs, tmp_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1462,9 +1463,9 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
XboxDevice* xbeLoc = CxbxDeviceByHostPath(xbePath.string());
|
||||
fileName = xbeLoc->XboxDevicePath;
|
||||
}
|
||||
// Otherwise it might be from titleDevice source.
|
||||
// Otherwise it might be from CdRom0 device.
|
||||
else {
|
||||
fileName = titleDevice;
|
||||
fileName = DeviceCdrom0;
|
||||
}
|
||||
|
||||
// Strip out the path, leaving only the XBE file name to append.
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include "core\kernel\init\CxbxKrnl.h"
|
||||
#include "Logging.h"
|
||||
#include "common/util/strConverter.hpp" // utf16_to_ascii
|
||||
#include "common/util/cliConfig.hpp"
|
||||
#include "common/CxbxDebugger.h"
|
||||
#include "EmuShared.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
|
@ -402,7 +405,8 @@ NTSTATUS CxbxConvertFilePath(
|
|||
std::string RelativePath = RelativeXboxPath;
|
||||
std::string XboxFullPath;
|
||||
std::string HostPath;
|
||||
EmuNtSymbolicLinkObject* NtSymbolicLinkObject = NULL;
|
||||
EmuNtSymbolicLinkObject* NtSymbolicLinkObject = nullptr;
|
||||
EmuDirPath find_path;
|
||||
|
||||
// Always trim '\??\' off :
|
||||
if (RelativePath.compare(0, DrivePrefix.length(), DrivePrefix.c_str()) == 0)
|
||||
|
@ -442,8 +446,9 @@ NTSTATUS CxbxConvertFilePath(
|
|||
}
|
||||
else {
|
||||
// TODO : How should we handle accesses to the serial: (?semi-)volume?
|
||||
if (RelativePath.compare(0, 7, "serial:") == 0)
|
||||
if (RelativePath.compare(0, 7, "serial:") == 0) {
|
||||
return STATUS_UNRECOGNIZED_VOLUME;
|
||||
}
|
||||
|
||||
// TODO: CDROM0: need access to raw file handle which doesn't exist in file system.
|
||||
// Similar concept with serial: and perhaps mediaboards.
|
||||
|
@ -454,51 +459,52 @@ NTSTATUS CxbxConvertFilePath(
|
|||
}*/
|
||||
|
||||
// The path seems to be a device path, look it up :
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByDevice(RelativePath);
|
||||
FindEmuDirPathByDevice(RelativePath, find_path);
|
||||
// Fixup RelativePath path here
|
||||
if (NtSymbolicLinkObject != NULL)
|
||||
RelativePath.erase(0, NtSymbolicLinkObject->XboxSymbolicLinkPath.length()); // Remove '\Device\Harddisk0\Partition2'
|
||||
if (!find_path.HostDirPath.empty()) {
|
||||
RelativePath.erase(0, find_path.XboxDirPath.length()); // Remove '\Device\Harddisk0\Partition2'
|
||||
}
|
||||
}
|
||||
|
||||
if (NtSymbolicLinkObject == NULL) {
|
||||
// Check if the path accesses a partition from Harddisk0 :
|
||||
if (_strnicmp(RelativePath.c_str(), DeviceHarddisk0PartitionPrefix.c_str(), DeviceHarddisk0PartitionPrefix.length()) == 0) {
|
||||
XboxFullPath = RelativePath;
|
||||
// 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;
|
||||
}
|
||||
// NOTE: RootDirectory cannot be ignored.
|
||||
// Any special handling for it should be done below.
|
||||
else if (*RootDirectory == nullptr) {
|
||||
// Assume relative to Xbe path
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByRootHandle(g_hCurDir);
|
||||
}
|
||||
else if (*RootDirectory == ObDosDevicesDirectory()) {
|
||||
// This is a special handle that tells the API that this is a DOS device
|
||||
// We can safely remove it and forward to the Xbe directory.
|
||||
// Test case GTA3
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByRootHandle(g_hCurDir);
|
||||
}
|
||||
else if (*RootDirectory == ObWin32NamedObjectsDirectory()) {
|
||||
// NOTE: A handle of -4 on the Xbox signifies the path should be in the BaseNamedObjects namespace.
|
||||
// This handle doesn't exist on Windows, so we prefix the name instead. (note from LukeUsher)
|
||||
// Handle special root directory constants
|
||||
*RootDirectory = NULL;
|
||||
|
||||
if (OriginalPath.size() == 0){
|
||||
RelativePath = "\\BaseNamedObjects";
|
||||
} else {
|
||||
RelativePath = "\\BaseNamedObjects\\" + OriginalPath;
|
||||
}
|
||||
}
|
||||
// else {} // NOTE: Allow RootDirectory handle to take control of relative path.
|
||||
// Test-case: Turok Evolution
|
||||
if (NtSymbolicLinkObject != nullptr || !find_path.HostDirPath.empty()) {
|
||||
/// If found, then we can skip misc checks below.
|
||||
}
|
||||
// Check if the path accesses a partition from Harddisk0 :
|
||||
else if (_strnicmp(RelativePath.c_str(), DeviceHarddisk0PartitionPrefix.c_str(), DeviceHarddisk0PartitionPrefix.length()) == 0) {
|
||||
XboxFullPath = RelativePath;
|
||||
// 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;
|
||||
}
|
||||
// NOTE: RootDirectory cannot be ignored.
|
||||
// Any special handling for it should be done below.
|
||||
else if (*RootDirectory == nullptr) {
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByRootHandle(g_hCurDir);
|
||||
}
|
||||
else if (*RootDirectory == ObDosDevicesDirectory()) {
|
||||
// This is a special handle that tells the API that this is a DOS device
|
||||
// We can safely remove it and forward to the Xbe directory.
|
||||
// Test case GTA3
|
||||
NtSymbolicLinkObject = FindNtSymbolicLinkObjectByRootHandle(g_hCurDir);
|
||||
}
|
||||
else if (*RootDirectory == ObWin32NamedObjectsDirectory()) {
|
||||
// NOTE: A handle of -4 on the Xbox signifies the path should be in the BaseNamedObjects namespace.
|
||||
// This handle doesn't exist on Windows, so we prefix the name instead. (note from LukeUsher)
|
||||
// Handle special root directory constants
|
||||
*RootDirectory = NULL;
|
||||
|
||||
if (NtSymbolicLinkObject != NULL) {
|
||||
if (OriginalPath.size() == 0){
|
||||
RelativePath = "\\BaseNamedObjects";
|
||||
} else {
|
||||
RelativePath = "\\BaseNamedObjects\\" + OriginalPath;
|
||||
}
|
||||
}
|
||||
// else {} // NOTE: Allow RootDirectory handle to take control of relative path.
|
||||
// Test-case: Turok Evolution
|
||||
|
||||
if (NtSymbolicLinkObject != nullptr) {
|
||||
HostPath = NtSymbolicLinkObject->HostSymbolicLinkPath;
|
||||
|
||||
XboxFullPath = NtSymbolicLinkObject->XboxSymbolicLinkPath;
|
||||
|
@ -506,6 +512,11 @@ NTSTATUS CxbxConvertFilePath(
|
|||
// If accessing a partition as a directly, set the root directory handle and keep relative path as is
|
||||
*RootDirectory = NtSymbolicLinkObject->RootDirectoryHandle;
|
||||
}
|
||||
else if (!find_path.HostDirPath.empty()) {
|
||||
HostPath = find_path.HostDirPath;
|
||||
XboxFullPath = find_path.XboxDirPath;
|
||||
*RootDirectory = find_path.HostDirHandle;
|
||||
}
|
||||
} else {
|
||||
*RootDirectory = CxbxBasePathHandle;
|
||||
HostPath = CxbxBasePath;
|
||||
|
@ -679,6 +690,7 @@ int CxbxRegisterDeviceHostPath(const std::string_view XboxDevicePath, std::strin
|
|||
}
|
||||
|
||||
if (succeeded) {
|
||||
newDevice.HostRootHandle = CreateFile(newDevice.HostDevicePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
Devices.push_back(newDevice);
|
||||
return static_cast<int>(Devices.size()) - 1;
|
||||
}
|
||||
|
@ -833,16 +845,18 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLink
|
|||
}
|
||||
|
||||
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName)
|
||||
void FindEmuDirPathByDevice(std::string DeviceName, EmuDirPath& hybrid_path)
|
||||
{
|
||||
for (char DriveLetter = 'A'; DriveLetter <= 'Z'; DriveLetter++)
|
||||
{
|
||||
EmuNtSymbolicLinkObject* result = NtSymbolicLinkObjects[DriveLetter - 'A'];
|
||||
if ((result != NULL) && _strnicmp(DeviceName.c_str(), result->XboxSymbolicLinkPath.c_str(), result->XboxSymbolicLinkPath.length()) == 0)
|
||||
return result;
|
||||
for (auto device = Devices.begin(); device != Devices.end(); device++) {
|
||||
if (_strnicmp(DeviceName.c_str(), device->XboxDevicePath.c_str(), device->XboxDevicePath.length()) == 0) {
|
||||
hybrid_path.XboxDirPath = device->XboxDevicePath;
|
||||
hybrid_path.HostDirPath = device->HostDevicePath;
|
||||
hybrid_path.HostDirHandle = device->HostRootHandle;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
hybrid_path.HostDirPath = "";
|
||||
}
|
||||
|
||||
|
||||
|
@ -1142,6 +1156,52 @@ NTSTATUS NTToXboxFileInformation
|
|||
return result;
|
||||
}
|
||||
|
||||
void CxbxLaunchNewXbe(const std::string& XbePath) {
|
||||
cli_config::SetLoad(XbePath);
|
||||
|
||||
bool Debugging{ false };
|
||||
g_EmuShared->GetDebuggingFlag(&Debugging);
|
||||
|
||||
if (Debugging)
|
||||
{
|
||||
std::string cliCommands;
|
||||
if (!cli_config::GenCMD(cliCommands))
|
||||
{
|
||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||
}
|
||||
|
||||
CxbxDebugger::ReportNewTarget(cliCommands.c_str());
|
||||
|
||||
// The debugger will execute this process
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CxbxExec(false, nullptr, false))
|
||||
{
|
||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// This is a requirement to have shared memory buffers remain alive and transfer to new emulation process.
|
||||
unsigned int retryAttempt = 0;
|
||||
unsigned int curProcID = 0;
|
||||
unsigned int oldProcID = GetCurrentProcessId();
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
g_EmuShared->GetKrnlProcID(&curProcID);
|
||||
// Break when new emulation process has take over.
|
||||
if (curProcID != oldProcID) {
|
||||
break;
|
||||
}
|
||||
retryAttempt++;
|
||||
// Terminate after 5 seconds of failure.
|
||||
if (retryAttempt >= (5 * (1000 / 100))) {
|
||||
PopupError(nullptr, "Could not reboot; New emulation process did not take over.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FS_INFORMATION_CLASS and its related structs most likely need to be converted too
|
||||
|
||||
// TODO : Move to a better suited file
|
||||
|
|
|
@ -216,18 +216,24 @@ struct XboxDevice {
|
|||
HANDLE HostRootHandle;
|
||||
};
|
||||
|
||||
struct EmuDirPath {
|
||||
std::string_view XboxDirPath;
|
||||
std::string_view HostDirPath;
|
||||
HANDLE HostDirHandle;
|
||||
};
|
||||
|
||||
CHAR* NtStatusToString(IN NTSTATUS Status);
|
||||
|
||||
int CxbxRegisterDeviceHostPath(std::string_view XboxFullPath, std::string HostDevicePath, bool IsFile = false);
|
||||
int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath);
|
||||
XboxDevice *CxbxDeviceByDevicePath(const std::string_view XboxDevicePath);
|
||||
XboxDevice* CxbxDeviceByDevicePath(const std::string_view XboxDevicePath);
|
||||
XboxDevice* CxbxDeviceByHostPath(const std::string_view HostPath);
|
||||
std::string CxbxConvertXboxToHostPath(const std::string_view XboxDevicePath);
|
||||
|
||||
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDriveLetter(const char DriveLetter);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName);
|
||||
void FindEmuDirPathByDevice(std::string DeviceName, EmuDirPath& hybrid_path);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
|
||||
void CleanupSymbolicLinks();
|
||||
|
||||
|
@ -322,4 +328,6 @@ void NTAPI CxbxIoApcDispatcher
|
|||
xbox::ulong_xt Reserved
|
||||
);
|
||||
|
||||
void CxbxLaunchNewXbe(const std::string& XbePath);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue