mirror of
https://github.com/SysRay/psOff_public.git
synced 2024-11-23 14:29:39 +00:00
commit
f9634d9543
@ -6,6 +6,8 @@ project(${libName})
|
||||
|
||||
add_library(${libName} SHARED entry.cpp wepoll.c epoll.cpp socket.cpp resolver.cpp)
|
||||
|
||||
target_link_libraries(${libName} ws2_32)
|
||||
add_dependencies(${libName} boost config_emu)
|
||||
target_compile_definitions(${libName} PUBLIC BOOST_ALL_NO_LIB WIN32_LEAN_AND_MEAN)
|
||||
target_link_libraries(${libName} ws2_32 libboost_thread config_emu.lib)
|
||||
|
||||
setupModule(${libName})
|
||||
|
@ -124,10 +124,19 @@ constexpr int32_t ERROR_RESOLVER_ENOTFOUND = -2143223317;
|
||||
constexpr int32_t ERROR_RESOLVER_ENOTINIT = -2143223316;
|
||||
} // namespace Err
|
||||
|
||||
namespace NetErrNo {
|
||||
constexpr int32_t SCE_NET_EINTR = 4;
|
||||
constexpr int32_t SCE_NET_EBADF = 9;
|
||||
constexpr int32_t SCE_NET_EINVAL = 22;
|
||||
constexpr int32_t SCE_NET_EPROTONOSUPPORT = 43;
|
||||
constexpr int32_t SCE_NET_ENAMETOOLONG = 63;
|
||||
constexpr int32_t SCE_NET_RESOLVER_ETIMEDOUT = 226;
|
||||
}; // namespace NetErrNo
|
||||
|
||||
constexpr size_t SCE_NET_ETHER_ADDR_LEN = 6;
|
||||
constexpr size_t SCE_NET_ETHER_ADDRSTRLEN = 18;
|
||||
|
||||
constexpr size_t SCE_NET_RESOLVER_MULTIPLE_RECORDS_MAX = 16;
|
||||
|
||||
constexpr size_t SCE_NET_RESOLVER_PORT = 53;
|
||||
constexpr size_t SCE_NET_RESOLVER_HOSTNAME_LEN_MAX = 255;
|
||||
constexpr size_t SCE_NET_RESOLVER_HOSTNAME_LEN_MAX = 255;
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "logging.h"
|
||||
#include "types.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <WS2tcpip.h>
|
||||
#include <WinSock2.h>
|
||||
|
||||
@ -24,7 +23,6 @@ extern "C" {
|
||||
EXPORT const char* MODULE_NAME = "libSceNet";
|
||||
|
||||
EXPORT SYSV_ABI int* sceNetErrnoLoc() {
|
||||
g_net_errno = sce_WSAGetLastError();
|
||||
return &g_net_errno;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "types.h"
|
||||
#include "wepoll.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <WinSock2.h>
|
||||
#include <unordered_map>
|
||||
|
||||
|
@ -1,49 +1,226 @@
|
||||
#include "common.h"
|
||||
#include "config_emu.h"
|
||||
#include "logging.h"
|
||||
#include "resolverTypes.h"
|
||||
#include "socketTypes.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
LOG_DEFINE_MODULE(libSceNet);
|
||||
|
||||
namespace {} // namespace
|
||||
namespace {
|
||||
#define TEST_RESOLVER \
|
||||
if (rid < 0 || rid > 127 || g_resolvers[rid] == nullptr) return Err::ERROR_EINVAL
|
||||
|
||||
extern "C" int* sceNetErrnoLoc();
|
||||
|
||||
static io_service svc;
|
||||
|
||||
struct Resolver {
|
||||
char name[32];
|
||||
ip::tcp::resolver res;
|
||||
bool interrupted;
|
||||
int internError;
|
||||
|
||||
Resolver(): res(svc), interrupted(false), name() {}
|
||||
};
|
||||
|
||||
static Resolver* g_resolvers[128] = {nullptr};
|
||||
|
||||
class PreMap {
|
||||
std::unordered_map<std::string, SceNetInAddr_t> m_mapAddrs;
|
||||
|
||||
public:
|
||||
PreMap() {
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::RESOLVE);
|
||||
|
||||
if ((*jData).is_object()) {
|
||||
for (auto [key, value]: (*jData).items()) {
|
||||
try {
|
||||
SceNetInAddr_t addr;
|
||||
if (value.is_number_integer()) {
|
||||
value.get_to(addr);
|
||||
} else {
|
||||
std::string saddr;
|
||||
value.get_to(saddr);
|
||||
addr = ip::address_v4::from_string(saddr).to_ulong();
|
||||
}
|
||||
|
||||
m_mapAddrs.insert(std::pair<std::string, SceNetInAddr_t>(key, addr));
|
||||
} catch (json::exception& ex) {
|
||||
LOG_ERR(L"Invalid resolve.json field: %S", key.c_str());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_ERR(L"Something wrong with your resolve.json!");
|
||||
}
|
||||
|
||||
SceNetInAddr_t search(const std::string& hostname) {
|
||||
auto it = m_mapAddrs.find(hostname);
|
||||
if (it != m_mapAddrs.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
std::string_view const reverse_search(const SceNetInAddr_t addr) {
|
||||
auto it = std::find_if(m_mapAddrs.begin(), m_mapAddrs.end(), [&addr](auto&& p) { return p.second == addr; });
|
||||
if (it == m_mapAddrs.end()) return "";
|
||||
return it->first;
|
||||
}
|
||||
};
|
||||
|
||||
PreMap& getPreMap() {
|
||||
static PreMap imp;
|
||||
return imp;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
EXPORT SYSV_ABI SceNetId sceNetResolverCreate(const char* name, int memid, int flags) {
|
||||
if (flags != 0) {
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
static size_t count = 0;
|
||||
return ++count;
|
||||
LOG_TRACE(L"new resolver: %S (memid: %d, flags: %d)", name, memid, flags);
|
||||
static size_t count = 0;
|
||||
g_resolvers[++count] = new Resolver();
|
||||
if (auto namelen = ::strlen(name)) {
|
||||
if (namelen > sizeof(Resolver::name) - 1) {
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
::strncpy_s(g_resolvers[count]->name, name, namelen);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverStartNtoa(SceNetId rid, const char* hostname, SceNetInAddr_t* addr, int timeout, int retry, int flags) {
|
||||
EXPORT SYSV_ABI int sceNetResolverStartNtoa(SceNetId rid, const char* hostname, SceNetInAddr_t* addr, int timeout, int retries, int flags) {
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
TEST_RESOLVER;
|
||||
|
||||
auto resolver = g_resolvers[rid];
|
||||
resolver->internError = 0;
|
||||
|
||||
{
|
||||
std::string _hostname(hostname);
|
||||
if (auto _raddr = getPreMap().search(_hostname)) {
|
||||
*addr = _raddr;
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
|
||||
ip::tcp::resolver::query query(ip::tcp::v4(), hostname, "0");
|
||||
for (int cretr = 0; cretr < retries; ++cretr) {
|
||||
if (resolver->interrupted) {
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_EINTR;
|
||||
return Err::ERROR_EFAULT;
|
||||
}
|
||||
try {
|
||||
auto it = resolver->res.resolve(query);
|
||||
*addr = (*it).endpoint().address().to_v4().to_uint();
|
||||
return Ok;
|
||||
} catch (boost::system::system_error& ex) {
|
||||
LOG_ERR(L"%S: failed to resolve %S (%d/%d): %S", __FUNCTION__, hostname, cretr, retries, ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_RESOLVER_ETIMEDOUT;
|
||||
return getErr(ErrCode::_ETIMEDOUT);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverStartAton(SceNetId rid, const SceNetInAddr_t* addr, char* hostname, int len, int timeout, int retry, int flags) {
|
||||
TEST_RESOLVER;
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
|
||||
auto resolver = g_resolvers[rid];
|
||||
resolver->internError = 0;
|
||||
|
||||
{
|
||||
auto _hn = getPreMap().reverse_search(*addr);
|
||||
if (auto _hnlen = _hn.length()) {
|
||||
if (len <= _hnlen) return Err::ERROR_EINVAL;
|
||||
_hn.copy(hostname, _hnlen + 1);
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_RESOLVER_ETIMEDOUT;
|
||||
return getErr(ErrCode::_ETIMEDOUT);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverStartNtoaMultipleRecords(SceNetId rid, const char* hostname, SceNetResolverInfo* info, int timeout, int retry, int flags) {
|
||||
EXPORT SYSV_ABI int sceNetResolverStartNtoaMultipleRecords(SceNetId rid, const char* hostname, SceNetResolverInfo* info, int timeout, int retries, int flags) {
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
TEST_RESOLVER;
|
||||
|
||||
auto resolver = g_resolvers[rid];
|
||||
resolver->internError = 0;
|
||||
|
||||
{
|
||||
std::string _hostname(hostname);
|
||||
if (auto _raddr = getPreMap().search(_hostname)) {
|
||||
info->addrs[0].af = SCE_NET_AF_INET;
|
||||
info->addrs[0].un.addr = _raddr;
|
||||
info->records = 1;
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
|
||||
ip::tcp::resolver::query query(ip::tcp::v4(), hostname, "0");
|
||||
info->records = 0;
|
||||
for (int cretr = 0; cretr < retries; ++cretr) {
|
||||
// todo: should set sce_net_errno
|
||||
if (resolver->interrupted) {
|
||||
resolver->internError = NetErrNo::SCE_NET_EINTR;
|
||||
return Err::ERROR_EFAULT;
|
||||
}
|
||||
try {
|
||||
for (auto addr: resolver->res.resolve(query)) {
|
||||
auto& iaddr = info->addrs[info->records++];
|
||||
iaddr.af = SCE_NET_AF_INET;
|
||||
iaddr.un.addr = addr.endpoint().address().to_v4().to_uint();
|
||||
if (info->records == SCE_NET_RESOLVER_MULTIPLE_RECORDS_MAX) break;
|
||||
}
|
||||
info->records -= 1; // We should decrease value by 1 to get the actual records count
|
||||
info->dns4records = info->records;
|
||||
return Ok;
|
||||
} catch (boost::system::system_error& ex) {
|
||||
LOG_ERR(L"%S: failed to resolve %S (%d/%d): %S", __FUNCTION__, hostname, cretr, retries, ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_RESOLVER_ETIMEDOUT;
|
||||
return getErr(ErrCode::_ETIMEDOUT);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverGetError(SceNetId rid, int* result) {
|
||||
TEST_RESOLVER;
|
||||
LOG_USE_MODULE(libSceNet);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
*result = (int)ErrCode::_ETIMEDOUT;
|
||||
*result = g_resolvers[rid]->internError;
|
||||
return Ok;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverDestroy(SceNetId rid) {
|
||||
TEST_RESOLVER;
|
||||
delete g_resolvers[rid];
|
||||
g_resolvers[rid] = nullptr;
|
||||
return Ok;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceNetResolverAbort(SceNetId rid, int flags) {
|
||||
TEST_RESOLVER;
|
||||
g_resolvers[rid]->interrupted = true;
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "logging.h"
|
||||
#include "socketTypes.h"
|
||||
LOG_DEFINE_MODULE(libSceNet);
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <WS2tcpip.h>
|
||||
#include <mutex>
|
||||
|
||||
LOG_DEFINE_MODULE(libSceNet);
|
||||
|
||||
namespace {
|
||||
extern "C" int* sceNetErrnoLoc();
|
||||
|
||||
static inline int32_t sce_WSAGetLastError() {
|
||||
auto win_err = (uint32_t)WSAGetLastError();
|
||||
if (win_err == WSANOTINITIALISED) return Err::ERROR_ENOTINIT;
|
||||
@ -18,14 +20,20 @@ static inline int32_t sce_WSAGetLastError() {
|
||||
extern "C" {
|
||||
|
||||
EXPORT SYSV_ABI SceNetId sceNetSocket(const char* name, int family, int type, int protocol) {
|
||||
if (family != SCE_NET_AF_INET) return Err::ERROR_EINVAL;
|
||||
if (family != SCE_NET_AF_INET) {
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_EPROTONOSUPPORT;
|
||||
return Err::ERROR_EINVAL;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SCE_NET_SOCK_STREAM:
|
||||
case SCE_NET_SOCK_DGRAM:
|
||||
case SCE_NET_SOCK_RAW: return socket(AF_INET, type, protocol);
|
||||
|
||||
default: return Err::ERROR_EPROTOTYPE;
|
||||
default: {
|
||||
*sceNetErrnoLoc() = NetErrNo::SCE_NET_EPROTONOSUPPORT;
|
||||
return Err::ERROR_EPROTOTYPE;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok;
|
||||
|
@ -397,4 +397,15 @@ EXPORT SYSV_ABI int32_t __NID(_ZNK3sce7Toolkit2NP2V24Core12ResponseBase8getState
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sce::Toolkit::NP::V2::Core::Response<sce::Toolkit::NP::V2::UserProfile::NpProfiles>::Response()
|
||||
*
|
||||
*/
|
||||
|
||||
EXPORT SYSV_ABI int32_t __NID(_ZN3sce7Toolkit2NP2V24Core8ResponseINS2_11UserProfile10NpProfilesEEC1Ev)() {
|
||||
LOG_USE_MODULE(libSceNpToolkit2);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,12 @@ class Item {
|
||||
public:
|
||||
std::string_view const _name;
|
||||
|
||||
bool _dontfix; // If this flag is set then load function won't try fix the file according to default object
|
||||
json _json;
|
||||
boost::mutex _mutex;
|
||||
std::future<void> _future;
|
||||
|
||||
Item(std::string_view name): _name(name) {}
|
||||
Item(std::string_view name, bool df = false): _name(name), _dontfix(df) {}
|
||||
|
||||
std::pair<boost::unique_lock<boost::mutex>, json*> access() {
|
||||
_future.wait();
|
||||
@ -42,6 +43,7 @@ class Config: public IConfig {
|
||||
Item m_audio = {"audio.json"};
|
||||
Item m_controls = {"controls.json"};
|
||||
Item m_general = {"general.json"};
|
||||
Item m_resolve = {"resolve.json", true /*dontfix flag*/};
|
||||
|
||||
public:
|
||||
Config();
|
||||
@ -64,6 +66,7 @@ std::pair<boost::unique_lock<boost::mutex>, json*> Config::accessModule(ConfigMo
|
||||
case ConfigModFlag::AUDIO: return m_audio.access();
|
||||
case ConfigModFlag::CONTROLS: return m_controls.access();
|
||||
case ConfigModFlag::GENERAL: return m_general.access();
|
||||
case ConfigModFlag::RESOLVE: return m_resolve.access();
|
||||
|
||||
default: printf("Invalid bit flag!\n"); exit(1);
|
||||
}
|
||||
@ -79,6 +82,7 @@ bool Config::save(uint32_t flags) {
|
||||
if (flags & (uint32_t)ConfigModFlag::AUDIO) result &= m_audio.save();
|
||||
if (flags & (uint32_t)ConfigModFlag::CONTROLS) result &= m_controls.save();
|
||||
if (flags & (uint32_t)ConfigModFlag::GENERAL) result &= m_general.save();
|
||||
if (flags & (uint32_t)ConfigModFlag::RESOLVE) result &= m_resolve.save();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -153,7 +157,7 @@ Config::Config() {
|
||||
return missing;
|
||||
};
|
||||
|
||||
if (fixMissing(item->_json, defaults)) {
|
||||
if (!item->_dontfix && fixMissing(item->_json, defaults)) {
|
||||
should_resave = true;
|
||||
printf("%s: some missing parameters has been added!\n", item->_name.data());
|
||||
}
|
||||
@ -177,7 +181,7 @@ Config::Config() {
|
||||
return unused;
|
||||
};
|
||||
|
||||
if (removeUnused(item->_json, defaults)) {
|
||||
if (!item->_dontfix && removeUnused(item->_json, defaults)) {
|
||||
should_backup = true;
|
||||
should_resave = true;
|
||||
printf("%s: some unused parameters has been removed!\n", item->_name.data());
|
||||
@ -224,4 +228,6 @@ Config::Config() {
|
||||
m_general._future = std::async(std::launch::async, load, &m_general,
|
||||
json({{"systemlang", 1}, {"userIndex", 1}, {"profiles", json::array({defaultprof, defaultprof, defaultprof, defaultprof})}}),
|
||||
ConfigModFlag::GENERAL);
|
||||
|
||||
m_resolve._future = std::async(std::launch::async | std::launch::deferred, load, &m_resolve, json({{"localhost", "127.0.0.1"}}), ConfigModFlag::RESOLVE);
|
||||
}
|
||||
|
@ -8,11 +8,12 @@ using json = nlohmann::json;
|
||||
|
||||
enum class ConfigModFlag : uint32_t {
|
||||
NONE = 0,
|
||||
LOGGING = 2 << 0,
|
||||
GRAPHICS = 2 << 1,
|
||||
AUDIO = 2 << 2,
|
||||
CONTROLS = 2 << 3,
|
||||
GENERAL = 2 << 4,
|
||||
LOGGING = 1 << 0,
|
||||
GRAPHICS = 1 << 1,
|
||||
AUDIO = 1 << 2,
|
||||
CONTROLS = 1 << 3,
|
||||
GENERAL = 1 << 4,
|
||||
RESOLVE = 1 << 5,
|
||||
};
|
||||
|
||||
class IConfig {
|
||||
|
Loading…
Reference in New Issue
Block a user