@@ -1106,151 +1106,106 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11061106 return 0 ;
11071107}
11081108
1109-
1110-
1111-
11121109#ifdef VFS_FRONTEND
11131110struct retro_vfs_dir_handle
11141111#else
11151112struct libretro_vfs_implementation_dir
11161113#endif
11171114{
1118- IVectorView<IStorageItem^>^ directory;
1119- IIterator<IStorageItem^>^ entry;
1120- char *entry_name;
1115+ char * orig_path;
1116+ WIN32_FIND_DATAW entry;
1117+ HANDLE directory;
1118+ bool next;
1119+ char path[PATH_MAX_LENGTH];
11211120};
11221121
1123- libretro_vfs_implementation_dir* retro_vfs_opendir_impl (const char * name, bool include_hidden)
1122+ libretro_vfs_implementation_dir* retro_vfs_opendir_impl (
1123+ const char * name, bool include_hidden)
11241124{
1125- wchar_t * name_wide;
1126- Platform::String^ name_str;
1125+ unsigned path_len;
1126+ char path_buf[1024 ];
1127+ size_t copied = 0 ;
1128+ wchar_t * path_wide = NULL ;
11271129 libretro_vfs_implementation_dir* rdir;
11281130
1129- if (!name || !*name)
1131+ /* Reject null or empty string paths*/
1132+ if (!name || (*name == 0 ))
11301133 return NULL ;
11311134
1135+ /* Allocate RDIR struct. Tidied later with retro_closedir*/
11321136 rdir = (libretro_vfs_implementation_dir*)calloc (1 , sizeof (*rdir));
11331137 if (!rdir)
11341138 return NULL ;
11351139
1136- name_wide = utf8_to_utf16_string_alloc (name);
1137- windowsize_path (name_wide);
1138- name_str = ref new Platform::String (name_wide);
1139- free (name_wide);
1140+ rdir->orig_path = strdup (name);
11401141
1142+ path_buf[0 ] = ' \0 ' ;
1143+ path_len = strlen (name);
11411144
1142- WIN32_FILE_ATTRIBUTE_DATA lpFileInfo;
1143- std::filesystem::path dir (name);
1145+ copied = strlcpy (path_buf, name, sizeof (path_buf));
11441146
1145- if (dir.empty ())
1146- return NULL ;
1147+ /* Non-NT platforms don't like extra slashes in the path */
1148+ if (name[path_len - 1 ] != ' \\ ' )
1149+ path_buf[copied++] = ' \\ ' ;
11471150
1148- if (!(rdir->directory ))
1149- {
1150- // check if file attributes can be gotten successfully
1151- if (GetFileAttributesExFromAppW (dir.parent_path ().wstring ().c_str (), GetFileExInfoStandard, &lpFileInfo))
1152- {
1153- // check that the files attributes are not null or empty
1154- if (lpFileInfo.dwFileAttributes != INVALID_FILE_ATTRIBUTES && lpFileInfo.dwFileAttributes != 0 )
1155- {
1156- if (lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1157- {
1158- std::wstring filteredPath (dir.wstring ().c_str ());
1159- WIN32_FIND_DATA findDataResult;
1160- if (filteredPath[filteredPath.size () - 1 ] == ' \\ ' )
1161- filteredPath.erase (filteredPath.size () - 1 );
1162- filteredPath += L" \\ *.*" ;
1163- HANDLE searchResults = FindFirstFileExFromAppW (filteredPath.c_str (), FindExInfoBasic, &findDataResult, FindExSearchNameMatch, nullptr , FIND_FIRST_EX_LARGE_FETCH);
1164- if (searchResults != INVALID_HANDLE_VALUE)
1165- {
1166- Platform::Collections::Vector<IStorageItem^>^ result = ref new Platform::Collections::Vector<IStorageItem^>();
1167- do
1168- {
1169- if (wcscmp (findDataResult.cFileName , L" ." ) != 0 && wcscmp (findDataResult.cFileName , L" .." ) != 0 )
1170- {
1171- if (!((findDataResult.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) || (findDataResult.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)))
1172- {
1173- std::filesystem::path temp_new = dir;
1174- temp_new /= findDataResult.cFileName ;
1175-
1176- std::wstring temp_path = temp_new.generic_wstring ();
1177- while (true ) {
1178- size_t p = temp_path.find (L" /" );
1179- if (p == std::wstring::npos) break ;
1180- temp_path.replace (p, 1 , L" \\ " );
1181- }
1182- IStorageItem^ item;
1183- if (findDataResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1184- {
1185- item = RunAsyncAndCatchErrors<StorageFolder^>([&]() {
1186- return concurrency::create_task (LocateStorageItem<StorageFolder>(ref new Platform::String (temp_path.c_str ())));
1187- }, nullptr );
1188- }
1189- else
1190- {
1191- item = RunAsyncAndCatchErrors<StorageFile^>([&]() {
1192- return concurrency::create_task (LocateStorageItem<StorageFile>(ref new Platform::String (temp_path.c_str ())));
1193- }, nullptr );
1194- }
1195-
1196- if (item)
1197- if (result)
1198- result->Append (item);
1199- }
1200- }
1201- } while (FindNextFile (searchResults, &findDataResult));
1202- FindClose (searchResults);
1203- if (result)
1204- rdir->directory = result->GetView ();
1205- }
1206- }
1207- }
1208- }
1209- }
1210- if (rdir->directory )
1211- return rdir;
1151+ path_buf[copied] = ' *' ;
1152+ path_buf[copied + 1 ] = ' \0 ' ;
12121153
1213- free (rdir);
1214- return NULL ;
1154+ path_wide = utf8_to_utf16_string_alloc (path_buf);
1155+ rdir->directory = FindFirstFileExFromAppW (path_wide, FindExInfoStandard, &rdir->entry , FindExSearchNameMatch, nullptr , FIND_FIRST_EX_LARGE_FETCH);
1156+
1157+ if (path_wide)
1158+ free (path_wide);
1159+
1160+ if (include_hidden)
1161+ rdir->entry .dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1162+ else
1163+ rdir->entry .dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
1164+
1165+ if (rdir->directory && rdir != INVALID_HANDLE_VALUE)
1166+ return rdir;
1167+
1168+ retro_vfs_closedir_impl (rdir);
1169+ return NULL ;
12151170}
12161171
1217- bool retro_vfs_readdir_impl (libretro_vfs_implementation_dir * rdir)
1172+ bool retro_vfs_readdir_impl (libretro_vfs_implementation_dir* rdir)
12181173{
1219- if (!rdir->entry )
1220- {
1221- rdir->entry = rdir->directory ->First ();
1222- return rdir->entry ->HasCurrent ;
1223- }
1224- return rdir->entry ->MoveNext ();
1174+ if (rdir->next )
1175+ return (FindNextFileW (rdir->directory , &rdir->entry ) != 0 );
1176+
1177+ rdir->next = true ;
1178+ return (rdir->directory != INVALID_HANDLE_VALUE);
12251179}
12261180
1227- const char *retro_vfs_dirent_get_name_impl (
1228- libretro_vfs_implementation_dir *rdir)
1181+ const char * retro_vfs_dirent_get_name_impl (libretro_vfs_implementation_dir* rdir)
12291182{
1230- if (rdir->entry_name )
1231- free (rdir->entry_name );
1232- rdir->entry_name = utf16_to_utf8_string_alloc (
1233- rdir->entry ->Current ->Name ->Data ());
1234- return rdir->entry_name ;
1183+ char * name = utf16_to_utf8_string_alloc (rdir->entry .cFileName );
1184+ memset (rdir->entry .cFileName , 0 , sizeof (rdir->entry .cFileName ));
1185+ strlcpy ((char *)rdir->entry .cFileName , name, sizeof (rdir->entry .cFileName ));
1186+ if (name)
1187+ free (name);
1188+ return (char *)rdir->entry .cFileName ;
12351189}
12361190
1237- bool retro_vfs_dirent_is_dir_impl (libretro_vfs_implementation_dir * rdir)
1191+ bool retro_vfs_dirent_is_dir_impl (libretro_vfs_implementation_dir* rdir)
12381192{
1239- return rdir->entry ->Current ->IsOfType (StorageItemTypes::Folder);
1193+ const WIN32_FIND_DATA* entry = (const WIN32_FIND_DATA*)&rdir->entry ;
1194+ return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
12401195}
12411196
1242- int retro_vfs_closedir_impl (libretro_vfs_implementation_dir * rdir)
1197+ int retro_vfs_closedir_impl (libretro_vfs_implementation_dir* rdir)
12431198{
1244- if (!rdir)
1245- return -1 ;
1199+ if (!rdir)
1200+ return -1 ;
12461201
1247- if (rdir->entry_name )
1248- free (rdir->entry_name );
1249- rdir->entry = nullptr ;
1250- rdir->directory = nullptr ;
1202+ if (rdir->directory != INVALID_HANDLE_VALUE)
1203+ FindClose (rdir->directory );
12511204
1252- free (rdir);
1253- return 0 ;
1205+ if (rdir->orig_path )
1206+ free (rdir->orig_path );
1207+ free (rdir);
1208+ return 0 ;
12541209}
12551210
12561211char * uwp_trigger_picker (void )
0 commit comments