https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7d93362f5aa002fe40366…
commit 7d93362f5aa002fe4036691976e1f092334f4857
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun Jan 9 09:54:53 2022 +0100
Commit: hpoussin <32227662+hpoussin(a)users.noreply.github.com>
CommitDate: Fri Apr 15 23:09:16 2022 +0200
[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)
---
win32ss/gdi/eng/device.c | 23 ++++++----
win32ss/gdi/eng/ldevobj.c | 106 +++++++++++++++++++++++-----------------------
win32ss/gdi/eng/ldevobj.h | 16 ++++---
3 files changed, 80 insertions(+), 65 deletions(-)
diff --git a/win32ss/gdi/eng/device.c b/win32ss/gdi/eng/device.c
index f651c213b09..27edfe2a56e 100644
--- a/win32ss/gdi/eng/device.c
+++ b/win32ss/gdi/eng/device.c
@@ -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;
diff --git a/win32ss/gdi/eng/ldevobj.c b/win32ss/gdi/eng/ldevobj.c
index 7afbf1584fa..b1cdc7b1247 100644
--- a/win32ss/gdi/eng/ldevobj.c
+++ b/win32ss/gdi/eng/ldevobj.c
@@ -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(
diff --git a/win32ss/gdi/eng/ldevobj.h b/win32ss/gdi/eng/ldevobj.h
index c7b803a9a4c..351328fe61e 100644
--- a/win32ss/gdi/eng/ldevobj.h
+++ b/win32ss/gdi/eng/ldevobj.h
@@ -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