Index: gdi/eng/device.c =================================================================== --- win32ss/gdi/eng/device.c (revision 71321) +++ win32ss/gdi/eng/device.c (working copy) @@ -30,100 +30,23 @@ return STATUS_SUCCESS; } - -PGRAPHICS_DEVICE -NTAPI -EngpRegisterGraphicsDevice( - _In_ PUNICODE_STRING pustrDeviceName, - _In_ PUNICODE_STRING pustrDiplayDrivers, - _In_ PUNICODE_STRING pustrDescription, +BOOLEAN +EngpPopulateDeviceModeList( + _Inout_ PGRAPHICS_DEVICE pGraphicsDevice, _In_ PDEVMODEW pdmDefault) { - PGRAPHICS_DEVICE pGraphicsDevice; - PDEVICE_OBJECT pDeviceObject; - PFILE_OBJECT pFileObject; - NTSTATUS Status; PWSTR pwsz; - ULONG i, cj, cModes = 0; - SIZE_T cjWritten; - BOOL bEnable = TRUE; + PLDEVOBJ pldev; PDEVMODEINFO pdminfo; PDEVMODEW pdm, pdmEnd; - PLDEVOBJ pldev; + ULONG i, cModes = 0; BOOLEAN bModeMatch = FALSE; + + ASSERT(pGraphicsDevice->pdevmodeInfo == NULL); + ASSERT(pGraphicsDevice->pDevModeList == NULL); - TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName); + pwsz = pGraphicsDevice->pDiplayDrivers; - /* Allocate a GRAPHICS_DEVICE structure */ - pGraphicsDevice = ExAllocatePoolWithTag(PagedPool, - sizeof(GRAPHICS_DEVICE), - GDITAG_GDEVICE); - if (!pGraphicsDevice) - { - ERR("ExAllocatePoolWithTag failed\n"); - return NULL; - } - - /* Try to open the driver */ - Status = IoGetDeviceObjectPointer(pustrDeviceName, - FILE_READ_DATA | FILE_WRITE_DATA, - &pFileObject, - &pDeviceObject); - if (!NT_SUCCESS(Status)) - { - ERR("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status); - ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); - return NULL; - } - - /* Enable the device */ - EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cjWritten); - - /* Copy the device and file object pointers */ - pGraphicsDevice->DeviceObject = pDeviceObject; - pGraphicsDevice->FileObject = pFileObject; - - /* Copy device name */ - RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, - sizeof(pGraphicsDevice->szNtDeviceName), - pustrDeviceName->Buffer, - pustrDeviceName->Length); - - /* Create a win device name (FIXME: virtual devices!) */ - swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\DISPLAY%d", (int)giDevNum); - - /* Allocate a buffer for the strings */ - cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); - pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP); - if (!pwsz) - { - ERR("Could not allocate string buffer\n"); - ASSERT(FALSE); // FIXME - ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); - return NULL; - } - - /* Copy display driver names */ - pGraphicsDevice->pDiplayDrivers = pwsz; - RtlCopyMemory(pGraphicsDevice->pDiplayDrivers, - pustrDiplayDrivers->Buffer, - pustrDiplayDrivers->Length); - - /* Copy description */ - pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR); - RtlCopyMemory(pGraphicsDevice->pwszDescription, - pustrDescription->Buffer, - pustrDescription->Length); - pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0; - - /* Initialize the pdevmodeInfo list and default index */ - pGraphicsDevice->pdevmodeInfo = NULL; - pGraphicsDevice->iDefaultMode = 0; - pGraphicsDevice->iCurrentMode = 0; - - // FIXME: initialize state flags - pGraphicsDevice->StateFlags = 0; - /* Loop through the driver names * This is a REG_MULTI_SZ string */ for (; *pwsz; pwsz += wcslen(pwsz) + 1) @@ -138,7 +61,7 @@ } /* Get the mode list from the driver */ - pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject); + pdminfo = LDEVOBJ_pdmiGetModes(pldev, pGraphicsDevice->DeviceObject); if (!pdminfo) { ERR("Could not get mode list for '%ls'\n", pwsz); @@ -170,8 +93,7 @@ if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) { ERR("No devmodes\n"); - ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); - return NULL; + return FALSE; } /* Allocate an index buffer */ @@ -182,8 +104,7 @@ if (!pGraphicsDevice->pDevModeList) { ERR("No devmode list\n"); - ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); - return NULL; + return FALSE; } TRACE("Looking for mode %lux%lux%lu(%lu Hz)\n", @@ -232,8 +153,107 @@ pGraphicsDevice->pDevModeList[i].pdm = pdm; i++; } - } + } + return TRUE; +} +PGRAPHICS_DEVICE +NTAPI +EngpRegisterGraphicsDevice( + _In_ PUNICODE_STRING pustrDeviceName, + _In_ PUNICODE_STRING pustrDiplayDrivers, + _In_ PUNICODE_STRING pustrDescription, + _In_ PDEVMODEW pdmDefault) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVICE_OBJECT pDeviceObject; + PFILE_OBJECT pFileObject; + NTSTATUS Status; + PWSTR pwsz; + ULONG cj; + SIZE_T cjWritten; + BOOL bEnable = TRUE; + + TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName); + + /* Allocate a GRAPHICS_DEVICE structure */ + pGraphicsDevice = ExAllocatePoolWithTag(PagedPool, + sizeof(GRAPHICS_DEVICE), + GDITAG_GDEVICE); + if (!pGraphicsDevice) + { + ERR("ExAllocatePoolWithTag failed\n"); + return NULL; + } + + /* Try to open the driver */ + Status = IoGetDeviceObjectPointer(pustrDeviceName, + FILE_READ_DATA | FILE_WRITE_DATA, + &pFileObject, + &pDeviceObject); + if (!NT_SUCCESS(Status)) + { + ERR("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; + } + + /* Enable the device */ + EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cjWritten); + + /* Copy the device and file object pointers */ + pGraphicsDevice->DeviceObject = pDeviceObject; + pGraphicsDevice->FileObject = pFileObject; + + /* Copy device name */ + RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, + sizeof(pGraphicsDevice->szNtDeviceName), + pustrDeviceName->Buffer, + pustrDeviceName->Length); + + /* Create a win device name (FIXME: virtual devices!) */ + swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\DISPLAY%d", (int)giDevNum); + + /* Allocate a buffer for the strings */ + cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); + pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP); + if (!pwsz) + { + ERR("Could not allocate string buffer\n"); + ASSERT(FALSE); // FIXME + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; + } + + /* Copy display driver names */ + pGraphicsDevice->pDiplayDrivers = pwsz; + RtlCopyMemory(pGraphicsDevice->pDiplayDrivers, + pustrDiplayDrivers->Buffer, + pustrDiplayDrivers->Length); + + /* Copy description */ + pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR); + RtlCopyMemory(pGraphicsDevice->pwszDescription, + pustrDescription->Buffer, + pustrDescription->Length); + pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0; + + /* Initialize the pdevmodeInfo list and default index */ + pGraphicsDevice->pdevmodeInfo = NULL; + pGraphicsDevice->iDefaultMode = 0; + pGraphicsDevice->iCurrentMode = 0; + + // FIXME: initialize state flags + pGraphicsDevice->StateFlags = 0; + + /* Create the mode list */ + pGraphicsDevice->pDevModeList = NULL; + if (!EngpPopulateDeviceModeList(pGraphicsDevice, pdmDefault)) + { + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; + } + /* Lock loader */ EngAcquireSemaphore(ghsemGraphicsDeviceList); @@ -250,7 +270,7 @@ /* Unlock loader */ EngReleaseSemaphore(ghsemGraphicsDeviceList); - TRACE("Prepared %lu modes for %ls\n", cModes, pGraphicsDevice->pwszDescription); + TRACE("Prepared %lu modes for %ls\n", pGraphicsDevice->cDevModes, pGraphicsDevice->pwszDescription); return pGraphicsDevice; } Index: gdi/eng/device.h =================================================================== --- win32ss/gdi/eng/device.h (revision 71321) +++ win32ss/gdi/eng/device.h (working copy) @@ -3,6 +3,11 @@ #define TAG_GDEV 'gdev' +VOID +NTAPI +PDEVOBJ_vRefreshModeList( + PPDEVOBJ ppdev); + extern PGRAPHICS_DEVICE gpPrimaryGraphicsDevice; extern PGRAPHICS_DEVICE gpVgaGraphicsDevice; @@ -29,6 +34,11 @@ _In_ PUNICODE_STRING pustrDescription, _In_ PDEVMODEW pdmDefault); +BOOLEAN +EngpPopulateDeviceModeList( + _Inout_ PGRAPHICS_DEVICE pGraphicsDevice, + _In_ PDEVMODEW pdmDefault); + INIT_FUNCTION NTSTATUS NTAPI Index: gdi/eng/pdevobj.c =================================================================== --- win32ss/gdi/eng/pdevobj.c (revision 71321) +++ win32ss/gdi/eng/pdevobj.c (working copy) @@ -251,6 +251,45 @@ return ppdev->pSurface; } +VOID +NTAPI +PDEVOBJ_vRefreshModeList( + PPDEVOBJ ppdev) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVMODEINFO pdminfo, pdmiNext; + DEVMODEW dmDefault; + + /* Lock the PDEV */ + EngAcquireSemaphore(ppdev->hsemDevLock); + + pGraphicsDevice = ppdev->pGraphicsDevice; + + /* Remember our default mode */ + dmDefault = *pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm; + + /* Clear out the modes */ + for (pdminfo = pGraphicsDevice->pdevmodeInfo; + pdminfo; + pdminfo = pdmiNext) + { + pdmiNext = pdminfo->pdmiNext; + ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE); + } + pGraphicsDevice->pdevmodeInfo = NULL; + ExFreePoolWithTag(pGraphicsDevice->pDevModeList, GDITAG_GDEVICE); + pGraphicsDevice->pDevModeList = NULL; + + /* Now re-populate the list */ + if (!EngpPopulateDeviceModeList(pGraphicsDevice, &dmDefault)) + { + DPRINT1("FIXME: EngpPopulateDeviceModeList failed, we just destroyed a perfectly good mode list\n"); + } + + /* Unlock PDEV */ + EngReleaseSemaphore(ppdev->hsemDevLock); +} + PDEVMODEW NTAPI PDEVOBJ_pdmMatchDevMode( Index: user/ntuser/display.c =================================================================== --- win32ss/user/ntuser/display.c (revision 71321) +++ win32ss/user/ntuser/display.c (working copy) @@ -462,6 +462,7 @@ PGRAPHICS_DEVICE pGraphicsDevice; PDEVMODEENTRY pdmentry; ULONG i, iFoundMode; + PPDEVOBJ ppdev; TRACE("Enter UserEnumDisplaySettings('%wZ', %lu)\n", pustrDevice, iModeNum); @@ -468,8 +469,9 @@ /* Ask GDI for the GRAPHICS_DEVICE */ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0); + ppdev = EngpGetPDEV(pustrDevice); - if (!pGraphicsDevice) + if (!pGraphicsDevice || !ppdev) { /* No device found */ ERR("No device found!\n"); @@ -476,8 +478,18 @@ return STATUS_UNSUCCESSFUL; } + /* let's politely ask the driver for an updated mode list, + just in case there's something new in there (vbox) */ + + PDEVOBJ_vRefreshModeList(ppdev); + PDEVOBJ_vRelease(ppdev); + + /* FIXME: maybe only refresh when iModeNum is bigger than cDevModes? */ if (iModeNum >= pGraphicsDevice->cDevModes) + { + ERR("STATUS_NO_MORE_ENTRIES!\n"); return STATUS_NO_MORE_ENTRIES; + } iFoundMode = 0; for (i = 0; i < pGraphicsDevice->cDevModes; i++)