mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
Opening a volume needs administrator rights, so the volume flush skipped every volume in a normal user session. The libc, libkernel, save data and app content file functions now record each host file and directory they change. On Windows sceKernelSync flushes the recorded paths that changed since the previous call, plus their changed parent directories, through handles a normal user can open. Linux still calls sync().
74 lines
3.4 KiB
C++
74 lines
3.4 KiB
C++
#include "prx/libc/include/General.hpp"
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#ifdef _WIN32
|
|
#define NOMINMAX
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#endif
|
|
extern "C" {
|
|
int APS5_VABI sceKernelOpen(const char*, int, unsigned short);
|
|
int APS5_VABI sceKernelClose(int);
|
|
std::int64_t APS5_VABI sceKernelWrite(int, const void*, std::size_t);
|
|
int APS5_VABI sceKernelMkdir(const char*, unsigned short);
|
|
int APS5_VABI sceKernelRename(const char*, const char*);
|
|
int APS5_VABI sceKernelUnlink(const char*);
|
|
int APS5_VABI sceKernelChmod_nid_postfix(const char*, std::uint16_t);
|
|
void APS5_VABI sceKernelSync();
|
|
void* APS5_VABI fopen_nid_postfix(const char*, const char*);
|
|
int APS5_VABI fclose_nid_postfix(void*);
|
|
}
|
|
static void Check(bool value, int line) {
|
|
if (!value) {
|
|
std::fprintf(stderr, "Kernel sync check failed at line %d\n", line);
|
|
std::abort();
|
|
}
|
|
}
|
|
#define Require(value) Check((value), __LINE__)
|
|
static bool Recorded(const char* guest) {
|
|
const auto paths = WrittenPaths_nid_no_patch();
|
|
return std::find(paths.begin(), paths.end(), ResolvePath_nid_no_patch(guest).lexically_normal()) != paths.end();
|
|
}
|
|
int main() {
|
|
std::filesystem::remove_all("kernel_sync_probe");
|
|
Require(sceKernelMkdir("kernel_sync_probe", 0777) == 0);
|
|
Require(Recorded("kernel_sync_probe"));
|
|
std::ofstream("kernel_sync_probe/existing.bin") << "existing";
|
|
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");
|
|
Require(stream != nullptr && fclose_nid_postfix(stream) == 0);
|
|
Require(!Recorded("kernel_sync_probe/existing.bin"));
|
|
stream = fopen_nid_postfix("kernel_sync_probe/existing.bin", "a");
|
|
Require(stream != nullptr && fclose_nid_postfix(stream) == 0);
|
|
Require(Recorded("kernel_sync_probe/existing.bin"));
|
|
const int writer = sceKernelOpen("kernel_sync_probe/data.bin", 0x1 | 0x200 | 0x400, 0644);
|
|
Require(writer >= 0 && sceKernelWrite(writer, "data", 4) == 4 && sceKernelClose(writer) == 0);
|
|
Require(Recorded("kernel_sync_probe/data.bin"));
|
|
Require(sceKernelRename("kernel_sync_probe/data.bin", "kernel_sync_probe/moved.bin") == 0);
|
|
Require(Recorded("kernel_sync_probe/moved.bin"));
|
|
Require(sceKernelUnlink("kernel_sync_probe/moved.bin") == 0);
|
|
sceKernelSync();
|
|
Require(!Recorded("kernel_sync_probe/data.bin") && !Recorded("kernel_sync_probe/moved.bin"));
|
|
sceKernelSync();
|
|
const int locked = sceKernelOpen("kernel_sync_probe/read_only.bin", 0x1 | 0x200, 0644);
|
|
Require(locked >= 0 && sceKernelWrite(locked, "data", 4) == 4 && sceKernelClose(locked) == 0);
|
|
Require(sceKernelChmod_nid_postfix("kernel_sync_probe/read_only.bin", 0444) == 0);
|
|
Require(Recorded("kernel_sync_probe/read_only.bin"));
|
|
sceKernelSync();
|
|
Require(sceKernelChmod_nid_postfix("kernel_sync_probe/read_only.bin", 0644) == 0);
|
|
#ifdef _WIN32
|
|
const auto exclusive = CreateFileW(ResolvePath_nid_no_patch("kernel_sync_probe/read_only.bin").c_str(), GENERIC_READ, FILE_SHARE_READ,
|
|
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
|
Require(exclusive != INVALID_HANDLE_VALUE);
|
|
sceKernelSync();
|
|
CloseHandle(exclusive);
|
|
#endif
|
|
sceKernelSync();
|
|
std::filesystem::remove_all("kernel_sync_probe");
|
|
}
|