# PESetup.exe internals What GE Image Setup actually does, start to finish. Written from the decompiled assembly, not from observation, because several long-standing beliefs about this tool turned out to be wrong and cost weeks of debugging. **Version documented:** 4.0.0.17 (`Sources/PESetup.exe`, PE32+ native apphost wrapping a .NET 6 single-file bundle, 468 embedded files). ## How to re-derive this The managed code is not directly readable - the outer PE has no managed metadata, so ILSpy refuses it. Extract `PESetup.dll` from the bundle first: ```python # .NET single-file bundle: signature is SHA-256 of ".net core bundle"; # the int64 EIGHT BYTES BEFORE it is the bundle header offset. SIG = bytes([0x8b,0x12,0x02,0xb9,0x6a,0x61,0x20,0x38, 0x72,0x7b,0x93,0x02,0x14,0xd7,0xa0,0x32]) i = data.find(SIG) header = struct.unpack_from(' PESetup.dll`. ## Paths it hardcodes From `PESetup.Models.GlobalSettings`. All are relative to the MEDIA drive (`Z:\`, whichever winpeapps share startnet mapped) unless stated. ``` ControlDir \Deploy\Control ToolsDir \Deploy\Tools\GE SoftwarePackagesDir \Deploy\Applications HWPackagesDir \Deploy\HW_Apps UnattendFile \Deploy\Tools\GE\XML\FlatUnattendW10.xml UnattendFile2 \Deploy\FlatUnattendW10.xml (fallback) DiskPartDir \DiskPart ConfigSkipPackagesFile skip.json ConfigDisableAutoStartFile disableauto.json ExpirationDuration 30 days AutoStartCountDown 31 MinRequiredSpaceWithoutCompression 128849018880 (120 GB) ``` **`W:` IS HARDCODED, EVERYWHERE.** Not derived, not configurable, not a convention this project invented: ```csharp CopyPackages destDir = "W:\\" + SoftwarePackagesDir CopyHWPackages destDir = "W:\\" + HWPackagesDir CopyTools destDir = "W:\\GE" CopyDrivers destinationPath = "W:\\Drivers\\" + ApplyImage destination = "W:\\" CreateBCD "W:\\Windows\\System32\\bcdboot.exe", "W:\\Windows /l en-US" ApplyPackages DismApi.OpenOfflineSession("W:\\") CopyLogs tags -> "w:\\windows\\system32\\" ``` PESetup's own disk preparation is what makes W: exist. Any downstream script that hunts for "the applied volume" is solving a problem this tool does not have. `diskpart list volume` on a machine mid-image shows `Volume 0 W Windows NTFS 237GB Healthy`. ## The five working steps Keys as they appear in the log: `workingstep_gatherdata`, `workingstep_selectos`, `workingstep_prepare`, `workingstep_copy`, `workingstep_apply`, `workingstep_finalize`, `workingstep_reboot`. ### 1. GATHER DATA Four operations, all automatic: | Operation | What it establishes | |---|---| | `GatherDataMediaDrive` | `ImageInfo.MediaDrive`, e.g. `Z:\` | | `GatherDataBootDrive` | `ImageInfo.BootDrive`, always `X:\` (WinPE RAM disk) | | `GatherDataSelection` | BIOS version/type, serial, secure boot, OS, languages, model, **driver** | | `GatherDataImageDisk` | picks the physical disk and logs its partitions | `GatherDataSelection` is where most decisions are made: 1. **Secure boot is mandatory.** `SecurebootEnabled != 1` fails the step outright. 2. Reads `Control\LanguagePacks.json`. 3. `SystemHelpers.GetModel()` and `GetManufacturer()` off WMI. 4. Reads `Control\HardwareDriver.json` and `Control\hw_applications.json`. NOTE: it reads **HardwareDriver.json**, not the `hw_drivers.json` that also sits in that folder. Editing the wrong one changes nothing. 5. **Virtual platform check.** If ANY driver entry has a manufacturer containing "virtual platform", the tool goes into virtual-only mode: it takes `list[0]` as the driver and then REQUIRES the machine to look virtual (model/serial/BIOS containing VIRTUAL, VMWARE, XEN, QEMU, VirtualBox, vmw). On real hardware that is a hard failure. A stray "virtual platform" entry in the catalogue therefore breaks imaging for every physical machine. 6. Otherwise `GetDriverByModel` (below). 7. If `Control\skip.json` exists, package installation is skipped. ### 2. SELECT OS Operator-facing. Warns when the media holds an LTSC image ("99% of the time only for ShopFloor"). Also shows days-to-expiry - the media expires 30 days after build (`ExpirationDuration`). ### 3. PREPARE | Operation | What it does | |---|---| | `PrepareDoDisking` | copies `\DiskPart\diskpartEFI.txt` to `X:\diskpartEFI.txt`, then `cmd /c DISKPART /S X:\diskpartEFI.txt` | | `PrepareUnattend` | loads the unattend, substitutes, saves to `X:\Unattend.xml` | `PrepareUnattend` in detail: ```csharp text = MediaDrive + UnattendFile; // \Deploy\Tools\GE\XML\FlatUnattendW10.xml if (!File.Exists(text)) text = MediaDrive + UnattendFile2; // \Deploy\FlatUnattendW10.xml xml.Load(text); xml.InnerXml = xml.InnerXml.Replace("%serialnumber%", imageinfo.Serialnumber); xml.InnerXml = xml.InnerXml.Replace("*arch*", arch); SetPackages(arch, xml, imageinfo); // needs Control\Packages.xml xml.Save("X:\\Unattend.xml"); ``` Two tokens are substituted: `%serialnumber%` and `*arch*`. `SetPackages` merges in servicing packages from `Control\Packages.xml` and `Control\PackageGroups.xml`. The unattend that is USED is the one on the media at `Tools\GE\XML\` if present, otherwise `Deploy\FlatUnattendW10.xml`. A shopfloor variant only takes effect if it occupies one of those two paths. ### 4. COPY Four operations. **None of them filters, and none of them reads the unattend.** | Operation | Source | Destination | Rule | |---|---|---|---| | `CopyTools` | `Z:\Deploy\Tools\GE` | `W:\GE` | whole directory, recursive | | `CopyPackages` | `Z:\Deploy\Applications` | `W:\Deploy\Applications` | whole directory, recursive | | `CopyHWPackages` | `Z:\Deploy\HW_Apps` | `W:\Deploy\HW_Apps` | whole directory; **skipped if `IsVirtual` or `HWApps == null`** | | `CopyDrivers` | one `.zip` chosen by model | `W:\Drivers\` | **unzipped**, not copied | `ExecuteInternalCopy` walks `GetDirectoriesRecursive(source, includeSubDirs: true)` then `Directory.GetFiles(item, "*")`. Every file, every subdirectory. It clears the read-only attribute on each copy. **Consequences worth designing around:** - Anything dropped into `Deploy\Applications` on the media lands on the target. No manifest, no registration, no unattend reference required. - The copy is FAIL-FAST. One exception on one file returns false and fails the whole step with `copy_packages_error`. A locked or unreadable file in `Applications` fails imaging, it does not get skipped. - Progress is computed from total directory size up front, so bulky additions visibly lengthen this phase. ### 5. APPLY | Operation | What it does | |---|---| | `ApplyImage` | `install.wim` from `OperatingSystem.json`'s `destinationDir`, at `wimindex`, applied to `W:\` | | `ApplyPackages` | DISM offline session on `W:\`, adds servicing packages; logs to `X:\ApplyOSPatch_.log` | | `ApplyLanguagePacks` | same pattern, `X:\ApplyLanguagePack_.log` | | `ApplyUnattend` | DISM offline session on `W:\`, applies `X:\Unattend.xml`; logs to `X:\ApplyUnattend.log` | | `CreateBCD` | `W:\Windows\System32\bcdboot.exe W:\Windows /l en-US` | | `CopyWinRE` | `reagentc /setreimage /path T:\Recovery\WindowsRE /target W:\Windows` | All DISM work uses `W:\imagetemp` as scratch and deletes it afterwards. ### 6. FINALIZE `CopyLogs`: - `CopyTagFiles(ToolsDir)` - every `*.tag` from the tools dir to **`w:\windows\system32\`**. This is how build/media tags reach the OS. - `CopyLogFiles("X:\\")` and `CopyXMLFile("X:\\")` - the PESetup log and the generated unattend are preserved. ## Driver selection, in full This is the part most worth understanding, because a miss is nearly silent. ```csharp // GatherDataSelection List list = JSONHelpers.ReadJSON_Driver(MediaDrive + ControlDir + "\\HardwareDriver.json"); ... imageinfo.HWDriver = GetDriverByModel(list, imageinfo.Model); if (imageinfo.HWDriver == null) { // status = Warning, message "driver for [MODEL] not found" return operationResult; } ``` ```csharp private static HardwareDriversRootObject? GetDriverByModel(List<...> drivers, string model) { string modelFamily = ""; if (model.ToUpper().Contains("LATITUDE")) modelFamily = "Latitude"; if (model.ToUpper().Contains("OPTIPLEX")) modelFamily = "Optiplex"; if (model.ToUpper().Contains("PRECISION")) modelFamily = "Precision"; return drivers.Where(d => { if (!string.IsNullOrEmpty(modelFamily) && !d.family.ToLower().Contains(modelFamily.ToLower())) return false; foreach (string token in d.modelswminame.Split(',')) if (model.ToLower().Contains(token.ToLower())) return true; // SUBSTRING return false; }).ToList()?.FirstOrDefault(); } ``` Then: ```csharp sourceFilePath = MediaDrive + HWDriver.destinationDir.Replace("*destinationdir*","") + "\\" + HWDriver.fileName; destinationPath = "W:\\Drivers\\" + Path.GetFileNameWithoutExtension(sourceFilePath); StartUnzipAsync(...) ``` ### Four traps in that logic 1. **A miss is a WARNING, not a failure.** Imaging continues and the machine comes up with no drivers - no NIC, no WiFi, so DNS fails and anything network-dependent at first boot fails with it. Symptoms appear far from the cause. 2. **Matching is substring, first match wins.** A token like `7020` matches any model string containing 7020. Order in the JSON decides ties. 3. **The family filter knows only three Dell lines.** Anything else - MicroPCs, NUCs, non-Dell - skips the filter and depends entirely on `modelswminame` substrings being right. 4. **One "virtual platform" entry hijacks the whole catalogue** (see GATHER DATA step 5) and fails every physical machine. ## What this means for startnet.cmd Three beliefs encoded in `startnet.cmd` do not survive contact with the source: - *"The applied volume might not be W:."* PESetup hardcodes W: in nine places and creates it during disk prep. The volume finder, the diskpart reassignment and the `W:` wait loop are machinery around a non-problem. - *"We must copy our payload from the enrollment share after imaging."* Anything in `Deploy\Applications` on the media is copied to `W:\Deploy\Applications` by PESetup itself, and is readable at `C:\Deploy\Applications` at first boot. - *"Display MicroPCs failed because the applied volume was not W:."* Worth re-testing. A missing `HardwareDriver.json` match produces the same end-state - no drivers, no network - via a completely different route, and that route only logs a warning. ## Files PESetup reads from the media ``` Deploy\Control\HardwareDriver.json driver catalogue (NOT hw_drivers.json) Deploy\Control\hw_applications.json per-model applications Deploy\Control\OperatingSystem.json OS list, wim path, wimindex Deploy\Control\LanguagePacks.json language packs Deploy\Control\packages.json servicing packages Deploy\Control\Packages.xml unattend package merge Deploy\Control\PackageGroups.xml package grouping Deploy\Control\Media.tag media identity Deploy\Control\skip.json presence = skip package install Deploy\Control\disableauto.json presence = disable autostart Deploy\Tools\GE\XML\FlatUnattendW10.xml preferred unattend Deploy\FlatUnattendW10.xml fallback unattend ```