Dmitry Philippov <shedon@mail.ru>
authorAleksey Bragin <aleksey@reactos.org>
Sun, 23 Dec 2007 19:13:05 +0000 (19:13 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Sun, 23 Dec 2007 19:13:05 +0000 (19:13 +0000)
- The EngLoadImage and EngUnloadImage functions have been fixed to store handles of loaded drivers. EngLoadImage should not fail if a driver is already loaded, it should return a handle of the already loaded driver instead.
- The gpDxFuncs variable has been redefined. Earlier, memory was not allocated for this variable, thus resulting in memory corruption.

svn path=/trunk/; revision=31416

reactos/subsystems/win32/win32k/include/intddraw.h
reactos/subsystems/win32/win32k/ldr/loader.c
reactos/subsystems/win32/win32k/main/dllmain.c
reactos/subsystems/win32/win32k/ntddraw/ddraw.c

index b0c563c..fd11d1e 100644 (file)
@@ -8,7 +8,7 @@
 #include <reactos/drivers/directx/dxeng.h>
 
 /* From ddraw.c */
-extern PDRVFN gpDxFuncs;
+extern DRVFN gpDxFuncs[];
 
 typedef BOOL (NTAPI* PGD_DDSETGAMMARAMP)(HANDLE, HDC, LPVOID);
 typedef BOOL (NTAPI* PGD_DDRELEASEDC)(HANDLE);
index 18880e8..2f9a1be 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+
+typedef struct _DRIVERS
+{
+       LIST_ENTRY ListEntry;
+       HANDLE ImageHandle;
+       UNICODE_STRING DriverName;
+}DRIVERS, *PDRIVERS;
+
+extern LIST_ENTRY GlobalDriverListHead;
+
 /*
  * Blatantly stolen from ldr/utils.c in ntdll.  I can't link ntdll from
  * here, though.
@@ -189,14 +199,47 @@ HANDLE
 STDCALL
 EngLoadImage (LPWSTR DriverName)
 {
-  SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
-  NTSTATUS Status;
+       HANDLE hImageHandle = NULL;
+       SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+       NTSTATUS Status;
 
-  RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
-  Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-  if (!NT_SUCCESS(Status)) return NULL;
+       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)) ) {
+                               hImageHandle = Current->ImageHandle;
+                               break;
+                       }
+                       CurrentEntry = CurrentEntry->Flink;
+               };
+       }
 
-  return (HANDLE)GdiDriverInfo.ImageAddress;
+       if( !hImageHandle )
+       {
+               /* 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 faild with status 0x%lx\n", Status);
+               }
+               else {
+                       hImageHandle = (HANDLE)GdiDriverInfo.ImageAddress;
+                       PDRIVERS 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->ImageHandle = hImageHandle;
+                       InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
+               }
+       }
+
+       return hImageHandle;
 }
 
 
@@ -226,7 +269,8 @@ EngUnloadImage ( IN HANDLE hModule )
 {
   NTSTATUS Status;
 
-  DPRINT1("hModule=%x\n", hModule);
+  DPRINT1("hModule=%x\n", hModule); 
+
   Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
     &hModule, sizeof(HANDLE));
 
@@ -235,6 +279,30 @@ EngUnloadImage ( IN HANDLE hModule )
     DPRINT1("%s: ZwSetSystemInformation failed with status %x.",
       __FUNCTION__, Status);
   }
+  else
+  {
+         /* remove from the list */
+         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 ) {
+                                 if(Current->ImageHandle == hModule) { 
+                                         ExFreePool(Current->DriverName.Buffer);
+                                         RemoveEntryList(&Current->ListEntry);
+                                         ExFreePool(Current);
+                                         break;
+                                 }
+                         }
+                         CurrentEntry = CurrentEntry->Flink;
+                 };
+         }
+  }
 }
 
 /* EOF */
index 52f92b0..0c42059 100644 (file)
@@ -33,6 +33,8 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (PGDI_HANDLE_TABLE HandleTable, struct
 PGDI_HANDLE_TABLE GdiHandleTable = NULL;
 PSECTION_OBJECT GdiTableSection = NULL;
 
+LIST_ENTRY GlobalDriverListHead;
+
 HANDLE GlobalUserHeap = NULL;
 PSECTION_OBJECT GlobalUserHeapSection = NULL;
 
@@ -402,6 +404,8 @@ DriverEntry (
         return STATUS_UNSUCCESSFUL;
     }
 
+  /* Initialize a list of loaded drivers in Win32 subsystem */
+  InitializeListHead(&GlobalDriverListHead);
 
   Status = InitUserImpl();
   if (!NT_SUCCESS(Status))
index 4160b81..2e08dc6 100644 (file)
@@ -18,8 +18,8 @@ PGD_DXDDCLEANUPDXGRAPHICS gpfnCleanupDxGraphics = NULL;
 extern DRVFN gaEngFuncs;
 extern ULONG gcEngFuncs;
 
-PDRVFN gpDxFuncs;
-HANDLE ghDxGraphics;
+DRVFN gpDxFuncs[DXG_INDEX_DxDdIoctl];
+HANDLE ghDxGraphics = NULL;
 ULONG gdwDirectDrawContext;
 
 
@@ -126,7 +126,6 @@ HANDLE
 STDCALL 
 NtGdiDdCreateDirectDrawObject(HDC hdc)
 {
-
     PGD_DDCREATEDIRECTDRAWOBJECT pfnDdCreateDirectDrawObject = NULL;
     NTSTATUS Status;
     PEPROCESS Proc = NULL;
@@ -152,7 +151,6 @@ NtGdiDdCreateDirectDrawObject(HDC hdc)
 
     DPRINT1("Calling dxg.sys DdCreateDirectDrawObject\n");
     return pfnDdCreateDirectDrawObject(hdc);
-
 }
 
 /*++