uwp: fix dirent. Implement access() and stat()

Use UWP version of FindFirstFileEx
Implement basic access() and stat()
Add home dir to list of drives
Allow external storage folders to be added and scanned for games
This commit is contained in:
flyinghead 2021-12-01 14:40:17 +01:00
parent 6a8f1b941e
commit 280c159078
3 changed files with 302 additions and 257 deletions

View File

@ -29,6 +29,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#define FindFirstFileExW FindFirstFileExFromAppW
#endif
/* Indicates that d_type field is available in dirent structure */ /* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE #define _DIRENT_HAVE_D_TYPE

View File

@ -87,6 +87,26 @@ inline int stat(const char *filename, struct stat *buf)
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
#ifdef TARGET_UWP
WIN32_FILE_ATTRIBUTE_DATA attrs;
bool rc = GetFileAttributesExFromAppW(wname.c_str(), GetFileExInfoStandard, &attrs);
if (!rc)
return -1;
memset(buf, 0, sizeof(struct stat));
if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
buf->st_mode = S_IFDIR;
else
buf->st_mode = S_IFREG;
buf->st_size = attrs.nFileSizeLow;
constexpr UINT64 WINDOWS_TICK = 10000000u;
constexpr UINT64 SEC_TO_UNIX_EPOCH = 11644473600llu;
buf->st_ctime = (unsigned)(((UINT64)attrs.ftCreationTime.dwLowDateTime | ((UINT64)attrs.ftCreationTime.dwHighDateTime << 32)) / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
buf->st_mtime = (unsigned)(((UINT64)attrs.ftLastWriteTime.dwLowDateTime | ((UINT64)attrs.ftLastWriteTime.dwHighDateTime << 32)) / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
buf->st_atime =(unsigned)(((UINT64)attrs.ftLastAccessTime.dwLowDateTime | ((UINT64)attrs.ftLastAccessTime.dwHighDateTime << 32)) / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
return 0;
#else
struct _stat _st; struct _stat _st;
int rc = _wstat(wname.c_str(), &_st); int rc = _wstat(wname.c_str(), &_st);
buf->st_ctime = _st.st_ctime; buf->st_ctime = _st.st_ctime;
@ -102,6 +122,7 @@ inline int stat(const char *filename, struct stat *buf)
buf->st_size = _st.st_size; buf->st_size = _st.st_size;
return rc; return rc;
#endif
} }
inline int access(const char *filename, int how) inline int access(const char *filename, int how)
@ -111,7 +132,18 @@ inline int access(const char *filename, int how)
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
#ifdef TARGET_UWP
WIN32_FILE_ATTRIBUTE_DATA attrs;
bool rc = GetFileAttributesExFromAppW(wname.c_str(), GetFileExInfoStandard, &attrs);
if (!rc)
return -1;
if (how != R_OK && (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
return -1;
else
return 0;
#else
return ::_waccess(wname.c_str(), how); return ::_waccess(wname.c_str(), how);
#endif
} }
inline int mkdir(const char *path, mode_t mode) { inline int mkdir(const char *path, mode_t mode) {

View File

@ -109,6 +109,15 @@ void select_file_popup(const char *prompt, StringCallback callback,
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
if ((drives & (1 << i)) != 0) if ((drives & (1 << i)) != 0)
subfolders.push_back(std::string(1, (char)('A' + i)) + ":\\"); subfolders.push_back(std::string(1, (char)('A' + i)) + ":\\");
#ifdef TARGET_UWP
// Add the home directory to the list of drives as it's not accessible from the root
std::string home;
const char *home_drive = nowide::getenv("HOMEDRIVE");
if (home_drive != NULL)
home = home_drive;
home += nowide::getenv("HOMEPATH");
subfolders.push_back(home);
#endif
} }
else else
#elif __ANDROID__ #elif __ANDROID__