From d2de3a01bbe65d611aff1983b5b7dc28e40671eb 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 23:28:41 +0800 Subject: [PATCH] IO (Windows): prefers native functions --- src/common/impl/io_windows.c | 17 +++++++++++------ src/common/windows/nt.h | 9 +++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/common/impl/io_windows.c b/src/common/impl/io_windows.c index 241d875d7..d2b5018b1 100644 --- a/src/common/impl/io_windows.c +++ b/src/common/impl/io_windows.c @@ -2,6 +2,7 @@ #include "common/io.h" #include "common/stringUtils.h" #include "common/windows/nt.h" +#include "common/windows/unicode.h" #include @@ -314,13 +315,17 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out) } } - DWORD length = ExpandEnvironmentStringsA(in, NULL, 0); - if (length <= 1) return false; + wchar_t pathInW[MAX_PATH], pathOutW[MAX_PATH]; + ULONG len = (ULONG) strlen(in); + if (!NT_SUCCESS(RtlUTF8ToUnicodeN(pathInW, (ULONG) sizeof(pathInW), &len, in, len))) + return false; + len /= sizeof(wchar_t); // convert from bytes to characters - ffStrbufClear(out); - ffStrbufEnsureFree(out, (uint32_t)length); - ExpandEnvironmentStringsA(in, out->chars, length); - out->length = (uint32_t)length - 1; + size_t outLen; // in characters, including null terminator + if (!NT_SUCCESS(RtlExpandEnvironmentStrings(NULL, pathInW, len, pathOutW, ARRAY_SIZE(pathOutW), &outLen))) + return false; + + ffStrbufSetNWS(out, (uint32_t) outLen - 1, pathOutW); return true; } diff --git a/src/common/windows/nt.h b/src/common/windows/nt.h index 4fe1e00da..4538c834f 100644 --- a/src/common/windows/nt.h +++ b/src/common/windows/nt.h @@ -996,3 +996,12 @@ static inline RTL_USER_PROCESS_PARAMETERS_FULL* ffGetProcessParams() { return (RTL_USER_PROCESS_PARAMETERS_FULL*) NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters; } + +NTSYSAPI NTSTATUS NTAPI RtlExpandEnvironmentStrings( + _In_opt_ PVOID Environment, + _In_reads_(SourceLength) PCWSTR Source, + _In_ SIZE_T SourceLength, + _Out_writes_(DestinationLength) PWSTR Destination, + _In_ SIZE_T DestinationLength, + _Out_opt_ PSIZE_T ReturnLength +);