aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorAlexander Karatarakis <alkarata@microsoft.com>2018-04-05 17:03:45 -0700
committerAlexander Karatarakis <alkarata@microsoft.com>2018-04-06 17:24:46 -0700
commitc1257f988a49b167cd9d94a0931806c6e465700a (patch)
tree591741e69ae5781394a3e0ae2ffa507cd3a615de /toolsrc/src
parente71230855443a0b87c38e011531cfc6b9d6ffce5 (diff)
downloadvcpkg-c1257f988a49b167cd9d94a0931806c6e465700a.tar.gz
vcpkg-c1257f988a49b167cd9d94a0931806c6e465700a.zip
[vcpkg hash] Refactor to reduce code duplication
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/vcpkg/commands.hash.cpp149
1 files changed, 78 insertions, 71 deletions
diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp
index 856b0e283..c0130f12f 100644
--- a/toolsrc/src/vcpkg/commands.hash.cpp
+++ b/toolsrc/src/vcpkg/commands.hash.cpp
@@ -18,7 +18,7 @@ namespace vcpkg::Commands::Hash
{
namespace
{
- static std::string to_hex(const unsigned char* string, const size_t bytes)
+ std::string to_hex(const unsigned char* string, const size_t bytes)
{
static constexpr char HEX_MAP[] = "0123456789abcdef";
@@ -58,86 +58,93 @@ namespace vcpkg::Commands::Hash
if (handle) BCryptDestroyHash(handle);
}
};
- }
- std::string get_file_hash(const fs::path& path, const std::string& hash_type)
- {
- BCryptAlgorithmHandle algorithm_handle;
-
- NTSTATUS error_code = BCryptOpenAlgorithmProvider(
- &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider");
-
- DWORD hash_buffer_bytes;
- DWORD cb_data;
- error_code = BCryptGetProperty(algorithm_handle.handle,
- BCRYPT_HASH_LENGTH,
- reinterpret_cast<PUCHAR>(&hash_buffer_bytes),
- sizeof(DWORD),
- &cb_data,
- 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length");
- const ULONG length_in_bytes = hash_buffer_bytes;
-
- BCryptHashHandle hash_handle;
-
- error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher");
-
- FILE* file = nullptr;
- const auto ec = _wfopen_s(&file, path.c_str(), L"rb");
- Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string());
- unsigned char buffer[4096];
- while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file))
+ struct BCryptHasher
{
- error_code = BCryptHashData(hash_handle.handle, buffer, static_cast<ULONG>(actual_size), 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data");
- }
-
- fclose(file);
-
- std::unique_ptr<unsigned char[]> hash_buffer = std::make_unique<UCHAR[]>(length_in_bytes);
-
- error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash");
-
- return to_hex(hash_buffer.get(), length_in_bytes);
- }
-
- std::string get_string_hash(const std::string& s, const std::string& hash_type)
- {
- BCryptAlgorithmHandle algorithm_handle;
+ explicit BCryptHasher(const std::string& hash_type)
+ {
+ NTSTATUS error_code =
+ BCryptOpenAlgorithmProvider(&this->algorithm_handle.handle,
+ Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(),
+ nullptr,
+ 0);
+ Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider");
+
+ DWORD hash_buffer_bytes;
+ DWORD cb_data;
+ error_code = BCryptGetProperty(this->algorithm_handle.handle,
+ BCRYPT_HASH_LENGTH,
+ reinterpret_cast<PUCHAR>(&hash_buffer_bytes),
+ sizeof(DWORD),
+ &cb_data,
+ 0);
+ Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length");
+ this->length_in_bytes = hash_buffer_bytes;
+ }
- NTSTATUS error_code = BCryptOpenAlgorithmProvider(
- &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider");
+ std::string hash_file(const fs::path& path) const
+ {
+ BCryptHashHandle hash_handle;
+ this->initialize_hash_handle(hash_handle);
+
+ FILE* file = nullptr;
+ const auto ec = _wfopen_s(&file, path.c_str(), L"rb");
+ Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string());
+ unsigned char buffer[4096];
+ while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file))
+ {
+ hash_data(hash_handle, buffer, actual_size);
+ }
+ fclose(file);
+
+ return this->finalize_hash_handle(hash_handle);
+ }
- DWORD hash_buffer_bytes;
- DWORD cb_data;
- error_code = BCryptGetProperty(algorithm_handle.handle,
- BCRYPT_HASH_LENGTH,
- reinterpret_cast<PUCHAR>(&hash_buffer_bytes),
- sizeof(DWORD),
- &cb_data,
- 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length");
- const ULONG length_in_bytes = hash_buffer_bytes;
+ std::string hash_string(const std::string& s) const
+ {
+ BCryptHashHandle hash_handle;
+ this->initialize_hash_handle(hash_handle);
+ hash_data(hash_handle, reinterpret_cast<unsigned char*>(const_cast<char*>(s.c_str())), s.size());
+ return this->finalize_hash_handle(hash_handle);
+ }
- BCryptHashHandle hash_handle;
+ private:
+ void initialize_hash_handle(BCryptHashHandle& hash_handle) const
+ {
+ const NTSTATUS error_code =
+ BCryptCreateHash(this->algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0);
+ Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher");
+ }
- error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher");
+ void hash_data(BCryptHashHandle& hash_handle, unsigned char* buffer, const size_t& data_size) const
+ {
+ const NTSTATUS error_code =
+ BCryptHashData(hash_handle.handle, buffer, static_cast<ULONG>(data_size), 0);
+ Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data");
+ }
- auto* const buffer = reinterpret_cast<unsigned char*>(const_cast<char*>(s.c_str()));
- error_code = BCryptHashData(hash_handle.handle, buffer, static_cast<ULONG>(s.size()), 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data");
+ std::string finalize_hash_handle(const BCryptHashHandle& hash_handle) const
+ {
+ std::unique_ptr<unsigned char[]> hash_buffer = std::make_unique<UCHAR[]>(this->length_in_bytes);
+ const NTSTATUS error_code =
+ BCryptFinishHash(hash_handle.handle, hash_buffer.get(), this->length_in_bytes, 0);
+ Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash");
+ return to_hex(hash_buffer.get(), this->length_in_bytes);
+ }
- std::unique_ptr<unsigned char[]> hash_buffer = std::make_unique<UCHAR[]>(length_in_bytes);
+ BCryptAlgorithmHandle algorithm_handle;
+ ULONG length_in_bytes;
+ };
+ }
- error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0);
- Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash");
+ std::string get_file_hash(const fs::path& path, const std::string& hash_type)
+ {
+ return BCryptHasher{hash_type}.hash_file(path);
+ }
- return to_hex(hash_buffer.get(), length_in_bytes);
+ std::string get_string_hash(const std::string& s, const std::string& hash_type)
+ {
+ return BCryptHasher{hash_type}.hash_string(s);
}
}