diff --git a/src/core/kernel/exports/EmuKrnlNt.cpp b/src/core/kernel/exports/EmuKrnlNt.cpp index c4dc8099d..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); } // ****************************************************************** @@ -1448,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 @@ -1466,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!"); } @@ -1704,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 0d8c24e3d..65c43370d 100644 --- a/src/core/kernel/exports/EmuKrnlOb.cpp +++ b/src/core/kernel/exports/EmuKrnlOb.cpp @@ -389,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() // ****************************************************************** @@ -781,31 +800,13 @@ XBSYSAPI EXPORTNUM(243) xbox::ntstatus_xt NTAPI xbox::ObOpenObjectByName LOG_FUNC_ARG_OUT(Handle) LOG_FUNC_END; -#if 0 // Enable when ObInitSystem/IoCreateDevice are functional. - +#ifdef CXBX_KERNEL_REWORK_ENABLED PVOID Object; - HANDLE newHandle = nullptr; ntstatus_xt result = ObpReferenceObjectByName(ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, ObjectAttributes->Attributes, ObjectType, ParseContext, &Object); - if (nt_success(result)) { - KIRQL oldIrql = KeRaiseIrqlToDpcLevel(); - - newHandle = ObpCreateObjectHandle(Object); - - KfLowerIrql(oldIrql); - - if (newHandle == nullptr) { - ObfDereferenceObject(Object); - result = xbox::status_insufficient_resources; - } - } - - *Handle = newHandle; - - RETURN(result); - -#endif + *Handle = ObpGetHandleByObjectThenDereferenceInline(Object, result); +#else ntstatus_xt result = STATUS_OBJECT_PATH_NOT_FOUND; @@ -836,6 +837,7 @@ XBSYSAPI EXPORTNUM(243) xbox::ntstatus_xt NTAPI xbox::ObOpenObjectByName assert(false); result = xbox::status_success; } +#endif RETURN(result); } @@ -856,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 } // ******************************************************************