2005-09-27 12:43:36 +00:00
|
|
|
|
/*
|
2006-07-09 00:01:31 +00:00
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2006-07-09 02:34:32 +00:00
|
|
|
|
* FILE: ntoskrnl/io/iomgr/driver.c
|
2006-07-09 00:01:31 +00:00
|
|
|
|
* PURPOSE: Driver Object Management
|
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
|
* Filip Navara (navaraf@reactos.org)
|
|
|
|
|
* Herv<EFBFBD> Poussineau (hpoussin@reactos.org)
|
2003-10-06 18:49:50 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/* INCLUDES *******************************************************************/
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
|
#include <ntoskrnl.h>
|
2003-10-06 18:49:50 +00:00
|
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
|
#include <debug.h>
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/* GLOBALS ********************************************************************/
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2006-07-09 02:34:32 +00:00
|
|
|
|
LIST_ENTRY DriverReinitListHead;
|
|
|
|
|
KSPIN_LOCK DriverReinitListLock;
|
|
|
|
|
PLIST_ENTRY DriverReinitTailEntry;
|
2003-12-15 17:50:23 +00:00
|
|
|
|
|
2006-07-09 02:34:32 +00:00
|
|
|
|
PLIST_ENTRY DriverBootReinitTailEntry;
|
|
|
|
|
LIST_ENTRY DriverBootReinitListHead;
|
|
|
|
|
KSPIN_LOCK DriverBootReinitListLock;
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2006-07-09 02:34:32 +00:00
|
|
|
|
UNICODE_STRING IopHardwareDatabaseKey =
|
2005-06-25 14:04:56 +00:00
|
|
|
|
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
|
2004-11-07 21:20:51 +00:00
|
|
|
|
|
2005-11-22 02:30:18 +00:00
|
|
|
|
POBJECT_TYPE IoDriverObjectType = NULL;
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2009-08-24 18:19:53 +00:00
|
|
|
|
#define TAG_RTLREGISTRY 'vrqR'
|
2008-08-31 15:29:21 +00:00
|
|
|
|
|
2006-10-01 18:27:59 +00:00
|
|
|
|
extern BOOLEAN ExpInTextModeSetup;
|
2012-02-02 18:08:28 +00:00
|
|
|
|
extern BOOLEAN PnpSystemInit;
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
USHORT IopGroupIndex;
|
|
|
|
|
PLIST_ENTRY IopGroupTable;
|
|
|
|
|
|
2004-03-28 09:48:13 +00:00
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
2003-10-06 18:49:50 +00:00
|
|
|
|
|
2008-11-29 20:47:48 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2004-03-28 09:48:13 +00:00
|
|
|
|
IopInvalidDeviceRequest(
|
2004-03-27 19:41:32 +00:00
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
|
PIRP Irp)
|
|
|
|
|
{
|
2004-09-07 11:48:16 +00:00
|
|
|
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2004-09-07 11:48:16 +00:00
|
|
|
|
return STATUS_INVALID_DEVICE_REQUEST;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
VOID
|
|
|
|
|
NTAPI
|
|
|
|
|
IopDeleteDriver(IN PVOID ObjectBody)
|
2004-03-28 09:48:13 +00:00
|
|
|
|
{
|
2006-07-09 00:01:31 +00:00
|
|
|
|
PDRIVER_OBJECT DriverObject = ObjectBody;
|
|
|
|
|
PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
|
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
|
|
/* Get the extension and loop them */
|
|
|
|
|
DriverExtension = IoGetDrvObjExtension(DriverObject)->
|
|
|
|
|
ClientDriverExtension;
|
|
|
|
|
while (DriverExtension)
|
|
|
|
|
{
|
|
|
|
|
/* Get the next one */
|
|
|
|
|
NextDriverExtension = DriverExtension->NextExtension;
|
|
|
|
|
ExFreePoolWithTag(DriverExtension, TAG_DRIVER_EXTENSION);
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Move on */
|
|
|
|
|
DriverExtension = NextDriverExtension;
|
|
|
|
|
}
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Check if the driver image is still loaded */
|
|
|
|
|
if (DriverObject->DriverSection)
|
|
|
|
|
{
|
|
|
|
|
/* Unload it */
|
2009-04-25 09:07:10 +00:00
|
|
|
|
MmUnloadSystemImage(DriverObject->DriverSection);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
}
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Check if it has a name */
|
|
|
|
|
if (DriverObject->DriverName.Buffer)
|
|
|
|
|
{
|
|
|
|
|
/* Free it */
|
|
|
|
|
ExFreePool(DriverObject->DriverName.Buffer);
|
|
|
|
|
}
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2007-05-25 17:10:11 +00:00
|
|
|
|
#if 0 /* See a bit of hack in IopCreateDriver */
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Check if it has a service key name */
|
|
|
|
|
if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
|
|
|
|
|
{
|
|
|
|
|
/* Free it */
|
2007-05-25 13:52:58 +00:00
|
|
|
|
ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
}
|
2007-05-25 17:10:11 +00:00
|
|
|
|
#endif
|
2004-03-28 09:48:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-19 22:02:34 +00:00
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
|
IopGetDriverObject(
|
|
|
|
|
PDRIVER_OBJECT *DriverObject,
|
|
|
|
|
PUNICODE_STRING ServiceName,
|
|
|
|
|
BOOLEAN FileSystem)
|
|
|
|
|
{
|
|
|
|
|
PDRIVER_OBJECT Object;
|
|
|
|
|
WCHAR NameBuffer[MAX_PATH];
|
|
|
|
|
UNICODE_STRING DriverName;
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
2007-06-09 20:16:29 +00:00
|
|
|
|
DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
|
2005-05-19 22:02:34 +00:00
|
|
|
|
DriverObject, ServiceName, FileSystem);
|
|
|
|
|
|
|
|
|
|
*DriverObject = NULL;
|
|
|
|
|
|
|
|
|
|
/* Create ModuleName string */
|
|
|
|
|
if (ServiceName == NULL || ServiceName->Buffer == NULL)
|
|
|
|
|
/* We don't know which DriverObject we have to open */
|
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
2005-07-22 22:40:54 +00:00
|
|
|
|
DriverName.Buffer = NameBuffer;
|
|
|
|
|
DriverName.Length = 0;
|
|
|
|
|
DriverName.MaximumLength = sizeof(NameBuffer);
|
|
|
|
|
|
2005-05-19 22:02:34 +00:00
|
|
|
|
if (FileSystem == TRUE)
|
2005-07-22 22:40:54 +00:00
|
|
|
|
RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME);
|
2005-05-19 22:02:34 +00:00
|
|
|
|
else
|
2005-07-22 22:40:54 +00:00
|
|
|
|
RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME);
|
|
|
|
|
RtlAppendUnicodeStringToString(&DriverName, ServiceName);
|
2005-05-19 22:02:34 +00:00
|
|
|
|
|
|
|
|
|
DPRINT("Driver name: '%wZ'\n", &DriverName);
|
|
|
|
|
|
|
|
|
|
/* Open driver object */
|
|
|
|
|
Status = ObReferenceObjectByName(
|
|
|
|
|
&DriverName,
|
2007-06-11 22:02:55 +00:00
|
|
|
|
OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */
|
2005-05-19 22:02:34 +00:00
|
|
|
|
NULL, /* PassedAccessState */
|
|
|
|
|
0, /* DesiredAccess */
|
|
|
|
|
IoDriverObjectType,
|
|
|
|
|
KernelMode,
|
|
|
|
|
NULL, /* ParseContext */
|
|
|
|
|
(PVOID*)&Object);
|
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
2007-06-11 22:02:55 +00:00
|
|
|
|
{
|
2007-06-12 08:38:32 +00:00
|
|
|
|
DPRINT("Failed to reference driver object, status=0x%08x\n", Status);
|
2005-05-19 22:02:34 +00:00
|
|
|
|
return Status;
|
2007-06-11 22:02:55 +00:00
|
|
|
|
}
|
2005-05-19 22:02:34 +00:00
|
|
|
|
|
|
|
|
|
*DriverObject = Object;
|
|
|
|
|
|
2007-06-11 22:02:55 +00:00
|
|
|
|
DPRINT("Driver Object: %p\n", Object);
|
|
|
|
|
|
2005-05-19 22:02:34 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-14 19:21:38 +00:00
|
|
|
|
/*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* TRUE if String2 contains String1 as a suffix.
|
|
|
|
|
*/
|
|
|
|
|
BOOLEAN
|
|
|
|
|
NTAPI
|
|
|
|
|
IopSuffixUnicodeString(
|
|
|
|
|
IN PCUNICODE_STRING String1,
|
|
|
|
|
IN PCUNICODE_STRING String2)
|
|
|
|
|
{
|
|
|
|
|
PWCHAR pc1;
|
|
|
|
|
PWCHAR pc2;
|
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
|
|
if (String2->Length < String1->Length)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
Length = String1->Length / 2;
|
|
|
|
|
pc1 = String1->Buffer;
|
|
|
|
|
pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
|
|
|
|
|
|
|
|
|
|
if (pc1 && pc2)
|
|
|
|
|
{
|
|
|
|
|
while (Length--)
|
|
|
|
|
{
|
|
|
|
|
if( *pc1++ != *pc2++ )
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
/*
|
|
|
|
|
* IopDisplayLoadingMessage
|
|
|
|
|
*
|
|
|
|
|
* Display 'Loading XXX...' message.
|
|
|
|
|
*/
|
|
|
|
|
|
2010-12-21 21:48:29 +00:00
|
|
|
|
VOID
|
2005-05-18 19:08:00 +00:00
|
|
|
|
FASTCALL
|
|
|
|
|
INIT_FUNCTION
|
2010-03-13 23:19:05 +00:00
|
|
|
|
IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
|
2004-03-27 19:41:32 +00:00
|
|
|
|
{
|
2005-05-18 19:08:00 +00:00
|
|
|
|
CHAR TextBuffer[256];
|
2010-03-14 19:21:38 +00:00
|
|
|
|
UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
|
2007-01-25 17:51:45 +00:00
|
|
|
|
|
2007-01-25 01:13:09 +00:00
|
|
|
|
if (ExpInTextModeSetup) return;
|
2010-04-03 07:44:38 +00:00
|
|
|
|
if (!KeLoaderBlock) return;
|
2010-03-13 23:19:05 +00:00
|
|
|
|
RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE);
|
|
|
|
|
snprintf(TextBuffer, sizeof(TextBuffer),
|
2010-03-14 19:21:38 +00:00
|
|
|
|
"%s%sSystem32\\Drivers\\%wZ%s\n",
|
2010-03-13 23:19:05 +00:00
|
|
|
|
KeLoaderBlock->ArcBootDeviceName,
|
|
|
|
|
KeLoaderBlock->NtBootPathName,
|
2010-03-14 19:21:38 +00:00
|
|
|
|
ServiceName,
|
|
|
|
|
IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
|
2005-05-18 19:08:00 +00:00
|
|
|
|
HalDisplayString(TextBuffer);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopNormalizeImagePath
|
|
|
|
|
*
|
|
|
|
|
* Normalize an image path to contain complete path.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* ImagePath
|
|
|
|
|
* The input path and on exit the result path. ImagePath.Buffer
|
|
|
|
|
* must be allocated by ExAllocatePool on input. Caller is responsible
|
|
|
|
|
* for freeing the buffer when it's no longer needed.
|
|
|
|
|
*
|
|
|
|
|
* ServiceName
|
|
|
|
|
* Name of the service that ImagePath belongs to.
|
|
|
|
|
*
|
|
|
|
|
* Return Value
|
|
|
|
|
* Status
|
|
|
|
|
*
|
|
|
|
|
* Remarks
|
|
|
|
|
* The input image path isn't freed on error.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
|
IopNormalizeImagePath(
|
|
|
|
|
IN OUT PUNICODE_STRING ImagePath,
|
|
|
|
|
IN PUNICODE_STRING ServiceName)
|
|
|
|
|
{
|
|
|
|
|
UNICODE_STRING InputImagePath;
|
|
|
|
|
|
2011-10-01 04:56:14 +00:00
|
|
|
|
DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
RtlCopyMemory(
|
|
|
|
|
&InputImagePath,
|
|
|
|
|
ImagePath,
|
|
|
|
|
sizeof(UNICODE_STRING));
|
|
|
|
|
|
|
|
|
|
if (InputImagePath.Length == 0)
|
|
|
|
|
{
|
2008-01-02 16:06:03 +00:00
|
|
|
|
ImagePath->Length = 0;
|
|
|
|
|
ImagePath->MaximumLength =
|
|
|
|
|
(33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
|
|
|
|
|
if (ImagePath->Buffer == NULL)
|
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
|
2008-01-02 16:06:03 +00:00
|
|
|
|
RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\");
|
|
|
|
|
RtlAppendUnicodeStringToString(ImagePath, ServiceName);
|
|
|
|
|
RtlAppendUnicodeToString(ImagePath, L".sys");
|
2004-03-27 19:41:32 +00:00
|
|
|
|
} else
|
|
|
|
|
if (InputImagePath.Buffer[0] != L'\\')
|
|
|
|
|
{
|
2008-01-02 16:06:03 +00:00
|
|
|
|
ImagePath->Length = 0;
|
|
|
|
|
ImagePath->MaximumLength =
|
|
|
|
|
12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
|
|
|
|
|
if (ImagePath->Buffer == NULL)
|
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
|
2008-01-02 16:06:03 +00:00
|
|
|
|
RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\");
|
|
|
|
|
RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
|
|
|
|
|
|
|
|
|
|
/* Free caller's string */
|
2008-08-31 15:29:21 +00:00
|
|
|
|
ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
}
|
2011-10-01 04:56:14 +00:00
|
|
|
|
|
|
|
|
|
DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopLoadServiceModule
|
|
|
|
|
*
|
|
|
|
|
* Load a module specified by registry settings for service.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* ServiceName
|
|
|
|
|
* Name of the service to load.
|
|
|
|
|
*
|
|
|
|
|
* Return Value
|
|
|
|
|
* Status
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
|
IopLoadServiceModule(
|
|
|
|
|
IN PUNICODE_STRING ServiceName,
|
2005-07-30 16:25:35 +00:00
|
|
|
|
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
|
2004-03-27 19:41:32 +00:00
|
|
|
|
{
|
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
|
|
|
|
ULONG ServiceStart;
|
2007-12-19 17:46:58 +00:00
|
|
|
|
UNICODE_STRING ServiceImagePath, CCSName;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
NTSTATUS Status;
|
2007-12-19 17:46:58 +00:00
|
|
|
|
HANDLE CCSKey, ServiceKey;
|
2008-09-02 08:26:05 +00:00
|
|
|
|
PVOID BaseAddress;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2005-07-04 22:11:00 +00:00
|
|
|
|
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
|
2004-03-28 12:03:25 +00:00
|
|
|
|
|
2006-11-19 17:22:18 +00:00
|
|
|
|
/* FIXME: This check may be removed once the bug is fixed */
|
|
|
|
|
if (ServiceName->Buffer == NULL)
|
2008-02-27 20:54:27 +00:00
|
|
|
|
{
|
|
|
|
|
DPRINT1("If you see this, please report to Fireball or hpoussin!\n");
|
2006-11-19 17:22:18 +00:00
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2008-02-27 20:54:27 +00:00
|
|
|
|
}
|
2006-11-19 17:22:18 +00:00
|
|
|
|
|
2011-05-27 21:56:55 +00:00
|
|
|
|
if (ExpInTextModeSetup)
|
2007-12-19 17:46:58 +00:00
|
|
|
|
{
|
2011-05-27 21:56:55 +00:00
|
|
|
|
/* We have no registry, but luckily we know where all the drivers are */
|
2007-12-19 17:46:58 +00:00
|
|
|
|
|
2011-05-27 21:56:55 +00:00
|
|
|
|
/* ServiceStart < 4 is all that matters */
|
|
|
|
|
ServiceStart = 0;
|
|
|
|
|
|
|
|
|
|
/* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
|
|
|
|
|
ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0;
|
|
|
|
|
ServiceImagePath.Buffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
2007-12-19 17:46:58 +00:00
|
|
|
|
{
|
2011-05-27 21:56:55 +00:00
|
|
|
|
/* Open CurrentControlSet */
|
|
|
|
|
RtlInitUnicodeString(&CCSName,
|
|
|
|
|
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
|
|
|
|
|
Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Open service key */
|
|
|
|
|
Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
ZwClose(CCSKey);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get information about the service.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
|
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&ServiceImagePath, NULL);
|
|
|
|
|
|
|
|
|
|
QueryTable[0].Name = L"Start";
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
|
QueryTable[0].EntryContext = &ServiceStart;
|
|
|
|
|
|
|
|
|
|
QueryTable[1].Name = L"ImagePath";
|
|
|
|
|
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
|
QueryTable[1].EntryContext = &ServiceImagePath;
|
|
|
|
|
|
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
|
|
|
|
|
(PWSTR)ServiceKey, QueryTable, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
ZwClose(ServiceKey);
|
2007-12-19 17:46:58 +00:00
|
|
|
|
ZwClose(CCSKey);
|
2011-05-27 21:56:55 +00:00
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
2007-12-19 17:46:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
/*
|
2011-05-27 21:56:55 +00:00
|
|
|
|
* Normalize the image path for all later processing.
|
2004-03-27 19:41:32 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2011-05-27 21:56:55 +00:00
|
|
|
|
Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2011-05-27 21:56:55 +00:00
|
|
|
|
DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2011-05-27 21:56:55 +00:00
|
|
|
|
* Case for disabled drivers
|
2004-03-27 19:41:32 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2011-05-27 21:56:55 +00:00
|
|
|
|
if (ServiceStart >= 4)
|
2004-03-27 19:41:32 +00:00
|
|
|
|
{
|
2011-05-27 21:56:55 +00:00
|
|
|
|
/* FIXME: Check if it is the right status code */
|
|
|
|
|
Status = STATUS_PLUGPLAY_NO_DEVICE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-10-01 04:56:14 +00:00
|
|
|
|
DPRINT("Loading module from %wZ\n", &ServiceImagePath);
|
2011-05-27 21:56:55 +00:00
|
|
|
|
Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
|
2011-08-13 14:28:45 +00:00
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
IopDisplayLoadingMessage(ServiceName);
|
|
|
|
|
}
|
2004-03-27 19:41:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-05 20:19:01 +00:00
|
|
|
|
ExFreePool(ServiceImagePath.Buffer);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Now check if the module was loaded successfully.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT("Module loading failed (Status %x)\n", Status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DPRINT("Module loading (Status %x)\n", Status);
|
|
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopInitializeDriverModule
|
|
|
|
|
*
|
|
|
|
|
* Initalize a loaded driver.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* DeviceNode
|
|
|
|
|
* Pointer to device node.
|
|
|
|
|
*
|
|
|
|
|
* ModuleObject
|
|
|
|
|
* Module object representing the driver. It can be retrieve by
|
|
|
|
|
* IopLoadServiceModule.
|
|
|
|
|
*
|
2005-04-11 17:28:14 +00:00
|
|
|
|
* ServiceName
|
|
|
|
|
* Name of the service (as in registry).
|
|
|
|
|
*
|
2004-03-27 19:41:32 +00:00
|
|
|
|
* FileSystemDriver
|
|
|
|
|
* Set to TRUE for file system drivers.
|
|
|
|
|
*
|
|
|
|
|
* DriverObject
|
|
|
|
|
* On successful return this contains the driver object representing
|
|
|
|
|
* the loaded driver.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
|
IopInitializeDriverModule(
|
|
|
|
|
IN PDEVICE_NODE DeviceNode,
|
2005-07-30 16:25:35 +00:00
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY ModuleObject,
|
2005-04-11 17:28:14 +00:00
|
|
|
|
IN PUNICODE_STRING ServiceName,
|
2004-03-27 19:41:32 +00:00
|
|
|
|
IN BOOLEAN FileSystemDriver,
|
|
|
|
|
OUT PDRIVER_OBJECT *DriverObject)
|
|
|
|
|
{
|
2005-05-06 00:07:05 +00:00
|
|
|
|
const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
|
2007-03-09 18:14:34 +00:00
|
|
|
|
WCHAR NameBuffer[MAX_PATH];
|
|
|
|
|
UNICODE_STRING DriverName;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
UNICODE_STRING RegistryKey;
|
2005-05-06 00:07:05 +00:00
|
|
|
|
PDRIVER_INITIALIZE DriverEntry;
|
2006-07-27 19:56:38 +00:00
|
|
|
|
PDRIVER_OBJECT Driver;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
NTSTATUS Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2005-05-06 00:07:05 +00:00
|
|
|
|
DriverEntry = ModuleObject->EntryPoint;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2005-05-06 00:07:05 +00:00
|
|
|
|
if (ServiceName != NULL && ServiceName->Length != 0)
|
|
|
|
|
{
|
|
|
|
|
RegistryKey.Length = 0;
|
|
|
|
|
RegistryKey.MaximumLength = sizeof(ServicesKeyName) + ServiceName->Length;
|
|
|
|
|
RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength);
|
|
|
|
|
if (RegistryKey.Buffer == NULL)
|
|
|
|
|
{
|
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
}
|
|
|
|
|
RtlAppendUnicodeToString(&RegistryKey, ServicesKeyName);
|
|
|
|
|
RtlAppendUnicodeStringToString(&RegistryKey, ServiceName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
RtlInitUnicodeString(&RegistryKey, NULL);
|
|
|
|
|
}
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2007-03-09 18:14:34 +00:00
|
|
|
|
/* Create ModuleName string */
|
|
|
|
|
if (ServiceName && ServiceName->Length > 0)
|
|
|
|
|
{
|
|
|
|
|
if (FileSystemDriver == TRUE)
|
|
|
|
|
wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
|
|
|
|
|
else
|
|
|
|
|
wcscpy(NameBuffer, DRIVER_ROOT_NAME);
|
|
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&DriverName, NameBuffer);
|
2007-12-19 17:46:58 +00:00
|
|
|
|
DriverName.MaximumLength = sizeof(NameBuffer);
|
|
|
|
|
|
|
|
|
|
RtlAppendUnicodeStringToString(&DriverName, ServiceName);
|
|
|
|
|
|
2007-03-09 18:14:34 +00:00
|
|
|
|
DPRINT("Driver name: '%wZ'\n", &DriverName);
|
|
|
|
|
}
|
|
|
|
|
else
|
2007-06-10 16:15:16 +00:00
|
|
|
|
DriverName.Length = 0;
|
|
|
|
|
|
|
|
|
|
Status = IopCreateDriver(
|
|
|
|
|
DriverName.Length > 0 ? &DriverName : NULL,
|
|
|
|
|
DriverEntry,
|
|
|
|
|
&RegistryKey,
|
2010-09-10 21:25:53 +00:00
|
|
|
|
ModuleObject,
|
2007-06-10 16:15:16 +00:00
|
|
|
|
&Driver);
|
2007-06-09 20:16:29 +00:00
|
|
|
|
RtlFreeUnicodeString(&RegistryKey);
|
2007-03-09 18:14:34 +00:00
|
|
|
|
|
2006-07-27 19:56:38 +00:00
|
|
|
|
*DriverObject = Driver;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-06-10 16:15:16 +00:00
|
|
|
|
DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-27 19:56:38 +00:00
|
|
|
|
/* Set the driver as initialized */
|
2010-04-11 16:10:49 +00:00
|
|
|
|
IopReadyDeviceObjects(Driver);
|
2006-07-27 19:56:38 +00:00
|
|
|
|
|
2012-02-02 18:08:28 +00:00
|
|
|
|
if (PnpSystemInit) IopReinitializeDrivers();
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopAttachFilterDriversCallback
|
|
|
|
|
*
|
|
|
|
|
* Internal routine used by IopAttachFilterDrivers.
|
|
|
|
|
*/
|
|
|
|
|
|
2008-11-29 20:47:48 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2004-03-27 19:41:32 +00:00
|
|
|
|
IopAttachFilterDriversCallback(
|
|
|
|
|
PWSTR ValueName,
|
|
|
|
|
ULONG ValueType,
|
|
|
|
|
PVOID ValueData,
|
|
|
|
|
ULONG ValueLength,
|
|
|
|
|
PVOID Context,
|
|
|
|
|
PVOID EntryContext)
|
|
|
|
|
{
|
|
|
|
|
PDEVICE_NODE DeviceNode = Context;
|
|
|
|
|
UNICODE_STRING ServiceName;
|
|
|
|
|
PWCHAR Filters;
|
2005-07-30 16:25:35 +00:00
|
|
|
|
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
|
|
|
|
NTSTATUS Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
for (Filters = ValueData;
|
|
|
|
|
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
|
|
|
|
|
*Filters != 0;
|
|
|
|
|
Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
|
|
|
|
|
{
|
|
|
|
|
DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
|
|
|
|
|
ServiceName.Buffer = Filters;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
ServiceName.MaximumLength =
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
|
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
/* Load and initialize the filter driver */
|
|
|
|
|
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
|
2005-04-11 22:29:31 +00:00
|
|
|
|
if (Status != STATUS_IMAGE_ALREADY_LOADED)
|
|
|
|
|
{
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
continue;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2005-04-11 22:29:31 +00:00
|
|
|
|
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
|
|
|
|
|
FALSE, &DriverObject);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* get existing DriverObject pointer */
|
2005-05-19 22:02:34 +00:00
|
|
|
|
Status = IopGetDriverObject(
|
2005-04-11 22:29:31 +00:00
|
|
|
|
&DriverObject,
|
|
|
|
|
&ServiceName,
|
2005-05-19 22:02:34 +00:00
|
|
|
|
FALSE);
|
2005-04-11 22:29:31 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
2007-06-11 22:02:55 +00:00
|
|
|
|
{
|
|
|
|
|
DPRINT1("IopGetDriverObject() returned status 0x%08x!\n", Status);
|
2005-04-11 22:29:31 +00:00
|
|
|
|
continue;
|
2007-06-11 22:02:55 +00:00
|
|
|
|
}
|
2005-04-11 22:29:31 +00:00
|
|
|
|
}
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopAttachFilterDrivers
|
|
|
|
|
*
|
|
|
|
|
* Load filter drivers for specified device node.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* Lower
|
|
|
|
|
* Set to TRUE for loading lower level filters or FALSE for upper
|
|
|
|
|
* level filters.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
|
IopAttachFilterDrivers(
|
|
|
|
|
PDEVICE_NODE DeviceNode,
|
|
|
|
|
BOOLEAN Lower)
|
|
|
|
|
{
|
2008-12-03 17:28:59 +00:00
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
|
2004-03-27 19:41:32 +00:00
|
|
|
|
UNICODE_STRING Class;
|
|
|
|
|
WCHAR ClassBuffer[40];
|
2008-01-01 20:44:09 +00:00
|
|
|
|
UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
|
|
|
|
|
HANDLE EnumRootKey, SubKey;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
2008-01-01 20:44:09 +00:00
|
|
|
|
/* Open enumeration root key */
|
2008-01-02 13:33:40 +00:00
|
|
|
|
Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL,
|
|
|
|
|
&EnumRoot, KEY_READ);
|
2008-01-01 20:44:09 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Open subkey */
|
2008-01-02 13:33:40 +00:00
|
|
|
|
Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey,
|
|
|
|
|
&DeviceNode->InstancePath, KEY_READ);
|
2008-01-01 20:44:09 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
ZwClose(EnumRootKey);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
/*
|
|
|
|
|
* First load the device filters
|
|
|
|
|
*/
|
|
|
|
|
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
|
|
|
|
|
if (Lower)
|
|
|
|
|
QueryTable[0].Name = L"LowerFilters";
|
|
|
|
|
else
|
|
|
|
|
QueryTable[0].Name = L"UpperFilters";
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
|
|
|
|
|
|
|
|
|
RtlQueryRegistryValues(
|
2008-01-01 20:44:09 +00:00
|
|
|
|
RTL_REGISTRY_HANDLE,
|
|
|
|
|
(PWSTR)SubKey,
|
2004-03-27 19:41:32 +00:00
|
|
|
|
QueryTable,
|
|
|
|
|
DeviceNode,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Now get the class GUID
|
|
|
|
|
*/
|
|
|
|
|
Class.Length = 0;
|
|
|
|
|
Class.MaximumLength = 40 * sizeof(WCHAR);
|
|
|
|
|
Class.Buffer = ClassBuffer;
|
|
|
|
|
QueryTable[0].QueryRoutine = NULL;
|
|
|
|
|
QueryTable[0].Name = L"ClassGUID";
|
|
|
|
|
QueryTable[0].EntryContext = &Class;
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
|
|
|
|
|
|
Status = RtlQueryRegistryValues(
|
2008-01-01 20:44:09 +00:00
|
|
|
|
RTL_REGISTRY_HANDLE,
|
|
|
|
|
(PWSTR)SubKey,
|
2004-03-27 19:41:32 +00:00
|
|
|
|
QueryTable,
|
|
|
|
|
DeviceNode,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2008-01-01 20:44:09 +00:00
|
|
|
|
/* Close handles */
|
|
|
|
|
ZwClose(SubKey);
|
|
|
|
|
ZwClose(EnumRootKey);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Load the class filter driver
|
|
|
|
|
*/
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
|
{
|
2008-01-01 20:44:09 +00:00
|
|
|
|
UNICODE_STRING ControlClass = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
|
|
|
|
|
|
2008-01-02 13:33:40 +00:00
|
|
|
|
Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL,
|
|
|
|
|
&ControlClass, KEY_READ);
|
2008-01-01 20:44:09 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Open subkey */
|
2008-01-02 13:33:40 +00:00
|
|
|
|
Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey,
|
|
|
|
|
&Class, KEY_READ);
|
2008-01-01 20:44:09 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
|
|
|
|
ZwClose(EnumRootKey);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
|
|
|
|
|
if (Lower)
|
|
|
|
|
QueryTable[0].Name = L"LowerFilters";
|
|
|
|
|
else
|
|
|
|
|
QueryTable[0].Name = L"UpperFilters";
|
|
|
|
|
QueryTable[0].EntryContext = NULL;
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
|
|
|
|
|
|
|
|
|
RtlQueryRegistryValues(
|
2008-01-01 20:44:09 +00:00
|
|
|
|
RTL_REGISTRY_HANDLE,
|
|
|
|
|
(PWSTR)SubKey,
|
2004-03-27 19:41:32 +00:00
|
|
|
|
QueryTable,
|
|
|
|
|
DeviceNode,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2008-01-01 20:44:09 +00:00
|
|
|
|
/* Clean up */
|
|
|
|
|
ZwClose(SubKey);
|
|
|
|
|
ZwClose(EnumRootKey);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
2003-10-06 18:49:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-02-22 18:02:53 +00:00
|
|
|
|
NTSTATUS
|
|
|
|
|
NTAPI
|
|
|
|
|
MiResolveImageReferences(IN PVOID ImageBase,
|
|
|
|
|
IN PUNICODE_STRING ImageFileDirectory,
|
|
|
|
|
IN PUNICODE_STRING NamePrefix OPTIONAL,
|
|
|
|
|
OUT PCHAR *MissingApi,
|
|
|
|
|
OUT PWCHAR *MissingDriver,
|
|
|
|
|
OUT PLOAD_IMPORTS *LoadImports);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Used for images already loaded (boot drivers)
|
|
|
|
|
//
|
|
|
|
|
NTSTATUS
|
|
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
|
INIT_FUNCTION
|
2007-02-22 18:02:53 +00:00
|
|
|
|
LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
|
|
|
|
|
PUNICODE_STRING FileName,
|
|
|
|
|
PLDR_DATA_TABLE_ENTRY *ModuleObject)
|
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
UNICODE_STRING BaseName, BaseDirectory;
|
|
|
|
|
PLOAD_IMPORTS LoadedImports = (PVOID)-2;
|
|
|
|
|
PCHAR MissingApiName, Buffer;
|
|
|
|
|
PWCHAR MissingDriverName;
|
|
|
|
|
PVOID DriverBase = LdrEntry->DllBase;
|
|
|
|
|
|
|
|
|
|
/* Allocate a buffer we'll use for names */
|
|
|
|
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);
|
|
|
|
|
if (!Buffer)
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check for a separator */
|
|
|
|
|
if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
|
|
|
|
|
{
|
|
|
|
|
PWCHAR p;
|
|
|
|
|
ULONG BaseLength;
|
|
|
|
|
|
|
|
|
|
/* Loop the path until we get to the base name */
|
|
|
|
|
p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
|
|
|
|
|
while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
|
|
|
|
|
|
|
|
|
|
/* Get the length */
|
|
|
|
|
BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
|
|
|
|
|
BaseLength *= sizeof(WCHAR);
|
|
|
|
|
|
|
|
|
|
/* Setup the string */
|
|
|
|
|
BaseName.Length = (USHORT)BaseLength;
|
|
|
|
|
BaseName.Buffer = p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Otherwise, we already have a base name */
|
|
|
|
|
BaseName.Length = FileName->Length;
|
|
|
|
|
BaseName.Buffer = FileName->Buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Setup the maximum length */
|
|
|
|
|
BaseName.MaximumLength = BaseName.Length;
|
|
|
|
|
|
|
|
|
|
/* Now compute the base directory */
|
|
|
|
|
BaseDirectory = *FileName;
|
|
|
|
|
BaseDirectory.Length -= BaseName.Length;
|
|
|
|
|
BaseDirectory.MaximumLength = BaseDirectory.Length;
|
|
|
|
|
|
|
|
|
|
/* Resolve imports */
|
|
|
|
|
MissingApiName = Buffer;
|
|
|
|
|
Status = MiResolveImageReferences(DriverBase,
|
|
|
|
|
&BaseDirectory,
|
|
|
|
|
NULL,
|
|
|
|
|
&MissingApiName,
|
|
|
|
|
&MissingDriverName,
|
|
|
|
|
&LoadedImports);
|
2007-02-28 19:04:27 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2007-02-22 18:02:53 +00:00
|
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
|
*ModuleObject = LdrEntry;
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
|
|
|
|
* IopInitializeBuiltinDriver
|
|
|
|
|
*
|
|
|
|
|
* Initialize a driver that is already loaded in memory.
|
|
|
|
|
*/
|
|
|
|
|
|
2007-02-22 18:02:53 +00:00
|
|
|
|
NTSTATUS
|
|
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
|
INIT_FUNCTION
|
2007-02-22 18:02:53 +00:00
|
|
|
|
IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
2003-10-15 17:04:39 +00:00
|
|
|
|
{
|
2007-02-22 18:02:53 +00:00
|
|
|
|
PDEVICE_NODE DeviceNode;
|
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PWCHAR FileNameWithoutPath;
|
|
|
|
|
LPWSTR FileExtension;
|
|
|
|
|
PUNICODE_STRING ModuleName = &LdrEntry->BaseDllName;
|
2007-03-22 17:13:14 +00:00
|
|
|
|
UNICODE_STRING ServiceName;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
|
|
|
|
/*
|
2005-05-18 19:08:00 +00:00
|
|
|
|
* Display 'Loading XXX...' message
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
2010-03-13 23:19:05 +00:00
|
|
|
|
IopDisplayLoadingMessage(ModuleName);
|
Patch for better boot logo/progress bar, fixed /SOS (debug) boot screen/output, removal of "funny" shutdown messages, addition of shutdown logo/screen, and misc:
[NTOS]: Add missing InbvIndicateProgress routine to update the progress bar while drivers are loading. Make boot and system driver initialization call it for each new driver. This updates the progress bar in the 25-75% range which was defined prior to IoInitSystem.
[NTOS]: Fix InbvUpdateProgressBar code to correctly handle the floor and ceiling.
[NTOS]: Remove shutdown "funny messages", do correct shutdown (should fix the ACPI shutdown issues) procedure. Display the shutdown screen on systems without ACPI (just like Windows does).
[NTOS]: Add a resource header with IDB_ definitions for all the embedded bitmaps, instead of using magic numbers and guessing which is which.
[NTOS]: Fix the boot logo initialization code as it was all wrong. 5 is the logo to be used during shutdown, for example, not the full logo background (which is supposed to be in 1, with a special palette that's faded in). Also handle server vs workstation scenarios.
[NTOS]: Booting in the new WinNT mode now correctly displays the blue background screen when in debug (/SOS) mode, and the header/footer also has the correct color, as does the separator band.
[DDK]: Add missing SUITE_TYPE definitions.
[NTOS]: Remove logo files that are simply not needed for ReactOS (Compute Cluster Edition, Tablet PC, etc...)
[NTOS]: Fix logo files (mostly) to have correct palettes. Note that 1.bmp is still quite different from Windows (no fade).
svn path=/trunk/; revision=45822
2010-03-04 06:26:11 +00:00
|
|
|
|
InbvIndicateProgress();
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
|
|
|
|
/*
|
2003-10-16 17:59:48 +00:00
|
|
|
|
* Generate filename without path (not needed by freeldr)
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
2006-10-01 05:05:57 +00:00
|
|
|
|
FileNameWithoutPath = wcsrchr(ModuleName->Buffer, L'\\');
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (FileNameWithoutPath == NULL)
|
2003-10-16 17:59:48 +00:00
|
|
|
|
{
|
2006-10-01 05:05:57 +00:00
|
|
|
|
FileNameWithoutPath = ModuleName->Buffer;
|
2003-10-16 17:59:48 +00:00
|
|
|
|
}
|
2007-01-01 14:50:16 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
FileNameWithoutPath++;
|
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
2003-10-16 17:59:48 +00:00
|
|
|
|
/*
|
|
|
|
|
* Strip the file extension from ServiceName
|
|
|
|
|
*/
|
2007-03-22 17:13:14 +00:00
|
|
|
|
RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
|
|
|
|
|
FileExtension = wcsrchr(ServiceName.Buffer, '.');
|
2003-10-16 17:59:48 +00:00
|
|
|
|
if (FileExtension != NULL)
|
|
|
|
|
{
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
|
ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
|
2003-10-16 17:59:48 +00:00
|
|
|
|
FileExtension[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-22 17:13:14 +00:00
|
|
|
|
/*
|
|
|
|
|
* Determine the right device object
|
|
|
|
|
*/
|
|
|
|
|
/* Use IopRootDeviceNode for now */
|
|
|
|
|
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2008-08-24 15:48:05 +00:00
|
|
|
|
DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
|
2007-03-22 17:13:14 +00:00
|
|
|
|
return(Status);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
|
|
|
|
* Initialize the driver
|
|
|
|
|
*/
|
2007-02-23 19:48:25 +00:00
|
|
|
|
Status = IopInitializeDriverModule(DeviceNode, LdrEntry,
|
2005-04-11 17:28:14 +00:00
|
|
|
|
&DeviceNode->ServiceName, FALSE, &DriverObject);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-03-22 17:13:14 +00:00
|
|
|
|
IopFreeDeviceNode(DeviceNode);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return Status;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
2005-05-16 18:08:55 +00:00
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
Status = IopStartDevice(DeviceNode);
|
|
|
|
|
}
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IopInitializeBootDrivers
|
|
|
|
|
*
|
|
|
|
|
* Initialize boot drivers and free memory for boot files.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* None
|
2005-05-09 01:38:29 +00:00
|
|
|
|
*
|
2003-10-15 17:04:39 +00:00
|
|
|
|
* Return Value
|
|
|
|
|
* None
|
|
|
|
|
*/
|
2006-10-01 05:05:57 +00:00
|
|
|
|
VOID
|
|
|
|
|
FASTCALL
|
2010-11-02 16:29:06 +00:00
|
|
|
|
INIT_FUNCTION
|
2003-10-15 17:04:39 +00:00
|
|
|
|
IopInitializeBootDrivers(VOID)
|
|
|
|
|
{
|
2010-04-02 17:57:33 +00:00
|
|
|
|
PLIST_ENTRY ListHead, NextEntry, NextEntry2;
|
2006-10-01 05:05:57 +00:00
|
|
|
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
2006-10-18 17:46:55 +00:00
|
|
|
|
PDEVICE_NODE DeviceNode;
|
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
|
|
|
|
LDR_DATA_TABLE_ENTRY ModuleObject;
|
|
|
|
|
NTSTATUS Status;
|
2007-05-28 21:34:49 +00:00
|
|
|
|
UNICODE_STRING DriverName;
|
2010-04-02 17:57:33 +00:00
|
|
|
|
ULONG i, Index;
|
|
|
|
|
PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
|
|
|
|
|
HANDLE KeyHandle;
|
|
|
|
|
PBOOT_DRIVER_LIST_ENTRY BootEntry;
|
2008-03-31 15:58:59 +00:00
|
|
|
|
DPRINT("IopInitializeBootDrivers()\n");
|
2007-06-11 22:02:55 +00:00
|
|
|
|
|
2006-10-18 17:46:55 +00:00
|
|
|
|
/* Use IopRootDeviceNode for now */
|
2007-03-22 17:13:14 +00:00
|
|
|
|
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode);
|
2006-10-18 17:46:55 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return;
|
|
|
|
|
|
|
|
|
|
/* Setup the module object for the RAW FS Driver */
|
|
|
|
|
ModuleObject.DllBase = NULL;
|
|
|
|
|
ModuleObject.SizeOfImage = 0;
|
|
|
|
|
ModuleObject.EntryPoint = RawFsDriverEntry;
|
2007-05-28 21:34:49 +00:00
|
|
|
|
RtlInitUnicodeString(&DriverName, L"RAW");
|
2006-10-18 17:46:55 +00:00
|
|
|
|
|
|
|
|
|
/* Initialize it */
|
|
|
|
|
Status = IopInitializeDriverModule(DeviceNode,
|
|
|
|
|
&ModuleObject,
|
2007-05-28 21:34:49 +00:00
|
|
|
|
&DriverName,
|
2006-10-18 17:46:55 +00:00
|
|
|
|
TRUE,
|
|
|
|
|
&DriverObject);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
IopFreeDeviceNode(DeviceNode);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now initialize the associated device */
|
|
|
|
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
IopFreeDeviceNode(DeviceNode);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Start it up */
|
|
|
|
|
Status = IopStartDevice(DeviceNode);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
IopFreeDeviceNode(DeviceNode);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Get highest group order index */
|
|
|
|
|
IopGroupIndex = PpInitGetGroupOrderIndex(NULL);
|
|
|
|
|
if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Allocate the group table */
|
|
|
|
|
IopGroupTable = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
|
IopGroupIndex * sizeof(LIST_ENTRY),
|
|
|
|
|
TAG_IO);
|
|
|
|
|
if (IopGroupTable == NULL) ASSERT(FALSE);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Initialize the group table lists */
|
|
|
|
|
for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2006-10-01 05:05:57 +00:00
|
|
|
|
/* Loop the boot modules */
|
|
|
|
|
ListHead = &KeLoaderBlock->LoadOrderListHead;
|
|
|
|
|
NextEntry = ListHead->Flink;
|
|
|
|
|
while (ListHead != NextEntry)
|
|
|
|
|
{
|
|
|
|
|
/* Get the entry */
|
|
|
|
|
LdrEntry = CONTAINING_RECORD(NextEntry,
|
|
|
|
|
LDR_DATA_TABLE_ENTRY,
|
|
|
|
|
InLoadOrderLinks);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Check if the DLL needs to be initialized */
|
|
|
|
|
if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
|
|
|
|
|
{
|
|
|
|
|
/* Call its entrypoint */
|
|
|
|
|
MmCallDllInitialize(LdrEntry, NULL);
|
|
|
|
|
}
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Go to the next driver */
|
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
|
}
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Loop the boot drivers */
|
|
|
|
|
ListHead = &KeLoaderBlock->BootDriverListHead;
|
|
|
|
|
NextEntry = ListHead->Flink;
|
|
|
|
|
while (ListHead != NextEntry)
|
|
|
|
|
{
|
|
|
|
|
/* Get the entry */
|
|
|
|
|
BootEntry = CONTAINING_RECORD(NextEntry,
|
|
|
|
|
BOOT_DRIVER_LIST_ENTRY,
|
|
|
|
|
Link);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Get the driver loader entry */
|
|
|
|
|
LdrEntry = BootEntry->LdrEntry;
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Allocate our internal accounting structure */
|
|
|
|
|
DriverInfo = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
|
sizeof(DRIVER_INFORMATION),
|
|
|
|
|
TAG_IO);
|
|
|
|
|
if (DriverInfo)
|
2006-10-01 05:05:57 +00:00
|
|
|
|
{
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Zero it and initialize it */
|
|
|
|
|
RtlZeroMemory(DriverInfo, sizeof(DRIVER_INFORMATION));
|
|
|
|
|
InitializeListHead(&DriverInfo->Link);
|
|
|
|
|
DriverInfo->DataTableEntry = BootEntry;
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Open the registry key */
|
|
|
|
|
Status = IopOpenRegistryKeyEx(&KeyHandle,
|
|
|
|
|
NULL,
|
|
|
|
|
&BootEntry->RegistryPath,
|
|
|
|
|
KEY_READ);
|
|
|
|
|
if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
|
2010-12-21 21:48:29 +00:00
|
|
|
|
((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
|
2006-10-01 05:05:57 +00:00
|
|
|
|
{
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Save the handle */
|
|
|
|
|
DriverInfo->ServiceHandle = KeyHandle;
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Get the group oder index */
|
|
|
|
|
Index = PpInitGetGroupOrderIndex(KeyHandle);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Get the tag position */
|
|
|
|
|
DriverInfo->TagPosition = PipGetDriverTagPriority(KeyHandle);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Insert it into the list, at the right place */
|
|
|
|
|
ASSERT(Index < IopGroupIndex);
|
|
|
|
|
NextEntry2 = IopGroupTable[Index].Flink;
|
|
|
|
|
while (NextEntry2 != &IopGroupTable[Index])
|
|
|
|
|
{
|
|
|
|
|
/* Get the driver info */
|
|
|
|
|
DriverInfoTag = CONTAINING_RECORD(NextEntry2,
|
|
|
|
|
DRIVER_INFORMATION,
|
|
|
|
|
Link);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Check if we found the right tag position */
|
|
|
|
|
if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
|
|
|
|
|
{
|
|
|
|
|
/* We're done */
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Next entry */
|
|
|
|
|
NextEntry2 = NextEntry2->Flink;
|
|
|
|
|
}
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Insert us right before the next entry */
|
|
|
|
|
NextEntry2 = NextEntry2->Blink;
|
|
|
|
|
InsertHeadList(NextEntry2, &DriverInfo->Link);
|
2006-10-01 05:05:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-01-05 19:06:05 +00:00
|
|
|
|
|
2006-10-01 05:05:57 +00:00
|
|
|
|
/* Go to the next driver */
|
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Loop each group index */
|
|
|
|
|
for (i = 0; i < IopGroupIndex; i++)
|
|
|
|
|
{
|
|
|
|
|
/* Loop each group table */
|
|
|
|
|
NextEntry = IopGroupTable[i].Flink;
|
|
|
|
|
while (NextEntry != &IopGroupTable[i])
|
|
|
|
|
{
|
|
|
|
|
/* Get the entry */
|
|
|
|
|
DriverInfo = CONTAINING_RECORD(NextEntry,
|
|
|
|
|
DRIVER_INFORMATION,
|
|
|
|
|
Link);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Get the driver loader entry */
|
|
|
|
|
LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Initialize it */
|
|
|
|
|
IopInitializeBuiltinDriver(LdrEntry);
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2010-04-02 17:57:33 +00:00
|
|
|
|
/* Next entry */
|
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-12-21 21:35:04 +00:00
|
|
|
|
|
2006-10-01 05:05:57 +00:00
|
|
|
|
/* In old ROS, the loader list became empty after this point. Simulate. */
|
|
|
|
|
InitializeListHead(&KeLoaderBlock->LoadOrderListHead);
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
VOID
|
|
|
|
|
FASTCALL
|
2010-11-02 16:29:06 +00:00
|
|
|
|
INIT_FUNCTION
|
2010-04-03 07:44:38 +00:00
|
|
|
|
IopInitializeSystemDrivers(VOID)
|
|
|
|
|
{
|
|
|
|
|
PUNICODE_STRING *DriverList, *SavedList;
|
2010-12-21 21:48:29 +00:00
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
/* No system drivers on the boot cd */
|
|
|
|
|
if (KeLoaderBlock->SetupLdrBlock) return;
|
2010-12-21 21:48:29 +00:00
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
/* Get the driver list */
|
|
|
|
|
SavedList = DriverList = CmGetSystemDriverList();
|
|
|
|
|
ASSERT(DriverList);
|
2010-12-21 21:48:29 +00:00
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
/* Loop it */
|
|
|
|
|
while (*DriverList)
|
|
|
|
|
{
|
|
|
|
|
/* Load the driver */
|
|
|
|
|
ZwLoadDriver(*DriverList);
|
2010-12-21 21:48:29 +00:00
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
/* Free the entry */
|
|
|
|
|
RtlFreeUnicodeString(*DriverList);
|
|
|
|
|
ExFreePool(*DriverList);
|
2010-12-21 21:48:29 +00:00
|
|
|
|
|
2010-04-03 07:44:38 +00:00
|
|
|
|
/* Next entry */
|
|
|
|
|
InbvIndicateProgress();
|
|
|
|
|
DriverList++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free the list */
|
|
|
|
|
ExFreePool(SavedList);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
|
|
|
|
* IopUnloadDriver
|
|
|
|
|
*
|
|
|
|
|
* Unloads a device driver.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* DriverServiceName
|
|
|
|
|
* Name of the service to unload (registry key).
|
2004-03-27 19:41:32 +00:00
|
|
|
|
*
|
2003-10-15 17:04:39 +00:00
|
|
|
|
* UnloadPnpDrivers
|
|
|
|
|
* Whether to unload Plug & Plug or only legacy drivers. If this
|
|
|
|
|
* parameter is set to FALSE, the routine will unload only legacy
|
|
|
|
|
* drivers.
|
2005-05-09 01:38:29 +00:00
|
|
|
|
*
|
2003-10-15 17:04:39 +00:00
|
|
|
|
* Return Value
|
|
|
|
|
* Status
|
|
|
|
|
*
|
|
|
|
|
* To do
|
|
|
|
|
* Guard the whole function by SEH.
|
|
|
|
|
*/
|
|
|
|
|
|
2008-11-29 20:47:48 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2003-10-15 17:04:39 +00:00
|
|
|
|
IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
|
|
|
|
|
{
|
2004-03-27 19:41:32 +00:00
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
2003-10-15 17:04:39 +00:00
|
|
|
|
UNICODE_STRING ImagePath;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
UNICODE_STRING ServiceName;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
UNICODE_STRING ObjectName;
|
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
2009-06-02 12:10:17 +00:00
|
|
|
|
PDEVICE_OBJECT DeviceObject;
|
|
|
|
|
PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
|
2007-10-03 11:54:31 +00:00
|
|
|
|
LOAD_UNLOAD_PARAMS LoadParams;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
LPWSTR Start;
|
2009-06-02 12:10:17 +00:00
|
|
|
|
BOOLEAN SafeToUnload = TRUE;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
|
|
|
|
DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers);
|
|
|
|
|
|
2005-07-29 15:08:20 +00:00
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
2004-03-27 19:41:32 +00:00
|
|
|
|
* Get the service name from the registry key name
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
Start = wcsrchr(DriverServiceName->Buffer, L'\\');
|
|
|
|
|
if (Start == NULL)
|
|
|
|
|
Start = DriverServiceName->Buffer;
|
|
|
|
|
else
|
|
|
|
|
Start++;
|
|
|
|
|
|
2004-03-27 19:41:32 +00:00
|
|
|
|
RtlInitUnicodeString(&ServiceName, Start);
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
|
|
|
|
* Construct the driver object name
|
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
|
ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
|
2003-10-23 19:16:33 +00:00
|
|
|
|
ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
|
2005-07-29 15:08:20 +00:00
|
|
|
|
ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
|
2009-09-02 13:02:30 +00:00
|
|
|
|
if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
wcscpy(ObjectName.Buffer, L"\\Driver\\");
|
2007-11-18 16:12:45 +00:00
|
|
|
|
memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
|
2003-10-23 19:16:33 +00:00
|
|
|
|
ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Find the driver object
|
|
|
|
|
*/
|
2008-10-11 17:39:12 +00:00
|
|
|
|
Status = ObReferenceObjectByName(&ObjectName,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
IoDriverObjectType,
|
|
|
|
|
KernelMode,
|
|
|
|
|
0,
|
|
|
|
|
(PVOID*)&DriverObject);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-12-19 09:52:12 +00:00
|
|
|
|
DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
|
2010-05-22 16:03:25 +00:00
|
|
|
|
ExFreePool(ObjectName.Buffer);
|
2003-10-15 17:04:39 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-22 16:03:25 +00:00
|
|
|
|
/*
|
|
|
|
|
* Free the buffer for driver object name
|
|
|
|
|
*/
|
|
|
|
|
ExFreePool(ObjectName.Buffer);
|
|
|
|
|
|
2009-06-02 12:10:17 +00:00
|
|
|
|
/* Check that driver is not already unloading */
|
|
|
|
|
if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("Driver deletion pending\n");
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
return STATUS_DELETE_PENDING;
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
/*
|
|
|
|
|
* Get path of service...
|
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
|
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&ImagePath, NULL);
|
|
|
|
|
|
|
|
|
|
QueryTable[0].Name = L"ImagePath";
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
|
QueryTable[0].EntryContext = &ImagePath;
|
|
|
|
|
|
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
|
|
|
|
DriverServiceName->Buffer, QueryTable, NULL, NULL);
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-11-18 16:12:45 +00:00
|
|
|
|
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
|
2009-06-02 12:10:17 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Normalize the image path for all later processing.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
|
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-11-18 16:12:45 +00:00
|
|
|
|
DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
|
2009-06-02 12:10:17 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
2003-10-15 17:04:39 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Free the service path
|
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2005-05-05 20:19:01 +00:00
|
|
|
|
ExFreePool(ImagePath.Buffer);
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Unload the module and release the references to the device object
|
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2007-10-03 11:54:31 +00:00
|
|
|
|
/* Call the load/unload routine, depending on current process */
|
2008-07-15 14:24:47 +00:00
|
|
|
|
if (DriverObject->DriverUnload && DriverObject->DriverSection)
|
2007-10-03 11:54:31 +00:00
|
|
|
|
{
|
2009-06-07 01:18:15 +00:00
|
|
|
|
/* Loop through each device object of the driver
|
|
|
|
|
and set DOE_UNLOAD_PENDING flag */
|
|
|
|
|
DeviceObject = DriverObject->DeviceObject;
|
|
|
|
|
while (DeviceObject)
|
|
|
|
|
{
|
|
|
|
|
/* Set the unload pending flag for the device */
|
|
|
|
|
DeviceExtension = IoGetDevObjExtension(DeviceObject);
|
|
|
|
|
DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
|
|
|
|
|
|
|
|
|
|
/* Make sure there are no attached devices or no reference counts */
|
|
|
|
|
if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
|
|
|
|
|
{
|
|
|
|
|
/* Not safe to unload */
|
|
|
|
|
DPRINT1("Drivers device object is referenced or has attached devices\n");
|
|
|
|
|
|
|
|
|
|
SafeToUnload = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeviceObject = DeviceObject->NextDevice;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If not safe to unload, then return success */
|
|
|
|
|
if (!SafeToUnload)
|
2009-06-11 12:37:16 +00:00
|
|
|
|
{
|
2009-06-07 01:18:15 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
return STATUS_SUCCESS;
|
2009-06-11 12:37:16 +00:00
|
|
|
|
}
|
2009-06-07 01:18:15 +00:00
|
|
|
|
|
2009-06-02 12:10:17 +00:00
|
|
|
|
/* Set the unload invoked flag */
|
|
|
|
|
DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
|
|
|
|
|
|
2007-10-03 11:54:31 +00:00
|
|
|
|
if (PsGetCurrentProcess() == PsInitialSystemProcess)
|
|
|
|
|
{
|
|
|
|
|
/* Just call right away */
|
|
|
|
|
(*DriverObject->DriverUnload)(DriverObject);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Load/Unload must be called from system process */
|
|
|
|
|
|
|
|
|
|
/* Prepare parameters block */
|
|
|
|
|
LoadParams.DriverObject = DriverObject;
|
|
|
|
|
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE);
|
|
|
|
|
|
|
|
|
|
ExInitializeWorkItem(&LoadParams.WorkItem,
|
|
|
|
|
(PWORKER_THREAD_ROUTINE)IopLoadUnloadDriver,
|
|
|
|
|
(PVOID)&LoadParams);
|
|
|
|
|
|
|
|
|
|
/* Queue it */
|
|
|
|
|
ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue);
|
|
|
|
|
|
|
|
|
|
/* And wait when it completes */
|
|
|
|
|
KeWaitForSingleObject(&LoadParams.Event, UserRequest, KernelMode,
|
|
|
|
|
FALSE, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-11 17:39:12 +00:00
|
|
|
|
/* Mark the driver object temporary, so it could be deleted later */
|
|
|
|
|
ObMakeTemporaryObject(DriverObject);
|
|
|
|
|
|
|
|
|
|
/* Dereference it 2 times */
|
2008-07-15 14:24:47 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
2008-10-11 17:39:12 +00:00
|
|
|
|
|
2008-07-15 14:24:47 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Dereference one time (refd inside this function) */
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
|
|
|
|
|
/* Return unloading failure */
|
|
|
|
|
return STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
VOID
|
|
|
|
|
NTAPI
|
2004-03-28 09:48:13 +00:00
|
|
|
|
IopReinitializeDrivers(VOID)
|
|
|
|
|
{
|
2006-07-09 02:21:13 +00:00
|
|
|
|
PDRIVER_REINIT_ITEM ReinitItem;
|
|
|
|
|
PLIST_ENTRY Entry;
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Get the first entry and start looping */
|
2004-03-28 09:48:13 +00:00
|
|
|
|
Entry = ExInterlockedRemoveHeadList(&DriverReinitListHead,
|
2006-07-09 02:21:13 +00:00
|
|
|
|
&DriverReinitListLock);
|
|
|
|
|
while (Entry)
|
|
|
|
|
{
|
|
|
|
|
/* Get the item*/
|
|
|
|
|
ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Increment reinitialization counter */
|
|
|
|
|
ReinitItem->DriverObject->DriverExtension->Count++;
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Remove the device object flag */
|
|
|
|
|
ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Call the routine */
|
|
|
|
|
ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
|
|
|
|
|
ReinitItem->Context,
|
|
|
|
|
ReinitItem->DriverObject->
|
|
|
|
|
DriverExtension->Count);
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Free the entry */
|
|
|
|
|
ExFreePool(Entry);
|
2004-03-28 09:48:13 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Move to the next one */
|
|
|
|
|
Entry = ExInterlockedRemoveHeadList(&DriverReinitListHead,
|
|
|
|
|
&DriverReinitListLock);
|
|
|
|
|
}
|
2004-03-28 09:48:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
VOID
|
|
|
|
|
NTAPI
|
2006-07-02 18:34:21 +00:00
|
|
|
|
IopReinitializeBootDrivers(VOID)
|
|
|
|
|
{
|
2006-07-09 02:21:13 +00:00
|
|
|
|
PDRIVER_REINIT_ITEM ReinitItem;
|
|
|
|
|
PLIST_ENTRY Entry;
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Get the first entry and start looping */
|
2006-07-02 18:34:21 +00:00
|
|
|
|
Entry = ExInterlockedRemoveHeadList(&DriverBootReinitListHead,
|
2006-07-09 02:21:13 +00:00
|
|
|
|
&DriverBootReinitListLock);
|
|
|
|
|
while (Entry)
|
|
|
|
|
{
|
|
|
|
|
/* Get the item*/
|
|
|
|
|
ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Increment reinitialization counter */
|
|
|
|
|
ReinitItem->DriverObject->DriverExtension->Count++;
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Remove the device object flag */
|
|
|
|
|
ReinitItem->DriverObject->Flags &= ~DRVO_BOOTREINIT_REGISTERED;
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Call the routine */
|
|
|
|
|
ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
|
|
|
|
|
ReinitItem->Context,
|
|
|
|
|
ReinitItem->DriverObject->
|
|
|
|
|
DriverExtension->Count);
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Free the entry */
|
|
|
|
|
ExFreePool(Entry);
|
2006-07-02 18:34:21 +00:00
|
|
|
|
|
2006-07-09 02:21:13 +00:00
|
|
|
|
/* Move to the next one */
|
|
|
|
|
Entry = ExInterlockedRemoveHeadList(&DriverBootReinitListHead,
|
|
|
|
|
&DriverBootReinitListLock);
|
|
|
|
|
}
|
2006-07-02 18:34:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-06-23 21:42:50 +00:00
|
|
|
|
NTSTATUS
|
2006-07-09 00:01:31 +00:00
|
|
|
|
NTAPI
|
2007-03-09 18:14:34 +00:00
|
|
|
|
IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
|
|
|
|
|
IN PDRIVER_INITIALIZE InitializationFunction,
|
2007-06-09 20:16:29 +00:00
|
|
|
|
IN PUNICODE_STRING RegistryPath,
|
2010-09-10 21:25:53 +00:00
|
|
|
|
PLDR_DATA_TABLE_ENTRY ModuleObject,
|
2007-03-09 18:14:34 +00:00
|
|
|
|
OUT PDRIVER_OBJECT *pDriverObject)
|
2004-06-23 21:42:50 +00:00
|
|
|
|
{
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
WCHAR NameBuffer[100];
|
|
|
|
|
USHORT NameLength;
|
2006-07-09 00:01:31 +00:00
|
|
|
|
UNICODE_STRING LocalDriverName;
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
|
ULONG ObjectSize;
|
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
|
|
|
|
UNICODE_STRING ServiceKeyName;
|
|
|
|
|
HANDLE hDriver;
|
2007-05-25 13:52:58 +00:00
|
|
|
|
ULONG i, RetryCount = 0;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2007-05-25 13:52:58 +00:00
|
|
|
|
try_again:
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* First, create a unique name for the driver if we don't have one */
|
2006-07-09 00:01:31 +00:00
|
|
|
|
if (!DriverName)
|
|
|
|
|
{
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Create a random name and set up the string*/
|
2007-08-05 11:27:39 +00:00
|
|
|
|
NameLength = (USHORT)swprintf(NameBuffer,
|
|
|
|
|
L"\\Driver\\%08u",
|
|
|
|
|
KeTickCount);
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
LocalDriverName.Length = NameLength * sizeof(WCHAR);
|
|
|
|
|
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
|
|
|
|
|
LocalDriverName.Buffer = NameBuffer;
|
2006-07-09 00:01:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* So we can avoid another code path, use a local var */
|
|
|
|
|
LocalDriverName = *DriverName;
|
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Initialize the Attributes */
|
2006-07-09 00:01:31 +00:00
|
|
|
|
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
|
&LocalDriverName,
|
|
|
|
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Create the Object */
|
|
|
|
|
Status = ObCreateObject(KernelMode,
|
|
|
|
|
IoDriverObjectType,
|
|
|
|
|
&ObjectAttributes,
|
|
|
|
|
KernelMode,
|
|
|
|
|
NULL,
|
|
|
|
|
ObjectSize,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
(PVOID*)&DriverObject);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2007-05-28 21:34:49 +00:00
|
|
|
|
DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
|
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Set up the Object */
|
|
|
|
|
RtlZeroMemory(DriverObject, ObjectSize);
|
2005-01-01 08:20:47 +00:00
|
|
|
|
DriverObject->Type = IO_TYPE_DRIVER;
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
DriverObject->Size = sizeof(DRIVER_OBJECT);
|
2009-06-03 09:48:33 +00:00
|
|
|
|
DriverObject->Flags = DRVO_LEGACY_DRIVER;//DRVO_BUILTIN_DRIVER;
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
|
|
|
|
|
DriverObject->DriverExtension->DriverObject = DriverObject;
|
|
|
|
|
DriverObject->DriverInit = InitializationFunction;
|
2010-09-10 21:25:53 +00:00
|
|
|
|
DriverObject->DriverSection = ModuleObject;
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Loop all Major Functions */
|
2005-04-17 16:26:44 +00:00
|
|
|
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
|
|
|
|
{
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Invalidate each function */
|
2005-04-17 16:26:44 +00:00
|
|
|
|
DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
|
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/* Set up the service key name buffer */
|
|
|
|
|
ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
|
LocalDriverName.Length +
|
|
|
|
|
sizeof(WCHAR),
|
|
|
|
|
TAG_IO);
|
|
|
|
|
if (!ServiceKeyName.Buffer)
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
ObMakeTemporaryObject(DriverObject);
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fill out the key data and copy the buffer */
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
ServiceKeyName.Length = LocalDriverName.Length;
|
|
|
|
|
ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength;
|
2006-10-22 09:06:58 +00:00
|
|
|
|
RtlCopyMemory(ServiceKeyName.Buffer,
|
2006-07-09 00:01:31 +00:00
|
|
|
|
LocalDriverName.Buffer,
|
|
|
|
|
LocalDriverName.Length);
|
|
|
|
|
|
|
|
|
|
/* Null-terminate it and set it */
|
|
|
|
|
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
2007-03-02 07:23:19 +00:00
|
|
|
|
DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Also store it in the Driver Object. This is a bit of a hack. */
|
2006-10-22 09:06:58 +00:00
|
|
|
|
RtlCopyMemory(&DriverObject->DriverName,
|
2006-07-09 00:01:31 +00:00
|
|
|
|
&ServiceKeyName,
|
|
|
|
|
sizeof(UNICODE_STRING));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Add the Object and get its handle */
|
|
|
|
|
Status = ObInsertObject(DriverObject,
|
|
|
|
|
NULL,
|
|
|
|
|
FILE_READ_DATA,
|
2008-07-10 11:29:50 +00:00
|
|
|
|
0,
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
NULL,
|
|
|
|
|
&hDriver);
|
2007-05-25 13:52:58 +00:00
|
|
|
|
|
|
|
|
|
/* Eliminate small possibility when this function is called more than
|
|
|
|
|
once in a row, and KeTickCount doesn't get enough time to change */
|
|
|
|
|
if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
|
|
|
|
|
{
|
|
|
|
|
RetryCount++;
|
|
|
|
|
goto try_again;
|
|
|
|
|
}
|
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Now reference it */
|
|
|
|
|
Status = ObReferenceObjectByHandle(hDriver,
|
|
|
|
|
0,
|
|
|
|
|
IoDriverObjectType,
|
|
|
|
|
KernelMode,
|
|
|
|
|
(PVOID*)&DriverObject,
|
|
|
|
|
NULL);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/* Fail */
|
|
|
|
|
ObMakeTemporaryObject(DriverObject);
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Close the extra handle */
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
ZwClose(hDriver);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2007-06-10 16:15:16 +00:00
|
|
|
|
DriverObject->HardwareDatabase = &IopHardwareDatabaseKey;
|
2010-09-10 21:25:53 +00:00
|
|
|
|
DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
|
|
|
|
|
DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
|
2007-06-10 16:15:16 +00:00
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Finally, call its init function */
|
2007-06-11 22:02:55 +00:00
|
|
|
|
DPRINT("RegistryKey: %wZ\n", RegistryPath);
|
2007-06-09 20:16:29 +00:00
|
|
|
|
DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
|
|
|
|
|
Status = (*InitializationFunction)(DriverObject, RegistryPath);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* If it didn't work, then kill the object */
|
2007-08-07 11:45:30 +00:00
|
|
|
|
DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
|
2010-09-10 21:25:53 +00:00
|
|
|
|
DriverObject->DriverSection = NULL;
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
ObMakeTemporaryObject(DriverObject);
|
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
}
|
2007-03-09 18:14:34 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Returns to caller the object */
|
|
|
|
|
*pDriverObject = DriverObject;
|
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2009-06-03 09:48:33 +00:00
|
|
|
|
/* Loop all Major Functions */
|
|
|
|
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
|
|
|
|
{
|
2009-10-20 16:47:01 +00:00
|
|
|
|
/*
|
|
|
|
|
* Make sure the driver didn't set any dispatch entry point to NULL!
|
|
|
|
|
* Doing so is illegal; drivers shouldn't touch entry points they
|
|
|
|
|
* do not implement.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Check if it did so anyway */
|
2010-05-22 16:12:59 +00:00
|
|
|
|
if (!DriverObject->MajorFunction[i])
|
2009-10-20 16:47:01 +00:00
|
|
|
|
{
|
2010-05-22 16:12:59 +00:00
|
|
|
|
/* Print a warning in the debug log */
|
|
|
|
|
DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%d] to NULL!\n",
|
|
|
|
|
&DriverObject->DriverName, i);
|
|
|
|
|
|
2009-10-20 16:47:01 +00:00
|
|
|
|
/* Fix it up */
|
2009-06-03 09:48:33 +00:00
|
|
|
|
DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
|
2009-10-20 16:47:01 +00:00
|
|
|
|
}
|
2009-06-03 09:48:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
/* Return the Status */
|
|
|
|
|
return Status;
|
2004-06-23 21:42:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-03-09 18:14:34 +00:00
|
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
NTSTATUS
|
|
|
|
|
NTAPI
|
|
|
|
|
IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
|
|
|
|
|
IN PDRIVER_INITIALIZE InitializationFunction)
|
|
|
|
|
{
|
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
2010-09-10 21:25:53 +00:00
|
|
|
|
return IopCreateDriver(DriverName, InitializationFunction, NULL, NULL, &DriverObject);
|
2007-03-09 18:14:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-06-23 21:42:50 +00:00
|
|
|
|
/*
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
* @implemented
|
2004-06-23 21:42:50 +00:00
|
|
|
|
*/
|
|
|
|
|
VOID
|
2006-07-09 00:01:31 +00:00
|
|
|
|
NTAPI
|
|
|
|
|
IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
|
2004-06-23 21:42:50 +00:00
|
|
|
|
{
|
2008-05-14 20:59:43 +00:00
|
|
|
|
/* Simply dereference the Object */
|
Implemented:
ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver
Thanks to Filip for reviewing some of these.
svn path=/trunk/; revision=12408
2004-12-30 18:30:05 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
2004-06-23 21:42:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-09 00:01:31 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
VOID
|
|
|
|
|
NTAPI
|
|
|
|
|
IoRegisterBootDriverReinitialization(IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PDRIVER_REINITIALIZE ReinitRoutine,
|
|
|
|
|
IN PVOID Context)
|
|
|
|
|
{
|
|
|
|
|
PDRIVER_REINIT_ITEM ReinitItem;
|
|
|
|
|
|
|
|
|
|
/* Allocate the entry */
|
|
|
|
|
ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
|
sizeof(DRIVER_REINIT_ITEM),
|
|
|
|
|
TAG_REINIT);
|
|
|
|
|
if (!ReinitItem) return;
|
|
|
|
|
|
|
|
|
|
/* Fill it out */
|
|
|
|
|
ReinitItem->DriverObject = DriverObject;
|
|
|
|
|
ReinitItem->ReinitRoutine = ReinitRoutine;
|
|
|
|
|
ReinitItem->Context = Context;
|
|
|
|
|
|
|
|
|
|
/* Set the Driver Object flag and insert the entry into the list */
|
|
|
|
|
DriverObject->Flags |= DRVO_BOOTREINIT_REGISTERED;
|
|
|
|
|
ExInterlockedInsertTailList(&DriverBootReinitListHead,
|
|
|
|
|
&ReinitItem->ItemEntry,
|
|
|
|
|
&DriverBootReinitListLock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
VOID
|
|
|
|
|
NTAPI
|
|
|
|
|
IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PDRIVER_REINITIALIZE ReinitRoutine,
|
|
|
|
|
IN PVOID Context)
|
|
|
|
|
{
|
|
|
|
|
PDRIVER_REINIT_ITEM ReinitItem;
|
|
|
|
|
|
|
|
|
|
/* Allocate the entry */
|
|
|
|
|
ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
|
sizeof(DRIVER_REINIT_ITEM),
|
|
|
|
|
TAG_REINIT);
|
|
|
|
|
if (!ReinitItem) return;
|
|
|
|
|
|
|
|
|
|
/* Fill it out */
|
|
|
|
|
ReinitItem->DriverObject = DriverObject;
|
|
|
|
|
ReinitItem->ReinitRoutine = ReinitRoutine;
|
|
|
|
|
ReinitItem->Context = Context;
|
|
|
|
|
|
|
|
|
|
/* Set the Driver Object flag and insert the entry into the list */
|
|
|
|
|
DriverObject->Flags |= DRVO_REINIT_REGISTERED;
|
|
|
|
|
ExInterlockedInsertTailList(&DriverReinitListHead,
|
|
|
|
|
&ReinitItem->ItemEntry,
|
|
|
|
|
&DriverReinitListLock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
NTSTATUS
|
|
|
|
|
NTAPI
|
|
|
|
|
IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PVOID ClientIdentificationAddress,
|
|
|
|
|
IN ULONG DriverObjectExtensionSize,
|
|
|
|
|
OUT PVOID *DriverObjectExtension)
|
|
|
|
|
{
|
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
|
|
|
|
|
BOOLEAN Inserted = FALSE;
|
|
|
|
|
|
|
|
|
|
/* Assume failure */
|
|
|
|
|
*DriverObjectExtension = NULL;
|
|
|
|
|
|
|
|
|
|
/* Allocate the extension */
|
|
|
|
|
NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
|
sizeof(IO_CLIENT_EXTENSION) +
|
|
|
|
|
DriverObjectExtensionSize,
|
|
|
|
|
TAG_DRIVER_EXTENSION);
|
|
|
|
|
if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
|
|
/* Clear the extension for teh caller */
|
|
|
|
|
RtlZeroMemory(NewDriverExtension,
|
|
|
|
|
sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
|
|
|
|
|
|
|
|
|
|
/* Acqure lock */
|
|
|
|
|
OldIrql = KeRaiseIrqlToDpcLevel();
|
|
|
|
|
|
|
|
|
|
/* Fill out the extension */
|
|
|
|
|
NewDriverExtension->ClientIdentificationAddress = ClientIdentificationAddress;
|
|
|
|
|
|
|
|
|
|
/* Loop the current extensions */
|
|
|
|
|
DriverExtensions = IoGetDrvObjExtension(DriverObject)->
|
|
|
|
|
ClientDriverExtension;
|
|
|
|
|
while (DriverExtensions)
|
|
|
|
|
{
|
|
|
|
|
/* Check if the identifier matches */
|
|
|
|
|
if (DriverExtensions->ClientIdentificationAddress ==
|
|
|
|
|
ClientIdentificationAddress)
|
|
|
|
|
{
|
|
|
|
|
/* We have a collision, break out */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Go to the next one */
|
|
|
|
|
DriverExtensions = DriverExtensions->NextExtension;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check if we didn't collide */
|
|
|
|
|
if (!DriverExtensions)
|
|
|
|
|
{
|
|
|
|
|
/* Link this one in */
|
|
|
|
|
NewDriverExtension->NextExtension =
|
|
|
|
|
IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
|
|
|
|
|
IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
|
|
|
|
|
NewDriverExtension;
|
|
|
|
|
Inserted = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Release the lock */
|
2007-03-26 20:28:13 +00:00
|
|
|
|
KeLowerIrql(OldIrql);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
|
|
|
|
|
/* Check if insertion failed */
|
|
|
|
|
if (!Inserted)
|
|
|
|
|
{
|
|
|
|
|
/* Free the entry and fail */
|
|
|
|
|
ExFreePool(NewDriverExtension);
|
|
|
|
|
return STATUS_OBJECT_NAME_COLLISION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise, return the pointer */
|
|
|
|
|
*DriverObjectExtension = NewDriverExtension + 1;
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
PVOID
|
|
|
|
|
NTAPI
|
|
|
|
|
IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PVOID ClientIdentificationAddress)
|
|
|
|
|
{
|
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
PIO_CLIENT_EXTENSION DriverExtensions;
|
|
|
|
|
|
|
|
|
|
/* Acquire lock */
|
|
|
|
|
OldIrql = KeRaiseIrqlToDpcLevel();
|
|
|
|
|
|
|
|
|
|
/* Loop the list until we find the right one */
|
|
|
|
|
DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
|
|
|
|
|
while (DriverExtensions)
|
|
|
|
|
{
|
|
|
|
|
/* Check for a match */
|
|
|
|
|
if (DriverExtensions->ClientIdentificationAddress ==
|
|
|
|
|
ClientIdentificationAddress)
|
|
|
|
|
{
|
|
|
|
|
/* Break out */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Keep looping */
|
|
|
|
|
DriverExtensions = DriverExtensions->NextExtension;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Release lock */
|
2007-03-26 20:28:13 +00:00
|
|
|
|
KeLowerIrql(OldIrql);
|
2006-07-09 00:01:31 +00:00
|
|
|
|
|
|
|
|
|
/* Return nothing or the extension */
|
|
|
|
|
if (!DriverExtensions) return NULL;
|
|
|
|
|
return DriverExtensions + 1;
|
|
|
|
|
}
|
2004-06-23 21:42:50 +00:00
|
|
|
|
|
2007-10-03 10:17:04 +00:00
|
|
|
|
VOID NTAPI
|
|
|
|
|
IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
|
2003-10-15 17:04:39 +00:00
|
|
|
|
{
|
2004-03-27 19:41:32 +00:00
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
2003-10-15 17:04:39 +00:00
|
|
|
|
UNICODE_STRING ImagePath;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
UNICODE_STRING ServiceName;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
ULONG Type;
|
|
|
|
|
PDEVICE_NODE DeviceNode;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
PDRIVER_OBJECT DriverObject;
|
2007-11-25 21:04:44 +00:00
|
|
|
|
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
2008-09-02 08:26:05 +00:00
|
|
|
|
PVOID BaseAddress;
|
2005-05-05 02:46:17 +00:00
|
|
|
|
WCHAR *cur;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2007-10-03 11:54:31 +00:00
|
|
|
|
/* Check if it's an unload request */
|
|
|
|
|
if (LoadParams->DriverObject)
|
|
|
|
|
{
|
2007-11-25 21:04:44 +00:00
|
|
|
|
(*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
|
2007-10-03 11:54:31 +00:00
|
|
|
|
|
|
|
|
|
/* Return success and signal the event */
|
|
|
|
|
LoadParams->Status = STATUS_SUCCESS;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
RtlInitUnicodeString(&ImagePath, NULL);
|
|
|
|
|
|
|
|
|
|
/*
|
2004-03-27 19:41:32 +00:00
|
|
|
|
* Get the service name from the registry key name.
|
|
|
|
|
*/
|
2007-10-03 10:17:04 +00:00
|
|
|
|
ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2007-10-03 10:17:04 +00:00
|
|
|
|
ServiceName = *LoadParams->ServiceName;
|
|
|
|
|
cur = LoadParams->ServiceName->Buffer +
|
|
|
|
|
(LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1;
|
|
|
|
|
while (LoadParams->ServiceName->Buffer != cur)
|
2005-05-05 02:46:17 +00:00
|
|
|
|
{
|
|
|
|
|
if(*cur == L'\\')
|
|
|
|
|
{
|
|
|
|
|
ServiceName.Buffer = cur + 1;
|
2007-10-03 10:17:04 +00:00
|
|
|
|
ServiceName.Length = LoadParams->ServiceName->Length -
|
2005-05-05 02:46:17 +00:00
|
|
|
|
(USHORT)((ULONG_PTR)ServiceName.Buffer -
|
2007-10-03 10:17:04 +00:00
|
|
|
|
(ULONG_PTR)LoadParams->ServiceName->Buffer);
|
2005-05-05 02:46:17 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
cur--;
|
|
|
|
|
}
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get service type.
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&ImagePath, NULL);
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
QueryTable[0].Name = L"Type";
|
|
|
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
|
|
|
|
QueryTable[0].EntryContext = &Type;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
QueryTable[1].Name = L"ImagePath";
|
|
|
|
|
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
|
|
|
QueryTable[1].EntryContext = &ImagePath;
|
|
|
|
|
|
2003-10-16 12:50:30 +00:00
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
2007-10-03 10:17:04 +00:00
|
|
|
|
LoadParams->ServiceName->Buffer, QueryTable, NULL, NULL);
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
2009-06-07 01:18:15 +00:00
|
|
|
|
if (ImagePath.Buffer)
|
|
|
|
|
ExFreePool(ImagePath.Buffer);
|
2007-10-03 10:17:04 +00:00
|
|
|
|
LoadParams->Status = Status;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2004-03-27 19:41:32 +00:00
|
|
|
|
* Normalize the image path for all later processing.
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
|
|
|
|
Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
|
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2004-03-27 19:41:32 +00:00
|
|
|
|
DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
|
2007-10-03 10:17:04 +00:00
|
|
|
|
LoadParams->Status = Status;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-05 02:46:17 +00:00
|
|
|
|
DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
|
2003-10-15 17:04:39 +00:00
|
|
|
|
DPRINT("Type: %lx\n", Type);
|
|
|
|
|
|
2007-06-11 22:02:55 +00:00
|
|
|
|
/* Get existing DriverObject pointer (in case the driver has
|
|
|
|
|
already been loaded and initialized) */
|
|
|
|
|
Status = IopGetDriverObject(
|
|
|
|
|
&DriverObject,
|
|
|
|
|
&ServiceName,
|
|
|
|
|
(Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
|
|
|
|
|
Type == 8 /* SERVICE_RECOGNIZER_DRIVER */));
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2003-10-15 17:04:39 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2007-06-11 22:02:55 +00:00
|
|
|
|
/*
|
|
|
|
|
* Load the driver module
|
|
|
|
|
*/
|
|
|
|
|
|
2011-10-01 04:56:14 +00:00
|
|
|
|
DPRINT("Loading module from %wZ\n", &ImagePath);
|
2008-09-02 08:26:05 +00:00
|
|
|
|
Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
|
2010-09-10 21:25:53 +00:00
|
|
|
|
|
2007-06-11 22:02:55 +00:00
|
|
|
|
if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED)
|
|
|
|
|
{
|
|
|
|
|
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
|
2007-10-03 10:17:04 +00:00
|
|
|
|
LoadParams->Status = Status;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
2007-06-11 22:02:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Initialize the driver module if it's loaded for the first time
|
|
|
|
|
*/
|
|
|
|
|
if (Status != STATUS_IMAGE_ALREADY_LOADED)
|
|
|
|
|
{
|
2011-07-12 18:18:13 +00:00
|
|
|
|
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
|
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
|
|
|
|
MmUnloadSystemImage(ModuleObject);
|
|
|
|
|
LoadParams->Status = Status;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IopDisplayLoadingMessage(&DeviceNode->ServiceName);
|
|
|
|
|
|
2007-06-11 22:02:55 +00:00
|
|
|
|
Status = IopInitializeDriverModule(
|
|
|
|
|
DeviceNode,
|
|
|
|
|
ModuleObject,
|
|
|
|
|
&DeviceNode->ServiceName,
|
|
|
|
|
(Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
|
|
|
|
|
Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
|
|
|
|
|
&DriverObject);
|
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status);
|
|
|
|
|
MmUnloadSystemImage(ModuleObject);
|
|
|
|
|
IopFreeDeviceNode(DeviceNode);
|
2007-10-03 10:17:04 +00:00
|
|
|
|
LoadParams->Status = Status;
|
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
return;
|
2007-06-11 22:02:55 +00:00
|
|
|
|
}
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
|
|
2011-07-12 18:18:13 +00:00
|
|
|
|
/* Initialize and start device */
|
|
|
|
|
IopInitializeDevice(DeviceNode, DriverObject);
|
|
|
|
|
Status = IopStartDevice(DeviceNode);
|
2007-06-11 22:02:55 +00:00
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
2009-08-07 18:27:31 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DPRINT("DriverObject already exist in ObjectManager\n");
|
2009-08-10 14:03:01 +00:00
|
|
|
|
|
|
|
|
|
/* IopGetDriverObject references the DriverObject, so dereference it */
|
2009-08-07 18:27:31 +00:00
|
|
|
|
ObDereferenceObject(DriverObject);
|
|
|
|
|
}
|
2003-10-15 17:04:39 +00:00
|
|
|
|
|
2009-08-10 14:03:01 +00:00
|
|
|
|
/* Pass status to the caller and signal the event */
|
|
|
|
|
LoadParams->Status = Status;
|
2007-10-03 10:17:04 +00:00
|
|
|
|
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
|
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
|
2007-10-03 10:17:04 +00:00
|
|
|
|
/*
|
|
|
|
|
* NtLoadDriver
|
|
|
|
|
*
|
|
|
|
|
* Loads a device driver.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* DriverServiceName
|
|
|
|
|
* Name of the service to load (registry key).
|
|
|
|
|
*
|
|
|
|
|
* Return Value
|
|
|
|
|
* Status
|
|
|
|
|
*
|
|
|
|
|
* Status
|
|
|
|
|
* implemented
|
|
|
|
|
*/
|
2008-11-29 20:47:48 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2007-10-03 10:17:04 +00:00
|
|
|
|
NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
|
|
|
|
|
{
|
2008-12-03 17:28:59 +00:00
|
|
|
|
UNICODE_STRING CapturedDriverServiceName = { 0, 0, NULL };
|
2007-10-03 10:17:04 +00:00
|
|
|
|
KPROCESSOR_MODE PreviousMode;
|
|
|
|
|
LOAD_UNLOAD_PARAMS LoadParams;
|
|
|
|
|
NTSTATUS Status;
|
2004-03-27 19:41:32 +00:00
|
|
|
|
|
2007-10-03 10:17:04 +00:00
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
|
|
PreviousMode = KeGetPreviousMode();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check security privileges
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* FIXME: Uncomment when privileges will be correctly implemented. */
|
|
|
|
|
#if 0
|
|
|
|
|
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
|
|
|
|
|
{
|
|
|
|
|
DPRINT("Privilege not held\n");
|
|
|
|
|
return STATUS_PRIVILEGE_NOT_HELD;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
|
|
|
|
|
PreviousMode,
|
|
|
|
|
DriverServiceName);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DPRINT("NtLoadDriver('%wZ')\n", &CapturedDriverServiceName);
|
|
|
|
|
|
|
|
|
|
LoadParams.ServiceName = &CapturedDriverServiceName;
|
2007-10-03 11:54:31 +00:00
|
|
|
|
LoadParams.DriverObject = NULL;
|
2007-10-03 10:17:04 +00:00
|
|
|
|
KeInitializeEvent(&LoadParams.Event, NotificationEvent, FALSE);
|
|
|
|
|
|
|
|
|
|
/* Call the load/unload routine, depending on current process */
|
|
|
|
|
if (PsGetCurrentProcess() == PsInitialSystemProcess)
|
|
|
|
|
{
|
|
|
|
|
/* Just call right away */
|
|
|
|
|
IopLoadUnloadDriver(&LoadParams);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Load/Unload must be called from system process */
|
|
|
|
|
ExInitializeWorkItem(&LoadParams.WorkItem,
|
|
|
|
|
(PWORKER_THREAD_ROUTINE)IopLoadUnloadDriver,
|
|
|
|
|
(PVOID)&LoadParams);
|
|
|
|
|
|
|
|
|
|
/* Queue it */
|
|
|
|
|
ExQueueWorkItem(&LoadParams.WorkItem, DelayedWorkQueue);
|
|
|
|
|
|
|
|
|
|
/* And wait when it completes */
|
|
|
|
|
KeWaitForSingleObject(&LoadParams.Event, UserRequest, KernelMode,
|
|
|
|
|
FALSE, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
|
|
|
|
|
PreviousMode);
|
|
|
|
|
|
|
|
|
|
return LoadParams.Status;
|
2003-10-15 17:04:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* NtUnloadDriver
|
|
|
|
|
*
|
|
|
|
|
* Unloads a legacy device driver.
|
|
|
|
|
*
|
|
|
|
|
* Parameters
|
|
|
|
|
* DriverServiceName
|
|
|
|
|
* Name of the service to unload (registry key).
|
2005-05-09 01:38:29 +00:00
|
|
|
|
*
|
2003-10-15 17:04:39 +00:00
|
|
|
|
* Return Value
|
|
|
|
|
* Status
|
2004-03-28 09:48:13 +00:00
|
|
|
|
*
|
|
|
|
|
* Status
|
|
|
|
|
* implemented
|
2003-10-15 17:04:39 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2008-11-29 20:47:48 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2003-10-15 17:04:39 +00:00
|
|
|
|
NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
|
|
|
|
|
{
|
|
|
|
|
return IopUnloadDriver(DriverServiceName, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 18:49:50 +00:00
|
|
|
|
/* EOF */
|