Skip to content

Conversation

@JonasKloseBW
Copy link
Contributor

  • Add functions to read data from driver .ini files
  • Copy driver files required into the PE driver folder for system devices, scsi and raid controllers, keyboards and mice

This PR should filter and copy the files for the PE stage. I'll test the code and add fixes as required.

@rbalsleyMSFT
This should minimize the amount of copied files for the PE stage while enabling the usage of all necessary devices.

- Add functions to read data from driver .ini files
- Copy driver files required into the PE driver folder for system devices, scsi and raid controllers, keyboards and mice
Fix an error for the DLLImport
- Filter correctly for inf-driver files
- Ensure target path is created
- Cast PE driver directory creation to void to avoid unnecessary console output
@JonasKloseBW
Copy link
Contributor Author

First successful test run completed. I'll test the PE drivers on real hardware asap.
The code copied more than 70 drivers to the PE folder.

- Increase the buffer reader size by 8x read longer file name lists
- Fix cases in which the driver files are in subdirectories
@JonasKloseBW
Copy link
Contributor Author

JonasKloseBW commented Dec 29, 2024

Successful test run for Surface Laptop Go 3 (code part only).
The PE driver folder ended to be 200MB though. Which is a bit too large for me.

@JonasKloseBW
Copy link
Contributor Author

The regular Surface Laptop Go 3 driver folder is 2.3GB, so 200MB isn't that bad.
Apparently, Intel says that the 180MB audio driver is required for system stability, so they classified it as System driver.

- Avoid drivers that reference wdmaudio.inf or contain Smart Sound

This is necessary since some larger audio drivers that want to be included can be too big for PE. And we don't need audio in the PE stage anyways.
@JonasKloseBW
Copy link
Contributor Author

Avoiding drivers that reference some keywords brings the size of the PE folder for the Surface Laptop Go 3 down to 19.6MB.
I think that's a good size.

I'll test more models later to find out if there are other unexpected sizes.

- Expand the driver exclusion list to:
   wdmaudio.inf, Sound, Machine Learning, Camera, Firmware
- Display the correct manufacturer by using the Provider value (if set correctly)
@JonasKloseBW
Copy link
Contributor Author

The list of tested devices for PE driver copy so far are:

  • HP Z4 G4 Workstation
  • Microsoft Surface Book 3
  • Microsoft Surface Laptop Go 3
  • Microsoft Surface Pro 6
  • Microsoft Surface Pro 8
  • Microsoft Surface Pro 11th
  • Microsoft Surface Studio 2+
  • Lenovo ThinkBook 16p G2 ACH

It looks like the current code works exactly as expected so far.
I think now would be the time to test this on real hardware.

- Include HID device drivers (745a17a0-74d3-11d0-b6fe-00a0c90f57da)
- These drivers should stay pretty small since they're class drivers but they're necessary for touch support
@rbalsleyMSFT rbalsleyMSFT changed the base branch from dev to UI_2508 September 10, 2025 18:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds initial support for using existing drivers as PE drivers by filtering and copying only the necessary driver files for Windows PE stage. This implementation parses driver .ini files to identify system devices, SCSI/RAID controllers, keyboards, and mice drivers, then copies only the required files to minimize PE image size while maintaining device compatibility.

  • Added infrastructure for reading INI files using Windows kernel32.dll APIs
  • Implemented driver filtering logic based on device class GUIDs and exclusion patterns
  • Added new parameter UseDriversAsPEDrivers to enable selective driver copying for PE

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


foreach ($keyValue in $keyValues) {
if (![string]::IsNullOrEmpty($keyValue)) {
$parts = $keyValue -split "="
Copy link

Copilot AI Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code assumes that each key-value pair has exactly one '=' character and will fail if the value contains '=' characters. Use -split with a limit parameter to handle values containing '=' properly: $parts = $keyValue -split '=', 2

Suggested change
$parts = $keyValue -split "="
$parts = $keyValue -split "=", 2

Copilot uses AI. Check for mistakes.
#Find more information about device classes here:
#https://learn.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors
#For now, included are system devices, scsi and raid controllers, keyboards, mice and HID devices for touch support
$filterGUIDs = @("{4D36E97D-E325-11CE-BFC1-08002BE10318}", "{4D36E97B-E325-11CE-BFC1-08002BE10318}", "{4d36e96b-e325-11ce-bfc1-08002be10318}", "{d36e96f-e325-11ce-bfc1-08002be10318}", "{745a17a0-74d3-11d0-b6fe-00a0c90f57da}")
Copy link

Copilot AI Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The GUID strings have inconsistent casing (some lowercase 'd' and 'e'). For consistency and to avoid potential matching issues, standardize all GUIDs to uppercase format.

Suggested change
$filterGUIDs = @("{4D36E97D-E325-11CE-BFC1-08002BE10318}", "{4D36E97B-E325-11CE-BFC1-08002BE10318}", "{4d36e96b-e325-11ce-bfc1-08002be10318}", "{d36e96f-e325-11ce-bfc1-08002be10318}", "{745a17a0-74d3-11d0-b6fe-00a0c90f57da}")
$filterGUIDs = @("{4D36E97D-E325-11CE-BFC1-08002BE10318}", "{4D36E97B-E325-11CE-BFC1-08002BE10318}", "{4D36E96B-E325-11CE-BFC1-08002BE10318}", "{0D36E96F-E325-11CE-BFC1-08002BE10318}", "{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}")

Copilot uses AI. Check for mistakes.
Comment on lines +3072 to +3089
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
}
}

#Arch specific files override the files specified in the universal section
$sourceDiskFiles = Get-PrivateProfileSection -FileName $infFullName -SectionName "SourceDisksFiles.$WindowsArch"
foreach ($sourceDiskFile in $sourceDiskFiles.Keys) {
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
Copy link

Copilot AI Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition checks if the value doesn't contain a comma, but the logic suggests it should check if it does contain a comma to determine if there's a subdirectory specification. The condition should be if ($sourceDiskFiles[$sourceDiskFile].Contains(',')) for the simple case without subdirectory.

Suggested change
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
}
}
#Arch specific files override the files specified in the universal section
$sourceDiskFiles = Get-PrivateProfileSection -FileName $infFullName -SectionName "SourceDisksFiles.$WindowsArch"
foreach ($sourceDiskFile in $sourceDiskFiles.Keys) {
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
if ($sourceDiskFiles[$sourceDiskFile].Contains(",")) {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
} else {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
}
}
#Arch specific files override the files specified in the universal section
$sourceDiskFiles = Get-PrivateProfileSection -FileName $infFullName -SectionName "SourceDisksFiles.$WindowsArch"
foreach ($sourceDiskFile in $sourceDiskFiles.Keys) {
if ($sourceDiskFiles[$sourceDiskFile].Contains(",")) {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
} else {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force

Copilot uses AI. Check for mistakes.
Comment on lines +3084 to +3089
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
Copy link

Copilot AI Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above - this condition is inverted. The logic should check for the presence of a comma to determine if there's a subdirectory specification.

Suggested change
if (!$sourceDiskFiles[$sourceDiskFile].Contains(",")) {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force
} else {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
if ($sourceDiskFiles[$sourceDiskFile].Contains(",")) {
$subdir = ($sourceDiskFiles[$sourceDiskFile] -split ",")[1]
[void](New-Item -Path "$targetPath\$subdir" -ItemType Directory -Force)
Copy-Item -Path "$infPath\$subdir\$sourceDiskFile" -Destination "$targetPath\$subdir" -Force
} else {
Copy-Item -Path "$infPath\$sourceDiskFile" -Destination $targetPath -Force

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant