mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[NTOSKRNL]
Fix SystemUnloadGdiDriverInformation case of NtSetSystemInformation. svn path=/trunk/; revision=60949
This commit is contained in:
parent
76568b06b5
commit
7833279fa4
3 changed files with 66 additions and 86 deletions
|
@ -1397,7 +1397,7 @@ SSI_DEF(SystemLoadGdiDriverInformation)
|
|||
/* Class 27 - Unload Image */
|
||||
SSI_DEF(SystemUnloadGdiDriverInformation)
|
||||
{
|
||||
PVOID SectionPointer = Buffer;
|
||||
PVOID *SectionPointer = Buffer;
|
||||
|
||||
/* Validate size */
|
||||
if (Size != sizeof(PVOID))
|
||||
|
@ -1410,7 +1410,7 @@ SSI_DEF(SystemUnloadGdiDriverInformation)
|
|||
if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD;
|
||||
|
||||
/* Unload the image */
|
||||
MmUnloadSystemImage(SectionPointer);
|
||||
MmUnloadSystemImage(*SectionPointer);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <win32k.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(EngLDev);
|
||||
|
||||
#ifndef RVA_TO_ADDR
|
||||
#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
|
||||
|
@ -16,9 +17,9 @@
|
|||
|
||||
/** Globals *******************************************************************/
|
||||
|
||||
HSEMAPHORE ghsemLDEVList;
|
||||
LDEVOBJ *gpldevHead = NULL;
|
||||
LDEVOBJ *gpldevWin32k = NULL;
|
||||
static HSEMAPHORE ghsemLDEVList;
|
||||
static LDEVOBJ *gpldevHead = NULL;
|
||||
static LDEVOBJ *gpldevWin32k = NULL;
|
||||
|
||||
|
||||
/** Private functions *********************************************************/
|
||||
|
@ -26,7 +27,7 @@ LDEVOBJ *gpldevWin32k = NULL;
|
|||
INIT_FUNCTION
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
InitLDEVImpl()
|
||||
InitLDEVImpl(VOID)
|
||||
{
|
||||
ULONG cbSize;
|
||||
|
||||
|
@ -34,6 +35,7 @@ InitLDEVImpl()
|
|||
ghsemLDEVList = EngCreateSemaphore();
|
||||
if (!ghsemLDEVList)
|
||||
{
|
||||
ERR("Failed to create ghsemLDEVList\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
@ -69,9 +71,10 @@ InitLDEVImpl()
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
PLDEVOBJ
|
||||
NTAPI
|
||||
LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
|
||||
LDEVOBJ_AllocLDEV(
|
||||
_In_ LDEVTYPE ldevtype)
|
||||
{
|
||||
PLDEVOBJ pldev;
|
||||
|
||||
|
@ -79,7 +82,7 @@ LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
|
|||
pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV);
|
||||
if (!pldev)
|
||||
{
|
||||
DPRINT1("Failed to allocate LDEVOBJ.\n");
|
||||
ERR("Failed to allocate LDEVOBJ.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -92,9 +95,10 @@ LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
|
|||
return pldev;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
|
||||
LDEVOBJ_vFreeLDEV(
|
||||
_In_ _Post_ptr_invalid_ PLDEVOBJ pldev)
|
||||
{
|
||||
/* Make sure we don't have a driver loaded */
|
||||
ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
|
||||
|
@ -107,19 +111,19 @@ LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
|
|||
PDEVMODEINFO
|
||||
NTAPI
|
||||
LDEVOBJ_pdmiGetModes(
|
||||
PLDEVOBJ pldev,
|
||||
HANDLE hDriver)
|
||||
_In_ PLDEVOBJ pldev,
|
||||
_In_ HANDLE hDriver)
|
||||
{
|
||||
ULONG cbSize, cbFull;
|
||||
PDEVMODEINFO pdminfo;
|
||||
|
||||
DPRINT("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
|
||||
TRACE("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");
|
||||
ERR("DrvGetModes returned 0\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -130,7 +134,7 @@ LDEVOBJ_pdmiGetModes(
|
|||
pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
|
||||
if (!pdminfo)
|
||||
{
|
||||
DPRINT1("Could not allocate devmodeinfo\n");
|
||||
ERR("Could not allocate devmodeinfo\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -142,7 +146,7 @@ LDEVOBJ_pdmiGetModes(
|
|||
if (!cbSize)
|
||||
{
|
||||
/* Could not get modes */
|
||||
DPRINT1("returned size %lu(%lu)\n", cbSize, pdminfo->cbdevmode);
|
||||
ERR("returned size %lu(%lu)\n", cbSize, pdminfo->cbdevmode);
|
||||
ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE);
|
||||
pdminfo = NULL;
|
||||
}
|
||||
|
@ -150,12 +154,11 @@ LDEVOBJ_pdmiGetModes(
|
|||
return pdminfo;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
BOOL
|
||||
NTAPI
|
||||
LDEVOBJ_bLoadImage(
|
||||
IN PLDEVOBJ pldev,
|
||||
PUNICODE_STRING pstrPathName)
|
||||
_Inout_ PLDEVOBJ pldev,
|
||||
_In_ PUNICODE_STRING pustrPathName)
|
||||
{
|
||||
PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo;
|
||||
NTSTATUS Status;
|
||||
|
@ -165,19 +168,19 @@ LDEVOBJ_bLoadImage(
|
|||
ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
|
||||
|
||||
/* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
|
||||
cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length;
|
||||
cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pustrPathName->Length;
|
||||
pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
|
||||
if (!pDriverInfo)
|
||||
{
|
||||
DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
|
||||
ERR("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize the UNICODE_STRING and copy the driver name */
|
||||
RtlInitEmptyUnicodeString(&pDriverInfo->DriverName,
|
||||
(PWSTR)(pDriverInfo + 1),
|
||||
pstrPathName->Length);
|
||||
RtlCopyUnicodeString(&pDriverInfo->DriverName, pstrPathName);
|
||||
pustrPathName->Length);
|
||||
RtlCopyUnicodeString(&pDriverInfo->DriverName, pustrPathName);
|
||||
|
||||
/* Try to load the driver */
|
||||
Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
|
||||
|
@ -186,8 +189,8 @@ LDEVOBJ_bLoadImage(
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to load a GDI driver: '%S', Status = 0x%lx\n",
|
||||
pstrPathName->Buffer, Status);
|
||||
ERR("Failed to load a GDI driver: '%wZ', Status = 0x%lx\n",
|
||||
pustrPathName, Status);
|
||||
|
||||
/* Free the allocated memory */
|
||||
ExFreePoolWithTag(pDriverInfo, GDITAG_LDEV);
|
||||
|
@ -201,10 +204,10 @@ LDEVOBJ_bLoadImage(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
LDEVOBJ_vUnloadImage(
|
||||
IN PLDEVOBJ pldev)
|
||||
_Inout_ PLDEVOBJ pldev)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
|
@ -220,11 +223,11 @@ LDEVOBJ_vUnloadImage(
|
|||
|
||||
/* Unload the driver */
|
||||
Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
|
||||
&pldev->pGdiDriverInfo->ImageAddress,
|
||||
&pldev->pGdiDriverInfo->SectionPointer,
|
||||
sizeof(HANDLE));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to unload the driver, this is bad.\n");
|
||||
ERR("Failed to unload the driver, this is bad.\n");
|
||||
}
|
||||
|
||||
/* Free the driver info structure */
|
||||
|
@ -232,10 +235,10 @@ LDEVOBJ_vUnloadImage(
|
|||
pldev->pGdiDriverInfo = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL
|
||||
NTAPI
|
||||
LDEVOBJ_bLoadDriver(
|
||||
IN PLDEVOBJ pldev)
|
||||
LDEVOBJ_bEnableDriver(
|
||||
_Inout_ PLDEVOBJ pldev)
|
||||
{
|
||||
PFN_DrvEnableDriver pfnEnableDriver;
|
||||
DRVENABLEDATA ded;
|
||||
|
@ -249,10 +252,7 @@ LDEVOBJ_bLoadDriver(
|
|||
pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint;
|
||||
if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
|
||||
{
|
||||
DPRINT1("DrvEnableDriver failed\n");
|
||||
|
||||
/* Unload the image. */
|
||||
LDEVOBJ_vUnloadImage(pldev);
|
||||
ERR("DrvEnableDriver failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -269,12 +269,11 @@ LDEVOBJ_bLoadDriver(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PVOID
|
||||
NTAPI
|
||||
LDEVOBJ_pvFindImageProcAddress(
|
||||
IN PLDEVOBJ pldev,
|
||||
IN LPSTR pszProcName)
|
||||
_In_ PLDEVOBJ pldev,
|
||||
_In_z_ LPSTR pszProcName)
|
||||
{
|
||||
PVOID pvImageBase;
|
||||
PIMAGE_EXPORT_DIRECTORY pExportDir;
|
||||
|
@ -318,8 +317,8 @@ LDEVOBJ_pvFindImageProcAddress(
|
|||
PLDEVOBJ
|
||||
NTAPI
|
||||
EngLoadImageEx(
|
||||
LPWSTR pwszDriverName,
|
||||
ULONG ldevtype)
|
||||
_In_z_ LPWSTR pwszDriverName,
|
||||
_In_ ULONG ldevtype)
|
||||
{
|
||||
WCHAR acwBuffer[MAX_PATH];
|
||||
PLDEVOBJ pldev;
|
||||
|
@ -327,7 +326,7 @@ EngLoadImageEx(
|
|||
SIZE_T cwcLength;
|
||||
LPWSTR pwsz;
|
||||
|
||||
DPRINT("EngLoadImageEx(%ls, %lu)\n", pwszDriverName, ldevtype);
|
||||
TRACE("EngLoadImageEx(%ls, %lu)\n", pwszDriverName, ldevtype);
|
||||
ASSERT(pwszDriverName);
|
||||
|
||||
/* Initialize buffer for the the driver name */
|
||||
|
@ -343,7 +342,7 @@ EngLoadImageEx(
|
|||
pwsz = pwszDriverName + cwcLength;
|
||||
while (pwsz > pwszDriverName)
|
||||
{
|
||||
if (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0)
|
||||
if ((*pwsz == L'\\') && (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0))
|
||||
{
|
||||
/* Driver name starts after system32 */
|
||||
pwsz += 10;
|
||||
|
@ -356,12 +355,11 @@ EngLoadImageEx(
|
|||
RtlAppendUnicodeToString(&strDriverName, pwsz);
|
||||
|
||||
/* MSDN says "The driver must include this suffix in the pwszDriver string."
|
||||
But in fact it's optional.
|
||||
|
||||
ms win32k EngLoadImageEx loading .sys file without append .dll
|
||||
*/
|
||||
if ( (_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) &&
|
||||
(_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0) )
|
||||
But in fact it's optional. The function can also load .sys files without
|
||||
appending the .dll extension. */
|
||||
if ((cwcLength < 4) ||
|
||||
((_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) &&
|
||||
(_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0)) )
|
||||
{
|
||||
/* Append the .dll suffix */
|
||||
RtlAppendUnicodeToString(&strDriverName, L".dll");
|
||||
|
@ -392,7 +390,7 @@ EngLoadImageEx(
|
|||
pldev = LDEVOBJ_AllocLDEV(ldevtype);
|
||||
if (!pldev)
|
||||
{
|
||||
DPRINT1("Could not allocate LDEV\n");
|
||||
ERR("Could not allocate LDEV\n");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -401,7 +399,7 @@ EngLoadImageEx(
|
|||
{
|
||||
LDEVOBJ_vFreeLDEV(pldev);
|
||||
pldev = NULL;
|
||||
DPRINT1("LDEVOBJ_bLoadImage failed\n");
|
||||
ERR("LDEVOBJ_bLoadImage failed\n");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -409,9 +407,12 @@ EngLoadImageEx(
|
|||
if (ldevtype != LDEV_IMAGE)
|
||||
{
|
||||
/* Load the driver */
|
||||
if (!LDEVOBJ_bLoadDriver(pldev))
|
||||
if (!LDEVOBJ_bEnableDriver(pldev))
|
||||
{
|
||||
DPRINT1("LDEVOBJ_bLoadDriver failed\n");
|
||||
ERR("LDEVOBJ_bEnableDriver failed\n");
|
||||
|
||||
/* Unload the image. */
|
||||
LDEVOBJ_vUnloadImage(pldev);
|
||||
LDEVOBJ_vFreeLDEV(pldev);
|
||||
pldev = NULL;
|
||||
goto leave;
|
||||
|
@ -431,8 +432,7 @@ leave:
|
|||
/* Unlock loader */
|
||||
EngReleaseSemaphore(ghsemLDEVList);
|
||||
|
||||
DPRINT("EngLoadImageEx returning %p\n", pldev);
|
||||
|
||||
TRACE("EngLoadImageEx returning %p\n", pldev);
|
||||
return pldev;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,37 +30,17 @@ typedef struct _LDEVOBJ
|
|||
|
||||
} 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);
|
||||
|
||||
INIT_FUNCTION
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
InitLDEVImpl(VOID);
|
||||
|
||||
PDEVMODEINFO
|
||||
NTAPI
|
||||
LDEVOBJ_pdmiGetModes(
|
||||
_In_ PLDEVOBJ pldev,
|
||||
_In_ HANDLE hDriver);
|
||||
|
||||
PLDEVOBJ
|
||||
APIENTRY
|
||||
EngLoadImageEx(
|
||||
|
@ -75,6 +55,6 @@ EngGetLDEV(
|
|||
NTSTATUS
|
||||
APIENTRY
|
||||
DriverEntry (
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath);
|
||||
|
||||
|
|
Loading…
Reference in a new issue