Dmitry Philippov <shedon@mail.ru>

- 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
This commit is contained in:
Aleksey Bragin 2007-12-23 19:13:05 +00:00
parent 41e2d7b240
commit a6ca74e2cf
4 changed files with 82 additions and 12 deletions

View 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);

View file

@ -25,6 +25,16 @@
#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 */

View 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))

View 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);
}
/*++