Format all the code

This commit is contained in:
momo5502
2025-01-06 17:13:33 +01:00
parent 64c2a79f0f
commit bff8420ffd
100 changed files with 16439 additions and 14509 deletions

View File

@@ -8,376 +8,365 @@ using namespace std::literals;
namespace network
{
void initialize_wsa()
{
void initialize_wsa()
{
#ifdef _WIN32
static struct wsa_initializer
{
public:
wsa_initializer()
{
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
throw std::runtime_error("Unable to initialize WSA");
}
}
static struct wsa_initializer
{
wsa_initializer()
{
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
throw std::runtime_error("Unable to initialize WSA");
}
}
~wsa_initializer()
{
WSACleanup();
}
} _;
~wsa_initializer()
{
WSACleanup();
}
} _;
#endif
}
}
address::address()
{
initialize_wsa();
ZeroMemory(&this->storage_, this->get_max_size());
address::address()
{
initialize_wsa();
ZeroMemory(&this->storage_, this->get_max_size());
this->address_.sa_family = AF_UNSPEC;
}
this->address_.sa_family = AF_UNSPEC;
}
address::address(const std::string& addr, const std::optional<int>& family)
: address()
{
this->parse(addr, family);
}
address::address(const std::string& addr, const std::optional<int>& family)
: address()
{
this->parse(addr, family);
}
address::address(const sockaddr_in6& addr)
: address()
{
this->address6_ = addr;
}
address::address(const sockaddr_in6& addr)
: address()
{
this->address6_ = addr;
}
address::address(const sockaddr_in& addr)
: address()
{
this->address4_ = addr;
}
address::address(const sockaddr_in& addr)
: address()
{
this->address4_ = addr;
}
address::address(const sockaddr* addr, const socklen_t length)
: address()
{
this->set_address(addr, length);
}
address::address(const sockaddr* addr, const socklen_t length)
: address()
{
this->set_address(addr, length);
}
void address::set_ipv4(const uint32_t ip)
{
in_addr addr{};
addr.s_addr = ip;
this->set_ipv4(addr);
}
void address::set_ipv4(const uint32_t ip)
{
in_addr addr{};
addr.s_addr = ip;
this->set_ipv4(addr);
}
bool address::operator==(const address& obj) const
{
if (this->address_.sa_family != obj.address_.sa_family)
{
return false;
}
bool address::operator==(const address& obj) const
{
if (this->address_.sa_family != obj.address_.sa_family)
{
return false;
}
if (this->get_port() != obj.get_port())
{
return false;
}
if (this->get_port() != obj.get_port())
{
return false;
}
if (this->address_.sa_family == AF_INET)
{
return this->address4_.sin_addr.s_addr == obj.address4_.sin_addr.s_addr;
}
else if (this->address_.sa_family == AF_INET6)
{
return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr,
sizeof(obj.address6_.sin6_addr.s6_addr));
}
if (this->address_.sa_family == AF_INET)
{
return this->address4_.sin_addr.s_addr == obj.address4_.sin_addr.s_addr;
}
else if (this->address_.sa_family == AF_INET6)
{
return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr,
sizeof(obj.address6_.sin6_addr.s6_addr));
}
return false;
}
return false;
}
void address::set_ipv4(const in_addr& addr)
{
ZeroMemory(&this->address4_, sizeof(this->address4_));
this->address4_.sin_family = AF_INET;
this->address4_.sin_addr = addr;
}
void address::set_ipv4(const in_addr& addr)
{
ZeroMemory(&this->address4_, sizeof(this->address4_));
this->address4_.sin_family = AF_INET;
this->address4_.sin_addr = addr;
}
void address::set_ipv6(const in6_addr& addr)
{
ZeroMemory(&this->address6_, sizeof(this->address6_));
this->address6_.sin6_family = AF_INET6;
this->address6_.sin6_addr = addr;
}
void address::set_ipv6(const in6_addr& addr)
{
ZeroMemory(&this->address6_, sizeof(this->address6_));
this->address6_.sin6_family = AF_INET6;
this->address6_.sin6_addr = addr;
}
void address::set_address(const sockaddr* addr, const socklen_t length)
{
if (static_cast<size_t>(length) >= sizeof(sockaddr_in) && addr->sa_family == AF_INET)
{
this->address4_ = *reinterpret_cast<const sockaddr_in*>(addr);
}
else if (static_cast<size_t>(length) == sizeof(sockaddr_in6) && addr->sa_family == AF_INET6)
{
this->address6_ = *reinterpret_cast<const sockaddr_in6*>(addr);
}
else
{
throw std::runtime_error("Invalid network address");
}
}
void address::set_address(const sockaddr* addr, const socklen_t length)
{
if (static_cast<size_t>(length) >= sizeof(sockaddr_in) && addr->sa_family == AF_INET)
{
this->address4_ = *reinterpret_cast<const sockaddr_in*>(addr);
}
else if (static_cast<size_t>(length) == sizeof(sockaddr_in6) && addr->sa_family == AF_INET6)
{
this->address6_ = *reinterpret_cast<const sockaddr_in6*>(addr);
}
else
{
throw std::runtime_error("Invalid network address");
}
}
void address::set_port(const unsigned short port)
{
switch (this->address_.sa_family)
{
case AF_INET:
this->address4_.sin_port = htons(port);
break;
case AF_INET6:
this->address6_.sin6_port = htons(port);
break;
default:
throw std::runtime_error("Invalid address family");
}
}
void address::set_port(const unsigned short port)
{
switch (this->address_.sa_family)
{
case AF_INET:
this->address4_.sin_port = htons(port);
break;
case AF_INET6:
this->address6_.sin6_port = htons(port);
break;
default:
throw std::runtime_error("Invalid address family");
}
}
unsigned short address::get_port() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return ntohs(this->address4_.sin_port);
case AF_INET6:
return ntohs(this->address6_.sin6_port);
default:
return 0;
}
}
unsigned short address::get_port() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return ntohs(this->address4_.sin_port);
case AF_INET6:
return ntohs(this->address6_.sin6_port);
default:
return 0;
}
}
std::string address::to_string() const
{
char buffer[1000] = {0};
std::string addr;
std::string address::to_string() const
{
char buffer[1000] = {0};
std::string addr;
switch (this->address_.sa_family)
{
case AF_INET:
inet_ntop(this->address_.sa_family, &this->address4_.sin_addr, buffer, sizeof(buffer));
addr = std::string(buffer);
break;
case AF_INET6:
inet_ntop(this->address_.sa_family, &this->address6_.sin6_addr, buffer, sizeof(buffer));
addr = "[" + std::string(buffer) + "]";
break;
default:
buffer[0] = '?';
buffer[1] = 0;
addr = std::string(buffer);
break;
}
switch (this->address_.sa_family)
{
case AF_INET:
inet_ntop(this->address_.sa_family, &this->address4_.sin_addr, buffer, sizeof(buffer));
addr = std::string(buffer);
break;
case AF_INET6:
inet_ntop(this->address_.sa_family, &this->address6_.sin6_addr, buffer, sizeof(buffer));
addr = "[" + std::string(buffer) + "]";
break;
default:
buffer[0] = '?';
buffer[1] = 0;
addr = std::string(buffer);
break;
}
return addr + ":"s + std::to_string(this->get_port());
}
return addr + ":"s + std::to_string(this->get_port());
}
bool address::is_local() const
{
if (this->address_.sa_family != AF_INET)
{
return false;
}
bool address::is_local() const
{
if (this->address_.sa_family != AF_INET)
{
return false;
}
// According to: https://en.wikipedia.org/wiki/Private_network
// According to: https://en.wikipedia.org/wiki/Private_network
uint8_t bytes[4];
*reinterpret_cast<uint32_t*>(&bytes) = this->address4_.sin_addr.s_addr;
uint8_t bytes[4];
*reinterpret_cast<uint32_t*>(&bytes) = this->address4_.sin_addr.s_addr;
// 10.X.X.X
if (bytes[0] == 10)
{
return true;
}
// 10.X.X.X
if (bytes[0] == 10)
{
return true;
}
// 192.168.X.X
if (bytes[0] == 192
&& bytes[1] == 168)
{
return true;
}
// 192.168.X.X
if (bytes[0] == 192 && bytes[1] == 168)
{
return true;
}
// 172.16.X.X - 172.31.X.X
if (bytes[0] == 172
&& bytes[1] >= 16
&& bytes[1] < 32)
{
return true;
}
// 172.16.X.X - 172.31.X.X
if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] < 32)
{
return true;
}
// 127.0.0.1
if (this->address4_.sin_addr.s_addr == 0x0100007F)
{
return true;
}
// 127.0.0.1
if (this->address4_.sin_addr.s_addr == 0x0100007F)
{
return true;
}
return false;
}
return false;
}
sockaddr& address::get_addr()
{
return this->address_;
}
sockaddr& address::get_addr()
{
return this->address_;
}
const sockaddr& address::get_addr() const
{
return this->address_;
}
const sockaddr& address::get_addr() const
{
return this->address_;
}
sockaddr_in& address::get_in_addr()
{
return this->address4_;
}
sockaddr_in& address::get_in_addr()
{
return this->address4_;
}
sockaddr_in6& address::get_in6_addr()
{
return this->address6_;
}
sockaddr_in6& address::get_in6_addr()
{
return this->address6_;
}
const sockaddr_in& address::get_in_addr() const
{
return this->address4_;
}
const sockaddr_in& address::get_in_addr() const
{
return this->address4_;
}
const sockaddr_in6& address::get_in6_addr() const
{
return this->address6_;
}
const sockaddr_in6& address::get_in6_addr() const
{
return this->address6_;
}
socklen_t address::get_size() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return static_cast<socklen_t>(sizeof(this->address4_));
case AF_INET6:
return static_cast<socklen_t>(sizeof(this->address6_));
default:
return static_cast<socklen_t>(sizeof(this->address_));
}
}
socklen_t address::get_size() const
{
switch (this->address_.sa_family)
{
case AF_INET:
return static_cast<socklen_t>(sizeof(this->address4_));
case AF_INET6:
return static_cast<socklen_t>(sizeof(this->address6_));
default:
return static_cast<socklen_t>(sizeof(this->address_));
}
}
socklen_t address::get_max_size() const
{
constexpr auto s = sizeof(this->address_);
constexpr auto s4 = sizeof(this->address4_);
constexpr auto s6 = sizeof(this->address6_);
constexpr auto sstore = sizeof(this->storage_);
constexpr auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
static_assert(max_size == sstore);
socklen_t address::get_max_size() const
{
constexpr auto s = sizeof(this->address_);
constexpr auto s4 = sizeof(this->address4_);
constexpr auto s6 = sizeof(this->address6_);
constexpr auto sstore = sizeof(this->storage_);
constexpr auto max_size = std::max(sstore, std::max(s, std::max(s4, s6)));
static_assert(max_size == sstore);
return static_cast<socklen_t>(max_size);
}
return static_cast<socklen_t>(max_size);
}
bool address::is_ipv4() const
{
return this->address_.sa_family == AF_INET;
}
bool address::is_ipv4() const
{
return this->address_.sa_family == AF_INET;
}
bool address::is_ipv6() const
{
return this->address_.sa_family == AF_INET6;
}
bool address::is_ipv6() const
{
return this->address_.sa_family == AF_INET6;
}
bool address::is_supported() const
{
return is_ipv4() || is_ipv6();
}
bool address::is_supported() const
{
return is_ipv4() || is_ipv6();
}
void address::parse(std::string addr, const std::optional<int>& family)
{
std::optional<uint16_t> port_value{};
void address::parse(std::string addr, const std::optional<int>& family)
{
std::optional<uint16_t> port_value{};
const auto pos = addr.find_last_of(':');
if (pos != std::string::npos)
{
auto port = addr.substr(pos + 1);
port_value = uint16_t(atoi(port.data()));
addr = addr.substr(0, pos);
}
const auto pos = addr.find_last_of(':');
if (pos != std::string::npos)
{
auto port = addr.substr(pos + 1);
port_value = uint16_t(atoi(port.data()));
addr = addr.substr(0, pos);
}
this->resolve(addr, family);
this->resolve(addr, family);
if (port_value)
{
this->set_port(*port_value);
}
}
if (port_value)
{
this->set_port(*port_value);
}
}
void address::resolve(const std::string& hostname, const std::optional<int>& family)
{
const auto port = this->get_port();
auto port_reset_action = utils::finally([this, port]()
{
this->set_port(port);
});
void address::resolve(const std::string& hostname, const std::optional<int>& family)
{
const auto port = this->get_port();
auto port_reset_action = utils::finally([this, port]() { this->set_port(port); });
const auto result = resolve_multiple(hostname);
for (const auto& addr : result)
{
if (addr.is_supported() && (!family || addr.get_addr().sa_family == *family))
{
this->set_address(&addr.get_addr(), addr.get_size());
return;
}
}
const auto result = resolve_multiple(hostname);
for (const auto& addr : result)
{
if (addr.is_supported() && (!family || addr.get_addr().sa_family == *family))
{
this->set_address(&addr.get_addr(), addr.get_size());
return;
}
}
port_reset_action.cancel();
throw std::runtime_error{"Unable to resolve hostname: " + hostname};
}
port_reset_action.cancel();
throw std::runtime_error{"Unable to resolve hostname: " + hostname};
}
std::vector<address> address::resolve_multiple(const std::string& hostname)
{
std::vector<address> results{};
std::vector<address> address::resolve_multiple(const std::string& hostname)
{
std::vector<address> results{};
addrinfo* result = nullptr;
if (!getaddrinfo(hostname.data(), nullptr, nullptr, &result))
{
const auto _2 = utils::finally([&result]
{
freeaddrinfo(result);
});
addrinfo* result = nullptr;
if (!getaddrinfo(hostname.data(), nullptr, nullptr, &result))
{
const auto _2 = utils::finally([&result] { freeaddrinfo(result); });
for (auto* i = result; i; i = i->ai_next)
{
if (i->ai_family == AF_INET || i->ai_family == AF_INET6)
{
address a{};
a.set_address(i->ai_addr, static_cast<socklen_t>(i->ai_addrlen));
results.emplace_back(std::move(a));
}
}
}
for (auto* i = result; i; i = i->ai_next)
{
if (i->ai_family == AF_INET || i->ai_family == AF_INET6)
{
address a{};
a.set_address(i->ai_addr, static_cast<socklen_t>(i->ai_addrlen));
results.emplace_back(std::move(a));
}
}
}
return results;
}
return results;
}
}
std::size_t std::hash<network::address>::operator()(const network::address& a) const noexcept
{
const uint32_t family = a.get_addr().sa_family;
const uint32_t port = a.get_port();
const uint32_t family = a.get_addr().sa_family;
const uint32_t port = a.get_port();
std::size_t hash = std::hash<uint32_t>{}(family);
hash ^= std::hash<uint32_t>{}(port);
switch (a.get_addr().sa_family)
{
case AF_INET:
hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr);
break;
case AF_INET6:
hash ^= std::hash<std::string_view>{}(std::string_view{
reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr),
sizeof(a.get_in6_addr().sin6_addr.s6_addr)
});
break;
}
std::size_t hash = std::hash<uint32_t>{}(family);
hash ^= std::hash<uint32_t>{}(port);
switch (a.get_addr().sa_family)
{
case AF_INET:
hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr);
break;
case AF_INET6:
hash ^= std::hash<std::string_view>{}(
std::string_view{reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr),
sizeof(a.get_in6_addr().sin6_addr.s6_addr)});
break;
}
return hash;
return hash;
}

View File

@@ -36,71 +36,71 @@ using socklen_t = int;
namespace network
{
void initialize_wsa();
void initialize_wsa();
class address
{
public:
address();
address(const std::string& addr, const std::optional<int>& family = {});
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, socklen_t length);
class address
{
public:
address();
address(const std::string& addr, const std::optional<int>& family = {});
address(const sockaddr_in& addr);
address(const sockaddr_in6& addr);
address(const sockaddr* addr, socklen_t length);
void set_ipv4(uint32_t ip);
void set_ipv4(const in_addr& addr);
void set_ipv6(const in6_addr& addr);
void set_address(const sockaddr* addr, socklen_t length);
void set_ipv4(uint32_t ip);
void set_ipv4(const in_addr& addr);
void set_ipv6(const in6_addr& addr);
void set_address(const sockaddr* addr, socklen_t length);
void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const;
void set_port(unsigned short port);
[[nodiscard]] unsigned short get_port() const;
sockaddr& get_addr();
sockaddr_in& get_in_addr();
sockaddr_in6& get_in6_addr();
sockaddr& get_addr();
sockaddr_in& get_in_addr();
sockaddr_in6& get_in6_addr();
const sockaddr& get_addr() const;
const sockaddr_in& get_in_addr() const;
const sockaddr_in6& get_in6_addr() const;
const sockaddr& get_addr() const;
const sockaddr_in& get_in_addr() const;
const sockaddr_in6& get_in6_addr() const;
socklen_t get_size() const;
socklen_t get_max_size() const;
socklen_t get_size() const;
socklen_t get_max_size() const;
bool is_ipv4() const;
bool is_ipv6() const;
bool is_supported() const;
bool is_ipv4() const;
bool is_ipv6() const;
bool is_supported() const;
[[nodiscard]] bool is_local() const;
[[nodiscard]] std::string to_string() const;
[[nodiscard]] bool is_local() const;
[[nodiscard]] std::string to_string() const;
bool operator==(const address& obj) const;
bool operator==(const address& obj) const;
bool operator!=(const address& obj) const
{
return !(*this == obj);
}
bool operator!=(const address& obj) const
{
return !(*this == obj);
}
static std::vector<address> resolve_multiple(const std::string& hostname);
static std::vector<address> resolve_multiple(const std::string& hostname);
private:
union
{
sockaddr address_;
sockaddr_in address4_;
sockaddr_in6 address6_;
sockaddr_storage storage_;
};
private:
union
{
sockaddr address_;
sockaddr_in address4_;
sockaddr_in6 address6_;
sockaddr_storage storage_;
};
void parse(std::string addr, const std::optional<int>& family = {});
void resolve(const std::string& hostname, const std::optional<int>& family = {});
};
void parse(std::string addr, const std::optional<int>& family = {});
void resolve(const std::string& hostname, const std::optional<int>& family = {});
};
}
namespace std
{
template <>
struct hash<network::address>
{
std::size_t operator()(const network::address& a) const noexcept;
};
template <>
struct hash<network::address>
{
std::size_t operator()(const network::address& a) const noexcept;
};
}

View File

@@ -6,226 +6,225 @@ using namespace std::literals;
namespace network
{
socket::socket(const int af)
: address_family_(af)
{
initialize_wsa();
this->socket_ = ::socket(af, SOCK_DGRAM, IPPROTO_UDP);
socket::socket(const int af)
: address_family_(af)
{
initialize_wsa();
this->socket_ = ::socket(af, SOCK_DGRAM, IPPROTO_UDP);
if (af == AF_INET6)
{
int i = 1;
setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i),
static_cast<int>(sizeof(i)));
}
}
if (af == AF_INET6)
{
int i = 1;
setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i),
static_cast<int>(sizeof(i)));
}
}
socket::~socket()
{
this->release();
}
socket::~socket()
{
this->release();
}
socket::socket(socket&& obj) noexcept
{
this->operator=(std::move(obj));
}
socket::socket(socket&& obj) noexcept
{
this->operator=(std::move(obj));
}
socket& socket::operator=(socket&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->socket_ = obj.socket_;
this->port_ = obj.port_;
this->address_family_ = obj.address_family_;
socket& socket::operator=(socket&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->socket_ = obj.socket_;
this->port_ = obj.port_;
this->address_family_ = obj.address_family_;
obj.socket_ = INVALID_SOCKET;
obj.address_family_ = AF_UNSPEC;
}
obj.socket_ = INVALID_SOCKET;
obj.address_family_ = AF_UNSPEC;
}
return *this;
}
return *this;
}
void socket::release()
{
if (this->socket_ != INVALID_SOCKET)
{
closesocket(this->socket_);
this->socket_ = INVALID_SOCKET;
}
}
void socket::release()
{
if (this->socket_ != INVALID_SOCKET)
{
closesocket(this->socket_);
this->socket_ = INVALID_SOCKET;
}
}
bool socket::bind_port(const address& target)
{
const auto result = bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
if (result)
{
this->port_ = target.get_port();
}
bool socket::bind_port(const address& target)
{
const auto result = bind(this->socket_, &target.get_addr(), target.get_size()) == 0;
if (result)
{
this->port_ = target.get_port();
}
return result;
}
return result;
}
bool socket::send(const address& target, const void* data, const size_t size) const
{
const auto res = sendto(this->socket_, static_cast<const char*>(data), static_cast<send_size>(size), 0,
&target.get_addr(),
target.get_size());
return static_cast<size_t>(res) == size;
}
bool socket::send(const address& target, const void* data, const size_t size) const
{
const auto res = sendto(this->socket_, static_cast<const char*>(data), static_cast<send_size>(size), 0,
&target.get_addr(), target.get_size());
return static_cast<size_t>(res) == size;
}
bool socket::send(const address& target, const std::string& data) const
{
return this->send(target, data.data(), data.size());
}
bool socket::send(const address& target, const std::string& data) const
{
return this->send(target, data.data(), data.size());
}
bool socket::receive(address& source, std::string& data) const
{
char buffer[0x2000];
auto len = source.get_max_size();
bool socket::receive(address& source, std::string& data) const
{
char buffer[0x2000];
auto len = source.get_max_size();
const auto result = recvfrom(this->socket_, buffer, static_cast<int>(sizeof(buffer)), 0, &source.get_addr(),
&len);
if (result == SOCKET_ERROR)
{
return false;
}
const auto result =
recvfrom(this->socket_, buffer, static_cast<int>(sizeof(buffer)), 0, &source.get_addr(), &len);
if (result == SOCKET_ERROR)
{
return false;
}
data.assign(buffer, buffer + result);
return true;
}
data.assign(buffer, buffer + result);
return true;
}
bool socket::set_blocking(const bool blocking)
{
return socket::set_blocking(this->socket_, blocking);
}
bool socket::set_blocking(const bool blocking)
{
return socket::set_blocking(this->socket_, blocking);
}
bool socket::set_blocking(SOCKET s, const bool blocking)
{
bool socket::set_blocking(SOCKET s, const bool blocking)
{
#ifdef _WIN32
unsigned long mode = blocking ? 0 : 1;
return ioctlsocket(s, FIONBIO, &mode) == 0;
unsigned long mode = blocking ? 0 : 1;
return ioctlsocket(s, FIONBIO, &mode) == 0;
#else
int flags = fcntl(s, F_GETFL, 0);
if (flags == -1) return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return fcntl(s, F_SETFL, flags) == 0;
int flags = fcntl(s, F_GETFL, 0);
if (flags == -1)
return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return fcntl(s, F_SETFL, flags) == 0;
#endif
}
}
bool socket::sleep(const std::chrono::milliseconds timeout) const
{
/*fd_set fdr;
FD_ZERO(&fdr);
FD_SET(this->socket_, &fdr);
bool socket::sleep(const std::chrono::milliseconds timeout) const
{
/*fd_set fdr;
FD_ZERO(&fdr);
FD_SET(this->socket_, &fdr);
const auto msec = timeout.count();
const auto msec = timeout.count();
timeval tv{};
tv.tv_sec = static_cast<long>(msec / 1000ll);
tv.tv_usec = static_cast<long>((msec % 1000) * 1000);
timeval tv{};
tv.tv_sec = static_cast<long>(msec / 1000ll);
tv.tv_usec = static_cast<long>((msec % 1000) * 1000);
const auto retval = select(static_cast<int>(this->socket_) + 1, &fdr, nullptr, nullptr, &tv);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
const auto retval = select(static_cast<int>(this->socket_) + 1, &fdr, nullptr, nullptr, &tv);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;*/
return !socket_is_ready;*/
std::vector<const socket*> sockets{};
sockets.push_back(this);
std::vector<const socket*> sockets{};
sockets.push_back(this);
return sleep_sockets(sockets, timeout);
}
return sleep_sockets(sockets, timeout);
}
bool socket::sleep_until(const std::chrono::high_resolution_clock::time_point time_point) const
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return this->sleep(std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
bool socket::sleep_until(const std::chrono::high_resolution_clock::time_point time_point) const
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return this->sleep(std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
SOCKET socket::get_socket() const
{
return this->socket_;
}
SOCKET socket::get_socket() const
{
return this->socket_;
}
uint16_t socket::get_port() const
{
return this->port_;
}
uint16_t socket::get_port() const
{
return this->port_;
}
int socket::get_address_family() const
{
return this->address_family_;
}
int socket::get_address_family() const
{
return this->address_family_;
}
bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout)
{
std::vector<pollfd> pfds{};
pfds.resize(sockets.size());
bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout)
{
std::vector<pollfd> pfds{};
pfds.resize(sockets.size());
for (size_t i = 0; i < sockets.size(); ++i)
{
auto& pfd = pfds.at(i);
const auto& socket = sockets[i];
for (size_t i = 0; i < sockets.size(); ++i)
{
auto& pfd = pfds.at(i);
const auto& socket = sockets[i];
pfd.fd = socket->get_socket();
pfd.events = POLLIN;
pfd.revents = 0;
}
pfd.fd = socket->get_socket();
pfd.events = POLLIN;
pfd.revents = 0;
}
const auto retval = poll(pfds.data(), static_cast<uint32_t>(pfds.size()),
static_cast<int>(timeout.count()));
const auto retval = poll(pfds.data(), static_cast<uint32_t>(pfds.size()), static_cast<int>(timeout.count()));
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;
}
return !socket_is_ready;
}
bool socket::is_socket_ready(const SOCKET s, const bool in_poll)
{
pollfd pfd{};
bool socket::is_socket_ready(const SOCKET s, const bool in_poll)
{
pollfd pfd{};
pfd.fd = s;
pfd.events = in_poll ? POLLIN : POLLOUT;
pfd.revents = 0;
pfd.fd = s;
pfd.events = in_poll ? POLLIN : POLLOUT;
pfd.revents = 0;
const auto retval = poll(&pfd, 1, 0);
const auto retval = poll(&pfd, 1, 0);
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval == SOCKET_ERROR)
{
std::this_thread::sleep_for(1ms);
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
if (retval > 0)
{
return socket_is_ready;
}
return !socket_is_ready;
}
return !socket_is_ready;
}
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
const std::chrono::high_resolution_clock::time_point time_point)
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
const std::chrono::high_resolution_clock::time_point time_point)
{
const auto duration = time_point - std::chrono::high_resolution_clock::now();
return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
}

View File

@@ -8,63 +8,63 @@
#ifdef _WIN32
using send_size = int;
#define GET_SOCKET_ERROR() (WSAGetLastError())
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#define poll WSAPoll
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
#else
using SOCKET = int;
using send_size = size_t;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define GET_SOCKET_ERROR() (errno)
#define closesocket close
#define SOCK_WOULDBLOCK EWOULDBLOCK
#define closesocket close
#define SOCK_WOULDBLOCK EWOULDBLOCK
#endif
namespace network
{
class socket
{
public:
socket() = default;
class socket
{
public:
socket() = default;
socket(int af);
~socket();
socket(int af);
~socket();
socket(const socket& obj) = delete;
socket& operator=(const socket& obj) = delete;
socket(const socket& obj) = delete;
socket& operator=(const socket& obj) = delete;
socket(socket&& obj) noexcept;
socket& operator=(socket&& obj) noexcept;
socket(socket&& obj) noexcept;
socket& operator=(socket&& obj) noexcept;
bool bind_port(const address& target);
bool bind_port(const address& target);
[[maybe_unused]] bool send(const address& target, const void* data, size_t size) const;
[[maybe_unused]] bool send(const address& target, const std::string& data) const;
bool receive(address& source, std::string& data) const;
[[maybe_unused]] bool send(const address& target, const void* data, size_t size) const;
[[maybe_unused]] bool send(const address& target, const std::string& data) const;
bool receive(address& source, std::string& data) const;
bool set_blocking(bool blocking);
static bool set_blocking(SOCKET s, bool blocking);
bool set_blocking(bool blocking);
static bool set_blocking(SOCKET s, bool blocking);
static constexpr bool socket_is_ready = true;
bool sleep(std::chrono::milliseconds timeout) const;
bool sleep_until(std::chrono::high_resolution_clock::time_point time_point) const;
static constexpr bool socket_is_ready = true;
bool sleep(std::chrono::milliseconds timeout) const;
bool sleep_until(std::chrono::high_resolution_clock::time_point time_point) const;
SOCKET get_socket() const;
uint16_t get_port() const;
SOCKET get_socket() const;
uint16_t get_port() const;
int get_address_family() const;
int get_address_family() const;
static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout);
static bool sleep_sockets_until(const std::span<const socket*>& sockets,
std::chrono::high_resolution_clock::time_point time_point);
static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout);
static bool sleep_sockets_until(const std::span<const socket*>& sockets,
std::chrono::high_resolution_clock::time_point time_point);
static bool is_socket_ready(SOCKET s, bool in_poll);
static bool is_socket_ready(SOCKET s, bool in_poll);
private:
int address_family_{AF_UNSPEC};
uint16_t port_ = 0;
SOCKET socket_ = INVALID_SOCKET;
private:
int address_family_{AF_UNSPEC};
uint16_t port_ = 0;
SOCKET socket_ = INVALID_SOCKET;
void release();
};
void release();
};
}

View File

@@ -3,7 +3,7 @@
#if defined(_WIN32) || defined(_WIN64)
#define OS_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define OS_MAC
#define OS_MAC
#elif defined(__linux__)
#define OS_LINUX
#else
@@ -11,9 +11,9 @@
#endif
#ifdef OS_WINDOWS
#define EXPORT_SYMBOL __declspec(dllexport)
#define IMPORT_SYMBOL __declspec(dllimport)
#define NO_INLINE __declspec(noinline)
#define EXPORT_SYMBOL __declspec(dllexport)
#define IMPORT_SYMBOL __declspec(dllimport)
#define NO_INLINE __declspec(noinline)
#define DECLSPEC_ALIGN(n) __declspec(align(n))
@@ -24,21 +24,21 @@
#define EXPORT_SYMBOL __attribute__((visibility("default")))
#define IMPORT_SYMBOL
#define NO_INLINE __attribute__((noinline))
#define NO_INLINE __attribute__((noinline))
#define DECLSPEC_ALIGN(n) alignas(n)
#define fopen_s fopen
#define DECLSPEC_ALIGN(n) alignas(n)
#define fopen_s fopen
#define RESTRICTED_POINTER __restrict
#ifdef OS_MAC
#define _fseeki64 fseeko
#define _ftelli64 ftello
#define _stat64 stat
#define _stat64 stat
#else
#define _fseeki64 fseeko64
#define _ftelli64 ftello64
#define _stat64 stat64
#define _stat64 stat64
#endif
#endif

View File

@@ -1,246 +1,250 @@
#pragma once
#define ACCESS_MASK DWORD
#define DEVICE_TYPE DWORD
#define ACCESS_MASK DWORD
#define DEVICE_TYPE DWORD
#define FILE_DEVICE_DISK 0x00000007
#define FILE_DEVICE_CONSOLE 0x00000050
#define FILE_DEVICE_DISK 0x00000007
#define FILE_DEVICE_CONSOLE 0x00000050
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#ifndef OS_WINDOWS
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_ALL 0x10000000
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_ALL 0x10000000
#undef DELETE
#define DELETE 0x00010000
#define READ_CONTROL 0x00020000
#define WRITE_DAC 0x00040000
#define WRITE_OWNER 0x00080000
#define SYNCHRONIZE 0x00100000
#define STANDARD_RIGHTS_REQUIRED 0x000f0000
#undef DELETE
#define DELETE 0x00010000
#define READ_CONTROL 0x00020000
#define WRITE_DAC 0x00040000
#define WRITE_OWNER 0x00080000
#define SYNCHRONIZE 0x00100000
#define STANDARD_RIGHTS_REQUIRED 0x000f0000
#define FILE_READ_DATA 0x0001 /* file & pipe */
#define FILE_LIST_DIRECTORY 0x0001 /* directory */
#define FILE_WRITE_DATA 0x0002 /* file & pipe */
#define FILE_ADD_FILE 0x0002 /* directory */
#define FILE_APPEND_DATA 0x0004 /* file */
#define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */
#define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */
#define FILE_READ_EA 0x0008 /* file & directory */
#define FILE_READ_DATA 0x0001 /* file & pipe */
#define FILE_LIST_DIRECTORY 0x0001 /* directory */
#define FILE_WRITE_DATA 0x0002 /* file & pipe */
#define FILE_ADD_FILE 0x0002 /* directory */
#define FILE_APPEND_DATA 0x0004 /* file */
#define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */
#define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */
#define FILE_READ_EA 0x0008 /* file & directory */
#define FILE_READ_PROPERTIES FILE_READ_EA
#define FILE_WRITE_EA 0x0010 /* file & directory */
#define FILE_WRITE_EA 0x0010 /* file & directory */
#define FILE_WRITE_PROPERTIES FILE_WRITE_EA
#define FILE_EXECUTE 0x0020 /* file */
#define FILE_TRAVERSE 0x0020 /* directory */
#define FILE_DELETE_CHILD 0x0040 /* directory */
#define FILE_READ_ATTRIBUTES 0x0080 /* all */
#define FILE_WRITE_ATTRIBUTES 0x0100 /* all */
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
#define FILE_EXECUTE 0x0020 /* file */
#define FILE_TRAVERSE 0x0020 /* directory */
#define FILE_DELETE_CHILD 0x0040 /* directory */
#define FILE_READ_ATTRIBUTES 0x0080 /* all */
#define FILE_WRITE_ATTRIBUTES 0x0100 /* all */
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1ff)
#endif
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff
#define PS_ATTRIBUTE_THREAD 0x00010000 // may be used with thread creation
#define PS_ATTRIBUTE_INPUT 0x00020000 // input only
#define PS_ATTRIBUTE_ADDITIVE 0x00040000 // "accumulated" e.g. bitmasks, counters, etc.
#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff
#define PS_ATTRIBUTE_THREAD 0x00010000 // may be used with thread creation
#define PS_ATTRIBUTE_INPUT 0x00020000 // input only
#define PS_ATTRIBUTE_ADDITIVE 0x00040000 // "accumulated" e.g. bitmasks, counters, etc.
#define SL_RESTART_SCAN 0x01
#define SL_RETURN_SINGLE_ENTRY 0x02
#define SL_NO_CURSOR_UPDATE 0x10
#define SL_RESTART_SCAN 0x01
#define SL_RETURN_SINGLE_ENTRY 0x02
#define SL_NO_CURSOR_UPDATE 0x10
#define SEC_IMAGE 0x01000000
#define SEC_IMAGE 0x01000000
typedef enum _FSINFOCLASS
{
FileFsVolumeInformation = 1, // q: FILE_FS_VOLUME_INFORMATION
FileFsLabelInformation, // s: FILE_FS_LABEL_INFORMATION (requires FILE_WRITE_DATA to volume)
FileFsSizeInformation, // q: FILE_FS_SIZE_INFORMATION
FileFsDeviceInformation, // q: FILE_FS_DEVICE_INFORMATION
FileFsAttributeInformation, // q: FILE_FS_ATTRIBUTE_INFORMATION
FileFsControlInformation,
// q, s: FILE_FS_CONTROL_INFORMATION (q: requires FILE_READ_DATA; s: requires FILE_WRITE_DATA to volume)
FileFsFullSizeInformation, // q: FILE_FS_FULL_SIZE_INFORMATION
FileFsObjectIdInformation, // q; s: FILE_FS_OBJECTID_INFORMATION (s: requires FILE_WRITE_DATA to volume)
FileFsDriverPathInformation, // q: FILE_FS_DRIVER_PATH_INFORMATION
FileFsVolumeFlagsInformation,
// q; s: FILE_FS_VOLUME_FLAGS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES to volume) // 10
FileFsSectorSizeInformation, // q: FILE_FS_SECTOR_SIZE_INFORMATION // since WIN8
FileFsDataCopyInformation, // q: FILE_FS_DATA_COPY_INFORMATION
FileFsMetadataSizeInformation, // q: FILE_FS_METADATA_SIZE_INFORMATION // since THRESHOLD
FileFsFullSizeInformationEx, // q: FILE_FS_FULL_SIZE_INFORMATION_EX // since REDSTONE5
FileFsGuidInformation, // q: FILE_FS_GUID_INFORMATION // since 23H2
FileFsMaximumInformation
FileFsVolumeInformation = 1, // q: FILE_FS_VOLUME_INFORMATION
FileFsLabelInformation, // s: FILE_FS_LABEL_INFORMATION (requires FILE_WRITE_DATA to volume)
FileFsSizeInformation, // q: FILE_FS_SIZE_INFORMATION
FileFsDeviceInformation, // q: FILE_FS_DEVICE_INFORMATION
FileFsAttributeInformation, // q: FILE_FS_ATTRIBUTE_INFORMATION
FileFsControlInformation,
// q, s: FILE_FS_CONTROL_INFORMATION (q: requires FILE_READ_DATA; s: requires FILE_WRITE_DATA to volume)
FileFsFullSizeInformation, // q: FILE_FS_FULL_SIZE_INFORMATION
FileFsObjectIdInformation, // q; s: FILE_FS_OBJECTID_INFORMATION (s: requires FILE_WRITE_DATA to volume)
FileFsDriverPathInformation, // q: FILE_FS_DRIVER_PATH_INFORMATION
FileFsVolumeFlagsInformation,
// q; s: FILE_FS_VOLUME_FLAGS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES to
// volume) // 10
FileFsSectorSizeInformation, // q: FILE_FS_SECTOR_SIZE_INFORMATION // since WIN8
FileFsDataCopyInformation, // q: FILE_FS_DATA_COPY_INFORMATION
FileFsMetadataSizeInformation, // q: FILE_FS_METADATA_SIZE_INFORMATION // since THRESHOLD
FileFsFullSizeInformationEx, // q: FILE_FS_FULL_SIZE_INFORMATION_EX // since REDSTONE5
FileFsGuidInformation, // q: FILE_FS_GUID_INFORMATION // since 23H2
FileFsMaximumInformation
} FSINFOCLASS, *PFSINFOCLASS;
typedef enum _FSINFOCLASS FS_INFORMATION_CLASS;
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
// q: FILE_DIRECTORY_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileFullDirectoryInformation,
// q: FILE_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBothDirectoryInformation,
// q: FILE_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBasicInformation,
// q; s: FILE_BASIC_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileStandardInformation, // q: FILE_STANDARD_INFORMATION, FILE_STANDARD_INFORMATION_EX
FileInternalInformation, // q: FILE_INTERNAL_INFORMATION
FileEaInformation, // q: FILE_EA_INFORMATION
FileAccessInformation, // q: FILE_ACCESS_INFORMATION
FileNameInformation, // q: FILE_NAME_INFORMATION
FileRenameInformation, // s: FILE_RENAME_INFORMATION (requires DELETE) // 10
FileLinkInformation, // s: FILE_LINK_INFORMATION
FileNamesInformation, // q: FILE_NAMES_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileDispositionInformation, // s: FILE_DISPOSITION_INFORMATION (requires DELETE)
FilePositionInformation, // q; s: FILE_POSITION_INFORMATION
FileFullEaInformation, // FILE_FULL_EA_INFORMATION
FileModeInformation, // q; s: FILE_MODE_INFORMATION
FileAlignmentInformation, // q: FILE_ALIGNMENT_INFORMATION
FileAllInformation, // q: FILE_ALL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAllocationInformation, // s: FILE_ALLOCATION_INFORMATION (requires FILE_WRITE_DATA)
FileEndOfFileInformation, // s: FILE_END_OF_FILE_INFORMATION (requires FILE_WRITE_DATA) // 20
FileAlternateNameInformation, // q: FILE_NAME_INFORMATION
FileStreamInformation, // q: FILE_STREAM_INFORMATION
FilePipeInformation,
// q; s: FILE_PIPE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FilePipeLocalInformation, // q: FILE_PIPE_LOCAL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FilePipeRemoteInformation,
// q; s: FILE_PIPE_REMOTE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION
FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION
FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION
FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30
FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA)
FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileReparsePointInformation,
// q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAttributeTagInformation, // q: FILE_ATTRIBUTE_TAG_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileTrackingInformation, // s: FILE_TRACKING_INFORMATION (requires FILE_WRITE_DATA)
FileIdBothDirectoryInformation,
// q: FILE_ID_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileIdFullDirectoryInformation,
// q: FILE_ID_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileValidDataLengthInformation,
// s: FILE_VALID_DATA_LENGTH_INFORMATION (requires FILE_WRITE_DATA and/or SeManageVolumePrivilege)
FileShortNameInformation, // s: FILE_NAME_INFORMATION (requires DELETE) // 40
FileIoCompletionNotificationInformation,
// q; s: FILE_IO_COMPLETION_NOTIFICATION_INFORMATION (q: requires FILE_READ_ATTRIBUTES) // since VISTA
FileIoStatusBlockRangeInformation, // s: FILE_IOSTATUSBLOCK_RANGE_INFORMATION (requires SeLockMemoryPrivilege)
FileIoPriorityHintInformation,
// q; s: FILE_IO_PRIORITY_HINT_INFORMATION, FILE_IO_PRIORITY_HINT_INFORMATION_EX (q: requires FILE_READ_DATA)
FileSfioReserveInformation, // q; s: FILE_SFIO_RESERVE_INFORMATION (q: requires FILE_READ_DATA)
FileSfioVolumeInformation, // q: FILE_SFIO_VOLUME_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileHardLinkInformation, // q: FILE_LINKS_INFORMATION
FileProcessIdsUsingFileInformation, // q: FILE_PROCESS_IDS_USING_FILE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileNormalizedNameInformation, // q: FILE_NAME_INFORMATION
FileNetworkPhysicalNameInformation, // q: FILE_NETWORK_PHYSICAL_NAME_INFORMATION
FileIdGlobalTxDirectoryInformation,
// q: FILE_ID_GLOBAL_TX_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since WIN7 // 50
FileIsRemoteDeviceInformation, // q: FILE_IS_REMOTE_DEVICE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileUnusedInformation,
FileNumaNodeInformation, // q: FILE_NUMA_NODE_INFORMATION
FileStandardLinkInformation, // q: FILE_STANDARD_LINK_INFORMATION
FileRemoteProtocolInformation, // q: FILE_REMOTE_PROTOCOL_INFORMATION
FileRenameInformationBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION // since WIN8
FileLinkInformationBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION
FileVolumeNameInformation, // q: FILE_VOLUME_NAME_INFORMATION
FileIdInformation, // q: FILE_ID_INFORMATION
FileIdExtdDirectoryInformation,
// q: FILE_ID_EXTD_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // 60
FileReplaceCompletionInformation, // s: FILE_COMPLETION_INFORMATION // since WINBLUE
FileHardLinkFullIdInformation, // q: FILE_LINK_ENTRY_FULL_ID_INFORMATION // FILE_LINKS_FULL_ID_INFORMATION
FileIdExtdBothDirectoryInformation,
// q: FILE_ID_EXTD_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since THRESHOLD
FileDispositionInformationEx, // s: FILE_DISPOSITION_INFO_EX (requires DELETE) // since REDSTONE
FileRenameInformationEx, // s: FILE_RENAME_INFORMATION_EX
FileRenameInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION_EX
FileDesiredStorageClassInformation,
// q; s: FILE_DESIRED_STORAGE_CLASS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since REDSTONE2
FileStatInformation, // q: FILE_STAT_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileMemoryPartitionInformation, // s: FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
FileStatLxInformation,
// q: FILE_STAT_LX_INFORMATION (requires FILE_READ_ATTRIBUTES and FILE_READ_EA) // since REDSTONE4 // 70
FileCaseSensitiveInformation,
// q; s: FILE_CASE_SENSITIVE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileLinkInformationEx, // s: FILE_LINK_INFORMATION_EX // since REDSTONE5
FileLinkInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION_EX
FileStorageReserveIdInformation,
// q; s: FILE_STORAGE_RESERVE_ID_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileCaseSensitiveInformationForceAccessCheck, // q; s: FILE_CASE_SENSITIVE_INFORMATION
FileKnownFolderInformation,
// q; s: FILE_KNOWN_FOLDER_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since WIN11
FileStatBasicInformation, // since 23H2
FileId64ExtdDirectoryInformation, // FILE_ID_64_EXTD_DIR_INFORMATION
FileId64ExtdBothDirectoryInformation, // FILE_ID_64_EXTD_BOTH_DIR_INFORMATION
FileIdAllExtdDirectoryInformation, // FILE_ID_ALL_EXTD_DIR_INFORMATION
FileIdAllExtdBothDirectoryInformation, // FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION
FileStreamReservationInformation, // FILE_STREAM_RESERVATION_INFORMATION // since 24H2
FileMupProviderInfo, // MUP_PROVIDER_INFORMATION
FileMaximumInformation
FileDirectoryInformation = 1,
// q: FILE_DIRECTORY_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileFullDirectoryInformation,
// q: FILE_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBothDirectoryInformation,
// q: FILE_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileBasicInformation,
// q; s: FILE_BASIC_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileStandardInformation, // q: FILE_STANDARD_INFORMATION, FILE_STANDARD_INFORMATION_EX
FileInternalInformation, // q: FILE_INTERNAL_INFORMATION
FileEaInformation, // q: FILE_EA_INFORMATION
FileAccessInformation, // q: FILE_ACCESS_INFORMATION
FileNameInformation, // q: FILE_NAME_INFORMATION
FileRenameInformation, // s: FILE_RENAME_INFORMATION (requires DELETE) // 10
FileLinkInformation, // s: FILE_LINK_INFORMATION
FileNamesInformation, // q: FILE_NAMES_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileDispositionInformation, // s: FILE_DISPOSITION_INFORMATION (requires DELETE)
FilePositionInformation, // q; s: FILE_POSITION_INFORMATION
FileFullEaInformation, // FILE_FULL_EA_INFORMATION
FileModeInformation, // q; s: FILE_MODE_INFORMATION
FileAlignmentInformation, // q: FILE_ALIGNMENT_INFORMATION
FileAllInformation, // q: FILE_ALL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAllocationInformation, // s: FILE_ALLOCATION_INFORMATION (requires FILE_WRITE_DATA)
FileEndOfFileInformation, // s: FILE_END_OF_FILE_INFORMATION (requires FILE_WRITE_DATA) // 20
FileAlternateNameInformation, // q: FILE_NAME_INFORMATION
FileStreamInformation, // q: FILE_STREAM_INFORMATION
FilePipeInformation,
// q; s: FILE_PIPE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FilePipeLocalInformation, // q: FILE_PIPE_LOCAL_INFORMATION (requires FILE_READ_ATTRIBUTES)
FilePipeRemoteInformation,
// q; s: FILE_PIPE_REMOTE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION
FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION
FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION
FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30
FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA)
FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileReparsePointInformation,
// q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileAttributeTagInformation, // q: FILE_ATTRIBUTE_TAG_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileTrackingInformation, // s: FILE_TRACKING_INFORMATION (requires FILE_WRITE_DATA)
FileIdBothDirectoryInformation,
// q: FILE_ID_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileIdFullDirectoryInformation,
// q: FILE_ID_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileValidDataLengthInformation,
// s: FILE_VALID_DATA_LENGTH_INFORMATION (requires FILE_WRITE_DATA and/or SeManageVolumePrivilege)
FileShortNameInformation, // s: FILE_NAME_INFORMATION (requires DELETE) // 40
FileIoCompletionNotificationInformation,
// q; s: FILE_IO_COMPLETION_NOTIFICATION_INFORMATION (q: requires FILE_READ_ATTRIBUTES) // since VISTA
FileIoStatusBlockRangeInformation, // s: FILE_IOSTATUSBLOCK_RANGE_INFORMATION (requires SeLockMemoryPrivilege)
FileIoPriorityHintInformation,
// q; s: FILE_IO_PRIORITY_HINT_INFORMATION, FILE_IO_PRIORITY_HINT_INFORMATION_EX (q: requires FILE_READ_DATA)
FileSfioReserveInformation, // q; s: FILE_SFIO_RESERVE_INFORMATION (q: requires FILE_READ_DATA)
FileSfioVolumeInformation, // q: FILE_SFIO_VOLUME_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileHardLinkInformation, // q: FILE_LINKS_INFORMATION
FileProcessIdsUsingFileInformation, // q: FILE_PROCESS_IDS_USING_FILE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileNormalizedNameInformation, // q: FILE_NAME_INFORMATION
FileNetworkPhysicalNameInformation, // q: FILE_NETWORK_PHYSICAL_NAME_INFORMATION
FileIdGlobalTxDirectoryInformation,
// q: FILE_ID_GLOBAL_TX_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since WIN7 //
// 50
FileIsRemoteDeviceInformation, // q: FILE_IS_REMOTE_DEVICE_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileUnusedInformation,
FileNumaNodeInformation, // q: FILE_NUMA_NODE_INFORMATION
FileStandardLinkInformation, // q: FILE_STANDARD_LINK_INFORMATION
FileRemoteProtocolInformation, // q: FILE_REMOTE_PROTOCOL_INFORMATION
FileRenameInformationBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION // since WIN8
FileLinkInformationBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION
FileVolumeNameInformation, // q: FILE_VOLUME_NAME_INFORMATION
FileIdInformation, // q: FILE_ID_INFORMATION
FileIdExtdDirectoryInformation,
// q: FILE_ID_EXTD_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // 60
FileReplaceCompletionInformation, // s: FILE_COMPLETION_INFORMATION // since WINBLUE
FileHardLinkFullIdInformation, // q: FILE_LINK_ENTRY_FULL_ID_INFORMATION // FILE_LINKS_FULL_ID_INFORMATION
FileIdExtdBothDirectoryInformation,
// q: FILE_ID_EXTD_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since THRESHOLD
FileDispositionInformationEx, // s: FILE_DISPOSITION_INFO_EX (requires DELETE) // since REDSTONE
FileRenameInformationEx, // s: FILE_RENAME_INFORMATION_EX
FileRenameInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION_EX
FileDesiredStorageClassInformation,
// q; s: FILE_DESIRED_STORAGE_CLASS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires
// FILE_WRITE_ATTRIBUTES) // since REDSTONE2
FileStatInformation, // q: FILE_STAT_INFORMATION (requires FILE_READ_ATTRIBUTES)
FileMemoryPartitionInformation, // s: FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
FileStatLxInformation,
// q: FILE_STAT_LX_INFORMATION (requires FILE_READ_ATTRIBUTES and FILE_READ_EA) // since REDSTONE4 // 70
FileCaseSensitiveInformation,
// q; s: FILE_CASE_SENSITIVE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileLinkInformationEx, // s: FILE_LINK_INFORMATION_EX // since REDSTONE5
FileLinkInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION_EX
FileStorageReserveIdInformation,
// q; s: FILE_STORAGE_RESERVE_ID_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)
FileCaseSensitiveInformationForceAccessCheck, // q; s: FILE_CASE_SENSITIVE_INFORMATION
FileKnownFolderInformation,
// q; s: FILE_KNOWN_FOLDER_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) //
// since WIN11
FileStatBasicInformation, // since 23H2
FileId64ExtdDirectoryInformation, // FILE_ID_64_EXTD_DIR_INFORMATION
FileId64ExtdBothDirectoryInformation, // FILE_ID_64_EXTD_BOTH_DIR_INFORMATION
FileIdAllExtdDirectoryInformation, // FILE_ID_ALL_EXTD_DIR_INFORMATION
FileIdAllExtdBothDirectoryInformation, // FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION
FileStreamReservationInformation, // FILE_STREAM_RESERVATION_INFORMATION // since 24H2
FileMupProviderInfo, // MUP_PROVIDER_INFORMATION
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION
ObjectNameInformation, // q: OBJECT_NAME_INFORMATION
ObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION
ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION
ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege)
ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege)
MaxObjectInfoClass
ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION
ObjectNameInformation, // q: OBJECT_NAME_INFORMATION
ObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION
ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION
ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege)
ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege)
MaxObjectInfoClass
} OBJECT_INFORMATION_CLASS;
typedef enum _HARDERROR_RESPONSE_OPTION
{
OptionAbortRetryIgnore,
OptionOk,
OptionOkCancel,
OptionRetryCancel,
OptionYesNo,
OptionYesNoCancel,
OptionShutdownSystem,
OptionOkNoWait,
OptionCancelTryContinue
OptionAbortRetryIgnore,
OptionOk,
OptionOkCancel,
OptionRetryCancel,
OptionYesNo,
OptionYesNoCancel,
OptionShutdownSystem,
OptionOkNoWait,
OptionCancelTryContinue
} HARDERROR_RESPONSE_OPTION;
typedef enum _HARDERROR_RESPONSE
{
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort,
ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes,
ResponseTryAgain,
ResponseContinue
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort,
ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes,
ResponseTryAgain,
ResponseContinue
} HARDERROR_RESPONSE;
typedef USHORT RTL_ATOM;
@@ -248,113 +252,112 @@ typedef USHORT RTL_ATOM;
template <typename Traits>
struct IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
typename Traits::PVOID Pointer;
};
union
{
NTSTATUS Status;
typename Traits::PVOID Pointer;
};
typename Traits::ULONG_PTR Information;
typename Traits::ULONG_PTR Information;
};
template <typename Traits>
struct OBJECT_ATTRIBUTES
{
ULONG Length;
typename Traits::HANDLE RootDirectory;
EMULATOR_CAST(typename Traits::PVOID, UNICODE_STRING*) ObjectName;
ULONG Attributes;
typename Traits::PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
typename Traits::PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
ULONG Length;
typename Traits::HANDLE RootDirectory;
EMULATOR_CAST(typename Traits::PVOID, UNICODE_STRING*) ObjectName;
ULONG Attributes;
typename Traits::PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
typename Traits::PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
};
typedef struct _FILE_FS_DEVICE_INFORMATION
{
DEVICE_TYPE DeviceType;
ULONG Characteristics;
DEVICE_TYPE DeviceType;
ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION
{
LARGE_INTEGER CurrentByteOffset;
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION
{
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_NAME_INFORMATION
{
ULONG FileNameLength;
char16_t FileName[1];
ULONG FileNameLength;
char16_t FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_BASIC_INFORMATION
{
LARGE_INTEGER CreationTime; // Specifies the time that the file was created.
LARGE_INTEGER LastAccessTime; // Specifies the time that the file was last accessed.
LARGE_INTEGER LastWriteTime; // Specifies the time that the file was last written to.
LARGE_INTEGER ChangeTime; // Specifies the last time the file was changed.
ULONG FileAttributes; // Specifies one or more FILE_ATTRIBUTE_XXX flags.
LARGE_INTEGER CreationTime; // Specifies the time that the file was created.
LARGE_INTEGER LastAccessTime; // Specifies the time that the file was last accessed.
LARGE_INTEGER LastWriteTime; // Specifies the time that the file was last written to.
LARGE_INTEGER ChangeTime; // Specifies the last time the file was changed.
ULONG FileAttributes; // Specifies one or more FILE_ATTRIBUTE_XXX flags.
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef struct _FILE_DIRECTORY_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
char16_t FileName[1];
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
char16_t FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
typedef struct _FILE_FULL_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
char16_t FileName[1];
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
char16_t FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;
typedef struct _FILE_BOTH_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
char ShortNameLength;
char16_t ShortName[12];
char16_t FileName[1];
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
char ShortNameLength;
char16_t ShortName[12];
char16_t FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
#ifndef OS_WINDOWS
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,
* PSECURITY_CONTEXT_TRACKING_MODE;
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
typedef struct _SECURITY_QUALITY_OF_SERVICE
{
DWORD Length;
@@ -367,17 +370,17 @@ typedef struct _SECURITY_QUALITY_OF_SERVICE
typedef struct _PORT_VIEW64
{
ULONG Length;
EMULATOR_CAST(std::uint64_t, HANDLE) SectionHandle;
ULONG SectionOffset;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
EmulatorTraits<Emu64>::PVOID ViewRemoteBase;
ULONG Length;
EMULATOR_CAST(std::uint64_t, HANDLE) SectionHandle;
ULONG SectionOffset;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
EmulatorTraits<Emu64>::PVOID ViewRemoteBase;
} PORT_VIEW64, *PPORT_VIEW64;
typedef struct _REMOTE_PORT_VIEW64
{
ULONG Length;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
ULONG Length;
EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize;
EmulatorTraits<Emu64>::PVOID ViewBase;
} REMOTE_PORT_VIEW64, *PREMOTE_PORT_VIEW64;

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,21 @@
#pragma once
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_TARGETS_INVALID 0x40000000
#define PAGE_TARGETS_NO_UPDATE 0x40000000
#define PAGE_TARGETS_INVALID 0x40000000
#define PAGE_TARGETS_NO_UPDATE 0x40000000
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
#define PAGE_WRITECOMBINE 0x400
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
#define PAGE_WRITECOMBINE 0x400
#define MEM_COMMIT 0x00001000
#define MEM_RESERVE 0x00002000
@@ -38,94 +38,92 @@
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, // q: MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // q: MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // q: UNICODE_STRING
MemoryRegionInformation, // q: MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // q: MEMORY_WORKING_SET_EX_INFORMATION // since VISTA
MemorySharedCommitInformation, // q: MEMORY_SHARED_COMMIT_INFORMATION // since WIN8
MemoryImageInformation, // q: MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION
MemoryPrivilegedBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
MemoryBasicInformationCapped, // 10
MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1
MemoryBadInformation, // since WIN11
MemoryBadInformationAllProcesses, // since 22H1
MemoryImageExtensionInformation, // since 24H2
MaxMemoryInfoClass
MemoryBasicInformation, // q: MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // q: MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // q: UNICODE_STRING
MemoryRegionInformation, // q: MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // q: MEMORY_WORKING_SET_EX_INFORMATION // since VISTA
MemorySharedCommitInformation, // q: MEMORY_SHARED_COMMIT_INFORMATION // since WIN8
MemoryImageInformation, // q: MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION
MemoryPrivilegedBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
MemoryBasicInformationCapped, // 10
MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1
MemoryBadInformation, // since WIN11
MemoryBadInformationAllProcesses, // since 22H1
MemoryImageExtensionInformation, // since 24H2
MaxMemoryInfoClass
} MEMORY_INFORMATION_CLASS;
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;
typedef struct DECLSPEC_ALIGN(16) _EMU_MEMORY_BASIC_INFORMATION64
{
void* BaseAddress;
void* AllocationBase;
DWORD AllocationProtect;
WORD PartitionId;
std::int64_t RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
void* BaseAddress;
void* AllocationBase;
DWORD AllocationProtect;
WORD PartitionId;
std::int64_t RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} EMU_MEMORY_BASIC_INFORMATION64, *PEMU_MEMORY_BASIC_INFORMATION64;
typedef struct _MEMORY_IMAGE_INFORMATION64
{
void* ImageBase;
std::int64_t SizeOfImage;
void* ImageBase;
std::int64_t SizeOfImage;
union
{
ULONG ImageFlags;
union
{
ULONG ImageFlags;
struct
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
ULONG ImageSigningLevel : 4; // REDSTONE3
ULONG ImageExtensionPresent : 1; // since 24H2
ULONG Reserved : 25;
};
};
struct
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
ULONG ImageSigningLevel : 4; // REDSTONE3
ULONG ImageExtensionPresent : 1; // since 24H2
ULONG Reserved : 25;
};
};
} MEMORY_IMAGE_INFORMATION64, *PMEMORY_IMAGE_INFORMATION64;
typedef struct _MEMORY_REGION_INFORMATION
{
void* AllocationBase;
ULONG AllocationProtect;
void* AllocationBase;
ULONG AllocationProtect;
union
{
ULONG RegionType;
union
{
ULONG RegionType;
struct
{
ULONG Private : 1;
ULONG MappedDataFile : 1;
ULONG MappedImage : 1;
ULONG MappedPageFile : 1;
ULONG MappedPhysical : 1;
ULONG DirectMapped : 1;
ULONG SoftwareEnclave : 1; // REDSTONE3
ULONG PageSize64K : 1;
ULONG PlaceholderReservation : 1; // REDSTONE4
ULONG MappedAwe : 1; // 21H1
ULONG MappedWriteWatch : 1;
ULONG PageSizeLarge : 1;
ULONG PageSizeHuge : 1;
ULONG Reserved : 19;
};
};
struct
{
ULONG Private : 1;
ULONG MappedDataFile : 1;
ULONG MappedImage : 1;
ULONG MappedPageFile : 1;
ULONG MappedPhysical : 1;
ULONG DirectMapped : 1;
ULONG SoftwareEnclave : 1; // REDSTONE3
ULONG PageSize64K : 1;
ULONG PlaceholderReservation : 1; // REDSTONE4
ULONG MappedAwe : 1; // 21H1
ULONG MappedWriteWatch : 1;
ULONG PageSizeLarge : 1;
ULONG PageSizeHuge : 1;
ULONG Reserved : 19;
};
};
std::int64_t RegionSize;
std::int64_t CommitSize;
DWORD64 PartitionId; // 19H1
DWORD64 NodePreference; // 20H1
std::int64_t RegionSize;
std::int64_t CommitSize;
DWORD64 PartitionId; // 19H1
DWORD64 NodePreference; // 20H1
} MEMORY_REGION_INFORMATION64, *PMEMORY_REGION_INFORMATION64;

View File

@@ -3,6 +3,6 @@
template <typename Traits>
struct EMU_WSABUF
{
ULONG len;
EMULATOR_CAST(typename Traits::PVOID, CHAR*) buf;
ULONG len;
EMULATOR_CAST(typename Traits::PVOID, CHAR*) buf;
};

View File

@@ -2,8 +2,8 @@
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4201) // nameless struct/union
#pragma warning(disable: 4702) // unreachable code
#pragma warning(disable : 4201) // nameless struct/union
#pragma warning(disable : 4702) // unreachable code
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
@@ -27,18 +27,12 @@
#ifdef OS_WINDOWS
#pragma comment(lib, "ntdll")
extern "C" {
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQuerySystemInformationEx(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
extern "C"
{
NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformationEx(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength, _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength);
}
#pragma warning(pop)
#else

View File

@@ -20,31 +20,30 @@ using LONGLONG = std::int64_t;
typedef union _ULARGE_INTEGER
{
struct
{
DWORD LowPart;
DWORD HighPart;
};
struct
{
DWORD LowPart;
DWORD HighPart;
};
ULONGLONG QuadPart;
ULONGLONG QuadPart;
} ULARGE_INTEGER;
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG HighPart;
};
struct
{
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
LONGLONG QuadPart;
} LARGE_INTEGER;
using BYTE = std::uint8_t;
#define CHAR BYTE
#define CHAR BYTE
#endif
using WORD = std::uint16_t;
#define UCHAR unsigned char
@@ -53,7 +52,6 @@ using WORD = std::uint16_t;
using CSHORT = short;
using USHORT = WORD;
#define DUMMYSTRUCTNAME
#ifndef TRUE

File diff suppressed because it is too large Load Diff

View File

@@ -2,63 +2,63 @@
typedef enum _KEY_INFORMATION_CLASS
{
KeyBasicInformation, // KEY_BASIC_INFORMATION
KeyNodeInformation, // KEY_NODE_INFORMATION
KeyFullInformation, // KEY_FULL_INFORMATION
KeyNameInformation, // KEY_NAME_INFORMATION
KeyCachedInformation, // KEY_CACHED_INFORMATION
KeyFlagsInformation, // KEY_FLAGS_INFORMATION
KeyVirtualizationInformation, // KEY_VIRTUALIZATION_INFORMATION
KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
KeyTrustInformation, // KEY_TRUST_INFORMATION
KeyLayerInformation, // KEY_LAYER_INFORMATION
MaxKeyInfoClass
KeyBasicInformation, // KEY_BASIC_INFORMATION
KeyNodeInformation, // KEY_NODE_INFORMATION
KeyFullInformation, // KEY_FULL_INFORMATION
KeyNameInformation, // KEY_NAME_INFORMATION
KeyCachedInformation, // KEY_CACHED_INFORMATION
KeyFlagsInformation, // KEY_FLAGS_INFORMATION
KeyVirtualizationInformation, // KEY_VIRTUALIZATION_INFORMATION
KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
KeyTrustInformation, // KEY_TRUST_INFORMATION
KeyLayerInformation, // KEY_LAYER_INFORMATION
MaxKeyInfoClass
} KEY_INFORMATION_CLASS;
typedef enum _KEY_VALUE_INFORMATION_CLASS
{
KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION
KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION
KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64
KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION
MaxKeyValueInfoClass
KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION
KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION
KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64
KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION
MaxKeyValueInfoClass
} KEY_VALUE_INFORMATION_CLASS;
struct KEY_NAME_INFORMATION
{
std::uint32_t NameLength;
char16_t Name[1];
std::uint32_t NameLength;
char16_t Name[1];
};
struct KEY_HANDLE_TAGS_INFORMATION
{
ULONG HandleTags;
ULONG HandleTags;
};
struct KEY_VALUE_BASIC_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
char16_t Name[1];
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
char16_t Name[1];
};
struct KEY_VALUE_PARTIAL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
};
struct KEY_VALUE_FULL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
char16_t Name[1];
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
char16_t Name[1];
};

View File

@@ -5,42 +5,41 @@
using NTSTATUS = std::uint32_t;
#ifndef OS_WINDOWS
#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L)
#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L)
#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L)
#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L)
#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L)
#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L)
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L)
#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L)
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001DL)
#define STATUS_PENDING ((DWORD)0x00000103L)
#define STATUS_PENDING ((NTSTATUS)0x00000103L)
#endif
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_WAIT_1 ((NTSTATUS)0x00000001L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_WAIT_1 ((NTSTATUS)0x00000001L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x00000001L)
#define STATUS_ALERTED ((NTSTATUS)0x00000101L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x00000001L)
#define STATUS_ALERTED ((NTSTATUS)0x00000101L)
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L)
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L)
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define STATUS_ILLEGAL_INSTRUCTION ((DWORD )0xC000001DL)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL)
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L)
#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000328L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL)
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L)
#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000328L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define FILE_DEVICE_NETWORK 0x00000012
#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK
#define FILE_DEVICE_NETWORK 0x00000012
#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK

View File

@@ -2,15 +2,15 @@
typedef enum _EVENT_TYPE
{
NotificationEvent,
SynchronizationEvent
NotificationEvent,
SynchronizationEvent
} EVENT_TYPE;
typedef enum _WAIT_TYPE
{
WaitAll,
WaitAny,
WaitNotification,
WaitDequeue,
WaitDpc,
WaitAll,
WaitAny,
WaitNotification,
WaitDequeue,
WaitDpc,
} WAIT_TYPE;

View File

@@ -2,70 +2,69 @@
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY (requires SeIncreaseBasePriorityPrivilege)
ThreadBasePriority, // s: KPRIORITY
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY (requires SeIncreaseBasePriorityPrivilege)
ThreadBasePriority, // s: KPRIORITY
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair,
ThreadQuerySetWin32StartAddress, // q: ULONG_PTR
ThreadZeroTlsCell, // s: ULONG // TlsIndex // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress, // s: ULONG_PTR // Obsolete
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // q: BOOLEAN; s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState, // s: void // NtCurrentThread // NPX/FPU
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT (requires SeIncreaseBasePriorityPrivilege)
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ThreadActualBasePriority, // s: LONG (requires SeIncreaseBasePriorityPrivilege)
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon, // Obsolete
ThreadZeroTlsCell, // s: ULONG // TlsIndex // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress, // s: ULONG_PTR // Obsolete
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // q: BOOLEAN; s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState, // s: void // NtCurrentThread // NPX/FPU
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT (requires SeIncreaseBasePriorityPrivilege)
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ThreadActualBasePriority, // s: LONG (requires SeIncreaseBasePriorityPrivilege)
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon, // Obsolete
ThreadCSwitchPmu,
ThreadWow64Context, // qs: WOW64_CONTEXT, ARM_NT_CONTEXT since 20H1
ThreadGroupInformation, // qs: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION // Obsolete
ThreadCounterProfiling, // q: BOOLEAN; s: THREAD_PROFILING_INFORMATION?
ThreadIdealProcessorEx, // qs: PROCESSOR_NUMBER; s: previous PROCESSOR_NUMBER on return
ThreadWow64Context, // qs: WOW64_CONTEXT, ARM_NT_CONTEXT since 20H1
ThreadGroupInformation, // qs: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION // Obsolete
ThreadCounterProfiling, // q: BOOLEAN; s: THREAD_PROFILING_INFORMATION?
ThreadIdealProcessorEx, // qs: PROCESSOR_NUMBER; s: previous PROCESSOR_NUMBER on return
ThreadCpuAccountingInformation, // q: BOOLEAN; s: HANDLE (NtOpenSession) // NtCurrentThread // since WIN8
ThreadSuspendCount, // q: ULONG // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION
ThreadSuspendCount, // q: ULONG // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION
ThreadSelectedCpuSets,
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // q: GROUP_AFFINITY // since THRESHOLD2
ThreadDynamicCodePolicyInfo, // q: ULONG; s: ULONG (NtCurrentThread)
ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables
ThreadWorkOnBehalfTicket, // RTL_WORK_ON_BEHALF_TICKET_EX
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive, // s: ULONG; s: 0 disables, otherwise enables
ThreadAttachContainer, // s: HANDLE (job object) // NtCurrentThread
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // q: GROUP_AFFINITY // since THRESHOLD2
ThreadDynamicCodePolicyInfo, // q: ULONG; s: ULONG (NtCurrentThread)
ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables
ThreadWorkOnBehalfTicket, // RTL_WORK_ON_BEHALF_TICKET_EX
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive, // s: ULONG; s: 0 disables, otherwise enables
ThreadAttachContainer, // s: HANDLE (job object) // NtCurrentThread
ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ThreadPowerThrottlingState, // POWER_THROTTLING_THREAD_STATE // since REDSTONE3 (set), WIN11 22H2 (query)
ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50
ThreadCreateStateChange, // since WIN11
ThreadPowerThrottlingState, // POWER_THROTTLING_THREAD_STATE // since REDSTONE3 (set), WIN11 22H2 (query)
ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50
ThreadCreateStateChange, // since WIN11
ThreadApplyStateChange,
ThreadStrongerBadHandleChecks, // since 22H1
ThreadEffectiveIoPriority, // q: IO_PRIORITY_HINT
ThreadEffectivePagePriority, // q: ULONG
ThreadUpdateLockOwnership, // since 24H2
ThreadEffectiveIoPriority, // q: IO_PRIORITY_HINT
ThreadEffectivePagePriority, // q: ULONG
ThreadUpdateLockOwnership, // since 24H2
ThreadSchedulerSharedDataSlot, // SCHEDULER_SHARED_DATA_SLOT_INFORMATION
ThreadTebInformationAtomic, // THREAD_TEB_INFORMATION
ThreadIndexInformation, // THREAD_INDEX_INFORMATION
ThreadTebInformationAtomic, // THREAD_TEB_INFORMATION
ThreadIndexInformation, // THREAD_INDEX_INFORMATION
MaxThreadInfoClass
} THREADINFOCLASS;
template <typename Traits>
struct THREAD_NAME_INFORMATION
{
@@ -80,4 +79,4 @@ typedef struct _THREAD_BASIC_INFORMATION64
EMULATOR_CAST(std::uint64_t, KAFFINITY) AffinityMask;
EMULATOR_CAST(std::uint32_t, KPRIORITY) Priority;
EMULATOR_CAST(std::uint32_t, KPRIORITY) BasePriority;
} THREAD_BASIC_INFORMATION64, *PTHREAD_BASIC_INFORMATION64;
} THREAD_BASIC_INFORMATION64, *PTHREAD_BASIC_INFORMATION64;

View File

@@ -19,19 +19,19 @@ struct EmulatorTraits;
template <>
struct EmulatorTraits<Emu32>
{
using PVOID = std::uint32_t;
using ULONG_PTR = std::uint32_t;
using SIZE_T = std::uint32_t;
using UNICODE = char16_t;
using HANDLE = std::uint32_t;
using PVOID = std::uint32_t;
using ULONG_PTR = std::uint32_t;
using SIZE_T = std::uint32_t;
using UNICODE = char16_t;
using HANDLE = std::uint32_t;
};
template <>
struct EmulatorTraits<Emu64>
{
using PVOID = std::uint64_t;
using ULONG_PTR = std::uint64_t;
using SIZE_T = std::uint64_t;
using UNICODE = char16_t;
using HANDLE = std::uint64_t;
using PVOID = std::uint64_t;
using ULONG_PTR = std::uint64_t;
using SIZE_T = std::uint64_t;
using UNICODE = char16_t;
using HANDLE = std::uint64_t;
};

View File

@@ -5,76 +5,76 @@
template <typename Traits>
struct UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
USHORT Length;
USHORT MaximumLength;
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
};
inline std::string u16_to_u8(const std::u16string_view u16_view)
{
std::string utf8_str;
utf8_str.reserve(u16_view.size() * 2);
for (const char16_t ch : u16_view)
{
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
std::string utf8_str;
utf8_str.reserve(u16_view.size() * 2);
for (const char16_t ch : u16_view)
{
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
inline std::string w_to_u8(const std::wstring_view w_view)
{
std::string utf8_str;
utf8_str.reserve(w_view.size() * 2);
for (const wchar_t w_ch : w_view)
{
const auto ch = static_cast<char16_t>(w_ch);
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
std::string utf8_str;
utf8_str.reserve(w_view.size() * 2);
for (const wchar_t w_ch : w_view)
{
const auto ch = static_cast<char16_t>(w_ch);
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
#ifndef OS_WINDOWS
inline int open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
{
*handle = fopen(u16_to_u8(fileName).c_str(), u16_to_u8(mode).c_str());
return errno;
*handle = fopen(u16_to_u8(fileName).c_str(), u16_to_u8(mode).c_str());
return errno;
}
#else
inline std::wstring u16_to_w(const std::u16string& u16str)
{
return std::wstring(reinterpret_cast<const wchar_t*>(u16str.data()), u16str.size());
return std::wstring(reinterpret_cast<const wchar_t*>(u16str.data()), u16str.size());
}
inline auto open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
{
return _wfopen_s(handle, u16_to_w(fileName).c_str(), u16_to_w(mode).c_str());
return _wfopen_s(handle, u16_to_w(fileName).c_str(), u16_to_w(mode).c_str());
}
#endif

View File

@@ -2,96 +2,95 @@
#include <cstdint>
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_ARM_MOV32A 5
#define IMAGE_REL_BASED_ARM_MOV32 5
#define IMAGE_REL_BASED_SECTION 6
#define IMAGE_REL_BASED_REL 7
#define IMAGE_REL_BASED_ARM_MOV32T 7
#define IMAGE_REL_BASED_THUMB_MOV32 7
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
#define IMAGE_REL_BASED_HIGH3ADJ 11
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_ARM_MOV32A 5
#define IMAGE_REL_BASED_ARM_MOV32 5
#define IMAGE_REL_BASED_SECTION 6
#define IMAGE_REL_BASED_REL 7
#define IMAGE_REL_BASED_ARM_MOV32T 7
#define IMAGE_REL_BASED_THUMB_MOV32 7
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
#define IMAGE_REL_BASED_HIGH3ADJ 11
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#define IMAGE_FILE_DLL 0x2000
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#define IMAGE_FILE_DLL 0x2000
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define PROCESSOR_ARCHITECTURE_AMD64 9
#define PROCESSOR_ARCHITECTURE_AMD64 9
enum class PEMachineType : std::uint16_t
{
UNKNOWN = 0,
I386 = 0x014c, // Intel 386.
R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian
R4000 = 0x0166, // MIPS little-endian
R10000 = 0x0168, // MIPS little-endian
WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2
ALPHA = 0x0184, // Alpha_AXP
SH3 = 0x01a2, // SH3 little-endian
SH3DSP = 0x01a3,
SH3E = 0x01a4, // SH3E little-endian
SH4 = 0x01a6, // SH4 little-endian
SH5 = 0x01a8, // SH5
ARM = 0x01c0, // ARM Little-Endian
THUMB = 0x01c2, // ARM Thumb/Thumb-2 Little-Endian
ARMNT = 0x01c4, // ARM Thumb-2 Little-Endian
AM33 = 0x01d3,
POWERPC = 0x01F0, // IBM PowerPC Little-Endian
POWERPCFP = 0x01f1,
IA64 = 0x0200, // Intel 64
MIPS16 = 0x0266, // MIPS
ALPHA64 = 0x0284, // ALPHA64
MIPSFPU = 0x0366, // MIPS
MIPSFPU16 = 0x0466, // MIPS
AXP64 = ALPHA64,
TRICORE = 0x0520, // Infineon
CEF = 0x0CEF,
EBC = 0x0EBC, // EFI Byte Code
AMD64 = 0x8664, // AMD64 (K8)
M32R = 0x9041, // M32R little-endian
CEE = 0xC0EE,
UNKNOWN = 0,
I386 = 0x014c, // Intel 386.
R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian
R4000 = 0x0166, // MIPS little-endian
R10000 = 0x0168, // MIPS little-endian
WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2
ALPHA = 0x0184, // Alpha_AXP
SH3 = 0x01a2, // SH3 little-endian
SH3DSP = 0x01a3,
SH3E = 0x01a4, // SH3E little-endian
SH4 = 0x01a6, // SH4 little-endian
SH5 = 0x01a8, // SH5
ARM = 0x01c0, // ARM Little-Endian
THUMB = 0x01c2, // ARM Thumb/Thumb-2 Little-Endian
ARMNT = 0x01c4, // ARM Thumb-2 Little-Endian
AM33 = 0x01d3,
POWERPC = 0x01F0, // IBM PowerPC Little-Endian
POWERPCFP = 0x01f1,
IA64 = 0x0200, // Intel 64
MIPS16 = 0x0266, // MIPS
ALPHA64 = 0x0284, // ALPHA64
MIPSFPU = 0x0366, // MIPS
MIPSFPU16 = 0x0466, // MIPS
AXP64 = ALPHA64,
TRICORE = 0x0520, // Infineon
CEF = 0x0CEF,
EBC = 0x0EBC, // EFI Byte Code
AMD64 = 0x8664, // AMD64 (K8)
M32R = 0x9041, // M32R little-endian
CEE = 0xC0EE,
};
#pragma pack(push, 4)
template <typename T>
@@ -102,65 +101,64 @@ struct PEOptionalHeaderBasePart2_t
template <>
struct PEOptionalHeaderBasePart2_t<std::uint32_t>
{
std::uint32_t BaseOfData;
std::uint32_t ImageBase;
std::uint32_t BaseOfData;
std::uint32_t ImageBase;
};
template <>
struct PEOptionalHeaderBasePart2_t<std::uint64_t>
{
std::uint64_t ImageBase;
std::uint64_t ImageBase;
};
template <typename T>
struct PEOptionalHeaderBasePart1_t
{
enum
{
k_NumberOfDataDirectors = 16
};
enum
{
k_NumberOfDataDirectors = 16
};
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
};
struct PEDirectory_t2
{
std::uint32_t VirtualAddress;
std::uint32_t Size;
std::uint32_t VirtualAddress;
std::uint32_t Size;
};
template <typename T>
struct PEOptionalHeaderBasePart3_t : PEOptionalHeaderBasePart1_t<T>, PEOptionalHeaderBasePart2_t<T>
{
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
T SizeOfStackReserve;
T SizeOfStackCommit;
T SizeOfHeapReserve;
T SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
PEDirectory_t2 DataDirectory[PEOptionalHeaderBasePart1_t<T>::k_NumberOfDataDirectors];
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
T SizeOfStackReserve;
T SizeOfStackCommit;
T SizeOfHeapReserve;
T SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
PEDirectory_t2 DataDirectory[PEOptionalHeaderBasePart1_t<T>::k_NumberOfDataDirectors];
};
template <typename T>
@@ -171,113 +169,116 @@ struct PEOptionalHeader_t
template <>
struct PEOptionalHeader_t<std::uint32_t> : PEOptionalHeaderBasePart3_t<std::uint32_t>
{
enum
{
k_Magic = 0x10b, // IMAGE_NT_OPTIONAL_HDR32_MAGIC
};
enum
{
k_Magic = 0x10b, // IMAGE_NT_OPTIONAL_HDR32_MAGIC
};
};
template <>
struct PEOptionalHeader_t<std::uint64_t> : PEOptionalHeaderBasePart3_t<std::uint64_t>
{
enum
{
k_Magic = 0x20b, // IMAGE_NT_OPTIONAL_HDR64_MAGIC
};
enum
{
k_Magic = 0x20b, // IMAGE_NT_OPTIONAL_HDR64_MAGIC
};
};
struct PEFileHeader_t
{
PEMachineType Machine;
std::uint16_t NumberOfSections;
std::uint32_t TimeDateStamp;
std::uint32_t PointerToSymbolTable;
std::uint32_t NumberOfSymbols;
std::uint16_t SizeOfOptionalHeader;
std::uint16_t Characteristics;
PEMachineType Machine;
std::uint16_t NumberOfSections;
std::uint32_t TimeDateStamp;
std::uint32_t PointerToSymbolTable;
std::uint32_t NumberOfSymbols;
std::uint16_t SizeOfOptionalHeader;
std::uint16_t Characteristics;
};
template <typename T>
struct PENTHeaders_t
{
enum
{
k_Signature = 0x00004550, // IMAGE_NT_SIGNATURE
};
enum
{
k_Signature = 0x00004550, // IMAGE_NT_SIGNATURE
};
uint32_t Signature;
PEFileHeader_t FileHeader;
PEOptionalHeader_t<T> OptionalHeader;
uint32_t Signature;
PEFileHeader_t FileHeader;
PEOptionalHeader_t<T> OptionalHeader;
};
struct PEDosHeader_t
{
enum
{
k_Magic = 0x5A4D
};
enum
{
k_Magic = 0x5A4D
};
std::uint16_t e_magic; // Magic number ( k_Magic )
std::uint16_t e_cblp; // Bytes on last page of file
std::uint16_t e_cp; // Pages in file
std::uint16_t e_crlc; // Relocations
std::uint16_t e_cparhdr; // Size of header in paragraphs
std::uint16_t e_minalloc; // Minimum extra paragraphs needed
std::uint16_t e_maxalloc; // Maximum extra paragraphs needed
std::uint16_t e_ss; // Initial (relative) SS value
std::uint16_t e_sp; // Initial SP value
std::uint16_t e_csum; // Checksum
std::uint16_t e_ip; // Initial IP value
std::uint16_t e_cs; // Initial (relative) CS value
std::uint16_t e_lfarlc; // File address of relocation table
std::uint16_t e_ovno; // Overlay number
std::uint16_t e_res[4]; // Reserved words
std::uint16_t e_oemid; // OEM identifier (for e_oeminfo)
std::uint16_t e_oeminfo; // OEM information; e_oemid specific
std::uint16_t e_res2[10]; // Reserved words
std::uint32_t e_lfanew; // File address of new exe header
std::uint16_t e_magic; // Magic number ( k_Magic )
std::uint16_t e_cblp; // Bytes on last page of file
std::uint16_t e_cp; // Pages in file
std::uint16_t e_crlc; // Relocations
std::uint16_t e_cparhdr; // Size of header in paragraphs
std::uint16_t e_minalloc; // Minimum extra paragraphs needed
std::uint16_t e_maxalloc; // Maximum extra paragraphs needed
std::uint16_t e_ss; // Initial (relative) SS value
std::uint16_t e_sp; // Initial SP value
std::uint16_t e_csum; // Checksum
std::uint16_t e_ip; // Initial IP value
std::uint16_t e_cs; // Initial (relative) CS value
std::uint16_t e_lfarlc; // File address of relocation table
std::uint16_t e_ovno; // Overlay number
std::uint16_t e_res[4]; // Reserved words
std::uint16_t e_oemid; // OEM identifier (for e_oeminfo)
std::uint16_t e_oeminfo; // OEM information; e_oemid specific
std::uint16_t e_res2[10]; // Reserved words
std::uint32_t e_lfanew; // File address of new exe header
};
#pragma pack(pop)
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_SIZEOF_SHORT_NAME 8
#ifndef OS_WINDOWS
typedef struct _IMAGE_SECTION_HEADER
{
std::uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
union {
std:: uint32_t PhysicalAddress;
std::uint32_t VirtualSize;
std::uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
union
{
std::uint32_t PhysicalAddress;
std::uint32_t VirtualSize;
} Misc;
std::uint32_t VirtualAddress;
std::uint32_t SizeOfRawData;
std::uint32_t PointerToRawData;
std::uint32_t PointerToRelocations;
std::uint32_t PointerToLinenumbers;
std::uint16_t NumberOfRelocations;
std::uint16_t NumberOfLinenumbers;
std::uint32_t Characteristics;
std::uint32_t VirtualAddress;
std::uint32_t SizeOfRawData;
std::uint32_t PointerToRawData;
std::uint32_t PointerToRelocations;
std::uint32_t PointerToLinenumbers;
std::uint16_t NumberOfRelocations;
std::uint16_t NumberOfLinenumbers;
std::uint32_t Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions;
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
typedef struct _IMAGE_EXPORT_DIRECTORY
{
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions;
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
WORD TypeOffset[1];
typedef struct _IMAGE_BASE_RELOCATION
{
DWORD VirtualAddress;
DWORD SizeOfBlock;
WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
#endif
@@ -285,56 +286,56 @@ typedef struct _IMAGE_BASE_RELOCATION {
template <typename Traits>
struct SECTION_IMAGE_INFORMATION
{
typename Traits::PVOID TransferAddress;
ULONG ZeroBits;
typename Traits::SIZE_T MaximumStackSize;
typename Traits::SIZE_T CommittedStackSize;
ULONG SubSystemType;
typename Traits::PVOID TransferAddress;
ULONG ZeroBits;
typename Traits::SIZE_T MaximumStackSize;
typename Traits::SIZE_T CommittedStackSize;
ULONG SubSystemType;
union
{
struct
{
USHORT SubSystemMinorVersion;
USHORT SubSystemMajorVersion;
};
union
{
struct
{
USHORT SubSystemMinorVersion;
USHORT SubSystemMajorVersion;
};
ULONG SubSystemVersion;
};
ULONG SubSystemVersion;
};
union
{
struct
{
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
};
union
{
struct
{
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
};
ULONG OperatingSystemVersion;
};
ULONG OperatingSystemVersion;
};
USHORT ImageCharacteristics;
USHORT DllCharacteristics;
PEMachineType Machine;
BOOLEAN ImageContainsCode;
USHORT ImageCharacteristics;
USHORT DllCharacteristics;
PEMachineType Machine;
BOOLEAN ImageContainsCode;
union
{
UCHAR ImageFlags;
union
{
UCHAR ImageFlags;
struct
{
UCHAR ComPlusNativeReady : 1;
UCHAR ComPlusILOnly : 1;
UCHAR ImageDynamicallyRelocated : 1;
UCHAR ImageMappedFlat : 1;
UCHAR BaseBelow4gb : 1;
UCHAR ComPlusPrefer32bit : 1;
UCHAR Reserved : 2;
};
};
struct
{
UCHAR ComPlusNativeReady : 1;
UCHAR ComPlusILOnly : 1;
UCHAR ImageDynamicallyRelocated : 1;
UCHAR ImageMappedFlat : 1;
UCHAR BaseBelow4gb : 1;
UCHAR ComPlusPrefer32bit : 1;
UCHAR Reserved : 2;
};
};
ULONG LoaderFlags;
ULONG ImageFileSize;
ULONG CheckSum;
ULONG LoaderFlags;
ULONG ImageFileSize;
ULONG CheckSum;
};

View File

@@ -5,114 +5,114 @@
namespace utils
{
template <typename T, typename S = const uint8_t>
requires(std::is_trivially_copyable_v<T> && std::is_same_v<uint8_t, std::remove_cv_t<S>>)
class safe_object_accessor
{
public:
safe_object_accessor(const std::span<S> buffer, const size_t offset)
: buffer_(buffer)
, offset_(offset)
{
}
template <typename T, typename S = const uint8_t>
requires(std::is_trivially_copyable_v<T> && std::is_same_v<uint8_t, std::remove_cv_t<S>>)
class safe_object_accessor
{
public:
safe_object_accessor(const std::span<S> buffer, const size_t offset)
: buffer_(buffer),
offset_(offset)
{
}
/*****************************************************************************
* Object is copied to make sure platform-dependent alignment requirements
* are respected
****************************************************************************/
/*****************************************************************************
* Object is copied to make sure platform-dependent alignment requirements
* are respected
****************************************************************************/
T get(const size_t element_index = 0) const
{
T value{};
memcpy(&value, get_valid_pointer(element_index), size);
return value;
}
T get(const size_t element_index = 0) const
{
T value{};
memcpy(&value, get_valid_pointer(element_index), size);
return value;
}
void set(const T value, const size_t element_index = 0) const
{
memcpy(get_valid_pointer(element_index), &value, size);
}
void set(const T value, const size_t element_index = 0) const
{
memcpy(get_valid_pointer(element_index), &value, size);
}
private:
static constexpr auto size = sizeof(T);
private:
static constexpr auto size = sizeof(T);
std::span<S> buffer_{};
size_t offset_{};
std::span<S> buffer_{};
size_t offset_{};
S* get_valid_pointer(const size_t element_index) const
{
const auto start_offset = offset_ + (size * element_index);
const auto end_offset = start_offset + size;
if (end_offset > buffer_.size())
{
throw std::runtime_error("Buffer accessor overflow");
}
S* get_valid_pointer(const size_t element_index) const
{
const auto start_offset = offset_ + (size * element_index);
const auto end_offset = start_offset + size;
if (end_offset > buffer_.size())
{
throw std::runtime_error("Buffer accessor overflow");
}
return buffer_.data() + start_offset;
}
};
return buffer_.data() + start_offset;
}
};
template <typename T>
requires(std::is_same_v<uint8_t, std::remove_cv_t<T>>)
class safe_buffer_accessor
{
public:
safe_buffer_accessor(const std::span<T> buffer)
: buffer_(buffer)
{
}
template <typename T>
requires(std::is_same_v<uint8_t, std::remove_cv_t<T>>)
class safe_buffer_accessor
{
public:
safe_buffer_accessor(const std::span<T> buffer)
: buffer_(buffer)
{
}
template <typename S>
safe_buffer_accessor(const safe_buffer_accessor<S>& obj)
: buffer_(obj.get_buffer())
{
}
template <typename S>
safe_buffer_accessor(const safe_buffer_accessor<S>& obj)
: buffer_(obj.get_buffer())
{
}
template <typename S>
safe_object_accessor<S, T> as(const size_t offset) const
{
return {this->buffer_, offset};
}
template <typename S>
safe_object_accessor<S, T> as(const size_t offset) const
{
return {this->buffer_, offset};
}
T* get_pointer_for_range(const size_t offset, const size_t size) const
{
this->validate(offset, size);
return this->buffer_.data() + offset;
}
T* get_pointer_for_range(const size_t offset, const size_t size) const
{
this->validate(offset, size);
return this->buffer_.data() + offset;
}
void validate(const size_t offset, const size_t size) const
{
const auto end = offset + size;
if (end > buffer_.size())
{
throw std::runtime_error("Buffer accessor overflow");
}
}
void validate(const size_t offset, const size_t size) const
{
const auto end = offset + size;
if (end > buffer_.size())
{
throw std::runtime_error("Buffer accessor overflow");
}
}
template <typename S = char>
std::basic_string<S> as_string(const size_t offset) const
{
safe_object_accessor<S> string_accessor{this->buffer_, offset};
std::basic_string<S> result{};
template <typename S = char>
std::basic_string<S> as_string(const size_t offset) const
{
safe_object_accessor<S> string_accessor{this->buffer_, offset};
std::basic_string<S> result{};
while (true)
{
auto value = string_accessor.get(result.size());
if (!value)
{
return result;
}
while (true)
{
auto value = string_accessor.get(result.size());
if (!value)
{
return result;
}
result.push_back(std::move(value));
}
}
result.push_back(std::move(value));
}
}
std::span<T> get_buffer() const
{
return this->buffer_;
}
std::span<T> get_buffer() const
{
return this->buffer_;
}
private:
const std::span<T> buffer_{};
};
private:
const std::span<T> buffer_{};
};
}

View File

@@ -4,54 +4,60 @@
namespace utils::concurrency
{
template <typename T, typename MutexType = std::mutex>
class container
{
public:
template <typename R = void, typename F>
R access(F&& accessor) const
{
std::lock_guard<MutexType> _{mutex_};
return accessor(object_);
}
template <typename T, typename MutexType = std::mutex>
class container
{
public:
template <typename R = void, typename F>
R access(F&& accessor) const
{
std::lock_guard<MutexType> _{mutex_};
return accessor(object_);
}
template <typename R = void, typename F>
R access(F&& accessor)
{
std::lock_guard<MutexType> _{mutex_};
return accessor(object_);
}
template <typename R = void, typename F>
R access(F&& accessor)
{
std::lock_guard<MutexType> _{mutex_};
return accessor(object_);
}
template <typename R = void, typename F>
R access_with_lock(F&& accessor) const
{
std::unique_lock<MutexType> lock{mutex_};
return accessor(object_, lock);
}
template <typename R = void, typename F>
R access_with_lock(F&& accessor) const
{
std::unique_lock<MutexType> lock{mutex_};
return accessor(object_, lock);
}
template <typename R = void, typename F>
R access_with_lock(F&& accessor)
{
std::unique_lock<MutexType> lock{mutex_};
return accessor(object_, lock);
}
template <typename R = void, typename F>
R access_with_lock(F&& accessor)
{
std::unique_lock<MutexType> lock{mutex_};
return accessor(object_, lock);
}
T& get_raw() { return object_; }
const T& get_raw() const { return object_; }
T& get_raw()
{
return object_;
}
const T& get_raw() const
{
return object_;
}
T copy() const
{
std::unique_lock<MutexType> lock{mutex_};
return object_;
}
T copy() const
{
std::unique_lock<MutexType> lock{mutex_};
return object_;
}
std::unique_lock<MutexType> acquire_lock()
{
return std::unique_lock<MutexType>{mutex_};
}
std::unique_lock<MutexType> acquire_lock()
{
return std::unique_lock<MutexType>{mutex_};
}
private:
mutable MutexType mutex_{};
T object_{};
};
private:
mutable MutexType mutex_{};
T object_{};
};
}

View File

@@ -7,19 +7,19 @@
namespace utils
{
struct string_hash
{
using is_transparent = void;
struct string_hash
{
using is_transparent = void;
size_t operator()(const std::string_view str) const
{
constexpr std::hash<std::string_view> hasher{};
return hasher(str);
}
};
size_t operator()(const std::string_view str) const
{
constexpr std::hash<std::string_view> hasher{};
return hasher(str);
}
};
template <typename T>
using unordered_string_map = std::unordered_map<std::string, T, string_hash, std::equal_to<>>;
template <typename T>
using unordered_string_map = std::unordered_map<std::string, T, string_hash, std::equal_to<>>;
using unordered_string_set = std::unordered_set<std::string, string_hash, std::equal_to<>>;
using unordered_string_set = std::unordered_set<std::string, string_hash, std::equal_to<>>;
}

View File

@@ -5,91 +5,91 @@
namespace utils
{
class file_handle
{
public:
file_handle() = default;
class file_handle
{
public:
file_handle() = default;
file_handle(FILE* file)
: file_(file)
{
}
file_handle(FILE* file)
: file_(file)
{
}
~file_handle()
{
this->release();
}
~file_handle()
{
this->release();
}
file_handle(const file_handle&) = delete;
file_handle& operator=(const file_handle&) = delete;
file_handle(const file_handle&) = delete;
file_handle& operator=(const file_handle&) = delete;
file_handle(file_handle&& obj) noexcept
: file_handle()
{
this->operator=(std::move(obj));
}
file_handle(file_handle&& obj) noexcept
: file_handle()
{
this->operator=(std::move(obj));
}
file_handle& operator=(file_handle&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->file_ = obj.file_;
obj.file_ = {};
}
file_handle& operator=(file_handle&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->file_ = obj.file_;
obj.file_ = {};
}
return *this;
}
return *this;
}
file_handle& operator=(FILE* file) noexcept
{
this->release();
this->file_ = file;
file_handle& operator=(FILE* file) noexcept
{
this->release();
this->file_ = file;
return *this;
}
return *this;
}
[[nodiscard]] operator bool() const
{
return this->file_;
}
[[nodiscard]] operator bool() const
{
return this->file_;
}
[[nodiscard]] operator FILE*() const
{
return this->file_;
}
[[nodiscard]] operator FILE*() const
{
return this->file_;
}
[[nodiscard]] int64_t size() const
{
const auto current_position = this->tell();
[[nodiscard]] int64_t size() const
{
const auto current_position = this->tell();
this->seek_to(0, SEEK_END);
const auto size = this->tell();
this->seek_to(current_position);
this->seek_to(0, SEEK_END);
const auto size = this->tell();
this->seek_to(current_position);
return size;
}
return size;
}
bool seek_to(const int64_t position, const int origin = SEEK_SET) const
{
return _fseeki64(this->file_, position, origin) == 0;
}
bool seek_to(const int64_t position, const int origin = SEEK_SET) const
{
return _fseeki64(this->file_, position, origin) == 0;
}
[[nodiscard]] int64_t tell() const
{
return _ftelli64(this->file_);
}
[[nodiscard]] int64_t tell() const
{
return _ftelli64(this->file_);
}
private:
FILE* file_{};
private:
FILE* file_{};
void release()
{
if (this->file_)
{
(void)fclose(this->file_);
this->file_ = {};
}
}
};
void release()
{
if (this->file_)
{
(void)fclose(this->file_);
this->file_ = {};
}
}
};
}

View File

@@ -4,52 +4,53 @@
namespace utils
{
/*
* Copied from here: https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57
*/
/*
* Copied from here:
* https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57
*/
template <class F>
class final_action
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
template <class F>
class final_action
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value && !std::is_volatile<F>::value,
"Final_action should store its callable by value");
explicit final_action(F f) noexcept : f_(std::move(f))
{
}
explicit final_action(F f) noexcept
: f_(std::move(f))
{
}
final_action(final_action&& other) noexcept
: f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
{
}
final_action(final_action&& other) noexcept
: f_(std::move(other.f_)),
invoke_(std::exchange(other.invoke_, false))
{
}
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
~final_action() noexcept
{
if (invoke_) f_();
}
~final_action() noexcept
{
if (invoke_)
f_();
}
// Added by momo5502
void cancel()
{
invoke_ = false;
}
// Added by momo5502
void cancel()
{
invoke_ = false;
}
private:
F f_;
bool invoke_{true};
};
private:
F f_;
bool invoke_{true};
};
template <class F>
final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
finally(F&& f) noexcept
{
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
}
template <class F>
final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type> finally(F&& f) noexcept
{
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(std::forward<F>(f));
}
}

View File

@@ -4,121 +4,123 @@
namespace utils::io
{
bool remove_file(const std::filesystem::path& file)
{
std::error_code ec{};
return std::filesystem::remove(file, ec) && !ec;
}
bool remove_file(const std::filesystem::path& file)
{
std::error_code ec{};
return std::filesystem::remove(file, ec) && !ec;
}
bool move_file(const std::filesystem::path& src, const std::filesystem::path& target)
{
copy_folder(src, target);
return remove_file(src);
}
bool move_file(const std::filesystem::path& src, const std::filesystem::path& target)
{
copy_folder(src, target);
return remove_file(src);
}
bool file_exists(const std::filesystem::path& file)
{
return std::ifstream(file).good();
}
bool file_exists(const std::filesystem::path& file)
{
return std::ifstream(file).good();
}
bool write_file(const std::filesystem::path& file, const std::vector<uint8_t>& data, const bool append)
{
if (file.has_parent_path())
{
io::create_directory(file.parent_path());
}
bool write_file(const std::filesystem::path& file, const std::vector<uint8_t>& data, const bool append)
{
if (file.has_parent_path())
{
io::create_directory(file.parent_path());
}
std::ofstream stream(
file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : std::ofstream::out));
std::ofstream stream(file, std::ios::binary | std::ofstream::out |
(append ? std::ofstream::app : std::ofstream::out));
if (stream.is_open())
{
stream.write(reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
stream.close();
return true;
}
if (stream.is_open())
{
stream.write(reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
stream.close();
return true;
}
return false;
}
return false;
}
std::vector<uint8_t> read_file(const std::filesystem::path& file)
{
std::vector<uint8_t> data;
read_file(file, &data);
return data;
}
std::vector<uint8_t> read_file(const std::filesystem::path& file)
{
std::vector<uint8_t> data;
read_file(file, &data);
return data;
}
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data)
{
if (!data) return false;
data->clear();
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data)
{
if (!data)
return false;
data->clear();
std::ifstream stream(file, std::ios::binary);
if (!stream) return false;
std::ifstream stream(file, std::ios::binary);
if (!stream)
return false;
*data = std::vector<uint8_t>{(std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>()};
return true;
}
*data = std::vector<uint8_t>{(std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>()};
return true;
}
std::size_t file_size(const std::filesystem::path& file)
{
std::ifstream stream(file, std::ios::binary);
std::size_t file_size(const std::filesystem::path& file)
{
std::ifstream stream(file, std::ios::binary);
if (stream)
{
stream.seekg(0, std::ios::end);
return static_cast<std::size_t>(stream.tellg());
}
if (stream)
{
stream.seekg(0, std::ios::end);
return static_cast<std::size_t>(stream.tellg());
}
return 0;
}
return 0;
}
bool create_directory(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::create_directories(directory, ec) && !ec;
}
bool create_directory(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::create_directories(directory, ec) && !ec;
}
bool directory_exists(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::is_directory(directory, ec) && !ec;
}
bool directory_exists(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::is_directory(directory, ec) && !ec;
}
bool directory_is_empty(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::is_empty(directory, ec) && !ec;
}
bool directory_is_empty(const std::filesystem::path& directory)
{
std::error_code ec{};
return std::filesystem::is_empty(directory, ec) && !ec;
}
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target)
{
std::error_code ec{};
std::filesystem::copy(src, target,
std::filesystem::copy_options::overwrite_existing |
std::filesystem::copy_options::recursive, ec);
}
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target)
{
std::error_code ec{};
std::filesystem::copy(
src, target, std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive,
ec);
}
std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, const bool recursive)
{
std::error_code code{};
std::vector<std::filesystem::path> files;
std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, const bool recursive)
{
std::error_code code{};
std::vector<std::filesystem::path> files;
if (recursive)
{
for (auto& file : std::filesystem::recursive_directory_iterator(directory, code))
{
files.push_back(file.path());
}
}
else
{
for (auto& file : std::filesystem::directory_iterator(directory, code))
{
files.push_back(file.path());
}
}
if (recursive)
{
for (auto& file : std::filesystem::recursive_directory_iterator(directory, code))
{
files.push_back(file.path());
}
}
else
{
for (auto& file : std::filesystem::directory_iterator(directory, code))
{
files.push_back(file.path());
}
}
return files;
}
return files;
}
}

View File

@@ -6,17 +6,17 @@
namespace utils::io
{
bool remove_file(const std::filesystem::path& file);
bool move_file(const std::filesystem::path& src, const std::filesystem::path& target);
bool file_exists(const std::filesystem::path& file);
bool write_file(const std::filesystem::path& file, const std::vector<uint8_t>& data, bool append = false);
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data);
std::vector<uint8_t> read_file(const std::filesystem::path& file);
size_t file_size(const std::filesystem::path& file);
bool create_directory(const std::filesystem::path& directory);
bool directory_exists(const std::filesystem::path& directory);
bool directory_is_empty(const std::filesystem::path& directory);
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target);
bool remove_file(const std::filesystem::path& file);
bool move_file(const std::filesystem::path& src, const std::filesystem::path& target);
bool file_exists(const std::filesystem::path& file);
bool write_file(const std::filesystem::path& file, const std::vector<uint8_t>& data, bool append = false);
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data);
std::vector<uint8_t> read_file(const std::filesystem::path& file);
size_t file_size(const std::filesystem::path& file);
bool create_directory(const std::filesystem::path& directory);
bool directory_exists(const std::filesystem::path& directory);
bool directory_is_empty(const std::filesystem::path& directory);
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target);
std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, bool recursive = false);
std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, bool recursive = false);
}

View File

@@ -10,80 +10,80 @@
namespace utils::nt
{
using HandleFunction = HANDLE();
using HandleFunction = HANDLE();
inline HANDLE null_handle()
{
return nullptr;
}
inline HANDLE null_handle()
{
return nullptr;
}
inline HANDLE invalid_handle()
{
return INVALID_HANDLE_VALUE;
}
inline HANDLE invalid_handle()
{
return INVALID_HANDLE_VALUE;
}
template <HandleFunction InvalidHandleFunction = null_handle>
class handle
{
public:
handle() = default;
template <HandleFunction InvalidHandleFunction = null_handle>
class handle
{
public:
handle() = default;
handle(const HANDLE h)
: handle_(h)
{
}
handle(const HANDLE h)
: handle_(h)
{
}
~handle()
{
if (*this)
{
CloseHandle(this->handle_);
this->handle_ = InvalidHandleFunction();
}
}
~handle()
{
if (*this)
{
CloseHandle(this->handle_);
this->handle_ = InvalidHandleFunction();
}
}
handle(const handle&) = delete;
handle& operator=(const handle&) = delete;
handle(const handle&) = delete;
handle& operator=(const handle&) = delete;
handle(handle&& obj) noexcept
: handle()
{
this->operator=(std::move(obj));
}
handle(handle&& obj) noexcept
: handle()
{
this->operator=(std::move(obj));
}
handle& operator=(handle&& obj) noexcept
{
if (this != &obj)
{
this->~handle();
this->handle_ = obj.handle_;
obj.handle_ = InvalidHandleFunction();
}
handle& operator=(handle&& obj) noexcept
{
if (this != &obj)
{
this->~handle();
this->handle_ = obj.handle_;
obj.handle_ = InvalidHandleFunction();
}
return *this;
}
return *this;
}
handle& operator=(HANDLE h) noexcept
{
this->~handle();
this->handle_ = h;
handle& operator=(HANDLE h) noexcept
{
this->~handle();
this->handle_ = h;
return *this;
}
return *this;
}
[[nodiscard]] operator bool() const
{
return this->handle_ != InvalidHandleFunction();
}
[[nodiscard]] operator bool() const
{
return this->handle_ != InvalidHandleFunction();
}
[[nodiscard]] operator HANDLE() const
{
return this->handle_;
}
[[nodiscard]] operator HANDLE() const
{
return this->handle_;
}
private:
HANDLE handle_{InvalidHandleFunction()};
};
private:
HANDLE handle_{InvalidHandleFunction()};
};
}
#endif

View File

@@ -6,45 +6,42 @@
namespace utils::string
{
inline char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
}
inline char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
}
inline char16_t char_to_lower(const char16_t val)
{
if (val >= u'A' && val <= u'Z')
{
return val + 32;
}
inline char16_t char_to_lower(const char16_t val)
{
if (val >= u'A' && val <= u'Z')
{
return val + 32;
}
return val;
}
return val;
}
inline wchar_t char_to_lower(const wchar_t val)
{
return std::towlower(val);
}
inline wchar_t char_to_lower(const wchar_t val)
{
return std::towlower(val);
}
template <class Elem, class Traits, class Alloc>
void to_lower_inplace(std::basic_string<Elem, Traits, Alloc>& str)
{
std::ranges::transform(str, str.begin(), [](const Elem e)
{
return char_to_lower(e);
});
}
template <class Elem, class Traits, class Alloc>
void to_lower_inplace(std::basic_string<Elem, Traits, Alloc>& str)
{
std::ranges::transform(str, str.begin(), [](const Elem e) { return char_to_lower(e); });
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower(std::basic_string<Elem, Traits, Alloc> str)
{
to_lower_inplace(str);
return str;
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower(std::basic_string<Elem, Traits, Alloc> str)
{
to_lower_inplace(str);
return str;
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower_consume(std::basic_string<Elem, Traits, Alloc>& str)
{
return to_lower(std::move(str));
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower_consume(std::basic_string<Elem, Traits, Alloc>& str)
{
return to_lower(std::move(str));
}
}

View File

@@ -4,23 +4,23 @@
namespace utils
{
template <typename Clock = std::chrono::high_resolution_clock>
class timer
{
public:
void update()
{
this->point_ = Clock::now();
}
template <typename Clock = std::chrono::high_resolution_clock>
class timer
{
public:
void update()
{
this->point_ = Clock::now();
}
bool has_elapsed(typename Clock::duration duration) const
{
const auto now = Clock::now();
const auto diff = now - this->point_;
return diff > duration;
}
bool has_elapsed(typename Clock::duration duration) const
{
const auto now = Clock::now();
const auto diff = now - this->point_;
return diff > duration;
}
private:
typename Clock::time_point point_{Clock::now()};
};
private:
typename Clock::time_point point_{Clock::now()};
};
}