From 0e34f07e13eae93c3cfa37afe56591fc7c52b7b4 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Mon, 26 Oct 2026 22:52:17 +0000 Subject: [PATCH] Decompile 10 functions in Source/Utility/CRC32.cpp, Source/Utility/CRC32.h Batch #850 by ragnarok-clanker: 0 byte-identical, 10 confirmed by peer review. - fn_00142 CRC32::CRC32: logic confirmed by peer review - fn_00143 CRC32::~CRC32: logic confirmed by peer review - fn_00144 CRC32::Update: logic confirmed by peer review - fn_00145 CRC32::UpdateFile: logic confirmed by peer review - fn_00146 CRC32::Calculate: logic confirmed by peer review - fn_00147 CRC32::Calculate: logic confirmed by peer review - fn_00148 CRC32::CalculateLowercase: logic confirmed by peer review - fn_00149 CRC32::CalculateLowercase: logic confirmed by peer review - fn_00150 CRC32::Calculate: logic confirmed by peer review - fn_00151 CRC32::CalculateFile: logic confirmed by peer review Reviewed-by: ragnarok-clanker Adds to the build: Source/Utility/CRC32.cpp --- Source/Utility/CRC32.cpp | 158 +++++++++++++++++++++++++++++++++++++++ Source/Utility/CRC32.h | 36 +++++++++ compile.json | 1 + 3 files changed, 195 insertions(+) create mode 100644 Source/Utility/CRC32.cpp create mode 100644 Source/Utility/CRC32.h diff --git a/Source/Utility/CRC32.cpp b/Source/Utility/CRC32.cpp new file mode 100644 index 0000000..a395237 --- /dev/null +++ b/Source/Utility/CRC32.cpp @@ -0,0 +1,158 @@ +#include "Utility/CRC32.h" + +#include +#include + +// FUNCTION: fn_00142 +CRC32::CRC32() { + for (int i = 0; i < 256; ++i) { + DWORD value = i; + for (int bit = 0; bit < 8; ++bit) { + if (value & 1) { + value = (value >> 1) ^ 0xEDB88320; + } else { + value >>= 1; + } + } + m_table[i] = value; + } +} + +// FUNCTION: fn_00143 +CRC32::~CRC32() { +} + +// FUNCTION: fn_00144 +bool CRC32::Update(const BYTE* data, int length, DWORD* checksum) { + if (data == nullptr) { + m_error = InvalidArgument; + return false; + } + + const BYTE* end = data + length; + while (data < end) { + *checksum = m_table[static_cast(*checksum) ^ *data++] ^ (*checksum >> 8); + } + return true; +} + +// FUNCTION: fn_00145 +bool CRC32::UpdateFile(const WCHAR* filename, LONG offset, DWORD length, DWORD* checksum) { + BYTE buffer[65536]; + DWORD bytesRead; + + if (filename == nullptr || *filename == 0) { + m_error = InvalidArgument; + return false; + } + + HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (file == INVALID_HANDLE_VALUE) { + m_error = FileOpenFailed; + return false; + } + + if (SetFilePointer(file, offset, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { + m_error = FileSeekFailed; + CloseHandle(file); + return false; + } + + BOOL readResult = ReadFile(file, buffer, 0xFFFF, &bytesRead, nullptr); + while (readResult && bytesRead != 0) { + DWORD chunkLength; + if (length > bytesRead) { + chunkLength = bytesRead; + length -= bytesRead; + } else { + chunkLength = length; + length = 0; + } + Update(buffer, chunkLength, checksum); + if (length == 0) { + break; + } + readResult = ReadFile(file, buffer, 0xFFFF, &bytesRead, nullptr); + } + + if (!readResult) { + m_error = FileReadFailed; + } + CloseHandle(file); + return true; +} + +// FUNCTION: fn_00146 +DWORD CRC32::Calculate(const char* text) { + DWORD checksum = 0xFFFFFFFF; + Update(reinterpret_cast(text), std::strlen(text), &checksum); + return ~checksum; +} + +// FUNCTION: fn_00147 +DWORD CRC32::Calculate(const WCHAR* text) { + char converted[MAX_PATH]; + WideCharToMultiByte(CP_ACP, 0, text, -1, converted, MAX_PATH, nullptr, nullptr); + DWORD checksum = 0xFFFFFFFF; + Update(reinterpret_cast(converted), std::strlen(converted), &checksum); + return ~checksum; +} + +// FUNCTION: fn_00148 +DWORD CRC32::CalculateLowercase(const char* text) { + char lowercase[MAX_PATH]; + strcpy_s(lowercase, MAX_PATH, text); + _strlwr_s(lowercase, MAX_PATH); + DWORD checksum = 0xFFFFFFFF; + Update(reinterpret_cast(lowercase), std::strlen(lowercase), &checksum); + return ~checksum; +} + +// FUNCTION: fn_00149 +DWORD CRC32::CalculateLowercase(const WCHAR* text) { + WCHAR lowercase[MAX_PATH]; + wcscpy_s(lowercase, MAX_PATH, text); + _wcslwr_s(lowercase, MAX_PATH); + return Calculate(lowercase); +} + +// FUNCTION: fn_00150 +bool CRC32::Calculate(const BYTE* data, int length, DWORD* checksum) { + *checksum = 0xFFFFFFFF; + Update(data, length, checksum); + *checksum = ~*checksum; + return true; +} + +// FUNCTION: fn_00151 +bool CRC32::CalculateFile(const WCHAR* filename, DWORD* checksum) { + if (filename == nullptr || *filename == 0) { + m_error = InvalidArgument; + return false; + } + + HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (file == INVALID_HANDLE_VALUE) { + m_error = FileOpenFailed; + return false; + } + + LARGE_INTEGER fileSize; + if (GetFileSizeEx(file, &fileSize)) { + if (fileSize.QuadPart > 500000000) { + fileSize.QuadPart = 500000000; + } + + HANDLE mapping = CreateFileMappingW(file, nullptr, PAGE_READONLY, fileSize.HighPart, fileSize.LowPart, nullptr); + if (mapping != nullptr) { + const BYTE* data = static_cast(MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, fileSize.LowPart)); + if (data != nullptr) { + Calculate(data, fileSize.LowPart, checksum); + UnmapViewOfFile(data); + } + CloseHandle(mapping); + } + CloseHandle(file); + } + return true; +} diff --git a/Source/Utility/CRC32.h b/Source/Utility/CRC32.h new file mode 100644 index 0000000..b144771 --- /dev/null +++ b/Source/Utility/CRC32.h @@ -0,0 +1,36 @@ +#ifndef RAGNAROK_SOURCE_UTILITY_CRC32_H +#define RAGNAROK_SOURCE_UTILITY_CRC32_H + +#include +#include + +class CRC32 { +public: + enum Error : DWORD { + InvalidArgument = 1, + FileOpenFailed = 2, + FileReadFailed = 3, + FileSeekFailed = 4 + }; + + /* 0000 */ DWORD m_table[256]; + /* 0400 */ DWORD m_error; + + CRC32(); + ~CRC32(); + + bool Update(const BYTE* data, int length, DWORD* checksum); + bool UpdateFile(const WCHAR* filename, LONG offset, DWORD length, DWORD* checksum); + DWORD Calculate(const char* text); + DWORD Calculate(const WCHAR* text); + DWORD CalculateLowercase(const char* text); + DWORD CalculateLowercase(const WCHAR* text); + bool Calculate(const BYTE* data, int length, DWORD* checksum); + bool CalculateFile(const WCHAR* filename, DWORD* checksum); +}; + +static_assert(offsetof(CRC32, m_table) == 0x0000); +static_assert(offsetof(CRC32, m_error) == 0x0400); +static_assert(sizeof(CRC32) == 0x0404); + +#endif diff --git a/compile.json b/compile.json index ba49d2e..f45da82 100644 --- a/compile.json +++ b/compile.json @@ -586,6 +586,7 @@ "Source/Utility/Async/NMessageQueue.cpp": 0, "Source/Utility/Async/NObject.cpp": 0, "Source/Utility/Async/NRecycleObjectPoolMgr.cpp": 0, + "Source/Utility/CRC32.cpp": 0, "Source/Utility/Cipher/Rijndael.cpp": 0, "Source/Utility/Cipher/XorBytes.cpp": 0, "Source/Utility/GuidParse.cpp": 0,