[NTDLL_WINETEST][NTOS:PS] Fix a few NtQueryInformationProcess(Process*) handling cases (#8136)

* [NTDLL_WINETEST] `test_query_process_debug_object_handle()`: one WINESYNC

Cherry-pick WineTest part of:
52d733b5c4
server: Implement retrieving the debug object of a process.
by: Alexandre Julliard <julliard@winehq.org>

* [NTOS:PS] Fix `NtQueryInformationProcess(ProcessDebugObjectHandle)`

Close the retrieved `DebugPort` on failure.
Addendum to commit 1e172203a (r55734).

* [NTOS:PS] Optimize `NtQueryInformationProcess(ProcessWow64Information)` on 32-bit.

No need to do the ExAcquire/ReleaseRundownProtection rigamarole since
we aren't retrieving the `Process->Wow64Process` on 32-bit builds.
Addendum to commit 1e172203a (r55734).

* [NTOS:PS] Fix `NtQueryInformationProcess(ProcessExecuteFlags)`

s/return/break/ on a failure case.
Addendum to commit 1e172203a (r55734).

* [NTOS:PS] NtQueryInformationProcess(): Optimize `*ReturnLength` assignment

Enter the SEH block only if we know we'll have to set `*ReturnLength` on return.
Addendum to commit 2278c2914 (r23175).
This commit is contained in:
Serge Gautherie 2025-06-19 18:47:31 +02:00 committed by GitHub
parent b8c5e9c209
commit 9832737843
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 22 deletions

View file

@ -1582,12 +1582,20 @@ static void test_query_process_debug_object_handle(int argc, char **argv)
debug_object = (HANDLE)0xdeadbeef; debug_object = (HANDLE)0xdeadbeef;
status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugObjectHandle, status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugObjectHandle,
&debug_object, sizeof(debug_object), NULL); &debug_object, sizeof(debug_object), NULL);
#ifndef __REACTOS__
todo_wine todo_wine
#endif
ok(status == STATUS_SUCCESS, ok(status == STATUS_SUCCESS,
"Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status); "Expected NtQueryInformationProcess to return STATUS_SUCCESS, got 0x%08x\n", status);
#ifndef __REACTOS__
todo_wine todo_wine
#endif
ok(debug_object != NULL, ok(debug_object != NULL,
"Expected debug object handle to be non-NULL, got %p\n", debug_object); "Expected debug object handle to be non-NULL, got %p\n", debug_object);
#ifdef __REACTOS__
status = NtClose( debug_object );
ok( !status, "NtClose failed %x\n", status );
#endif
for (;;) for (;;)
{ {

View file

@ -907,7 +907,7 @@ NtQueryInformationProcess(
case ProcessDebugObjectHandle: case ProcessDebugObjectHandle:
{ {
HANDLE DebugPort = 0; HANDLE DebugPort = NULL;
if (ProcessInformationLength != sizeof(HANDLE)) if (ProcessInformationLength != sizeof(HANDLE))
{ {
@ -927,7 +927,7 @@ NtQueryInformationProcess(
NULL); NULL);
if (!NT_SUCCESS(Status)) break; if (!NT_SUCCESS(Status)) break;
/* Get the debug port */ /* Get the debug port. Continue even if this fails. */
Status = DbgkOpenProcessDebugPort(Process, PreviousMode, &DebugPort); Status = DbgkOpenProcessDebugPort(Process, PreviousMode, &DebugPort);
/* Let go of the process */ /* Let go of the process */
@ -941,7 +941,11 @@ NtQueryInformationProcess(
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
/* Get the exception code */ if (DebugPort)
ObCloseHandle(DebugPort, PreviousMode);
/* Get the exception code.
* Note: This overwrites any previous failure status. */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} }
_SEH2_END; _SEH2_END;
@ -1040,23 +1044,24 @@ NtQueryInformationProcess(
NULL); NULL);
if (!NT_SUCCESS(Status)) break; if (!NT_SUCCESS(Status)) break;
#ifdef _WIN64
/* Make sure the process isn't dying */ /* Make sure the process isn't dying */
if (ExAcquireRundownProtection(&Process->RundownProtect)) if (ExAcquireRundownProtection(&Process->RundownProtect))
{ {
/* Get the WOW64 process structure */ /* Get the WOW64 process structure */
#ifdef _WIN64
Wow64 = (ULONG_PTR)Process->Wow64Process; Wow64 = (ULONG_PTR)Process->Wow64Process;
#else
Wow64 = 0;
#endif
/* Release the lock */ /* Release the lock */
ExReleaseRundownProtection(&Process->RundownProtect); ExReleaseRundownProtection(&Process->RundownProtect);
} }
#endif
/* Dereference the process */
ObDereferenceObject(Process);
/* Protect write with SEH */ /* Protect write with SEH */
_SEH2_TRY _SEH2_TRY
{ {
/* Return whether or not we have a debug port */ /* Return the Wow64 process information */
*(PULONG_PTR)ProcessInformation = Wow64; *(PULONG_PTR)ProcessInformation = Wow64;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@ -1065,9 +1070,6 @@ NtQueryInformationProcess(
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} }
_SEH2_END; _SEH2_END;
/* Dereference the process */
ObDereferenceObject(Process);
break; break;
} }
@ -1086,7 +1088,8 @@ NtQueryInformationProcess(
if (ProcessHandle != NtCurrentProcess()) if (ProcessHandle != NtCurrentProcess())
{ {
return STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
break;
} }
/* Get the options */ /* Get the options */
@ -1130,18 +1133,22 @@ NtQueryInformationProcess(
Status = STATUS_INVALID_INFO_CLASS; Status = STATUS_INVALID_INFO_CLASS;
} }
/* Protect write with SEH */ /* Check if caller wants the return length and if there is one */
_SEH2_TRY if (ReturnLength != NULL && Length != 0)
{ {
/* Check if caller wanted return length */ /* Protect write with SEH */
if ((ReturnLength) && (Length)) *ReturnLength = Length; _SEH2_TRY
{
*ReturnLength = Length;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code.
* Note: This overwrites any previous failure status. */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
return Status; return Status;
} }