in library/src/RegistryQuery.cpp [149:198]
void RegistryQuery::FillDriverDetails(Device& device)
{
// Log the device ID to provide context for any subsequent log messages and errors
LOG(L"Querying device driver registry details for device {}", device.ID);
// Attempt to open the DirectX adapter for the device
auto adapterDetails = ObjectHelpers::GetZeroedStruct<D3DKMT_OPENADAPTERFROMLUID>();
adapterDetails.AdapterLuid = LuidFromInt64(device.DeviceAdapter.InstanceLuid);
auto error = CheckNtStatus(D3DKMTOpenAdapterFromLuid(&adapterDetails));
if (error)
{
throw error.Wrap(
L"D3DKMTOpenAdapterFromLuid failed to open adapter with LUID " +
std::to_wstring(device.DeviceAdapter.InstanceLuid)
);
}
// Ensure we automatically close the adapter handle when we finish
unique_adapter_handle adapter(adapterDetails.hAdapter);
// Retrieve the path to the driver store directory for the adapter
QueryD3DRegistryInfo queryDriverStore;
queryDriverStore.SetFilesystemQuery(D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH);
queryDriverStore.PerformQuery(adapter);
device.DriverStorePath = wstring(queryDriverStore.RegistryInfo->OutputString);
// If the driver store path begins with the "\SystemRoot" prefix then expand it
wstring prefix = L"\\SystemRoot";
wstring systemRoot = wstring(wil::GetEnvironmentVariableW(L"SystemRoot").get());
if (device.DriverStorePath.find(prefix, 0) == 0) {
device.DriverStorePath = device.DriverStorePath.replace(0, prefix.size(), systemRoot);
}
// Determine whether we're running on the host or inside a container
// (e.g. when using a client tool to verify that a device has been mounted correctly)
if (device.DriverStorePath.find(L"HostDriverStore", 0) != wstring::npos)
{
// We have no way of enumerating the CopyToVmWhenNewer subkey inside a container, so stop processing here
LOG(L"Running inside a container, skipping runtime file enumeration");
return;
}
// Retrieve the list of additional runtime files that need to be copied to the System32 directory
RegistryQuery::ProcessRuntimeFiles(device, L"CopyToVmOverwrite", false);
RegistryQuery::ProcessRuntimeFiles(device, L"CopyToVmWhenNewer", false);
// Retrieve the list of additional runtime files that need to be copied to the SysWOW64 directory
RegistryQuery::ProcessRuntimeFiles(device, L"CopyToVmOverwriteWow64", true);
RegistryQuery::ProcessRuntimeFiles(device, L"CopyToVmWhenNewerWow64", true);
}