[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 11 Nov 2013 19:09:53 +0000 (19:09 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 11 Nov 2013 19:09:53 +0000 (19:09 +0000)
Fix SystemUnloadGdiDriverInformation case of NtSetSystemInformation.

svn path=/trunk/; revision=60949

reactos/ntoskrnl/ex/sysinfo.c
reactos/win32ss/gdi/eng/ldevobj.c
reactos/win32ss/gdi/eng/ldevobj.h

index 22ba4f9..f441dff 100644 (file)
@@ -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;
 }
 
index a4afcf7..42d087f 100644 (file)
@@ -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;
 }
 
index 82918f3..8173041 100644 (file)
@@ -30,36 +30,16 @@ 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
+INIT_FUNCTION
+NTSTATUS
 NTAPI
-LDEVOBJ_pvFindImageProcAddress(
-    IN PLDEVOBJ pldev,
-    IN LPSTR    lpProcName);
+InitLDEVImpl(VOID);
 
 PDEVMODEINFO
 NTAPI
 LDEVOBJ_pdmiGetModes(
-    PLDEVOBJ pldev,
-    HANDLE hDriver);
-
-INIT_FUNCTION
-NTSTATUS
-NTAPI
-InitLDEVImpl(VOID);
+    _In_ PLDEVOBJ pldev,
+    _In_ HANDLE hDriver);
 
 PLDEVOBJ
 APIENTRY
@@ -75,6 +55,6 @@ EngGetLDEV(
 NTSTATUS
 APIENTRY
 DriverEntry (
-  IN   PDRIVER_OBJECT  DriverObject,
-  IN   PUNICODE_STRING RegistryPath);
+    _In_ PDRIVER_OBJECT        DriverObject,
+    _In_ PUNICODE_STRING RegistryPath);