#pragma once typedef LONG NTSTATUS; typedef NTSTATUS(NTAPI *NtCreateThreadEx_t)(PHANDLE hThread, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, DWORD StackZeroBits, DWORD SizeOfStackCommit, DWORD SizeOfStackReserve, LPVOID lpBytesBuffer); typedef NTSTATUS(NTAPI* NtQueryInformationThread_t)(HANDLE ThreadHandle, LONG ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); #define ThreadQuerySetWin32StartAddress 9 namespace Utils { std::string GetMimeType(const std::string& url); std::string ParseChallenge(const std::string& data); void OutputDebugLastError(); std::string GetLastWindowsError(); bool IsWineEnvironment(); unsigned long GetParentProcessId(); size_t GetModuleSize(HMODULE); void* GetThreadStartAddress(HANDLE hThread); HMODULE GetNTDLL(); void SetEnvironment(); void OpenUrl(const std::string& url); bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2); float Vec3SqrDistance(const float v1[3], const float v2[3]); template inline void RotLeft(T& object, size_t bits) { bits %= sizeof(T) * 8; T sign = 1; sign = sign << (sizeof(T) * 8 - 1); bool negative = (object & sign) != 0; object &= ~sign; object = (object << bits) | (object >> (sizeof(T) * 8 - bits)); object |= T(negative) << ((sizeof(T) * 8 - 1 + bits) % (sizeof(T) * 8)); } template inline void RotRight(T& object, size_t bits) { bits %= (sizeof(T) * 8); RotLeft(object, ((sizeof(T) * 8) - bits)); } template inline void Merge(std::vector* target, T* source, size_t length) { if (source) { for (size_t i = 0; i < length; ++i) { target->push_back(source[i]); } } } template inline void Merge(std::vector* target, std::vector source) { for (auto &entry : source) { target->push_back(entry); } } template using Slot = std::function; template class Signal { public: Signal() { std::lock_guard _(this->mutex); this->slots.clear(); } Signal(Signal& obj) : Signal() { std::lock_guard _(this->mutex); std::lock_guard __(obj.mutex); Utils::Merge(&this->slots, obj.getSlots()); } void connect(Slot slot) { std::lock_guard _(this->mutex); if (slot) { this->slots.push_back(slot); } } void clear() { std::lock_guard _(this->mutex); this->slots.clear(); } std::vector>& getSlots() { return this->slots; } template void operator()(Args&&... args) const { std::lock_guard _(this->mutex); std::vector> copiedSlots; Utils::Merge(&copiedSlots, this->slots); for (auto& slot : copiedSlots) { if (slot) { slot(std::forward(args)...); } } } private: mutable std::recursive_mutex mutex; std::vector> slots; }; template constexpr auto VectorCopy(T a, T b) { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; } }