SHA-256 Checksums
sha256.c / sha256.h provide a pure C, streaming SHA-256 implementation
conforming to FIPS 180-4. The module is used for post-capture integrity
verification and for the hash / verify CLI commands.
Design Constraints
- Pure C89, no C++ and no MFC dependency – the file must be compiled
without the precompiled header (
StdAfx.h). - No heap allocation: the
SHA256_CTXcontext is caller-allocated. - Compatible with both MSVC 6.0 and MSVC 2017+.
- All symbols are wrapped in
extern "C"to allow calling from C++ files.
SHA256_CTX Structure
typedef struct {
unsigned char data[64]; /* current 64-byte input block */
unsigned int datalen; /* number of bytes in current block */
unsigned int bitlen[2]; /* total message length in bits (64-bit as two 32-bit) */
unsigned int state[8]; /* running hash state (H0..H7) */
} SHA256_CTX;
The context is designed to be stack-allocated or embedded as a member variable. No dynamic memory is used.
API
void sha256_init (SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const unsigned char *data,
unsigned int len);
void sha256_final (SHA256_CTX *ctx, unsigned char hash[32]);
void sha256_hex (const unsigned char hash[32], char out[65]);
| Function | Description |
|---|---|
sha256_init |
Initialize context. Must be called before first update. |
sha256_update |
Feed data into the hash. Can be called multiple times with arbitrary-sized chunks. |
sha256_final |
Finalize and write the 32-byte (256-bit) hash. |
sha256_hex |
Format a 32-byte hash as 64 lowercase hex characters + NUL terminator. |
The typical usage pattern is to stream file data in 64 KB blocks via
repeated sha256_update() calls.
Post-capture Integration
After every successful capture file is finalized,
CDV::CapturingThread() calls ComputeFileSHA256() (in DShow.cpp)
to hash the completed AVI file.
ComputeFileSHA256() reads the file in 64 KB blocks and feeds them
through the streaming SHA-256 API.
On success it calls WriteSHA256Sidecar() to write a
sha256sum-compatible sidecar file (.sha256) next to the AVI:
<64-hex-hash> *<bare-filename>
The computed hash is also stored in CaptureStats::szSHA256 and written
to the CSV capture log.
SHA-256 computation is controlled by CDV::m_enableSHA256 (default:
true), toggled via the IDC_CHK_SHA256 checkbox in the Capture Config
dialog (IDD_CAPTURE_CONFIG).
Build System Integration
CMake
The CMake project file declares LANGUAGES C CXX to support sha256.c:
project(WinDV VERSION 1.6.0 LANGUAGES C CXX)
sha256.c is explicitly excluded from the precompiled header:
set_source_files_properties(sha256.c PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
VC6
In the VC6 .dsp file, sha256.c has the /Y- flag
(# SUBTRACT CPP /YX /Yc /Yu) to disable precompiled header processing.
CLI Commands
The hash and verify CLI commands expose the same functionality for
off-line use:
hash
WinDV hash [-q] <file> [file2 ...]
For each file, ComputeFileSHA256() hashes the file and prints
<hash> <filename> to stdout in sha256sum format.
Unless -q (quiet) is given, a .sha256 sidecar file is written next
to each input file.
Exit code: 0 if all files were hashed successfully, non-zero if any file could not be read.
verify
WinDV verify <file> [file2 ...]
For each file, VerifyFileSHA256() reads the .sha256 sidecar, hashes
the file, and compares the results.
Prints OK or FAILED per file.
Return codes per file (accumulated into the process exit code):
| Code | Meaning |
|---|---|
| 0 | Hash matches |
| 1 | Hash mismatch |
| 2 | Sidecar not found or unreadable |
Sidecar File Format
The .sha256 sidecar file uses the standard sha256sum format:
a1b2c3d4... *filename.avi
- 64 lowercase hexadecimal characters (the SHA-256 hash)
- Two spaces
-
*prefix (binary mode indicator, persha256sumconvention) - Bare filename (no path components)
This format is compatible with the sha256sum -c verification command
available on Linux/macOS and via Git for Windows.