- Properly implement SystemLoadGdiDriverInformation.

- Properly implement SystemExtendServiceTableInformation, except that the SE_LOAD_DRIVER_PRIVILEGE check is currently disabled since our smss doesn't acquire it (and we should therefore ban it from loading win32k.sys...).
- Delete LdrpLoadImage, LdrpUnlaodImage, LdrpLoadAndCallImage.

svn path=/trunk/; revision=25862
This commit is contained in:
Alex Ionescu 2007-02-21 02:46:30 +00:00
parent effa3a52ef
commit 828eda9888
3 changed files with 115 additions and 116 deletions

View file

@ -1137,33 +1137,62 @@ QSI_DEF(SystemFullMemoryInformation)
} }
/* Class 26 - Load Image */ /* Class 26 - Load Image */
SSI_DEF(SystemLoadImage) SSI_DEF(SystemLoadGdiDriverInformation)
{ {
PSYSTEM_GDI_DRIVER_INFORMATION Sli = (PSYSTEM_GDI_DRIVER_INFORMATION)Buffer; PSYSTEM_GDI_DRIVER_INFORMATION DriverInfo = (PVOID)Buffer;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
UNICODE_STRING ImageName;
PVOID ImageBase;
ULONG_PTR EntryPoint;
NTSTATUS Status;
PLDR_DATA_TABLE_ENTRY ModuleObject;
ULONG DirSize;
PIMAGE_NT_HEADERS NtHeader;
if (sizeof(SYSTEM_GDI_DRIVER_INFORMATION) != Size) /* Validate size */
if (Size != sizeof(SYSTEM_GDI_DRIVER_INFORMATION))
{ {
return(STATUS_INFO_LENGTH_MISMATCH); /* Incorrect buffer length, fail */
return STATUS_INFO_LENGTH_MISMATCH;
} }
return(LdrpLoadImage(&Sli->DriverName, /* Only kernel-mode can call this function */
&Sli->ImageAddress, if (PreviousMode != KernelMode) return STATUS_PRIVILEGE_NOT_HELD;
&Sli->SectionPointer,
&Sli->EntryPoint, /* Load the driver */
(PVOID)&Sli->ExportSectionPointer)); ImageName = DriverInfo->DriverName;
Status = LdrLoadModule(&ImageName, &ModuleObject);
if (!NT_SUCCESS(Status)) return Status;
/* Return the export pointer */
ImageBase = ModuleObject->DllBase;
DriverInfo->ExportSectionPointer =
RtlImageDirectoryEntryToData(ImageBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&DirSize);
/* Get the entrypoint */
NtHeader = RtlImageNtHeader(ImageBase);
EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint;
EntryPoint += (ULONG_PTR)ImageBase;
/* Save other data */
DriverInfo->ImageAddress = ImageBase;
DriverInfo->SectionPointer = NULL;
DriverInfo->EntryPoint = (PVOID)EntryPoint;
DriverInfo->ImageLength = NtHeader->OptionalHeader.SizeOfImage;
/* All is good */
return STATUS_SUCCESS;
} }
/* Class 27 - Unload Image */ /* Class 27 - Unload Image */
SSI_DEF(SystemUnloadImage) SSI_DEF(SystemUnloadGdiDriverInformation)
{ {
PVOID Sui = (PVOID)Buffer; /* FIXME: TODO */
if (Size != sizeof(PVOID)) return STATUS_INFO_LENGTH_MISMATCH;
if (sizeof(PVOID) != Size) return STATUS_NOT_IMPLEMENTED;
{
return(STATUS_INFO_LENGTH_MISMATCH);
}
return(LdrpUnloadImage(Sui));
} }
/* Class 28 - Time Adjustment Information */ /* Class 28 - Time Adjustment Information */
@ -1290,16 +1319,74 @@ SSI_DEF(SystemRegistryQuotaInformation)
} }
/* Class 38 - Load And Call Image */ /* Class 38 - Load And Call Image */
SSI_DEF(SystemLoadAndCallImage) SSI_DEF(SystemExtendServiceTableInformation)
{ {
PUNICODE_STRING Slci = (PUNICODE_STRING)Buffer; UNICODE_STRING ImageName;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PLDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
PIMAGE_NT_HEADERS NtHeader;
DRIVER_OBJECT Win32k;
PDRIVER_INITIALIZE DriverInit;
PVOID ImageBase;
ULONG_PTR EntryPoint;
if (sizeof(UNICODE_STRING) != Size) /* Validate the size */
if (Size != sizeof(UNICODE_STRING)) return STATUS_INFO_LENGTH_MISMATCH;
/* Check who is calling */
if (PreviousMode != KernelMode)
{ {
return(STATUS_INFO_LENGTH_MISMATCH); /* Make sure we can load drivers */
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, UserMode))
{
/* FIXME: We can't, fail */
//return STATUS_PRIVILEGE_NOT_HELD;
} }
return(LdrpLoadAndCallImage(Slci)); /* Probe and capture the driver name */
ProbeAndCaptureUnicodeString(&ImageName, UserMode, Buffer);
/* Force kernel as previous mode */
return ZwSetSystemInformation(SystemExtendServiceTableInformation,
&ImageName,
sizeof(ImageName));
}
/* Just copy the string */
ImageName = *(PUNICODE_STRING)Buffer;
/* Load the image */
Status = LdrLoadModule(&ImageName, &ModuleObject);
if (!NT_SUCCESS(Status)) return Status;
/* Get the headers */
ImageBase = ModuleObject->DllBase;
NtHeader = RtlImageNtHeader(ImageBase);
if (!NtHeader)
{
/* Fail */
LdrUnloadModule(ModuleObject);
return STATUS_INVALID_IMAGE_FORMAT;
}
/* Get the entrypoint */
EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint;
EntryPoint += (ULONG_PTR)ImageBase;
DriverInit = (PDRIVER_INITIALIZE)EntryPoint;
/* Create a dummy device */
RtlZeroMemory(&Win32k, sizeof(Win32k));
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
Win32k.DriverStart = ImageBase;
/* Call it */
Status = (DriverInit)(&Win32k, NULL);
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
/* Unload if we failed */
if (!NT_SUCCESS(Status)) LdrUnloadModule(ModuleObject);
return Status;
} }
/* Class 39 - Priority Separation */ /* Class 39 - Priority Separation */
@ -1511,8 +1598,8 @@ CallQS [] =
SI_QX(SystemInterruptInformation), SI_QX(SystemInterruptInformation),
SI_QS(SystemDpcBehaviourInformation), SI_QS(SystemDpcBehaviourInformation),
SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */ SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
SI_XS(SystemLoadImage), SI_XS(SystemLoadGdiDriverInformation),
SI_XS(SystemUnloadImage), SI_XS(SystemUnloadGdiDriverInformation),
SI_QS(SystemTimeAdjustmentInformation), SI_QS(SystemTimeAdjustmentInformation),
SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */ SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */ SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
@ -1523,7 +1610,7 @@ CallQS [] =
SI_QX(SystemKernelDebuggerInformation), SI_QX(SystemKernelDebuggerInformation),
SI_QX(SystemContextSwitchInformation), SI_QX(SystemContextSwitchInformation),
SI_QS(SystemRegistryQuotaInformation), SI_QS(SystemRegistryQuotaInformation),
SI_XS(SystemLoadAndCallImage), SI_XS(SystemExtendServiceTableInformation),
SI_XS(SystemPrioritySeperation), SI_XS(SystemPrioritySeperation),
SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */ SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
SI_QX(SystemDockInformation), /* it should be SI_XX */ SI_QX(SystemDockInformation), /* it should be SI_XX */

View file

@ -78,7 +78,7 @@ IopDeleteDriver(IN PVOID ObjectBody)
if (DriverObject->DriverSection) if (DriverObject->DriverSection)
{ {
/* Unload it */ /* Unload it */
LdrpUnloadImage(DriverObject->DriverSection); //LdrpUnloadImage(DriverObject->DriverSection);
} }
/* Check if it has a name */ /* Check if it has a name */

View file

@ -556,7 +556,7 @@ LdrPEProcessModule(
DPRINT("Failed to allocate a virtual section for driver\n"); DPRINT("Failed to allocate a virtual section for driver\n");
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
DPRINT1("DriverBase for %wZ: %x\n", FileName, DriverBase); DPRINT("DriverBase for %wZ: %x\n", FileName, DriverBase);
/* Copy headers over */ /* Copy headers over */
memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders); memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
@ -740,94 +740,6 @@ LdrGetModuleObject ( PUNICODE_STRING ModuleName )
return(NULL); return(NULL);
} }
//
// Used by NtSetSystemInformation
//
NTSTATUS
NTAPI
LdrpLoadImage (
PUNICODE_STRING DriverName,
PVOID *ModuleBase,
PVOID *SectionPointer,
PVOID *EntryPoint,
PVOID *ExportSectionPointer )
{
PLDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
ModuleObject = LdrGetModuleObject(DriverName);
if (ModuleObject == NULL)
{
Status = LdrLoadModule(DriverName, &ModuleObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
if (ModuleBase)
*ModuleBase = ModuleObject->DllBase;
if (SectionPointer)
*SectionPointer = ModuleObject;
if (EntryPoint)
*EntryPoint = ModuleObject->EntryPoint;
//if (ExportSectionPointer)
// *ExportSectionPointer = ModuleObject->
return(STATUS_SUCCESS);
}
//
// Used by NtSetSystemInformation
//
NTSTATUS
NTAPI
LdrpUnloadImage ( PVOID ModuleBase )
{
return(STATUS_NOT_IMPLEMENTED);
}
//
// Used by NtSetSystemInformation
//
NTSTATUS
NTAPI
LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName )
{
PDRIVER_INITIALIZE DriverEntry;
PLDR_DATA_TABLE_ENTRY ModuleObject;
DRIVER_OBJECT DriverObject;
NTSTATUS Status;
ModuleObject = LdrGetModuleObject(ModuleName);
if (ModuleObject != NULL)
{
return(STATUS_IMAGE_ALREADY_LOADED);
}
Status = LdrLoadModule(ModuleName, &ModuleObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DriverEntry = (PDRIVER_INITIALIZE)ModuleObject->EntryPoint;
RtlZeroMemory(&DriverObject, sizeof(DriverObject));
// DriverObject.DriverStart = ModuleObject->DllBase;
Status = DriverEntry(&DriverObject, NULL);
if (!NT_SUCCESS(Status))
{
LdrUnloadModule(ModuleObject);
}
return(Status);
}
// //
// Used when unloading drivers // Used when unloading drivers
// //