mirror of
https://codeberg.org/1414codeforge/ubgpsuite.git
synced 2025-06-05 21:29:11 +02:00
[*] Initial commit
This commit is contained in:
159
lonetix/sys/fs_windows.c
Executable file
159
lonetix/sys/fs_windows.c
Executable file
@@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
/**
|
||||
* \file sys/fs_windows.c
|
||||
*
|
||||
* System specific filesystem utilities over Windows.
|
||||
*
|
||||
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
|
||||
* \author Lorenzo Cogotti
|
||||
*/
|
||||
|
||||
#include "sys/fs.h"
|
||||
#include "sys/err_local.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#error "Sorry, not fully implemented yet!"
|
||||
|
||||
typedef union {
|
||||
wchar_t wstr[_MAX_PATH + 1];
|
||||
char str[(_MAX_PATH + 1) * sizeof(wchar_t)];
|
||||
} Pathbuf;
|
||||
|
||||
static THREAD_LOCAL Pathbuf pathbuf;
|
||||
|
||||
static wchar_t *Sys_Utf8PathToW(const char *path)
|
||||
{
|
||||
int n = MultiByteToWideChar(CP_UTF8, 0, dir, -1, pathbuf.wstr, ARRAY_SIZE(pathbuf.wstr));
|
||||
if (n < 0) {
|
||||
Sys_SetErrStat(GetLastError(), "MultiByteToWideChar() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pathbuf.wstr;
|
||||
}
|
||||
|
||||
static char *Sys_WPathToUtf8(const wchar_t *path)
|
||||
{
|
||||
int n = WideCharToMultiByte(CP_UTF16, 0, path, -1, pathbuf.str, sizeof(pathbuf.str));
|
||||
if (n < 0) {
|
||||
Sys_GetErrStat(GetLastError(), "WideCharToMultiByte() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pathbuf.str;
|
||||
}
|
||||
|
||||
Judgement Sys_SetEof(Fildes fd)
|
||||
{
|
||||
if (!SetEndOfFile(fd)) {
|
||||
Sys_SetErrStat(GetLastError(), "SetEndOfFile() failed");
|
||||
return NG;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void Sys_Fclose(Fildes fd)
|
||||
{
|
||||
CloseHandle(fd);
|
||||
}
|
||||
|
||||
typedef struct FileList dfFileList;
|
||||
struct FileList {
|
||||
FileList *next;
|
||||
unsigned len;
|
||||
char name[1]; // dynamically sized len+1
|
||||
};
|
||||
|
||||
char **Sys_ListFiles(const char *dir, unsigned *nfiles, const char *pat)
|
||||
{
|
||||
if (!pat)
|
||||
pat = "";
|
||||
|
||||
int flag;
|
||||
if (strcmp(pat, "/") == 0) {
|
||||
pat = "";
|
||||
flag = _A_SUBDIR;
|
||||
} else {
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
char *search = (char *) alloca(strlen(dir) + 1 + 1 + strlen(pat) + 1);
|
||||
if (sprintf(search, "%s\\*%s", dir, pat) < 0) {
|
||||
Sys_SetErrStat(errno, "sprintf() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wchar_t *wsearch = Sys_Utf8PathToW(search);
|
||||
if (!wsearch)
|
||||
return NULL; // error already set
|
||||
|
||||
FileList *entries = NULL;
|
||||
unsigned count = 0;
|
||||
size_t nchars = 0;
|
||||
|
||||
errno = 0;
|
||||
|
||||
struct _wfinddata_t finddata;
|
||||
intptr_t findhn = _wfindfirst(wsearch, &finddata);
|
||||
if (findhn != -1) {
|
||||
// Scan directory
|
||||
do {
|
||||
if (finddata.attrib & flag) {
|
||||
// remember this file
|
||||
char *path = Sys_WPathToUtf8(finddata.name);
|
||||
size_t n = strlen(path);
|
||||
|
||||
count++;
|
||||
nchars += n + 1;
|
||||
|
||||
FileList *e = (FileList *) alloca(sizeof(*e) + n);
|
||||
e->next = entries;
|
||||
e->len = n;
|
||||
memcpy(e->name, path, n + 1);
|
||||
|
||||
entries = e;
|
||||
}
|
||||
} while (_wfindnext(findhn, &finddata) == 0);
|
||||
}
|
||||
if (errno != 0) {
|
||||
Sys_SetErrStat(errno, "_wfindfirst()/_wfindnext()");
|
||||
goto fail;
|
||||
}
|
||||
_findclose(findhn);
|
||||
|
||||
char **files = (char **) malloc(sizeof(*files) * (count + 1) + nchars);
|
||||
if (!files) {
|
||||
Sys_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *namep = (char *) (files + count + 1);
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
files[i] = namep;
|
||||
|
||||
size_t n = entries->len + 1;
|
||||
memcpy(namep, entries->name, n);
|
||||
namep += n;
|
||||
|
||||
entries = entries->next;
|
||||
}
|
||||
files[count] = NULL;
|
||||
|
||||
if (nfiles)
|
||||
*nfiles = count;
|
||||
|
||||
return files;
|
||||
|
||||
fail:
|
||||
_findclose(findhn);
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user