Windows MinGW build and raw-device support
August 9, 2026 ยท View on GitHub
CI-built Windows executable
The supported Windows executable is a CI artifact built by
.github/workflows/mingw.yml, not by a
native Windows developer build or an installer. The workflow runs on pushes to
main, manually dispatched runs, and relevant non-draft pull requests;
documentation-only pull requests are excluded.
On Ubuntu 24.04, the workflow installs the x86_64 MinGW-w64 POSIX toolchain, checks out a pinned vcpkg revision, builds static Expat, RE2, and Abseil, and builds a checksum-pinned static libewf release. It then configures an out-of-tree cross-build with:
bash bootstrap.sh
mkdir build-mingw && cd build-mingw
target_root="$VCPKG_ROOT/installed/x64-mingw-static"
PKG_CONFIG="pkg-config --static" \
PKG_CONFIG_LIBDIR="$target_root/lib/pkgconfig" \
CPPFLAGS="-I$target_root/include" \
LDFLAGS="-L$target_root/lib" \
../configure --host=x86_64-w64-mingw32 --quiet
grep -q '^#define HAVE_LIBEWF 1' config.h
make -j2 LDFLAGS="-L$target_root/lib -all-static"
The resulting PE executable is copied to bulk_extractor64.exe and uploaded
as the bulk_extractor-windows-x86_64 artifact. The workflow verifies that it
is a PE32+ executable larger than 1 MiB and imports only Windows system DLLs;
it rejects MinGW, RE2, Abseil, Expat, zlib, and GNU crypto runtime DLLs.
A Windows runner downloads that exact artifact and verifies that it can:
- recursively scan a directory containing a Unicode filename;
- scan the checked-in E01 fixture and create its report;
- scan the checked-in IP fixture and report its expected IPv4 address; and
- scan an attached disposable FAT32 VHD as a raw drive-letter volume and recover a known email address.
The artifact includes static libewf support but is not signed and is not a release installer. Keep the import check and Windows runtime tests in the same pull request as any Windows-build change.
Raw-device input
The Windows executable accepts these raw-device input forms:
C:as a shorthand for\\.\C:;\\.\PhysicalDriveNfor a physical disk;\\.\X:for a drive-letter volume; and\\?\Volume{GUID}for a named volume, without the trailing backslash used for a mounted-volume directory.
Run from an elevated command prompt and use a separate output directory.
bulk_extractor opens the device read-only with shared read/write access. It
does not lock, mount, modify, or write the device. The reader uses
CreateFileW, obtains the precise length with IOCTL_DISK_GET_LENGTH_INFO,
and uses offset-based ReadFile calls; it does not use
std::filesystem::file_size or calculated disk geometry.
A volume is not interchangeable with its physical disk: it can have distinct
boundaries or span disks. Windows may require FSCTL_ALLOW_EXTENDED_DASD_IO
to read the final sectors of a volume. bulk_extractor does not issue that
control code, so it reports a short read at that boundary rather than bypassing
the operating system's protection.
The CI VHD test covers a drive-letter volume. Before a release, also validate the physical-drive and volume-GUID forms from an elevated Windows system using disposable media with known size and known bytes near both ends.