Global (Windows): prefers RtlUnicodeToUTF8N instead of WideCharToMultiByte

This commit is contained in:
李通洲
2026-03-11 14:55:09 +08:00
parent bdb9593c0d
commit 72bdee7fbf
7 changed files with 45 additions and 34 deletions
+5 -3
View File
@@ -131,11 +131,13 @@ HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool d
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
{
wchar_t fileNameW[MAX_PATH];
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fileName, -1, fileNameW, ARRAY_SIZE(fileNameW));
if (len == 0) return INVALID_HANDLE_VALUE;
ULONG len;
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &len, fileName, (ULONG)strlen(fileName) + 1)))
return INVALID_HANDLE_VALUE;
// Implies `fileNameW[len] = L'\0';` and `len` includes the null terminator
len /= sizeof(wchar_t); // convert from bytes to characters
for (int i = 0; i < len - 1; ++i)
for (uint32_t i = 0; i < len - 1; ++i)
{
if (fileNameW[i] == L'/')
fileNameW[i] = L'\\';
+6 -1
View File
@@ -7,6 +7,7 @@
#include <fileapi.h>
#include <handleapi.h>
#include <io.h>
#include "common/windows/nt.h"
typedef HANDLE FFNativeFD;
#define FF_INVALID_FD INVALID_HANDLE_VALUE
#else
@@ -117,7 +118,11 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
{
#ifdef _WIN32
DWORD attr = GetFileAttributesA(path);
wchar_t wPath[MAX_PATH];
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(wPath, (ULONG) sizeof(wPath), NULL, path, (ULONG)strlen(path) + 1)))
return false;
DWORD attr = GetFileAttributesW(wPath);
if(attr == INVALID_FILE_ATTRIBUTES)
return false;
+23 -13
View File
@@ -1,6 +1,6 @@
#include "unicode.h"
#include <windows.h>
#include "common/windows/nt.h"
void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
{
@@ -10,15 +10,19 @@ void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
return;
}
int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL);
if (size_needed <= 0)
ULONG size_needed = 0;
NTSTATUS status = RtlUnicodeToUTF8N(NULL, 0, &size_needed, source, length * sizeof(wchar_t));
if (size_needed == 0)
{
ffStrbufSetF(result, "WCTMB failed: %u", (unsigned) GetLastError());
ffStrbufSetF(result, "RtlUnicodeToUTF8N failed: %X", (unsigned) status);
return;
}
ffStrbufEnsureFixedLengthFree(result, (uint32_t)size_needed);
WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result->chars, size_needed, NULL, NULL);
result->length = (uint32_t)size_needed;
ffStrbufEnsureFixedLengthFree(result, size_needed);
RtlUnicodeToUTF8N(result->chars, size_needed, &size_needed, source, length * sizeof(wchar_t));
result->length = size_needed;
result->chars[size_needed] = '\0';
}
@@ -27,12 +31,18 @@ void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
if(!length)
return;
int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL);
if (size_needed <= 0)
return;
ULONG size_needed = 0;
NTSTATUS status = RtlUnicodeToUTF8N(NULL, 0, &size_needed, source, length * sizeof(wchar_t));
ffStrbufEnsureFree(result, (uint32_t)size_needed);
WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result->chars + result->length, size_needed, NULL, NULL);
result->length += (uint32_t)size_needed;
if (size_needed == 0)
{
ffStrbufAppendF(result, "RtlUnicodeToUTF8N failed: %X", (unsigned) status);
return;
}
ffStrbufEnsureFree(result, size_needed);
RtlUnicodeToUTF8N(result->chars + result->length, size_needed, &size_needed, source, length * sizeof(wchar_t));
result->length += size_needed;
result->chars[result->length] = '\0';
}
+1 -3
View File
@@ -38,10 +38,8 @@ const char* detectThermalTemp(const FFCPUOptions* options, double* result)
if (options->tempSensor.length > 0)
{
int written = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, options->tempSensor.chars, (int) options->tempSensor.length, querySpec.Name, (int)(ARRAY_SIZE(querySpec.Name) - 1));
if (written == 0)
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(querySpec.Name, (ULONG) sizeof(querySpec.Name), NULL, options->tempSensor.chars, (ULONG)options->tempSensor.length + 1)))
return "Invalid temp sensor string";
querySpec.Name[written] = L'\0';
}
DWORD dataSize = 0;
+5 -6
View File
@@ -99,11 +99,10 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
continue;
}
char name[128];
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, ARRAY_SIZE(name), NULL, NULL);
FF_DEBUG("Adapter %u name: '%s'", (unsigned)adapter->IfIndex, name);
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateWS(adapter->FriendlyName);
FF_DEBUG("Adapter %u name: '%s'", (unsigned)adapter->IfIndex, name.chars);
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
{
FF_DEBUG("Skipping adapter %u (name doesn't match prefix '%.*s')",
(unsigned)adapter->IfIndex, (int)options->namePrefix.length, options->namePrefix.chars);
@@ -121,10 +120,10 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}
processedCount++;
FF_DEBUG("Creating result item for adapter %u ('%s')", (unsigned)adapter->IfIndex, name);
FF_DEBUG("Creating result item for adapter %u ('%s')", (unsigned)adapter->IfIndex, name.chars);
FFLocalIpResult* item = (FFLocalIpResult*) ffListAdd(results);
ffStrbufInitS(&item->name, name);
ffStrbufInitMove(&item->name, &name);
ffStrbufInit(&item->ipv4);
ffStrbufInit(&item->ipv6);
ffStrbufInit(&item->mac);
+3 -4
View File
@@ -46,9 +46,8 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
if (options->defaultRouteOnly && !isDefaultRoute)
continue;
char name[128];
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, ARRAY_SIZE(name), NULL, NULL);
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateWS(adapter->FriendlyName);
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
MIB_IF_ROW2 ifRow = { .InterfaceIndex = adapter->IfIndex };
@@ -56,7 +55,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
{
FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result);
*counters = (FFNetIOResult) {
.name = ffStrbufCreateS(name),
.name = ffStrbufCreateMove(&name),
.txBytes = ifRow.OutOctets,
.rxBytes = ifRow.InOctets,
.txPackets = (ifRow.OutUcastPkts + ifRow.OutNUcastPkts),
+2 -4
View File
@@ -25,10 +25,8 @@
static bool getFileVersion(const FFstrbuf* exePath, const wchar_t* stringName, FFstrbuf* version)
{
wchar_t exePathW[PATH_MAX + 1];
int len = MultiByteToWideChar(CP_UTF8, 0, exePath->chars, (int)exePath->length, exePathW, ARRAY_SIZE(exePathW));
if (len <= 0) return false;
assert(len < (int) ARRAY_SIZE(exePathW));
exePathW[len] = L'\0';
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(exePathW, (ULONG) sizeof(exePathW), NULL, exePath->chars, (ULONG)exePath->length + 1)))
return false;
return ffGetFileVersion(exePathW, stringName, version);
}