Skip to content

Commit 86d1bf8

Browse files
committed
vfs/uwp: fix rename discarding new_path and inverted delete checks
retro_vfs_file_rename_impl passed old_path as both arguments of uwp_move_path, and DeleteFileFromAppW's nonzero-on-success return was checked inverted, so any rename whose source existed deleted it and returned failure, while a missing source fell through to success. Playlist writes on Xbox hit this through edb8fac's write-to-temporary and reported success with nothing on disk. Pass new_path through, fix both delete checks, fail on a missing source, and treat a self-rename as a no-op success. Needs a UWP build to verify; this TU is not compilable outside MSVC/WinRT.
1 parent 892e42a commit 86d1bf8

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

libretro-common/vfs/vfs_implementation_uwp.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <ppl.h>
2424
#include <ppltasks.h>
2525
#include <stdio.h>
26+
#include <string.h>
2627
#include <wrl.h>
2728
#include <wrl/implements.h>
2829
#include <robuffer.h>
@@ -555,7 +556,10 @@ static int uwp_move_path(
555556
&& targetfileinfo.dwFileAttributes != 0
556557
&& (!(targetfileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)))
557558
{
558-
if (DeleteFileFromAppW(new_path.wstring().c_str()))
559+
/* DeleteFileFromAppW returns nonzero on
560+
* success; MoveFileFromAppW cannot replace
561+
* an existing destination. */
562+
if (!DeleteFileFromAppW(new_path.wstring().c_str()))
559563
return -1;
560564
}
561565
}
@@ -567,7 +571,11 @@ static int uwp_move_path(
567571
uwp_set_acl(new_path.wstring().c_str(), L"S-1-15-2-1");
568572
}
569573
}
574+
else
575+
return -1; /* source attributes unusable */
570576
}
577+
else
578+
return -1; /* source does not exist */
571579

572580
}
573581
else
@@ -617,7 +625,8 @@ static int uwp_move_path(
617625
&& (!(targetfileinfo.dwFileAttributes
618626
& FILE_ATTRIBUTE_DIRECTORY)))
619627
{
620-
if (DeleteFileFromAppW(temp_new.wstring().c_str()))
628+
/* Nonzero is success. */
629+
if (!DeleteFileFromAppW(temp_new.wstring().c_str()))
621630
fail = true;
622631
}
623632
}
@@ -647,8 +656,12 @@ static int uwp_move_path(
647656
* Default arguments mean that we can do better recursion */
648657
int retro_vfs_file_rename_impl(const char* old_path, const char* new_path)
649658
{
659+
/* A self-rename is a no-op; it must not reach the replace logic,
660+
* which would delete the destination - and the source with it. */
661+
if (old_path && new_path && strcmp(old_path, new_path) == 0)
662+
return 0;
650663
return uwp_move_path(std::filesystem::path(old_path),
651-
std::filesystem::path(old_path), true);
664+
std::filesystem::path(new_path), true);
652665
}
653666

654667
const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream)

0 commit comments

Comments
 (0)