Building a Windows driver using Docker

24 Apr, 21
Tags:
202
1
Docker logo and WinDDK image

Previously I talked about how useful Docker was for build environments. Now I'm going to give a practical example of a simple Docker image that is able to build a driver using the WinDDK 7.1

This is going to use a Linux x64 based Docker image so that it will work almost anywhere (MacOs, Linux Desktop, and Windows all can run Linux x64 Docker images). The building will be done using WinDDK 7.1. We will use Wine inside the Docker container to run the Windows WinDDK executables. The end result will be to be able to build the HelloWorld driver example.

One of the huge benefits with Docker is that images can easily be shared. Unfortunately due to the WinDDK being owned by Microsoft, the license agreement for the WinDDK prevents people from publicly sharing it or distributing it in any manner. Therefore I can not provide a complete Docker image that contains the WinDDK. Instead I will provide the instructions for building it yourself.

The first step is getting the WinDDK as a .tar.gz file. This is not the format the Microsoft deliver it in though. For this step you will need a Windows OS. If you don't have a Windows OS then you can install VirtualBox for free and download and install Windows 10 from Microsoft. You do not need a key to install Windows initially and once the next step is done the VM can be discarded.

Install the WinDDK to the default location. You only need to install the Build Environments.

WinDDK Installation screen (1)WinDDK Installation screen 2

This does not take very long to install. Once done there will be the directory C:\WinDDK created.

Now run the following command to create the tar.gz 

tar czf WINDDK7.1.tar.gz C:\WinDDK

This will take a while and produce a tar file around 550 MB. Keep a copy of the tar file and you can now discard the VM if you choose to.

The following is a simple Dockerfile along with some additional files for creating an image containing the WinDDK and Wine.

(Files available in this zip)

Dockerfile

FROM ubuntu:20.04

# Set useful variables
ENV DEBIAN_FRONTEND=noninteractive

ENV \
 WINEDEBUG=-all \
 WINEDLLOVERRIDES="vcruntime140_1=n"

RUN set -ex ;\
 dpkg --add-architecture i386 ;\
 apt-get update ;\
 apt-get install -y wine-development ;\
 rm -rf /var/lib/apt/lists/* ;\
 wine wineboot --init; while pgrep wineserver; do sleep 1; done ;\
 mv /root/.wine/drive_c /drive_c ;\
 rm /root/.wine/dosdevices/c: ;\
 ln -s /drive_c /root/.wine/dosdevices/c: ;\
 chmod o+rwx /root /root/.wine ;\
 chmod o+rw /root/.wine/*.reg ;\
 chmod -R a+w /drive_c ;\
 true

ADD ["WINDDK7.1.tar.gz", "/drive_c/"]
ADD ["doskey.bat", "/drive_c/windows/"]
ADD ["setenvbuild.sh", "/usr/local/bin/"]
ADD ["setenvbuild.bat", "/drive_c/windows/"]
RUN chmod +x /usr/local/bin/setenvbuild.sh

ENTRYPOINT ["setenvbuild.sh"]

doskey.bat

@echo off
rem Dummy file to suppress error message that doskey is missing (its not in wine)

setenvbuild.sh

#!/usr/bin/bash
wine cmd /c setenvbuild.bat "$@"

setenvbuild.bat

@echo off
pushd
call C:\WinDDK\7600.16385.1\bin\setenv C:\WinDDK\7600.16385.1 %*
popd
build -cZw

Build the Docker image

Put the above files into a directory along with WINDDK7.1.tar.gz. (A zip of the above files can be downloaded here)

Run the following command:

docker build -t build-winddk7.1 .

This will create a docker image named "build-winddk7.1". This image can now be used to build the HelloWorld driver sample. In a directory containing the source and makefiles

for the HelloWorld driver run the following command (on a Windows host)

docker run --rm -v %CD%:/build -w /build build-winddk7.1

 Or on a non Windows host use:

docker run --rm -v $PWD -w $PWD:$PWD build-winddk7.1

This will build the driver. Additionally you can add parameters at the end of the command line that will be passed to the WinDDK setenv.bat program. For example to build x64 use:

docker run --rm -v $PWD -w $PWD:$PWD build-winddk7.1 x64

 

This is a very basic Docker image. Many improvements can be made to make it more useful, for example adding in CMake rather than using the WinDDKs makefile system. This should serve as a good base for demonstrating how useful Docker can be for build environments. Once the Docker image is made and shared there is no need for anyone else in the team to have to worry about setting up the build environment on their own computer, they just use the Docker image and everything is self contained.

 

 

1 评论

28 Sep, 21

Great article! I will definitely be giving this a try.

I read recently that it's possible to use Windows container images with Docker as well, and that MS provides several Windows server base images on Docker Hub. I haven't looked into it too much, but would this be a viable approach as well vs. using Wine? https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/run-your-first-container

(I suppose the disadvantage of that is that the host must be Windows, whereas the approach using Wine can work on any of Windows / MacOS / Linux hosts.)