mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
make dir stuff more like the normal win32 stuff (#13006)
Co-authored-by: Tunip3 <tunip3@users.noreply.github.com>
This commit is contained in:
parent
0a5bb29c43
commit
895676430f
@ -1106,151 +1106,106 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef VFS_FRONTEND
|
#ifdef VFS_FRONTEND
|
||||||
struct retro_vfs_dir_handle
|
struct retro_vfs_dir_handle
|
||||||
#else
|
#else
|
||||||
struct libretro_vfs_implementation_dir
|
struct libretro_vfs_implementation_dir
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
IVectorView<IStorageItem^>^ directory;
|
char* orig_path;
|
||||||
IIterator<IStorageItem^>^ entry;
|
WIN32_FIND_DATAW entry;
|
||||||
char *entry_name;
|
HANDLE directory;
|
||||||
|
bool next;
|
||||||
|
char path[PATH_MAX_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
libretro_vfs_implementation_dir* retro_vfs_opendir_impl(const char* name, bool include_hidden)
|
libretro_vfs_implementation_dir* retro_vfs_opendir_impl(
|
||||||
|
const char* name, bool include_hidden)
|
||||||
{
|
{
|
||||||
wchar_t* name_wide;
|
unsigned path_len;
|
||||||
Platform::String^ name_str;
|
char path_buf[1024];
|
||||||
|
size_t copied = 0;
|
||||||
|
wchar_t* path_wide = NULL;
|
||||||
libretro_vfs_implementation_dir* rdir;
|
libretro_vfs_implementation_dir* rdir;
|
||||||
|
|
||||||
if (!name || !*name)
|
/*Reject null or empty string paths*/
|
||||||
|
if (!name || (*name == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/*Allocate RDIR struct. Tidied later with retro_closedir*/
|
||||||
rdir = (libretro_vfs_implementation_dir*)calloc(1, sizeof(*rdir));
|
rdir = (libretro_vfs_implementation_dir*)calloc(1, sizeof(*rdir));
|
||||||
if (!rdir)
|
if (!rdir)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
name_wide = utf8_to_utf16_string_alloc(name);
|
rdir->orig_path = strdup(name);
|
||||||
windowsize_path(name_wide);
|
|
||||||
name_str = ref new Platform::String(name_wide);
|
|
||||||
free(name_wide);
|
|
||||||
|
|
||||||
|
path_buf[0] = '\0';
|
||||||
|
path_len = strlen(name);
|
||||||
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA lpFileInfo;
|
copied = strlcpy(path_buf, name, sizeof(path_buf));
|
||||||
std::filesystem::path dir(name);
|
|
||||||
|
|
||||||
if (dir.empty())
|
/* Non-NT platforms don't like extra slashes in the path */
|
||||||
return NULL;
|
if (name[path_len - 1] != '\\')
|
||||||
|
path_buf[copied++] = '\\';
|
||||||
|
|
||||||
if (!(rdir->directory))
|
path_buf[copied] = '*';
|
||||||
{
|
path_buf[copied + 1] = '\0';
|
||||||
//check if file attributes can be gotten successfully
|
|
||||||
if (GetFileAttributesExFromAppW(dir.parent_path().wstring().c_str(), GetFileExInfoStandard, &lpFileInfo))
|
|
||||||
{
|
|
||||||
//check that the files attributes are not null or empty
|
|
||||||
if (lpFileInfo.dwFileAttributes != INVALID_FILE_ATTRIBUTES && lpFileInfo.dwFileAttributes != 0)
|
|
||||||
{
|
|
||||||
if (lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
{
|
|
||||||
std::wstring filteredPath(dir.wstring().c_str());
|
|
||||||
WIN32_FIND_DATA findDataResult;
|
|
||||||
if (filteredPath[filteredPath.size() - 1] == '\\')
|
|
||||||
filteredPath.erase(filteredPath.size() - 1);
|
|
||||||
filteredPath += L"\\*.*";
|
|
||||||
HANDLE searchResults = FindFirstFileExFromAppW(filteredPath.c_str(), FindExInfoBasic, &findDataResult, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH);
|
|
||||||
if (searchResults != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Platform::Collections::Vector<IStorageItem^>^ result = ref new Platform::Collections::Vector<IStorageItem^>();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (wcscmp(findDataResult.cFileName, L".") != 0 && wcscmp(findDataResult.cFileName, L"..") != 0)
|
|
||||||
{
|
|
||||||
if (!((findDataResult.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) || (findDataResult.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)))
|
|
||||||
{
|
|
||||||
std::filesystem::path temp_new = dir;
|
|
||||||
temp_new /= findDataResult.cFileName;
|
|
||||||
|
|
||||||
std::wstring temp_path = temp_new.generic_wstring();
|
path_wide = utf8_to_utf16_string_alloc(path_buf);
|
||||||
while (true) {
|
rdir->directory = FindFirstFileExFromAppW(path_wide, FindExInfoStandard, &rdir->entry, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH);
|
||||||
size_t p = temp_path.find(L"/");
|
|
||||||
if (p == std::wstring::npos) break;
|
|
||||||
temp_path.replace(p, 1, L"\\");
|
|
||||||
}
|
|
||||||
IStorageItem^ item;
|
|
||||||
if (findDataResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
{
|
|
||||||
item = RunAsyncAndCatchErrors<StorageFolder^>([&]() {
|
|
||||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(ref new Platform::String(temp_path.c_str())));
|
|
||||||
}, nullptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = RunAsyncAndCatchErrors<StorageFile^>([&]() {
|
|
||||||
return concurrency::create_task(LocateStorageItem<StorageFile>(ref new Platform::String(temp_path.c_str())));
|
|
||||||
}, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item)
|
if (path_wide)
|
||||||
if (result)
|
free(path_wide);
|
||||||
result->Append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (FindNextFile(searchResults, &findDataResult));
|
|
||||||
FindClose(searchResults);
|
|
||||||
if (result)
|
|
||||||
rdir->directory = result->GetView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rdir->directory)
|
|
||||||
return rdir;
|
|
||||||
|
|
||||||
free(rdir);
|
if (include_hidden)
|
||||||
return NULL;
|
rdir->entry.dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||||
|
else
|
||||||
|
rdir->entry.dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
|
||||||
|
|
||||||
|
if (rdir->directory && rdir != INVALID_HANDLE_VALUE)
|
||||||
|
return rdir;
|
||||||
|
|
||||||
|
retro_vfs_closedir_impl(rdir);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir)
|
bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir* rdir)
|
||||||
{
|
{
|
||||||
if (!rdir->entry)
|
if (rdir->next)
|
||||||
{
|
return (FindNextFileW(rdir->directory, &rdir->entry) != 0);
|
||||||
rdir->entry = rdir->directory->First();
|
|
||||||
return rdir->entry->HasCurrent;
|
rdir->next = true;
|
||||||
}
|
return (rdir->directory != INVALID_HANDLE_VALUE);
|
||||||
return rdir->entry->MoveNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *retro_vfs_dirent_get_name_impl(
|
const char* retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir* rdir)
|
||||||
libretro_vfs_implementation_dir *rdir)
|
|
||||||
{
|
{
|
||||||
if (rdir->entry_name)
|
char* name = utf16_to_utf8_string_alloc(rdir->entry.cFileName);
|
||||||
free(rdir->entry_name);
|
memset(rdir->entry.cFileName, 0, sizeof(rdir->entry.cFileName));
|
||||||
rdir->entry_name = utf16_to_utf8_string_alloc(
|
strlcpy((char*)rdir->entry.cFileName, name, sizeof(rdir->entry.cFileName));
|
||||||
rdir->entry->Current->Name->Data());
|
if (name)
|
||||||
return rdir->entry_name;
|
free(name);
|
||||||
|
return (char*)rdir->entry.cFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir)
|
bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir* rdir)
|
||||||
{
|
{
|
||||||
return rdir->entry->Current->IsOfType(StorageItemTypes::Folder);
|
const WIN32_FIND_DATA* entry = (const WIN32_FIND_DATA*)&rdir->entry;
|
||||||
|
return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir)
|
int retro_vfs_closedir_impl(libretro_vfs_implementation_dir* rdir)
|
||||||
{
|
{
|
||||||
if (!rdir)
|
if (!rdir)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (rdir->entry_name)
|
if (rdir->directory != INVALID_HANDLE_VALUE)
|
||||||
free(rdir->entry_name);
|
FindClose(rdir->directory);
|
||||||
rdir->entry = nullptr;
|
|
||||||
rdir->directory = nullptr;
|
|
||||||
|
|
||||||
free(rdir);
|
if (rdir->orig_path)
|
||||||
return 0;
|
free(rdir->orig_path);
|
||||||
|
free(rdir);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* uwp_trigger_picker(void)
|
char* uwp_trigger_picker(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user