mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
IO (Windows): enhances openat
This commit is contained in:
@@ -254,4 +254,5 @@ bool ffRemoveFile(const char* fileName);
|
||||
#ifdef _WIN32
|
||||
// Only O_RDONLY is supported
|
||||
HANDLE openat(HANDLE dfd, const char* fileName, bool directory);
|
||||
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory);
|
||||
#endif
|
||||
|
||||
+35
-18
@@ -3,8 +3,8 @@
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "util/windows/nt.h"
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
@@ -102,31 +102,48 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
return ffAppendFDBuffer(handle, buffer);
|
||||
}
|
||||
|
||||
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
|
||||
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
UNICODE_STRING fileNameW;
|
||||
ret = RtlAnsiStringToUnicodeString(&fileNameW, &(ANSI_STRING) {
|
||||
.Length = (USHORT) strlen(fileName),
|
||||
.Buffer = (PCHAR) fileName
|
||||
}, TRUE);
|
||||
if (!NT_SUCCESS(ret)) return INVALID_HANDLE_VALUE;
|
||||
assert(fileNameLen <= 0x7FFF);
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hFile;
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK iosb = {};
|
||||
ret = NtOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
|
||||
.Length = sizeof(OBJECT_ATTRIBUTES),
|
||||
.RootDirectory = dfd,
|
||||
.ObjectName = &fileNameW,
|
||||
}, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE));
|
||||
RtlFreeUnicodeString(&fileNameW);
|
||||
|
||||
if(!NT_SUCCESS(ret) || iosb.Information != FILE_OPENED)
|
||||
if(!NT_SUCCESS(NtOpenFile(&hFile,
|
||||
(directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
|
||||
.Length = sizeof(OBJECT_ATTRIBUTES),
|
||||
.RootDirectory = dfd,
|
||||
.ObjectName = &(UNICODE_STRING) {
|
||||
.Buffer = (PWSTR) fileName,
|
||||
.Length = fileNameLen * (USHORT) sizeof(wchar_t),
|
||||
.MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t),
|
||||
},
|
||||
.Attributes = OBJ_CASE_INSENSITIVE,
|
||||
},
|
||||
&iosb,
|
||||
FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0),
|
||||
FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)
|
||||
)))
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
return hFile;
|
||||
}
|
||||
|
||||
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;
|
||||
fileNameW[len] = L'\0';
|
||||
|
||||
for (int i = 0; i < len - 1; ++i)
|
||||
{
|
||||
if (fileNameW[i] == L'/')
|
||||
fileNameW[i] = L'\\';
|
||||
}
|
||||
|
||||
return openatW(dfd, fileNameW, (uint16_t)(len - 1), directory);
|
||||
}
|
||||
|
||||
bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false);
|
||||
|
||||
Reference in New Issue
Block a user