diff --git a/src/common/xbox_types.h b/src/common/xbox_types.h index 8c813dd10..971fa9a9d 100644 --- a/src/common/xbox_types.h +++ b/src/common/xbox_types.h @@ -85,7 +85,7 @@ namespace xbox // ****************************************************************** typedef char_xt *PCHAR; typedef char_xt *PSZ; - typedef char_xt *PCSZ; + typedef const char_xt *PCSZ; typedef byte_xt *PBYTE; typedef boolean_xt *PBOOLEAN; typedef uchar_xt *PUCHAR; diff --git a/src/core/kernel/common/types.h b/src/core/kernel/common/types.h index c6c039493..759483b1e 100644 --- a/src/core/kernel/common/types.h +++ b/src/core/kernel/common/types.h @@ -74,6 +74,7 @@ inline constexpr dword_xt status_pending = 0x00000103L; inline constexpr dword_xt status_timer_resume_ignored = 0x40000025L; inline constexpr dword_xt status_buffer_overflow = 0x80000005L; inline constexpr dword_xt status_unsuccessful = 0xC0000001; +inline constexpr dword_xt status_invalid_handle = 0xC0000008; inline constexpr dword_xt status_unrecognized_media = 0xC0000014; inline constexpr dword_xt status_no_memory = 0xC0000017L; inline constexpr dword_xt status_buffer_too_small = 0xC0000023L; @@ -88,6 +89,7 @@ inline constexpr dword_xt status_insufficient_resources = 0xC000009AL; inline constexpr dword_xt status_too_many_secrets = 0xC0000156L; inline constexpr dword_xt status_xbe_region_mismatch = 0xC0050001L; inline constexpr dword_xt status_xbe_media_mismatch = 0xC0050002L; +inline constexpr dword_xt status_object_name_invalid = 0xC0000033L; inline constexpr dword_xt status_object_name_not_found = 0xC0000034L; inline constexpr dword_xt status_object_name_collision = 0xC0000035L; inline constexpr dword_xt status_invalid_page_protection = 0xC0000045L; diff --git a/src/core/kernel/exports/EmuKrnlIo.cpp b/src/core/kernel/exports/EmuKrnlIo.cpp index 471c6f9ab..b0b9c333f 100644 --- a/src/core/kernel/exports/EmuKrnlIo.cpp +++ b/src/core/kernel/exports/EmuKrnlIo.cpp @@ -193,12 +193,12 @@ XBSYSAPI EXPORTNUM(64) xbox::OBJECT_TYPE xbox::IoCompletionObjectType = // ****************************************************************** XBSYSAPI EXPORTNUM(65) xbox::ntstatus_xt NTAPI xbox::IoCreateDevice ( - IN PDRIVER_OBJECT DriverObject, - IN ulong_xt DeviceExtensionSize, - IN PSTRING DeviceName OPTIONAL, - IN ulong_xt DeviceType, - IN boolean_xt Exclusive, - OUT PDEVICE_OBJECT* DeviceObject + IN PDRIVER_OBJECT DriverObject, + IN ulong_xt DeviceExtensionSize, + IN PSTRING DeviceName OPTIONAL, + IN ulong_xt DeviceType, + IN boolean_xt Exclusive, + OUT PDEVICE_OBJECT* DeviceObject ) { LOG_FUNC_BEGIN @@ -210,6 +210,9 @@ XBSYSAPI EXPORTNUM(65) xbox::ntstatus_xt NTAPI xbox::IoCreateDevice LOG_FUNC_ARG_OUT(DeviceObject) LOG_FUNC_END; + // TODO: IoCreateDevice is critical to enable support for devices interface. + // Which include disk, dvd-rom, memory unit cards, etc. + // Find a way to coexist with host interface from here. LOG_UNIMPLEMENTED(); RETURN(xbox::status_success); diff --git a/src/core/kernel/exports/EmuKrnlKe.cpp b/src/core/kernel/exports/EmuKrnlKe.cpp index d6c48b4b2..7a2d9851a 100644 --- a/src/core/kernel/exports/EmuKrnlKe.cpp +++ b/src/core/kernel/exports/EmuKrnlKe.cpp @@ -724,7 +724,7 @@ XBSYSAPI EXPORTNUM(108) xbox::void_xt NTAPI xbox::KeInitializeEvent LOG_FUNC_END; // HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own - // In this case, it is already initialized so no need tod o anything + // In this case, it is already initialized so no need todo anything // Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection) DWORD flags = 0; if (GetHandleInformation((HANDLE)Event, &flags)) { diff --git a/src/core/kernel/exports/EmuKrnlNt.cpp b/src/core/kernel/exports/EmuKrnlNt.cpp index efbebd61a..a8c7d9bfe 100644 --- a/src/core/kernel/exports/EmuKrnlNt.cpp +++ b/src/core/kernel/exports/EmuKrnlNt.cpp @@ -233,24 +233,22 @@ XBSYSAPI EXPORTNUM(189) xbox::ntstatus_xt NTAPI xbox::NtCreateEvent LOG_FUNC_ARG(InitialState) LOG_FUNC_END; -/* - NTSTATUS Status; - + ntstatus_xt result; +#ifdef CXBX_KERNEL_REWORK_ENABLED if ((EventType != NotificationEvent) && (EventType != SynchronizationEvent)) { - Status = STATUS_INVALID_PARAMETER; + result = STATUS_INVALID_PARAMETER; } else { PKEVENT Event; - Status = ObCreateObject(&ExEventObjectType, ObjectAttributes, sizeof(KEVENT), (PVOID *)&Event); - if (nt_success(Status)) { + result = ObCreateObject(&ExEventObjectType, ObjectAttributes, sizeof(KEVENT), (PVOID *)&Event); + if (nt_success(result)) { KeInitializeEvent(Event, EventType, InitialState); - Status = ObInsertObject(Event, ObjectAttributes, 0, EventHandle); + result = ObInsertObject(Event, ObjectAttributes, 0, EventHandle); } } +#else - RETURN(Status); -*/ LOG_INCOMPLETE(); // TODO : Verify arguments, use ObCreateObject, KeInitializeEvent and ObInsertObject instead of this: // initialize object attributes @@ -261,7 +259,7 @@ XBSYSAPI EXPORTNUM(189) xbox::ntstatus_xt NTAPI xbox::NtCreateEvent const ACCESS_MASK DesiredAccess = EVENT_ALL_ACCESS; // redirect to Win2k/XP - NTSTATUS ret = NtDll::NtCreateEvent( + result = NtDll::NtCreateEvent( /*OUT*/EventHandle, DesiredAccess, nativeObjectAttributes.NtObjAttrPtr, @@ -271,28 +269,29 @@ XBSYSAPI EXPORTNUM(189) xbox::ntstatus_xt NTAPI xbox::NtCreateEvent // TODO : Instead of the above, we should consider using the Ke*Event APIs, but // that would require us to create the event's kernel object with the Ob* api's too! - if (FAILED(ret)) + if (FAILED(result)) { - EmuLog(LOG_LEVEL::WARNING, "Trying fallback (without object attributes)...\nError code 0x%X", ret); + EmuLog(LOG_LEVEL::WARNING, "Trying fallback (without object attributes)...\nError code 0x%X", result); // If it fails, try again but without the object attributes stucture // This fixes Panzer Dragoon games on non-Vista OSes. - ret = NtDll::NtCreateEvent( + result = NtDll::NtCreateEvent( /*OUT*/EventHandle, DesiredAccess, /*nativeObjectAttributes.NtObjAttrPtr*/ NULL, (NtDll::EVENT_TYPE)EventType, InitialState); - if(FAILED(ret)) + if(FAILED(result)) EmuLog(LOG_LEVEL::WARNING, "NtCreateEvent Failed!"); else EmuLog(LOG_LEVEL::DEBUG, "NtCreateEvent EventHandle = 0x%.8X", *EventHandle); } else EmuLog(LOG_LEVEL::DEBUG, "NtCreateEvent EventHandle = 0x%.8X", *EventHandle); +#endif - RETURN(ret); + RETURN(result); } // ****************************************************************** @@ -680,25 +679,26 @@ XBSYSAPI EXPORTNUM(197) xbox::ntstatus_xt NTAPI xbox::NtDuplicateObject LOG_FUNC_ARG(Options) LOG_FUNC_END; - NTSTATUS ret = xbox::status_success; + NTSTATUS result = xbox::status_success; + +#ifdef CXBX_KERNEL_REWORK_ENABLED + PVOID Object; + + result = ObReferenceObjectByHandle(SourceHandle, /*ObjectType=*/nullptr, &Object); + if (nt_success(result)) { + if (ObpIsFlagSet(Options, DUPLICATE_CLOSE_SOURCE)) + NtClose(SourceHandle); + + result = ObOpenObjectByPointer(Object, OBJECT_TO_OBJECT_HEADER(Object)->Type, /*OUT*/TargetHandle); + ObfDereferenceObject(Object); + } + else + *TargetHandle = NULL; +#else if (EmuHandle::IsEmuHandle(SourceHandle)) { auto iEmuHandle = (EmuHandle*)SourceHandle; - ret = iEmuHandle->NtDuplicateObject(TargetHandle, Options); -/* - PVOID Object; - - ret = ObReferenceObjectByHandle(SourceHandle, /*ObjectType=* /NULL, &Object); - if (nt_success(ret)) { - if (ObpIsFlagSet(Options, DUPLICATE_CLOSE_SOURCE)) - NtClose(SourceHandle); - - status = ObOpenObjectByPointer(Object, OBJECT_TO_OBJECT_HEADER(Object)->Type, /*OUT* /TargetHandle); - ObDereferenceObject(Object); - } - else - *TargetHandle = NULL; -*/ + result = iEmuHandle->NtDuplicateObject(TargetHandle, Options); } else { @@ -708,7 +708,7 @@ XBSYSAPI EXPORTNUM(197) xbox::ntstatus_xt NTAPI xbox::NtDuplicateObject Options |= (DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_SAME_ACCESS); // redirect to Win2k/XP - ret = NtDll::NtDuplicateObject( + result = NtDll::NtDuplicateObject( /*SourceProcessHandle=*/g_CurrentProcessHandle, SourceHandle, /*TargetProcessHandle=*/g_CurrentProcessHandle, @@ -718,10 +718,11 @@ XBSYSAPI EXPORTNUM(197) xbox::ntstatus_xt NTAPI xbox::NtDuplicateObject Options); } - if (ret != xbox::status_success) + if (result != xbox::status_success) EmuLog(LOG_LEVEL::WARNING, "Object was not duplicated!"); +#endif - RETURN(ret); + RETURN(result); } // ****************************************************************** @@ -873,33 +874,9 @@ XBSYSAPI EXPORTNUM(203) xbox::ntstatus_xt NTAPI xbox::NtOpenSymbolicLinkObject IN POBJECT_ATTRIBUTES ObjectAttributes ) { - /* TODO : LOG_FORWARD("ObOpenObjectByName"); return ObOpenObjectByName(ObjectAttributes, &ObSymbolicLinkObjectType, NULL, LinkHandle); - */ - LOG_FUNC_BEGIN - LOG_FUNC_ARG_OUT(LinkHandle) - LOG_FUNC_ARG(ObjectAttributes) - LOG_FUNC_END; - - NTSTATUS ret = STATUS_OBJECT_PATH_NOT_FOUND; - EmuNtSymbolicLinkObject* symbolicLinkObject = - FindNtSymbolicLinkObjectByName(PSTRING_to_string(ObjectAttributes->ObjectName)); - - if (symbolicLinkObject != NULL) - { - // Return a new handle (which is an EmuHandle, actually) : - *LinkHandle = symbolicLinkObject->NewHandle(); - ret = xbox::status_success; - } - - if (ret != xbox::status_success) - EmuLog(LOG_LEVEL::WARNING, "NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret)); - else - EmuLog(LOG_LEVEL::DEBUG, "NtOpenSymbolicLinkObject LinkHandle^ = 0x%.8X", *LinkHandle); - - RETURN(ret); } // ****************************************************************** @@ -1472,8 +1449,8 @@ XBSYSAPI EXPORTNUM(217) xbox::ntstatus_xt NTAPI xbox::NtQueryVirtualMemory } #if 0 - if (FAILED(ret)) { - EmuLog(LOG_LEVEL::WARNING, "NtQueryVirtualMemory failed (%s)!", NtStatusToString(ret)); + if (FAILED(result)) { + EmuLog(LOG_LEVEL::WARNING, "NtQueryVirtualMemory failed (%s)!", NtStatusToString(result)); // Bugfix for "Forza Motorsport", which iterates over 2 Gb of memory in 64kb chunks, // but fails on this last query. It's not done though, as after this Forza tries to @@ -1490,7 +1467,7 @@ XBSYSAPI EXPORTNUM(217) xbox::ntstatus_xt NTAPI xbox::NtQueryVirtualMemory Buffer->Protect = PAGE_READONLY; // One of the flags listed for the AllocationProtect member is specified Buffer->Type = 262144; // Specifies the type of pages in the region. (MEM_IMAGE, MEM_MAPPED or MEM_PRIVATE) - ret = xbox::status_success; + result = xbox::status_success; EmuLog(LOG_LEVEL::DEBUG, "NtQueryVirtualMemory: Applied fix for Forza Motorsport!"); } @@ -1728,7 +1705,7 @@ XBSYSAPI EXPORTNUM(221) xbox::ntstatus_xt NTAPI xbox::NtReleaseMutant if (FAILED(ret)) EmuLog(LOG_LEVEL::WARNING, "NtReleaseMutant Failed!"); - RETURN(xbox::status_success); // TODO : RETURN(ret); + RETURN(xbox::status_success); // TODO : RETURN(result); } // ****************************************************************** diff --git a/src/core/kernel/exports/EmuKrnlOb.cpp b/src/core/kernel/exports/EmuKrnlOb.cpp index 1d42dc071..65c43370d 100644 --- a/src/core/kernel/exports/EmuKrnlOb.cpp +++ b/src/core/kernel/exports/EmuKrnlOb.cpp @@ -28,6 +28,13 @@ #define LOG_PREFIX CXBXR_MODULE::OB +// TODO: What needs proper implement from Ob functions' side: (use CXBX_KERNEL_REWORK_ENABLED defined to evaluate what needs fixing) +// ObpDeleteSymbolicLink - internal function which would need a call to ObDereferenceObject with LinkTargetObject pass down. +// Plus it require proper IoCreateSymbolicLink implement as well, not emulated implement method. +// ObpDefaultObject - Find out how to initialize this. Then connect the dots from TODO message. +// OBJECT_DIRECTORY interface (root, dos, device, and named object, you can find global varables about 30 lines below) +// etc (add more above this line) + #include // For ObDirectoryObjectType, etc. #include "Logging.h" // For LOG_FUNC() @@ -42,11 +49,11 @@ #pragma warning(default:4005) #define INITIALIZED_OBJECT_STRING(ObjectString, Value) \ - xbox::char_xt ObjectString##Buffer[] = Value; \ - xbox::OBJECT_STRING ObjectString = { \ - sizeof(Value) - sizeof(CHAR), \ - sizeof(Value), \ - ObjectString##Buffer \ + xbox::char_xt ObjectString##Buffer[] = Value; \ + xbox::OBJECT_STRING ObjectString = { \ + sizeof(Value) - sizeof(xbox::char_xt), \ + sizeof(Value), \ + ObjectString##Buffer \ } INITIALIZED_OBJECT_STRING(ObpDosDevicesString, "\\??"); @@ -65,8 +72,8 @@ XBSYSAPI EXPORTNUM(245) xbox::OBJECT_HANDLE_TABLE xbox::ObpObjectHandleTable = { xbox::PVOID ObpDosDevicesDriveLetterMap['Z' - 'A' + 1]; xbox::boolean_xt xbox::ObpCreatePermanentDirectoryObject( - IN xbox::POBJECT_STRING DirectoryName OPTIONAL, - OUT xbox::POBJECT_DIRECTORY *DirectoryObject + IN POBJECT_STRING DirectoryName OPTIONAL, + OUT POBJECT_DIRECTORY *DirectoryObject ) { LOG_FUNC_BEGIN @@ -128,23 +135,25 @@ xbox::ntstatus_xt xbox::ObpReferenceObjectByName( FoundObject = (POBJECT_DIRECTORY)ObpGetObjectHandleContents(RootDirectoryHandle); if (FoundObject == NULL) { - status = STATUS_INVALID_HANDLE; + status = xbox::status_invalid_handle; goto CleanupAndExit; } } if ((RemainingName.Length != 0) && (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)) { - status = STATUS_OBJECT_NAME_INVALID; + status = xbox::status_object_name_invalid; goto CleanupAndExit; } goto OpenRootDirectory; } + FoundObject = ObpRootDirectoryObject; + if ((RemainingName.Length == 0) || (RemainingName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR)) { - status = STATUS_OBJECT_NAME_INVALID; + status = xbox::status_object_name_invalid; goto CleanupAndExit; } @@ -162,7 +171,7 @@ xbox::ntstatus_xt xbox::ObpReferenceObjectByName( if (RemainingName.Length != 0) { if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) { - status = STATUS_OBJECT_NAME_INVALID; + status = xbox::status_object_name_invalid; goto CleanupAndExit; } } else { @@ -380,6 +389,25 @@ xbox::void_xt xbox::ObDissectName(OBJECT_STRING Path, POBJECT_STRING FirstName, return; } +static inline xbox::HANDLE ObpGetHandleByObjectThenDereferenceInline(const xbox::PVOID Object, xbox::ntstatus_xt& result) { + xbox::HANDLE newHandle = nullptr; + + if (xbox::nt_success(result)) { + xbox::KIRQL oldIrql = xbox::KeRaiseIrqlToDpcLevel(); + + newHandle = xbox::ObpCreateObjectHandle(Object); + + xbox::KfLowerIrql(oldIrql); + + if (newHandle == nullptr) { + xbox::ObfDereferenceObject(Object); + result = xbox::status_insufficient_resources; + } + } + + return newHandle; +} + // ****************************************************************** // * 0x00EF - ObCreateObject() // ****************************************************************** @@ -444,7 +472,7 @@ XBSYSAPI EXPORTNUM(239) xbox::ntstatus_xt NTAPI xbox::ObCreateObject POBJECT_HEADER ObjectHeader = (POBJECT_HEADER)(ObjectNameInfo + 1); ObjectNameInfo->ChainLink = NULL; ObjectNameInfo->Directory = NULL; - ObjectNameInfo->Name.Buffer = (PSTR)((PUCHAR)&ObjectHeader->Body + ObjectBodySize); + ObjectNameInfo->Name.Buffer = (PSTR)((PUCHAR)&ObjectHeader->Body + ObjectBodySize); ObjectNameInfo->Name.Length = ElementName.Length; ObjectNameInfo->Name.MaximumLength = ElementName.Length; @@ -772,10 +800,46 @@ XBSYSAPI EXPORTNUM(243) xbox::ntstatus_xt NTAPI xbox::ObOpenObjectByName LOG_FUNC_ARG_OUT(Handle) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); - assert(false); +#ifdef CXBX_KERNEL_REWORK_ENABLED + PVOID Object; + ntstatus_xt result = ObpReferenceObjectByName(ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, ObjectType, ParseContext, &Object); - RETURN(xbox::status_success); + *Handle = ObpGetHandleByObjectThenDereferenceInline(Object, result); +#else + + ntstatus_xt result = STATUS_OBJECT_PATH_NOT_FOUND; + + // Use this place for any interface implementation since + // it is origin of creating new handle. In other case, "ObpCreateObjectHandle" handle it directly. + // But global variables with POBJECT_DIRECTORY are not initialized properly. + // Along with IoCreateSymbolicLink for ObSymbolicLinkObjectType linkage in order to work. + if (ObjectType == &ObSymbolicLinkObjectType) { + EmuNtSymbolicLinkObject* symbolicLinkObject = + FindNtSymbolicLinkObjectByName(PSTRING_to_string(ObjectAttributes->ObjectName)); + + if (symbolicLinkObject != nullptr) + { + // Return a new handle (which is an EmuHandle, actually) : + *Handle = symbolicLinkObject->NewHandle(); + result = xbox::status_success; + } + + if (!nt_success(result)) { + EmuLog(LOG_LEVEL::WARNING, "NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(result)); + } + else { + EmuLog(LOG_LEVEL::DEBUG, "NtOpenSymbolicLinkObject LinkHandle^ = 0x%.8X", *Handle); + } + } + else { + LOG_UNIMPLEMENTED(); + assert(false); + result = xbox::status_success; + } +#endif + + RETURN(result); } // ****************************************************************** @@ -794,10 +858,17 @@ XBSYSAPI EXPORTNUM(244) xbox::ntstatus_xt NTAPI xbox::ObOpenObjectByPointer LOG_FUNC_ARG_OUT(Handle) LOG_FUNC_END; +#ifdef CXBX_KERNEL_REWORK_ENABLED + ntstatus_xt result = ObReferenceObjectByPointer(Object, ObjectType); + + *Handle = ObpGetHandleByObjectThenDereferenceInline(Object, result); + RETURN(result); +#else LOG_UNIMPLEMENTED(); assert(false); RETURN(xbox::status_success); +#endif } // ****************************************************************** diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 8f90196ac..da4c41c36 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -1072,10 +1072,10 @@ XBSYSAPI EXPORTNUM(289) xbox::void_xt NTAPI xbox::RtlInitAnsiString LOG_FUNC_ARG(SourceString) LOG_FUNC_END; - DestinationString->Buffer = SourceString; + DestinationString->Buffer = const_cast(SourceString); if (SourceString != NULL) { CCHAR *pSourceString = (CCHAR*)(SourceString); - DestinationString->Buffer = SourceString; + DestinationString->Buffer = const_cast(SourceString); DestinationString->Length = (USHORT)strlen(pSourceString); DestinationString->MaximumLength = DestinationString->Length + 1; } diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index 1625c5ea8..5bd167979 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -1520,7 +1520,10 @@ __declspec(noreturn) void CxbxKrnlInit InitXboxThread(); g_AffinityPolicy->SetAffinityXbox(); - xbox::ObInitSystem(); + if (!xbox::ObInitSystem()) { + // TODO: Replace EmuLogEx to CxbxKrnlCleanupEx when ObInitSystem's calls are properly implement. + EmuLogEx(LOG_PREFIX_INIT, LOG_LEVEL::WARNING, "Unable to intialize xbox::ObInitSystem."); + } xbox::KiInitSystem(); EmuX86_Init(); diff --git a/src/core/kernel/support/EmuFile.cpp b/src/core/kernel/support/EmuFile.cpp index 26faf4d37..71e501ea3 100644 --- a/src/core/kernel/support/EmuFile.cpp +++ b/src/core/kernel/support/EmuFile.cpp @@ -276,7 +276,7 @@ const std::string DeviceHarddisk0Partition20 = DeviceHarddisk0PartitionPrefix + const char CxbxDefaultXbeDriveLetter = 'D'; int CxbxDefaultXbeDriveIndex = -1; -EmuNtSymbolicLinkObject* NtSymbolicLinkObjects[26]; +EmuNtSymbolicLinkObject* NtSymbolicLinkObjects['Z' - 'A' + 1]; std::vector Devices; EmuHandle::EmuHandle(EmuNtObject* ntObject) @@ -360,11 +360,19 @@ std::wstring string_to_wstring(std::string const & src) std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src) { -return std::wstring(src->Buffer, src->Length / sizeof(NtDll::WCHAR)); + if (src == nullptr) { + return L""; + } + + return std::wstring(src->Buffer, src->Length / sizeof(NtDll::WCHAR)); } std::string PSTRING_to_string(xbox::PSTRING const & src) { + if (src == nullptr) { + return ""; + } + return std::string(src->Buffer, src->Length); } @@ -461,13 +469,13 @@ NTSTATUS CxbxConvertFilePath( // Assume relative to Xbe path NtSymbolicLinkObject = FindNtSymbolicLinkObjectByRootHandle(g_hCurDir); } - else if (*RootDirectory == (NtDll::HANDLE)-3) { + 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 == (NtDll::HANDLE)-4) { + 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 @@ -705,7 +713,6 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin HostSymbolicLinkPath = HostSymbolicLinkPath + ExtraPath; } - SHCreateDirectoryEx(NULL, HostSymbolicLinkPath.c_str(), NULL); 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) {