[WIN32SS] Implement LDEVOBJ_ulGetDriverModes

- implement LDEVOBJ_ulGetDriverModes (which get modes from a not yet loaded driver),
  and use it in EngpPopulateDeviceModeList
- remove now useless LDEVOBJ_pdmiGetModes (replaced by LDEVOBJ_ulGetDriverModes)
This commit is contained in:
Hervé Poussineau 2022-01-09 09:54:53 +01:00 committed by hpoussin
parent 3b234cce25
commit 7d93362f5a
3 changed files with 80 additions and 65 deletions

View file

@ -130,11 +130,11 @@ EngpPopulateDeviceModeList(
_In_ PDEVMODEW pdmDefault)
{
PWSTR pwsz;
PLDEVOBJ pldev;
PDEVMODEINFO pdminfo;
PDEVMODEW pdm, pdmEnd;
ULONG i, cModes = 0;
BOOLEAN bModeMatch = FALSE;
ULONG cbSize, cbFull;
ASSERT(pGraphicsDevice->pdevmodeInfo == NULL);
ASSERT(pGraphicsDevice->pDevModeList == NULL);
@ -145,23 +145,30 @@ EngpPopulateDeviceModeList(
* This is a REG_MULTI_SZ string */
for (; *pwsz; pwsz += wcslen(pwsz) + 1)
{
/* Try to load the display driver */
/* Get the mode list from the driver */
TRACE("Trying driver: %ls\n", pwsz);
pldev = LDEVOBJ_pLoadDriver(pwsz, LDEV_DEVICE_DISPLAY);
if (!pldev)
cbSize = LDEVOBJ_ulGetDriverModes(pwsz, pGraphicsDevice->DeviceObject, &pdm);
if (!cbSize)
{
ERR("Could not load driver: '%ls'\n", pwsz);
WARN("Driver %ls returned no valid mode\n", pwsz);
continue;
}
/* Get the mode list from the driver */
pdminfo = LDEVOBJ_pdmiGetModes(pldev, pGraphicsDevice->DeviceObject);
/* Add space for the header */
cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
/* Allocate a buffer for the DEVMODE array */
pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
if (!pdminfo)
{
ERR("Could not get mode list for '%ls'\n", pwsz);
ERR("Could not allocate devmodeinfo\n");
continue;
}
pdminfo->pldev = LDEVOBJ_pLoadDriver(pwsz, LDEV_DEVICE_DISPLAY);
pdminfo->cbdevmode = cbSize;
RtlCopyMemory(pdminfo->adevmode, pdm, cbSize);
/* Attach the mode info to the device */
pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
pGraphicsDevice->pdevmodeInfo = pdminfo;

View file

@ -111,58 +111,6 @@ LDEVOBJ_vFreeLDEV(
ExFreePoolWithTag(pldev, GDITAG_LDEV);
}
PDEVMODEINFO
NTAPI
LDEVOBJ_pdmiGetModes(
_In_ PLDEVOBJ pldev,
_In_ HANDLE hDriver)
{
ULONG cbSize, cbFull;
PDEVMODEINFO pdminfo;
TRACE("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
/* Mirror drivers may omit this function */
if (!pldev->pfn.GetModes)
{
return NULL;
}
/* Call the driver to get the required size */
cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
if (!cbSize)
{
ERR("DrvGetModes returned 0\n");
return NULL;
}
/* Add space for the header */
cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
/* Allocate a buffer for the DEVMODE array */
pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
if (!pdminfo)
{
ERR("Could not allocate devmodeinfo\n");
return NULL;
}
pdminfo->pldev = pldev;
pdminfo->cbdevmode = cbSize;
/* Call the driver again to fill the buffer */
cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdminfo->adevmode);
if (!cbSize)
{
/* Could not get modes */
ERR("returned size %lu(%lu)\n", cbSize, pdminfo->cbdevmode);
ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE);
pdminfo = NULL;
}
return pdminfo;
}
static
BOOL
LDEVOBJ_bLoadImage(
@ -277,6 +225,60 @@ LDEVOBJ_bEnableDriver(
return TRUE;
}
ULONG
LDEVOBJ_ulGetDriverModes(
_In_ LPWSTR pwszDriverName,
_In_ HANDLE hDriver,
_Out_ PDEVMODEW *ppdm)
{
PLDEVOBJ pldev = NULL;
ULONG cbSize = 0;
PDEVMODEW pdm = NULL;
TRACE("LDEVOBJ_ulGetDriverModes('%ls', %p)\n", pwszDriverName, hDriver);
pldev = LDEVOBJ_pLoadDriver(pwszDriverName, LDEV_DEVICE_DISPLAY);
if (!pldev)
goto cleanup;
/* Mirror drivers may omit this function */
if (!pldev->pfn.GetModes)
goto cleanup;
/* Call the driver to get the required size */
cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
if (!cbSize)
{
ERR("DrvGetModes returned 0\n");
goto cleanup;
}
/* Allocate a buffer for the DEVMODE array */
pdm = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_DEVMODE);
if (!pdm)
{
ERR("Could not allocate devmodeinfo\n");
goto cleanup;
}
/* Call the driver again to fill the buffer */
cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdm);
if (!cbSize)
{
/* Could not get modes */
ERR("DrvrGetModes returned 0 on second call\n");
ExFreePoolWithTag(pdm, GDITAG_DEVMODE);
pdm = NULL;
}
cleanup:
if (pldev)
LDEVOBJ_vUnloadImage(pldev);
*ppdm = pdm;
return cbSize;
}
static
PVOID
LDEVOBJ_pvFindImageProcAddress(

View file

@ -34,11 +34,17 @@ NTSTATUS
NTAPI
InitLDEVImpl(VOID);
PDEVMODEINFO
NTAPI
LDEVOBJ_pdmiGetModes(
_In_ PLDEVOBJ pldev,
_In_ HANDLE hDriver);
/* Get all available device modes from a driver
* - pwszDriverName: name of the driver
* - hDriver: handle of the driver
* - ppdm: allocated memory containing driver modes or NULL on error
* Return value: number of bytes allocated for *ppdm buffer or 0 on error
*/
ULONG
LDEVOBJ_ulGetDriverModes(
_In_ LPWSTR pwszDriverName,
_In_ HANDLE hDriver,
_Out_ PDEVMODEW *ppdm);
PLDEVOBJ
APIENTRY