diff --git a/reactos/subsystems/win32/win32k/include/intddraw.h b/reactos/subsystems/win32/win32k/include/intddraw.h index b0c563cd9ad..fd11d1e8162 100644 --- a/reactos/subsystems/win32/win32k/include/intddraw.h +++ b/reactos/subsystems/win32/win32k/include/intddraw.h @@ -8,7 +8,7 @@ #include /* From ddraw.c */ -extern PDRVFN gpDxFuncs; +extern DRVFN gpDxFuncs[]; typedef BOOL (NTAPI* PGD_DDSETGAMMARAMP)(HANDLE, HDC, LPVOID); typedef BOOL (NTAPI* PGD_DDRELEASEDC)(HANDLE); diff --git a/reactos/subsystems/win32/win32k/ldr/loader.c b/reactos/subsystems/win32/win32k/ldr/loader.c index 18880e82879..2f9a1beee9b 100644 --- a/reactos/subsystems/win32/win32k/ldr/loader.c +++ b/reactos/subsystems/win32/win32k/ldr/loader.c @@ -25,6 +25,16 @@ #define NDEBUG #include + +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 */ diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index 52f92b05815..0c42059d288 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -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)) diff --git a/reactos/subsystems/win32/win32k/ntddraw/ddraw.c b/reactos/subsystems/win32/win32k/ntddraw/ddraw.c index 4160b81daf4..2e08dc6a881 100644 --- a/reactos/subsystems/win32/win32k/ntddraw/ddraw.c +++ b/reactos/subsystems/win32/win32k/ntddraw/ddraw.c @@ -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); - } /*++