fix(libkernel): unlink a dangling Windows directory link

This commit is contained in:
JJenkx committed 2026-11-01 20:17:24 -05:00
1 parent 93dbd0f82a
commit 79e6d32c05
2 files changed
+15 -11

No files matched your search

+14 -11
View File
@@ -493,19 +493,22 @@ int APS5_VABI sceKernelUnlink(const char* path) {
const DWORD linkAttributes = GetFileAttributesW(native.c_str());
if (linkAttributes != INVALID_FILE_ATTRIBUTES && (linkAttributes & DirectoryLink) == DirectoryLink) directory = true;
#endif
if (directory) {
#ifdef _WIN32
if (native.has_filename()) {
WIN32_FIND_DATAW found{};
if (const HANDLE find = FindFirstFileW(native.c_str(), &found); find != INVALID_HANDLE_VALUE) {
FindClose(find);
if ((found.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 && found.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
if (!RemoveDirectoryW(native.c_str())) return SceErrorFromErrno(GetLastError() == ERROR_ACCESS_DENIED ? 13 : 5);
RecordWrittenPath_nid_no_patch(native);
return 0;
}
if (native.has_filename() && native.filename().native().find_first_of(L"*?<>\"") == std::wstring::npos) {
WIN32_FIND_DATAW found{};
if (const HANDLE find = FindFirstFileW(native.c_str(), &found); find != INVALID_HANDLE_VALUE) {
FindClose(find);
constexpr DWORD DirectoryLink = FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY;
if ((found.dwFileAttributes & DirectoryLink) == DirectoryLink && found.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
if (!RemoveDirectoryW(native.c_str())) return SceErrorFromErrno(GetLastError() == ERROR_ACCESS_DENIED ? 13 : 5);
RecordWrittenPath_nid_no_patch(native);
return 0;
}
}
}
#endif
if (directory) {
#ifdef _WIN32
const DWORD attributes = GetFileAttributesW(native.c_str());
if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
std::string junctionTarget;
@@ -557,4 +560,4 @@ int APS5_VABI sceKernelFcntl(int d, int command, ...) {
return result < 0 ? SceKernelError(*__error_nid_postfix()) : result;
}
}
}
+1
View File
@@ -1575,6 +1575,7 @@ int main() {
Require(sceKernelRmdir(directoryLink.string().c_str()) == static_cast<int>(0x80020014u));
Require(rmdir_nid_postfix(danglingDirectoryLink.string().c_str()) == -1 && *__error_nid_postfix() == 20);
Require((GetFileAttributesW(directoryLink.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0 && std::filesystem::is_directory(linkedDirectory));
Require(unlink_nid_postfix((root / "directory-li*").string().c_str()) == -1 && *__error_nid_postfix() != 5 && (GetFileAttributesW(directoryLink.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
Require(unlink_nid_postfix(directoryLink.string().c_str()) == 0 && unlink_nid_postfix(danglingDirectoryLink.string().c_str()) == 0);
}
#else