diff --git a/core/libs/prx/libkernel/File/src/Stdio.cpp b/core/libs/prx/libkernel/File/src/Stdio.cpp index 711b9f388..5db08e781 100644 --- a/core/libs/prx/libkernel/File/src/Stdio.cpp +++ b/core/libs/prx/libkernel/File/src/Stdio.cpp @@ -544,10 +544,13 @@ int APS5_VABI getdents_nid_postfix(int fd, char* buf, int nbytes) { int APS5_VABI sceKernelMkdir(const char* path, uint16_t mode) { (void)mode; if (path == nullptr) throw std::invalid_argument("sceKernelMkdir: path is null"); - const auto native = ResolvePath_nid_no_patch(path); + auto native = ResolvePath_nid_no_patch(path); + while (!native.has_filename() && native.has_relative_path()) native = native.parent_path(); std::error_code error; if (std::filesystem::exists(native, error)) return SceErrorFromErrno(GUEST_EEXIST); - if (!std::filesystem::exists(native.parent_path(), error)) return SceErrorFromErrno(GUEST_ENOENT); + const auto parent = std::filesystem::status(native.parent_path(), error); + if (!std::filesystem::exists(parent)) return SceErrorFromErrno(GUEST_ENOENT); + if (!std::filesystem::is_directory(parent)) return SceErrorFromErrno(GUEST_ENOTDIR); if (!std::filesystem::create_directory(native, error)) return SceErrorFromErrno(error.value() ? error.value() : GUEST_EIO); RecordWrittenPath_nid_no_patch(native); return 0; diff --git a/core/libs/tests/GuestKernelSync.cpp b/core/libs/tests/GuestKernelSync.cpp index 526218a99..9fc11185f 100644 --- a/core/libs/tests/GuestKernelSync.cpp +++ b/core/libs/tests/GuestKernelSync.cpp @@ -40,6 +40,10 @@ int main() { Require(sceKernelMkdir("kernel_sync_probe", 0777) == 0); Require(Recorded("kernel_sync_probe")); std::ofstream("kernel_sync_probe/existing.bin") << "existing"; + Require(sceKernelMkdir("kernel_sync_probe/nested/", 0777) == 0); + Require(std::filesystem::is_directory("kernel_sync_probe/nested") && Recorded("kernel_sync_probe/nested")); + Require(sceKernelMkdir("kernel_sync_probe/nested/", 0777) == static_cast(0x80020011u)); + Require(sceKernelMkdir("kernel_sync_probe/existing.bin/child", 0777) == static_cast(0x80020014u)); const int reader = sceKernelOpen("kernel_sync_probe/existing.bin", 0x0, 0); Require(reader >= 0 && sceKernelClose(reader) == 0); void* stream = fopen_nid_postfix("kernel_sync_probe/existing.bin", "r");