| 21 | constexpr size_t FILE_BUFFER_SIZE = 8 * 1024 * 1024; // 8 MiB |
| 22 | |
| 23 | struct BCryptContext |
| 24 | { |
| 25 | wil::unique_bcrypt_algorithm hAlg; |
| 26 | wil::unique_bcrypt_hash hHash; |
| 27 | |
| 28 | std::unique_ptr<uint8_t[]> hashObject; |
| 29 | DWORD hashObjectLength = 0; |
| 30 | std::unique_ptr<uint8_t[]> hash; |
| 31 | DWORD hashLength = 0; |
| 32 | |
| 33 | wil::unique_virtualalloc_ptr<uint8_t> fileBuffer; |
| 34 | |
| 35 | BCryptContext() |
| 36 | { |
| 37 | fileBuffer.reset( |
| 38 | static_cast<uint8_t*>( |
| 39 | THROW_LAST_ERROR_IF_NULL(VirtualAlloc( |
| 40 | nullptr, |
| 41 | FILE_BUFFER_SIZE, |
| 42 | MEM_COMMIT | MEM_RESERVE, |
| 43 | PAGE_READWRITE)))); |
| 44 | |
| 45 | THROW_IF_NTSTATUS_FAILED(BCryptOpenAlgorithmProvider( |
| 46 | hAlg.put(), |
| 47 | BCRYPT_SHA1_ALGORITHM, |
| 48 | nullptr, |
| 49 | BCRYPT_HASH_REUSABLE_FLAG |
| 50 | )); |
| 51 | |
| 52 | ULONG result = 0; |
| 53 | |
| 54 | THROW_IF_NTSTATUS_FAILED(BCryptGetProperty( |
| 55 | hAlg.get(), |
| 56 | BCRYPT_OBJECT_LENGTH, |
| 57 | reinterpret_cast<PUCHAR>(&hashObjectLength), |
| 58 | sizeof(hashObjectLength), |
| 59 | &result, 0 |
| 60 | )); |
| 61 | hashObject = std::make_unique<uint8_t[]>(hashObjectLength); |
| 62 | |
| 63 | THROW_IF_NTSTATUS_FAILED(BCryptGetProperty( |
| 64 | hAlg.get(), |
| 65 | BCRYPT_HASH_LENGTH, |
| 66 | reinterpret_cast<PUCHAR>(&hashLength), |
| 67 | sizeof(hashLength), |
| 68 | &result, 0 |
| 69 | )); |
| 70 | hash = std::make_unique<uint8_t[]>(hashLength); |
| 71 | |
| 72 | THROW_IF_NTSTATUS_FAILED(BCryptCreateHash( |
| 73 | hAlg.get(), |
| 74 | hHash.put(), |
| 75 | hashObject.get(), |
| 76 | hashObjectLength, |
| 77 | nullptr, |
| 78 | 0, |
| 79 | BCRYPT_HASH_REUSABLE_FLAG |
| 80 | )); |
nothing calls this directly
no outgoing calls
no test coverage detected