diff --git a/core/libs/prx/libkernel/File/include/SharedMemory.hpp b/core/libs/prx/libkernel/File/include/SharedMemory.hpp index 5c9ffc9f47..bdaa1bd007 100644 --- a/core/libs/prx/libkernel/File/include/SharedMemory.hpp +++ b/core/libs/prx/libkernel/File/include/SharedMemory.hpp @@ -14,6 +14,9 @@ std::int64_t WriteSharedMemory_nid_no_patch(int descriptor, const void* buffer, std::int64_t PwriteSharedMemory_nid_no_patch(int descriptor, const void* buffer, std::size_t size, std::int64_t offset); std::int64_t SeekSharedMemory_nid_no_patch(int descriptor, std::int64_t offset, int whence); int TruncateSharedMemory_nid_no_patch(int descriptor, std::int64_t length); +#ifdef _WIN32 +bool LimitSharedMemoryWrite_nid_no_patch(int descriptor, std::size_t& size, std::int64_t offset); +#endif #ifndef _WIN32 std::int64_t WritevSharedMemory_nid_no_patch(int descriptor, const struct iovec* vectors, int count); std::int64_t PwritevSharedMemory_nid_no_patch(int descriptor, const struct iovec* vectors, int count, std::int64_t offset); diff --git a/core/libs/prx/libkernel/File/src/Open.cpp b/core/libs/prx/libkernel/File/src/Open.cpp index 9b79078010..c5f43c6964 100644 --- a/core/libs/prx/libkernel/File/src/Open.cpp +++ b/core/libs/prx/libkernel/File/src/Open.cpp @@ -74,6 +74,11 @@ static int NativeWrite(int fd, const void* buf, std::size_t n) { throw std::runtime_error("sceKernelWrite: nbytes exceeds platform limit"); } const auto positioned = File::LockPositionedTransfer(fd); + if (File::HasFixedSizeWrites(fd)) { + const auto position = ::_lseeki64(fd, 0, SEEK_CUR); + if (position < 0 || !File::LimitSharedMemoryWrite_nid_no_patch(fd, n, position)) return -1; + if (n == 0) return 0; + } const auto shared = File::WriteSharedMemory_nid_no_patch(fd, buf, n); if (shared != -2) return static_cast(shared); if (File::Appends(fd)) { diff --git a/core/libs/prx/libkernel/File/src/Stdio.cpp b/core/libs/prx/libkernel/File/src/Stdio.cpp index b2f2f31897..65f000d061 100644 --- a/core/libs/prx/libkernel/File/src/Stdio.cpp +++ b/core/libs/prx/libkernel/File/src/Stdio.cpp @@ -245,7 +245,7 @@ void File::SharePositionedTransfer(int from, int to) { if (!source) source = std::make_shared(); g_positionedLocks[to] = source; } -static bool LimitSharedMemoryWrite(int descriptor, std::size_t& size, std::int64_t offset) { +bool File::LimitSharedMemoryWrite_nid_no_patch(int descriptor, std::size_t& size, std::int64_t offset) { if (offset < 0) { errno = EINVAL; return false; } const auto length = WithoutParameterHandler([descriptor] { return ::_filelengthi64(descriptor); }); if (length < 0) return false; @@ -258,7 +258,7 @@ static std::int64_t NativePositionedTransfer(int descriptor, void* buf, std::siz throw std::runtime_error("NativePositioned: nbytes exceeds platform limit"); } if (write && File::HasFixedSizeWrites(descriptor)) { - if (!LimitSharedMemoryWrite(descriptor, nbytes, offset)) return -1; + if (!File::LimitSharedMemoryWrite_nid_no_patch(descriptor, nbytes, offset)) return -1; if (nbytes == 0) return 0; } const auto handle = reinterpret_cast(WithoutParameterHandler([descriptor] { return ::_get_osfhandle(descriptor); })); @@ -325,7 +325,7 @@ static std::int64_t NativeTransferBuffer(int descriptor, void* buf, std::size_t if (write) { if (File::HasFixedSizeWrites(descriptor)) { const auto position = WithoutParameterHandler([descriptor] { return ::_lseeki64(descriptor, 0, SEEK_CUR); }); - if (position < 0 || !LimitSharedMemoryWrite(descriptor, nbytes, position)) return -1; + if (position < 0 || !File::LimitSharedMemoryWrite_nid_no_patch(descriptor, nbytes, position)) return -1; if (nbytes == 0) return 0; } const auto result = File::WriteSharedMemory_nid_no_patch(descriptor, buf, nbytes);