Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/libs/prx/libkernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,15 @@ if(BUILD_TESTING)
set_tests_properties(guest_signals PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
endif()
add_test_executable(guest_parent_process_tests ${LIBS_INCLUDE_DIR}/tests/GuestParentProcess.cpp)
target_include_directories(guest_parent_process_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_parent_process_tests PRIVATE libkernel libc)
configure_windows_unwind(guest_parent_process_tests)
add_test(NAME guest_parent_process COMMAND guest_parent_process_tests)
if(WIN32)
set_tests_properties(guest_parent_process PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
endif()
add_test_executable(guest_kill_tests ${LIBS_INCLUDE_DIR}/tests/GuestKill.cpp)
target_include_directories(guest_kill_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_kill_tests PRIVATE libkernel libc)
Expand Down
27 changes: 27 additions & 0 deletions core/libs/prx/libkernel/System/src/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#endif
#include <windows.h>
#include <shellapi.h>
#include <tlhelp32.h>
#else
#include <sched.h>
#include <unistd.h>
Expand Down Expand Up @@ -199,6 +200,32 @@ int APS5_VABI getpid_nid_postfix(void) {
return static_cast<int>(pid);
}

int APS5_VABI getppid_nid_postfix(void) {
#ifdef _WIN32
const DWORD self = GetCurrentProcessId();
const HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
throw std::system_error(static_cast<int>(GetLastError()), std::system_category(), "getppid: CreateToolhelp32Snapshot");
PROCESSENTRY32W entry{};
entry.dwSize = sizeof(entry);
bool found = false;
DWORD pid = 0;
for (BOOL more = Process32FirstW(snapshot, &entry); more && !found; more = Process32NextW(snapshot, &entry)) {
if (entry.th32ProcessID == self) {
pid = entry.th32ParentProcessID;
found = true;
}
}
CloseHandle(snapshot);
if (!found) throw std::runtime_error("getppid: the process is missing from the process snapshot");
#else
const auto pid = ::getppid();
#endif
if (static_cast<std::uint64_t>(pid) > static_cast<std::uint64_t>(std::numeric_limits<int>::max()))
throw std::runtime_error("Parent process identifier is outside the guest range");
return static_cast<int>(pid);
}

int APS5_VABI sceKernelGetAppInfo(int pid, void* info) {
if (pid != getpid_nid_postfix()) return SCE_KERNEL_ERROR_EPERM;
if (info == nullptr) return 0;
Expand Down
25 changes: 25 additions & 0 deletions core/libs/tests/GuestParentProcess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdlib>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
extern "C" {
int APS5_VABI getpid_nid_postfix(void);
int APS5_VABI getppid_nid_postfix(void);
}
static void Require(bool value) { if (!value) std::abort(); }
int main() {
const int parent = getppid_nid_postfix();
Require(parent > 0 && parent != getpid_nid_postfix());
Require(getppid_nid_postfix() == parent);
#ifdef _WIN32
const HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, static_cast<DWORD>(parent));
Require(process != nullptr);
CloseHandle(process);
#else
Require(parent == static_cast<int>(::getppid()));
#endif
return 0;
}
Loading