ExFreePool(DriverObject->DriverName.Buffer);
}
-#if 0 /* See a bit of hack in IopCreateDriver */
/* Check if it has a service key name */
if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
{
/* Free it */
ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
}
-#endif
}
NTSTATUS FASTCALL
if (!KeLoaderBlock) return;
RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE);
snprintf(TextBuffer, sizeof(TextBuffer),
- "%s%sSystem32\\Drivers\\%wZ%s\n",
+ "%s%sSystem32\\Drivers\\%wZ%s\r\n",
KeLoaderBlock->ArcBootDeviceName,
KeLoaderBlock->NtBootPathName,
ServiceName,
HANDLE CCSKey, ServiceKey;
PVOID BaseAddress;
- DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
-
- /* FIXME: This check may be removed once the bug is fixed */
- if (ServiceName->Buffer == NULL)
- {
- DPRINT1("If you see this, please report to Fireball or hpoussin!\n");
- return STATUS_UNSUCCESSFUL;
- }
+ ASSERT(ServiceName->Length);
+ DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
if (ExpInTextModeSetup)
{
Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
if (!NT_SUCCESS(Status))
{
- DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+ DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n",
+ &CCSName, Status);
return Status;
}
Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
if (!NT_SUCCESS(Status))
{
- DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
+ DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with Status %08X\n",
+ ServiceName, Status);
ZwClose(CCSKey);
return Status;
}
DriverName.Length > 0 ? &DriverName : NULL,
DriverEntry,
&RegistryKey,
+ ServiceName,
ModuleObject,
&Driver);
RtlFreeUnicodeString(&RegistryKey);
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
+ /* No filter value present */
+ if (ValueType == REG_NONE)
+ return STATUS_SUCCESS;
+
for (Filters = ValueData;
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
*Filters != 0;
/* Load and initialize the filter driver */
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
if (!NT_SUCCESS(Status))
- continue;
+ return Status;
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
FALSE, &DriverObject);
if (!NT_SUCCESS(Status))
- continue;
+ return Status;
}
Status = IopInitializeDevice(DeviceNode, DriverObject);
/* Remove extra reference */
ObDereferenceObject(DriverObject);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
}
return STATUS_SUCCESS;
QueryTable[0].Name = L"LowerFilters";
else
QueryTable[0].Name = L"UpperFilters";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].Flags = 0;
+ QueryTable[0].DefaultType = REG_NONE;
- RtlQueryRegistryValues(
+ Status = RtlQueryRegistryValues(
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey,
QueryTable,
DeviceNode,
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load device %s filters: %08X\n",
+ Lower ? "lower" : "upper", Status);
+ ZwClose(SubKey);
+ ZwClose(EnumRootKey);
+ return Status;
+ }
/*
* Now get the class GUID
&Class, KEY_READ);
if (!NT_SUCCESS(Status))
{
+ /* It's okay if there's no class key */
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
ZwClose(EnumRootKey);
- return Status;
+ return STATUS_SUCCESS;
}
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
else
QueryTable[0].Name = L"UpperFilters";
QueryTable[0].EntryContext = NULL;
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].Flags = 0;
+ QueryTable[0].DefaultType = REG_NONE;
- RtlQueryRegistryValues(
+ Status = RtlQueryRegistryValues(
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey,
QueryTable,
/* Clean up */
ZwClose(SubKey);
ZwClose(EnumRootKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load class %s filters: %08X\n",
+ Lower ? "lower" : "upper", Status);
+ ZwClose(SubKey);
+ ZwClose(EnumRootKey);
+ return Status;
+ }
}
return STATUS_SUCCESS;
NTSTATUS
NTAPI
INIT_FUNCTION
-IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
{
PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
PWCHAR FileNameWithoutPath;
LPWSTR FileExtension;
- PUNICODE_STRING ModuleName = &LdrEntry->BaseDllName;
+ PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ PLIST_ENTRY NextEntry;
UNICODE_STRING ServiceName;
/*
return(Status);
}
+ /* Lookup the new Ldr entry in PsLoadedModuleList */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ if (RtlEqualUnicodeString(ModuleName, &LdrEntry->BaseDllName, TRUE))
+ {
+ break;
+ }
+
+ NextEntry = NextEntry->Flink;
+ }
+ NT_ASSERT(NextEntry != &PsLoadedModuleList);
+
/*
* Initialize the driver
*/
LPWSTR Start;
BOOLEAN SafeToUnload = TRUE;
- DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers);
+ DPRINT("IopUnloadDriver('%wZ', %u)\n", DriverServiceName, UnloadPnpDrivers);
PAGED_CODE();
ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
- wcscpy(ObjectName.Buffer, L"\\Driver\\");
+ wcscpy(ObjectName.Buffer, DRIVER_ROOT_NAME);
memcpy(ObjectName.Buffer + 8, Start, ObjectName.Length - 8 * sizeof(WCHAR));
ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0;
IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
IN PDRIVER_INITIALIZE InitializationFunction,
IN PUNICODE_STRING RegistryPath,
+ IN PCUNICODE_STRING ServiceName,
PLDR_DATA_TABLE_ENTRY ModuleObject,
OUT PDRIVER_OBJECT *pDriverObject)
{
{
/* Create a random name and set up the string*/
NameLength = (USHORT)swprintf(NameBuffer,
- L"\\Driver\\%08u",
+ DRIVER_ROOT_NAME L"%08u",
KeTickCount);
LocalDriverName.Length = NameLength * sizeof(WCHAR);
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
}
/* Set up the service key name buffer */
- ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool,
- LocalDriverName.Length +
- sizeof(WCHAR),
+ ServiceKeyName.MaximumLength = ServiceName->Length + sizeof(UNICODE_NULL);
+ ServiceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ ServiceKeyName.MaximumLength,
TAG_IO);
if (!ServiceKeyName.Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- /* Fill out the key data and copy the buffer */
- ServiceKeyName.Length = LocalDriverName.Length;
- ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength;
- RtlCopyMemory(ServiceKeyName.Buffer,
- LocalDriverName.Buffer,
- LocalDriverName.Length);
-
- /* Null-terminate it and set it */
- ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ /* Copy the name and set it in the driver extension */
+ RtlCopyUnicodeString(&ServiceKeyName,
+ ServiceName);
DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
- /* Also store it in the Driver Object. This is a bit of a hack. */
- RtlCopyMemory(&DriverObject->DriverName,
- &ServiceKeyName,
- sizeof(UNICODE_STRING));
+ /* Make a copy of the driver name to store in the driver object */
+ DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
+ DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
+ DriverObject->DriverName.MaximumLength,
+ TAG_IO);
+ if (!DriverObject->DriverName.Buffer)
+ {
+ /* Fail */
+ ObMakeTemporaryObject(DriverObject);
+ ObDereferenceObject(DriverObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCopyUnicodeString(&DriverObject->DriverName,
+ &LocalDriverName);
/* Add the Object and get its handle */
Status = ObInsertObject(DriverObject,
if (!DriverObject->MajorFunction[i])
{
/* Print a warning in the debug log */
- DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%d] to NULL!\n",
+ DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
&DriverObject->DriverName, i);
/* Fix it up */
IN PDRIVER_INITIALIZE InitializationFunction)
{
PDRIVER_OBJECT DriverObject;
- return IopCreateDriver(DriverName, InitializationFunction, NULL, NULL, &DriverObject);
+ return IopCreateDriver(DriverName, InitializationFunction, NULL, DriverName, NULL, &DriverObject);
}
/*
VOID NTAPI
IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
{
- RTL_QUERY_REGISTRY_TABLE QueryTable[3];
- UNICODE_STRING ImagePath;
- UNICODE_STRING ServiceName;
- NTSTATUS Status;
- ULONG Type;
- PDEVICE_NODE DeviceNode;
- PDRIVER_OBJECT DriverObject;
- PLDR_DATA_TABLE_ENTRY ModuleObject;
- PVOID BaseAddress;
- WCHAR *cur;
-
- /* Check if it's an unload request */
- if (LoadParams->DriverObject)
- {
- (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
+ RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+ UNICODE_STRING ImagePath;
+ UNICODE_STRING ServiceName;
+ NTSTATUS Status;
+ ULONG Type;
+ PDEVICE_NODE DeviceNode;
+ PDRIVER_OBJECT DriverObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
+ PVOID BaseAddress;
+ WCHAR *cur;
- /* Return success and signal the event */
- LoadParams->Status = STATUS_SUCCESS;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ /* Check if it's an unload request */
+ if (LoadParams->DriverObject)
+ {
+ (*LoadParams->DriverObject->DriverUnload)(LoadParams->DriverObject);
- RtlInitUnicodeString(&ImagePath, NULL);
+ /* Return success and signal the event */
+ LoadParams->Status = STATUS_SUCCESS;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- /*
- * Get the service name from the registry key name.
- */
- ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
+ RtlInitUnicodeString(&ImagePath, NULL);
- ServiceName = *LoadParams->ServiceName;
- cur = LoadParams->ServiceName->Buffer +
- (LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1;
- while (LoadParams->ServiceName->Buffer != cur)
- {
- if(*cur == L'\\')
- {
- ServiceName.Buffer = cur + 1;
- ServiceName.Length = LoadParams->ServiceName->Length -
- (USHORT)((ULONG_PTR)ServiceName.Buffer -
- (ULONG_PTR)LoadParams->ServiceName->Buffer);
- break;
- }
- cur--;
- }
+ /*
+ * Get the service name from the registry key name.
+ */
+ ASSERT(LoadParams->ServiceName->Length >= sizeof(WCHAR));
+
+ ServiceName = *LoadParams->ServiceName;
+ cur = LoadParams->ServiceName->Buffer +
+ (LoadParams->ServiceName->Length / sizeof(WCHAR)) - 1;
+ while (LoadParams->ServiceName->Buffer != cur)
+ {
+ if (*cur == L'\\')
+ {
+ ServiceName.Buffer = cur + 1;
+ ServiceName.Length = LoadParams->ServiceName->Length -
+ (USHORT)((ULONG_PTR)ServiceName.Buffer -
+ (ULONG_PTR)LoadParams->ServiceName->Buffer);
+ break;
+ }
+ cur--;
+ }
- /*
+ /*
* Get service type.
*/
- RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+ RtlZeroMemory(&QueryTable, sizeof(QueryTable));
- RtlInitUnicodeString(&ImagePath, NULL);
+ RtlInitUnicodeString(&ImagePath, NULL);
- QueryTable[0].Name = L"Type";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
- QueryTable[0].EntryContext = &Type;
+ QueryTable[0].Name = L"Type";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].EntryContext = &Type;
- QueryTable[1].Name = L"ImagePath";
- QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[1].EntryContext = &ImagePath;
+ QueryTable[1].Name = L"ImagePath";
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[1].EntryContext = &ImagePath;
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- LoadParams->ServiceName->Buffer, QueryTable, NULL, NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- if (ImagePath.Buffer)
- ExFreePool(ImagePath.Buffer);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ LoadParams->ServiceName->Buffer,
+ QueryTable, NULL, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ if (ImagePath.Buffer) ExFreePool(ImagePath.Buffer);
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- /*
+ /*
* Normalize the image path for all later processing.
*/
- Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
-
- DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
- DPRINT("Type: %lx\n", Type);
+ Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- /* 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 */));
+ DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
+ DPRINT("Type: %lx\n", Type);
- if (!NT_SUCCESS(Status))
- {
- /*
- * Load the driver module
- */
+ /*
+ * 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 */));
- DPRINT("Loading module from %wZ\n", &ImagePath);
- Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ /*
+ * Load the driver module
+ */
- if (!NT_SUCCESS(Status))
- {
- DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ DPRINT("Loading module from %wZ\n", &ImagePath);
+ Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- /*
- * Initialize the driver module if it's loaded for the first time
- */
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
- MmUnloadSystemImage(ModuleObject);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ /*
+ * Initialize the driver module if it's loaded for the first time
+ */
+ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+ MmUnloadSystemImage(ModuleObject);
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- IopDisplayLoadingMessage(&DeviceNode->ServiceName);
+ IopDisplayLoadingMessage(&DeviceNode->ServiceName);
- Status = IopInitializeDriverModule(DeviceNode,
- ModuleObject,
- &DeviceNode->ServiceName,
- (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
- Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
- &DriverObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
- MmUnloadSystemImage(ModuleObject);
- IopFreeDeviceNode(DeviceNode);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ Status = IopInitializeDriverModule(DeviceNode,
+ ModuleObject,
+ &DeviceNode->ServiceName,
+ (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
+ Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
+ &DriverObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
+ MmUnloadSystemImage(ModuleObject);
+ IopFreeDeviceNode(DeviceNode);
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- /* Initialize and start device */
- IopInitializeDevice(DeviceNode, DriverObject);
- Status = IopStartDevice(DeviceNode);
- }
- else
- {
- DPRINT("DriverObject already exist in ObjectManager\n");
- Status = STATUS_IMAGE_ALREADY_LOADED;
+ /* Initialize and start device */
+ IopInitializeDevice(DeviceNode, DriverObject);
+ Status = IopStartDevice(DeviceNode);
+ }
+ else
+ {
+ DPRINT("DriverObject already exist in ObjectManager\n");
+ Status = STATUS_IMAGE_ALREADY_LOADED;
- /* IopGetDriverObject references the DriverObject, so dereference it */
- ObDereferenceObject(DriverObject);
- }
+ /* IopGetDriverObject references the DriverObject, so dereference it */
+ ObDereferenceObject(DriverObject);
+ }
- /* Pass status to the caller and signal the event */
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+ /* Pass status to the caller and signal the event */
+ LoadParams->Status = Status;
+ KeSetEvent(&LoadParams->Event, 0, FALSE);
}
/*
PreviousMode = KeGetPreviousMode();
/*
- * Check security privileges
- */
+ * Check security privileges
+ */
/* FIXME: Uncomment when privileges will be correctly implemented. */
#if 0