PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
PAGED_CODE();
+ DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
+
+ /* There must be no device objects remaining at this point */
+ ASSERT(!DriverObject->DeviceObject);
+
/* Get the extension and loop them */
DriverExtension = IoGetDrvObjExtension(DriverObject)->
ClientDriverExtension;
* The input image path isn't freed on error.
*/
-NTSTATUS FASTCALL
+NTSTATUS
+FASTCALL
IopNormalizeImagePath(
- IN OUT PUNICODE_STRING ImagePath,
- IN PUNICODE_STRING ServiceName)
+ _Inout_ _When_(return>=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
+ PUNICODE_STRING ImagePath,
+ _In_ PUNICODE_STRING ServiceName)
{
UNICODE_STRING InputImagePath;
/* Free caller's string */
ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
}
-
+
DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
return STATUS_SUCCESS;
if (ServiceStart >= 4)
{
- /* FIXME: Check if it is the right status code */
- Status = STATUS_PLUGPLAY_NO_DEVICE;
+ /* We can't load this */
+ Status = STATUS_DRIVER_UNABLE_TO_LOAD;
}
else
{
DPRINT("IopCreateDriver() failed (Status 0x%08lx)\n", Status);
return Status;
}
-
+
MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection);
/* Set the driver as initialized */
Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
{
DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
+
ServiceName.Buffer = Filters;
ServiceName.MaximumLength =
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
- /* Load and initialize the filter driver */
- Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
- if (Status != STATUS_IMAGE_ALREADY_LOADED)
- {
- if (!NT_SUCCESS(Status))
- continue;
+ Status = IopGetDriverObject(&DriverObject,
+ &ServiceName,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Load and initialize the filter driver */
+ Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
+ if (!NT_SUCCESS(Status))
+ continue;
- Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
- FALSE, &DriverObject);
- if (!NT_SUCCESS(Status))
- continue;
- }
- else
- {
- /* get existing DriverObject pointer */
- Status = IopGetDriverObject(
- &DriverObject,
- &ServiceName,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopGetDriverObject() returned status 0x%08x!\n", Status);
- continue;
- }
- }
+ Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
+ FALSE, &DriverObject);
+ if (!NT_SUCCESS(Status))
+ continue;
+ }
- Status = IopInitializeDevice(DeviceNode, DriverObject);
- if (!NT_SUCCESS(Status))
- continue;
+ Status = IopInitializeDevice(DeviceNode, DriverObject);
+
+ /* Remove extra reference */
+ ObDereferenceObject(DriverObject);
}
return STATUS_SUCCESS;
&MissingApiName,
&MissingDriverName,
&LoadedImports);
+
+ /* Free the temporary buffer */
+ ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);
+
+ /* Check the result of the imports resolution */
if (!NT_SUCCESS(Status)) return Status;
/* Return */
Status = IopStartDevice(DeviceNode);
}
+ /* Remove extra reference from IopInitializeDriverModule */
+ ObDereferenceObject(DriverObject);
+
return Status;
}
{
/* Fail */
IopFreeDeviceNode(DeviceNode);
+ ObDereferenceObject(DriverObject);
return;
}
{
/* Fail */
IopFreeDeviceNode(DeviceNode);
+ ObDereferenceObject(DriverObject);
return;
}
*/
/* Call the load/unload routine, depending on current process */
- if (DriverObject->DriverUnload && DriverObject->DriverSection)
+ if (DriverObject->DriverUnload && DriverObject->DriverSection &&
+ (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
{
/* Loop through each device object of the driver
and set DOE_UNLOAD_PENDING flag */
return STATUS_SUCCESS;
}
+ DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
+
/* Set the unload invoked flag */
DriverObject->Flags |= DRVO_UNLOAD_INVOKED;
}
else
{
+ DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
+
/* Dereference one time (refd inside this function) */
ObDereferenceObject(DriverObject);
RtlZeroMemory(DriverObject, ObjectSize);
DriverObject->Type = IO_TYPE_DRIVER;
DriverObject->Size = sizeof(DRIVER_OBJECT);
- DriverObject->Flags = DRVO_LEGACY_DRIVER;//DRVO_BUILTIN_DRIVER;
+ DriverObject->Flags = DRVO_LEGACY_DRIVER;
DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
DriverObject->DriverExtension->DriverObject = DriverObject;
DriverObject->DriverInit = InitializationFunction;
KernelMode,
(PVOID*)&DriverObject,
NULL);
+
+ /* Close the extra handle */
+ ZwClose(hDriver);
+
if (!NT_SUCCESS(Status))
{
/* Fail */
return Status;
}
- /* Close the extra handle */
- ZwClose(hDriver);
-
DriverObject->HardwareDatabase = &IopHardwareDatabaseKey;
DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
DriverObject->DriverSection = NULL;
ObMakeTemporaryObject(DriverObject);
ObDereferenceObject(DriverObject);
+ return Status;
}
else
{
*pDriverObject = DriverObject;
}
+ /* We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
+ * Other parts of the I/O manager depend on this behavior */
+ if (!DriverObject->DeviceObject) DriverObject->Flags &= ~DRVO_LEGACY_DRIVER;
+
/* Loop all Major Functions */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
if (!Inserted)
{
/* Free the entry and fail */
- ExFreePool(NewDriverExtension);
+ ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
return STATUS_OBJECT_NAME_COLLISION;
}
DPRINT("Loading module from %wZ\n", &ImagePath);
Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
- if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED)
+ if (!NT_SUCCESS(Status))
{
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
LoadParams->Status = Status;
/*
* Initialize the driver module if it's loaded for the first time
*/
- if (Status != STATUS_IMAGE_ALREADY_LOADED)
+ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+ if (!NT_SUCCESS(Status))
{
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
+ DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+ MmUnloadSystemImage(ModuleObject);
+ LoadParams->Status = Status;
+ (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
+ }
- 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);
-
- Status = IopInitializeDriverModule(
- DeviceNode,
- ModuleObject,
- &DeviceNode->ServiceName,
- (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
- Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
- &DriverObject);
+ IopDisplayLoadingMessage(&DeviceNode->ServiceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status);
- MmUnloadSystemImage(ModuleObject);
- IopFreeDeviceNode(DeviceNode);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
-
- /* Initialize and start device */
- IopInitializeDevice(DeviceNode, DriverObject);
- Status = IopStartDevice(DeviceNode);
+ 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;
}
+
+ /* 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);