[WIN32SS:ENG] Rework EngpUpdateGraphicsDeviceList

- choose VGA adapter outside of driver initialization loop
- choose primary adapter outside of driver initialization loop
- link VGA adapter to primary adapter at the end
- only set DISPLAY_DEVICE_PRIMARY_DEVICE in this function

Also mark VgaSave driver as SystemStart instead of Disabled,
so it is available if main display driver doesn't work.
This commit is contained in:
Hervé Poussineau 2024-02-07 20:20:22 +01:00
parent 6df1cc63b6
commit dca369cf41
4 changed files with 64 additions and 47 deletions

View file

@ -7,6 +7,3 @@ Signature = "$Windows NT$"
;
; Display driver section
;
; VGA miniport driver
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000001

View file

@ -3,7 +3,7 @@
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Group",0x00000000,"Video Save"
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","ImagePath",0x00020000,"system32\drivers\vga.sys"
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Tag",0x00010001,0x00000002
HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave\Video","Service",0x00000000,"VgaSave"

View file

@ -170,16 +170,23 @@ EngpUnlinkGraphicsDevice(
}
}
/* Goal of this function is to:
* - detect new graphic devices (from registry) and initialize them
* - link primary device and VGA device (if available) using pVgaDevice field
* - handle gbBaseVideo global flag
* - set DISPLAY_DEVICE_PRIMARY_DEVICE on at least one device
* - set gpPrimaryGraphicsDevice
* - set gpVgaGraphicsDevice
*/
NTSTATUS
EngpUpdateGraphicsDeviceList(VOID)
{
ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0;
ULONG iDevNum, ulMaxObjectNumber = 0;
WCHAR awcDeviceName[20], awcWinDeviceName[20];
UNICODE_STRING ustrDeviceName;
WCHAR awcBuffer[256];
NTSTATUS Status;
PGRAPHICS_DEVICE pGraphicsDevice;
BOOLEAN bFoundNewDevice = FALSE;
PGRAPHICS_DEVICE pGraphicsDevice, pNewPrimaryGraphicsDevice = NULL;
ULONG cbValue;
HKEY hkey;
@ -191,15 +198,6 @@ EngpUpdateGraphicsDeviceList(VOID)
return Status;
}
/* Read the name of the VGA adapter */
cbValue = sizeof(awcDeviceName);
Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue);
if (NT_SUCCESS(Status))
{
iVGACompatible = _wtoi(&awcDeviceName[sizeof("\\Device\\Video")-1]);
ERR("VGA adapter = %lu\n", iVGACompatible);
}
/* Get the maximum number of adapters */
if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
{
@ -208,7 +206,7 @@ EngpUpdateGraphicsDeviceList(VOID)
TRACE("Found %lu devices\n", ulMaxObjectNumber + 1);
/* Loop through all adapters */
/* Loop through all adapters, to detect new ones */
for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
{
/* Create the adapter's key name */
@ -237,43 +235,29 @@ EngpUpdateGraphicsDeviceList(VOID)
/* Initialize the driver for this device */
pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
if (!pGraphicsDevice) continue;
/* Check if this is a VGA compatible adapter */
if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE)
{
/* Save this as the VGA adapter */
if (!gpVgaGraphicsDevice || !EngpHasVgaDriver(gpVgaGraphicsDevice))
{
gpVgaGraphicsDevice = pGraphicsDevice;
TRACE("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice);
}
}
bFoundNewDevice = TRUE;
/* Set the first one as primary device */
if (!gpPrimaryGraphicsDevice || EngpHasVgaDriver(gpPrimaryGraphicsDevice))
{
gpPrimaryGraphicsDevice = pGraphicsDevice;
TRACE("gpPrimaryGraphicsDevice = %p\n", gpPrimaryGraphicsDevice);
}
}
/* Close the device map registry key */
ZwClose(hkey);
/* Can we link VGA device to primary device? */
if (gpPrimaryGraphicsDevice &&
gpVgaGraphicsDevice &&
gpPrimaryGraphicsDevice != gpVgaGraphicsDevice &&
!gpPrimaryGraphicsDevice->pVgaDevice)
/* Choose a VGA device */
/* Try a device with DISPLAY_DEVICE_VGA_COMPATIBLE flag. If not found,
* fall back to current VGA device */
for (pGraphicsDevice = gpGraphicsDeviceFirst;
pGraphicsDevice;
pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
{
/* Yes. Remove VGA device from global list, and attach it to primary device */
TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName);
EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice);
gpPrimaryGraphicsDevice->pVgaDevice = gpVgaGraphicsDevice;
if (pGraphicsDevice == gpVgaGraphicsDevice)
continue;
if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE && EngpHasVgaDriver(pGraphicsDevice))
{
gpVgaGraphicsDevice = pGraphicsDevice;
break;
}
}
if (bFoundNewDevice && gbBaseVideo)
/* Handle gbBaseVideo */
if (gbBaseVideo)
{
PGRAPHICS_DEVICE pToDelete;
@ -307,6 +291,42 @@ EngpUpdateGraphicsDeviceList(VOID)
EngReleaseSemaphore(ghsemGraphicsDeviceList);
}
/* Choose a primary device (if none already exists) */
if (!gpPrimaryGraphicsDevice)
{
for (pGraphicsDevice = gpGraphicsDeviceFirst;
pGraphicsDevice;
pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
{
if (!EngpHasVgaDriver(pGraphicsDevice))
{
pNewPrimaryGraphicsDevice = pGraphicsDevice;
break;
}
}
if (!pNewPrimaryGraphicsDevice)
pNewPrimaryGraphicsDevice = gpGraphicsDeviceFirst;
if (pNewPrimaryGraphicsDevice)
{
pNewPrimaryGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
gpPrimaryGraphicsDevice = pNewPrimaryGraphicsDevice;
}
}
/* Can we link VGA device to primary device? */
if (gpPrimaryGraphicsDevice &&
gpVgaGraphicsDevice &&
gpPrimaryGraphicsDevice != gpVgaGraphicsDevice &&
!gpPrimaryGraphicsDevice->pVgaDevice)
{
/* Yes. Remove VGA device from global list, and attach it to primary device */
TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName);
EngAcquireSemaphore(ghsemGraphicsDeviceList);
EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice);
gpPrimaryGraphicsDevice->pVgaDevice = gpVgaGraphicsDevice;
EngReleaseSemaphore(ghsemGraphicsDeviceList);
}
return STATUS_SUCCESS;
}

View file

@ -547,7 +547,7 @@ PDEVOBJ_Create(
{
RtlCopyMemory(ppdev->pdmwDev, pdm, pdm->dmSize + pdm->dmDriverExtra);
/* FIXME: this must be done in a better way */
pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
}
}