mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 00:37:23 +01:00
Processing (Windows): prefers NT APIs
This commit is contained in:
@@ -140,40 +140,60 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
|
||||
int32_t timeout = instance.config.general.processingTimeout;
|
||||
FF_AUTO_CLOSE_FD HANDLE hProcess = handle->pid;
|
||||
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = handle->pipeRead;
|
||||
FF_AUTO_CLOSE_FD HANDLE hReadEvent = NULL;
|
||||
handle->pid = INVALID_HANDLE_VALUE;
|
||||
handle->pipeRead = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (timeout >= 0 && !NT_SUCCESS(NtCreateEvent(&hReadEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE)))
|
||||
return "NtCreateEvent() failed";
|
||||
|
||||
char str[FF_PIPE_BUFSIZ];
|
||||
DWORD nRead = 0;
|
||||
OVERLAPPED overlapped = {};
|
||||
// ReadFile always completes synchronously if the pipe is not created with FILE_FLAG_OVERLAPPED
|
||||
uint32_t nRead = 0;
|
||||
IO_STATUS_BLOCK iosb = {};
|
||||
do
|
||||
{
|
||||
if (!ReadFile(hChildPipeRead, str, sizeof(str), &nRead, &overlapped))
|
||||
NTSTATUS status = NtReadFile(
|
||||
hChildPipeRead,
|
||||
hReadEvent,
|
||||
NULL,
|
||||
NULL,
|
||||
&iosb,
|
||||
str,
|
||||
(ULONG) sizeof(str),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (status == STATUS_PENDING)
|
||||
{
|
||||
switch (GetLastError())
|
||||
switch (NtWaitForSingleObject(hReadEvent, TRUE, &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 }))
|
||||
{
|
||||
case ERROR_IO_PENDING:
|
||||
if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, timeout < 0 ? INFINITE : (DWORD) timeout, FALSE))
|
||||
{
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
||||
return NULL;
|
||||
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "GetOverlappedResultEx(hChildPipeRead) failed";
|
||||
}
|
||||
case STATUS_WAIT_0:
|
||||
status = iosb.Status;
|
||||
break;
|
||||
|
||||
case ERROR_BROKEN_PIPE:
|
||||
goto exit;
|
||||
case STATUS_TIMEOUT:
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "NtReadFile(hChildPipeRead) timed out";
|
||||
|
||||
default:
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "ReadFile(hChildPipeRead) failed";
|
||||
return "WaitForSingleObject(hReadEvent) failed";
|
||||
}
|
||||
}
|
||||
|
||||
if (status == STATUS_PIPE_BROKEN || status == STATUS_END_OF_FILE)
|
||||
goto exit;
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "NtReadFile(hChildPipeRead) failed";
|
||||
}
|
||||
|
||||
nRead = (uint32_t) iosb.Information;
|
||||
ffStrbufAppendNS(buffer, nRead, str);
|
||||
} while (nRead > 0);
|
||||
|
||||
|
||||
@@ -893,3 +893,23 @@ NTSYSAPI NTSTATUS NTAPI NtQueryInformationToken(
|
||||
_Out_ PULONG ReturnLength
|
||||
);
|
||||
#define NtCurrentProcessToken() ((HANDLE)(LONG_PTR)-4) // for NtQueryInformationToken only; Windows 8+
|
||||
|
||||
NTSYSAPI NTSTATUS NTAPI NtReadFile(
|
||||
_In_ HANDLE FileHandle,
|
||||
_In_opt_ HANDLE Event,
|
||||
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
|
||||
_In_opt_ PVOID ApcContext,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_Out_writes_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Length,
|
||||
_In_opt_ PLARGE_INTEGER ByteOffset,
|
||||
_In_opt_ PULONG Key
|
||||
);
|
||||
|
||||
NTSYSAPI NTSTATUS NTAPI NtCreateEvent(
|
||||
_Out_ PHANDLE EventHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_ EVENT_TYPE EventType,
|
||||
_In_ BOOLEAN InitialState
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user