mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
Merge 76d9bf9bf5
into 95a386308a
This commit is contained in:
commit
513d32f51b
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -106,3 +106,9 @@
|
|||||||
[submodule "externals/libusb"]
|
[submodule "externals/libusb"]
|
||||||
path = externals/libusb
|
path = externals/libusb
|
||||||
url = https://github.com/libusb/libusb-cmake.git
|
url = https://github.com/libusb/libusb-cmake.git
|
||||||
|
[submodule "externals/wepoll"]
|
||||||
|
path = externals/wepoll
|
||||||
|
url = https://github.com/piscisaureus/wepoll.git
|
||||||
|
[submodule "externals/epoll-shim"]
|
||||||
|
path = externals/epoll-shim
|
||||||
|
url = https://github.com/jiixyj/epoll-shim.git
|
||||||
|
@ -246,6 +246,7 @@ find_package(pugixml 1.14 CONFIG)
|
|||||||
find_package(libusb 1.0.27 MODULE)
|
find_package(libusb 1.0.27 MODULE)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
find_package(date 3.0.1 CONFIG)
|
find_package(date 3.0.1 CONFIG)
|
||||||
|
find_package(epoll-shim 3.14 CONFIG)
|
||||||
endif()
|
endif()
|
||||||
list(POP_BACK CMAKE_MODULE_PATH)
|
list(POP_BACK CMAKE_MODULE_PATH)
|
||||||
|
|
||||||
@ -378,6 +379,8 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
|||||||
src/core/libraries/network/net_ctl_codes.h
|
src/core/libraries/network/net_ctl_codes.h
|
||||||
src/core/libraries/network/net_util.cpp
|
src/core/libraries/network/net_util.cpp
|
||||||
src/core/libraries/network/net_util.h
|
src/core/libraries/network/net_util.h
|
||||||
|
src/core/libraries/network/net_epoll.cpp
|
||||||
|
src/core/libraries/network/net_epoll.h
|
||||||
src/core/libraries/network/net_error.h
|
src/core/libraries/network/net_error.h
|
||||||
src/core/libraries/network/net.h
|
src/core/libraries/network/net.h
|
||||||
src/core/libraries/network/ssl.cpp
|
src/core/libraries/network/ssl.cpp
|
||||||
@ -1173,7 +1176,7 @@ if (APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Replacement for std::chrono::time_zone
|
# Replacement for std::chrono::time_zone
|
||||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
target_link_libraries(shadps4 PRIVATE date::date-tz epoll-shim)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_QT_GUI)
|
if (ENABLE_QT_GUI)
|
||||||
|
6
externals/CMakeLists.txt
vendored
6
externals/CMakeLists.txt
vendored
@ -140,6 +140,8 @@ endif()
|
|||||||
# sirit
|
# sirit
|
||||||
add_subdirectory(sirit)
|
add_subdirectory(sirit)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
add_library(wepoll wepoll/wepoll.c)
|
||||||
|
target_include_directories(wepoll INTERFACE wepoll/)
|
||||||
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -229,4 +231,8 @@ if (APPLE)
|
|||||||
if (NOT TARGET MoltenVK)
|
if (NOT TARGET MoltenVK)
|
||||||
add_subdirectory(MoltenVK)
|
add_subdirectory(MoltenVK)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT TARGET epoll-shim)
|
||||||
|
add_subdirectory(epoll-shim)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
1
externals/epoll-shim
vendored
Submodule
1
externals/epoll-shim
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 18159584bb3d17e601b9315a7398ace018251bdc
|
1
externals/wepoll
vendored
Submodule
1
externals/wepoll
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 0598a791bf9cbbf480793d778930fc635b044980
|
@ -47,6 +47,7 @@ static bool isShowSplash = false;
|
|||||||
static std::string isSideTrophy = "right";
|
static std::string isSideTrophy = "right";
|
||||||
static bool compatibilityData = false;
|
static bool compatibilityData = false;
|
||||||
static bool checkCompatibilityOnStartup = false;
|
static bool checkCompatibilityOnStartup = false;
|
||||||
|
static bool isConnectedToNetwork = false;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
static int cursorState = HideCursorState::Idle;
|
static int cursorState = HideCursorState::Idle;
|
||||||
@ -107,7 +108,7 @@ u32 m_language = 1; // english
|
|||||||
static std::string trophyKey = "";
|
static std::string trophyKey = "";
|
||||||
|
|
||||||
// Expected number of items in the config file
|
// Expected number of items in the config file
|
||||||
static constexpr u64 total_entries = 54;
|
static constexpr u64 total_entries = 55;
|
||||||
|
|
||||||
int getVolumeSlider() {
|
int getVolumeSlider() {
|
||||||
return volumeSlider;
|
return volumeSlider;
|
||||||
@ -353,6 +354,10 @@ bool getCheckCompatibilityOnStartup() {
|
|||||||
return checkCompatibilityOnStartup;
|
return checkCompatibilityOnStartup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getIsConnectedToNetwork() {
|
||||||
|
return isConnectedToNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
void setGpuId(s32 selectedGpuId) {
|
void setGpuId(s32 selectedGpuId) {
|
||||||
gpuId = selectedGpuId;
|
gpuId = selectedGpuId;
|
||||||
}
|
}
|
||||||
@ -636,6 +641,9 @@ void load(const std::filesystem::path& path) {
|
|||||||
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", compatibilityData);
|
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", compatibilityData);
|
||||||
checkCompatibilityOnStartup = toml::find_or<bool>(general, "checkCompatibilityOnStartup",
|
checkCompatibilityOnStartup = toml::find_or<bool>(general, "checkCompatibilityOnStartup",
|
||||||
checkCompatibilityOnStartup);
|
checkCompatibilityOnStartup);
|
||||||
|
|
||||||
|
isConnectedToNetwork =
|
||||||
|
toml::find_or<bool>(general, "isConnectedToNetwork", isConnectedToNetwork);
|
||||||
chooseHomeTab = toml::find_or<std::string>(general, "chooseHomeTab", chooseHomeTab);
|
chooseHomeTab = toml::find_or<std::string>(general, "chooseHomeTab", chooseHomeTab);
|
||||||
|
|
||||||
entry_count += general.size();
|
entry_count += general.size();
|
||||||
@ -830,6 +838,7 @@ void save(const std::filesystem::path& path) {
|
|||||||
data["General"]["sideTrophy"] = isSideTrophy;
|
data["General"]["sideTrophy"] = isSideTrophy;
|
||||||
data["General"]["compatibilityEnabled"] = compatibilityData;
|
data["General"]["compatibilityEnabled"] = compatibilityData;
|
||||||
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
|
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
|
||||||
|
data["General"]["isConnectedToNetwork"] = isConnectedToNetwork;
|
||||||
data["Input"]["cursorState"] = cursorState;
|
data["Input"]["cursorState"] = cursorState;
|
||||||
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
||||||
data["Input"]["useSpecialPad"] = useSpecialPad;
|
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||||
@ -926,6 +935,7 @@ void setDefaultValues() {
|
|||||||
isSideTrophy = "right";
|
isSideTrophy = "right";
|
||||||
compatibilityData = false;
|
compatibilityData = false;
|
||||||
checkCompatibilityOnStartup = false;
|
checkCompatibilityOnStartup = false;
|
||||||
|
isConnectedToNetwork = false;
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
cursorState = HideCursorState::Idle;
|
cursorState = HideCursorState::Idle;
|
||||||
|
@ -111,6 +111,7 @@ std::filesystem::path GetSaveDataPath();
|
|||||||
void setLoadGameSizeEnabled(bool enable);
|
void setLoadGameSizeEnabled(bool enable);
|
||||||
bool getCompatibilityEnabled();
|
bool getCompatibilityEnabled();
|
||||||
bool getCheckCompatibilityOnStartup();
|
bool getCheckCompatibilityOnStartup();
|
||||||
|
bool getIsConnectedToNetwork();
|
||||||
std::string getUserName();
|
std::string getUserName();
|
||||||
std::string getChooseHomeTab();
|
std::string getChooseHomeTab();
|
||||||
bool GetUseUnifiedInputConfig();
|
bool GetUseUnifiedInputConfig();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/logging/formatter.h"
|
#include "common/logging/formatter.h"
|
||||||
#include "core/devices/base_device.h"
|
#include "core/devices/base_device.h"
|
||||||
|
#include "core/libraries/network/sockets.h"
|
||||||
|
|
||||||
namespace Core::FileSys {
|
namespace Core::FileSys {
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ enum class FileType {
|
|||||||
Regular, // standard file
|
Regular, // standard file
|
||||||
Directory,
|
Directory,
|
||||||
Device,
|
Device,
|
||||||
|
Socket,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct File {
|
struct File {
|
||||||
@ -89,6 +91,7 @@ struct File {
|
|||||||
u32 dirents_index;
|
u32 dirents_index;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
std::shared_ptr<Devices::BaseDevice> device; // only valid for type == Device
|
std::shared_ptr<Devices::BaseDevice> device; // only valid for type == Device
|
||||||
|
std::shared_ptr<Libraries::Net::Socket> socket; // only valid for type == Socket
|
||||||
};
|
};
|
||||||
|
|
||||||
class HandleTable {
|
class HandleTable {
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/kernel/equeue.h"
|
#include "core/libraries/kernel/equeue.h"
|
||||||
#include "core/libraries/kernel/orbis_error.h"
|
#include "core/libraries/kernel/orbis_error.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
@ -412,6 +414,34 @@ int PS4_SYSV_ABI sceKernelDeleteTimerEvent(SceKernelEqueue eq, int id) {
|
|||||||
: ORBIS_KERNEL_ERROR_ENOENT;
|
: ORBIS_KERNEL_ERROR_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelAddReadEvent(SceKernelEqueue eq, int fd, size_t size, void* udata) {
|
||||||
|
if (eq == nullptr) {
|
||||||
|
return ORBIS_KERNEL_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
LOG_ERROR(Kernel_Event, "(DUMMY) eq = {}, fd = {}, size = {}, udata = {:#x}", eq->GetName(), fd,
|
||||||
|
size, reinterpret_cast<u64>(udata));
|
||||||
|
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(fd);
|
||||||
|
if (!file) {
|
||||||
|
return ORBIS_KERNEL_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
EqueueEvent event{};
|
||||||
|
event.event.ident = static_cast<u64>(fd);
|
||||||
|
event.event.filter = SceKernelEvent::Filter::Read;
|
||||||
|
event.event.flags = SceKernelEvent::Flags::Add;
|
||||||
|
event.event.fflags = 0;
|
||||||
|
event.event.data = size;
|
||||||
|
event.event.udata = udata;
|
||||||
|
|
||||||
|
if (!eq->AddEvent(event)) {
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id) {
|
int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id) {
|
||||||
if (eq == nullptr) {
|
if (eq == nullptr) {
|
||||||
return ORBIS_KERNEL_ERROR_EBADF;
|
return ORBIS_KERNEL_ERROR_EBADF;
|
||||||
@ -488,6 +518,7 @@ void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("jpFjmgAC5AE", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEqueue);
|
LIB_FUNCTION("jpFjmgAC5AE", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEqueue);
|
||||||
LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEqueue);
|
LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEqueue);
|
||||||
LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData);
|
LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData);
|
||||||
|
LIB_FUNCTION("VHCS3rCd0PM", "libkernel", 1, "libkernel", 1, 1, sceKernelAddReadEvent);
|
||||||
LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent);
|
LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent);
|
||||||
LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge);
|
LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge);
|
||||||
LIB_FUNCTION("R74tt43xP6k", "libkernel", 1, "libkernel", 1, 1, sceKernelAddHRTimerEvent);
|
LIB_FUNCTION("R74tt43xP6k", "libkernel", 1, "libkernel", 1, 1, sceKernelAddHRTimerEvent);
|
||||||
|
@ -23,6 +23,13 @@
|
|||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace D = Core::Devices;
|
namespace D = Core::Devices;
|
||||||
using FactoryDevice = std::function<std::shared_ptr<D::BaseDevice>(u32, const char*, int, u16)>;
|
using FactoryDevice = std::function<std::shared_ptr<D::BaseDevice>(u32, const char*, int, u16)>;
|
||||||
|
|
||||||
@ -257,6 +264,8 @@ s32 PS4_SYSV_ABI close(s32 fd) {
|
|||||||
}
|
}
|
||||||
if (file->type == Core::FileSys::FileType::Regular) {
|
if (file->type == Core::FileSys::FileType::Regular) {
|
||||||
file->f.Close();
|
file->f.Close();
|
||||||
|
} else if (file->type == Core::FileSys::FileType::Regular) {
|
||||||
|
file->socket->Close();
|
||||||
}
|
}
|
||||||
file->is_opened = false;
|
file->is_opened = false;
|
||||||
LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name);
|
LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name);
|
||||||
@ -294,6 +303,13 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||||
|
s64 result = file->socket->write(buf, nbytes);
|
||||||
|
if (result < 0) {
|
||||||
|
ErrSceToPosix(result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file->f.WriteRaw<u8>(buf, nbytes);
|
return file->f.WriteRaw<u8>(buf, nbytes);
|
||||||
@ -475,6 +491,13 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||||
|
s64 result = file->socket->read(buf, nbytes);
|
||||||
|
if (result < 0) {
|
||||||
|
ErrSceToPosix(result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return ReadFile(file->f, buf, nbytes);
|
return ReadFile(file->f, buf, nbytes);
|
||||||
}
|
}
|
||||||
@ -667,6 +690,14 @@ s32 PS4_SYSV_ABI fstat(s32 fd, OrbisKernelStat* sb) {
|
|||||||
// TODO incomplete
|
// TODO incomplete
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Core::FileSys::FileType::Socket: {
|
||||||
|
s32 result = file->socket->fstat(sb);
|
||||||
|
if (result < 0) {
|
||||||
|
ErrSceToPosix(result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -1055,6 +1086,240 @@ s32 PS4_SYSV_ABI sceKernelUnlink(const char* path) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI posix_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
|
||||||
|
OrbisKernelTimeval* timeout) {
|
||||||
|
LOG_INFO(Kernel_Fs, "nfds = {}, readfds = {}, writefds = {}, exceptfds = {}, timeout = {}",
|
||||||
|
nfds, fmt::ptr(readfds), fmt::ptr(writefds), fmt::ptr(exceptfds), fmt::ptr(timeout));
|
||||||
|
|
||||||
|
fd_set read_host, write_host, except_host;
|
||||||
|
FD_ZERO(&read_host);
|
||||||
|
FD_ZERO(&write_host);
|
||||||
|
FD_ZERO(&except_host);
|
||||||
|
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
// Separate sockets for select()
|
||||||
|
for (auto i = 0; i < nfds; ++i) {
|
||||||
|
auto read = readfds && FD_ISSET(i, readfds);
|
||||||
|
auto write = writefds && FD_ISSET(i, writefds);
|
||||||
|
auto except = exceptfds && FD_ISSET(i, exceptfds);
|
||||||
|
if (read || write || except) {
|
||||||
|
LOG_INFO(Kernel_Fs, "guest fd {} expected", i);
|
||||||
|
auto* file = h->GetFile(i);
|
||||||
|
if (file == nullptr ||
|
||||||
|
((file->type == Core::FileSys::FileType::Regular && !file->f.IsOpen()) ||
|
||||||
|
(file->type == Core::FileSys::FileType::Socket && !file->is_opened))) {
|
||||||
|
LOG_ERROR(Kernel_Fs, "fd {} is null or not opened", i);
|
||||||
|
*__Error() = POSIX_EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->type != Core::FileSys::FileType::Socket) {
|
||||||
|
LOG_WARNING(Kernel_Fs, "fd {} is not a socket, ignoring", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fd = [&] {
|
||||||
|
switch (file->type) {
|
||||||
|
case Core::FileSys::FileType::Socket:
|
||||||
|
return file->socket->Native();
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
FD_SET(fd, &read_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (write) {
|
||||||
|
FD_SET(fd, &write_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (except) {
|
||||||
|
FD_SET(fd, &except_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int result =
|
||||||
|
select(0, &read_host, &write_host, &except_host, reinterpret_cast<timeval*>(timeout));
|
||||||
|
int total_ready = result;
|
||||||
|
|
||||||
|
for (int fd = 0; fd < nfds; ++fd) {
|
||||||
|
auto* file = h->GetFile(fd);
|
||||||
|
|
||||||
|
if (file->type == Core::FileSys::FileType::Socket) {
|
||||||
|
auto sock = file->socket->Native();
|
||||||
|
if (readfds && !(FD_ISSET(sock, &read_host))) {
|
||||||
|
FD_CLR(fd, &readfds);
|
||||||
|
}
|
||||||
|
if (writefds && !(FD_ISSET(sock, &write_host))) {
|
||||||
|
FD_CLR(fd, &writefds);
|
||||||
|
}
|
||||||
|
if (exceptfds && !(FD_ISSET(sock, &except_host))) {
|
||||||
|
FD_CLR(fd, &exceptfds);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
||||||
|
DWORD type = GetFileType(h);
|
||||||
|
if (type == FILE_TYPE_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// READ check
|
||||||
|
if (readfds && FD_ISSET(fd, readfds)) {
|
||||||
|
if (type == FILE_TYPE_PIPE) {
|
||||||
|
DWORD avail = 0;
|
||||||
|
if (PeekNamedPipe(h, NULL, 0, NULL, &avail, NULL) && avail > 0) {
|
||||||
|
total_ready++;
|
||||||
|
} else {
|
||||||
|
FD_CLR(fd, readfds);
|
||||||
|
}
|
||||||
|
} else if (type == FILE_TYPE_DISK) {
|
||||||
|
char tmp;
|
||||||
|
long pos = _lseek(fd, 0, SEEK_CUR);
|
||||||
|
if (_read(fd, &tmp, 1) > 0) {
|
||||||
|
_lseek(fd, pos, SEEK_SET);
|
||||||
|
total_ready++;
|
||||||
|
} else {
|
||||||
|
FD_CLR(fd, readfds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WRITE check
|
||||||
|
if (writefds && FD_ISSET(fd, writefds)) {
|
||||||
|
DWORD written = 0;
|
||||||
|
char dummy = 0;
|
||||||
|
BOOL writable = FALSE;
|
||||||
|
if (type == FILE_TYPE_PIPE) {
|
||||||
|
// Try writing 0 bytes to check if it's broken
|
||||||
|
writable = WriteFile(h, &dummy, 0, &written, NULL);
|
||||||
|
} else if (type == FILE_TYPE_DISK) {
|
||||||
|
writable = true; // Disk files are always "writable"
|
||||||
|
}
|
||||||
|
if (writable) {
|
||||||
|
total_ready++;
|
||||||
|
} else {
|
||||||
|
FD_CLR(fd, writefds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXCEPTION check
|
||||||
|
if (exceptfds && FD_ISSET(fd, exceptfds)) {
|
||||||
|
DWORD err = 0, size = sizeof(err);
|
||||||
|
BOOL error_detected = false;
|
||||||
|
|
||||||
|
if (type == FILE_TYPE_PIPE) {
|
||||||
|
// Check broken pipe by trying non-blocking zero write
|
||||||
|
DWORD written;
|
||||||
|
char tmp = 0;
|
||||||
|
if (!WriteFile(h, &tmp, 0, &written, NULL)) {
|
||||||
|
DWORD e = GetLastError();
|
||||||
|
if (e == ERROR_NO_DATA || e == ERROR_BROKEN_PIPE) {
|
||||||
|
error_detected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_detected) {
|
||||||
|
total_ready++;
|
||||||
|
} else {
|
||||||
|
FD_CLR(fd, exceptfds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_ready;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
std::map<int, int> host_to_guest;
|
||||||
|
int max_fd = 0;
|
||||||
|
|
||||||
|
for (auto i = 0; i < nfds; ++i) {
|
||||||
|
auto read = readfds && FD_ISSET(i, readfds);
|
||||||
|
auto write = writefds && FD_ISSET(i, writefds);
|
||||||
|
auto except = exceptfds && FD_ISSET(i, exceptfds);
|
||||||
|
if (read || write || except) {
|
||||||
|
LOG_DEBUG(Kernel_Fs, "guest fd {} expected", i);
|
||||||
|
auto* file = h->GetFile(i);
|
||||||
|
if (file == nullptr ||
|
||||||
|
((file->type == Core::FileSys::FileType::Regular && !file->f.IsOpen()) ||
|
||||||
|
(file->type == Core::FileSys::FileType::Socket && !file->is_opened))) {
|
||||||
|
LOG_ERROR(Kernel_Fs, "fd {} is null or not opened", i);
|
||||||
|
*__Error() = POSIX_EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = [&] {
|
||||||
|
switch (file->type) {
|
||||||
|
case Core::FileSys::FileType::Regular:
|
||||||
|
return static_cast<int>(file->f.GetFileMapping());
|
||||||
|
case Core::FileSys::FileType::Socket:
|
||||||
|
return file->socket->Native();
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
host_to_guest.emplace(fd, i);
|
||||||
|
|
||||||
|
max_fd = std::max(max_fd, fd);
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
FD_SET(fd, &read_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (write) {
|
||||||
|
FD_SET(fd, &write_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (except) {
|
||||||
|
FD_SET(fd, &except_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = select(max_fd + 1, &read_host, &write_host, &except_host, (timeval*)timeout);
|
||||||
|
LOG_DEBUG(Kernel_Fs, "select = {}", ret);
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
if (readfds) {
|
||||||
|
FD_ZERO(readfds);
|
||||||
|
}
|
||||||
|
if (writefds) {
|
||||||
|
FD_ZERO(writefds);
|
||||||
|
}
|
||||||
|
if (exceptfds) {
|
||||||
|
FD_ZERO(exceptfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i < max_fd + 1; ++i) {
|
||||||
|
if (FD_ISSET(i, &read_host)) {
|
||||||
|
LOG_DEBUG(Kernel_Fs, "host fd {} (guest {}) ready for reading", i, host_to_guest[i]);
|
||||||
|
FD_SET(host_to_guest[i], readfds);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(i, &write_host)) {
|
||||||
|
LOG_DEBUG(Kernel_Fs, "host fd {} (guest {}) ready for writing", i, host_to_guest[i]);
|
||||||
|
FD_SET(host_to_guest[i], writefds);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(i, &except_host)) {
|
||||||
|
LOG_DEBUG(Kernel_Fs, "host fd {} (guest {}) ready for except", i, host_to_guest[i]);
|
||||||
|
FD_SET(host_to_guest[i], exceptfds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
|
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, open);
|
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, open);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
@ -1112,6 +1377,8 @@ void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("nKWi-N2HBV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPwrite);
|
LIB_FUNCTION("nKWi-N2HBV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPwrite);
|
||||||
LIB_FUNCTION("mBd4AfLP+u8", "libkernel", 1, "libkernel", 1, 1, sceKernelPwritev);
|
LIB_FUNCTION("mBd4AfLP+u8", "libkernel", 1, "libkernel", 1, 1, sceKernelPwritev);
|
||||||
LIB_FUNCTION("AUXVxWeJU-A", "libkernel", 1, "libkernel", 1, 1, sceKernelUnlink);
|
LIB_FUNCTION("AUXVxWeJU-A", "libkernel", 1, "libkernel", 1, 1, sceKernelUnlink);
|
||||||
|
LIB_FUNCTION("T8fER+tIGgk", "libScePosix", 1, "libkernel", 1, 1, posix_select);
|
||||||
|
LIB_FUNCTION("T8fER+tIGgk", "libkernel", 1, "libkernel", 1, 1, posix_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
@ -222,16 +222,18 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
|
|||||||
|
|
||||||
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
|
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
|
||||||
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
|
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
auto* netcall = Common::Singleton<Libraries::Net::NetInternal>::Instance();
|
LOG_DEBUG(Lib_Net, "s = {}", s);
|
||||||
auto sock = netcall->FindSocket(s);
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
if (!sock) {
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
s32 returncode = sock->GetSocketAddress(addr, paddrlen);
|
s32 returncode = sock->GetSocketAddress(addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
LOG_ERROR(Lib_Net, "return code : {:#x}", (u32)returncode);
|
LOG_DEBUG(Lib_Net, "return code : {:#x}", (u32)returncode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = 0x20;
|
*Libraries::Kernel::__Error() = 0x20;
|
||||||
@ -299,11 +301,13 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("pxnCmagrtao", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_listen);
|
LIB_FUNCTION("pxnCmagrtao", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_listen);
|
||||||
LIB_FUNCTION("3e+4Iv7IJ8U", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_accept);
|
LIB_FUNCTION("3e+4Iv7IJ8U", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_accept);
|
||||||
LIB_FUNCTION("TU-d9PfIHPM", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_socket);
|
LIB_FUNCTION("TU-d9PfIHPM", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_socket);
|
||||||
|
LIB_FUNCTION("fZOeZIOEmLw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_send);
|
||||||
LIB_FUNCTION("oBr313PppNE", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_sendto);
|
LIB_FUNCTION("oBr313PppNE", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_sendto);
|
||||||
|
LIB_FUNCTION("Ez8xjo9UF4E", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recv);
|
||||||
LIB_FUNCTION("lUk6wrGXyMw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recvfrom);
|
LIB_FUNCTION("lUk6wrGXyMw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recvfrom);
|
||||||
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
Libraries::Net::sys_setsockopt);
|
Libraries::Net::sys_setsockopt);
|
||||||
// LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, posix_getsockname);
|
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, posix_getsockname);
|
||||||
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
|
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
|
||||||
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
|
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
|
||||||
|
@ -318,6 +318,10 @@ s32 PS4_SYSV_ABI sceKernelIsStack(void* addr, void** start, void** end) {
|
|||||||
return memory->IsStack(std::bit_cast<VAddr>(addr), start, end);
|
return memory->IsStack(std::bit_cast<VAddr>(addr), start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 PS4_SYSV_ABI sceKernelIsAddressSanitizerEnabled() {
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelBatchMap(OrbisKernelBatchMapEntry* entries, s32 numEntries,
|
s32 PS4_SYSV_ABI sceKernelBatchMap(OrbisKernelBatchMapEntry* entries, s32 numEntries,
|
||||||
s32* numEntriesOut) {
|
s32* numEntriesOut) {
|
||||||
return sceKernelBatchMap2(entries, numEntries, numEntriesOut,
|
return sceKernelBatchMap2(entries, numEntries, numEntriesOut,
|
||||||
@ -689,6 +693,8 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("BC+OG5m9+bw", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemoryType);
|
LIB_FUNCTION("BC+OG5m9+bw", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemoryType);
|
||||||
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
||||||
LIB_FUNCTION("yDBwVAolDgg", "libkernel", 1, "libkernel", 1, 1, sceKernelIsStack);
|
LIB_FUNCTION("yDBwVAolDgg", "libkernel", 1, "libkernel", 1, 1, sceKernelIsStack);
|
||||||
|
LIB_FUNCTION("jh+8XiK4LeE", "libkernel", 1, "libkernel", 1, 1,
|
||||||
|
sceKernelIsAddressSanitizerEnabled);
|
||||||
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
||||||
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||||
LIB_FUNCTION("BQQniolj9tQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory2);
|
LIB_FUNCTION("BQQniolj9tQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory2);
|
||||||
|
@ -341,6 +341,8 @@ void RegisterCond(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init);
|
LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init);
|
||||||
LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
posix_pthread_condattr_destroy);
|
posix_pthread_condattr_destroy);
|
||||||
|
LIB_FUNCTION("EjllaAqAPZo", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
|
posix_pthread_condattr_setclock);
|
||||||
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
||||||
LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_signal);
|
LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_signal);
|
||||||
LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_destroy);
|
LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_destroy);
|
||||||
|
@ -324,6 +324,10 @@ PthreadT PS4_SYSV_ABI posix_pthread_self() {
|
|||||||
return g_curthread;
|
return g_curthread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PS4_SYSV_ABI posix_pthread_set_name_np(PthreadT thread, const char* name) {
|
||||||
|
Common::SetCurrentThreadName(name);
|
||||||
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI posix_pthread_yield() {
|
void PS4_SYSV_ABI posix_pthread_yield() {
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
@ -332,6 +336,14 @@ void PS4_SYSV_ABI sched_yield() {
|
|||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI posix_getpid() {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return GetCurrentProcessId();
|
||||||
|
#else
|
||||||
|
return getpid();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_pthread_once(PthreadOnce* once_control,
|
int PS4_SYSV_ABI posix_pthread_once(PthreadOnce* once_control,
|
||||||
void PS4_SYSV_ABI (*init_routine)()) {
|
void PS4_SYSV_ABI (*init_routine)()) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -644,9 +656,11 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("Jmi+9w9u0E4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create_name_np);
|
LIB_FUNCTION("Jmi+9w9u0E4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create_name_np);
|
||||||
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
||||||
LIB_FUNCTION("a2P9wYGeZvc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setprio);
|
LIB_FUNCTION("a2P9wYGeZvc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setprio);
|
||||||
|
LIB_FUNCTION("9vyP6Z7bqzc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_rename_np);
|
||||||
LIB_FUNCTION("FIs3-UQT9sg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getschedparam);
|
LIB_FUNCTION("FIs3-UQT9sg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getschedparam);
|
||||||
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
|
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
|
||||||
LIB_FUNCTION("6XG4B33N09g", "libScePosix", 1, "libkernel", 1, 1, sched_yield);
|
LIB_FUNCTION("6XG4B33N09g", "libScePosix", 1, "libkernel", 1, 1, sched_yield);
|
||||||
|
LIB_FUNCTION("HoLVWNanBBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpid);
|
||||||
|
|
||||||
// Posix-Kernel
|
// Posix-Kernel
|
||||||
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_once);
|
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_once);
|
||||||
@ -669,6 +683,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np));
|
LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np));
|
||||||
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit);
|
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit);
|
||||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||||
|
LIB_FUNCTION("oxMp8uPqa+U", "libkernel", 1, "libkernel", 1, 1, posix_pthread_set_name_np);
|
||||||
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_equal);
|
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_equal);
|
||||||
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, posix_pthread_yield);
|
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, posix_pthread_yield);
|
||||||
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, posix_pthread_getthreadid_np);
|
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, posix_pthread_getthreadid_np);
|
||||||
@ -676,6 +691,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setprio));
|
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setprio));
|
||||||
LIB_FUNCTION("rNhWz+lvOMU", "libkernel", 1, "libkernel", 1, 1, _sceKernelSetThreadDtors);
|
LIB_FUNCTION("rNhWz+lvOMU", "libkernel", 1, "libkernel", 1, 1, _sceKernelSetThreadDtors);
|
||||||
LIB_FUNCTION("6XG4B33N09g", "libkernel", 1, "libkernel", 1, 1, sched_yield);
|
LIB_FUNCTION("6XG4B33N09g", "libkernel", 1, "libkernel", 1, 1, sched_yield);
|
||||||
|
LIB_FUNCTION("HoLVWNanBBc", "libkernel", 1, "libkernel", 1, 1, posix_getpid);
|
||||||
LIB_FUNCTION("rcrVFJsQWRY", "libkernel", 1, "libkernel", 1, 1, ORBIS(scePthreadGetaffinity));
|
LIB_FUNCTION("rcrVFJsQWRY", "libkernel", 1, "libkernel", 1, 1, ORBIS(scePthreadGetaffinity));
|
||||||
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, ORBIS(scePthreadSetaffinity));
|
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, ORBIS(scePthreadSetaffinity));
|
||||||
}
|
}
|
||||||
|
@ -289,10 +289,14 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(PthreadAttrT* attr, const u64 mask) {
|
|||||||
void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) {
|
void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) {
|
||||||
// Posix
|
// Posix
|
||||||
LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init);
|
LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init);
|
||||||
|
LIB_FUNCTION("vQm4fDEsWi8", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_getstack);
|
||||||
LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
posix_pthread_attr_setstacksize);
|
posix_pthread_attr_setstacksize);
|
||||||
|
LIB_FUNCTION("Ucsu-OK+els", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_get_np);
|
||||||
LIB_FUNCTION("RtLRV-pBTTY", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("RtLRV-pBTTY", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
posix_pthread_attr_getschedpolicy);
|
posix_pthread_attr_getschedpolicy);
|
||||||
|
LIB_FUNCTION("JarMIy8kKEY", "libkernel", 1, "libkernel", 1, 1,
|
||||||
|
posix_pthread_attr_setschedpolicy);
|
||||||
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
posix_pthread_attr_setdetachstate);
|
posix_pthread_attr_setdetachstate);
|
||||||
LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy);
|
LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy);
|
||||||
|
@ -492,8 +492,9 @@ int PS4_SYSV_ABI sceHttpsFreeCaList() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceHttpsGetCaList() {
|
int PS4_SYSV_ABI sceHttpsGetCaList(int httpCtxId, OrbisHttpsCaList* list) {
|
||||||
LOG_ERROR(Lib_Http, "(STUBBED) called");
|
LOG_ERROR(Lib_Http, "(DUMMY) called, httpCtxId = {}", httpCtxId);
|
||||||
|
list->certsNum = 0;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "core/libraries/network/ssl.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
class SymbolsResolver;
|
class SymbolsResolver;
|
||||||
@ -24,6 +25,8 @@ struct OrbisHttpUriElement {
|
|||||||
u8 reserved[10];
|
u8 reserved[10];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using OrbisHttpsCaList = Libraries::Ssl::OrbisSslCaList;
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceHttpAbortRequest();
|
int PS4_SYSV_ABI sceHttpAbortRequest();
|
||||||
int PS4_SYSV_ABI sceHttpAbortRequestForce();
|
int PS4_SYSV_ABI sceHttpAbortRequestForce();
|
||||||
int PS4_SYSV_ABI sceHttpAbortWaitRequest();
|
int PS4_SYSV_ABI sceHttpAbortWaitRequest();
|
||||||
@ -120,7 +123,7 @@ int PS4_SYSV_ABI sceHttpSetResponseHeaderMaxSize();
|
|||||||
int PS4_SYSV_ABI sceHttpSetSendTimeOut();
|
int PS4_SYSV_ABI sceHttpSetSendTimeOut();
|
||||||
int PS4_SYSV_ABI sceHttpSetSocketCreationCallback();
|
int PS4_SYSV_ABI sceHttpSetSocketCreationCallback();
|
||||||
int PS4_SYSV_ABI sceHttpsFreeCaList();
|
int PS4_SYSV_ABI sceHttpsFreeCaList();
|
||||||
int PS4_SYSV_ABI sceHttpsGetCaList();
|
int PS4_SYSV_ABI sceHttpsGetCaList(int httpCtxId, OrbisHttpsCaList* list);
|
||||||
int PS4_SYSV_ABI sceHttpsGetSslError();
|
int PS4_SYSV_ABI sceHttpsGetSslError();
|
||||||
int PS4_SYSV_ABI sceHttpsLoadCert();
|
int PS4_SYSV_ABI sceHttpsLoadCert();
|
||||||
int PS4_SYSV_ABI sceHttpsSetMinSslVersion();
|
int PS4_SYSV_ABI sceHttpsSetMinSslVersion();
|
||||||
|
@ -11,15 +11,20 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <core/libraries/kernel/kernel.h>
|
#include <core/libraries/kernel/kernel.h>
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/error.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/network/net.h"
|
#include "core/libraries/network/net.h"
|
||||||
|
#include "net_epoll.h"
|
||||||
#include "net_error.h"
|
#include "net_error.h"
|
||||||
#include "net_util.h"
|
#include "net_util.h"
|
||||||
#include "netctl.h"
|
#include "netctl.h"
|
||||||
|
#include "sockets.h"
|
||||||
#include "sys_net.h"
|
#include "sys_net.h"
|
||||||
|
|
||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
@ -72,6 +77,8 @@ OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32*
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -169,6 +176,8 @@ int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addr
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_INFO(Lib_Net, "called, s = {}", s);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -551,6 +560,8 @@ int PS4_SYSV_ABI sceNetConnect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 a
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "s = {}", s);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -664,28 +675,156 @@ int PS4_SYSV_ABI sceNetEpollAbort() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollControl() {
|
int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, OrbisNetId id,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
OrbisNetEpollEvent* event) {
|
||||||
|
LOG_WARNING(Lib_Net, "called, epollid = {}, op = {}, id = {}", epollid,
|
||||||
|
magic_enum::enum_name(op), id);
|
||||||
|
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
|
if (!epoll) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto find_id = [&](OrbisNetId id) {
|
||||||
|
return std::ranges::find_if(epoll->events, [&](const auto& el) { return el.first == id; });
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case ORBIS_NET_EPOLL_CTL_ADD: {
|
||||||
|
if (event == nullptr) {
|
||||||
|
return -ORBIS_NET_EINVAL;
|
||||||
|
}
|
||||||
|
if (find_id(id) != epoll->events.end()) {
|
||||||
|
return -ORBIS_NET_EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(id);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
const auto socket = file->socket;
|
||||||
|
epoll_event native_event = {.events = ConvertEpollEventsIn(event->events),
|
||||||
|
.data = {.fd = id}};
|
||||||
|
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_ADD, socket->Native(), &native_event) == 0);
|
||||||
|
LOG_DEBUG(Lib_Net, "epoll_ctl succeeded");
|
||||||
|
#endif
|
||||||
|
epoll->events.emplace_back(id, *event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ORBIS_NET_EPOLL_CTL_MOD: {
|
||||||
|
if (event == nullptr) {
|
||||||
|
return -ORBIS_NET_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = find_id(id);
|
||||||
|
if (it == epoll->events.end()) {
|
||||||
|
return -ORBIS_NET_EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->second = *event;
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ORBIS_NET_EPOLL_CTL_DEL: {
|
||||||
|
if (event != nullptr) {
|
||||||
|
return -ORBIS_NET_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = find_id(id);
|
||||||
|
if (it == epoll->events.end()) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(id);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
const auto socket = file->socket;
|
||||||
|
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_DEL, socket->Native(), nullptr) == 0);
|
||||||
|
#endif
|
||||||
|
epoll->events.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return -ORBIS_NET_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollCreate() {
|
int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_WARNING(Lib_Net, "called, name = {}, flags = {}", name, flags);
|
||||||
|
if (flags != 0) {
|
||||||
|
return -ORBIS_NET_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->CreateHandle(name);
|
||||||
|
|
||||||
|
return epoll;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceNetEpollDestroy(OrbisNetId epollid) {
|
||||||
|
LOG_INFO(Lib_Net, "called, epollid = {}", epollid);
|
||||||
|
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
|
if (!epoll) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
epoll->Destroy();
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollDestroy() {
|
int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events, int maxevents,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
int timeout) {
|
||||||
return ORBIS_OK;
|
LOG_WARNING(Lib_Net, "called, epollid = {}, maxevents = {}, timeout = {}", epollid, maxevents,
|
||||||
}
|
timeout);
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollWait() {
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
LOG_TRACE(Lib_Net, "(STUBBED) called");
|
if (!epoll) {
|
||||||
|
return -ORBIS_NET_EBADF;
|
||||||
|
}
|
||||||
|
#ifdef __linux__
|
||||||
|
std::vector<epoll_event> native_events{static_cast<size_t>(maxevents)};
|
||||||
|
int result = epoll_wait(epoll->epoll_fd, native_events.data(), maxevents,
|
||||||
|
timeout == -1 ? timeout : timeout / 1000);
|
||||||
|
if (result < 0) {
|
||||||
|
LOG_ERROR(Lib_Net, "epoll_wait failed with {}", Common::GetLastErrorMsg());
|
||||||
|
return 0;
|
||||||
|
} else if (result == 0) {
|
||||||
|
LOG_DEBUG(Lib_Net, "timed out");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < result; ++i) {
|
||||||
|
const auto& current_event = native_events[i];
|
||||||
|
LOG_INFO(Lib_Net, "native_event[{}] = ( .events = {}, .data = {:#x} )", i,
|
||||||
|
current_event.events, current_event.data.u64);
|
||||||
|
const auto it = std::ranges::find_if(
|
||||||
|
epoll->events, [&](auto& el) { return el.first == current_event.data.fd; });
|
||||||
|
ASSERT(it != epoll->events.end());
|
||||||
|
events[i] = {
|
||||||
|
.events = ConvertEpollEventsOut(current_event.events),
|
||||||
|
.ident = static_cast<u64>(current_event.data.fd),
|
||||||
|
.data = it->second.data,
|
||||||
|
};
|
||||||
|
LOG_INFO(Lib_Net, "event[{}] = ( .events = {:#x}, .ident = {}, .data = {:#x} )", i,
|
||||||
|
events[i].events, events[i].ident, events[i].data.data_u64);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("sadness");
|
||||||
|
#endif
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int* PS4_SYSV_ABI sceNetErrnoLoc() {
|
int* PS4_SYSV_ABI sceNetErrnoLoc() {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_TRACE(Lib_Net, "called");
|
||||||
return &net_errno;
|
return &net_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,6 +903,8 @@ int PS4_SYSV_ABI sceNetGetMacAddress(Libraries::NetCtl::OrbisNetEtherAddr* addr,
|
|||||||
LOG_ERROR(Lib_Net, "addr is null!");
|
LOG_ERROR(Lib_Net, "addr is null!");
|
||||||
return ORBIS_NET_EINVAL;
|
return ORBIS_NET_EINVAL;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
||||||
netinfo->RetrieveEthernetAddr();
|
netinfo->RetrieveEthernetAddr();
|
||||||
memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6);
|
memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6);
|
||||||
@ -785,6 +926,8 @@ int PS4_SYSV_ABI sceNetGetpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* pa
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -847,6 +990,8 @@ int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* pa
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_INFO(Lib_Net, "called, s = {}", s);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1079,6 +1224,8 @@ const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32
|
|||||||
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "called, af = {}", af);
|
||||||
|
|
||||||
const char* returnvalue = nullptr;
|
const char* returnvalue = nullptr;
|
||||||
switch (af) {
|
switch (af) {
|
||||||
case ORBIS_NET_AF_INET:
|
case ORBIS_NET_AF_INET:
|
||||||
@ -1095,6 +1242,8 @@ const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32
|
|||||||
if (returnvalue == nullptr) {
|
if (returnvalue == nullptr) {
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ENOSPC;
|
*sceNetErrnoLoc() = ORBIS_NET_ENOSPC;
|
||||||
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG(Lib_Net, "returned {}", dst);
|
||||||
}
|
}
|
||||||
return returnvalue;
|
return returnvalue;
|
||||||
}
|
}
|
||||||
@ -1104,21 +1253,32 @@ int PS4_SYSV_ABI sceNetInetNtopWithScopeId() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ConvertFamilies(int family) {
|
||||||
|
switch (family) {
|
||||||
|
case ORBIS_NET_AF_INET:
|
||||||
|
return AF_INET;
|
||||||
|
case ORBIS_NET_AF_INET6:
|
||||||
|
return AF_INET6;
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("unsupported socket family {}", family);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst) {
|
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int res = InetPtonA(af, src, dst);
|
int res = InetPtonA(af, src, dst);
|
||||||
#else
|
#else
|
||||||
int res = inet_pton(af, src, dst);
|
int res = inet_pton(ConvertFamilies(af), src, dst);
|
||||||
#endif
|
#endif
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
UNREACHABLE();
|
UNREACHABLE_MSG("af = {}, src = {}, dst = {}", af, src, fmt::ptr(dst));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetInetPtonEx() {
|
int PS4_SYSV_ABI sceNetInetPtonEx(int af, const char* src, void* dst, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_WARNING(Lib_Net, "ignored flags, redirecting to sceNetInetPton");
|
||||||
return ORBIS_OK;
|
return sceNetInetPton(af, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetInetPtonWithScopeId() {
|
int PS4_SYSV_ABI sceNetInetPtonWithScopeId() {
|
||||||
@ -1155,6 +1315,8 @@ int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1240,6 +1402,8 @@ int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, u64 len, int flags) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "called, s = {}, len = {}, flags = {}", s, len, flags);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1283,6 +1447,8 @@ int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orb
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
// LOG_INFO(Lib_Net, "called, s = {}, len = {}, flags = {}", s, len, flags);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1325,6 +1491,8 @@ int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1388,12 +1556,13 @@ int PS4_SYSV_ABI sceNetResolverConnectDestroy() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverCreate() {
|
int PS4_SYSV_ABI sceNetResolverCreate(const char* name, int poolid, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called, name = {}, poolid = {}, flags = {}", name, poolid, flags);
|
||||||
return ORBIS_OK;
|
static int id = 1;
|
||||||
|
return id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverDestroy() {
|
int PS4_SYSV_ABI sceNetResolverDestroy(OrbisNetId resolverid) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
@ -1413,9 +1582,44 @@ int PS4_SYSV_ABI sceNetResolverStartAton6() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoa() {
|
int PS4_SYSV_ABI sceNetResolverStartNtoa(OrbisNetId resolverid, const char* hostname,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
OrbisNetInAddr* addr, int timeout, int retry, int flags) {
|
||||||
return ORBIS_OK;
|
LOG_INFO(Lib_Net,
|
||||||
|
"called, resolverid = {}, hostname = {}, timeout = {}, retry = {}, flags = {}",
|
||||||
|
resolverid, hostname, timeout, retry, flags);
|
||||||
|
|
||||||
|
if ((flags & ORBIS_NET_RESOLVER_ASYNC) != 0) {
|
||||||
|
// moves processing to EpollWait
|
||||||
|
LOG_ERROR(Lib_Net, "async resolution is not implemented");
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_RESOLVER_EINTERNAL;
|
||||||
|
auto ret = -ORBIS_NET_RESOLVER_EINTERNAL | ORBIS_NET_ERROR_BASE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const addrinfo hints = {
|
||||||
|
.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG,
|
||||||
|
.ai_family = AF_INET,
|
||||||
|
};
|
||||||
|
|
||||||
|
addrinfo* info = nullptr;
|
||||||
|
auto gai_result = getaddrinfo(hostname, nullptr, &hints, &info);
|
||||||
|
|
||||||
|
auto ret = ORBIS_OK;
|
||||||
|
if (gai_result != 0) {
|
||||||
|
// handle more errors
|
||||||
|
LOG_ERROR(Lib_Net, "address resolution for {} failed: {}", hostname,
|
||||||
|
gai_strerror(gai_result));
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
||||||
|
ret = -ORBIS_NET_ERETURN | ORBIS_NET_ERROR_BASE;
|
||||||
|
} else {
|
||||||
|
ASSERT(info && info->ai_addr);
|
||||||
|
in_addr resolved_addr = ((sockaddr_in*)info->ai_addr)->sin_addr;
|
||||||
|
LOG_DEBUG(Lib_Net, "resolved address for {}: {}", hostname, inet_ntoa(resolved_addr));
|
||||||
|
addr->inaddr_addr = resolved_addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(info);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoa6() {
|
int PS4_SYSV_ABI sceNetResolverStartNtoa6() {
|
||||||
@ -1423,9 +1627,21 @@ int PS4_SYSV_ABI sceNetResolverStartNtoa6() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords() {
|
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords(OrbisNetId resolverid, const char* hostname,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
OrbisNetResolverInfo* info, int timeout,
|
||||||
return ORBIS_OK;
|
int retry, int flags) {
|
||||||
|
LOG_WARNING(Lib_Net, "redirected to sceNetResolverStartNtoa");
|
||||||
|
|
||||||
|
OrbisNetInAddr addr{};
|
||||||
|
auto result = sceNetResolverStartNtoa(resolverid, hostname, &addr, timeout, retry, flags);
|
||||||
|
|
||||||
|
if (result == ORBIS_OK) {
|
||||||
|
info->addrs[0] = {.u = {.addr = addr}, .af = ORBIS_NET_AF_INET};
|
||||||
|
info->records = 1;
|
||||||
|
info->recordsv4 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx() {
|
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx() {
|
||||||
@ -1437,6 +1653,8 @@ int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, u64 len, int flags) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "called, s = {}, len = {}, flags = {}", s, len, flags);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1479,6 +1697,8 @@ int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flag
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1522,6 +1742,8 @@ int PS4_SYSV_ABI sceNetSendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1708,6 +1930,8 @@ int PS4_SYSV_ABI sceNetShutdown(OrbisNetId s, int how) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1750,6 +1974,9 @@ OrbisNetId PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_INFO(Lib_Net, "name = {}, family = {}, type = {}, protocol = {}", name ? name : "no-named",
|
||||||
|
family, type, protocol);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1758,6 +1985,7 @@ OrbisNetId PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int
|
|||||||
result = sys_socketex(name, family, type, protocol);
|
result = sys_socketex(name, family, type, protocol);
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
|
LOG_INFO(Lib_Net, "netId = {}", result);
|
||||||
return result; // Success
|
return result; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1792,6 +2020,8 @@ int PS4_SYSV_ABI sceNetSocketAbort(OrbisNetId s, int flags) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -1834,6 +2064,8 @@ int PS4_SYSV_ABI sceNetSocketClose(OrbisNetId s) {
|
|||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
LOG_INFO(Lib_Net, "netId = {}", s);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
int positiveErr;
|
int positiveErr;
|
||||||
@ -2097,12 +2329,14 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("rMyh97BU5pY", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetMemoryPoolStats);
|
LIB_FUNCTION("rMyh97BU5pY", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetMemoryPoolStats);
|
||||||
LIB_FUNCTION("+S-2-jlpaBo", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetNameToIndex);
|
LIB_FUNCTION("+S-2-jlpaBo", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetNameToIndex);
|
||||||
LIB_FUNCTION("TCkRD0DWNLg", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetpeername);
|
LIB_FUNCTION("TCkRD0DWNLg", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetpeername);
|
||||||
|
LIB_FUNCTION("TXFFFiNldU8", "libScePosix", 1, "libkernel", 1, 1, sys_getpeername);
|
||||||
LIB_FUNCTION("G3O2j9f5z00", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRandom);
|
LIB_FUNCTION("G3O2j9f5z00", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRandom);
|
||||||
LIB_FUNCTION("6Nx1hIQL9h8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRouteInfo);
|
LIB_FUNCTION("6Nx1hIQL9h8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRouteInfo);
|
||||||
LIB_FUNCTION("hLuXdjHnhiI", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo);
|
LIB_FUNCTION("hLuXdjHnhiI", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo);
|
||||||
LIB_FUNCTION("Cidi9Y65mP8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo6);
|
LIB_FUNCTION("Cidi9Y65mP8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo6);
|
||||||
LIB_FUNCTION("hoOAofhhRvE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockname);
|
LIB_FUNCTION("hoOAofhhRvE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockname);
|
||||||
LIB_FUNCTION("xphrZusl78E", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockopt);
|
LIB_FUNCTION("xphrZusl78E", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockopt);
|
||||||
|
LIB_FUNCTION("6O8EwYOgH9Y", "libScePosix", 1, "libkernel", 1, 1, sys_getsockopt);
|
||||||
LIB_FUNCTION("GA5ZDaLtUBE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfo);
|
LIB_FUNCTION("GA5ZDaLtUBE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfo);
|
||||||
LIB_FUNCTION("9mIcUExH34w", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfoInternal);
|
LIB_FUNCTION("9mIcUExH34w", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfoInternal);
|
||||||
LIB_FUNCTION("p2vxsE2U3RQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSystemTime);
|
LIB_FUNCTION("p2vxsE2U3RQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSystemTime);
|
||||||
|
@ -38,6 +38,7 @@ enum OrbisNetProtocol : u32 {
|
|||||||
ORBIS_NET_IPPROTO_IGMP = 2,
|
ORBIS_NET_IPPROTO_IGMP = 2,
|
||||||
ORBIS_NET_IPPROTO_TCP = 6,
|
ORBIS_NET_IPPROTO_TCP = 6,
|
||||||
ORBIS_NET_IPPROTO_UDP = 17,
|
ORBIS_NET_IPPROTO_UDP = 17,
|
||||||
|
ORBIS_NET_IPPROTO_IPV6 = 41,
|
||||||
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,6 +82,25 @@ enum OrbisNetSocketOption : u32 {
|
|||||||
ORBIS_NET_SO_PRIORITY = 0x1203
|
ORBIS_NET_SO_PRIORITY = 0x1203
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OrbisNetEpollFlag : u32 {
|
||||||
|
ORBIS_NET_EPOLL_CTL_ADD = 1,
|
||||||
|
ORBIS_NET_EPOLL_CTL_MOD = 2,
|
||||||
|
ORBIS_NET_EPOLL_CTL_DEL = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OrbisNetEpollEvents : u32 {
|
||||||
|
ORBIS_NET_EPOLLIN = 0x1,
|
||||||
|
ORBIS_NET_EPOLLOUT = 0x2,
|
||||||
|
ORBIS_NET_EPOLLERR = 0x8,
|
||||||
|
ORBIS_NET_EPOLLHUP = 0x10,
|
||||||
|
ORBIS_NET_EPOLLDESCID = 0x10000,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OrbisNetResolverFlag : u32 {
|
||||||
|
ORBIS_NET_RESOLVER_ASYNC = 0x1,
|
||||||
|
ORBIS_NET_RESOLVER_START_NTOA_DISABLE_IPADDRESS = 0x10000,
|
||||||
|
};
|
||||||
|
|
||||||
using OrbisNetId = s32;
|
using OrbisNetId = s32;
|
||||||
|
|
||||||
struct OrbisNetSockaddr {
|
struct OrbisNetSockaddr {
|
||||||
@ -98,6 +118,12 @@ struct OrbisNetSockaddrIn {
|
|||||||
char sin_zero[6];
|
char sin_zero[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using OrbisNetInAddr_t = u32;
|
||||||
|
|
||||||
|
struct OrbisNetInAddr {
|
||||||
|
OrbisNetInAddr_t inaddr_addr;
|
||||||
|
};
|
||||||
|
|
||||||
struct OrbisNetIovec {
|
struct OrbisNetIovec {
|
||||||
void* iov_base;
|
void* iov_base;
|
||||||
u64 iov_len;
|
u64 iov_len;
|
||||||
@ -113,6 +139,38 @@ struct OrbisNetMsghdr {
|
|||||||
int msg_flags;
|
int msg_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union OrbisNetEpollData {
|
||||||
|
void* ptr;
|
||||||
|
u32 data_u32;
|
||||||
|
int fd;
|
||||||
|
u64 data_u64;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisNetEpollEvent {
|
||||||
|
u32 events;
|
||||||
|
u32 pad;
|
||||||
|
u64 ident;
|
||||||
|
OrbisNetEpollData data;
|
||||||
|
};
|
||||||
|
|
||||||
|
union OrbisNetAddrUnion {
|
||||||
|
OrbisNetInAddr addr;
|
||||||
|
u8 addr6[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisNetResolverAddr {
|
||||||
|
OrbisNetAddrUnion u;
|
||||||
|
u32 af;
|
||||||
|
u32 pad[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisNetResolverInfo {
|
||||||
|
OrbisNetResolverAddr addrs[10];
|
||||||
|
u32 records;
|
||||||
|
u32 recordsv4;
|
||||||
|
u32 pad[14];
|
||||||
|
};
|
||||||
|
|
||||||
int PS4_SYSV_ABI in6addr_any();
|
int PS4_SYSV_ABI in6addr_any();
|
||||||
int PS4_SYSV_ABI in6addr_loopback();
|
int PS4_SYSV_ABI in6addr_loopback();
|
||||||
int PS4_SYSV_ABI sce_net_dummy();
|
int PS4_SYSV_ABI sce_net_dummy();
|
||||||
@ -218,10 +276,12 @@ int PS4_SYSV_ABI sceNetDumpRead();
|
|||||||
int PS4_SYSV_ABI sceNetDuplicateIpStart();
|
int PS4_SYSV_ABI sceNetDuplicateIpStart();
|
||||||
int PS4_SYSV_ABI sceNetDuplicateIpStop();
|
int PS4_SYSV_ABI sceNetDuplicateIpStop();
|
||||||
int PS4_SYSV_ABI sceNetEpollAbort();
|
int PS4_SYSV_ABI sceNetEpollAbort();
|
||||||
int PS4_SYSV_ABI sceNetEpollControl();
|
int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, OrbisNetId id,
|
||||||
int PS4_SYSV_ABI sceNetEpollCreate();
|
OrbisNetEpollEvent* event);
|
||||||
int PS4_SYSV_ABI sceNetEpollDestroy();
|
int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags);
|
||||||
int PS4_SYSV_ABI sceNetEpollWait();
|
int PS4_SYSV_ABI sceNetEpollDestroy(OrbisNetId epollid);
|
||||||
|
int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events, int maxevents,
|
||||||
|
int timeout);
|
||||||
int* PS4_SYSV_ABI sceNetErrnoLoc();
|
int* PS4_SYSV_ABI sceNetErrnoLoc();
|
||||||
int PS4_SYSV_ABI sceNetEtherNtostr();
|
int PS4_SYSV_ABI sceNetEtherNtostr();
|
||||||
int PS4_SYSV_ABI sceNetEtherStrton();
|
int PS4_SYSV_ABI sceNetEtherStrton();
|
||||||
@ -256,7 +316,7 @@ u16 PS4_SYSV_ABI sceNetHtons(u16 host16);
|
|||||||
const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size);
|
const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size);
|
||||||
int PS4_SYSV_ABI sceNetInetNtopWithScopeId();
|
int PS4_SYSV_ABI sceNetInetNtopWithScopeId();
|
||||||
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst);
|
int PS4_SYSV_ABI sceNetInetPton(int af, const char* src, void* dst);
|
||||||
int PS4_SYSV_ABI sceNetInetPtonEx();
|
int PS4_SYSV_ABI sceNetInetPtonEx(int af, const char* src, void* dst, int flags);
|
||||||
int PS4_SYSV_ABI sceNetInetPtonWithScopeId();
|
int PS4_SYSV_ABI sceNetInetPtonWithScopeId();
|
||||||
int PS4_SYSV_ABI sceNetInfoDumpStart();
|
int PS4_SYSV_ABI sceNetInfoDumpStart();
|
||||||
int PS4_SYSV_ABI sceNetInfoDumpStop();
|
int PS4_SYSV_ABI sceNetInfoDumpStop();
|
||||||
@ -282,14 +342,17 @@ int PS4_SYSV_ABI sceNetResolverConnect();
|
|||||||
int PS4_SYSV_ABI sceNetResolverConnectAbort();
|
int PS4_SYSV_ABI sceNetResolverConnectAbort();
|
||||||
int PS4_SYSV_ABI sceNetResolverConnectCreate();
|
int PS4_SYSV_ABI sceNetResolverConnectCreate();
|
||||||
int PS4_SYSV_ABI sceNetResolverConnectDestroy();
|
int PS4_SYSV_ABI sceNetResolverConnectDestroy();
|
||||||
int PS4_SYSV_ABI sceNetResolverCreate();
|
int PS4_SYSV_ABI sceNetResolverCreate(const char* name, int poolid, int flags);
|
||||||
int PS4_SYSV_ABI sceNetResolverDestroy();
|
int PS4_SYSV_ABI sceNetResolverDestroy(OrbisNetId resolverid);
|
||||||
int PS4_SYSV_ABI sceNetResolverGetError();
|
int PS4_SYSV_ABI sceNetResolverGetError();
|
||||||
int PS4_SYSV_ABI sceNetResolverStartAton();
|
int PS4_SYSV_ABI sceNetResolverStartAton();
|
||||||
int PS4_SYSV_ABI sceNetResolverStartAton6();
|
int PS4_SYSV_ABI sceNetResolverStartAton6();
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoa();
|
int PS4_SYSV_ABI sceNetResolverStartNtoa(OrbisNetId resolverid, const char* hostname,
|
||||||
|
OrbisNetInAddr* addr, int timeout, int retry, int flags);
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoa6();
|
int PS4_SYSV_ABI sceNetResolverStartNtoa6();
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords();
|
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords(OrbisNetId resolverid, const char* hostname,
|
||||||
|
OrbisNetResolverInfo* info, int timeout,
|
||||||
|
int retry, int flags);
|
||||||
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx();
|
int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx();
|
||||||
int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, u64 len, int flags);
|
int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, u64 len, int flags);
|
||||||
int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags);
|
int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags);
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "common/config.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/network/net_ctl_codes.h"
|
#include "core/libraries/network/net_ctl_codes.h"
|
||||||
#include "core/libraries/network/net_ctl_obj.h"
|
#include "core/libraries/network/net_ctl_obj.h"
|
||||||
#include "core/tls.h"
|
#include "core/tls.h"
|
||||||
@ -44,18 +46,22 @@ s32 NetCtlInternal::RegisterNpToolkitCallback(OrbisNetCtlCallbackForNpToolkit fu
|
|||||||
|
|
||||||
void NetCtlInternal::CheckCallback() {
|
void NetCtlInternal::CheckCallback() {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
const auto event = Config::getIsConnectedToNetwork() ? ORBIS_NET_CTL_EVENT_TYPE_IPOBTAINED
|
||||||
|
: ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED;
|
||||||
for (const auto [func, arg] : callbacks) {
|
for (const auto [func, arg] : callbacks) {
|
||||||
if (func != nullptr) {
|
if (func != nullptr) {
|
||||||
Core::ExecuteGuest(func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, arg);
|
Core::ExecuteGuest(func, event, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCtlInternal::CheckNpToolkitCallback() {
|
void NetCtlInternal::CheckNpToolkitCallback() {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
const auto event = Config::getIsConnectedToNetwork() ? ORBIS_NET_CTL_EVENT_TYPE_IPOBTAINED
|
||||||
|
: ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED;
|
||||||
for (const auto [func, arg] : nptool_callbacks) {
|
for (const auto [func, arg] : nptool_callbacks) {
|
||||||
if (func != nullptr) {
|
if (func != nullptr) {
|
||||||
Core::ExecuteGuest(func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, arg);
|
Core::ExecuteGuest(func, event, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
src/core/libraries/network/net_epoll.cpp
Normal file
72
src/core/libraries/network/net_epoll.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "net_epoll.h"
|
||||||
|
|
||||||
|
namespace Libraries::Net {
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsIn(u32 orbis_events) {
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
if ((orbis_events & ORBIS_NET_EPOLLIN) != 0) {
|
||||||
|
ret |= EPOLLIN;
|
||||||
|
}
|
||||||
|
if ((orbis_events & ORBIS_NET_EPOLLOUT) != 0) {
|
||||||
|
ret |= EPOLLOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsOut(u32 epoll_events) {
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
if ((epoll_events & EPOLLIN) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLIN;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLOUT) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLOUT;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLERR) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLERR;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLHUP) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLHUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EpollTable::CreateHandle(const char* name) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
|
if (auto it = std::ranges::find_if(epolls, [](const Epoll& e) { return e.Destroyed(); });
|
||||||
|
it != epolls.end()) {
|
||||||
|
*it = Epoll(name);
|
||||||
|
const auto ret = std::distance(epolls.begin(), it);
|
||||||
|
LOG_DEBUG(Lib_Net, "epollid = {}", ret);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
epolls.emplace_back(name);
|
||||||
|
const auto ret = epolls.size() - 1;
|
||||||
|
LOG_DEBUG(Lib_Net, "epollid = {}", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EpollTable::DeleteHandle(int d) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
Epoll* EpollTable::GetEpoll(int epollid) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
if (epollid >= epolls.size() || epolls[epollid].Destroyed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &epolls[epollid];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::Net
|
75
src/core/libraries/network/net_epoll.h
Normal file
75
src/core/libraries/network/net_epoll.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "core/libraries/network/net.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <wepoll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Libraries::Net {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
using epoll_handle = HANDLE;
|
||||||
|
#else
|
||||||
|
using epoll_handle = int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Epoll {
|
||||||
|
std::vector<std::pair<u32 /*netId*/, OrbisNetEpollEvent>> events{};
|
||||||
|
const char* name;
|
||||||
|
epoll_handle epoll_fd;
|
||||||
|
|
||||||
|
explicit Epoll(const char* name_) : name(name_), epoll_fd(epoll_create1(0)) {
|
||||||
|
ASSERT(epoll_fd != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Destroyed() const noexcept {
|
||||||
|
return destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy() noexcept {
|
||||||
|
events.clear();
|
||||||
|
#ifdef _WIN32
|
||||||
|
epoll_close(epoll_fd);
|
||||||
|
#else
|
||||||
|
close(epoll_fd);
|
||||||
|
#endif
|
||||||
|
epoll_fd = -1;
|
||||||
|
name = nullptr;
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool destroyed{};
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsIn(u32 orbis_events);
|
||||||
|
u32 ConvertEpollEventsOut(u32 epoll_events);
|
||||||
|
|
||||||
|
class EpollTable {
|
||||||
|
public:
|
||||||
|
EpollTable() = default;
|
||||||
|
virtual ~EpollTable() = default;
|
||||||
|
|
||||||
|
int CreateHandle(const char* name);
|
||||||
|
void DeleteHandle(int d);
|
||||||
|
Epoll* GetEpoll(int d);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Epoll> epolls;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::Net
|
@ -11,6 +11,7 @@ typedef int socklen_t;
|
|||||||
#else
|
#else
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -21,9 +22,13 @@ typedef int socklen_t;
|
|||||||
typedef int net_socket;
|
typedef int net_socket;
|
||||||
#endif
|
#endif
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if __linux__
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -100,6 +105,8 @@ bool NetUtilInternal::RetrieveEthernetAddr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
memcpy(ether_address.data(), ifr.ifr_hwaddr.sa_data, 6);
|
memcpy(ether_address.data(), ifr.ifr_hwaddr.sa_data, 6);
|
||||||
return true;
|
return true;
|
||||||
@ -107,4 +114,104 @@ bool NetUtilInternal::RetrieveEthernetAddr() {
|
|||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& NetUtilInternal::GetDefaultGateway() const {
|
||||||
|
return default_gateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetUtilInternal::RetrieveDefaultGateway() {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
#else
|
||||||
|
std::ifstream route{"/proc/net/route"};
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
std::getline(route, line);
|
||||||
|
while (std::getline(route, line)) {
|
||||||
|
std::istringstream iss{line};
|
||||||
|
std::string iface, destination, gateway;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
iss >> iface >> destination >> gateway >> std::hex >> flags;
|
||||||
|
|
||||||
|
if (destination == "00000000") {
|
||||||
|
u64 default_gateway{};
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << gateway;
|
||||||
|
ss >> default_gateway;
|
||||||
|
|
||||||
|
in_addr addr;
|
||||||
|
addr.s_addr = default_gateway;
|
||||||
|
this->default_gateway = inet_ntoa(addr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& NetUtilInternal::GetNetmask() const {
|
||||||
|
return netmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetUtilInternal::RetrieveNetmask() {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
char netmaskStr[INET_ADDRSTRLEN];
|
||||||
|
auto success = false;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::vector<u8> adapter_addresses(sizeof(IP_ADAPTER_ADDRESSES));
|
||||||
|
ULONG size_infos = sizeof(IP_ADAPTER_ADDRESSES);
|
||||||
|
|
||||||
|
if (GetAdaptersAddresses(AF_INET, 0, NULL,
|
||||||
|
reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_addresses.data()),
|
||||||
|
&size_infos) == ERROR_BUFFER_OVERFLOW)
|
||||||
|
adapter_addresses.resize(size_infos);
|
||||||
|
|
||||||
|
if (GetAdaptersAddresses(AF_INET, 0, NULL,
|
||||||
|
reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_addresses.data()),
|
||||||
|
&size_infos) == NO_ERROR &&
|
||||||
|
size_infos) {
|
||||||
|
PIP_ADAPTER_ADDRESSES adapter;
|
||||||
|
for (adapter = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_addresses.data()); adapter;
|
||||||
|
adapter = adapter->Next) {
|
||||||
|
PIP_ADAPTER_UNICAST_ADDRESS unicast = adapter->FirstUnicastAddress;
|
||||||
|
if (unicast) {
|
||||||
|
ULONG prefix_length = unicast->OnLinkPrefixLength;
|
||||||
|
ULONG mask = prefix_length == 0 ? 0 : 0xFFFFFFFF << (32 - prefix_length);
|
||||||
|
in_addr addr{};
|
||||||
|
addr.S_un.S_addr = htonl(mask);
|
||||||
|
inet_ntop(AF_INET, &addr, netmaskStr, INET_ADDRSTRLEN);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
ifaddrs* ifap;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifap) == 0) {
|
||||||
|
ifaddrs* p;
|
||||||
|
for (p = ifap; p; p = p->ifa_next) {
|
||||||
|
if (p->ifa_addr && p->ifa_addr->sa_family == AF_INET) {
|
||||||
|
auto sa = reinterpret_cast<sockaddr_in*>(p->ifa_netmask);
|
||||||
|
inet_ntop(AF_INET, &sa->sin_addr, netmaskStr, INET_ADDRSTRLEN);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
netmask = netmaskStr;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace NetUtil
|
} // namespace NetUtil
|
@ -15,10 +15,16 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<u8, 6> ether_address{};
|
std::array<u8, 6> ether_address{};
|
||||||
|
std::string default_gateway{};
|
||||||
|
std::string netmask{};
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const std::array<u8, 6>& GetEthernetAddr() const;
|
const std::array<u8, 6>& GetEthernetAddr() const;
|
||||||
|
const std::string& GetDefaultGateway() const;
|
||||||
|
const std::string& GetNetmask() const;
|
||||||
bool RetrieveEthernetAddr();
|
bool RetrieveEthernetAddr();
|
||||||
|
bool RetrieveDefaultGateway();
|
||||||
|
bool RetrieveNetmask();
|
||||||
};
|
};
|
||||||
} // namespace NetUtil
|
} // namespace NetUtil
|
@ -13,6 +13,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <common/singleton.h>
|
#include <common/singleton.h>
|
||||||
|
#include "common/config.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
@ -69,8 +70,8 @@ int PS4_SYSV_ABI sceNetBweUnregisterCallbackIpcInt() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlGetInfoV6() {
|
int PS4_SYSV_ABI sceNetCtlGetInfoV6(int code, void* param) {
|
||||||
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
|
LOG_ERROR(Lib_NetCtl, "(STUBBED) called, code = {}", code);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +96,9 @@ int PS4_SYSV_ABI sceNetCtlUnregisterCallbackV6() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlCheckCallback() {
|
int PS4_SYSV_ABI sceNetCtlCheckCallback() {
|
||||||
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
|
LOG_DEBUG(Lib_NetCtl, "called");
|
||||||
|
|
||||||
|
netctl.CheckCallback();
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,12 +163,14 @@ int PS4_SYSV_ABI sceNetCtlGetIfStat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "code = {}", code);
|
||||||
|
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case ORBIS_NET_CTL_INFO_DEVICE:
|
case ORBIS_NET_CTL_INFO_DEVICE:
|
||||||
info->device = ORBIS_NET_CTL_DEVICE_WIRED;
|
info->device = ORBIS_NET_CTL_DEVICE_WIRED;
|
||||||
break;
|
break;
|
||||||
case ORBIS_NET_CTL_INFO_ETHER_ADDR: {
|
case ORBIS_NET_CTL_INFO_ETHER_ADDR: {
|
||||||
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
|
||||||
netinfo->RetrieveEthernetAddr();
|
netinfo->RetrieveEthernetAddr();
|
||||||
memcpy(info->ether_addr.data, netinfo->GetEthernetAddr().data(), 6);
|
memcpy(info->ether_addr.data, netinfo->GetEthernetAddr().data(), 6);
|
||||||
} break;
|
} break;
|
||||||
@ -173,7 +178,8 @@ int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
|||||||
info->mtu = 1500; // default value
|
info->mtu = 1500; // default value
|
||||||
break;
|
break;
|
||||||
case ORBIS_NET_CTL_INFO_LINK:
|
case ORBIS_NET_CTL_INFO_LINK:
|
||||||
info->link = ORBIS_NET_CTL_LINK_DISCONNECTED;
|
info->link = Config::getIsConnectedToNetwork() ? ORBIS_NET_CTL_LINK_CONNECTED
|
||||||
|
: ORBIS_NET_CTL_LINK_DISCONNECTED;
|
||||||
break;
|
break;
|
||||||
case ORBIS_NET_CTL_INFO_IP_ADDRESS: {
|
case ORBIS_NET_CTL_INFO_IP_ADDRESS: {
|
||||||
strcpy(info->ip_address,
|
strcpy(info->ip_address,
|
||||||
@ -193,11 +199,50 @@ int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ORBIS_NET_CTL_INFO_PRIMARY_DNS:
|
||||||
|
strcpy(info->primary_dns, "1.1.1.1");
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_SECONDARY_DNS:
|
||||||
|
strcpy(info->secondary_dns, "1.1.1.1");
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_HTTP_PROXY_CONFIG:
|
||||||
|
info->http_proxy_config = 0;
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_HTTP_PROXY_SERVER:
|
||||||
|
strcpy(info->http_proxy_server, "0.0.0.0");
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_HTTP_PROXY_PORT:
|
||||||
|
info->http_proxy_port = 0;
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_IP_CONFIG:
|
||||||
|
info->ip_config = 1; // static
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_DHCP_HOSTNAME:
|
||||||
|
// info-> = ;
|
||||||
|
break;
|
||||||
|
case ORBIS_NET_CTL_INFO_NETMASK: {
|
||||||
|
auto success = netinfo->RetrieveNetmask();
|
||||||
|
if (success) {
|
||||||
|
strncpy(info->netmask, netinfo->GetNetmask().data(), sizeof(info->netmask));
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "netmask: {}", info->netmask);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Lib_NetCtl, "netmask: failed to retrieve");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ORBIS_NET_CTL_INFO_DEFAULT_ROUTE: {
|
||||||
|
auto success = netinfo->RetrieveDefaultGateway();
|
||||||
|
if (success) {
|
||||||
|
strncpy(info->netmask, netinfo->GetDefaultGateway().data(), sizeof(info->netmask));
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "default gateway: {}", info->netmask);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Lib_NetCtl, "default gateway: failed to retrieve");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Lib_NetCtl, "{} unsupported code", code);
|
LOG_ERROR(Lib_NetCtl, "{} unsupported code", code);
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +316,10 @@ int PS4_SYSV_ABI sceNetCtlGetScanInfoForSsidScanIpcInt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlGetState(int* state) {
|
int PS4_SYSV_ABI sceNetCtlGetState(int* state) {
|
||||||
*state = ORBIS_NET_CTL_STATE_DISCONNECTED;
|
LOG_DEBUG(Lib_NetCtl, "connected = {}", Config::getIsConnectedToNetwork());
|
||||||
|
const auto current_state = Config::getIsConnectedToNetwork() ? ORBIS_NET_CTL_STATE_IPOBTAINED
|
||||||
|
: ORBIS_NET_CTL_STATE_DISCONNECTED;
|
||||||
|
*state = current_state;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +344,7 @@ int PS4_SYSV_ABI sceNetCtlGetWifiType() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlInit() {
|
int PS4_SYSV_ABI sceNetCtlInit() {
|
||||||
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
|
LOG_DEBUG(Lib_NetCtl, "called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,12 +357,17 @@ int PS4_SYSV_ABI sceNetCtlRegisterCallback(OrbisNetCtlCallback func, void* arg,
|
|||||||
if (!func || !cid) {
|
if (!func || !cid) {
|
||||||
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
|
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 result = netctl.RegisterCallback(func, arg);
|
s32 result = netctl.RegisterCallback(func, arg);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "failed with {:#x}", result);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "*cid = {}", result);
|
||||||
*cid = result;
|
*cid = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +437,9 @@ int PS4_SYSV_ABI Func_D8DCB6973537A3DC() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit() {
|
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit() {
|
||||||
LOG_DEBUG(Lib_NetCtl, "(STUBBED) called");
|
LOG_DEBUG(Lib_NetCtl, "called");
|
||||||
|
|
||||||
|
netctl.CheckNpToolkitCallback();
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,10 +453,14 @@ int PS4_SYSV_ABI sceNetCtlRegisterCallbackForNpToolkit(OrbisNetCtlCallbackForNpT
|
|||||||
if (!func || !cid) {
|
if (!func || !cid) {
|
||||||
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
|
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 result = netctl.RegisterNpToolkitCallback(func, arg);
|
s32 result = netctl.RegisterNpToolkitCallback(func, arg);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
|
LOG_WARNING(Lib_NetCtl, "failed with {:#x}", result);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
LOG_DEBUG(Lib_NetCtl, "*cid = {}", result);
|
||||||
*cid = result;
|
*cid = result;
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -79,7 +79,7 @@ int PS4_SYSV_ABI sceNetBweSetInternetConnectionTestResultIpcInt();
|
|||||||
int PS4_SYSV_ABI sceNetBweStartInternetConnectionTestBandwidthTestIpcInt();
|
int PS4_SYSV_ABI sceNetBweStartInternetConnectionTestBandwidthTestIpcInt();
|
||||||
int PS4_SYSV_ABI sceNetBweStartInternetConnectionTestIpcInt();
|
int PS4_SYSV_ABI sceNetBweStartInternetConnectionTestIpcInt();
|
||||||
int PS4_SYSV_ABI sceNetBweUnregisterCallbackIpcInt();
|
int PS4_SYSV_ABI sceNetBweUnregisterCallbackIpcInt();
|
||||||
int PS4_SYSV_ABI sceNetCtlGetInfoV6();
|
int PS4_SYSV_ABI sceNetCtlGetInfoV6(int code, void* param);
|
||||||
int PS4_SYSV_ABI sceNetCtlGetResultV6();
|
int PS4_SYSV_ABI sceNetCtlGetResultV6();
|
||||||
int PS4_SYSV_ABI sceNetCtlGetStateV6();
|
int PS4_SYSV_ABI sceNetCtlGetStateV6();
|
||||||
int PS4_SYSV_ABI sceNetCtlRegisterCallbackV6();
|
int PS4_SYSV_ABI sceNetCtlRegisterCallbackV6();
|
||||||
|
@ -57,4 +57,23 @@ int P2PSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int P2PSocket::GetPeerName(OrbisNetSockaddr* addr, u32* namelen) {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int P2PSocket::read(void* buf, size_t len) {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int P2PSocket::write(const void* buf, size_t len) {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int P2PSocket::fstat(Libraries::Kernel::OrbisKernelStat* stat) {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} // namespace Libraries::Net
|
} // namespace Libraries::Net
|
@ -2,7 +2,12 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
|
#include "common/error.h"
|
||||||
|
#include "core/libraries/kernel/file_system.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
#include "net_error.h"
|
#include "net_error.h"
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
|
|
||||||
@ -108,6 +113,17 @@ static int ConvertReturnErrorCode(int retval) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ConvertFamilies(int family) {
|
||||||
|
switch (family) {
|
||||||
|
case ORBIS_NET_AF_INET:
|
||||||
|
return AF_INET;
|
||||||
|
case ORBIS_NET_AF_INET6:
|
||||||
|
return AF_INET6;
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("unsupported socket family {}", family);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ConvertLevels(int level) {
|
static int ConvertLevels(int level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case ORBIS_NET_SOL_SOCKET:
|
case ORBIS_NET_SOL_SOCKET:
|
||||||
@ -116,8 +132,13 @@ static int ConvertLevels(int level) {
|
|||||||
return IPPROTO_IP;
|
return IPPROTO_IP;
|
||||||
case ORBIS_NET_IPPROTO_TCP:
|
case ORBIS_NET_IPPROTO_TCP:
|
||||||
return IPPROTO_TCP;
|
return IPPROTO_TCP;
|
||||||
|
case ORBIS_NET_IPPROTO_UDP:
|
||||||
|
return IPPROTO_UDP;
|
||||||
|
case ORBIS_NET_IPPROTO_IPV6:
|
||||||
|
return IPPROTO_IPV6;
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("unhandled socket level {}", level);
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convertOrbisNetSockaddrToPosix(const OrbisNetSockaddr* src, sockaddr* dst) {
|
static void convertOrbisNetSockaddrToPosix(const OrbisNetSockaddr* src, sockaddr* dst) {
|
||||||
@ -142,6 +163,12 @@ static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) {
|
|||||||
memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4);
|
memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PosixSocket::PosixSocket(int domain, int type, int protocol) : Socket(domain, type, protocol) {
|
||||||
|
sock = socket(ConvertFamilies(domain), type, protocol);
|
||||||
|
LOG_DEBUG(Lib_Net, "socket = {}", sock);
|
||||||
|
socket_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
int PosixSocket::Close() {
|
int PosixSocket::Close() {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -154,19 +181,27 @@ int PosixSocket::Close() {
|
|||||||
|
|
||||||
int PosixSocket::Bind(const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PosixSocket::Bind(const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
sockaddr addr2;
|
sockaddr addr2;
|
||||||
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
||||||
return ConvertReturnErrorCode(::bind(sock, &addr2, sizeof(sockaddr_in)));
|
const auto result = ::bind(sock, &addr2, sizeof(addr2));
|
||||||
|
LOG_DEBUG(Lib_Net, "raw bind result = {}, errno = {}", result,
|
||||||
|
result == -1 ? Common::GetLastErrorMsg() : "none");
|
||||||
|
return ConvertReturnErrorCode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PosixSocket::Listen(int backlog) {
|
int PosixSocket::Listen(int backlog) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
return ConvertReturnErrorCode(::listen(sock, backlog));
|
return ConvertReturnErrorCode(::listen(sock, backlog));
|
||||||
}
|
}
|
||||||
|
|
||||||
int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to,
|
int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to,
|
||||||
u32 tolen) {
|
u32 tolen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
if (to != nullptr) {
|
if (to != nullptr) {
|
||||||
sockaddr addr;
|
sockaddr addr;
|
||||||
convertOrbisNetSockaddrToPosix(to, &addr);
|
convertOrbisNetSockaddrToPosix(to, &addr);
|
||||||
@ -180,6 +215,8 @@ int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetS
|
|||||||
int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from,
|
int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from,
|
||||||
u32* fromlen) {
|
u32* fromlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
// LOG_DEBUG(Lib_Net, "len = {}, flags = {:#x}, from = {:#x}", len, flags,
|
||||||
|
// reinterpret_cast<u64>(from));
|
||||||
if (from != nullptr) {
|
if (from != nullptr) {
|
||||||
sockaddr addr;
|
sockaddr addr;
|
||||||
int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen);
|
int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen);
|
||||||
@ -193,15 +230,20 @@ int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr*
|
|||||||
|
|
||||||
SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
sockaddr addr2;
|
sockaddr addr2;
|
||||||
net_socket new_socket = ::accept(sock, &addr2, (socklen_t*)addrlen);
|
socklen_t len = sizeof(addr2);
|
||||||
|
net_socket new_socket = ::accept(sock, &addr2, &len);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (new_socket != INVALID_SOCKET) {
|
if (new_socket != INVALID_SOCKET) {
|
||||||
#else
|
#else
|
||||||
if (new_socket >= 0) {
|
if (new_socket >= 0) {
|
||||||
#endif
|
#endif
|
||||||
|
if (addr && addrlen) {
|
||||||
convertPosixSockaddrToOrbis(&addr2, addr);
|
convertPosixSockaddrToOrbis(&addr2, addr);
|
||||||
*addrlen = sizeof(OrbisNetSockaddrIn);
|
*addrlen = sizeof(OrbisNetSockaddrIn);
|
||||||
|
}
|
||||||
return std::make_shared<PosixSocket>(new_socket);
|
return std::make_shared<PosixSocket>(new_socket);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -209,13 +251,23 @@ SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
|||||||
|
|
||||||
int PosixSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) {
|
int PosixSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
sockaddr addr2;
|
sockaddr addr2;
|
||||||
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
||||||
return ::connect(sock, &addr2, sizeof(sockaddr_in));
|
int result = 0;
|
||||||
|
do {
|
||||||
|
result = ::connect(sock, &addr2, sizeof(sockaddr_in));
|
||||||
|
LOG_DEBUG(Lib_Net, "raw connect result = {}, errno = {}", result,
|
||||||
|
result == -1 ? Common::GetLastErrorMsg() : "none");
|
||||||
|
} while (result == -1 && (errno == EINTR || errno == EINPROGRESS));
|
||||||
|
return ConvertReturnErrorCode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
sockaddr addr;
|
sockaddr addr;
|
||||||
convertOrbisNetSockaddrToPosix(name, &addr);
|
convertOrbisNetSockaddrToPosix(name, &addr);
|
||||||
if (name != nullptr) {
|
if (name != nullptr) {
|
||||||
@ -229,6 +281,23 @@ int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PosixSocket::GetPeerName(OrbisNetSockaddr* name, u32* namelen) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
|
sockaddr addr;
|
||||||
|
convertOrbisNetSockaddrToPosix(name, &addr);
|
||||||
|
if (name != nullptr) {
|
||||||
|
*namelen = sizeof(sockaddr_in);
|
||||||
|
}
|
||||||
|
int res = ::getpeername(sock, &addr, (socklen_t*)namelen);
|
||||||
|
if (res >= 0) {
|
||||||
|
convertPosixSockaddrToOrbis(&addr, name);
|
||||||
|
*namelen = sizeof(OrbisNetSockaddrIn);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#define CASE_SETSOCKOPT(opt) \
|
#define CASE_SETSOCKOPT(opt) \
|
||||||
case ORBIS_NET_##opt: \
|
case ORBIS_NET_##opt: \
|
||||||
return ConvertReturnErrorCode(setsockopt(sock, level, opt, (const char*)optval, optlen))
|
return ConvertReturnErrorCode(setsockopt(sock, level, opt, (const char*)optval, optlen))
|
||||||
@ -242,8 +311,9 @@ int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
|
||||||
level = ConvertLevels(level);
|
level = ConvertLevels(level);
|
||||||
|
LOG_INFO(Lib_Net, "level = {}, optname = {}, optlen = {}", level, optname, optlen);
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
::linger native_linger;
|
::linger native_linger;
|
||||||
if (level == SOL_SOCKET) {
|
if (level == SOL_SOCKET) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
@ -392,4 +462,37 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PosixSocket::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
sb->st_mode = 0000777u | 0140000u;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
struct stat st{};
|
||||||
|
int result = ::fstat(sock, &st);
|
||||||
|
sb->st_mode = 0000777u | 0140000u;
|
||||||
|
sb->st_size = st.st_size;
|
||||||
|
sb->st_blocks = st.st_blocks;
|
||||||
|
sb->st_blksize = st.st_blksize;
|
||||||
|
// sb->st_flags = st.st_flags;
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int PosixSocket::read(void* buf, size_t len) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return recv(sock, buf, len, 0);
|
||||||
|
#else
|
||||||
|
return ::read(sock, buf, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int PosixSocket::write(const void* buf, size_t len) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return send(sock, buf, len, 0);
|
||||||
|
#else
|
||||||
|
return ::write(sock, buf, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Net
|
} // namespace Libraries::Net
|
@ -26,6 +26,10 @@ typedef int net_socket;
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
|
namespace Libraries::Kernel {
|
||||||
|
struct OrbisKernelStat;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
|
|
||||||
struct Socket;
|
struct Socket;
|
||||||
@ -51,6 +55,12 @@ struct Socket {
|
|||||||
u32* fromlen) = 0;
|
u32* fromlen) = 0;
|
||||||
virtual int Connect(const OrbisNetSockaddr* addr, u32 namelen) = 0;
|
virtual int Connect(const OrbisNetSockaddr* addr, u32 namelen) = 0;
|
||||||
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
|
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
|
||||||
|
virtual int GetPeerName(OrbisNetSockaddr* addr, u32* namelen) = 0;
|
||||||
|
virtual int fstat(Libraries::Kernel::OrbisKernelStat* stat) = 0;
|
||||||
|
virtual int read(void* buf, size_t len) = 0;
|
||||||
|
virtual int write(const void* buf, size_t len) = 0;
|
||||||
|
virtual bool IsValid() const = 0;
|
||||||
|
virtual net_socket Native() const = 0;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,10 +75,7 @@ struct PosixSocket : public Socket {
|
|||||||
int sockopt_ip_maxttl = 0;
|
int sockopt_ip_maxttl = 0;
|
||||||
int sockopt_tcp_mss_to_advertise = 0;
|
int sockopt_tcp_mss_to_advertise = 0;
|
||||||
int socket_type;
|
int socket_type;
|
||||||
explicit PosixSocket(int domain, int type, int protocol)
|
explicit PosixSocket(int domain, int type, int protocol);
|
||||||
: Socket(domain, type, protocol), sock(socket(domain, type, protocol)) {
|
|
||||||
socket_type = type;
|
|
||||||
}
|
|
||||||
explicit PosixSocket(net_socket sock) : Socket(0, 0, 0), sock(sock) {}
|
explicit PosixSocket(net_socket sock) : Socket(0, 0, 0), sock(sock) {}
|
||||||
int Close() override;
|
int Close() override;
|
||||||
int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) override;
|
int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) override;
|
||||||
@ -81,6 +88,16 @@ struct PosixSocket : public Socket {
|
|||||||
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
||||||
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
||||||
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
||||||
|
int GetPeerName(OrbisNetSockaddr* addr, u32* namelen) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* stat) override;
|
||||||
|
int read(void* buf, size_t len) override;
|
||||||
|
int write(const void* buf, size_t len) override;
|
||||||
|
bool IsValid() const override {
|
||||||
|
return sock != -1;
|
||||||
|
}
|
||||||
|
net_socket Native() const override {
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct P2PSocket : public Socket {
|
struct P2PSocket : public Socket {
|
||||||
@ -96,6 +113,16 @@ struct P2PSocket : public Socket {
|
|||||||
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
||||||
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
||||||
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
||||||
|
int GetPeerName(OrbisNetSockaddr* addr, u32* namelen) override;
|
||||||
|
int read(void* buf, size_t len) override;
|
||||||
|
int write(const void* buf, size_t len) override;
|
||||||
|
int fstat(Libraries::Kernel::OrbisKernelStat* stat) override;
|
||||||
|
bool IsValid() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
net_socket Native() const override {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetInternal {
|
class NetInternal {
|
||||||
|
@ -633,8 +633,17 @@ int PS4_SYSV_ABI sceSslFreeSslCertName() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSslGetCaCerts() {
|
struct OrbisSslCaCerts {
|
||||||
|
void* certs;
|
||||||
|
u64 num;
|
||||||
|
void* pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSslGetCaCerts(int sslCtxId, OrbisSslCaCerts* certs) {
|
||||||
LOG_ERROR(Lib_Ssl, "(STUBBED) called");
|
LOG_ERROR(Lib_Ssl, "(STUBBED) called");
|
||||||
|
certs->certs = nullptr;
|
||||||
|
certs->num = 0;
|
||||||
|
certs->pool = nullptr;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,13 @@ class SymbolsResolver;
|
|||||||
|
|
||||||
namespace Libraries::Ssl {
|
namespace Libraries::Ssl {
|
||||||
|
|
||||||
|
struct OrbisSslCaCerts;
|
||||||
|
|
||||||
|
struct OrbisSslCaList {
|
||||||
|
void* certs;
|
||||||
|
int certsNum;
|
||||||
|
};
|
||||||
|
|
||||||
int PS4_SYSV_ABI CA_MGMT_allocCertDistinguishedName();
|
int PS4_SYSV_ABI CA_MGMT_allocCertDistinguishedName();
|
||||||
int PS4_SYSV_ABI CA_MGMT_certDistinguishedNameCompare();
|
int PS4_SYSV_ABI CA_MGMT_certDistinguishedNameCompare();
|
||||||
int PS4_SYSV_ABI CA_MGMT_convertKeyBlobToPKCS8Key();
|
int PS4_SYSV_ABI CA_MGMT_convertKeyBlobToPKCS8Key();
|
||||||
@ -136,7 +143,7 @@ int PS4_SYSV_ABI sceSslEnableOptionInternal();
|
|||||||
int PS4_SYSV_ABI sceSslFreeCaCerts();
|
int PS4_SYSV_ABI sceSslFreeCaCerts();
|
||||||
int PS4_SYSV_ABI sceSslFreeCaList();
|
int PS4_SYSV_ABI sceSslFreeCaList();
|
||||||
int PS4_SYSV_ABI sceSslFreeSslCertName();
|
int PS4_SYSV_ABI sceSslFreeSslCertName();
|
||||||
int PS4_SYSV_ABI sceSslGetCaCerts();
|
int PS4_SYSV_ABI sceSslGetCaCerts(int sslCtxId, OrbisSslCaCerts* certs);
|
||||||
int PS4_SYSV_ABI sceSslGetCaList();
|
int PS4_SYSV_ABI sceSslGetCaList();
|
||||||
int PS4_SYSV_ABI sceSslGetIssuerName();
|
int PS4_SYSV_ABI sceSslGetIssuerName();
|
||||||
int PS4_SYSV_ABI sceSslGetMemoryPoolStats();
|
int PS4_SYSV_ABI sceSslGetMemoryPoolStats();
|
||||||
|
@ -128,8 +128,18 @@ int PS4_SYSV_ABI sceSslGetAlpnSelected() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSslGetCaCerts() {
|
struct OrbisSslCaCerts {
|
||||||
LOG_ERROR(Lib_Ssl2, "(STUBBED) called");
|
void* certs;
|
||||||
|
u64 num;
|
||||||
|
void* pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceSslGetCaCerts(int sslCtxId, OrbisSslCaCerts* certs) {
|
||||||
|
// check if it is same as libSceSsl
|
||||||
|
LOG_ERROR(Lib_Ssl2, "(DUMMY) called");
|
||||||
|
certs->certs = nullptr;
|
||||||
|
certs->num = 0;
|
||||||
|
certs->pool = nullptr;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
#include <common/logging/log.h>
|
#include <common/logging/log.h>
|
||||||
#include <core/libraries/kernel/kernel.h>
|
#include <core/libraries/kernel/kernel.h>
|
||||||
|
#include "common/error.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
#include "net_error.h"
|
#include "net_error.h"
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
#include "sys_net.h"
|
#include "sys_net.h"
|
||||||
@ -12,13 +14,16 @@
|
|||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_WARNING(Lib_Net, "s = {}", s);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->Connect(addr, addrlen);
|
int returncode = sock->Connect(addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -28,13 +33,16 @@ int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 add
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_DEBUG(Lib_Net, "s = {}, addr = {}, addrlen = {}", s, fmt::ptr(addr), addrlen);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->Bind(addr, addrlen);
|
int returncode = sock->Bind(addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -44,35 +52,62 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
auto* file = h->GetFile(s);
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
auto new_sock = sock->Accept(addr, paddrlen);
|
|
||||||
if (!new_sock) {
|
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
|
||||||
LOG_ERROR(Lib_Net, "error creating new socket for accepting");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
auto id = ++netcall->next_sock_id;
|
|
||||||
netcall->socks.emplace(id, new_sock);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) {
|
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
|
auto new_sock = sock->Accept(addr, paddrlen);
|
||||||
|
if (!new_sock) {
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||||
|
LOG_ERROR(Lib_Net, "error creating new socket for accepting: {}",
|
||||||
|
Common::GetLastErrorMsg());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
u32 handle = h->CreateHandle();
|
||||||
|
auto* new_file = h->GetFile(handle);
|
||||||
|
new_file->is_opened = true;
|
||||||
|
new_file->type = Core::FileSys::FileType::Socket;
|
||||||
|
new_file->socket = new_sock;
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
|
int returncode = sock->GetPeerName(addr, paddrlen);
|
||||||
|
if (returncode >= 0) {
|
||||||
|
return returncode;
|
||||||
|
}
|
||||||
|
*Libraries::Kernel::__Error() = returncode;
|
||||||
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
|
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->GetSocketAddress(addr, paddrlen);
|
int returncode = sock->GetSocketAddress(addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -82,13 +117,16 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_WARNING(Lib_Net, "(DUMMY) called");
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->GetSocketOptions(level, optname, optval, optlen);
|
int returncode = sock->GetSocketOptions(level, optname, optval, optlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -98,13 +136,16 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_DEBUG(Lib_Net, "s = {}, backlog = {}", s, backlog);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->Listen(backlog);
|
int returncode = sock->Listen(backlog);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -113,16 +154,21 @@ int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
|||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
||||||
u32 optlen) {
|
u32 optlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_WARNING(Lib_Net, "netId = {}", s);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->SetSocketOptions(level, optname, optval, optlen);
|
int returncode = sock->SetSocketOptions(level, optname, optval, optlen);
|
||||||
|
LOG_INFO(Lib_Net, "returncode = {}", returncode);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
@ -145,9 +191,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case ORBIS_NET_SOCK_STREAM:
|
case ORBIS_NET_SOCK_STREAM:
|
||||||
case ORBIS_NET_SOCK_DGRAM:
|
case ORBIS_NET_SOCK_DGRAM:
|
||||||
case ORBIS_NET_SOCK_RAW:
|
case ORBIS_NET_SOCK_RAW: {
|
||||||
sock = std::make_shared<PosixSocket>(family, type, protocol);
|
const auto typed_socket = std::make_shared<PosixSocket>(family, type, protocol);
|
||||||
|
if (!typed_socket->IsValid()) {
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_EPROTONOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = std::move(typed_socket);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ORBIS_NET_SOCK_DGRAM_P2P:
|
case ORBIS_NET_SOCK_DGRAM_P2P:
|
||||||
case ORBIS_NET_SOCK_STREAM_P2P:
|
case ORBIS_NET_SOCK_STREAM_P2P:
|
||||||
sock = std::make_shared<P2PSocket>(family, type, protocol);
|
sock = std::make_shared<P2PSocket>(family, type, protocol);
|
||||||
@ -155,10 +208,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Unknown type {}", type);
|
UNREACHABLE_MSG("Unknown type {}", type);
|
||||||
}
|
}
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto id = ++netcall->next_sock_id;
|
u32 handle = h->CreateHandle();
|
||||||
netcall->socks.emplace(id, sock);
|
auto* file = h->GetFile(handle);
|
||||||
return id;
|
file->is_opened = true;
|
||||||
|
file->type = Core::FileSys::FileType::Socket;
|
||||||
|
file->socket = sock;
|
||||||
|
// auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||||
|
// auto id = ++netcall->next_sock_id;
|
||||||
|
// netcall->socks.emplace(id, sock);
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
|
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
|
||||||
return sys_socketex(nullptr, family, type, protocol);
|
return sys_socketex(nullptr, family, type, protocol);
|
||||||
@ -168,14 +227,19 @@ int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_INFO(Lib_Net, "called, s = {}", s);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
|
file->is_opened = false;
|
||||||
int returncode = sock->Close();
|
int returncode = sock->Close();
|
||||||
|
h->DeleteHandle(s);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
@ -183,15 +247,23 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
|||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sys_send(OrbisNetId s, const void* buf, u64 len, int flags) {
|
||||||
|
return sys_sendto(s, buf, len, flags, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
||||||
const OrbisNetSockaddr* addr, u32 addrlen) {
|
const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
LOG_WARNING(Lib_Net, "s = {}, len = {}, flags = {:#x}, addrlen = {}", s, len, flags, addrlen);
|
||||||
auto sock = netcall->FindSocket(s);
|
|
||||||
if (!sock) {
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->SendPacket(buf, len, flags, addr, addrlen);
|
int returncode = sock->SendPacket(buf, len, flags, addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@ -204,24 +276,33 @@ int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags)
|
|||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
|
||||||
|
ssize_t PS4_SYSV_ABI sys_recv(OrbisNetId s, void* buf, u64 len, int flags) {
|
||||||
|
return sys_recvfrom(s, buf, len, flags, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||||
u32* paddrlen) {
|
u32* paddrlen) {
|
||||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
// LOG_INFO(Lib_Net, "s = {}, buf = {:#x}, len = {}, flags = {:#x}", s,
|
||||||
auto sock = netcall->FindSocket(s);
|
// reinterpret_cast<u64>(buf), len, flags);
|
||||||
if (!sock) {
|
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(s);
|
||||||
|
if (!file || file->type != Core::FileSys::FileType::Socket) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto sock = file->socket;
|
||||||
int returncode = sock->ReceivePacket(buf, len, flags, addr, paddrlen);
|
int returncode = sock->ReceivePacket(buf, len, flags, addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
*Libraries::Kernel::__Error() = returncode;
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
// LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
ssize_t PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace Libraries::Net {
|
|||||||
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen);
|
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen);
|
||||||
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen);
|
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen);
|
||||||
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen);
|
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen);
|
||||||
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen);
|
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen);
|
||||||
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen);
|
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen);
|
||||||
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen);
|
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen);
|
||||||
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog);
|
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog);
|
||||||
@ -22,10 +22,12 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
|||||||
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol);
|
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol);
|
||||||
int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags);
|
int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags);
|
||||||
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s);
|
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s);
|
||||||
|
int PS4_SYSV_ABI sys_send(OrbisNetId s, const void* buf, u64 len, int flags);
|
||||||
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
||||||
const OrbisNetSockaddr* addr, u32 addrlen);
|
const OrbisNetSockaddr* addr, u32 addrlen);
|
||||||
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags);
|
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags);
|
||||||
int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
ssize_t PS4_SYSV_ABI sys_recv(OrbisNetId s, void* buf, u64 len, int flags);
|
||||||
|
ssize_t PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||||
u32* paddrlen);
|
u32* paddrlen);
|
||||||
int PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags);
|
ssize_t PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags);
|
||||||
} // namespace Libraries::Net
|
} // namespace Libraries::Net
|
@ -2545,14 +2545,18 @@ struct NpStateCallbackForNpToolkit {
|
|||||||
NpStateCallbackForNpToolkit NpStateCbForNp;
|
NpStateCallbackForNpToolkit NpStateCbForNp;
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpCheckCallbackForLib() {
|
int PS4_SYSV_ABI sceNpCheckCallbackForLib() {
|
||||||
LOG_DEBUG(Lib_NpManager, "(STUBBED) called");
|
LOG_DEBUG(Lib_NpManager, "called");
|
||||||
|
|
||||||
|
const auto state = Config::getPSNSignedIn() ? OrbisNpState::SignedIn : OrbisNpState::SignedOut;
|
||||||
|
|
||||||
|
NpStateCbForNp.func(1, state, NpStateCbForNp.userdata);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpRegisterStateCallbackForToolkit(OrbisNpStateCallbackForNpToolkit callback,
|
int PS4_SYSV_ABI sceNpRegisterStateCallbackForToolkit(OrbisNpStateCallbackForNpToolkit callback,
|
||||||
void* userdata) {
|
void* userdata) {
|
||||||
static int id = 0;
|
static int id = 0;
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_WARNING(Lib_NpManager, "(DUMMY) called");
|
||||||
NpStateCbForNp.func = callback;
|
NpStateCbForNp.func = callback;
|
||||||
NpStateCbForNp.userdata = userdata;
|
NpStateCbForNp.userdata = userdata;
|
||||||
return id;
|
return id;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
#include "core/libraries/system/commondialog.h"
|
||||||
#include "core/libraries/web_browser_dialog/webbrowserdialog.h"
|
#include "core/libraries/web_browser_dialog/webbrowserdialog.h"
|
||||||
|
|
||||||
namespace Libraries::WebBrowserDialog {
|
namespace Libraries::WebBrowserDialog {
|
||||||
@ -25,7 +26,7 @@ s32 PS4_SYSV_ABI sceWebBrowserDialogGetResult() {
|
|||||||
|
|
||||||
s32 PS4_SYSV_ABI sceWebBrowserDialogGetStatus() {
|
s32 PS4_SYSV_ABI sceWebBrowserDialogGetStatus() {
|
||||||
LOG_ERROR(Lib_WebBrowserDialog, "(STUBBED) called");
|
LOG_ERROR(Lib_WebBrowserDialog, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return (s32)Libraries::CommonDialog::Status::INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceWebBrowserDialogInitialize() {
|
s32 PS4_SYSV_ABI sceWebBrowserDialogInitialize() {
|
||||||
|
@ -134,6 +134,8 @@ void Emulator::Run(std::filesystem::path file, const std::vector<std::string> ar
|
|||||||
|
|
||||||
LOG_INFO(Config, "General LogType: {}", Config::getLogType());
|
LOG_INFO(Config, "General LogType: {}", Config::getLogType());
|
||||||
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
|
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
|
||||||
|
LOG_INFO(Config, "General isConnectedToNetwork: {}", Config::getIsConnectedToNetwork());
|
||||||
|
LOG_INFO(Config, "General isPsnSignedIn: {}", Config::getPSNSignedIn());
|
||||||
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());
|
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());
|
||||||
LOG_INFO(Config, "GPU readbacks: {}", Config::readbacks());
|
LOG_INFO(Config, "GPU readbacks: {}", Config::readbacks());
|
||||||
LOG_INFO(Config, "GPU readbackLinearImages: {}", Config::readbackLinearImages());
|
LOG_INFO(Config, "GPU readbackLinearImages: {}", Config::readbackLinearImages());
|
||||||
|
Loading…
Reference in New Issue
Block a user