mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +00:00
Commit the stuff. Lots of changes. I'll write a proper list of changes when it's done.
svn path=/branches/reactos-yarotows/; revision=45355
This commit is contained in:
parent
7f915c6746
commit
74ef03da5c
36 changed files with 3617 additions and 3485 deletions
|
@ -9,9 +9,10 @@
|
||||||
<include base="console">.</include>
|
<include base="console">.</include>
|
||||||
<compilerflag compilerset="gcc">-fms-extensions</compilerflag>
|
<compilerflag compilerset="gcc">-fms-extensions</compilerflag>
|
||||||
<library>ntdll</library>
|
<library>ntdll</library>
|
||||||
<library>user32</library>
|
<library delayimport="true">user32</library>
|
||||||
<library>gdi32</library>
|
<library delayimport="true">gdi32</library>
|
||||||
<library>advapi32</library>
|
<library delayimport="true">advapi32</library>
|
||||||
|
<library>delayimp</library>
|
||||||
<library>win32ksys</library>
|
<library>win32ksys</library>
|
||||||
<library>psapi</library>
|
<library>psapi</library>
|
||||||
<pch>w32csr.h</pch>
|
<pch>w32csr.h</pch>
|
||||||
|
|
|
@ -12,6 +12,260 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL;
|
||||||
|
static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL;
|
||||||
|
static HSEMAPHORE ghsemGraphicsDeviceList;
|
||||||
|
static ULONG giDevNum = 1;
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitDeviceImpl()
|
||||||
|
{
|
||||||
|
ghsemGraphicsDeviceList = EngCreateSemaphore();
|
||||||
|
if (!ghsemGraphicsDeviceList)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PGRAPHICS_DEVICE
|
||||||
|
NTAPI
|
||||||
|
EngpRegisterGraphicsDevice(
|
||||||
|
PUNICODE_STRING pustrDeviceName,
|
||||||
|
PUNICODE_STRING pustrDiplayDrivers,
|
||||||
|
PUNICODE_STRING pustrDescription,
|
||||||
|
PDEVMODEW pdmDefault)
|
||||||
|
{
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
PDEVICE_OBJECT pDeviceObject;
|
||||||
|
PFILE_OBJECT pFileObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PWSTR pwsz;
|
||||||
|
ULONG i, cj, cModes = 0;
|
||||||
|
BOOL bEnable = TRUE;
|
||||||
|
PDEVMODEINFO pdminfo;
|
||||||
|
PDEVMODEW pdm, pdmEnd;
|
||||||
|
PLDEVOBJ pldev;
|
||||||
|
|
||||||
|
DPRINT1("EngpRegisterGraphicsDevice(%S)\n", pustrDeviceName->Buffer);
|
||||||
|
|
||||||
|
/* Allocate a GRAPHICS_DEVICE structure */
|
||||||
|
pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(GRAPHICS_DEVICE),
|
||||||
|
GDITAG_GDEVICE);
|
||||||
|
if (!pGraphicsDevice)
|
||||||
|
{
|
||||||
|
DPRINT1("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))
|
||||||
|
{
|
||||||
|
DPRINT1("Could not open driver, 0x%lx\n", Status);
|
||||||
|
ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable the device */
|
||||||
|
EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);
|
||||||
|
|
||||||
|
/* Copy the device and file object pointers */
|
||||||
|
pGraphicsDevice->DeviceObject = pDeviceObject;
|
||||||
|
pGraphicsDevice->FileObject = pFileObject;
|
||||||
|
|
||||||
|
/* Copy device name */
|
||||||
|
wcsncpy(pGraphicsDevice->szNtDeviceName,
|
||||||
|
pustrDeviceName->Buffer,
|
||||||
|
sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* Create a win device name (FIXME: virtual devices!) */
|
||||||
|
swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);
|
||||||
|
|
||||||
|
/* Allocate a buffer for the strings */
|
||||||
|
cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
|
||||||
|
pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
|
||||||
|
if (!pwsz)
|
||||||
|
{
|
||||||
|
DPRINT1("Could not allocate string buffer\n");
|
||||||
|
ASSERT(FALSE); // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 + sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
for (; *pwsz; pwsz += wcslen(pwsz) + 1)
|
||||||
|
{
|
||||||
|
DPRINT1("trying driver: %ls\n", pwsz);
|
||||||
|
/* Try to load the display driver */
|
||||||
|
pldev = EngLoadDriver(pwsz, LDEV_DEVICE_DISPLAY);
|
||||||
|
if (!pldev)
|
||||||
|
{
|
||||||
|
DPRINT1("Could not load driver: '%ls'\n", pwsz);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the mode list from the driver */
|
||||||
|
pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
|
||||||
|
if (!pdminfo)
|
||||||
|
{
|
||||||
|
DPRINT1("Could not get mode list for '%ls'\n", pwsz);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach the mode info to the device */
|
||||||
|
pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
|
||||||
|
pGraphicsDevice->pdevmodeInfo = pdminfo;
|
||||||
|
|
||||||
|
/* Count DEVMODEs */
|
||||||
|
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
|
||||||
|
for (pdm = pdminfo->adevmode;
|
||||||
|
pdm + 1 <= pdmEnd;
|
||||||
|
pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
|
||||||
|
{
|
||||||
|
cModes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: release the driver again until it's used?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
|
||||||
|
{
|
||||||
|
DPRINT1("No devmodes\n");
|
||||||
|
ExFreePool(pGraphicsDevice);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate an index buffer */
|
||||||
|
pGraphicsDevice->cDevModes = cModes;
|
||||||
|
pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
cModes * sizeof(DEVMODEENTRY),
|
||||||
|
GDITAG_GDEVICE);
|
||||||
|
if (!pGraphicsDevice->pDevModeList)
|
||||||
|
{
|
||||||
|
DPRINT1("No devmode list\n");
|
||||||
|
ExFreePool(pGraphicsDevice);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop through all DEVMODEINFOs */
|
||||||
|
for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
|
||||||
|
pdminfo;
|
||||||
|
pdminfo = pdminfo->pdmiNext)
|
||||||
|
{
|
||||||
|
/* Calculate End of the DEVMODEs */
|
||||||
|
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
|
||||||
|
|
||||||
|
/* Loop through the DEVMODEs */
|
||||||
|
for (pdm = pdminfo->adevmode;
|
||||||
|
pdm + 1 <= pdmEnd;
|
||||||
|
pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
|
||||||
|
{
|
||||||
|
/* Compare with the default entry */
|
||||||
|
if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
|
||||||
|
pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
|
||||||
|
pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
|
||||||
|
pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
|
||||||
|
{
|
||||||
|
pGraphicsDevice->iDefaultMode = i;
|
||||||
|
pGraphicsDevice->iCurrentMode = i;
|
||||||
|
DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the entry */
|
||||||
|
pGraphicsDevice->pDevModeList[i].dwFlags = 0;
|
||||||
|
pGraphicsDevice->pDevModeList[i].pdm = pdm;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock loader */
|
||||||
|
EngAcquireSemaphore(ghsemGraphicsDeviceList);
|
||||||
|
|
||||||
|
/* Insert the device into the global list */
|
||||||
|
pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
|
||||||
|
gpGraphicsDeviceLast = pGraphicsDevice;
|
||||||
|
if (!gpGraphicsDeviceFirst)
|
||||||
|
gpGraphicsDeviceFirst = pGraphicsDevice;
|
||||||
|
|
||||||
|
/* Increment device number */
|
||||||
|
giDevNum++;
|
||||||
|
|
||||||
|
/* Unlock loader */
|
||||||
|
EngReleaseSemaphore(ghsemGraphicsDeviceList);
|
||||||
|
DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
|
||||||
|
|
||||||
|
return pGraphicsDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PGRAPHICS_DEVICE
|
||||||
|
NTAPI
|
||||||
|
EngpFindGraphicsDevice(
|
||||||
|
PUNICODE_STRING pustrDevice,
|
||||||
|
ULONG iDevNum,
|
||||||
|
DWORD dwFlags)
|
||||||
|
{
|
||||||
|
UNICODE_STRING ustrCurrent;
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Lock list */
|
||||||
|
EngAcquireSemaphore(ghsemGraphicsDeviceList);
|
||||||
|
|
||||||
|
if (pustrDevice)
|
||||||
|
{
|
||||||
|
/* Loop through the list of devices */
|
||||||
|
for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
|
||||||
|
pGraphicsDevice;
|
||||||
|
pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++)
|
||||||
|
{
|
||||||
|
/* Compare the device name */
|
||||||
|
RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
|
||||||
|
if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Loop through the list of devices */
|
||||||
|
for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
|
||||||
|
pGraphicsDevice && i < iDevNum;
|
||||||
|
pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock list */
|
||||||
|
EngReleaseSemaphore(ghsemGraphicsDeviceList);
|
||||||
|
|
||||||
|
return pGraphicsDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EngpFileIoRequest(
|
EngpFileIoRequest(
|
||||||
|
@ -39,7 +293,7 @@ EngpFileIoRequest(
|
||||||
/* Initialize an event */
|
/* Initialize an event */
|
||||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
/* Build IPR */
|
/* Build IRP */
|
||||||
liStartOffset.QuadPart = ullStartOffset;
|
liStartOffset.QuadPart = ullStartOffset;
|
||||||
pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
|
pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
|
||||||
pDeviceObject,
|
pDeviceObject,
|
||||||
|
@ -113,7 +367,7 @@ EngFileIoControl(
|
||||||
/* Initialize an event */
|
/* Initialize an event */
|
||||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
/* Build IO control IPR */
|
/* Build IO control IRP */
|
||||||
pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
|
pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
|
||||||
pDeviceObject,
|
pDeviceObject,
|
||||||
lpInBuffer,
|
lpInBuffer,
|
||||||
|
|
492
subsystems/win32/win32k/eng/ldevobj.c
Normal file
492
subsystems/win32/win32k/eng/ldevobj.c
Normal file
|
@ -0,0 +1,492 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* PURPOSE: Support for logical devices
|
||||||
|
* FILE: subsystems/win32/win32k/eng/ldevobj.c
|
||||||
|
* PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <w32k.h>
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#ifndef RVA_TO_ADDR
|
||||||
|
#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Globals *******************************************************************/
|
||||||
|
|
||||||
|
HSEMAPHORE ghsemLDEVList;
|
||||||
|
LDEVOBJ *gpldevHead = NULL;
|
||||||
|
LDEVOBJ *gpldevWin32k = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/** Private functions *********************************************************/
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitLDEVImpl()
|
||||||
|
{
|
||||||
|
/* Initialize the loader lock */
|
||||||
|
ghsemLDEVList = EngCreateSemaphore();
|
||||||
|
if (!ghsemLDEVList)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a LDEVOBJ for win32k */
|
||||||
|
gpldevWin32k = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(LDEVOBJ) +
|
||||||
|
sizeof(SYSTEM_GDI_DRIVER_INFORMATION),
|
||||||
|
GDITAG_LDEV);
|
||||||
|
if (!gpldevWin32k)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the LDEVOBJ for win32k */
|
||||||
|
gpldevWin32k->pldevNext = NULL;
|
||||||
|
gpldevWin32k->pldevPrev = NULL;
|
||||||
|
gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY;
|
||||||
|
gpldevWin32k->cRefs = 1;
|
||||||
|
gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION;
|
||||||
|
gpldevWin32k->pGdiDriverInfo = (PVOID)(gpldevWin32k + 1);
|
||||||
|
gpldevWin32k->pGdiDriverInfo->DriverName.Buffer = NULL; // FIXME
|
||||||
|
gpldevWin32k->pGdiDriverInfo->ImageAddress = &__ImageBase;
|
||||||
|
gpldevWin32k->pGdiDriverInfo->SectionPointer = NULL;
|
||||||
|
gpldevWin32k->pGdiDriverInfo->EntryPoint = (PVOID)DriverEntry;
|
||||||
|
gpldevWin32k->pGdiDriverInfo->ExportSectionPointer = NULL;
|
||||||
|
gpldevWin32k->pGdiDriverInfo->ImageLength = 0; // FIXME;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
|
||||||
|
{
|
||||||
|
PLDEVOBJ pldev;
|
||||||
|
|
||||||
|
/* Allocate the structure from paged pool */
|
||||||
|
pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV);
|
||||||
|
if (!pldev)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to allocate LDEVOBJ.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero out the structure */
|
||||||
|
RtlZeroMemory(pldev, sizeof(LDEVOBJ));
|
||||||
|
|
||||||
|
/* Set the ldevtype */
|
||||||
|
pldev->ldevtype = ldevtype;
|
||||||
|
|
||||||
|
return pldev;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
|
||||||
|
{
|
||||||
|
/* Make sure we don't have a driver loaded */
|
||||||
|
ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
|
||||||
|
|
||||||
|
/* Free the memory */
|
||||||
|
ExFreePoolWithTag(pldev, TAG_LDEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
PDEVMODEINFO
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_pdmiGetModes(
|
||||||
|
PLDEVOBJ pldev,
|
||||||
|
HANDLE hDriver)
|
||||||
|
{
|
||||||
|
ULONG cbSize, cbFull;
|
||||||
|
PDEVMODEINFO pdminfo;
|
||||||
|
|
||||||
|
DPRINT1("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
|
||||||
|
|
||||||
|
/* Call the driver to get the required size */
|
||||||
|
cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
|
||||||
|
if (!cbSize)
|
||||||
|
{
|
||||||
|
DPRINT1("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)
|
||||||
|
{
|
||||||
|
DPRINT1("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 */
|
||||||
|
DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode);
|
||||||
|
ExFreePool(pdminfo);
|
||||||
|
pdminfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdminfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_bLoadImage(
|
||||||
|
IN PLDEVOBJ pldev,
|
||||||
|
PUNICODE_STRING pstrPathName)
|
||||||
|
{
|
||||||
|
PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG cbSize;
|
||||||
|
|
||||||
|
/* Make sure no image is loaded yet */
|
||||||
|
ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
|
||||||
|
|
||||||
|
/* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
|
||||||
|
cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length;
|
||||||
|
pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
|
||||||
|
if (!pDriverInfo)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the UNICODE_STRING */
|
||||||
|
pDriverInfo->DriverName.Buffer = (PWSTR)(pDriverInfo + 1);
|
||||||
|
pDriverInfo->DriverName.Length = pstrPathName->Length;
|
||||||
|
pDriverInfo->DriverName.MaximumLength = pstrPathName->Length;
|
||||||
|
|
||||||
|
/* Copy the driver name */
|
||||||
|
// RtlCopyUnicodeString(pDriverInfo->DriverName, pstrPathName);
|
||||||
|
RtlCopyMemory(pDriverInfo->DriverName.Buffer,
|
||||||
|
pstrPathName->Buffer,
|
||||||
|
pstrPathName->Length);
|
||||||
|
|
||||||
|
/* Try to load the driver */
|
||||||
|
Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
|
||||||
|
pDriverInfo,
|
||||||
|
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to load a GDI driver: '%S'\n", pstrPathName->Buffer);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
/* Free the allocated memory */
|
||||||
|
ExFreePoolWithTag(pDriverInfo, TAG_LDEV);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the driver info */
|
||||||
|
pldev->pGdiDriverInfo = pDriverInfo;
|
||||||
|
|
||||||
|
/* Return success. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_vUnloadImage(
|
||||||
|
IN PLDEVOBJ pldev)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Make sure we have a driver info */
|
||||||
|
ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
|
||||||
|
|
||||||
|
/* Check if we have loaded a driver */
|
||||||
|
if (pldev->pfn.DisableDriver)
|
||||||
|
{
|
||||||
|
/* Call the unload function */
|
||||||
|
pldev->pfn.DisableDriver();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unload the driver */
|
||||||
|
Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
|
||||||
|
&pldev->pGdiDriverInfo->ImageAddress,
|
||||||
|
sizeof(HANDLE));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to unload the driver, this is bad.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the driver info structure */
|
||||||
|
ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV);
|
||||||
|
pldev->pGdiDriverInfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_bLoadDriver(
|
||||||
|
IN PLDEVOBJ pldev)
|
||||||
|
{
|
||||||
|
PFN_DrvEnableDriver pfnEnableDriver;
|
||||||
|
DRVENABLEDATA ded;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Make sure we have a driver info */
|
||||||
|
ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
|
||||||
|
|
||||||
|
/* Call the drivers DrvEnableDriver function */
|
||||||
|
RtlZeroMemory(&ded, sizeof(ded));
|
||||||
|
pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint;
|
||||||
|
if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
|
||||||
|
{
|
||||||
|
DPRINT1("DrvEnableDriver failed\n");
|
||||||
|
|
||||||
|
/* Unload the image. */
|
||||||
|
LDEVOBJ_vUnloadImage(pldev);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the returned driver version */
|
||||||
|
pldev->ulDriverVersion = ded.iDriverVersion;
|
||||||
|
|
||||||
|
/* Fill the driver function array */
|
||||||
|
for (i = 0; i < ded.c; i++)
|
||||||
|
{
|
||||||
|
pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_pvFindImageProcAddress(
|
||||||
|
IN PLDEVOBJ pldev,
|
||||||
|
IN LPSTR pszProcName)
|
||||||
|
{
|
||||||
|
PVOID pvImageBase;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY pExportDir;
|
||||||
|
PVOID pvProcAdress = NULL;
|
||||||
|
PUSHORT pOrdinals;
|
||||||
|
PULONG pNames, pAddresses;
|
||||||
|
ULONG i, cbSize;
|
||||||
|
|
||||||
|
/* Make sure we have a driver info */
|
||||||
|
ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
|
||||||
|
|
||||||
|
/* Get the pointer to the export directory */
|
||||||
|
pvImageBase = pldev->pGdiDriverInfo->ImageAddress;
|
||||||
|
pExportDir = RtlImageDirectoryEntryToData(pvImageBase,
|
||||||
|
TRUE,
|
||||||
|
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||||
|
&cbSize);
|
||||||
|
if (!pExportDir)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get pointers to some tables */
|
||||||
|
pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames);
|
||||||
|
pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals);
|
||||||
|
pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions);
|
||||||
|
|
||||||
|
/* Loop the export table */
|
||||||
|
for (i = 0; i < pExportDir->NumberOfNames; i++)
|
||||||
|
{
|
||||||
|
/* Compare the name */
|
||||||
|
if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0)
|
||||||
|
{
|
||||||
|
/* Found! Calculate the procedure address */
|
||||||
|
pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the address */
|
||||||
|
return pvProcAdress;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
EngLoadImageEx(
|
||||||
|
LPWSTR pwszDriverName,
|
||||||
|
ULONG ldevtype)
|
||||||
|
{
|
||||||
|
PLDEVOBJ pldev;
|
||||||
|
UNICODE_STRING strDriverName;
|
||||||
|
|
||||||
|
DPRINT("EngLoadImageEx(%ls, %ld)\n", pwszDriverName, ldevtype);
|
||||||
|
|
||||||
|
/* Initialize the driver name */
|
||||||
|
RtlInitUnicodeString(&strDriverName, pwszDriverName);
|
||||||
|
|
||||||
|
/* Lock loader */
|
||||||
|
EngAcquireSemaphore(ghsemLDEVList);
|
||||||
|
|
||||||
|
/* Search the List of LDEVS for the driver name */
|
||||||
|
for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
|
||||||
|
{
|
||||||
|
/* Check if the ldev is associated with a file */
|
||||||
|
if (pldev->pGdiDriverInfo)
|
||||||
|
{
|
||||||
|
/* Check for match */
|
||||||
|
if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
|
||||||
|
{
|
||||||
|
/* Image found in LDEV list */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we find one? */
|
||||||
|
if (!pldev)
|
||||||
|
{
|
||||||
|
/* No, allocate a new LDEVOBJ */
|
||||||
|
pldev = LDEVOBJ_AllocLDEV(ldevtype);
|
||||||
|
if (!pldev)
|
||||||
|
{
|
||||||
|
DPRINT1("Could not allocate LDEV\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the image */
|
||||||
|
if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
|
||||||
|
{
|
||||||
|
LDEVOBJ_vFreeLDEV(pldev);
|
||||||
|
pldev = NULL;
|
||||||
|
DPRINT1("LDEVOBJ_bLoadImage failed\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shall we load a driver? */
|
||||||
|
if (ldevtype != LDEV_IMAGE)
|
||||||
|
{
|
||||||
|
/* Load the driver */
|
||||||
|
if (!LDEVOBJ_bLoadDriver(pldev))
|
||||||
|
{
|
||||||
|
DPRINT1("LDEVOBJ_bLoadDriver failed\n");
|
||||||
|
LDEVOBJ_vFreeLDEV(pldev);
|
||||||
|
pldev = NULL;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the LDEV into the global list */
|
||||||
|
pldev->pldevPrev = NULL;
|
||||||
|
pldev->pldevNext = gpldevHead;
|
||||||
|
gpldevHead = pldev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase ref count */
|
||||||
|
pldev->cRefs++;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
/* Unlock loader */
|
||||||
|
EngReleaseSemaphore(ghsemLDEVList);
|
||||||
|
|
||||||
|
DPRINT("EngLoadImageEx returning %p\n", pldev);
|
||||||
|
|
||||||
|
return pldev;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
APIENTRY
|
||||||
|
EngLoadDriver(
|
||||||
|
LPWSTR pwszDriverName,
|
||||||
|
ULONG ldevtype)
|
||||||
|
{
|
||||||
|
WCHAR acwBuffer[MAX_PATH];
|
||||||
|
PLDEVOBJ pldev;
|
||||||
|
|
||||||
|
ASSERT(pwszDriverName);
|
||||||
|
DPRINT("EngLoadDriver(%ls, %ld)\n", pwszDriverName, ldevtype);
|
||||||
|
|
||||||
|
/* Create a full file name */ // FIXME: do better than that
|
||||||
|
swprintf(acwBuffer, L"\\SystemRoot\\System32\\%ls.dll", pwszDriverName);
|
||||||
|
|
||||||
|
pldev = EngLoadImageEx(acwBuffer, ldevtype);
|
||||||
|
|
||||||
|
return pldev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exported functions ********************************************************/
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
APIENTRY
|
||||||
|
EngLoadImage(
|
||||||
|
LPWSTR pwszDriverName)
|
||||||
|
{
|
||||||
|
return (HANDLE)EngLoadImageEx(pwszDriverName, LDEV_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
APIENTRY
|
||||||
|
EngUnloadImage(
|
||||||
|
IN HANDLE hModule)
|
||||||
|
{
|
||||||
|
PLDEVOBJ pldev = (PLDEVOBJ)hModule;
|
||||||
|
|
||||||
|
/* Make sure the LDEV is in the list */
|
||||||
|
ASSERT(pldev->pldevPrev || pldev->pldevNext);
|
||||||
|
|
||||||
|
/* Lock loader */
|
||||||
|
EngAcquireSemaphore(ghsemLDEVList);
|
||||||
|
|
||||||
|
/* Decrement reference count */
|
||||||
|
pldev->cRefs--;
|
||||||
|
|
||||||
|
/* No more references left? */
|
||||||
|
if (pldev->cRefs == 0)
|
||||||
|
{
|
||||||
|
/* Remove ldev from the list */
|
||||||
|
if (pldev->pldevPrev)
|
||||||
|
pldev->pldevPrev->pldevNext = pldev->pldevNext;
|
||||||
|
if (pldev->pldevNext)
|
||||||
|
pldev->pldevNext->pldevPrev = pldev->pldevPrev;
|
||||||
|
|
||||||
|
/* Unload the image */
|
||||||
|
LDEVOBJ_vUnloadImage(pldev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock loader */
|
||||||
|
EngReleaseSemaphore(ghsemLDEVList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
APIENTRY
|
||||||
|
EngFindImageProcAddress(
|
||||||
|
IN HANDLE hModule,
|
||||||
|
IN LPSTR lpProcName)
|
||||||
|
{
|
||||||
|
PLDEVOBJ pldev = (PLDEVOBJ)hModule;
|
||||||
|
|
||||||
|
ASSERT(gpldevWin32k != NULL);
|
||||||
|
|
||||||
|
/* Check if win32k is requested */
|
||||||
|
if (!pldev)
|
||||||
|
{
|
||||||
|
pldev = gpldevWin32k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the drivers entry point is requested */
|
||||||
|
if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0)
|
||||||
|
{
|
||||||
|
return pldev->pGdiDriverInfo->EntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to find the address */
|
||||||
|
return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName);
|
||||||
|
}
|
||||||
|
|
793
subsystems/win32/win32k/eng/pdevobj.c
Normal file
793
subsystems/win32/win32k/eng/pdevobj.c
Normal file
|
@ -0,0 +1,793 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* PURPOSE: Support for physical devices
|
||||||
|
* FILE: subsystems/win32/win32k/eng/pdevobj.c
|
||||||
|
* PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <w32k.h>
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
static PPDEVOBJ gppdevList = NULL;
|
||||||
|
PPDEVOBJ gppdevPrimary = NULL;
|
||||||
|
static HSEMAPHORE ghsemPDEV;
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitPDEVImpl()
|
||||||
|
{
|
||||||
|
ghsemPDEV = EngCreateSemaphore();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPDEVOBJ
|
||||||
|
PDEVOBJ_AllocPDEV()
|
||||||
|
{
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
|
||||||
|
ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
|
||||||
|
if (!ppdev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
|
||||||
|
|
||||||
|
ppdev->cPdevRefs = 1;
|
||||||
|
|
||||||
|
return ppdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vRelease(PPDEVOBJ ppdev)
|
||||||
|
{
|
||||||
|
/* Lock loader */
|
||||||
|
EngAcquireSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
/* Decrease reference count */
|
||||||
|
--ppdev->cPdevRefs;
|
||||||
|
|
||||||
|
/* Check if references are left */
|
||||||
|
if (ppdev->cPdevRefs == 0)
|
||||||
|
{
|
||||||
|
// FIXME: should delete the PDEV now
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock loader */
|
||||||
|
EngReleaseSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_bEnablePDEV(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVMODEW pdevmode,
|
||||||
|
PWSTR pwszLogAddress)
|
||||||
|
{
|
||||||
|
PFN_DrvEnablePDEV pfnEnablePDEV;
|
||||||
|
|
||||||
|
DPRINT1("PDEVOBJ_bEnablePDEV()\n");
|
||||||
|
|
||||||
|
/* Get the DrvEnablePDEV function */
|
||||||
|
pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV;
|
||||||
|
|
||||||
|
/* Call the drivers DrvEnablePDEV function */
|
||||||
|
ppdev->dhpdev = pfnEnablePDEV(pdevmode,
|
||||||
|
pwszLogAddress,
|
||||||
|
HS_DDI_MAX,
|
||||||
|
ppdev->ahsurf,
|
||||||
|
sizeof(GDIINFO),
|
||||||
|
&ppdev->gdiinfo,
|
||||||
|
sizeof(DEVINFO),
|
||||||
|
&ppdev->devinfo,
|
||||||
|
(HDEV)ppdev,
|
||||||
|
ppdev->pGraphicsDevice->pwszDescription,
|
||||||
|
ppdev->pGraphicsDevice->DeviceObject);
|
||||||
|
|
||||||
|
DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vCompletePDEV(
|
||||||
|
PPDEVOBJ ppdev)
|
||||||
|
{
|
||||||
|
/* Call the drivers DrvCompletePDEV function */
|
||||||
|
ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
PSURFACE
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_pSurface(
|
||||||
|
PPDEVOBJ ppdev)
|
||||||
|
{
|
||||||
|
HSURF hsurf;
|
||||||
|
|
||||||
|
DPRINT1("PDEVOBJ_pSurface()\n");
|
||||||
|
|
||||||
|
/* Check if we already have a surface */
|
||||||
|
if (ppdev->pSurface)
|
||||||
|
{
|
||||||
|
/* Increment reference count */
|
||||||
|
GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Call the drivers DrvEnableSurface */
|
||||||
|
hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
|
||||||
|
|
||||||
|
/* Lock the surface */
|
||||||
|
ppdev->pSurface = SURFACE_ShareLockSurface(hsurf);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface);
|
||||||
|
return ppdev->pSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDEVMODEW
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_pdmMatchDevMode(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVMODEW pdm)
|
||||||
|
{
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
PDEVMODEW pdmCurrent;
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
pGraphicsDevice = ppdev->pGraphicsDevice;
|
||||||
|
|
||||||
|
for (i = 0; i < pGraphicsDevice->cDevModes; i++)
|
||||||
|
{
|
||||||
|
pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
|
||||||
|
|
||||||
|
/* Compare DEVMODE fields */
|
||||||
|
if (pdmCurrent->dmBitsPerPel == pdm->dmBitsPerPel &&
|
||||||
|
pdmCurrent->dmPelsWidth == pdm->dmPelsWidth &&
|
||||||
|
pdmCurrent->dmPelsHeight == pdm->dmPelsHeight &&
|
||||||
|
pdmCurrent->dmDisplayFrequency == pdm->dmDisplayFrequency)
|
||||||
|
{
|
||||||
|
/* Match! Return the DEVMODE */
|
||||||
|
return pdmCurrent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
PPDEVOBJ
|
||||||
|
EngpCreatePDEV(
|
||||||
|
PUNICODE_STRING pustrDeviceName,
|
||||||
|
PDEVMODEW pdm)
|
||||||
|
{
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
|
||||||
|
/* Try to find the GRAPHICS_DEVICE */
|
||||||
|
pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
|
||||||
|
if (!pGraphicsDevice)
|
||||||
|
{
|
||||||
|
DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
|
||||||
|
pustrDeviceName ? pustrDeviceName->Buffer : 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new PDEVOBJ */
|
||||||
|
ppdev = PDEVOBJ_AllocPDEV();
|
||||||
|
if (!ppdev)
|
||||||
|
{
|
||||||
|
DPRINT1("failed to allocate a PDEV\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no DEVMODEW is given, ... */
|
||||||
|
if (!pdm)
|
||||||
|
{
|
||||||
|
/* ... use the device's default one */
|
||||||
|
pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
|
||||||
|
DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to get a diplay driver */
|
||||||
|
ppdev->pldev = EngLoadDriver(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
|
||||||
|
if (!ppdev->pldev)
|
||||||
|
{
|
||||||
|
DPRINT1("Could not load diplsay driver '%ls'\n", pGraphicsDevice->pDiplayDrivers);
|
||||||
|
ExFreePoolWithTag(ppdev, GDITAG_PDEV);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the function table */
|
||||||
|
ppdev->pfn = ppdev->pldev->pfn;
|
||||||
|
|
||||||
|
/* Set MovePointer function */
|
||||||
|
ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
|
||||||
|
if (!ppdev->pfnMovePointer)
|
||||||
|
ppdev->pfnMovePointer = EngMovePointer;
|
||||||
|
|
||||||
|
ppdev->pGraphicsDevice = pGraphicsDevice;
|
||||||
|
ppdev->hsemDevLock = EngCreateSemaphore();
|
||||||
|
ppdev->pdmwDev = pGraphicsDevice->pDevModeList[pGraphicsDevice->iCurrentMode].pdm;
|
||||||
|
|
||||||
|
/* FIXME! */
|
||||||
|
ppdev->flFlags = PDEV_DISPLAY;
|
||||||
|
|
||||||
|
/* HACK: Don't use the pointer */
|
||||||
|
ppdev->Pointer.Exclude.right = -1;
|
||||||
|
|
||||||
|
/* Call the driver to enable the PDEV */
|
||||||
|
if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to enable PDEV!\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix up some values */
|
||||||
|
if (ppdev->gdiinfo.ulLogPixelsX == 0)
|
||||||
|
ppdev->gdiinfo.ulLogPixelsX = 96;
|
||||||
|
|
||||||
|
if (ppdev->gdiinfo.ulLogPixelsY == 0)
|
||||||
|
ppdev->gdiinfo.ulLogPixelsY = 96;
|
||||||
|
|
||||||
|
/* FIXME: this must be done in a better way */
|
||||||
|
pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
|
||||||
|
|
||||||
|
/* Tell the driver that the PDEV is ready */
|
||||||
|
PDEVOBJ_vCompletePDEV(ppdev);
|
||||||
|
|
||||||
|
/* Return the PDEV */
|
||||||
|
return ppdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vSwitchPdev(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PPDEVOBJ ppdev2)
|
||||||
|
{
|
||||||
|
PDEVOBJ pdevTmp;
|
||||||
|
HDEV hdev;
|
||||||
|
|
||||||
|
/* Exchange data */
|
||||||
|
pdevTmp = *ppdev;
|
||||||
|
|
||||||
|
/* Exchange driver functions */
|
||||||
|
ppdev->pfn = ppdev2->pfn;
|
||||||
|
ppdev2->pfn = pdevTmp.pfn;
|
||||||
|
|
||||||
|
/* Exchange LDEVs */
|
||||||
|
ppdev->pldev = ppdev2->pldev;
|
||||||
|
ppdev2->pldev = pdevTmp.pldev;
|
||||||
|
|
||||||
|
/* Exchange DHPDEV */
|
||||||
|
ppdev->dhpdev = ppdev2->dhpdev;
|
||||||
|
ppdev2->dhpdev = pdevTmp.dhpdev;
|
||||||
|
|
||||||
|
/* Exchange surface */
|
||||||
|
ppdev->pSurface = ppdev2->pSurface;
|
||||||
|
ppdev2->pSurface = pdevTmp.pSurface;
|
||||||
|
hdev = ppdev->pSurface->SurfObj.hdev;
|
||||||
|
ppdev->pSurface->SurfObj.hdev = ppdev2->pSurface->SurfObj.hdev;
|
||||||
|
ppdev2->pSurface->SurfObj.hdev = hdev;
|
||||||
|
|
||||||
|
/* Exchange devinfo */
|
||||||
|
ppdev->devinfo = ppdev2->devinfo;
|
||||||
|
ppdev2->devinfo = pdevTmp.devinfo;
|
||||||
|
|
||||||
|
/* Exchange gdiinfo */
|
||||||
|
ppdev->gdiinfo = ppdev2->gdiinfo;
|
||||||
|
ppdev2->gdiinfo = pdevTmp.gdiinfo;
|
||||||
|
|
||||||
|
/* Notify each driver instance of its new HDEV association */
|
||||||
|
ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
|
||||||
|
ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestDraw()
|
||||||
|
{
|
||||||
|
RECTL rclTrg;
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
PDC pdc;
|
||||||
|
|
||||||
|
ppdev = EngpGetPDEV(0);
|
||||||
|
|
||||||
|
pdc = DC_AllocDcWithHandle();
|
||||||
|
DC_vInitDc(pdc, 0, ppdev);
|
||||||
|
|
||||||
|
|
||||||
|
rclTrg.left = rclTrg.top = 0;
|
||||||
|
rclTrg.right = rclTrg.bottom = 400;
|
||||||
|
|
||||||
|
IntEngBitBltEx(&ppdev->pSurface->SurfObj,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&rclTrg,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&pdc->eboFill.BrushObject,
|
||||||
|
NULL,
|
||||||
|
ROP3_TO_ROP4(PATCOPY),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_bSwitchMode(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVMODEW pdm)
|
||||||
|
{
|
||||||
|
UNICODE_STRING ustrDevice;
|
||||||
|
PPDEVOBJ ppdevTmp;
|
||||||
|
PSURFACE pSurface;
|
||||||
|
BOOL retval = FALSE;
|
||||||
|
|
||||||
|
// FIXME: dynamic mode switching is broken, need to fix PDEV locking first!
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Lock the PDEV */
|
||||||
|
EngAcquireSemaphore(ppdev->hsemDevLock);
|
||||||
|
|
||||||
|
DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
|
||||||
|
|
||||||
|
// Lookup the GraphicsDevice + select DEVMODE
|
||||||
|
// pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
|
||||||
|
|
||||||
|
/* 1. Temporarily disable the current PDEV */
|
||||||
|
if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
|
||||||
|
{
|
||||||
|
DPRINT1("DrvAssertMode failed\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. Create new PDEV */
|
||||||
|
RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
|
||||||
|
ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
|
||||||
|
if (!ppdevTmp)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create a new PDEV\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. Create a new surface */
|
||||||
|
pSurface = PDEVOBJ_pSurface(ppdevTmp);
|
||||||
|
if (!pSurface)
|
||||||
|
{
|
||||||
|
DPRINT1("DrvEnableSurface failed\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(pSurface->BitsLock);
|
||||||
|
|
||||||
|
/* 4. Get DirectDraw information */
|
||||||
|
/* 5. Enable DirectDraw Not traced */
|
||||||
|
/* 6. Copy old PDEV state to new PDEV instance */
|
||||||
|
|
||||||
|
/* 7. Switch the PDEVs */
|
||||||
|
PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp);
|
||||||
|
ASSERT(ppdev->pSurface->BitsLock);
|
||||||
|
|
||||||
|
/* 8. Disable DirectDraw */
|
||||||
|
|
||||||
|
/* 9. Disable old surface */
|
||||||
|
SURFACE_ShareUnlockSurface(ppdevTmp->pSurface);
|
||||||
|
ppdevTmp->pfn.DisableSurface(ppdevTmp->dhpdev);
|
||||||
|
|
||||||
|
/* 10. Disable old PDEV */
|
||||||
|
ppdevTmp->pfn.DisablePDEV(ppdevTmp->dhpdev);
|
||||||
|
// PDEVOBJ_vReleasePdev(ppdevTmp);
|
||||||
|
|
||||||
|
/* Success! */
|
||||||
|
retval = TRUE;
|
||||||
|
leave:
|
||||||
|
/* Unlock PDEV */
|
||||||
|
EngReleaseSemaphore(ppdev->hsemDevLock);
|
||||||
|
|
||||||
|
DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
|
||||||
|
ASSERT(ppdev->pSurface->BitsLock);
|
||||||
|
|
||||||
|
TestDraw();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
EngpGetPDEV(
|
||||||
|
PUNICODE_STRING pustrDeviceName)
|
||||||
|
{
|
||||||
|
UNICODE_STRING ustrCurrent;
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
|
||||||
|
/* Acquire PDEV lock */
|
||||||
|
EngAcquireSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
/* If no device name is given, ... */
|
||||||
|
if (!pustrDeviceName && gppdevPrimary)
|
||||||
|
{
|
||||||
|
/* ... use the primary PDEV */
|
||||||
|
ppdev = gppdevPrimary;
|
||||||
|
|
||||||
|
/* Reference the pdev */
|
||||||
|
InterlockedIncrement(&ppdev->cPdevRefs);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop all present PDEVs */
|
||||||
|
for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
|
||||||
|
{
|
||||||
|
/* Get a pointer to the GRAPHICS_DEVICE */
|
||||||
|
pGraphicsDevice = ppdev->pGraphicsDevice;
|
||||||
|
|
||||||
|
/* Compare the name */
|
||||||
|
RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
|
||||||
|
if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
|
||||||
|
{
|
||||||
|
/* Found! Reference the PDEV */
|
||||||
|
InterlockedIncrement(&ppdev->cPdevRefs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we find one? */
|
||||||
|
if (!ppdev)
|
||||||
|
{
|
||||||
|
/* No, create a new PDEV */
|
||||||
|
ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
|
||||||
|
if (ppdev)
|
||||||
|
{
|
||||||
|
/* Insert the PDEV into the list */
|
||||||
|
ppdev->ppdevNext = gppdevList;
|
||||||
|
gppdevList = ppdev;
|
||||||
|
|
||||||
|
/* Set as primary PDEV, if we don't have one yet */
|
||||||
|
if (!gppdevPrimary)
|
||||||
|
{
|
||||||
|
gppdevPrimary = ppdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
/* Release PDEV lock */
|
||||||
|
EngReleaseSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
return ppdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
|
||||||
|
{
|
||||||
|
INT ret = CM_NONE;
|
||||||
|
|
||||||
|
if (ppdev->flFlags & PDEV_DISPLAY)
|
||||||
|
{
|
||||||
|
if (ppdev->devinfo.iDitherFormat == BMF_8BPP ||
|
||||||
|
ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
|
||||||
|
ret = CM_GAMMA_RAMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
|
||||||
|
ret |= CM_CMYK_COLOR;
|
||||||
|
if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM)
|
||||||
|
ret |= CM_DEVICE_ICM;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vGetDeviceCaps(
|
||||||
|
IN PPDEVOBJ ppdev,
|
||||||
|
OUT PDEVCAPS pDevCaps)
|
||||||
|
{
|
||||||
|
PGDIINFO pGdiInfo = &ppdev->gdiinfo;
|
||||||
|
|
||||||
|
pDevCaps->ulVersion = pGdiInfo->ulVersion;
|
||||||
|
pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
|
||||||
|
pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
|
||||||
|
pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
|
||||||
|
pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
|
||||||
|
pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
|
||||||
|
pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
|
||||||
|
pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
|
||||||
|
pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
|
||||||
|
if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
|
||||||
|
pDevCaps->ulPlanes = pGdiInfo->cPlanes;
|
||||||
|
pDevCaps->ulNumPens = pGdiInfo->ulNumColors;
|
||||||
|
if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5;
|
||||||
|
pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev);
|
||||||
|
pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
|
||||||
|
pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
|
||||||
|
pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
|
||||||
|
pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
|
||||||
|
pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
|
||||||
|
pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
|
||||||
|
pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
|
||||||
|
pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
|
||||||
|
pDevCaps->ulColorRes = pGdiInfo->ulDACRed +
|
||||||
|
pGdiInfo->ulDACGreen +
|
||||||
|
pGdiInfo->ulDACBlue;
|
||||||
|
pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
|
||||||
|
pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
|
||||||
|
pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
|
||||||
|
pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
|
||||||
|
pDevCaps->ulTextCaps = pGdiInfo->flTextCaps;
|
||||||
|
pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
|
||||||
|
if (pGdiInfo->ulTechnology != DT_PLOTTER)
|
||||||
|
pDevCaps->ulTextCaps |= TC_VA_ABLE;
|
||||||
|
pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
|
||||||
|
pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
|
||||||
|
pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
|
||||||
|
pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
|
||||||
|
pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
|
||||||
|
pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
|
||||||
|
pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
|
||||||
|
pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
|
||||||
|
pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
|
||||||
|
pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Exported functions ********************************************************/
|
||||||
|
|
||||||
|
LPWSTR
|
||||||
|
APIENTRY
|
||||||
|
EngGetDriverName(IN HDEV hdev)
|
||||||
|
{
|
||||||
|
PPDEVOBJ ppdev = (PPDEVOBJ)hdev;
|
||||||
|
PLDEVOBJ pldev;
|
||||||
|
|
||||||
|
if (!hdev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pldev = ppdev->pldev;
|
||||||
|
ASSERT(pldev);
|
||||||
|
|
||||||
|
if (!pldev->pGdiDriverInfo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return pldev->pGdiDriverInfo->DriverName.Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INT
|
||||||
|
APIENTRY
|
||||||
|
NtGdiGetDeviceCaps(
|
||||||
|
HDC hdc,
|
||||||
|
INT Index)
|
||||||
|
{
|
||||||
|
PDC pdc;
|
||||||
|
DEVCAPS devcaps;
|
||||||
|
|
||||||
|
/* Lock the given DC */
|
||||||
|
pdc = DC_LockDc(hdc);
|
||||||
|
if (!pdc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the data */
|
||||||
|
PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
|
||||||
|
|
||||||
|
/* Unlock the DC */
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
|
/* Return capability */
|
||||||
|
switch (Index)
|
||||||
|
{
|
||||||
|
case DRIVERVERSION:
|
||||||
|
return devcaps.ulVersion;
|
||||||
|
|
||||||
|
case TECHNOLOGY:
|
||||||
|
return devcaps.ulTechnology;
|
||||||
|
|
||||||
|
case HORZSIZE:
|
||||||
|
return devcaps.ulHorzSize;
|
||||||
|
|
||||||
|
case VERTSIZE:
|
||||||
|
return devcaps.ulVertSize;
|
||||||
|
|
||||||
|
case HORZRES:
|
||||||
|
return devcaps.ulHorzRes;
|
||||||
|
|
||||||
|
case VERTRES:
|
||||||
|
return devcaps.ulVertRes;
|
||||||
|
|
||||||
|
case LOGPIXELSX:
|
||||||
|
return devcaps.ulLogPixelsX;
|
||||||
|
|
||||||
|
case LOGPIXELSY:
|
||||||
|
return devcaps.ulLogPixelsY;
|
||||||
|
|
||||||
|
case BITSPIXEL:
|
||||||
|
return devcaps.ulBitsPixel;
|
||||||
|
|
||||||
|
case PLANES:
|
||||||
|
return devcaps.ulPlanes;
|
||||||
|
|
||||||
|
case NUMBRUSHES:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case NUMPENS:
|
||||||
|
return devcaps.ulNumPens;
|
||||||
|
|
||||||
|
case NUMFONTS:
|
||||||
|
return devcaps.ulNumFonts;
|
||||||
|
|
||||||
|
case NUMCOLORS:
|
||||||
|
return devcaps.ulNumColors;
|
||||||
|
|
||||||
|
case ASPECTX:
|
||||||
|
return devcaps.ulAspectX;
|
||||||
|
|
||||||
|
case ASPECTY:
|
||||||
|
return devcaps.ulAspectY;
|
||||||
|
|
||||||
|
case ASPECTXY:
|
||||||
|
return devcaps.ulAspectXY;
|
||||||
|
|
||||||
|
case CLIPCAPS:
|
||||||
|
return CP_RECTANGLE;
|
||||||
|
|
||||||
|
case SIZEPALETTE:
|
||||||
|
return devcaps.ulSizePalette;
|
||||||
|
|
||||||
|
case NUMRESERVED:
|
||||||
|
return 20;
|
||||||
|
|
||||||
|
case COLORRES:
|
||||||
|
return devcaps.ulColorRes;
|
||||||
|
|
||||||
|
case DESKTOPVERTRES:
|
||||||
|
return devcaps.ulVertRes;
|
||||||
|
|
||||||
|
case DESKTOPHORZRES:
|
||||||
|
return devcaps.ulHorzRes;
|
||||||
|
|
||||||
|
case BLTALIGNMENT:
|
||||||
|
return devcaps.ulBltAlignment;
|
||||||
|
|
||||||
|
case SHADEBLENDCAPS:
|
||||||
|
return devcaps.ulShadeBlend;
|
||||||
|
|
||||||
|
case COLORMGMTCAPS:
|
||||||
|
return devcaps.ulColorMgmtCaps;
|
||||||
|
|
||||||
|
case PHYSICALWIDTH:
|
||||||
|
return devcaps.ulPhysicalWidth;
|
||||||
|
|
||||||
|
case PHYSICALHEIGHT:
|
||||||
|
return devcaps.ulPhysicalHeight;
|
||||||
|
|
||||||
|
case PHYSICALOFFSETX:
|
||||||
|
return devcaps.ulPhysicalOffsetX;
|
||||||
|
|
||||||
|
case PHYSICALOFFSETY:
|
||||||
|
return devcaps.ulPhysicalOffsetY;
|
||||||
|
|
||||||
|
case VREFRESH:
|
||||||
|
return devcaps.ulVRefresh;
|
||||||
|
|
||||||
|
case RASTERCAPS:
|
||||||
|
return devcaps.ulRasterCaps;
|
||||||
|
|
||||||
|
case CURVECAPS:
|
||||||
|
return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
|
||||||
|
CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
|
||||||
|
|
||||||
|
case LINECAPS:
|
||||||
|
return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
|
||||||
|
LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
|
||||||
|
|
||||||
|
case POLYGONALCAPS:
|
||||||
|
return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
|
||||||
|
PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
|
||||||
|
|
||||||
|
case TEXTCAPS:
|
||||||
|
return devcaps.ulTextCaps;
|
||||||
|
|
||||||
|
case CAPS1:
|
||||||
|
case PDEVICESIZE:
|
||||||
|
case SCALINGFACTORX:
|
||||||
|
case SCALINGFACTORY:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
APIENTRY
|
||||||
|
NtGdiGetDeviceCapsAll(
|
||||||
|
IN HDC hDC,
|
||||||
|
OUT PDEVCAPS pDevCaps)
|
||||||
|
{
|
||||||
|
PDC pdc;
|
||||||
|
DEVCAPS devcaps;
|
||||||
|
BOOL bResult = TRUE;
|
||||||
|
|
||||||
|
/* Lock the given DC */
|
||||||
|
pdc = DC_LockDc(hDC);
|
||||||
|
if (!pdc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the data */
|
||||||
|
PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
|
||||||
|
|
||||||
|
/* Unlock the DC */
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
|
/* Copy data to caller */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1);
|
||||||
|
RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS));
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
SetLastNtError(_SEH2_GetExceptionCode());
|
||||||
|
bResult = FALSE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHPDEV
|
||||||
|
APIENTRY
|
||||||
|
NtGdiGetDhpdev(
|
||||||
|
IN HDEV hdev)
|
||||||
|
{
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
DHPDEV dhpdev = NULL;
|
||||||
|
|
||||||
|
/* Check parameter */
|
||||||
|
if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Lock PDEV list */
|
||||||
|
EngAcquireSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
/* Walk through the list of PDEVs */
|
||||||
|
for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
|
||||||
|
{
|
||||||
|
/* Compare with the given HDEV */
|
||||||
|
if (ppdev == hdev)
|
||||||
|
{
|
||||||
|
/* Found the PDEV! Get it's dhpdev and break */
|
||||||
|
dhpdev = ppdev->dhpdev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock PDEV list */
|
||||||
|
EngReleaseSemaphore(ghsemPDEV);
|
||||||
|
|
||||||
|
return dhpdev;
|
||||||
|
}
|
|
@ -69,6 +69,15 @@ EngReleaseSemaphore ( IN HSEMAPHORE hsem )
|
||||||
IntGdiReleaseSemaphore ( hsem );
|
IntGdiReleaseSemaphore ( hsem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
EngAcquireSemaphoreShared(
|
||||||
|
IN HSEMAPHORE hsem)
|
||||||
|
{
|
||||||
|
ASSERT(hsem);
|
||||||
|
ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,6 +21,30 @@ typedef struct _DC *PDC;
|
||||||
/* fl */
|
/* fl */
|
||||||
#define DC_FL_PAL_BACK 1
|
#define DC_FL_PAL_BACK 1
|
||||||
|
|
||||||
|
#define DC_DISPLAY 1
|
||||||
|
#define DC_DIRECT 2
|
||||||
|
#define DC_CANCELED 4
|
||||||
|
#define DC_PERMANANT 0x08
|
||||||
|
#define DC_DIRTY_RAO 0x10
|
||||||
|
#define DC_ACCUM_WMGR 0x20
|
||||||
|
#define DC_ACCUM_APP 0x40
|
||||||
|
#define DC_RESET 0x80
|
||||||
|
#define DC_SYNCHRONIZEACCESS 0x100
|
||||||
|
#define DC_EPSPRINTINGESCAPE 0x200
|
||||||
|
#define DC_TEMPINFODC 0x400
|
||||||
|
#define DC_FULLSCREEN 0x800
|
||||||
|
#define DC_IN_CLONEPDEV 0x1000
|
||||||
|
#define DC_REDIRECTION 0x2000
|
||||||
|
#define DC_SHAREACCESS 0x4000
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DCTYPE_DIRECT = 0,
|
||||||
|
DCTYPE_MEMORY = 1,
|
||||||
|
DCTYPE_INFO = 2,
|
||||||
|
} DCTYPE;
|
||||||
|
|
||||||
|
|
||||||
/* Type definitions ***********************************************************/
|
/* Type definitions ***********************************************************/
|
||||||
|
|
||||||
typedef struct _ROS_DC_INFO
|
typedef struct _ROS_DC_INFO
|
||||||
|
@ -140,22 +164,44 @@ typedef struct _DC
|
||||||
|
|
||||||
/* Internal functions *********************************************************/
|
/* Internal functions *********************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define DC_LockDc(hDC) \
|
#define DC_LockDc(hDC) \
|
||||||
((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC))
|
((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC))
|
||||||
#define DC_UnlockDc(pDC) \
|
#define DC_UnlockDc(pDC) \
|
||||||
GDIOBJ_UnlockObjByPtr ((POBJ)pDC)
|
GDIOBJ_UnlockObjByPtr ((POBJ)pDC)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VOID NTAPI EngAcquireSemaphoreShared(IN HSEMAPHORE hsem);
|
||||||
|
|
||||||
|
PDC
|
||||||
|
FORCEINLINE
|
||||||
|
DC_LockDc(HDC hdc)
|
||||||
|
{
|
||||||
|
PDC pdc;
|
||||||
|
pdc = GDIOBJ_LockObj(hdc, GDI_OBJECT_TYPE_DC);
|
||||||
|
// EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
|
||||||
|
return pdc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FORCEINLINE
|
||||||
|
DC_UnlockDc(PDC pdc)
|
||||||
|
{
|
||||||
|
// EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
|
||||||
|
GDIOBJ_UnlockObjByPtr(&pdc->BaseObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern PDC defaultDCstate;
|
extern PDC defaultDCstate;
|
||||||
|
|
||||||
NTSTATUS FASTCALL InitDcImpl(VOID);
|
NTSTATUS FASTCALL InitDcImpl(VOID);
|
||||||
PPDEVOBJ FASTCALL IntEnumHDev(VOID);
|
PPDEVOBJ FASTCALL IntEnumHDev(VOID);
|
||||||
HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver);
|
PDC NTAPI DC_AllocDcWithHandle();
|
||||||
VOID FASTCALL DC_InitDC(HDC DCToInit);
|
VOID FASTCALL DC_InitDC(HDC DCToInit);
|
||||||
HDC FASTCALL DC_FindOpenDC(PUNICODE_STRING Driver);
|
|
||||||
VOID FASTCALL DC_AllocateDcAttr(HDC);
|
VOID FASTCALL DC_AllocateDcAttr(HDC);
|
||||||
VOID FASTCALL DC_FreeDcAttr(HDC);
|
VOID FASTCALL DC_FreeDcAttr(HDC);
|
||||||
BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
|
BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
|
||||||
BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
|
BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
|
||||||
VOID FASTCALL DC_LockDisplay(HDC);
|
VOID FASTCALL DC_LockDisplay(HDC);
|
||||||
VOID FASTCALL DC_UnlockDisplay(HDC);
|
VOID FASTCALL DC_UnlockDisplay(HDC);
|
||||||
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
|
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
|
||||||
|
@ -169,9 +215,13 @@ VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
|
||||||
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
|
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
|
||||||
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
|
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
|
||||||
|
|
||||||
|
VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
|
||||||
|
|
||||||
BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
|
BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
|
||||||
BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
|
BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
|
||||||
VOID FASTCALL DCU_SetDcUndeletable(HDC);
|
VOID FASTCALL DCU_SetDcUndeletable(HDC);
|
||||||
|
VOID NTAPI DC_vFreeDcAttr(PDC pdc);
|
||||||
|
VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
|
||||||
|
|
||||||
COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
|
COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
|
||||||
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
|
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
|
||||||
|
@ -187,9 +237,6 @@ VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
|
||||||
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
|
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
|
||||||
BOOL FASTCALL IntGdiCleanDC(HDC hDC);
|
BOOL FASTCALL IntGdiCleanDC(HDC hDC);
|
||||||
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
|
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
|
||||||
INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
|
|
||||||
|
|
||||||
extern PPDEVOBJ pPrimarySurface;
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -239,8 +286,4 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
|
||||||
pdc->dclevel.ppal = ppal;
|
pdc->dclevel.ppal = ppal;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
IntPrepareDriverIfNeeded(VOID);
|
|
||||||
extern PDEVOBJ PrimarySurface;
|
|
||||||
|
|
||||||
#endif /* not __WIN32K_DC_H */
|
#endif /* not __WIN32K_DC_H */
|
||||||
|
|
70
subsystems/win32/win32k/include/device.h
Normal file
70
subsystems/win32/win32k/include/device.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
//#define _PDEVOBJ _PDEVOBJ2
|
||||||
|
//#define PDEVOBJ PDEVOBJ2
|
||||||
|
//#define PPDEVOBJ PPDEVOBJ2
|
||||||
|
|
||||||
|
//typedef struct _PDEVOBJ *PPDEVOBJ;
|
||||||
|
|
||||||
|
#define TAG_GDEV 'gdev'
|
||||||
|
|
||||||
|
VOID
|
||||||
|
APIENTRY
|
||||||
|
EngFileWrite(
|
||||||
|
IN PFILE_OBJECT pFileObject,
|
||||||
|
IN PVOID lpBuffer,
|
||||||
|
IN SIZE_T nLength,
|
||||||
|
IN PSIZE_T lpBytesWritten);
|
||||||
|
|
||||||
|
PGRAPHICS_DEVICE
|
||||||
|
NTAPI
|
||||||
|
EngpFindGraphicsDevice(
|
||||||
|
PUNICODE_STRING pustrDevice,
|
||||||
|
DWORD iDevNum,
|
||||||
|
DWORD dwFlags);
|
||||||
|
|
||||||
|
PGRAPHICS_DEVICE
|
||||||
|
NTAPI
|
||||||
|
EngpRegisterGraphicsDevice(
|
||||||
|
PUNICODE_STRING pustrDeviceName,
|
||||||
|
PUNICODE_STRING pustrDiplayDrivers,
|
||||||
|
PUNICODE_STRING pustrDescription,
|
||||||
|
PDEVMODEW pdmDefault);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitDeviceImpl();
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
DC_AllocDcAttr(PDC pdc);
|
||||||
|
|
||||||
|
//#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl(TAG('R', 'o', 's', 'D'), (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
|
||||||
|
NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RegOpenKey(
|
||||||
|
LPCWSTR pwszKeyName,
|
||||||
|
PHKEY phkey);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RegQueryValue(
|
||||||
|
IN HKEY hkey,
|
||||||
|
IN PCWSTR pwszValueName,
|
||||||
|
IN ULONG ulType,
|
||||||
|
OUT PVOID pvData,
|
||||||
|
IN OUT PULONG pcbValue);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_bSwitchMode(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVMODEW pdm);
|
||||||
|
|
||||||
|
PDEVMODEW
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_pdmMatchDevMode(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVMODEW pdm);
|
|
@ -163,9 +163,6 @@ IntGetSysColor(INT nIndex);
|
||||||
|
|
||||||
/* Other Stuff */
|
/* Other Stuff */
|
||||||
|
|
||||||
INT FASTCALL
|
|
||||||
IntGdiGetDeviceCaps(PDC dc, INT Index);
|
|
||||||
|
|
||||||
INT
|
INT
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntGdiEscape(PDC dc,
|
IntGdiEscape(PDC dc,
|
||||||
|
@ -182,14 +179,6 @@ IntEnumDisplaySettings(
|
||||||
IN OUT LPDEVMODEW pDevMode,
|
IN OUT LPDEVMODEW pDevMode,
|
||||||
IN DWORD dwFlags);
|
IN DWORD dwFlags);
|
||||||
|
|
||||||
LONG
|
|
||||||
FASTCALL
|
|
||||||
IntChangeDisplaySettings(
|
|
||||||
IN PUNICODE_STRING pDeviceName OPTIONAL,
|
|
||||||
IN LPDEVMODEW pDevMode,
|
|
||||||
IN DWORD dwflags,
|
|
||||||
IN PVOID lParam OPTIONAL);
|
|
||||||
|
|
||||||
HBITMAP
|
HBITMAP
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntCreateCompatibleBitmap(PDC Dc,
|
IntCreateCompatibleBitmap(PDC Dc,
|
||||||
|
|
86
subsystems/win32/win32k/include/ldevobj.h
Normal file
86
subsystems/win32/win32k/include/ldevobj.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/* Hack, for bug in ld. Will be removed soon. */
|
||||||
|
#define __ImageBase _image_base__
|
||||||
|
#endif
|
||||||
|
extern IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
|
|
||||||
|
#define TAG_LDEV 'Gldv'
|
||||||
|
|
||||||
|
#define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LDEV_DEVICE_DISPLAY = 1,
|
||||||
|
LDEV_DEVICE_PRINTER = 2,
|
||||||
|
LDEV_DEVICE_META = 3,
|
||||||
|
LDEV_DEVICE_MIRROR = 4,
|
||||||
|
LDEV_IMAGE = 5,
|
||||||
|
LDEV_FONT = 6,
|
||||||
|
} LDEVTYPE;
|
||||||
|
|
||||||
|
typedef struct _LDEVOBJ
|
||||||
|
{
|
||||||
|
struct _LDEVOBJ *pldevNext;
|
||||||
|
struct _LDEVOBJ *pldevPrev;
|
||||||
|
SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo;
|
||||||
|
LDEVTYPE ldevtype;
|
||||||
|
ULONG cRefs;
|
||||||
|
ULONG ulDriverVersion;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PVOID apfn[INDEX_LAST];
|
||||||
|
DRIVER_FUNCTIONS pfn;
|
||||||
|
};
|
||||||
|
|
||||||
|
} LDEVOBJ, *PLDEVOBJ;
|
||||||
|
|
||||||
|
extern PLDEVOBJ gpldevHead;
|
||||||
|
extern HSEMAPHORE ghsemDriverMgmt;
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_pldevLoadImage(
|
||||||
|
PUNICODE_STRING pusPathName,
|
||||||
|
LDEVTYPE ldevtype);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_bLoadDriver(
|
||||||
|
IN PLDEVOBJ pldev);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_pvFindImageProcAddress(
|
||||||
|
IN PLDEVOBJ pldev,
|
||||||
|
IN LPSTR lpProcName);
|
||||||
|
|
||||||
|
PDEVMODEINFO
|
||||||
|
NTAPI
|
||||||
|
LDEVOBJ_pdmiGetModes(
|
||||||
|
PLDEVOBJ pldev,
|
||||||
|
HANDLE hDriver);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitLDEVImpl();
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
APIENTRY
|
||||||
|
EngLoadDriver(
|
||||||
|
LPWSTR pwszDriverName,
|
||||||
|
ULONG ldevtype);
|
||||||
|
|
||||||
|
PLDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
EngGetLDEV(
|
||||||
|
PDEVMODEW pdm);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
APIENTRY
|
||||||
|
DriverEntry (
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef __WIN32K_PDEVOBJ_H
|
#ifndef __WIN32K_PDEVOBJ_H
|
||||||
#define __WIN32K_PDEVOBJ_H
|
#define __WIN32K_PDEVOBJ_H
|
||||||
|
|
||||||
#include <drivers/directx/directxint.h>
|
|
||||||
|
|
||||||
/* PDEVOBJ flags */
|
/* PDEVOBJ flags */
|
||||||
#define PDEV_DISPLAY 0x00000001 /* Display device */
|
#define PDEV_DISPLAY 0x00000001 /* Display device */
|
||||||
#define PDEV_HARDWARE_POINTER 0x00000002 /* Supports hardware cursor */
|
#define PDEV_HARDWARE_POINTER 0x00000002 /* Supports hardware cursor */
|
||||||
|
@ -38,6 +36,21 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
|
||||||
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
|
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
|
||||||
} GDIPOINTER, *PGDIPOINTER;
|
} GDIPOINTER, *PGDIPOINTER;
|
||||||
|
|
||||||
|
typedef struct _DEVMODEINFO
|
||||||
|
{
|
||||||
|
struct _DEVMODEINFO *pdmiNext;
|
||||||
|
struct _LDEVOBJ *pldev;
|
||||||
|
ULONG cbdevmode;
|
||||||
|
DEVMODEW adevmode[1];
|
||||||
|
} DEVMODEINFO, *PDEVMODEINFO;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
PDEVMODEW pdm;
|
||||||
|
|
||||||
|
} DEVMODEENTRY, *PDEVMODEENTRY;
|
||||||
|
|
||||||
typedef struct _GRAPHICS_DEVICE
|
typedef struct _GRAPHICS_DEVICE
|
||||||
{
|
{
|
||||||
WCHAR szNtDeviceName[CCHDEVICENAME/2];
|
WCHAR szNtDeviceName[CCHDEVICENAME/2];
|
||||||
|
@ -49,15 +62,17 @@ typedef struct _GRAPHICS_DEVICE
|
||||||
DWORD hkClassDriverConfig;
|
DWORD hkClassDriverConfig;
|
||||||
DWORD StateFlags; /* See DISPLAY_DEVICE_* */
|
DWORD StateFlags; /* See DISPLAY_DEVICE_* */
|
||||||
ULONG cbdevmodeInfo;
|
ULONG cbdevmodeInfo;
|
||||||
PVOID devmodeInfo;
|
PDEVMODEINFO pdevmodeInfo;
|
||||||
DWORD cbdevmodeInfo1;
|
ULONG cDevModes;
|
||||||
PVOID devmodeInfo1;
|
PDEVMODEENTRY pDevModeList;
|
||||||
LPWSTR pwszDeviceNames;
|
LPWSTR pDiplayDrivers;
|
||||||
LPWSTR pwszDescription;
|
LPWSTR pwszDescription;
|
||||||
DWORD dwUnknown;
|
DWORD dwUnknown;
|
||||||
PVOID pUnknown;
|
PVOID pUnknown;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
DWORD ProtocolType;
|
DWORD ProtocolType;
|
||||||
|
ULONG iDefaultMode;
|
||||||
|
ULONG iCurrentMode;
|
||||||
} GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
|
} GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
|
||||||
|
|
||||||
typedef struct _PDEVOBJ
|
typedef struct _PDEVOBJ
|
||||||
|
@ -65,8 +80,8 @@ typedef struct _PDEVOBJ
|
||||||
BASEOBJECT BaseObject;
|
BASEOBJECT BaseObject;
|
||||||
|
|
||||||
struct _PDEVOBJ * ppdevNext;
|
struct _PDEVOBJ * ppdevNext;
|
||||||
INT cPdevRefs;
|
LONG cPdevRefs;
|
||||||
INT cPdevOpenRefs;
|
LONG cPdevOpenRefs;
|
||||||
struct _PDEVOBJ * ppdevParent;
|
struct _PDEVOBJ * ppdevParent;
|
||||||
FLONG flFlags; // flags
|
FLONG flFlags; // flags
|
||||||
// FLONG flAccelerated;
|
// FLONG flAccelerated;
|
||||||
|
@ -99,17 +114,17 @@ typedef struct _PDEVOBJ
|
||||||
// PFN_DrvSetPalette pfnDrvSetPalette;
|
// PFN_DrvSetPalette pfnDrvSetPalette;
|
||||||
// PFN_DrvNotify pfnDrvNotify;
|
// PFN_DrvNotify pfnDrvNotify;
|
||||||
// ULONG TagSig;
|
// ULONG TagSig;
|
||||||
// PLDEVOBJ pldev;
|
struct _LDEVOBJ * pldev;
|
||||||
DHPDEV dhpdev; /* DHPDEV for device. */
|
DHPDEV dhpdev; /* DHPDEV for device. */
|
||||||
PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
|
PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
|
||||||
DEVINFO devinfo;
|
DEVINFO devinfo;
|
||||||
GDIINFO gdiinfo;
|
GDIINFO gdiinfo;
|
||||||
HSURF pSurface; /* SURFACE for this device., FIXME: PSURFACE */
|
PSURFACE pSurface; /* SURFACE for this device. */
|
||||||
// HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */
|
// HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */
|
||||||
// PVOID pDesktopId;
|
// PVOID pDesktopId;
|
||||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
// POINTL ptlOrigion;
|
// POINTL ptlOrigion;
|
||||||
PVOID pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
|
PDEVMODEW pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
|
||||||
// DWORD Unknown3;
|
// DWORD Unknown3;
|
||||||
FLONG DxDd_Flags; /* DxDD active status flags. */
|
FLONG DxDd_Flags; /* DxDD active status flags. */
|
||||||
// LONG devAttr;
|
// LONG devAttr;
|
||||||
|
@ -118,15 +133,12 @@ typedef struct _PDEVOBJ
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
DRIVER_FUNCTIONS DriverFunctions;
|
DRIVER_FUNCTIONS DriverFunctions;
|
||||||
|
DRIVER_FUNCTIONS pfn;
|
||||||
PVOID apfn[INDEX_LAST]; // B8C 0x0598
|
PVOID apfn[INDEX_LAST]; // B8C 0x0598
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ros specific */
|
/* ros specific */
|
||||||
ULONG DxDd_nCount;
|
ULONG DxDd_nCount;
|
||||||
ULONG DisplayNumber;
|
|
||||||
DEVMODEW DMW;
|
|
||||||
PFILE_OBJECT VideoFileObject;
|
|
||||||
BOOLEAN PreparedDriver;
|
|
||||||
GDIPOINTER Pointer;
|
GDIPOINTER Pointer;
|
||||||
/* Stuff to keep track of software cursors; win32k gdi part */
|
/* Stuff to keep track of software cursors; win32k gdi part */
|
||||||
UINT SafetyRemoveLevel; /* at what level was the cursor removed?
|
UINT SafetyRemoveLevel; /* at what level was the cursor removed?
|
||||||
|
@ -135,13 +147,43 @@ typedef struct _PDEVOBJ
|
||||||
struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
|
struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
|
||||||
} PDEVOBJ, *PPDEVOBJ;
|
} PDEVOBJ, *PPDEVOBJ;
|
||||||
|
|
||||||
/* PDEV and EDDX extra data container.*/
|
/* Globals ********************************************************************/
|
||||||
typedef struct _PDEVEDD
|
|
||||||
{
|
|
||||||
PDEVOBJ pdevobj;
|
|
||||||
EDD_DIRECTDRAW_GLOBAL EDDgpl;
|
|
||||||
} PDEVEDD, *PPDEVEDD;
|
|
||||||
|
|
||||||
extern ULONG gdwDirectDrawContext;
|
extern PPDEVOBJ gppdevPrimary;
|
||||||
|
#define pPrimarySurface gppdevPrimary
|
||||||
|
|
||||||
|
|
||||||
|
/* Function prototypes ********************************************************/
|
||||||
|
|
||||||
|
PPDEVOBJ
|
||||||
|
NTAPI
|
||||||
|
EngpGetPDEV(PUNICODE_STRING pustrDevice);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vRelease(PPDEVOBJ ppdev);
|
||||||
|
|
||||||
|
PSURFACE
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_pSurface(
|
||||||
|
PPDEVOBJ ppdev);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PDEVOBJ_vGetDeviceCaps(
|
||||||
|
PPDEVOBJ ppdev,
|
||||||
|
PDEVCAPS pDevCaps);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitPDEVImpl();
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitLDEVImpl();
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
NTAPI
|
||||||
|
InitDeviceImpl();
|
||||||
|
|
||||||
#endif /* !__WIN32K_PDEVOBJ_H */
|
#endif /* !__WIN32K_PDEVOBJ_H */
|
||||||
|
|
|
@ -78,6 +78,8 @@
|
||||||
#include <include/gdifloat.h>
|
#include <include/gdifloat.h>
|
||||||
#include <include/engobjects.h>
|
#include <include/engobjects.h>
|
||||||
#include <include/engevent.h>
|
#include <include/engevent.h>
|
||||||
|
#include <include/ldevobj.h>
|
||||||
|
#include <include/device.h>
|
||||||
#include <dib/dib.h>
|
#include <dib/dib.h>
|
||||||
|
|
||||||
#endif /* __WIN32K_H */
|
#endif /* __WIN32K_H */
|
||||||
|
|
|
@ -1,24 +1,4 @@
|
||||||
/*
|
|
||||||
* ReactOS W32 Subsystem
|
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <w32k.h>
|
#include <w32k.h>
|
||||||
|
|
||||||
|
@ -26,239 +6,3 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
extern LIST_ENTRY GlobalDriverListHead;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from
|
|
||||||
* here, though.
|
|
||||||
*/
|
|
||||||
NTSTATUS APIENTRY
|
|
||||||
LdrGetProcedureAddress (IN PVOID BaseAddress,
|
|
||||||
IN PANSI_STRING Name,
|
|
||||||
IN ULONG Ordinal,
|
|
||||||
OUT PVOID *ProcedureAddress)
|
|
||||||
{
|
|
||||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
|
||||||
PUSHORT OrdinalPtr;
|
|
||||||
PULONG NamePtr;
|
|
||||||
PULONG AddressPtr;
|
|
||||||
ULONG i = 0;
|
|
||||||
|
|
||||||
DPRINT("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n",
|
|
||||||
BaseAddress, Name, Ordinal, ProcedureAddress);
|
|
||||||
|
|
||||||
/* Get the pointer to the export directory */
|
|
||||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
|
||||||
RtlImageDirectoryEntryToData (BaseAddress,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
|
||||||
&i);
|
|
||||||
|
|
||||||
DPRINT("ExportDir %x i %lu\n", ExportDir, i);
|
|
||||||
|
|
||||||
if (!ExportDir || !i || !ProcedureAddress)
|
|
||||||
{
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddressPtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfFunctions);
|
|
||||||
if (Name && Name->Length)
|
|
||||||
{
|
|
||||||
/* by name */
|
|
||||||
OrdinalPtr = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals);
|
|
||||||
NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames);
|
|
||||||
for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
|
|
||||||
{
|
|
||||||
if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr)))
|
|
||||||
{
|
|
||||||
*ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DPRINT1("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* by ordinal */
|
|
||||||
Ordinal &= 0x0000FFFF;
|
|
||||||
if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
|
|
||||||
{
|
|
||||||
*ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_PROCEDURE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID APIENTRY
|
|
||||||
EngFindImageProcAddress(IN HANDLE Module,
|
|
||||||
IN LPSTR ProcName)
|
|
||||||
{
|
|
||||||
PVOID Function;
|
|
||||||
NTSTATUS Status;
|
|
||||||
ANSI_STRING ProcNameString;
|
|
||||||
unsigned i;
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
PCSTR ProcName;
|
|
||||||
PVOID ProcAddress;
|
|
||||||
}
|
|
||||||
Win32kExports[] =
|
|
||||||
{
|
|
||||||
{ "BRUSHOBJ_hGetColorTransform", BRUSHOBJ_hGetColorTransform },
|
|
||||||
{ "EngAlphaBlend", EngAlphaBlend },
|
|
||||||
{ "EngClearEvent", EngClearEvent },
|
|
||||||
{ "EngControlSprites", EngControlSprites },
|
|
||||||
{ "EngCreateEvent", EngCreateEvent },
|
|
||||||
{ "EngDeleteEvent", EngDeleteEvent },
|
|
||||||
{ "EngDeleteFile", EngDeleteFile },
|
|
||||||
{ "EngDeleteSafeSemaphore", EngDeleteSafeSemaphore },
|
|
||||||
{ "EngDeleteWnd", EngDeleteWnd },
|
|
||||||
{ "EngDitherColor", EngDitherColor },
|
|
||||||
{ "EngGetPrinterDriver", EngGetPrinterDriver },
|
|
||||||
{ "EngGradientFill", EngGradientFill },
|
|
||||||
{ "EngHangNotification", EngHangNotification },
|
|
||||||
{ "EngInitializeSafeSemaphore", EngInitializeSafeSemaphore },
|
|
||||||
{ "EngLockDirectDrawSurface", EngLockDirectDrawSurface },
|
|
||||||
{ "EngLpkInstalled", EngLpkInstalled },
|
|
||||||
{ "EngMapEvent", EngMapEvent },
|
|
||||||
{ "EngMapFile", EngMapFile },
|
|
||||||
{ "EngMapFontFileFD", EngMapFontFileFD },
|
|
||||||
{ "EngModifySurface", EngModifySurface },
|
|
||||||
{ "EngMovePointer", EngMovePointer },
|
|
||||||
{ "EngPlgBlt", EngPlgBlt },
|
|
||||||
{ "EngQueryDeviceAttribute", EngQueryDeviceAttribute },
|
|
||||||
{ "EngQueryPalette", EngQueryPalette },
|
|
||||||
{ "EngQuerySystemAttribute", EngQuerySystemAttribute },
|
|
||||||
{ "EngReadStateEvent", EngReadStateEvent },
|
|
||||||
{ "EngRestoreFloatingPointState", EngRestoreFloatingPointState },
|
|
||||||
{ "EngSaveFloatingPointState", EngSaveFloatingPointState },
|
|
||||||
{ "EngSetEvent", EngSetEvent },
|
|
||||||
{ "EngSetPointerShape", EngSetPointerShape },
|
|
||||||
{ "EngSetPointerTag", EngSetPointerTag },
|
|
||||||
{ "EngStretchBltROP", EngStretchBltROP },
|
|
||||||
{ "EngTransparentBlt", EngTransparentBlt },
|
|
||||||
{ "EngUnlockDirectDrawSurface", EngUnlockDirectDrawSurface },
|
|
||||||
{ "EngUnmapEvent", EngUnmapEvent },
|
|
||||||
{ "EngUnmapFile", EngUnmapFile },
|
|
||||||
{ "EngUnmapFontFileFD", EngUnmapFontFileFD },
|
|
||||||
{ "EngWaitForSingleObject", EngWaitForSingleObject },
|
|
||||||
{ "FONTOBJ_pfdg", FONTOBJ_pfdg },
|
|
||||||
{ "FONTOBJ_pjOpenTypeTablePointer", FONTOBJ_pjOpenTypeTablePointer },
|
|
||||||
{ "FONTOBJ_pQueryGlyphAttrs", FONTOBJ_pQueryGlyphAttrs },
|
|
||||||
{ "FONTOBJ_pwszFontFilePaths", FONTOBJ_pwszFontFilePaths },
|
|
||||||
{ "HeapVidMemAllocAligned", HeapVidMemAllocAligned },
|
|
||||||
{ "HT_Get8BPPMaskPalette", HT_Get8BPPMaskPalette },
|
|
||||||
{ "STROBJ_bEnumPositionsOnly", STROBJ_bEnumPositionsOnly },
|
|
||||||
{ "STROBJ_bGetAdvanceWidths", STROBJ_bGetAdvanceWidths },
|
|
||||||
{ "STROBJ_fxBreakExtra", STROBJ_fxBreakExtra },
|
|
||||||
{ "STROBJ_fxCharacterExtra", STROBJ_fxCharacterExtra },
|
|
||||||
{ "VidMemFree", VidMemFree },
|
|
||||||
{ "XLATEOBJ_hGetColorTransform", XLATEOBJ_hGetColorTransform }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (NULL == Module)
|
|
||||||
{
|
|
||||||
DPRINT("Looking for win32k export %s\n", ProcName);
|
|
||||||
for (i = 0; i < sizeof(Win32kExports) / sizeof(Win32kExports[0]); i++)
|
|
||||||
{
|
|
||||||
if (0 == strcmp(ProcName, Win32kExports[i].ProcName))
|
|
||||||
{
|
|
||||||
DPRINT("Found it index %u address %p\n", i, Win32kExports[i].ProcName);
|
|
||||||
return Win32kExports[i].ProcAddress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
RtlInitAnsiString(&ProcNameString, ProcName);
|
|
||||||
Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
|
|
||||||
&ProcNameString,
|
|
||||||
0,
|
|
||||||
&Function);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
return(Function);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
HANDLE
|
|
||||||
APIENTRY
|
|
||||||
EngLoadImage (LPWSTR DriverName)
|
|
||||||
{
|
|
||||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
|
||||||
PDRIVERS DriverInfo = NULL;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
|
|
||||||
if( !IsListEmpty(&GlobalDriverListHead) )
|
|
||||||
{
|
|
||||||
PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
|
|
||||||
PDRIVERS Current;
|
|
||||||
/* probably the driver was already loaded, let's try to find it out */
|
|
||||||
while( CurrentEntry != &GlobalDriverListHead )
|
|
||||||
{
|
|
||||||
Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
|
|
||||||
if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) {
|
|
||||||
DriverInfo = Current;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !DriverInfo )
|
|
||||||
{
|
|
||||||
/* the driver was not loaded before, so let's do that */
|
|
||||||
Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
|
||||||
if (!NT_SUCCESS(Status)) {
|
|
||||||
DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DriverInfo = ExAllocatePool(PagedPool, sizeof(DRIVERS));
|
|
||||||
DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength;
|
|
||||||
DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length;
|
|
||||||
DriverInfo->DriverName.Buffer = ExAllocatePool(PagedPool, GdiDriverInfo.DriverName.MaximumLength);
|
|
||||||
RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName);
|
|
||||||
DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer;
|
|
||||||
DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress;
|
|
||||||
InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DriverInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
APIENTRY
|
|
||||||
EngUnloadImage ( IN HANDLE hModule )
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
PDRIVERS DriverInfo = (PDRIVERS)hModule;
|
|
||||||
|
|
||||||
DPRINT("hModule 0x%x\n", hModule);
|
|
||||||
|
|
||||||
Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
|
|
||||||
DriverInfo->SectionPointer, sizeof(PVOID));
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n",
|
|
||||||
Status);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExFreePool(DriverInfo->DriverName.Buffer);
|
|
||||||
RemoveEntryList(&DriverInfo->ListEntry);
|
|
||||||
ExFreePool(DriverInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
|
|
@ -34,8 +34,6 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
|
||||||
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
|
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
|
||||||
PSECTION_OBJECT GdiTableSection = NULL;
|
PSECTION_OBJECT GdiTableSection = NULL;
|
||||||
|
|
||||||
LIST_ENTRY GlobalDriverListHead;
|
|
||||||
|
|
||||||
HANDLE GlobalUserHeap = NULL;
|
HANDLE GlobalUserHeap = NULL;
|
||||||
PSECTION_OBJECT GlobalUserHeapSection = NULL;
|
PSECTION_OBJECT GlobalUserHeapSection = NULL;
|
||||||
|
|
||||||
|
@ -358,6 +356,7 @@ Win32kInitWin32Thread(PETHREAD Thread)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This definition doesn't work
|
* This definition doesn't work
|
||||||
|
@ -413,8 +412,19 @@ DriverEntry (
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize a list of loaded drivers in Win32 subsystem */
|
if (!gpsi)
|
||||||
InitializeListHead(&GlobalDriverListHead);
|
{
|
||||||
|
gpsi = UserHeapAlloc(sizeof(SERVERINFO));
|
||||||
|
if (gpsi)
|
||||||
|
{
|
||||||
|
RtlZeroMemory(gpsi, sizeof(SERVERINFO));
|
||||||
|
DPRINT("Global Server Data -> %x\n", gpsi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
|
if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
|
||||||
|
|
||||||
|
@ -425,6 +435,23 @@ DriverEntry (
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create stock objects, ie. precreated objects commonly
|
||||||
|
used by win32 applications */
|
||||||
|
CreateStockObjects();
|
||||||
|
CreateSysColorObjects();
|
||||||
|
|
||||||
|
InitXlateImpl();
|
||||||
|
InitPDEVImpl();
|
||||||
|
InitLDEVImpl();
|
||||||
|
InitDeviceImpl();
|
||||||
|
|
||||||
|
Status = InitDcImpl();
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to initialize Device context implementation!\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
Status = InitUserImpl();
|
Status = InitUserImpl();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -516,13 +543,6 @@ DriverEntry (
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = InitDcImpl();
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to initialize Device context implementation!\n");
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize FreeType library */
|
/* Initialize FreeType library */
|
||||||
if (! InitFontSupport())
|
if (! InitFontSupport())
|
||||||
{
|
{
|
||||||
|
@ -530,13 +550,6 @@ DriverEntry (
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitXlateImpl();
|
|
||||||
|
|
||||||
/* Create stock objects, ie. precreated objects commonly
|
|
||||||
used by win32 applications */
|
|
||||||
CreateStockObjects();
|
|
||||||
CreateSysColorObjects();
|
|
||||||
|
|
||||||
gusLanguageID = IntGdiGetLanguageID();
|
gusLanguageID = IntGdiGetLanguageID();
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -1,621 +1 @@
|
||||||
/*
|
|
||||||
* ReactOS W32 Subsystem
|
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
* GDI Driver support routines
|
|
||||||
* (mostly swiped from Wine)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <w32k.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
/* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
|
|
||||||
#undef TRACE_DRV_CALLS
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GRAPHICS_DRIVER
|
|
||||||
{
|
|
||||||
PWSTR Name;
|
|
||||||
PFN_DrvEnableDriver EnableDriver;
|
|
||||||
int ReferenceCount;
|
|
||||||
struct _GRAPHICS_DRIVER *Next;
|
|
||||||
} GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
|
|
||||||
|
|
||||||
static PGRAPHICS_DRIVER DriverList;
|
|
||||||
static PGRAPHICS_DRIVER GenericDriver = NULL;
|
|
||||||
|
|
||||||
BOOL DRIVER_RegisterDriver(LPCWSTR Name, PFN_DrvEnableDriver EnableDriver)
|
|
||||||
{
|
|
||||||
PGRAPHICS_DRIVER Driver;
|
|
||||||
|
|
||||||
DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
|
|
||||||
|
|
||||||
if (GenericDriver != NULL)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
|
|
||||||
if (!Driver) return FALSE;
|
|
||||||
Driver->ReferenceCount = 0;
|
|
||||||
Driver->EnableDriver = EnableDriver;
|
|
||||||
if (Name)
|
|
||||||
{
|
|
||||||
Driver->Name = ExAllocatePoolWithTag(PagedPool,
|
|
||||||
(wcslen(Name) + 1) * sizeof(WCHAR),
|
|
||||||
TAG_DRIVER);
|
|
||||||
if (Driver->Name == NULL)
|
|
||||||
{
|
|
||||||
DPRINT1("Out of memory\n");
|
|
||||||
ExFreePoolWithTag(Driver, TAG_DRIVER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
wcscpy(Driver->Name, Name);
|
|
||||||
Driver->Next = DriverList;
|
|
||||||
DriverList = Driver;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericDriver = Driver;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name)
|
|
||||||
{
|
|
||||||
GRAPHICS_DRIVER *Driver = DriverList;
|
|
||||||
while (Driver && Name)
|
|
||||||
{
|
|
||||||
if (!_wcsicmp(Driver->Name, Name))
|
|
||||||
{
|
|
||||||
return Driver->EnableDriver;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name)
|
|
||||||
{
|
|
||||||
static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
|
|
||||||
static WCHAR DefaultExtension[] = L".DLL";
|
|
||||||
PFN_DrvEnableDriver ExistingDriver;
|
|
||||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
|
||||||
NTSTATUS Status;
|
|
||||||
LPWSTR FullName;
|
|
||||||
LPCWSTR p;
|
|
||||||
BOOL PathSeparatorFound;
|
|
||||||
BOOL DotFound;
|
|
||||||
UINT Size;
|
|
||||||
|
|
||||||
DotFound = FALSE;
|
|
||||||
PathSeparatorFound = FALSE;
|
|
||||||
p = Name;
|
|
||||||
while (L'\0' != *p)
|
|
||||||
{
|
|
||||||
if (L'\\' == *p || L'/' == *p)
|
|
||||||
{
|
|
||||||
PathSeparatorFound = TRUE;
|
|
||||||
DotFound = FALSE;
|
|
||||||
}
|
|
||||||
else if (L'.' == *p)
|
|
||||||
{
|
|
||||||
DotFound = TRUE;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size = (wcslen(Name) + 1) * sizeof(WCHAR);
|
|
||||||
if (! PathSeparatorFound)
|
|
||||||
{
|
|
||||||
Size += sizeof(DefaultPath) - sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
if (! DotFound)
|
|
||||||
{
|
|
||||||
Size += sizeof(DefaultExtension) - sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
|
|
||||||
if (NULL == FullName)
|
|
||||||
{
|
|
||||||
DPRINT1("Out of memory\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (PathSeparatorFound)
|
|
||||||
{
|
|
||||||
FullName[0] = L'\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcscpy(FullName, DefaultPath);
|
|
||||||
}
|
|
||||||
wcscat(FullName, Name);
|
|
||||||
if (! DotFound)
|
|
||||||
{
|
|
||||||
wcscat(FullName, DefaultExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First see if the driver hasn't already been loaded */
|
|
||||||
ExistingDriver = DRIVER_FindExistingDDIDriver(FullName);
|
|
||||||
if (ExistingDriver)
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(FullName, TAG_DRIVER);
|
|
||||||
return ExistingDriver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not, then load it */
|
|
||||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName);
|
|
||||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePool(FullName);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
|
|
||||||
DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint);
|
|
||||||
ExFreePoolWithTag(FullName, TAG_DRIVER);
|
|
||||||
return (PFN_DrvEnableDriver)GdiDriverInfo.EntryPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BEGIN_FUNCTION_MAP() \
|
|
||||||
ULONG i; \
|
|
||||||
for (i = 0; i < DED->c; i++) \
|
|
||||||
{ \
|
|
||||||
switch(DED->pdrvfn[i].iFunc) \
|
|
||||||
{
|
|
||||||
|
|
||||||
#define END_FUNCTION_MAP() \
|
|
||||||
default: \
|
|
||||||
DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TRACE_DRV_CALLS
|
|
||||||
|
|
||||||
typedef struct _TRACEDRVINFO
|
|
||||||
{
|
|
||||||
unsigned Index;
|
|
||||||
char *Name;
|
|
||||||
PVOID DrvRoutine;
|
|
||||||
}
|
|
||||||
TRACEDRVINFO, *PTRACEDRVINFO;
|
|
||||||
|
|
||||||
__asm__(
|
|
||||||
" .text\n"
|
|
||||||
"TraceDrv:\n"
|
|
||||||
" pushl %eax\n"
|
|
||||||
" call _FindTraceInfo\n"
|
|
||||||
" add $4,%esp\n"
|
|
||||||
" pushl %eax\n"
|
|
||||||
" pushl 4(%eax)\n"
|
|
||||||
" call _DbgPrint\n"
|
|
||||||
" addl $4,%esp\n"
|
|
||||||
" popl %eax\n"
|
|
||||||
" mov 8(%eax),%eax\n"
|
|
||||||
" jmp *%eax\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
#define TRACEDRV_ROUTINE(function) \
|
|
||||||
unsigned TraceDrvIndex##function = INDEX_Drv##function; \
|
|
||||||
__asm__ ( \
|
|
||||||
" .text\n" \
|
|
||||||
"_Trace" #function ":\n" \
|
|
||||||
" movl _TraceDrvIndex" #function ",%eax\n" \
|
|
||||||
" jmp TraceDrv\n" \
|
|
||||||
); \
|
|
||||||
extern PVOID Trace##function;
|
|
||||||
|
|
||||||
TRACEDRV_ROUTINE(EnablePDEV)
|
|
||||||
TRACEDRV_ROUTINE(CompletePDEV)
|
|
||||||
TRACEDRV_ROUTINE(DisablePDEV)
|
|
||||||
TRACEDRV_ROUTINE(EnableSurface)
|
|
||||||
TRACEDRV_ROUTINE(DisableSurface)
|
|
||||||
TRACEDRV_ROUTINE(AssertMode)
|
|
||||||
TRACEDRV_ROUTINE(Offset)
|
|
||||||
TRACEDRV_ROUTINE(ResetPDEV)
|
|
||||||
TRACEDRV_ROUTINE(DisableDriver)
|
|
||||||
TRACEDRV_ROUTINE(CreateDeviceBitmap)
|
|
||||||
TRACEDRV_ROUTINE(DeleteDeviceBitmap)
|
|
||||||
TRACEDRV_ROUTINE(RealizeBrush)
|
|
||||||
TRACEDRV_ROUTINE(DitherColor)
|
|
||||||
TRACEDRV_ROUTINE(StrokePath)
|
|
||||||
TRACEDRV_ROUTINE(FillPath)
|
|
||||||
TRACEDRV_ROUTINE(StrokeAndFillPath)
|
|
||||||
TRACEDRV_ROUTINE(Paint)
|
|
||||||
TRACEDRV_ROUTINE(BitBlt)
|
|
||||||
TRACEDRV_ROUTINE(TransparentBlt)
|
|
||||||
TRACEDRV_ROUTINE(CopyBits)
|
|
||||||
TRACEDRV_ROUTINE(StretchBlt)
|
|
||||||
TRACEDRV_ROUTINE(StretchBltROP)
|
|
||||||
TRACEDRV_ROUTINE(SetPalette)
|
|
||||||
TRACEDRV_ROUTINE(TextOut)
|
|
||||||
TRACEDRV_ROUTINE(Escape)
|
|
||||||
TRACEDRV_ROUTINE(DrawEscape)
|
|
||||||
TRACEDRV_ROUTINE(QueryFont)
|
|
||||||
TRACEDRV_ROUTINE(QueryFontTree)
|
|
||||||
TRACEDRV_ROUTINE(QueryFontData)
|
|
||||||
TRACEDRV_ROUTINE(SetPointerShape)
|
|
||||||
TRACEDRV_ROUTINE(MovePointer)
|
|
||||||
TRACEDRV_ROUTINE(LineTo)
|
|
||||||
TRACEDRV_ROUTINE(SendPage)
|
|
||||||
TRACEDRV_ROUTINE(StartPage)
|
|
||||||
TRACEDRV_ROUTINE(EndDoc)
|
|
||||||
TRACEDRV_ROUTINE(StartDoc)
|
|
||||||
TRACEDRV_ROUTINE(GetGlyphMode)
|
|
||||||
TRACEDRV_ROUTINE(Synchronize)
|
|
||||||
TRACEDRV_ROUTINE(SaveScreenBits)
|
|
||||||
TRACEDRV_ROUTINE(GetModes)
|
|
||||||
TRACEDRV_ROUTINE(Free)
|
|
||||||
TRACEDRV_ROUTINE(DestroyFont)
|
|
||||||
TRACEDRV_ROUTINE(QueryFontCaps)
|
|
||||||
TRACEDRV_ROUTINE(LoadFontFile)
|
|
||||||
TRACEDRV_ROUTINE(UnloadFontFile)
|
|
||||||
TRACEDRV_ROUTINE(FontManagement)
|
|
||||||
TRACEDRV_ROUTINE(QueryTrueTypeTable)
|
|
||||||
TRACEDRV_ROUTINE(QueryTrueTypeOutline)
|
|
||||||
TRACEDRV_ROUTINE(GetTrueTypeFile)
|
|
||||||
TRACEDRV_ROUTINE(QueryFontFile)
|
|
||||||
TRACEDRV_ROUTINE(QueryAdvanceWidths)
|
|
||||||
TRACEDRV_ROUTINE(SetPixelFormat)
|
|
||||||
TRACEDRV_ROUTINE(DescribePixelFormat)
|
|
||||||
TRACEDRV_ROUTINE(SwapBuffers)
|
|
||||||
TRACEDRV_ROUTINE(StartBanding)
|
|
||||||
TRACEDRV_ROUTINE(NextBand)
|
|
||||||
TRACEDRV_ROUTINE(GetDirectDrawInfo)
|
|
||||||
TRACEDRV_ROUTINE(EnableDirectDraw)
|
|
||||||
TRACEDRV_ROUTINE(DisableDirectDraw)
|
|
||||||
TRACEDRV_ROUTINE(QuerySpoolType)
|
|
||||||
TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
|
|
||||||
TRACEDRV_ROUTINE(GradientFill)
|
|
||||||
TRACEDRV_ROUTINE(SynchronizeSurface)
|
|
||||||
TRACEDRV_ROUTINE(AlphaBlend)
|
|
||||||
|
|
||||||
#define TRACEDRVINFO_ENTRY(function) \
|
|
||||||
{ INDEX_Drv##function, "Drv" #function "\n", NULL }
|
|
||||||
static TRACEDRVINFO TraceDrvInfo[] =
|
|
||||||
{
|
|
||||||
TRACEDRVINFO_ENTRY(EnablePDEV),
|
|
||||||
TRACEDRVINFO_ENTRY(CompletePDEV),
|
|
||||||
TRACEDRVINFO_ENTRY(DisablePDEV),
|
|
||||||
TRACEDRVINFO_ENTRY(EnableSurface),
|
|
||||||
TRACEDRVINFO_ENTRY(DisableSurface),
|
|
||||||
TRACEDRVINFO_ENTRY(AssertMode),
|
|
||||||
TRACEDRVINFO_ENTRY(Offset),
|
|
||||||
TRACEDRVINFO_ENTRY(ResetPDEV),
|
|
||||||
TRACEDRVINFO_ENTRY(DisableDriver),
|
|
||||||
TRACEDRVINFO_ENTRY(CreateDeviceBitmap),
|
|
||||||
TRACEDRVINFO_ENTRY(DeleteDeviceBitmap),
|
|
||||||
TRACEDRVINFO_ENTRY(RealizeBrush),
|
|
||||||
TRACEDRVINFO_ENTRY(DitherColor),
|
|
||||||
TRACEDRVINFO_ENTRY(StrokePath),
|
|
||||||
TRACEDRVINFO_ENTRY(FillPath),
|
|
||||||
TRACEDRVINFO_ENTRY(StrokeAndFillPath),
|
|
||||||
TRACEDRVINFO_ENTRY(Paint),
|
|
||||||
TRACEDRVINFO_ENTRY(BitBlt),
|
|
||||||
TRACEDRVINFO_ENTRY(TransparentBlt),
|
|
||||||
TRACEDRVINFO_ENTRY(CopyBits),
|
|
||||||
TRACEDRVINFO_ENTRY(StretchBlt),
|
|
||||||
TRACEDRVINFO_ENTRY(StretchBltROP),
|
|
||||||
TRACEDRVINFO_ENTRY(SetPalette),
|
|
||||||
TRACEDRVINFO_ENTRY(TextOut),
|
|
||||||
TRACEDRVINFO_ENTRY(Escape),
|
|
||||||
TRACEDRVINFO_ENTRY(DrawEscape),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryFont),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryFontTree),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryFontData),
|
|
||||||
TRACEDRVINFO_ENTRY(SetPointerShape),
|
|
||||||
TRACEDRVINFO_ENTRY(MovePointer),
|
|
||||||
TRACEDRVINFO_ENTRY(LineTo),
|
|
||||||
TRACEDRVINFO_ENTRY(SendPage),
|
|
||||||
TRACEDRVINFO_ENTRY(StartPage),
|
|
||||||
TRACEDRVINFO_ENTRY(EndDoc),
|
|
||||||
TRACEDRVINFO_ENTRY(StartDoc),
|
|
||||||
TRACEDRVINFO_ENTRY(GetGlyphMode),
|
|
||||||
TRACEDRVINFO_ENTRY(Synchronize),
|
|
||||||
TRACEDRVINFO_ENTRY(SaveScreenBits),
|
|
||||||
TRACEDRVINFO_ENTRY(GetModes),
|
|
||||||
TRACEDRVINFO_ENTRY(Free),
|
|
||||||
TRACEDRVINFO_ENTRY(DestroyFont),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryFontCaps),
|
|
||||||
TRACEDRVINFO_ENTRY(LoadFontFile),
|
|
||||||
TRACEDRVINFO_ENTRY(UnloadFontFile),
|
|
||||||
TRACEDRVINFO_ENTRY(FontManagement),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryTrueTypeTable),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryTrueTypeOutline),
|
|
||||||
TRACEDRVINFO_ENTRY(GetTrueTypeFile),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryFontFile),
|
|
||||||
TRACEDRVINFO_ENTRY(QueryAdvanceWidths),
|
|
||||||
TRACEDRVINFO_ENTRY(SetPixelFormat),
|
|
||||||
TRACEDRVINFO_ENTRY(DescribePixelFormat),
|
|
||||||
TRACEDRVINFO_ENTRY(SwapBuffers),
|
|
||||||
TRACEDRVINFO_ENTRY(StartBanding),
|
|
||||||
TRACEDRVINFO_ENTRY(NextBand),
|
|
||||||
TRACEDRVINFO_ENTRY(GetDirectDrawInfo),
|
|
||||||
TRACEDRVINFO_ENTRY(EnableDirectDraw),
|
|
||||||
TRACEDRVINFO_ENTRY(DisableDirectDraw),
|
|
||||||
TRACEDRVINFO_ENTRY(QuerySpoolType),
|
|
||||||
TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
|
|
||||||
TRACEDRVINFO_ENTRY(GradientFill),
|
|
||||||
TRACEDRVINFO_ENTRY(SynchronizeSurface),
|
|
||||||
TRACEDRVINFO_ENTRY(AlphaBlend)
|
|
||||||
};
|
|
||||||
|
|
||||||
PTRACEDRVINFO
|
|
||||||
FindTraceInfo(unsigned Index)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++)
|
|
||||||
{
|
|
||||||
if (TraceDrvInfo[i].Index == Index)
|
|
||||||
{
|
|
||||||
return TraceDrvInfo + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DRIVER_FUNCTION(function) \
|
|
||||||
case INDEX_Drv##function: \
|
|
||||||
FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
|
|
||||||
*(PVOID*)&DF->function = &Trace##function; \
|
|
||||||
break
|
|
||||||
#else
|
|
||||||
#define DRIVER_FUNCTION(function) \
|
|
||||||
case INDEX_Drv##function: \
|
|
||||||
*(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
|
|
||||||
break
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
|
||||||
PDRIVER_FUNCTIONS DF)
|
|
||||||
{
|
|
||||||
BEGIN_FUNCTION_MAP();
|
|
||||||
DRIVER_FUNCTION(EnablePDEV);
|
|
||||||
DRIVER_FUNCTION(CompletePDEV);
|
|
||||||
DRIVER_FUNCTION(DisablePDEV);
|
|
||||||
DRIVER_FUNCTION(EnableSurface);
|
|
||||||
DRIVER_FUNCTION(DisableSurface);
|
|
||||||
DRIVER_FUNCTION(AssertMode);
|
|
||||||
DRIVER_FUNCTION(Offset);
|
|
||||||
DRIVER_FUNCTION(ResetPDEV);
|
|
||||||
DRIVER_FUNCTION(DisableDriver);
|
|
||||||
DRIVER_FUNCTION(Unknown1);
|
|
||||||
DRIVER_FUNCTION(CreateDeviceBitmap);
|
|
||||||
DRIVER_FUNCTION(DeleteDeviceBitmap);
|
|
||||||
DRIVER_FUNCTION(RealizeBrush);
|
|
||||||
DRIVER_FUNCTION(DitherColor);
|
|
||||||
DRIVER_FUNCTION(StrokePath);
|
|
||||||
DRIVER_FUNCTION(FillPath);
|
|
||||||
DRIVER_FUNCTION(StrokeAndFillPath);
|
|
||||||
DRIVER_FUNCTION(Paint);
|
|
||||||
DRIVER_FUNCTION(BitBlt);
|
|
||||||
DRIVER_FUNCTION(CopyBits);
|
|
||||||
DRIVER_FUNCTION(StretchBlt);
|
|
||||||
DRIVER_FUNCTION(Unknown2);
|
|
||||||
DRIVER_FUNCTION(SetPalette);
|
|
||||||
DRIVER_FUNCTION(TextOut);
|
|
||||||
DRIVER_FUNCTION(Escape);
|
|
||||||
DRIVER_FUNCTION(DrawEscape);
|
|
||||||
DRIVER_FUNCTION(QueryFont);
|
|
||||||
DRIVER_FUNCTION(QueryFontTree);
|
|
||||||
DRIVER_FUNCTION(QueryFontData);
|
|
||||||
DRIVER_FUNCTION(SetPointerShape);
|
|
||||||
DRIVER_FUNCTION(MovePointer);
|
|
||||||
DRIVER_FUNCTION(LineTo);
|
|
||||||
DRIVER_FUNCTION(SendPage);
|
|
||||||
DRIVER_FUNCTION(StartPage);
|
|
||||||
DRIVER_FUNCTION(EndDoc);
|
|
||||||
DRIVER_FUNCTION(StartDoc);
|
|
||||||
DRIVER_FUNCTION(Unknown3);
|
|
||||||
DRIVER_FUNCTION(GetGlyphMode);
|
|
||||||
DRIVER_FUNCTION(Synchronize);
|
|
||||||
DRIVER_FUNCTION(Unknown4);
|
|
||||||
DRIVER_FUNCTION(SaveScreenBits);
|
|
||||||
DRIVER_FUNCTION(GetModes);
|
|
||||||
DRIVER_FUNCTION(Free);
|
|
||||||
DRIVER_FUNCTION(DestroyFont);
|
|
||||||
DRIVER_FUNCTION(QueryFontCaps);
|
|
||||||
DRIVER_FUNCTION(LoadFontFile);
|
|
||||||
DRIVER_FUNCTION(UnloadFontFile);
|
|
||||||
DRIVER_FUNCTION(FontManagement);
|
|
||||||
DRIVER_FUNCTION(QueryTrueTypeTable);
|
|
||||||
DRIVER_FUNCTION(QueryTrueTypeOutline);
|
|
||||||
DRIVER_FUNCTION(GetTrueTypeFile);
|
|
||||||
DRIVER_FUNCTION(QueryFontFile);
|
|
||||||
DRIVER_FUNCTION(QueryAdvanceWidths);
|
|
||||||
DRIVER_FUNCTION(SetPixelFormat);
|
|
||||||
DRIVER_FUNCTION(DescribePixelFormat);
|
|
||||||
DRIVER_FUNCTION(SwapBuffers);
|
|
||||||
DRIVER_FUNCTION(StartBanding);
|
|
||||||
DRIVER_FUNCTION(NextBand);
|
|
||||||
DRIVER_FUNCTION(GetDirectDrawInfo);
|
|
||||||
DRIVER_FUNCTION(EnableDirectDraw);
|
|
||||||
DRIVER_FUNCTION(DisableDirectDraw);
|
|
||||||
DRIVER_FUNCTION(QuerySpoolType);
|
|
||||||
DRIVER_FUNCTION(Unknown5);
|
|
||||||
DRIVER_FUNCTION(IcmCreateColorTransform);
|
|
||||||
DRIVER_FUNCTION(IcmDeleteColorTransform);
|
|
||||||
DRIVER_FUNCTION(IcmCheckBitmapBits);
|
|
||||||
DRIVER_FUNCTION(IcmSetDeviceGammaRamp);
|
|
||||||
DRIVER_FUNCTION(GradientFill);
|
|
||||||
DRIVER_FUNCTION(StretchBltROP);
|
|
||||||
DRIVER_FUNCTION(PlgBlt);
|
|
||||||
DRIVER_FUNCTION(AlphaBlend);
|
|
||||||
DRIVER_FUNCTION(SynthesizeFont);
|
|
||||||
DRIVER_FUNCTION(GetSynthesizedFontFiles);
|
|
||||||
DRIVER_FUNCTION(TransparentBlt);
|
|
||||||
DRIVER_FUNCTION(QueryPerBandInfo);
|
|
||||||
DRIVER_FUNCTION(QueryDeviceSupport);
|
|
||||||
DRIVER_FUNCTION(Reserved1);
|
|
||||||
DRIVER_FUNCTION(Reserved2);
|
|
||||||
DRIVER_FUNCTION(Reserved3);
|
|
||||||
DRIVER_FUNCTION(Reserved4);
|
|
||||||
DRIVER_FUNCTION(Reserved5);
|
|
||||||
DRIVER_FUNCTION(Reserved6);
|
|
||||||
DRIVER_FUNCTION(Reserved7);
|
|
||||||
DRIVER_FUNCTION(Reserved8);
|
|
||||||
DRIVER_FUNCTION(DeriveSurface);
|
|
||||||
DRIVER_FUNCTION(QueryGlyphAttrs);
|
|
||||||
DRIVER_FUNCTION(Notify);
|
|
||||||
DRIVER_FUNCTION(SynchronizeSurface);
|
|
||||||
DRIVER_FUNCTION(ResetDevice);
|
|
||||||
DRIVER_FUNCTION(Reserved9);
|
|
||||||
DRIVER_FUNCTION(Reserved10);
|
|
||||||
DRIVER_FUNCTION(Reserved11);
|
|
||||||
END_FUNCTION_MAP();
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef LONG VP_STATUS;
|
|
||||||
typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID);
|
|
||||||
|
|
||||||
PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
WCHAR DeviceNameBuffer[20];
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
IO_STATUS_BLOCK Iosb;
|
|
||||||
HANDLE DisplayHandle;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PFILE_OBJECT VideoFileObject;
|
|
||||||
|
|
||||||
swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
|
|
||||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&DeviceName,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenFile(&DisplayHandle,
|
|
||||||
FILE_ALL_ACCESS,
|
|
||||||
&ObjectAttributes,
|
|
||||||
&Iosb,
|
|
||||||
0,
|
|
||||||
FILE_SYNCHRONOUS_IO_ALERT);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = ObReferenceObjectByHandle(DisplayHandle,
|
|
||||||
FILE_READ_DATA | FILE_WRITE_DATA,
|
|
||||||
IoFileObjectType,
|
|
||||||
KernelMode,
|
|
||||||
(PVOID *)&VideoFileObject,
|
|
||||||
NULL);
|
|
||||||
ZwClose(DisplayHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
|
|
||||||
DPRINT1("Perhaps the miniport wasn't loaded?\n");
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return VideoFileObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
|
|
||||||
{
|
|
||||||
PGRAPHICS_DRIVER Driver = NULL;
|
|
||||||
|
|
||||||
if (Name)
|
|
||||||
{
|
|
||||||
if (DriverList != NULL)
|
|
||||||
{
|
|
||||||
if (!_wcsicmp(DriverList->Name, Name))
|
|
||||||
{
|
|
||||||
Driver = DriverList;
|
|
||||||
DriverList = DriverList->Next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Driver = DriverList;
|
|
||||||
while (Driver->Next && _wcsicmp(Driver->Name, Name))
|
|
||||||
{
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (GenericDriver != NULL)
|
|
||||||
{
|
|
||||||
Driver = GenericDriver;
|
|
||||||
GenericDriver = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Driver != NULL)
|
|
||||||
{
|
|
||||||
ExFreePool(Driver->Name);
|
|
||||||
ExFreePool(Driver);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
|
||||||
{
|
|
||||||
GRAPHICS_DRIVER *Driver = DriverList;
|
|
||||||
|
|
||||||
while (Driver && Name)
|
|
||||||
{
|
|
||||||
DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
|
|
||||||
if (!_wcsicmp( Driver->Name, Name))
|
|
||||||
{
|
|
||||||
return ++Driver->ReferenceCount;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
|
||||||
DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
|
||||||
assert( GenericDriver != 0 );
|
|
||||||
return ++GenericDriver->ReferenceCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT DRIVER_UnreferenceDriver (LPCWSTR Name)
|
|
||||||
{
|
|
||||||
GRAPHICS_DRIVER *Driver = DriverList;
|
|
||||||
|
|
||||||
while (Driver && Name)
|
|
||||||
{
|
|
||||||
DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
|
|
||||||
if (!_wcsicmp( Driver->Name, Name))
|
|
||||||
{
|
|
||||||
return --Driver->ReferenceCount;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
|
||||||
DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
|
||||||
assert( GenericDriver != 0 );
|
|
||||||
return --GenericDriver->ReferenceCount;
|
|
||||||
}
|
|
||||||
/* EOF */
|
|
||||||
|
|
|
@ -302,22 +302,30 @@ UserLoadImage(PCWSTR pwszName)
|
||||||
HBITMAP hbmp = 0;
|
HBITMAP hbmp = 0;
|
||||||
BITMAPV5INFO bmiLocal;
|
BITMAPV5INFO bmiLocal;
|
||||||
|
|
||||||
|
DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
|
||||||
|
|
||||||
/* Open the file */
|
/* Open the file */
|
||||||
hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
|
hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (!hFile)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a section */
|
/* Create a section */
|
||||||
hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
|
hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
|
||||||
ZwClose(hFile);
|
ZwClose(hFile);
|
||||||
if (!hSection)
|
if (!hSection)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Map the section */
|
/* Map the section */
|
||||||
pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
|
pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
|
||||||
ZwClose(hSection);
|
ZwClose(hSection);
|
||||||
if (!pbmfh)
|
if (!pbmfh)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a pointer to the BITMAPINFO */
|
/* Get a pointer to the BITMAPINFO */
|
||||||
pbmi = (LPBITMAPINFO)(pbmfh + 1);
|
pbmi = (LPBITMAPINFO)(pbmfh + 1);
|
||||||
|
|
|
@ -11,6 +11,100 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RegOpenKey(
|
||||||
|
LPCWSTR pwszKeyName,
|
||||||
|
PHKEY phkey)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING ustrKeyName;
|
||||||
|
HKEY hkey;
|
||||||
|
|
||||||
|
/* Initialize the key name */
|
||||||
|
RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
|
||||||
|
|
||||||
|
/* Initialize object attributes */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&ustrKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Open the key */
|
||||||
|
Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*phkey = hkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RegQueryValue(
|
||||||
|
IN HKEY hkey,
|
||||||
|
IN PCWSTR pwszValueName,
|
||||||
|
IN ULONG ulType,
|
||||||
|
OUT PVOID pvData,
|
||||||
|
IN OUT PULONG pcbValue)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING ustrValueName;
|
||||||
|
BYTE ajBuffer[100];
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION pInfo;
|
||||||
|
ULONG cbInfoSize;
|
||||||
|
|
||||||
|
/* Check if the local buffer is sufficient */
|
||||||
|
cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue;
|
||||||
|
if (cbInfoSize <= sizeof(ajBuffer))
|
||||||
|
{
|
||||||
|
pInfo = (PVOID)ajBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It's not, allocate a sufficient buffer */
|
||||||
|
pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
|
||||||
|
if (!pInfo)
|
||||||
|
{
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query the value */
|
||||||
|
RtlInitUnicodeString(&ustrValueName, pwszValueName);
|
||||||
|
Status = ZwQueryValueKey(hkey,
|
||||||
|
&ustrValueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
(PVOID)pInfo,
|
||||||
|
cbInfoSize,
|
||||||
|
&cbInfoSize);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Did we get the right type */
|
||||||
|
if (pInfo->Type == ulType)
|
||||||
|
{
|
||||||
|
/* Copy the contents to the caller */
|
||||||
|
RtlCopyMemory(pvData, pInfo->Data, *pcbValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the data size to the caller */
|
||||||
|
*pcbValue = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
if (pInfo != (PVOID)ajBuffer)
|
||||||
|
ExFreePoolWithTag(pInfo, TAG_TEMP);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
RegReadUserSetting(
|
RegReadUserSetting(
|
||||||
|
@ -163,7 +257,8 @@ RegWriteUserSetting(
|
||||||
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
|
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", Status, usKeyName.Length, usKeyName.MaximumLength);
|
DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n",
|
||||||
|
Status, usKeyName.Length, usKeyName.MaximumLength);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,8 +297,7 @@ DxEngGetHdevData(HDEV hDev,
|
||||||
break;
|
break;
|
||||||
case DxEGShDevData_hSpooler:
|
case DxEGShDevData_hSpooler:
|
||||||
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n");
|
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n");
|
||||||
// retVal = (DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
|
retVal = 0;//(DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
|
||||||
retVal = (DWORD_PTR) PDev->VideoFileObject->DeviceObject;
|
|
||||||
break;
|
break;
|
||||||
case DxEGShDevData_DitherFmt:
|
case DxEGShDevData_DitherFmt:
|
||||||
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n");
|
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n");
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -163,10 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
|
||||||
DPRINT("Loaded %wZ\n", &FullLayoutPath);
|
DPRINT("Loaded %wZ\n", &FullLayoutPath);
|
||||||
|
|
||||||
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
|
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
|
||||||
LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress,
|
layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
|
||||||
&kbdProcedureName,
|
|
||||||
0,
|
|
||||||
(PVOID*)&layerDescGetFn);
|
|
||||||
|
|
||||||
if(layerDescGetFn)
|
if(layerDescGetFn)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,9 +24,22 @@ FASTCALL
|
||||||
InitMetrics(VOID)
|
InitMetrics(VOID)
|
||||||
{
|
{
|
||||||
INT *piSysMet;
|
INT *piSysMet;
|
||||||
|
PPDEVOBJ ppdev;
|
||||||
|
ULONG Width, Height;
|
||||||
|
|
||||||
ULONG Width = pPrimarySurface->gdiinfo.ulHorzRes;
|
/* FIXME: HACK, due to missing PDEV on first init */
|
||||||
ULONG Height = pPrimarySurface->gdiinfo.ulVertRes;
|
ppdev = EngpGetPDEV(NULL);
|
||||||
|
|
||||||
|
if (!ppdev)
|
||||||
|
{
|
||||||
|
Width = 640;
|
||||||
|
Height = 480;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Width = ppdev->gdiinfo.ulHorzRes;
|
||||||
|
Height = ppdev->gdiinfo.ulVertRes;
|
||||||
|
}
|
||||||
|
|
||||||
piSysMet = gpsi->aiSysMet;
|
piSysMet = gpsi->aiSysMet;
|
||||||
|
|
||||||
|
|
|
@ -199,39 +199,6 @@ NtUserDrawAnimatedRects(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
|
||||||
APIENTRY
|
|
||||||
NtUserEnumDisplayDevices (
|
|
||||||
PUNICODE_STRING lpDevice, /* device name */
|
|
||||||
DWORD iDevNum, /* display device */
|
|
||||||
PDISPLAY_DEVICEW lpDisplayDevice, /* device information */
|
|
||||||
DWORD dwFlags ) /* reserved */
|
|
||||||
{
|
|
||||||
DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n");
|
|
||||||
if (lpDevice->Length == 0 && iDevNum > 0)
|
|
||||||
{
|
|
||||||
/* Only one display device present */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else if (lpDevice->Length != 0)
|
|
||||||
{
|
|
||||||
/* Can't enumerate monitors :( */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
wcscpy(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1");
|
|
||||||
wcscpy(lpDisplayDevice->DeviceString, L"<Unknown>");
|
|
||||||
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
|
|
||||||
| DISPLAY_DEVICE_MODESPRUNED
|
|
||||||
| DISPLAY_DEVICE_PRIMARY_DEVICE
|
|
||||||
| DISPLAY_DEVICE_VGA_COMPATIBLE;
|
|
||||||
lpDisplayDevice->DeviceID[0] = L'0';
|
|
||||||
lpDisplayDevice->DeviceKey[0] = L'0';
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserEvent(
|
NtUserEvent(
|
||||||
|
|
|
@ -73,16 +73,6 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gpsi)
|
|
||||||
{
|
|
||||||
gpsi = UserHeapAlloc(sizeof(SERVERINFO));
|
|
||||||
if (gpsi)
|
|
||||||
{
|
|
||||||
RtlZeroMemory(gpsi, sizeof(SERVERINFO));
|
|
||||||
DPRINT("Global Server Data -> %x\n", gpsi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InitUserAtoms();
|
InitUserAtoms();
|
||||||
|
|
||||||
InitSysParams();
|
InitSysParams();
|
||||||
|
@ -90,6 +80,8 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InitVideo(ULONG);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -102,6 +94,7 @@ UserInitialize(
|
||||||
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
|
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
|
||||||
// Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
|
// Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
|
||||||
// Create Event for Diconnect Desktop.
|
// Create Event for Diconnect Desktop.
|
||||||
|
InitVideo(0);
|
||||||
// Initialize Video.
|
// Initialize Video.
|
||||||
// {
|
// {
|
||||||
// DrvInitConsole.
|
// DrvInitConsole.
|
||||||
|
@ -139,7 +132,7 @@ NtUserInitialize(
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n",
|
DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n",
|
||||||
dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
|
dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
|
||||||
|
|
||||||
/* Check the Windows version */
|
/* Check the Windows version */
|
||||||
|
|
|
@ -36,6 +36,9 @@ DceCreateDisplayDC(VOID)
|
||||||
UNICODE_STRING DriverName;
|
UNICODE_STRING DriverName;
|
||||||
RtlInitUnicodeString(&DriverName, L"DISPLAY");
|
RtlInitUnicodeString(&DriverName, L"DISPLAY");
|
||||||
hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
|
hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
|
||||||
|
|
||||||
|
co_IntGraphicsCheck(TRUE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// If NULL, first time through! Build the default window dc!
|
// If NULL, first time through! Build the default window dc!
|
||||||
//
|
//
|
||||||
|
|
|
@ -145,8 +145,8 @@ IntCreateCompatibleBitmap(
|
||||||
{
|
{
|
||||||
Bmp = IntGdiCreateBitmap(abs(Width),
|
Bmp = IntGdiCreateBitmap(abs(Width),
|
||||||
abs(Height),
|
abs(Height),
|
||||||
IntGdiGetDeviceCaps(Dc,PLANES),
|
Dc->ppdev->gdiinfo.cPlanes,
|
||||||
IntGdiGetDeviceCaps(Dc,BITSPIXEL),
|
Dc->ppdev->gdiinfo.cBitsPixel,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -176,7 +176,7 @@ IntCreateCompatibleBitmap(
|
||||||
Bmp = IntGdiCreateBitmap(abs(Width),
|
Bmp = IntGdiCreateBitmap(abs(Width),
|
||||||
abs(Height),
|
abs(Height),
|
||||||
dibs.dsBm.bmPlanes,
|
dibs.dsBm.bmPlanes,
|
||||||
IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
|
Dc->ppdev->gdiinfo.cBitsPixel,//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -27,6 +27,9 @@ CLIPPING_UpdateGCRegion(DC* Dc)
|
||||||
{
|
{
|
||||||
PROSRGNDATA CombinedRegion;
|
PROSRGNDATA CombinedRegion;
|
||||||
|
|
||||||
|
// would prefer this, but the rest of the code sucks
|
||||||
|
// ASSERT(Dc->rosdc.hGCClipRgn);
|
||||||
|
// ASSERT(Dc->rosdc.hClipRgn);
|
||||||
if (!Dc->rosdc.hVisRgn)
|
if (!Dc->rosdc.hVisRgn)
|
||||||
{
|
{
|
||||||
DPRINT1("Warning, hVisRgn is NULL!\n");
|
DPRINT1("Warning, hVisRgn is NULL!\n");
|
||||||
|
|
|
@ -152,30 +152,44 @@ FreeDcAttr(PDC_ATTR pDc_Attr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
DC_AllocDcAttr(PDC pdc)
|
||||||
|
{
|
||||||
|
DC_AllocateDcAttr(pdc->BaseObject.hHmgr);
|
||||||
|
*pdc->pdcattr = pdc->dcattr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK against current head
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
DC_AllocateDcAttr(HDC hDC)
|
DC_AllocateDcAttr(HDC hDC)
|
||||||
{
|
{
|
||||||
PVOID NewMem = NULL;
|
PVOID NewMem = NULL;
|
||||||
PDC pDC;
|
PDC pDC;
|
||||||
|
HANDLE Pid = NtCurrentProcess();
|
||||||
|
ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
|
||||||
|
|
||||||
|
NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
|
||||||
|
&NewMem,
|
||||||
|
0,
|
||||||
|
&MemSize,
|
||||||
|
MEM_COMMIT|MEM_RESERVE,
|
||||||
|
PAGE_READWRITE);
|
||||||
{
|
{
|
||||||
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
|
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
|
||||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
||||||
|
|
||||||
NewMem = AllocateDcAttr();
|
|
||||||
|
|
||||||
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
|
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
if (NewMem)
|
|
||||||
{
|
{
|
||||||
RtlZeroMemory(NewMem, sizeof(DC_ATTR));
|
RtlZeroMemory(NewMem, MemSize);
|
||||||
Entry->UserData = NewMem;
|
Entry->UserData = NewMem;
|
||||||
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
|
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("DC_ATTR not allocated!\n");
|
DPRINT("DC_ATTR not allocated!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pDC = DC_LockDc(hDC);
|
pDC = DC_LockDc(hDC);
|
||||||
|
@ -188,22 +202,36 @@ DC_AllocateDcAttr(HDC hDC)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
NTAPI
|
||||||
DC_FreeDcAttr(HDC DCToFree )
|
DC_vFreeDcAttr(PDC pdc)
|
||||||
{
|
{
|
||||||
PDC pDC = DC_LockDc(DCToFree);
|
HANDLE Pid = NtCurrentProcess();
|
||||||
if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
|
INT Index;
|
||||||
pDC->pdcattr = &pDC->dcattr;
|
PGDI_TABLE_ENTRY pent;
|
||||||
DC_UnlockDc(pDC);
|
|
||||||
|
|
||||||
|
if (pdc->pdcattr == &pdc->dcattr)
|
||||||
{
|
{
|
||||||
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
|
// Internal DC object!
|
||||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
return;
|
||||||
if (Entry->UserData)
|
|
||||||
{
|
|
||||||
FreeDcAttr(Entry->UserData);
|
|
||||||
Entry->UserData = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdc->pdcattr = &pdc->dcattr;
|
||||||
|
|
||||||
|
Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
|
||||||
|
pent = &GdiHandleTable->Entries[Index];
|
||||||
|
if(pent->UserData)
|
||||||
|
{
|
||||||
|
ULONG MemSize = sizeof(DC_ATTR);
|
||||||
|
NTSTATUS Status = ZwFreeVirtualMemory(Pid,
|
||||||
|
&pent->UserData,
|
||||||
|
&MemSize,
|
||||||
|
MEM_RELEASE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
pent->UserData = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,12 +247,8 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForWrite( pdcattr,
|
ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1);
|
||||||
sizeof(DC_ATTR),
|
RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR));
|
||||||
1);
|
|
||||||
RtlCopyMemory( pdcattr,
|
|
||||||
&dc->dcattr,
|
|
||||||
sizeof(DC_ATTR));
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,6 +15,8 @@ VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
DC_vCopyState(PDC pdcSrc, PDC pdcDst)
|
DC_vCopyState(PDC pdcSrc, PDC pdcDst)
|
||||||
{
|
{
|
||||||
|
DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
|
||||||
|
|
||||||
/* Copy full DC attribute */
|
/* Copy full DC attribute */
|
||||||
*pdcDst->pdcattr = *pdcSrc->pdcattr;
|
*pdcDst->pdcattr = *pdcSrc->pdcattr;
|
||||||
|
|
||||||
|
@ -93,17 +95,91 @@ NtGdiResetDC(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DC_vRestoreDC(
|
||||||
|
IN PDC pdc,
|
||||||
|
INT iSaveLevel)
|
||||||
|
{
|
||||||
|
PEPROCESS pepCurrentProcess;
|
||||||
|
HDC hdcSave;
|
||||||
|
PDC pdcSave;
|
||||||
|
|
||||||
|
ASSERT(iSaveLevel > 0);
|
||||||
|
DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
|
||||||
|
|
||||||
|
/* Get current process */
|
||||||
|
pepCurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
/* Loop the save levels */
|
||||||
|
while (pdc->dclevel.lSaveDepth > iSaveLevel)
|
||||||
|
{
|
||||||
|
hdcSave = pdc->dclevel.hdcSave;
|
||||||
|
DPRINT("RestoreDC = %p\n", hdcSave);
|
||||||
|
|
||||||
|
/* Set us as the owner */
|
||||||
|
if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
|
||||||
|
{
|
||||||
|
/* Could not get ownership. That's bad! */
|
||||||
|
DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
|
||||||
|
hdcSave, pdc->BaseObject.hHmgr);
|
||||||
|
return;// FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock the saved dc */
|
||||||
|
pdcSave = DC_LockDc(hdcSave);
|
||||||
|
if (!pdcSave)
|
||||||
|
{
|
||||||
|
/* WTF? Internal error! */
|
||||||
|
DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
|
||||||
|
hdcSave, pdc->BaseObject.hHmgr);
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
return;// FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the saved dc from the queue */
|
||||||
|
pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
|
||||||
|
|
||||||
|
/* Decrement save level */
|
||||||
|
pdc->dclevel.lSaveDepth--;
|
||||||
|
|
||||||
|
/* Is this the state we want? */
|
||||||
|
if (pdc->dclevel.lSaveDepth == iSaveLevel)
|
||||||
|
{
|
||||||
|
/* Copy the state back */
|
||||||
|
DC_vCopyState(pdcSave, pdc);
|
||||||
|
|
||||||
|
// Restore Path by removing it, if the Save flag is set.
|
||||||
|
// BeginPath will takecare of the rest.
|
||||||
|
if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
|
||||||
|
{
|
||||||
|
PATH_Delete(pdc->dclevel.hPath);
|
||||||
|
pdc->dclevel.hPath = 0;
|
||||||
|
pdc->dclevel.flPath &= ~DCPATH_SAVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent save dc from being restored */
|
||||||
|
pdcSave->dclevel.lSaveDepth = 1;
|
||||||
|
|
||||||
|
/* Delete the saved dc */
|
||||||
|
GreDeleteObject(hdcSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Leave DC_vRestoreDC()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtGdiRestoreDC(
|
NtGdiRestoreDC(
|
||||||
HDC hdc,
|
HDC hdc,
|
||||||
INT iSaveLevel)
|
INT iSaveLevel)
|
||||||
{
|
{
|
||||||
PDC pdc, pdcSave;
|
PDC pdc;
|
||||||
HDC hdcSave;
|
|
||||||
PEPROCESS pepCurrentProcess;
|
|
||||||
|
|
||||||
DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
|
DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
|
||||||
|
|
||||||
/* Lock the original DC */
|
/* Lock the original DC */
|
||||||
pdc = DC_LockDc(hdc);
|
pdc = DC_LockDc(hdc);
|
||||||
|
@ -129,63 +205,12 @@ NtGdiRestoreDC(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get current process */
|
/* Call the internal function */
|
||||||
pepCurrentProcess = PsGetCurrentProcess();
|
DC_vRestoreDC(pdc, iSaveLevel);
|
||||||
|
|
||||||
/* Loop the save levels */
|
|
||||||
while (pdc->dclevel.lSaveDepth > iSaveLevel)
|
|
||||||
{
|
|
||||||
hdcSave = pdc->dclevel.hdcSave;
|
|
||||||
|
|
||||||
/* Set us as the owner */
|
|
||||||
if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
|
|
||||||
{
|
|
||||||
/* Could not get ownership. That's bad! */
|
|
||||||
DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
|
|
||||||
hdcSave, hdc);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lock the saved dc */
|
|
||||||
pdcSave = DC_LockDc(hdcSave);
|
|
||||||
if (!pdcSave)
|
|
||||||
{
|
|
||||||
/* WTF? Internal error! */
|
|
||||||
DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
|
|
||||||
hdcSave, hdc);
|
|
||||||
DC_UnlockDc(pdc);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the saved dc from the queue */
|
|
||||||
pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
|
|
||||||
|
|
||||||
/* Decrement save level */
|
|
||||||
pdc->dclevel.lSaveDepth--;
|
|
||||||
|
|
||||||
/* Is this the state we want? */
|
|
||||||
if (pdc->dclevel.lSaveDepth == iSaveLevel)
|
|
||||||
{
|
|
||||||
/* Copy the state back */
|
|
||||||
DC_vCopyState(pdcSave, pdc);
|
|
||||||
|
|
||||||
// Restore Path by removing it, if the Save flag is set.
|
|
||||||
// BeginPath will takecare of the rest.
|
|
||||||
if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
|
|
||||||
{
|
|
||||||
PATH_Delete(pdc->dclevel.hPath);
|
|
||||||
pdc->dclevel.hPath = 0;
|
|
||||||
pdc->dclevel.flPath &= ~DCPATH_SAVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete the saved dc */
|
|
||||||
GreDeleteObject(hdcSave);
|
|
||||||
}
|
|
||||||
|
|
||||||
DC_UnlockDc(pdc);
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
DPRINT("Leaving NtGdiRestoreDC\n");
|
DPRINT("Leave NtGdiRestoreDC\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +224,7 @@ NtGdiSaveDC(
|
||||||
PDC pdc, pdcSave;
|
PDC pdc, pdcSave;
|
||||||
INT lSaveDepth;
|
INT lSaveDepth;
|
||||||
|
|
||||||
DPRINT("NtGdiSaveDC(%lx)\n", hDC);
|
DPRINT("NtGdiSaveDC(%p)\n", hDC);
|
||||||
|
|
||||||
/* Lock the original dc */
|
/* Lock the original dc */
|
||||||
pdc = DC_LockDc(hDC);
|
pdc = DC_LockDc(hDC);
|
||||||
|
@ -211,7 +236,7 @@ NtGdiSaveDC(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new dc */
|
/* Allocate a new dc */
|
||||||
pdcSave = DC_AllocDC(NULL);
|
pdcSave = DC_AllocDcWithHandle();
|
||||||
if (pdcSave == NULL)
|
if (pdcSave == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Could not allocate a new DC\n");
|
DPRINT("Could not allocate a new DC\n");
|
||||||
|
@ -220,6 +245,9 @@ NtGdiSaveDC(
|
||||||
}
|
}
|
||||||
hdcSave = pdcSave->BaseObject.hHmgr;
|
hdcSave = pdcSave->BaseObject.hHmgr;
|
||||||
|
|
||||||
|
InterlockedIncrement(&pdc->ppdev->cPdevRefs);
|
||||||
|
DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
|
||||||
|
|
||||||
/* Make it a kernel handle
|
/* Make it a kernel handle
|
||||||
(FIXME: windows handles this different, see wiki)*/
|
(FIXME: windows handles this different, see wiki)*/
|
||||||
GDIOBJ_SetOwnership(hdcSave, NULL);
|
GDIOBJ_SetOwnership(hdcSave, NULL);
|
||||||
|
@ -242,7 +270,7 @@ NtGdiSaveDC(
|
||||||
DC_UnlockDc(pdcSave);
|
DC_UnlockDc(pdcSave);
|
||||||
DC_UnlockDc(pdc);
|
DC_UnlockDc(pdc);
|
||||||
|
|
||||||
DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
|
DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
|
||||||
return lSaveDepth;
|
return lSaveDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1258,7 +1258,7 @@ NtGdiCreateDIBitmapInternal(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Dc->dctype != DC_TYPE_MEMORY)
|
if (Dc->dctype != DC_TYPE_MEMORY)
|
||||||
bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
|
bpp = Dc->ppdev->gdiinfo.cBitsPixel;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DIBSECTION dibs;
|
DIBSECTION dibs;
|
||||||
|
|
|
@ -2226,7 +2226,7 @@ TextIntGetTextExtentPoint(PDC dc,
|
||||||
|
|
||||||
Size->cx = (TotalWidth + 32) >> 6;
|
Size->cx = (TotalWidth + 32) >> 6;
|
||||||
Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
|
Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
|
||||||
Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72);
|
Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -3425,7 +3425,9 @@ GreExtTextOutW(
|
||||||
/* Create the xlateobj */
|
/* Create the xlateobj */
|
||||||
hDestPalette = psurf->hDIBPalette;
|
hDestPalette = psurf->hDIBPalette;
|
||||||
if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
|
if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
|
||||||
|
//if (!hDestPalette) hDestPalette = StockObjects[DEFAULT_PALETTE];//pPrimarySurface->devinfo.hpalDefault;
|
||||||
ppalDst = PALETTE_LockPalette(hDestPalette);
|
ppalDst = PALETTE_LockPalette(hDestPalette);
|
||||||
|
ASSERT(ppalDst);
|
||||||
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
|
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
|
||||||
EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
|
EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
|
||||||
PALETTE_UnlockPalette(ppalDst);
|
PALETTE_UnlockPalette(ppalDst);
|
||||||
|
|
|
@ -51,8 +51,9 @@ SynchonizeDriver(FLONG Flags)
|
||||||
Flags = DSS_TIMER_EVENT;
|
Flags = DSS_TIMER_EVENT;
|
||||||
|
|
||||||
Device = IntEnumHDev();
|
Device = IntEnumHDev();
|
||||||
|
// UNIMPLEMENTED;
|
||||||
SurfObj = EngLockSurface( Device->pSurface );
|
//ASSERT(FALSE);
|
||||||
|
SurfObj = 0;// EngLockSurface( Device->pSurface );
|
||||||
if(!SurfObj) return;
|
if(!SurfObj) return;
|
||||||
DoDeviceSync( SurfObj, NULL, Flags);
|
DoDeviceSync( SurfObj, NULL, Flags);
|
||||||
EngUnlockSurface(SurfObj);
|
EngUnlockSurface(SurfObj);
|
||||||
|
|
|
@ -5,10 +5,10 @@ NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN
|
||||||
|
|
||||||
static int leak_reported = 0;
|
static int leak_reported = 0;
|
||||||
#define GDI_STACK_LEVELS 12
|
#define GDI_STACK_LEVELS 12
|
||||||
static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
||||||
static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
||||||
static ULONG GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
ULONG GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
||||||
static ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
|
||||||
struct DbgOpenGDIHandle
|
struct DbgOpenGDIHandle
|
||||||
{
|
{
|
||||||
ULONG idx;
|
ULONG idx;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
/** INCLUDES ******************************************************************/
|
/** INCLUDES ******************************************************************/
|
||||||
|
|
||||||
//#define GDI_DEBUG
|
#define GDI_DEBUG
|
||||||
|
|
||||||
#include <w32k.h>
|
#include <w32k.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -761,7 +761,7 @@ GreDeleteObject(HGDIOBJ hObject)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDI_OBJECT_TYPE_DC:
|
case GDI_OBJECT_TYPE_DC:
|
||||||
DC_FreeDcAttr(hObject);
|
// DC_FreeDcAttr(hObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,6 +894,8 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
|
||||||
POBJ Object = NULL;
|
POBJ Object = NULL;
|
||||||
ULONG HandleType, HandleUpper;
|
ULONG HandleType, HandleUpper;
|
||||||
|
|
||||||
|
GDIDBG_INITLOOPTRACE();
|
||||||
|
|
||||||
HandleIndex = GDI_HANDLE_GET_INDEX(hObj);
|
HandleIndex = GDI_HANDLE_GET_INDEX(hObj);
|
||||||
HandleType = GDI_HANDLE_GET_TYPE(hObj);
|
HandleType = GDI_HANDLE_GET_TYPE(hObj);
|
||||||
HandleUpper = GDI_HANDLE_GET_UPPER(hObj);
|
HandleUpper = GDI_HANDLE_GET_UPPER(hObj);
|
||||||
|
@ -973,6 +975,11 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
|
||||||
{
|
{
|
||||||
if (Object->Tid != Thread)
|
if (Object->Tid != Thread)
|
||||||
{
|
{
|
||||||
|
GDIDBG_TRACELOOP(hObj, Object->Tid, Thread);
|
||||||
|
GDIDBG_TRACECALLER();
|
||||||
|
GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj));
|
||||||
|
GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
|
||||||
|
|
||||||
/* Unlock the handle table entry. */
|
/* Unlock the handle table entry. */
|
||||||
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
|
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
|
||||||
|
|
||||||
|
@ -1001,6 +1008,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
|
||||||
/*
|
/*
|
||||||
* The handle is currently locked, wait some time and try again.
|
* The handle is currently locked, wait some time and try again.
|
||||||
*/
|
*/
|
||||||
|
GDIDBG_TRACELOOP(hObj, PrevProcId, NULL);
|
||||||
|
|
||||||
DelayExecution();
|
DelayExecution();
|
||||||
continue;
|
continue;
|
||||||
|
@ -1651,10 +1659,9 @@ IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
|
||||||
{
|
{
|
||||||
pDC = DC_LockDc ( hDC );
|
pDC = DC_LockDc ( hDC );
|
||||||
MmCopyFromCaller(&pDC->dcattr, pDC->pdcattr, sizeof(DC_ATTR));
|
MmCopyFromCaller(&pDC->dcattr, pDC->pdcattr, sizeof(DC_ATTR));
|
||||||
|
DC_vFreeDcAttr(pDC);
|
||||||
DC_UnlockDc( pDC );
|
DC_UnlockDc( pDC );
|
||||||
|
|
||||||
DC_FreeDcAttr( hDC ); // Free the dcattr!
|
|
||||||
|
|
||||||
if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
|
if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,18 +150,6 @@ EngFindResource(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
LPWSTR
|
|
||||||
APIENTRY
|
|
||||||
EngGetDriverName ( IN HDEV hdev )
|
|
||||||
{
|
|
||||||
// www.osr.com/ddk/graphics/gdifncs_2gx3.htm
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -71,12 +71,14 @@
|
||||||
</directory>
|
</directory>
|
||||||
</if>
|
</if>
|
||||||
<file>gradient.c</file>
|
<file>gradient.c</file>
|
||||||
|
<file>ldevobj.c</file>
|
||||||
<file>lineto.c</file>
|
<file>lineto.c</file>
|
||||||
<file>mapping.c</file>
|
<file>mapping.c</file>
|
||||||
<file>mem.c</file>
|
<file>mem.c</file>
|
||||||
<file>engmisc.c</file>
|
<file>engmisc.c</file>
|
||||||
<file>mouse.c</file>
|
<file>mouse.c</file>
|
||||||
<file>paint.c</file>
|
<file>paint.c</file>
|
||||||
|
<file>pdevobj.c</file>
|
||||||
<file>perfcnt.c</file>
|
<file>perfcnt.c</file>
|
||||||
<file>semaphor.c</file>
|
<file>semaphor.c</file>
|
||||||
<file>sort.c</file>
|
<file>sort.c</file>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue