From bdb9593c0dc879769af8e82eeee6a0099cec9d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 11 Mar 2026 14:34:05 +0800 Subject: [PATCH] Platform (Windows): prefers data in PEB --- src/common/impl/FFPlatform_windows.c | 31 ++++++----- src/common/windows/nt.h | 83 ++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/src/common/impl/FFPlatform_windows.c b/src/common/impl/FFPlatform_windows.c index e4b99e010..d0bcb5889 100644 --- a/src/common/impl/FFPlatform_windows.c +++ b/src/common/impl/FFPlatform_windows.c @@ -17,20 +17,29 @@ static void getExePath(FFPlatform* platform) { wchar_t exePathW[MAX_PATH]; - DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH); - if (exePathWLen == 0 || exePathWLen >= MAX_PATH) return; - FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(exePathW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW( + ffGetProcessParams()->ImagePathName.Buffer, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); if (hPath != INVALID_HANDLE_VALUE) { DWORD len = GetFinalPathNameByHandleW(hPath, exePathW, MAX_PATH, FILE_NAME_OPENED); if (len > 0 && len < MAX_PATH) - exePathWLen = len; + { + ffStrbufSetNWS(&platform->exePath, len, exePathW); + if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\")) + ffStrbufSubstrAfter(&platform->exePath, 3); + } } - ffStrbufSetNWS(&platform->exePath, exePathWLen, exePathW); - if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\")) - ffStrbufSubstrAfter(&platform->exePath, 3); + if (platform->exePath.length == 0) + ffStrbufSetNWS(&platform->exePath, ffGetProcessParams()->ImagePathName.Length / 2, ffGetProcessParams()->ImagePathName.Buffer); + ffStrbufReplaceAllC(&platform->exePath, '\\', '/'); } @@ -286,13 +295,7 @@ static void getSystemArchitecture(FFPlatformSysinfo* info) static void getCwd(FFPlatform* platform) { - static_assert( - offsetof(RTL_USER_PROCESS_PARAMETERS, Reserved2[5]) == sizeof(ULONG) * 5 + sizeof(HANDLE) * 4 - #if __amd64__ || __aarch64__ - + sizeof(ULONG) // Padding - #endif - , "Structure layout mismatch detected."); - PCURDIR cwd = (PCURDIR) &NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->Reserved2[5]; + PCURDIR cwd = &ffGetProcessParams()->CurrentDirectory; ffStrbufSetNWS(&platform->cwd, cwd->DosPath.Length / sizeof(WCHAR), cwd->DosPath.Buffer); ffStrbufReplaceAllC(&platform->cwd, '\\', '/'); ffStrbufEnsureEndsWithC(&platform->cwd, '/'); diff --git a/src/common/windows/nt.h b/src/common/windows/nt.h index 7758396d4..4fe1e00da 100644 --- a/src/common/windows/nt.h +++ b/src/common/windows/nt.h @@ -913,3 +913,86 @@ NTSYSAPI NTSTATUS NTAPI NtCreateEvent( _In_ EVENT_TYPE EventType, _In_ BOOLEAN InitialState ); + +NTSYSAPI NTSTATUS NTAPI NtQueryAttributesFile( + _In_ PCOBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PFILE_BASIC_INFORMATION FileInformation +); + +NTSYSAPI NTSTATUS NTAPI RtlUnicodeToUTF8N( + _Out_writes_bytes_to_(UTF8StringMaxByteCount, *UTF8StringActualByteCount) PCHAR UTF8StringDestination, + _In_ ULONG UTF8StringMaxByteCount, + _Out_opt_ PULONG UTF8StringActualByteCount, + _In_reads_bytes_(UnicodeStringByteCount) PCWCH UnicodeStringSource, + _In_ ULONG UnicodeStringByteCount +); + +NTSYSAPI NTSTATUS NTAPI RtlUTF8ToUnicodeN( + _Out_writes_bytes_to_(UnicodeStringMaxByteCount, *UnicodeStringActualByteCount) PWSTR UnicodeStringDestination, + _In_ ULONG UnicodeStringMaxByteCount, + _Out_opt_ PULONG UnicodeStringActualByteCount, + _In_reads_bytes_(UTF8StringByteCount) PCCH UTF8StringSource, + _In_ ULONG UTF8StringByteCount +); + +#define RTL_MAX_DRIVE_LETTERS 32 +typedef struct _RTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + STRING DosPath; +} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; + +typedef struct _RTL_USER_PROCESS_PARAMETERS_FULL +{ + ULONG MaximumLength; + ULONG Length; + + ULONG Flags; + ULONG DebugFlags; + + HANDLE ConsoleHandle; + ULONG ConsoleFlags; + HANDLE StandardInput; + HANDLE StandardOutput; + HANDLE StandardError; + + CURDIR CurrentDirectory; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + PVOID Environment; + + ULONG StartingX; + ULONG StartingY; + ULONG CountX; + ULONG CountY; + ULONG CountCharsX; + ULONG CountCharsY; + ULONG FillAttribute; + + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; + + // Windows Vista + ULONG_PTR EnvironmentSize; + // Windows 7 + ULONG_PTR EnvironmentVersion; + + // Windows 8 + PVOID PackageDependencyData; + ULONG ProcessGroupId; + + // ... +} RTL_USER_PROCESS_PARAMETERS_FULL; + +static inline RTL_USER_PROCESS_PARAMETERS_FULL* ffGetProcessParams() +{ + return (RTL_USER_PROCESS_PARAMETERS_FULL*) NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters; +}