diff --git a/Include/Aurora/Async/IWorkItemHandler.hpp b/Include/Aurora/Async/IWorkItemHandler.hpp index fe2f1fbd..dd2da2f1 100644 --- a/Include/Aurora/Async/IWorkItemHandler.hpp +++ b/Include/Aurora/Async/IWorkItemHandler.hpp @@ -12,7 +12,7 @@ namespace Aurora::Async struct IWorkItemHandler { enum class EProcessNext - { + { eInvalid = -1, eFinished = 0, eRerun, diff --git a/Include/Aurora/HWInfo/CpuBitId.inl b/Include/Aurora/HWInfo/CpuBitId.inl index 25a29ecd..856e5b83 100644 --- a/Include/Aurora/HWInfo/CpuBitId.inl +++ b/Include/Aurora/HWInfo/CpuBitId.inl @@ -27,9 +27,9 @@ namespace Aurora::HWInfo AuString CpuBitId::ToString() const { #if defined(_AU_MASSIVE_CPUID) - return fmt::format("{1:#0{0}b} {2:#0{0}b} {3:#0{0}b} {4:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper, upper2, upper3); + return fmt::format("{4:#0{0}b} {3:#0{0}b} {2:#0{0}b} {1:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper, upper2, upper3); #else - return fmt::format("{1:#0{0}b} {2:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper); + return fmt::format("{2:#0{0}b} {1:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper); #endif } diff --git a/Include/Aurora/Locale/LocaleStrings.hpp b/Include/Aurora/Locale/LocaleStrings.hpp index d12534ac..5c109cf5 100644 --- a/Include/Aurora/Locale/LocaleStrings.hpp +++ b/Include/Aurora/Locale/LocaleStrings.hpp @@ -5,15 +5,15 @@ namespace Aurora::Locale { - AUKN_SYM AuString NumbericLocaleGetDecimal(); -# - AUKN_SYM AuString TimeLocaleGetMSChar(); - AUKN_SYM AuString TimeLocaleS(); - AUKN_SYM AuString TimeLocaleGetDayChar(); + AUKN_SYM AuString NumbericLocaleGetDecimal(); - AUKN_SYM AuString TimeDateToString(const Time::tm &time); - AUKN_SYM AuString TimeDateToISO8601(const Time::tm &time, Time::ETimezoneShift shift = Time::ETimezoneShift::eUTC); + AUKN_SYM AuString TimeLocaleGetMSChar(); + AUKN_SYM AuString TimeLocaleS(); + AUKN_SYM AuString TimeLocaleGetDayChar(); - AUKN_SYM AuString ConvertMSToTimescale(AuUInt32 ms); - AUKN_SYM AuString ConvertNSToTimescale(AuUInt64 ns); + AUKN_SYM AuString TimeDateToString(const Time::tm &time); + AUKN_SYM AuString TimeDateToISO8601(const Time::tm &time, Time::ETimezoneShift shift = Time::ETimezoneShift::eUTC); + + AUKN_SYM AuString ConvertMSToTimescale(AuUInt32 ms); + AUKN_SYM AuString ConvertNSToTimescale(AuUInt64 ns); } \ No newline at end of file diff --git a/Include/Aurora/Memory/ExtendStlLikeSharedPtr.hpp b/Include/Aurora/Memory/ExtendStlLikeSharedPtr.hpp index a45ae753..c374a6b5 100644 --- a/Include/Aurora/Memory/ExtendStlLikeSharedPtr.hpp +++ b/Include/Aurora/Memory/ExtendStlLikeSharedPtr.hpp @@ -9,93 +9,93 @@ namespace Aurora::Memory { - template - struct ExSharedPtr : public Base_t - { - bool cached {}; + template + struct ExSharedPtr : public Base_t + { + bool cached {}; - using element_type = Base_t::element_type; - using weak_type = Base_t::weak_type; - using base_type = Base_t; - using Base_t::Base_t; + using element_type = Base_t::element_type; + using weak_type = Base_t::weak_type; + using base_type = Base_t; + using Base_t::Base_t; - ExSharedPtr(Base_t &&in) : Base_t(in) - {} - ExSharedPtr(const Base_t &in) : Base_t(in) - {} + ExSharedPtr(Base_t &&in) : Base_t(in) + {} + ExSharedPtr(const Base_t &in) : Base_t(in) + {} - operator Base_t() const noexcept - { - return *this; - } + operator Base_t() const noexcept + { + return *this; + } - ExSharedPtr &operator =(const Base_t &in) noexcept - { - Base_t::operator=(in); - return *this; - } + ExSharedPtr &operator =(const Base_t &in) noexcept + { + Base_t::operator=(in); + return *this; + } - TType_t &operator*() const - { - throwif(); - return Base_t::operator*(); - } + TType_t &operator*() const + { + throwif(); + return Base_t::operator*(); + } - TType_t *operator->() const - { - throwif(); - return Base_t::operator->(); - } + TType_t *operator->() const + { + throwif(); + return Base_t::operator->(); + } - TType_t &operator*() - { - throwif(); - return Base_t::operator*(); - } + TType_t &operator*() + { + throwif(); + return Base_t::operator*(); + } - TType_t *operator->() - { - throwif(); - return Base_t::operator->(); - } + TType_t *operator->() + { + throwif(); + return Base_t::operator->(); + } - private: + private: - auline void _cache() - { - cached = Base_t::operator bool(); - } + auline void _cache() + { + cached = Base_t::operator bool(); + } - auline void throwif() const - { - if (!cached) [[unlikely]] - { - if (!Base_t::operator bool()) [[likely]] - { - AU_THROW_STRING("ExSharedPointer Null Access Violation"); - } - } - } + auline void throwif() const + { + if (!cached) [[unlikely]] + { + if (!Base_t::operator bool()) [[likely]] + { + AU_THROW_STRING("ExSharedPointer Null Access Violation"); + } + } + } - auline void throwif() - { - if (!cached) [[unlikely]] - { - cached = Base_t::operator bool(); - if (!cached) [[likely]] - { - AU_THROW_STRING("ExSharedPointer Null Access Violation"); - } - } - } - }; + auline void throwif() + { + if (!cached) [[unlikely]] + { + cached = Base_t::operator bool(); + if (!cached) [[likely]] + { + AU_THROW_STRING("ExSharedPointer Null Access Violation"); + } + } + } + }; - template - struct ExSharedFromThis : Base_t - { - ExSharedPtr> SharedFromThis() - { - return Base_t::shared_from_this(); - } - }; + template + struct ExSharedFromThis : Base_t + { + ExSharedPtr> SharedFromThis() + { + return Base_t::shared_from_this(); + } + }; } \ No newline at end of file diff --git a/Include/Aurora/Process/ProcessMap.hpp b/Include/Aurora/Process/ProcessMap.hpp index 4df5f954..a8d591eb 100644 --- a/Include/Aurora/Process/ProcessMap.hpp +++ b/Include/Aurora/Process/ProcessMap.hpp @@ -49,4 +49,5 @@ namespace Aurora::Process AUKN_SYM AuOptional GetSegment(AuUInt pointer); AUKN_SYM PublicModule DumpExecutableRoot(); AUKN_SYM Segments DumpExecutableAll(); + AUKN_SYM void TryRescanSlow(); } \ No newline at end of file diff --git a/Include/Aurora/SWInfo/SWInfo.hpp b/Include/Aurora/SWInfo/SWInfo.hpp index b51e63df..5ba37f84 100644 --- a/Include/Aurora/SWInfo/SWInfo.hpp +++ b/Include/Aurora/SWInfo/SWInfo.hpp @@ -1,56 +1,71 @@ /*** - Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. - File: SWInfo.hpp - Date: 2022-1-25 - Author: Reece + File: SWInfo.hpp + Date: 2022-1-25 + Author: Reece ***/ #pragma once namespace Aurora::SWInfo { - struct OSInformation - { - // I tried to make these references, but benji the retard decided that objects and functions should hold constantness, not the data - // Returning a const reference to a struct containing const references, keeping the ability to move, and disabling copy -> impossible - // Nice tardlang + struct OSInformation + { + // I tried to make these references, but benji the retard decided that objects and functions should hold constantness, not the data + // Returning a const reference to a struct containing const references, keeping the ability to move, and disabling copy -> impossible + // Nice tardlang - const AuString *kKernelString; // - const AuString *kUserlandBrand; // Windows 10 Pro, Xbox, glibc, Ubuntu, distro name - const AuString *kUserlandDesktopEnv; // DWM, CF, [kwin/etc] - const AuString *kBuildString; // Example: (`Linux version wtf-doxing-lts (no-lts@fingerprinterinos) (some things here) #1 SMP Mon, 69 Apr 2000 13:33:37 +0000`, `??7??.?.amd64???.rs?_release.??-??`) + const AuString *kKernelString; // + const AuString *kUserlandBrand; // Windows 10 Pro, Xbox, glibc, Ubuntu, distro name + const AuString *kUserlandDesktopEnv; // DWM, CF, [kwin/etc] + const AuString *kBuildString; // Example: (`Linux version wtf-doxing-lts (no-lts@fingerprinterinos) (some things here) #1 SMP Mon, 69 Apr 2000 13:33:37 +0000`, `??7??.?.amd64???.rs?_release.??-??`) - AuUInt32 uKernelMajor {}; - AuUInt32 uKernelMinor {}; - AuUInt32 uKernelPatch {}; + AuUInt32 uKernelMajor {}; + AuUInt32 uKernelMinor {}; + AuUInt32 uKernelPatch {}; - AuUInt32 uUserlandMajor {}; - AuUInt32 uUserlandMinor {}; - AuUInt32 uUserlandPatch {}; + AuUInt32 uUserlandMajor {}; + AuUInt32 uUserlandMinor {}; + AuUInt32 uUserlandPatch {}; - bool bIsServer {}; - bool bIsEnterprise {}; + bool bIsServer {}; + bool bIsEnterprise {}; - Aurora::Build::EPlatform ePlatform = Aurora::Build::EPlatform::eEnumInvalid; + Aurora::Build::EPlatform ePlatform = Aurora::Build::EPlatform::eEnumInvalid; - private: - static inline AuString _kIgnore {}; + private: + static inline AuString _kIgnore {}; - public: + public: - OSInformation() : kKernelString(&_kIgnore), kUserlandDesktopEnv(&_kIgnore), kUserlandBrand(&_kIgnore), kBuildString(&_kIgnore), ePlatform(Build::EPlatform::eEnumInvalid) - {} + OSInformation() : kKernelString(&_kIgnore), kUserlandDesktopEnv(&_kIgnore), kUserlandBrand(&_kIgnore), kBuildString(&_kIgnore), ePlatform(Build::EPlatform::eEnumInvalid) + {} - AU_DEFINE_CTOR_VA(OSInformation, ( - kKernelString, - kUserlandBrand, - kUserlandDesktopEnv, - kBuildString, - ePlatform - )) - AU_NO_COPY(OSInformation); - AU_MOVE(OSInformation); - }; + AU_DEFINE_CTOR_VA(OSInformation, ( + kKernelString, + kUserlandBrand, + kUserlandDesktopEnv, + kBuildString, + ePlatform + )) + AU_NO_COPY(OSInformation); + AU_MOVE(OSInformation); + }; - AUKN_SYM const OSInformation & GetPlatformInfo(); + AUKN_SYM const OSInformation &GetPlatformInfo(); + + // VersionHelpers.h, except it doesn't lie to you and wont break NIX land + AUKN_SYM bool IsWindowsXPOrGreater(); + AUKN_SYM bool IsWindowsXPSP1OrGreater(); + AUKN_SYM bool IsWindowsXPSP2OrGreater(); + AUKN_SYM bool IsWindowsXPSP3OrGreater(); + AUKN_SYM bool IsWindowsVistaOrGreater(); + AUKN_SYM bool IsWindowsVistaSP1OrGreater(); + AUKN_SYM bool IsWindowsVistaSP2OrGreater(); + AUKN_SYM bool IsWindows7OrGreater(); + AUKN_SYM bool IsWindows7SP1OrGreater(); + AUKN_SYM bool IsWindows8OrGreater(); + AUKN_SYM bool IsWindows8Point1OrGreater(); + AUKN_SYM bool IsWindows10OrGreater(); + AUKN_SYM bool IsWindows11OrGreater(); } \ No newline at end of file diff --git a/Source/Entrypoint.cpp b/Source/Entrypoint.cpp index 9198d5b3..b5b9d105 100644 --- a/Source/Entrypoint.cpp +++ b/Source/Entrypoint.cpp @@ -44,8 +44,8 @@ static void Init() Aurora::RNG::Init(); Aurora::Hashing::InitHashing(); Aurora::Async::InitAsync(); - Aurora::HWInfo::Init(); Aurora::SWInfo::InitSwInfo(); + Aurora::HWInfo::Init(); Aurora::Telemetry::Init(); Aurora::Process::InitProcessMap(); } diff --git a/Source/HWInfo/CpuInfo.BSD.cpp b/Source/HWInfo/CpuInfo.BSD.cpp new file mode 100644 index 00000000..fc544dc4 --- /dev/null +++ b/Source/HWInfo/CpuInfo.BSD.cpp @@ -0,0 +1,40 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.BSD.cpp + Date: 2022-1-25 + Author: Reece +***/ +#include +#include "HWInfo.hpp" +#include "CpuInfo.hpp" +#include "CpuInfo.BSD.hpp" + +#if defined(AURORA_IS_BSD_DERIVED) + #include + #include +#endif + +#if defined(AURORA_IS_POSIX_DERIVED) + #include + #include +#endif + +namespace Aurora::HWInfo +{ + void SetCpuTopologyBSD() + { + auto opt = QueryBsdHwStat(HW_AVAILCPU); + if (opt.value_or(0) < 1) + { + opt = QueryBsdHwStat(HW_NCPU); + } + + gCpuInfo.socket = 1; + gCpuInfo.cores = 1; + gCpuInfo.threads = opt.value_or(1); + + // TODO: parse sysctl kern.sched.topology_spec + gCpuInfo.maskMTHalf = true; + } +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.BSD.hpp b/Source/HWInfo/CpuInfo.BSD.hpp new file mode 100644 index 00000000..e24d0ade --- /dev/null +++ b/Source/HWInfo/CpuInfo.BSD.hpp @@ -0,0 +1,13 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.BSD.hpp + Date: 2022-1-25 + Author: Reece +***/ +#pragma once + +namespace Aurora::HWInfo +{ + void SetCpuTopologyBSD(); +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.Linux.cpp b/Source/HWInfo/CpuInfo.Linux.cpp new file mode 100644 index 00000000..07e9531b --- /dev/null +++ b/Source/HWInfo/CpuInfo.Linux.cpp @@ -0,0 +1,34 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.Linux.cpp + Date: 2022-1-25 + Author: Reece +***/ +#include +#include "HWInfo.hpp" +#include "CpuInfo.hpp" +#include "CpuInfo.Linux.hpp" + +#if defined(AURORA_IS_BSD_DERIVED) + #include + #include +#endif + +#if defined(AURORA_IS_POSIX_DERIVED) + #include + #include +#endif + +namespace Aurora::HWInfo +{ + void SetCpuTopologyLinux() + { + gCpuInfo.socket = 1; + gCpuInfo.cores = 1; + gCpuInfo.threads = get_nprocs(); + + // TODO: parse /proc/cpuinfo + gCpuInfo.maskMTHalf = true; + } +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.Linux.hpp b/Source/HWInfo/CpuInfo.Linux.hpp new file mode 100644 index 00000000..f6e10cac --- /dev/null +++ b/Source/HWInfo/CpuInfo.Linux.hpp @@ -0,0 +1,13 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.Linux.hpp + Date: 2022-1-25 + Author: Reece +***/ +#pragma once + +namespace Aurora::HWInfo +{ + void SetCpuTopologyLinux(); +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.NT.cpp b/Source/HWInfo/CpuInfo.NT.cpp new file mode 100644 index 00000000..9d38fd43 --- /dev/null +++ b/Source/HWInfo/CpuInfo.NT.cpp @@ -0,0 +1,176 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.Nt.cpp + Date: 2022-1-25 + Author: Reece +***/ +#include +#include "HWInfo.hpp" +#include "CpuInfo.hpp" +#include "CpuInfo.NT.hpp" + +#if defined(AURORA_IS_MODERNNT_DERIVED) + #include +#endif + +namespace Aurora::HWInfo +{ + static bool IsWindowsLTSC() + { + OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0}; + DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_EQUAL); + + return !VerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask); + } + + static bool TrySetNtCpuSetInfoSlowExtended() + { + SYSTEM_CPU_SET_INFORMATION cpuSetInfo[128]; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION sysinfo[128]; + DWORD length = {}; + + if (!GetSystemCpuSetInformation(cpuSetInfo, sizeof(cpuSetInfo), &length, 0, 0)) + { + return false; + } + + struct CpuInfo + { + AuList low; + AuList server; + CpuBitId mask; + }; + AuBST cpuThreads; + AuUInt8 cpuCount; + + cpuCount = length / sizeof(decltype(*cpuSetInfo)); + + for (int i = 0; i < cpuCount; i++) + { + auto &idx = cpuThreads[cpuSetInfo[i].CpuSet.CoreIndex]; + AuUInt8 id = AuUInt8(cpuSetInfo[i].CpuSet.LogicalProcessorIndex + cpuSetInfo[i].CpuSet.Group); + auto cpuId = CpuBitId(id); + idx.server.push_back(cpuId); + idx.low.push_back(id); + idx.mask.Add(cpuId); + } + + for (const auto &[cpuId, coreIds] : cpuThreads) + { + AuUInt64 shortMask {}; + for (const auto &id : coreIds.server) + { + // TODO (scar): + if (false) + { + gCpuInfo.maskECores.Add(id); + } + } + + for (const auto &id : coreIds.low) + { + shortMask |= AuUInt64(1) << AuUInt64(id); + } + + gCpuInfo.serverTopology.push_back(coreIds.mask); + gCpuInfo.threadTopology.push_back(shortMask); + } + + gCpuInfo.socket = 1; + gCpuInfo.threads = cpuCount; + gCpuInfo.cores = cpuThreads.size(); + + if (!GetLogicalProcessorInformation(sysinfo, &length)) + { + return true; + } + + gCpuInfo.socket = 0; + length /= sizeof(*sysinfo); + + for (auto i = 0; i < length; i++) + { + if (sysinfo[i].Relationship == RelationProcessorPackage) + { + gCpuInfo.socket++; + } + } + + return true; + } + + void SetCpuTopologyNT() + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION sysinfo[128]; + DWORD length = AuArraySize(sysinfo) * sizeof(*sysinfo); + + if (SWInfo::IsWindows10OrGreater() || IsWindowsServer() || IsWindowsLTSC()) + { + if (TrySetNtCpuSetInfoSlowExtended()) + { + return; + } + } + + if (!GetLogicalProcessorInformation(sysinfo, &length)) + { + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + gCpuInfo.socket = 1; + gCpuInfo.cores = 1; + gCpuInfo.threads = sysinfo.dwNumberOfProcessors; + return; + } + + length /= sizeof(*sysinfo); + + gCpuInfo.socket = 0; + gCpuInfo.cores = 0; + gCpuInfo.threads = 0; + + + bool sparse = false; + for (auto i = 0; i < length; i++) + { + if (sysinfo[i].Relationship == RelationProcessorCore) + { + auto mask = sysinfo[i].ProcessorMask; + + gCpuInfo.cores++; + gCpuInfo.threadTopology.push_back(mask); + + CpuBitId serverId; + serverId.lower = mask; + gCpuInfo.serverTopology.push_back(mask); + + // TODO: fuck it, if some macro fuckery, use popcnt on x86 + // we just need to count the bits. first it was just two BitScanForwards. discontiguous cores fucked things up so now we have a loop just to count a few bits. + int counter {}; + unsigned long offset {}, tmp; + while (offset != (sizeof(offset) * 8)) + { + // Count the index to a 1 + if (BitScanForward(&tmp, mask >> offset) == 0) break; // mask was zero, end of scan + offset += tmp; + + // Count the 1's by inverting the bitmap and counting to 1 + BitScanForward(&tmp, ~(mask >> offset)); + offset += tmp; + + if (counter++) sparse = true; + + // Increment threads by the bits set in + gCpuInfo.threads += tmp; + } + } + else if (sysinfo[i].Relationship == RelationProcessorPackage) + { + gCpuInfo.socket++; + } + } + + gCpuInfo.maskMTContig = !sparse; + gCpuInfo.maskMTHalf = sparse; + } +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.NT.hpp b/Source/HWInfo/CpuInfo.NT.hpp new file mode 100644 index 00000000..7f24b8c9 --- /dev/null +++ b/Source/HWInfo/CpuInfo.NT.hpp @@ -0,0 +1,13 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: CpuId.Nt.hpp + Date: 2022-1-25 + Author: Reece +***/ +#pragma once + +namespace Aurora::HWInfo +{ + void SetCpuTopologyNT(); +} \ No newline at end of file diff --git a/Source/HWInfo/CpuInfo.cpp b/Source/HWInfo/CpuInfo.cpp index 2838e4d2..8c0ebe70 100644 --- a/Source/HWInfo/CpuInfo.cpp +++ b/Source/HWInfo/CpuInfo.cpp @@ -10,215 +10,33 @@ #include "CpuInfo.hpp" #include "CpuId.hpp" -#if defined(AURORA_IS_BSD_DERIVED) - #include - #include -#endif - #if defined(AURORA_IS_POSIX_DERIVED) #include #include #endif -#if defined(AURORA_COMPILER_CLANG) || defined(AURORA_IS_POSIX_DERIVED) - #include -#endif - #if defined(AURORA_IS_MODERNNT_DERIVED) - #include + #include "CpuInfo.NT.hpp" #endif +#if defined(AURORA_IS_BSD_DERIVED) + #include "CpuInfo.BSD.hpp" +#endif + +#if defined(AURORA_IS_LINUX_DERIVED) + #include "CpuInfo.Linux.hpp" +#endif namespace Aurora::HWInfo { -#if defined(AURORA_IS_MODERNNT_DERIVED) - static bool IsWindowsLTSC() - { - OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0}; - DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_EQUAL); - - return !VerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask); - } - - static bool TrySetNtCpuSetInfoSlowExtended() - { - SYSTEM_CPU_SET_INFORMATION cpuSetInfo[128]; - SYSTEM_LOGICAL_PROCESSOR_INFORMATION sysinfo[128]; - DWORD length = {}; - - if (!GetSystemCpuSetInformation(cpuSetInfo, sizeof(cpuSetInfo), &length, 0, 0)) - { - return false; - } - - struct CpuInfo - { - AuList low; - AuList server; - CpuBitId mask; - }; - AuBST cpuThreads; - AuUInt8 cpuCount; - - cpuCount = length / sizeof(decltype(*cpuSetInfo)); - - for (int i = 0; i < cpuCount; i++) - { - auto &idx = cpuThreads[cpuSetInfo[i].CpuSet.CoreIndex]; - AuUInt8 id = AuUInt8(cpuSetInfo[i].CpuSet.LogicalProcessorIndex + cpuSetInfo[i].CpuSet.Group); - auto cpuId = CpuBitId(id); - idx.server.push_back(cpuId); - idx.low.push_back(id); - idx.mask.Add(cpuId); - } - - for (const auto &[cpuId, coreIds] : cpuThreads) - { - AuUInt64 shortMask {}; - for (const auto &id : coreIds.server) - { - // TODO (scar): - if (false) - { - gCpuInfo.maskECores.Add(id); - } - } - - for (const auto &id : coreIds.low) - { - shortMask |= AuUInt64(1) << AuUInt64(id); - } - - gCpuInfo.serverTopology.push_back(coreIds.mask); - gCpuInfo.threadTopology.push_back(shortMask); - } - - gCpuInfo.socket = 1; - gCpuInfo.threads = cpuCount; - gCpuInfo.cores = cpuThreads.size(); - - if (!GetLogicalProcessorInformation(sysinfo, &length)) - { - return true; - } - - gCpuInfo.socket = 0; - length /= sizeof(*sysinfo); - - for (auto i = 0; i < length; i++) - { - if (sysinfo[i].Relationship == RelationProcessorPackage) - { - gCpuInfo.socket++; - } - } - - return true; - } - - static void SetCpuTopologyNT() - { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION sysinfo[128]; - DWORD length = AuArraySize(sysinfo) * sizeof(*sysinfo); - - if (IsWindows10OrGreater() || IsWindowsServer() || IsWindowsLTSC()) - { - if (TrySetNtCpuSetInfoSlowExtended()) - { - return; - } - } - - if (!GetLogicalProcessorInformation(sysinfo, &length)) - { - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - gCpuInfo.socket = 1; - gCpuInfo.cores = 1; - gCpuInfo.threads = sysinfo.dwNumberOfProcessors; - return; - } - - length /= sizeof(*sysinfo); - - gCpuInfo.socket = 0; - gCpuInfo.cores = 0; - gCpuInfo.threads = 0; - - - bool sparse = false; - for (auto i = 0; i < length; i++) - { - if (sysinfo[i].Relationship == RelationProcessorCore) - { - auto mask = sysinfo[i].ProcessorMask; - - gCpuInfo.cores++; - gCpuInfo.threadTopology.push_back(mask); - - CpuBitId serverId; - serverId.lower = mask; - gCpuInfo.serverTopology.push_back(mask); - - // TODO: fuck it, if some macro fuckery, use popcnt on x86 - // we just need to count the bits. first it was just two BitScanForwards. discontiguous cores fucked things up so now we have a loop just to count a few bits. - int counter {}; - unsigned long offset {}, tmp; - while (offset != (sizeof(offset) * 8)) - { - // Count the index to a 1 - if (BitScanForward(&tmp, mask >> offset) == 0) break; // mask was zero, end of scan - offset += tmp; - - // Count the 1's by inverting the bitmap and counting to 1 - BitScanForward(&tmp, ~(mask >> offset)); - offset += tmp; - - if (counter++) sparse = true; - - // Increment threads by the bits set in - gCpuInfo.threads += tmp; - } - } - else if (sysinfo[i].Relationship == RelationProcessorPackage) - { - gCpuInfo.socket++; - } - } - - gCpuInfo.maskMTContig = !sparse; - gCpuInfo.maskMTHalf = sparse; - } -#endif - static void SetCpuTopology() { #if defined(AURORA_IS_MODERNNT_DERIVED) SetCpuTopologyNT(); #elif defined(AURORA_IS_BSD_DERIVED) - - auto opt = QueryBsdHwStat(HW_AVAILCPU); - if (opt.value_or(0) < 1) - { - opt = QueryBsdHwStat(HW_NCPU); - } - - gCpuInfo.socket = 1; - gCpuInfo.cores = 1; - gCpuInfo.threads = opt.value_or(1); - - // TODO: parse sysctl kern.sched.topology_spec - gCpuInfo.maskMTHalf = true; - + SetCpuTopologyBSD(); #elif defined(AURORA_IS_LINUX_DERIVED) - - gCpuInfo.socket = 1; - gCpuInfo.cores = 1; - gCpuInfo.threads = get_nprocs(); - - // TODO: parse /proc/cpuinfo - gCpuInfo.maskMTHalf = true; - + SetCpuTopologyLinux(); #elif defined(AURORA_IS_POSIX_DERIVED) gCpuInfo.socket = 1; @@ -236,7 +54,7 @@ namespace Aurora::HWInfo } bool fakeMtHalf = (gCpuInfo.threads & 1) == 0; - gCpuInfo.maskMTHalf = true; + gCpuInfo.maskMTHalf = fakeMtHalf; if (fakeMtHalf) { diff --git a/Source/Locale/LocaleStrings.cpp b/Source/Locale/LocaleStrings.cpp index cb36c874..6be62a11 100644 --- a/Source/Locale/LocaleStrings.cpp +++ b/Source/Locale/LocaleStrings.cpp @@ -82,7 +82,7 @@ namespace Aurora::Locale // This is completely arbitrary // I feel as though this would do juststice to large and small timescales; with sane formatting, without being too autistic on resolution, and without returning excessively long (^ and localized) strings // We probably don't need to keep the MS around for more than a minute - // We can use the lengthy the MS padding to pad out seconds more into the ballpark of HH:MM:SS + // We can use the lengthy MS padding to pad out seconds more into the ballpark of HH:MM:SS // We can measure months, perhaps years, using mere days. We, and most normies, can comprehend 30/60/90/360/720 without much problem // // ! = pad diff --git a/Source/Process/ProcessMap.cpp b/Source/Process/ProcessMap.cpp index c14d7ee3..e26b3dca 100644 --- a/Source/Process/ProcessMap.cpp +++ b/Source/Process/ProcessMap.cpp @@ -1,230 +1,235 @@ /*** - Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. - File: ProcessMap.cpp - Date: 2022-1-23 - Author: Reece + File: ProcessMap.cpp + Date: 2022-1-23 + Author: Reece ***/ #include #include "ProcessMap.hpp" #if defined(AURORA_PLATFORM_WIN32) - #include "ProcessMap.Win32.hpp" + #include "ProcessMap.Win32.hpp" #endif #if defined(AURORA_IS_MODERNNT_DERIVED) - #include "ProcessMap.NT.hpp" + #include "ProcessMap.NT.hpp" #endif namespace Aurora::Process { - struct ModuleBasePairUtil - { - AuUInt operator()(const ModuleBasePair &in) const - { - return in.modBase; - } + struct ModuleBasePairUtil + { + AuUInt operator()(const ModuleBasePair &in) const + { + return in.modBase; + } - constexpr bool operator()(const ModuleBasePair &lhs, const AuString &rhs) const - { - return lhs.module == rhs; - } + constexpr bool operator()(const ModuleBasePair &lhs, const AuString &rhs) const + { + return lhs.module == rhs; + } - constexpr bool operator()(const ModuleBasePair &lhs, const AuUInt &rhs) const - { - return lhs.modBase == rhs; - } + constexpr bool operator()(const ModuleBasePair &lhs, const AuUInt &rhs) const + { + return lhs.modBase == rhs; + } - constexpr bool operator()(const ModuleBasePair &lhs, const ModuleBasePair &rhs) const - { - return rhs.modBase ? lhs.modBase == rhs.modBase : (rhs.module.size() ? rhs.module == rhs.module : false); - } - }; - - struct ModuleLookup : Segment - { - ModuleLookup() - {} + constexpr bool operator()(const ModuleBasePair &lhs, const ModuleBasePair &rhs) const + { + return rhs.modBase ? lhs.modBase == rhs.modBase : (rhs.module.size() ? rhs.module == rhs.module : false); + } + }; + + struct ModuleLookup : Segment + { + ModuleLookup() + {} - ModuleLookup(const Segment &s) : Segment(s) - {} - }; + ModuleLookup(const Segment &s) : Segment(s) + {} + }; - static AuBST gModulePtrMap; + static AuBST gModulePtrMap; - static const auto kMinPageAlignment = 4096; - static const auto kPageBufferPad = 20; + static const auto kMinPageAlignment = 4096; + static const auto kPageBufferPad = 20; - static AuThreadPrimitives::MutexUnique_t gMutexUnique; - static AuHashMapEx, ModuleBasePairUtil> gModuleMap; + static AuThreadPrimitives::MutexUnique_t gMutexUnique; + static AuHashMapEx, ModuleBasePairUtil> gModuleMap; - static AuUInt ToLowestPageAlignment(AuUInt in) - { - return in & ~(kMinPageAlignment - 1); - } + static AuUInt ToLowestPageAlignment(AuUInt in) + { + return in & ~(kMinPageAlignment - 1); + } - static AuSPtr GetModuleFromSegmentCache(AuUInt pointer) - { - AU_LOCK_GUARD(gMutexUnique); - auto itr = gModulePtrMap.find(pointer); - if (itr == gModulePtrMap.end()) return {}; - return itr->second.moduleMeta.lock(); - } + static AuSPtr GetModuleFromSegmentCache(AuUInt pointer) + { + AU_LOCK_GUARD(gMutexUnique); + auto itr = gModulePtrMap.find(pointer); + if (itr == gModulePtrMap.end()) return {}; + return itr->second.moduleMeta.lock(); + } - static AuOptional GetSegmentCache(AuUInt pointer) - { - AU_LOCK_GUARD(gMutexUnique); - auto itr = gModulePtrMap.find(pointer); - if (itr == gModulePtrMap.end()) return {}; - return itr->second; - } + static AuOptional GetSegmentCache(AuUInt pointer) + { + AU_LOCK_GUARD(gMutexUnique); + auto itr = gModulePtrMap.find(pointer); + if (itr == gModulePtrMap.end()) return {}; + return itr->second; + } - bool IsInModuleCache(const ModuleBasePair &pair) - { - AU_LOCK_GUARD(gMutexUnique); - return gModuleMap.find(pair) != gModuleMap.end(); - } + bool IsInModuleCache(const ModuleBasePair &pair) + { + AU_LOCK_GUARD(gMutexUnique); + return gModuleMap.find(pair) != gModuleMap.end(); + } - void InsertModuleCache(const ModuleBasePair &pair, const AuSPtr &mod) - { - for (auto &segment : mod->segments) - { - AU_LOCK_GUARD(gMutexUnique); - segment.moduleMeta = mod; + void InsertModuleCache(const ModuleBasePair &pair, const AuSPtr &mod) + { + for (auto &segment : mod->segments) + { + AU_LOCK_GUARD(gMutexUnique); + segment.moduleMeta = mod; - for (AuUInt i = segment.baseVa; i < segment.baseVa + segment.size; i += (kMinPageAlignment * kPageBufferPad)) - { - ModuleLookup a(segment); - gModulePtrMap[i] = a; - } - } + for (AuUInt i = segment.baseVa; i < segment.baseVa + segment.size; i += (kMinPageAlignment * kPageBufferPad)) + { + ModuleLookup a(segment); + gModulePtrMap[i] = a; + } + } - { - AU_LOCK_GUARD(gMutexUnique); - gModuleMap[pair] = mod; - } - } + { + AU_LOCK_GUARD(gMutexUnique); + gModuleMap[pair] = mod; + } + } - void RemoveModuleCache(const ModuleBasePair &eitherOr) - { - AU_LOCK_GUARD(gMutexUnique); - auto itr = gModuleMap.find(eitherOr); - if (itr == gModuleMap.end()) return; - auto mod = itr->second; + void RemoveModuleCache(const ModuleBasePair &eitherOr) + { + AU_LOCK_GUARD(gMutexUnique); + auto itr = gModuleMap.find(eitherOr); + if (itr == gModuleMap.end()) return; + auto mod = itr->second; - for (const auto &segment : mod->segments) - { - for (AuUInt i = segment.baseVa; i < segment.baseVa + segment.size; i += (kMinPageAlignment * kPageBufferPad)) - { - auto itr = gModulePtrMap.find(i); - if (itr != gModulePtrMap.end()) - { - gModulePtrMap.erase(itr); - } - } - } + for (const auto &segment : mod->segments) + { + for (AuUInt i = segment.baseVa; i < segment.baseVa + segment.size; i += (kMinPageAlignment * kPageBufferPad)) + { + auto itr = gModulePtrMap.find(i); + if (itr != gModulePtrMap.end()) + { + gModulePtrMap.erase(itr); + } + } + } - gModuleMap.erase(itr); - } + gModuleMap.erase(itr); + } - PublicModule GetFromModuleCache(AuUInt handle) - { - AU_LOCK_GUARD(gMutexUnique); - auto itr = gModuleMap.find({"", handle}); - if (itr == gModuleMap.end()) return {}; - return *itr->second; - } + PublicModule GetFromModuleCache(AuUInt handle) + { + AU_LOCK_GUARD(gMutexUnique); + auto itr = gModuleMap.find({"", handle}); + if (itr == gModuleMap.end()) return {}; + return *itr->second; + } - static AuOptional FindInCache(AuUInt pointer) - { - auto curPtr = ToLowestPageAlignment(pointer); - auto temp = GetSegmentCache(curPtr); - if (temp.has_value()) return temp; + static AuOptional FindInCache(AuUInt pointer) + { + auto curPtr = ToLowestPageAlignment(pointer); + auto temp = GetSegmentCache(curPtr); + if (temp.has_value()) return temp; - for (int i = 0; i < kPageBufferPad + 1; i++) - { - curPtr -= kMinPageAlignment; - temp = GetSegmentCache(curPtr); // TODO: i dont want to start from the top of the tree, thats stupid - if (temp.has_value()) return temp; - } + for (int i = 0; i < kPageBufferPad + 1; i++) + { + curPtr -= kMinPageAlignment; + temp = GetSegmentCache(curPtr); // TODO: i dont want to start from the top of the tree, thats stupid + if (temp.has_value()) return temp; + } - return AuOptional{}; - } + return AuOptional{}; + } - void InitProcessMap() - { - gMutexUnique = AuThreadPrimitives::MutexUnique(); + void InitProcessMap() + { + gMutexUnique = AuThreadPrimitives::MutexUnique(); - #if defined(AURORA_IS_MODERNNT_DERIVED) - InitProcessMapNt(); - #endif + #if defined(AURORA_IS_MODERNNT_DERIVED) + InitProcessMapNt(); + #endif - #if defined(AURORA_PLATFORM_WIN32) - MakeToolHelp32Snapshot(); - #endif - } + TryRescanSlow(); + } - void DeinitProcessMap() - { - gMutexUnique.reset(); - DeinitProcessMapNt(); - } + AUKN_SYM void TryRescanSlow() + { + #if defined(AURORA_PLATFORM_WIN32) + MakeToolHelp32Snapshot(); + #endif + } - AUKN_SYM AuOptional GetSegment(AuUInt pointer) - { - try - { - auto ceg = FindInCache(pointer); - if (ceg.has_value()) - { - return ceg; - } + void DeinitProcessMap() + { + gMutexUnique.reset(); + DeinitProcessMapNt(); + } - #if defined(AURORA_IS_MODERNNT_DERIVED) - if (MakeAwarePtr(pointer)) - { - return FindInCache(pointer); - } - else - { - return LookupArbitrarySegment(pointer); - } - #endif + AUKN_SYM AuOptional GetSegment(AuUInt pointer) + { + try + { + auto ceg = FindInCache(pointer); + if (ceg.has_value()) + { + return ceg; + } - return {}; - } - catch (...) - { - return {}; - } - } + #if defined(AURORA_IS_MODERNNT_DERIVED) + if (MakeAwarePtr(pointer)) + { + return FindInCache(pointer); + } + else + { + return LookupArbitrarySegment(pointer); + } + #endif - AUKN_SYM PublicModule DumpExecutableRoot() - { - try - { - return GetExecutableRoot(); - } - catch (...) - { - return {}; - } - } + return {}; + } + catch (...) + { + return {}; + } + } - AUKN_SYM Segments DumpExecutableAll() - { - try - { - Segments ret; - for (const auto &[meta, ptr] : gModuleMap) - { - ret.insert(ret.end(), ptr->segments.begin(), ptr->segments.end()); - } - return ret; - } - catch (...) - { - return {}; - } - } + AUKN_SYM PublicModule DumpExecutableRoot() + { + try + { + return GetExecutableRoot(); + } + catch (...) + { + return {}; + } + } + + AUKN_SYM Segments DumpExecutableAll() + { + try + { + Segments ret; + for (const auto &[meta, ptr] : gModuleMap) + { + ret.insert(ret.end(), ptr->segments.begin(), ptr->segments.end()); + } + return ret; + } + catch (...) + { + return {}; + } + } } \ No newline at end of file diff --git a/Source/Process/ProcessMap.hpp b/Source/Process/ProcessMap.hpp index 497fa331..f6bbd19e 100644 --- a/Source/Process/ProcessMap.hpp +++ b/Source/Process/ProcessMap.hpp @@ -1,25 +1,25 @@ /*** - Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. - File: ProcessMap.hpp - Date: 2022-1-23 - Author: Reece + File: ProcessMap.hpp + Date: 2022-1-23 + Author: Reece ***/ #pragma once namespace Aurora::Process { - struct ModuleBasePair - { - AuString module; - AuUInt modBase; - }; + struct ModuleBasePair + { + AuString module; + AuUInt modBase; + }; - PublicModule GetFromModuleCache(AuUInt handle); - void InsertModuleCache(const ModuleBasePair &pair, const AuSPtr &mod); - void RemoveModuleCache(const ModuleBasePair &eitherOr); - bool IsInModuleCache(const ModuleBasePair &pair); - - void InitProcessMap(); - void DeinitProcessMap(); + PublicModule GetFromModuleCache(AuUInt handle); + void InsertModuleCache(const ModuleBasePair &pair, const AuSPtr &mod); + void RemoveModuleCache(const ModuleBasePair &eitherOr); + bool IsInModuleCache(const ModuleBasePair &pair); + + void InitProcessMap(); + void DeinitProcessMap(); } \ No newline at end of file diff --git a/Source/SWInfo/SWInfo.cpp b/Source/SWInfo/SWInfo.cpp index ad2cd369..5cfd5822 100644 --- a/Source/SWInfo/SWInfo.cpp +++ b/Source/SWInfo/SWInfo.cpp @@ -1,163 +1,241 @@ /*** - Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. - File: SWInfo.cpp - Date: 2022-1-25 - Author: Reece + File: SWInfo.cpp + Date: 2022-1-25 + Author: Reece ***/ #include #include "SWInfo.hpp" #if defined(AURORA_PLATFORM_WIN32) - #include - - #include - - NTSYSAPI NTSTATUS RtlGetVersion( - PRTL_OSVERSIONINFOW lpVersionInformation - ); + #include + #include #endif - namespace Aurora::SWInfo { - static const AuString kDefaultStr; - static const OSInformation kDefaultInfo; - static OSInformation const *gInfo = &kDefaultInfo; + static AuUInt8 kWinVerNT4 = 0x0400; + static AuUInt8 kWinVerWIN2K = 0x0500; + static AuUInt8 kWinVerWINXP = 0x0501; + static AuUInt8 kWinVerWS03 = 0x0502; + static AuUInt8 kWinVerWIN6 = 0x0600; + static AuUInt8 kWinVerVISTA = 0x0600; + static AuUInt8 kWinVerWS08 = 0x0600; + static AuUInt8 kWinVerLONGHORN = 0x0600; + static AuUInt8 kWinVerWIN7 = 0x0601; + static AuUInt8 kWinVerWIN8 = 0x0602; + static AuUInt8 kWinVerWINBLUE = 0x0603; + static AuUInt8 kWinVerWIN10 = 0x0A00; - static AuString gKernelString; - static AuString gUserlandBrand; - static AuString gUserlandDesktopEnv; - static AuString gBuildString; - static OSInformation gTempInfo; + static AuUInt8 kWinVerWIN10 = 0x0A00; + static const AuString kDefaultStr; + static const OSInformation kDefaultInfo; + static OSInformation const *gInfo = &kDefaultInfo; - static void Reset() - { - gInfo = &kDefaultInfo; - } + static AuString gKernelString; + static AuString gUserlandBrand; + static AuString gUserlandDesktopEnv; + static AuString gBuildString; + static OSInformation gTempInfo; - AUKN_SYM const OSInformation & GetPlatformInfo() - { - return *gInfo; - } + static void Reset() + { + gInfo = &kDefaultInfo; + } + + AUKN_SYM const OSInformation &GetPlatformInfo() + { + return *gInfo; + } #if defined(AURORA_PLATFORM_WIN32) - static bool IsWindowsEnterpriseBranch() - { - OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0}; - DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_EQUAL); + static bool IsWindowsEnterpriseBranch() + { + OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, VER_SUITE_ENTERPRISE, 0}; + DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_EQUAL); - return !VerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask); - } + return !VerifyVersionInfoW(&osvi, VER_SUITENAME, dwlConditionMask); + } - auline bool Win32ReadRegistry(HKEY hKey, const wchar_t *key, AuString &strValue) - { - DWORD dwBufferSize {}; + auline bool Win32ReadRegistry(HKEY hKey, const wchar_t *key, AuString &strValue) + { + DWORD dwBufferSize {}; - if (RegQueryValueExW(hKey, key, 0, NULL, NULL, &dwBufferSize) != ERROR_SUCCESS) - { - SysPushErrorUnavailableError("Couldn't access registery key"); - return false; - } + if (RegQueryValueExW(hKey, key, 0, NULL, NULL, &dwBufferSize) != ERROR_SUCCESS) + { + SysPushErrorUnavailableError("Couldn't access registery key"); + return false; + } - std::wstring in; + std::wstring in; - if (!AuTryResize(in, dwBufferSize)) - { - return false; - } + if (!AuTryResize(in, dwBufferSize)) + { + return false; + } - if (RegQueryValueExW(hKey, key, 0, NULL, reinterpret_cast(in.data()), &dwBufferSize) != ERROR_SUCCESS) - { - SysPushErrorUnavailableError("Couldn't access registery key"); - return false; - } + if (RegQueryValueExW(hKey, key, 0, NULL, reinterpret_cast(in.data()), &dwBufferSize) != ERROR_SUCCESS) + { + SysPushErrorUnavailableError("Couldn't access registery key"); + return false; + } - strValue = Locale::ConvertFromWChar(in.data(), in.size()); - return strValue.size() == in.size(); - } + strValue = Locale::ConvertFromWChar(in.data(), in.size()); + return strValue.size() == in.size(); + } #endif - void InitSwInfo() - { - Reset(); + void InitSwInfo() + { + Reset(); - gTempInfo = AuMove(OSInformation(&gKernelString, &gUserlandBrand, &gUserlandDesktopEnv, &gBuildString, Aurora::Build::EPlatform::eEnumInvalid)); + gTempInfo = AuMove(OSInformation(&gKernelString, &gUserlandBrand, &gUserlandDesktopEnv, &gBuildString, Aurora::Build::EPlatform::eEnumInvalid)); - #if defined(AURORA_IS_MODERNNT_DERIVED) - OSVERSIONINFOEX info {}; - info.dwOSVersionInfoSize = sizeof(info); + #if defined(AURORA_IS_MODERNNT_DERIVED) + OSVERSIONINFOEX info {}; + info.dwOSVersionInfoSize = sizeof(info); - #if defined(AURORA_PLATFORM_WIN32) - gTempInfo.bIsServer = IsWindowsServer(); - gTempInfo.bIsEnterprise = IsWindowsEnterpriseBranch(); - #else - gTempInfo.bIsServer = false; - gTempInfo.bIsEnterprise = false; - #endif + #if defined(AURORA_PLATFORM_WIN32) + gTempInfo.bIsServer = IsWindowsServer(); + gTempInfo.bIsEnterprise = IsWindowsEnterpriseBranch(); + #else + gTempInfo.bIsServer = false; + gTempInfo.bIsEnterprise = false; + #endif - gUserlandDesktopEnv = "Desktop Window Manager"; + gUserlandDesktopEnv = "Desktop Window Manager"; - if (GetVersionExA(reinterpret_cast(&info))) - { - gTempInfo.uKernelPatch = info.dwBuildNumber; - gTempInfo.uKernelMinor = info.dwMinorVersion; - gTempInfo.uKernelMajor = info.dwMajorVersion; + if (GetVersionExA(reinterpret_cast(&info))) + { + gTempInfo.uKernelPatch = info.dwBuildNumber; + gTempInfo.uKernelMinor = info.dwMinorVersion; + gTempInfo.uKernelMajor = info.dwMajorVersion; - gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor; - gTempInfo.uUserlandMinor = info.wServicePackMajor; - gTempInfo.uUserlandPatch = info.wServicePackMinor; - } + gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor; + gTempInfo.uUserlandMinor = info.wServicePackMajor; + gTempInfo.uUserlandPatch = info.wServicePackMinor; + } - #if defined(AURORA_PLATFORM_WIN32) - { - RTL_OSVERSIONINFOEXW ovi {}; - ovi.dwOSVersionInfoSize = sizeof(ovi); + #if defined(AURORA_PLATFORM_WIN32) + { + RTL_OSVERSIONINFOEXW ovi {}; + ovi.dwOSVersionInfoSize = sizeof(ovi); - NTSTATUS(CALLBACK *pRtlGetVersion) (PRTL_OSVERSIONINFOW lpVersionInformation); - pRtlGetVersion = (decltype(pRtlGetVersion))GetProcAddress(LoadLibrary(TEXT("Ntdll.dll")), "RtlGetVersion"); + NTSTATUS(CALLBACK *pRtlGetVersion) (PRTL_OSVERSIONINFOW lpVersionInformation); + pRtlGetVersion = (decltype(pRtlGetVersion))GetProcAddress(LoadLibrary(TEXT("Ntdll.dll")), "RtlGetVersion"); - if (pRtlGetVersion && pRtlGetVersion(reinterpret_cast(&ovi)) == 0) - { - gTempInfo.uKernelPatch = ovi.dwBuildNumber; - gTempInfo.uKernelMinor = ovi.dwMinorVersion; - gTempInfo.uKernelMajor = ovi.dwMajorVersion; + if (pRtlGetVersion && pRtlGetVersion(reinterpret_cast(&ovi)) == 0) + { + gTempInfo.uKernelPatch = ovi.dwBuildNumber; + gTempInfo.uKernelMinor = ovi.dwMinorVersion; + gTempInfo.uKernelMajor = ovi.dwMajorVersion; - gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor; - gTempInfo.uUserlandMinor = ovi.wServicePackMajor; - gTempInfo.uUserlandPatch = ovi.wServicePackMinor; - } - } - - HKEY hKey; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS) - { - if (!Win32ReadRegistry(hKey, L"BuildLabEx", gBuildString)) - { - Win32ReadRegistry(hKey, L"BuildLab", gBuildString); - } - Win32ReadRegistry(hKey, L"ProductName", gUserlandBrand); - RegCloseKey(hKey); - } - #endif + gTempInfo.uUserlandMajor = gTempInfo.uKernelMajor; + gTempInfo.uUserlandMinor = ovi.wServicePackMajor; + gTempInfo.uUserlandPatch = ovi.wServicePackMinor; + } + } + + HKEY hKey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (!Win32ReadRegistry(hKey, L"BuildLabEx", gBuildString)) + { + Win32ReadRegistry(hKey, L"BuildLab", gBuildString); + } + Win32ReadRegistry(hKey, L"ProductName", gUserlandBrand); + RegCloseKey(hKey); + } + #endif - if (gKernelString.empty()) - { - gKernelString = fmt::format("Microsoft NT {}.{}.{}", gTempInfo.uKernelMajor, gTempInfo.uKernelMinor, gTempInfo.uKernelPatch); - } + if (gKernelString.empty()) + { + gKernelString = fmt::format("Microsoft NT {}.{}.{}", gTempInfo.uKernelMajor, gTempInfo.uKernelMinor, gTempInfo.uKernelPatch); + } - if (gUserlandBrand.empty()) - { - gUserlandBrand = fmt::format("NT Userland {}.{}.{}", gTempInfo.uUserlandMajor, gTempInfo.uUserlandMinor, gTempInfo.uUserlandPatch); - } + if (gUserlandBrand.empty()) + { + gUserlandBrand = fmt::format("NT Userland {}.{}.{}", gTempInfo.uUserlandMajor, gTempInfo.uUserlandMinor, gTempInfo.uUserlandPatch); + } - #endif + #endif - gTempInfo.ePlatform = Build::kCurrentPlatform; + gTempInfo.ePlatform = Build::kCurrentPlatform; - gInfo = &gTempInfo; - } + gInfo = &gTempInfo; + } + + static bool IsWindowsVersionOrGreater(AuUInt8 major, AuUInt8 ignored, AuUInt8 sp) + { + return gInfo->ePlatform == Build::EPlatform::ePlatformWin32 && gInfo->uKernelMajor >= major && gInfo->uUserlandMinor >= sp; + } + + AUKN_SYM bool IsWindowsXPOrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 0); + } + + AUKN_SYM bool IsWindowsXPSP1OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 1); + } + + AUKN_SYM bool IsWindowsXPSP2OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 2); + } + + AUKN_SYM bool IsWindowsXPSP3OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWINXP, kWinVerWINXP, 3); + } + + AUKN_SYM bool IsWindowsVistaOrGreater() + { + return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 0); + } + + AUKN_SYM bool IsWindowsVistaSP1OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 1); + } + + AUKN_SYM bool IsWindowsVistaSP2OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerVISTA, kWinVerVISTA, 2); + } + + AUKN_SYM bool IsWindows7OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWIN7, kWinVerWIN7, 0); + } + + AUKN_SYM bool IsWindows7SP1OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWIN7, kWinVerWIN7, 1); + } + + AUKN_SYM bool IsWindows8OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWIN8, kWinVerWIN8, 0); + } + + AUKN_SYM bool IsWindows8Point1OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWINBLUE, kWinVerWINBLUE, 0); + } + + AUKN_SYM bool IsWindows10OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWIN10, kWinVerWIN10, 0); + } + + AUKN_SYM bool IsWindows11OrGreater() + { + return IsWindowsVersionOrGreater(kWinVerWIN10, kWinVerWIN10, 0) && gInfo->uKernelPatch >= 22000; + } } \ No newline at end of file diff --git a/readme.md b/readme.md index 400c5dfd..5df28b79 100644 --- a/readme.md +++ b/readme.md @@ -4,12 +4,14 @@ The Aurora Runtime is an platform abstraction layer for cross-platform C++ development targeting
embedded and PC systems. Simply fetch a binary package for your toolchain or integrate the build
-scripts into your applications build pipeline to get started. +scripts into your applications build pipeline to get started.
+ +View this raw file for improved formatting ## Features - Lightweight threading and synchronization primitives -- Async threading primitives, including WaitMultipleObjects paradigm [WIP] +- Async threading primitives, including WaitMultipleObjects paradigm - Asynchronous and synchronous IO abstraction - Optional event driven async programming paradigm - Console; graphical and standard; binary and UTF-8 logger @@ -32,7 +34,7 @@ Doxygen:
Examples:
Tests:
Cmake-stable:
-Build Pipeline: +Build Pipeline: https://git.reece.sx/AuroraPipeline/Build ## Utilities @@ -43,16 +45,35 @@ Aurora Overloadable Type Declerations: https://git.reece.sx/AuroraSupport/Aurora ## Logging -Aurora Runtime does not attempt to implement your favourite production logger. We instead -implement a subscription based log message dispatcher with some default backends including -a file logger, Windows debug logging, Windows conhost stdin/out using UTF-8, UNIX stdin/out -respecting the applications codepage, a wxWidgets toolkit GUI, and hopefully more to come. -Additionally, consoles that provide an input stream can be used in conjunction with the parse -subsystem to provide basic command-based deserialization, tokenization, and dispatch of UTF-8 +~~Aurora Runtime does not attempt to implement your favourite production logger. We instead
+implement a subscription based log message dispatcher with some default backends including
+a file logger, Windows debug logging, Windows conhost stdin/out using UTF-8, UNIX stdin/out
+respecting the applications codepage, a wxWidgets toolkit GUI, and hopefully more to come. ~~
+ + +Additionally, consoles that provide an input stream can be used in conjunction with the parse
+subsystem to provide basic command-based deserialization, tokenization, and dispatch of UTF-8
translated strings regardless of the system locale +## Exceptions -## Loop [WIP] +Through the use of compiler internal overloads, ELF hooking, and Win32 `AddVectoredExceptionHandler`, Aurora
+Runtime hooks exceptions at the time of throw, including *some* out of ecosystem exceptions, providing detailed
+telemetry of the object type, object string, and backtrace. In addition, the `AuDebug` namespace provides TLS based
+last-error and last-backtrace methods.
+ +EXCEPTIONS ARE NOT CONTROL FLOW...
+- Aurora Runtime WILL attempt to mitigate exceptions in internal logic +- Aurora Runtime WILL NOT abuse exceptions to communicate failure +- Aurora Runtime WILL try to decouple internal exceptions from the API +- Aurora Runtime WILL NOT use anything that automatically crashes on exception catch (no-nothrow) +- Aurora Runtime WILL provide extended exception information to telemetry backends and through the `AuDebug` namespace +- Aurora Runtime WILL NOT make any guarantees of being globally-nothrow; however, it should be a safe assumption in non-critical environments + +`SysPanic` can be used to format a `std::terminate`-like exit condition, complete with telemetry data and safe cleanup. + + +## Loop Aurora Runtime offers a main loop that connects multiple input sources into one delegate.
Timers, semaphores, mutexes, events, X11, FDs, Win32 msg loop, macos, IPC, file aio handles, and
@@ -117,9 +138,6 @@ represents a binary blob of UTF-8. Looking to switch to `tiny-utf8` for UTF-8 sa ## Memory -User-overloadable type declerations and generic access utilities are defined under [utilities](#utilities)
-Aurora provides a bring your own container and shared pointer model overloadable in your configuration header. - ``` Types: AuSPtr @@ -135,9 +153,45 @@ Macros: AuFunction<...> AuBindThis(This_t *::?, ...) ``` -Most Aurora Runtime APIs provide generic new and release functions should you not need the overhead of reference counting or unique ptrs
-However, strict C codebases would need to shim to C, perhaps using AuUnsafeRaiiToShared to convert T\*s to unsafe `AuSPtr`s, the namespaced C++ functions
+By default, AuSPtr is backed by `std::shared_ptr`, extended by `#include `
+Using this class, undefined behaviour on dereference and operator pointer is altered to guarantee an AU_THROW_STRING
+It would be 'nice' to live in a world without C++ exceptions; however, nothrow and attempts to mitigate them and their
+basis tend to result in `std::terminate` being called sooner or later. Defer to [exceptions](#exceptions) on how we log
+and treat them. Those who live in nothrow land can eat the exception, turning it into a terminate condition. Smarter
+applications may be able to catch the null dereference and continue operation without brining the whole kingdom down with it. + +### Note +Aurora provides a bring your own container and shared pointer model overloadable in your configuration header.
+User-overloadable type declerations and generic access utilities are defined under [utilities](#utilities)
+ + +## Binding + +Aurora Runtime provides C++ APIs; however, it should be noted that two libraries are used to extend interfaces and enums
+to help with porting and internal utility access. One, AuroraEnums, wraps basic enumerations and provides value vectors;
+value strings; look up; iteration; and more. The other, AuroraInterfaces, provides *TWO* class types for each virtual interface.
+Each interface can be backed by a; C++ class method overriding a superclass's `virtual ...(...) = 0;` method, or a `AuFunctional`
+-based structure.
+ It should be noted that most language bindings and generator libraries (^swig, v8pp, nbind, luabind) work with shared pointers.
+Other user code may wish to stuff pointers into a machineword-sized space, whether its a C library, a FFI, or a size constraint.
+One handle or abstraction layer will be required to integrate the C++ API into the destination platform, and assuming we have a
+C++ language frontend parsing our API, we can use `AuSPtr` for all caller-to-method constant reference scanerios.
+Furthermore, `AuSPtrs` can be created, without a deletor, using `AuUnsafeRaiiToShared(unique/raw pointer)`. To solve the raw
+pointer issue, `AuSPtrs` are created in the public headers with the help of exported/default visibility interface create and
+destroy functions. These APIs provide raw pointers to public C++ interfaces, and as such, can be binded using virtually any
+shim generator. Method and API mapping will likely involve manual work from the library developer to reimplement AU concepts
+under their language runtime instead of using the C++ platform, or at least require manual effort to shim or map each runtime
+prototype into something more sane across the language barrier.
+ +Memory is generally viewed through a `std::span` like concept called MemoryViews. `MemoryViewRead` and `MemoryViewWrite`
+provide windows into a defined address range. `MemoryViewStreamRead` and `MemoryViewStreamWrite` expand upon this concept by
+accepting an additional offset (`AuUInt &: reference`) that is used by internal APIs to indicate how many bytes were written or
+read from a given input region. Such requirement came about from so many APIs, networking, compression, encoding, doing the exact
+same thing in different not-so-portable ways. Unifying memory access to 4 class types should aid with SWIG prototyping. + +Unrelated note, structure interfacing with questionable C++ ABI reimplementations is somewhat sketchy in FFI projects (^ CppSharp)
+can lead to some memory leaks.
## IO @@ -157,7 +211,7 @@ The networking stack supports a handful of architectural paradigms
- read with an all-or-nothing flag and an async flag
- read with an asynchronous stream callback - peaking
-- async read/write pump whenever or all +- async read/write pump whenever and/or all ## FIO @@ -177,7 +231,11 @@ Path tokens include:
[0] == '?' = ., !, or ~
.. = go back
/ = splitter
-\ = splitter +\ = splitter
+ +
+[TODO] Aurora Branding
+[TODO] Aurora IO Resources
## Aurora Async @@ -201,24 +259,35 @@ system configuration, the unix locale env variable, and/or the provided overload ## Philosophies - Assume C++17 language support in the language driver -- Solve the large issues nobody is tackling. To avoid reinventing the wheel accept third party
- solutions when the pros (developer time) weighted against the negatives (legal, bulk) makes - sense. + - Use AuXXX type bindings for std types, allow customers to overload the std namespace + We assume *some* containers and utility APIs exist, but where they come from is up to you + - Keep the code and build chain simple such that any C++ developer could maintain their own software stack built around aurora components. -- Dependencies should be cross-platform friendly + +- Dependencies and concepts should be cross-platform, cross-architecture, cross-ring friendly + It is recommended to fork and replace any legacy OS specific code with equivalent - AuroraRuntime concepts + AuroraRuntime concepts, introducing a circular dependency with the Aurora Runtime + + APIs shouldn't be designed around userland, mobile computing, or desktop computing; + AuroraRuntime must provide a common backbone for all applications. + + Locale and user-info APIs will be limited due to the assumption userland is not a + concept + - Dependencies, excluding core reference algorithms (eg compression), must be rewritten and phased out over time. + - Dependencies should not be added if most platforms provide some degree of native support
Examples:
-> Don't depend on a pthread shim for windows; implement the best thread
primitives that lie on the best possible api for them
- Don't depend on ICU when POSIX's iconv and Win32's multibyte apis cover
+ -> Don't depend on ICU when POSIX's iconv and Win32's multibyte apis cover
everything a conservative developer cares about; chinese, utf-16, utf-8,
utf-32 conversion, on top of all the ancient windows codepages + - Dependencies should only be added conservatively when it saves development time and provides production hardening
Examples: