In the previous part of this project I found that it is possible to boot a custom image on DigitalOcean droplets by writing a new MBR to the disk and the corresponding files. In this part, I will go over how I got a sort of working Windows to boot on the droplet.

The first thing I had to solve was the corruption issues of the disk. Instead of writing the raw image o the disk, I had o find a way to preserve the current filesystem and structure so that it can be used as a source for the Windows system. I tried to use GRUB to load the Windows installation CD directly and install Windows from there, but due to the way the ISO is booted, the Windows install process fails to detect the installation media source and halts on an error.

My next attempt at getting the Windows installation process to start was by bootstrapping WinPE onto the target machine, and starting the installation process from within the temporary Windows environment. I had gone through multiple iterations to get WinPE to boot, the first strategy was to create a disk image, containing a SYSLINUX bootloader with additional modules to be able to load Windows’s bootmgr. The second strategy was to use the current GRUB loader to chainload iPXE with wimboot to load the image. After some experimenting, I had learned a few things about the Windows installation process.

The first things I had learned, before even booting the image, was all about the different files that make up the Windows installation CD. There are only a few files that are used for core boot and installation process, and the rest can be ignored. I had learned that all of the files used either for the WinPE environment or the actual Windows installation process are located in WIM^[More information in WIM files can be found in my post Manipulating WIM files with python]()] files (/sources/boot.wim and /sources/install.wim respectively). I had also learned that the WinPE uses two more important files in the boot process, the first is /boot/bcd which is re registry hive that is used to store all boot configurations (replaces the old XP boot.ini) , and the second, /boot/boot.sdi contains an empty ramdisk, which is used as the base for the boot.wim file.

After I got all my files together and wrote the whole GRUB/iPXE/wimboot configuration, I learned that setup.exe (the Windows installer process) which is auto-run on boot, will not detect the droplets hard-drive and later, will not agree to install Windows due to hardware compatibility issues (not enough RAM and disk space)^[Windows 7 x64 requires 2GB RAM and 20GB hard drive , compared to the 512MB RAM and 19.5GB hard-drive the droplet had. ]. I had to edit the boot.wim file to rename setup.exe to something else, in order to prevent the auto-install process to start. Once I got setup.exe out of my way, and got a cmd.exe shell, I learned through diskpart and netsh that the hard-drive was not detected by the OS and nether were the network cards.

At this point, I had to go back to a working droplet and check some things out, while running lspci I noticed that the hard-drive and network cards were all Red Hat, Inc Virtio devices. Windows, as well as WinPE, do not have the drivers needed to communicate with these VirtIO devices and therefore did not detect them. I solved this problem by downloading the drivers from Fedora’s website and added them to the image, using drvload.exe in the console to add them after boot.

%SYSTEMDRIVE%\windows\system32\drvload.exe %SYSTEMDRIVE%\drivers\netkvm.inf
%SYSTEMDRIVE%\windows\system32\drvload.exe %SYSTEMDRIVE%\drivers\viostor.inf

After I finally had a WinPE environment suitable for installing Windows, I had to install Windows manually to the disk, as setup.exe refused to do so. Since all of this is running as a ramdisk, I had to find a temporary place to store the 4+GB install.wim file while extracting it. To do so, I added a copy of wget for windows (statically compiled) in order to download the install.wim file later, after I re-partitioned the disk. I also added imagex.exe to the image, for easy WIM extraction (dism.exe can also be used, but requires more libraries). So, first I create the two partition needed with the following diskpart commands:

%SYSTEMDRIVE%\windows\system32\diskpart.exe
clean
create partition primary size=300
format quick fs=ntfs label="System"
assign letter=S
active
create partition primary
format quick fs=ntfs label="Windows"
assign letter=W
exit

After the disk was partitioned, I used the wge.exe I added earlier to download install.wim over HTTP to the new, empty disk. I then used imagex.exe /apply W:\install.wim 1 W: and proceeded to install the bootloader with bcdboot.exe W:\Windows /s S:\. After I was sure everything was OK, I reboot the droplet. Well, the installation did something, because I got a new error message! As Windows stared to boot, I got a BSOD with the code 0x0000007B. After some checking in MSDN, It appears that this STOP code is related to he boot device being inaccessible. After some time, I figured that I may have added the drivers to the WinPE environment, but the new Windows installation did not have any drivers added to it. After installing the drivers to the new Windows installation (either manually, or with dism.exe) I finally had a working Windows droplet on DigitalOcean.

But you know what was the best part after the installation success? It was finding out that I had installed Windows 7 Home Basic with not remote desktop support ¯\_(ツ)_/¯.