From 680b8925a1c8c22dfd4776debbee66e4b7856fb6 Mon Sep 17 00:00:00 2001 From: skye Date: Sat, 10 Jun 2023 14:04:14 +0100 Subject: [PATCH 01/14] winapi: Implement all `direct.h` functions apart from path manipulation `fnmerge` and `fnsplit` haven't been implemented since I noticed inconsistencies in the documentation relating to them, for now I simply have empty function definitions in the form described by https://www.digitalmars.com/rtl/direct.html (ie no `_` prefix) The status of other functions is as follows: `_chdir`, `_chdrive`: impossible to implement, succeeds without an error code, or change of state in the Xbox `_getcwd`, `_getwd`: impossible to implement, return NULL pointers and sets `errno` to `-EINVAL` `_getdrive`: as before, impossible to implement - returns `0` and sets `errno` to `-EINVAL` (this is the error state described by a combo of MS public documentation and digital mars docs) `_searchpath`: impossible to implement since there is no PATH variable on the Xbox `_mkdir`, `_rmdir`: implemented, testing required, however --- lib/xboxrt/libc_extensions/direct.c | 111 ++++++++++++++++++++++++++++ lib/xboxrt/libc_extensions/direct.h | 10 +++ 2 files changed, 121 insertions(+) create mode 100644 lib/xboxrt/libc_extensions/direct.c diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c new file mode 100644 index 000000000..96ae4ee19 --- /dev/null +++ b/lib/xboxrt/libc_extensions/direct.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT + +// SPDX-FileCopyrightText: 2023 ExoSkye + +// Part of Microsoft CRT + +#include +#include +#include +#include + +// Made referencing https://www.digitalmars.com/rtl/direct.html, retrieved 2023-06-10, copyrighted 1999-2018 by Digital Mars + +#define MAXPATH 80 +#define MAXDRIVE 3 +#define MAXDIR 66 +#define MAXFILE 9 +#define MAXEXT 5 + +/* + * These silently succeed, since they wouldn't have any effect on the program at all + */ + +int _chdir(char* path) { + return 0; +} + +int _chdrive(int drive) { + return 0; +} + +/* + * The Xbox has no concept of current working directory, so these can't work + */ + +char* _getcwd(char* buffer, size_t length) { + errno = -EINVAL; + return NULL; +} + +char* _getwd(char* path_name) { + errno = -EINVAL; + return NULL; +} + +int _getdrive(void) { + errno = -EINVAL; + return 0; +} + +/* + * There's no path variable on the Xbox, so this can't work + */ + +char* _searchpath(const char* file) { + errno = -EINVAL; + return NULL; +} + +/* + * Below are the only things that can work + */ + +int _mkdir(const char* pathname) { + BOOL result = CreateDirectoryA( + pathname, + NULL + ); + + if (result == true) { + return 0; + } else { + DWORD err = GetLastError(); + + if (err == ERROR_ALREADY_EXISTS) { + errno = EACCES; + } else if (err == ERROR_PATH_NOT_FOUND) { + errno = ENOENT; + } + + return -1; + } +} + +int _rmdir(const char* pathname) { + BOOL result = RemoveDirectoryA( + pathname + ); + + if (result == true) { + return 0; + } else { + DWORD err = GetLastError(); + + if (err == ERROR_ALREADY_EXISTS) { + errno = EACCES; + } else if (err == ERROR_PATH_NOT_FOUND) { + errno = ENOENT; + } + + return -1; + } +} + +void fnmerge(char* path, const char* drive, const char* dir, const char* name, const char* ext) { + +} + +void fnsplit(const char* path, char* drive, char* dir, char* name, char* ext) { + +} \ No newline at end of file diff --git a/lib/xboxrt/libc_extensions/direct.h b/lib/xboxrt/libc_extensions/direct.h index e7244239a..529397574 100644 --- a/lib/xboxrt/libc_extensions/direct.h +++ b/lib/xboxrt/libc_extensions/direct.h @@ -3,3 +3,13 @@ // SPDX-FileCopyrightText: 2020 Jannik Vogel // Part of Microsoft CRT + +int _chdir(char* path); +int _chdrive(int drive); +char* _getcwd(char* buffer, size_t length); +char* _getwd(char* path_name); +int _getdrive(void); +int _mkdir(const char* pathname); +int _rmdir(const char* pathname); +void _fnmerge(char* path, const char* drive, const char* dir, const char* name, const char* ext); +char* _searchpath(const char* file); \ No newline at end of file From 18c6acfde8b9706240eb0b6e82e3f0f9da56ca47 Mon Sep 17 00:00:00 2001 From: skye Date: Sat, 10 Jun 2023 14:09:02 +0100 Subject: [PATCH 02/14] winapi: Remove `MAXDIR`, `MAXEXT` and `MAXFILE` constants --- lib/xboxrt/libc_extensions/direct.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 96ae4ee19..b7246e13d 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -13,9 +13,6 @@ #define MAXPATH 80 #define MAXDRIVE 3 -#define MAXDIR 66 -#define MAXFILE 9 -#define MAXEXT 5 /* * These silently succeed, since they wouldn't have any effect on the program at all From 0b37066487c152860a60e3b77d3247cc7adeec84 Mon Sep 17 00:00:00 2001 From: ExoSkye Date: Sun, 11 Jun 2023 06:10:50 +0100 Subject: [PATCH 03/14] winapi: Fix ending newlines in `direct.h` --- lib/xboxrt/libc_extensions/direct.c | 2 +- lib/xboxrt/libc_extensions/direct.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index b7246e13d..77ccc03ca 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -105,4 +105,4 @@ void fnmerge(char* path, const char* drive, const char* dir, const char* name, c void fnsplit(const char* path, char* drive, char* dir, char* name, char* ext) { -} \ No newline at end of file +} diff --git a/lib/xboxrt/libc_extensions/direct.h b/lib/xboxrt/libc_extensions/direct.h index 529397574..16f43a836 100644 --- a/lib/xboxrt/libc_extensions/direct.h +++ b/lib/xboxrt/libc_extensions/direct.h @@ -12,4 +12,4 @@ int _getdrive(void); int _mkdir(const char* pathname); int _rmdir(const char* pathname); void _fnmerge(char* path, const char* drive, const char* dir, const char* name, const char* ext); -char* _searchpath(const char* file); \ No newline at end of file +char* _searchpath(const char* file); From e2f40bf7cecf897a3c09d0b0a6e1e2d4b4640c7d Mon Sep 17 00:00:00 2001 From: ExoSkye Date: Sun, 11 Jun 2023 05:29:14 +0000 Subject: [PATCH 04/14] winapi: Remove `MAXPATH` and `MAXDRIVE` --- lib/xboxrt/libc_extensions/direct.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 77ccc03ca..c263a0b97 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -11,8 +11,6 @@ // Made referencing https://www.digitalmars.com/rtl/direct.html, retrieved 2023-06-10, copyrighted 1999-2018 by Digital Mars -#define MAXPATH 80 -#define MAXDRIVE 3 /* * These silently succeed, since they wouldn't have any effect on the program at all From 72ae76594632e035ade091346582d5046bb50d14 Mon Sep 17 00:00:00 2001 From: ExoSkye Date: Sun, 11 Jun 2023 05:35:57 +0000 Subject: [PATCH 05/14] winapi: Remove uneeded functions --- lib/xboxrt/libc_extensions/direct.c | 23 +---------------------- lib/xboxrt/libc_extensions/direct.h | 2 -- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index c263a0b97..0e89dd283 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -13,7 +13,7 @@ /* - * These silently succeed, since they wouldn't have any effect on the program at all + * TODO: Make a working directory system? */ int _chdir(char* path) { @@ -24,10 +24,6 @@ int _chdrive(int drive) { return 0; } -/* - * The Xbox has no concept of current working directory, so these can't work - */ - char* _getcwd(char* buffer, size_t length) { errno = -EINVAL; return NULL; @@ -43,15 +39,6 @@ int _getdrive(void) { return 0; } -/* - * There's no path variable on the Xbox, so this can't work - */ - -char* _searchpath(const char* file) { - errno = -EINVAL; - return NULL; -} - /* * Below are the only things that can work */ @@ -96,11 +83,3 @@ int _rmdir(const char* pathname) { return -1; } } - -void fnmerge(char* path, const char* drive, const char* dir, const char* name, const char* ext) { - -} - -void fnsplit(const char* path, char* drive, char* dir, char* name, char* ext) { - -} diff --git a/lib/xboxrt/libc_extensions/direct.h b/lib/xboxrt/libc_extensions/direct.h index 16f43a836..76c8b29df 100644 --- a/lib/xboxrt/libc_extensions/direct.h +++ b/lib/xboxrt/libc_extensions/direct.h @@ -11,5 +11,3 @@ char* _getwd(char* path_name); int _getdrive(void); int _mkdir(const char* pathname); int _rmdir(const char* pathname); -void _fnmerge(char* path, const char* drive, const char* dir, const char* name, const char* ext); -char* _searchpath(const char* file); From aa898500457b8b0b5d73536e5c0b51b26963c7f6 Mon Sep 17 00:00:00 2001 From: ExoSkye Date: Fri, 16 Jun 2023 22:31:19 +0000 Subject: [PATCH 06/14] winapi: Add `direct.c` to xboxrt makefile --- lib/xboxrt/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/xboxrt/Makefile b/lib/xboxrt/Makefile index 05b8fc126..90a431513 100644 --- a/lib/xboxrt/Makefile +++ b/lib/xboxrt/Makefile @@ -1,5 +1,6 @@ XBOXRT_SRCS := \ $(NXDK_DIR)/lib/xboxrt/libc_extensions/stat.c \ + $(NXDK_DIR)/lib/xboxrt/libc_extensions/direct.c \ $(NXDK_DIR)/lib/xboxrt/libc_extensions/strings.c \ $(NXDK_DIR)/lib/xboxrt/libc_extensions/wchar.c \ $(NXDK_DIR)/lib/xboxrt/libc_extensions/wchar_ext_.c \ From 8893c029e20514415f1957d3666bce0cb8b7a1b4 Mon Sep 17 00:00:00 2001 From: Kai Date: Sat, 17 Jun 2023 20:43:11 +0100 Subject: [PATCH 07/14] winapi: Add a simple function to convert errors from winapi to errno errors --- lib/xboxrt/libc_extensions/direct.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 0e89dd283..828ba7d32 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -11,6 +11,35 @@ // Made referencing https://www.digitalmars.com/rtl/direct.html, retrieved 2023-06-10, copyrighted 1999-2018 by Digital Mars +static int convert_error(DWORD winerror) +{ + switch (winerror) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_FILENAME_EXCED_RANGE: + case ERROR_BAD_PATHNAME: + return ENOENT; + break; + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + return EEXIST; + break; + case ERROR_NOT_LOCKED: + case ERROR_ACCESS_DENIED: + return EACCES; + break; + case ERROR_INVAID_PARAMETER: + case ERROR_INVALID_FUNCTION: + return EINVAL; + break; + case ERROR_NOT_ENOUGH_MEMORY: + return ENOMEM; + break; + case ERROR_DIR_NOT_EMPTY: + return ENOTEMPTY; + break; + } +} /* * TODO: Make a working directory system? From 6078f613189cd03cfe32b839efc136a5a7df6b79 Mon Sep 17 00:00:00 2001 From: skye Date: Sat, 17 Jun 2023 08:17:03 +0100 Subject: [PATCH 08/14] winapi: Use `assert(0)` to stop the use of stubs --- lib/xboxrt/libc_extensions/direct.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 828ba7d32..2a278046a 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -46,26 +46,23 @@ static int convert_error(DWORD winerror) */ int _chdir(char* path) { - return 0; + assert(0); } int _chdrive(int drive) { - return 0; + assert(0); } char* _getcwd(char* buffer, size_t length) { - errno = -EINVAL; - return NULL; + assert(0); } char* _getwd(char* path_name) { - errno = -EINVAL; - return NULL; + assert(0); } int _getdrive(void) { - errno = -EINVAL; - return 0; + assert(0); } /* From a5e09e0f1fdf77524fa46d8ee298d0a29f0f7fff Mon Sep 17 00:00:00 2001 From: skye Date: Sat, 17 Jun 2023 10:23:41 +0100 Subject: [PATCH 09/14] winapi: Fix -Wreturn-type warnings --- lib/xboxrt/libc_extensions/direct.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 2a278046a..74b0fade2 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -47,22 +47,27 @@ static int convert_error(DWORD winerror) int _chdir(char* path) { assert(0); + return -1; // Unreachable } int _chdrive(int drive) { assert(0); + return -1; // Unreachable } char* _getcwd(char* buffer, size_t length) { assert(0); + return NULL; // Unreachable } char* _getwd(char* path_name) { assert(0); + return NULL; // Unreachable } int _getdrive(void) { assert(0); + return -1; // Unreachable } /* From cd71cb32302a605d4c5d923493e5b283a5f49fe0 Mon Sep 17 00:00:00 2001 From: skye Date: Sun, 18 Jun 2023 08:36:56 +0100 Subject: [PATCH 10/14] winapi: Fix typo --- lib/xboxrt/libc_extensions/direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 74b0fade2..b95b97458 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -28,7 +28,7 @@ static int convert_error(DWORD winerror) case ERROR_ACCESS_DENIED: return EACCES; break; - case ERROR_INVAID_PARAMETER: + case ERROR_INVALID_PARAMETER: case ERROR_INVALID_FUNCTION: return EINVAL; break; From 21fe55124210fd6a8c64537335bdb60eef71db9a Mon Sep 17 00:00:00 2001 From: skye Date: Sun, 18 Jun 2023 08:37:10 +0100 Subject: [PATCH 11/14] winapi: Actually include `assert.h` --- lib/xboxrt/libc_extensions/direct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index b95b97458..deb2c90eb 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -8,6 +8,7 @@ #include #include #include +#include // Made referencing https://www.digitalmars.com/rtl/direct.html, retrieved 2023-06-10, copyrighted 1999-2018 by Digital Mars From 57cded37eeae781916153f9d2f2c03fe3701c3ee Mon Sep 17 00:00:00 2001 From: skye Date: Sun, 18 Jun 2023 08:40:46 +0100 Subject: [PATCH 12/14] winapi: Add fallback to return `EINVAL` --- lib/xboxrt/libc_extensions/direct.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index deb2c90eb..652d97d3d 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -9,9 +9,11 @@ #include #include #include +#include // Made referencing https://www.digitalmars.com/rtl/direct.html, retrieved 2023-06-10, copyrighted 1999-2018 by Digital Mars +// Only call this function in the case there actually is an error static int convert_error(DWORD winerror) { switch (winerror) { @@ -39,6 +41,9 @@ static int convert_error(DWORD winerror) case ERROR_DIR_NOT_EMPTY: return ENOTEMPTY; break; + default: + debugPrint("WARNING: Unknown win32 error code 0x%08x, returning EINVAL", winerror); + return EINVAL; } } From 5ef78d29968b6f9f0b2783ff72cb92908b820473 Mon Sep 17 00:00:00 2001 From: skye Date: Sun, 18 Jun 2023 08:41:40 +0100 Subject: [PATCH 13/14] winapi: Edit functions to actually use the new `convert_error` function --- lib/xboxrt/libc_extensions/direct.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 652d97d3d..2c9a7f07a 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -89,13 +89,7 @@ int _mkdir(const char* pathname) { if (result == true) { return 0; } else { - DWORD err = GetLastError(); - - if (err == ERROR_ALREADY_EXISTS) { - errno = EACCES; - } else if (err == ERROR_PATH_NOT_FOUND) { - errno = ENOENT; - } + errno = convert_error(GetLastError()); return -1; } @@ -109,13 +103,7 @@ int _rmdir(const char* pathname) { if (result == true) { return 0; } else { - DWORD err = GetLastError(); - - if (err == ERROR_ALREADY_EXISTS) { - errno = EACCES; - } else if (err == ERROR_PATH_NOT_FOUND) { - errno = ENOENT; - } + errno = convert_error(GetLastError()); return -1; } From 014d66275c4eb391b9f25b7beabaf1e591c4aa92 Mon Sep 17 00:00:00 2001 From: skye Date: Sun, 18 Jun 2023 08:42:23 +0100 Subject: [PATCH 14/14] winapi: Fix debugPrint format specifier --- lib/xboxrt/libc_extensions/direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/xboxrt/libc_extensions/direct.c b/lib/xboxrt/libc_extensions/direct.c index 2c9a7f07a..64ce9bb32 100644 --- a/lib/xboxrt/libc_extensions/direct.c +++ b/lib/xboxrt/libc_extensions/direct.c @@ -42,7 +42,7 @@ static int convert_error(DWORD winerror) return ENOTEMPTY; break; default: - debugPrint("WARNING: Unknown win32 error code 0x%08x, returning EINVAL", winerror); + debugPrint("WARNING: Unknown win32 error code 0x%08lx, returning EINVAL", winerror); return EINVAL; } }