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;
* Display 'Loading XXX...' message.
*/
-VOID
+VOID
FASTCALL
INIT_FUNCTION
IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
* 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;
+ DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
+
RtlCopyMemory(
&InputImagePath,
ImagePath,
ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
}
+ DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
+
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
- /* Open CurrentControlSet */
- RtlInitUnicodeString(&CCSName,
- L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
- Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
- if (!NT_SUCCESS(Status))
+ if (ExpInTextModeSetup)
{
- DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
- return Status;
- }
+ /* We have no registry, but luckily we know where all the drivers are */
- /* 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;
+ /* 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
+ {
+ /* 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;
+ }
- /*
- * Get information about the service.
- */
+ /* 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;
+ }
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
+ /*
+ * Get information about the service.
+ */
- RtlInitUnicodeString(&ServiceImagePath, NULL);
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Name = L"Start";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].EntryContext = &ServiceStart;
+ RtlInitUnicodeString(&ServiceImagePath, NULL);
- QueryTable[1].Name = L"ImagePath";
- QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[1].EntryContext = &ServiceImagePath;
+ QueryTable[0].Name = L"Start";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &ServiceStart;
- Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
- (PWSTR)ServiceKey, QueryTable, NULL, NULL);
+ QueryTable[1].Name = L"ImagePath";
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[1].EntryContext = &ServiceImagePath;
- ZwClose(ServiceKey);
- ZwClose(CCSKey);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PWSTR)ServiceKey, QueryTable, NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
- return Status;
+ ZwClose(ServiceKey);
+ ZwClose(CCSKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
+ return Status;
+ }
}
/*
return Status;
}
- /*
- * Case for disabled drivers
- */
-
- if (ServiceStart >= 4)
- {
- /* FIXME: Check if it is the right status code */
- Status = STATUS_PLUGPLAY_NO_DEVICE;
- }
- else
- {
- DPRINT("Loading module\n");
- Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
- }
+ /*
+ * Case for disabled drivers
+ */
+
+ if (ServiceStart >= 4)
+ {
+ /* We can't load this */
+ Status = STATUS_DRIVER_UNABLE_TO_LOAD;
+ }
+ else
+ {
+ DPRINT("Loading module from %wZ\n", &ServiceImagePath);
+ Status = MmLoadSystemImage(&ServiceImagePath, NULL, NULL, 0, (PVOID)ModuleObject, &BaseAddress);
+ if (NT_SUCCESS(Status))
+ {
+ IopDisplayLoadingMessage(ServiceName);
+ }
+ }
ExFreePool(ServiceImagePath.Buffer);
return Status;
}
+VOID
+NTAPI
+MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
+
/*
* IopInitializeDriverModule
*
DriverName.Length > 0 ? &DriverName : NULL,
DriverEntry,
&RegistryKey,
- ModuleObject->DllBase,
- ModuleObject->SizeOfImage,
+ ModuleObject,
&Driver);
RtlFreeUnicodeString(&RegistryKey);
return Status;
}
+ MmFreeDriverInitialization((PLDR_DATA_TABLE_ENTRY)Driver->DriverSection);
+
/* Set the driver as initialized */
IopReadyDeviceObjects(Driver);
Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
{
DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
+
ServiceName.Buffer = Filters;
ServiceName.MaximumLength =
- ServiceName.Length = wcslen(Filters) * sizeof(WCHAR);
+ 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);
- Status = IopInitializeDevice(DeviceNode, DriverObject);
- if (!NT_SUCCESS(Status))
- continue;
+ /* Remove extra reference */
+ ObDereferenceObject(DriverObject);
}
return STATUS_SUCCESS;
//
NTSTATUS
NTAPI
+INIT_FUNCTION
LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
PUNICODE_STRING FileName,
PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
NTSTATUS Status;
- PLDR_DATA_TABLE_ENTRY NewEntry;
UNICODE_STRING BaseName, BaseDirectory;
PLOAD_IMPORTS LoadedImports = (PVOID)-2;
PCHAR MissingApiName, Buffer;
BaseDirectory.Length -= BaseName.Length;
BaseDirectory.MaximumLength = BaseDirectory.Length;
- NewEntry = LdrEntry;
-
/* Resolve imports */
MissingApiName = Buffer;
Status = MiResolveImageReferences(DriverBase,
&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 */
NTSTATUS
NTAPI
+INIT_FUNCTION
IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
{
PDEVICE_NODE DeviceNode;
FileExtension = wcsrchr(ServiceName.Buffer, '.');
if (FileExtension != NULL)
{
- ServiceName.Length -= wcslen(FileExtension) * sizeof(WCHAR);
+ ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
FileExtension[0] = 0;
}
DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
return(Status);
}
- DeviceNode->ServiceName = ServiceName;
/*
* Initialize the driver
Status = IopStartDevice(DeviceNode);
}
+ /* Remove extra reference from IopInitializeDriverModule */
+ ObDereferenceObject(DriverObject);
+
return Status;
}
*/
VOID
FASTCALL
+INIT_FUNCTION
IopInitializeBootDrivers(VOID)
{
PLIST_ENTRY ListHead, NextEntry, NextEntry2;
{
/* Fail */
IopFreeDeviceNode(DeviceNode);
+ ObDereferenceObject(DriverObject);
return;
}
{
/* Fail */
IopFreeDeviceNode(DeviceNode);
+ ObDereferenceObject(DriverObject);
return;
}
/* Get highest group order index */
IopGroupIndex = PpInitGetGroupOrderIndex(NULL);
if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
-
+
/* Allocate the group table */
IopGroupTable = ExAllocatePoolWithTag(PagedPool,
IopGroupIndex * sizeof(LIST_ENTRY),
TAG_IO);
if (IopGroupTable == NULL) ASSERT(FALSE);
-
+
/* Initialize the group table lists */
for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
-
+
/* Loop the boot modules */
ListHead = &KeLoaderBlock->LoadOrderListHead;
NextEntry = ListHead->Flink;
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
-
+
/* Check if the DLL needs to be initialized */
if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
{
/* Call its entrypoint */
MmCallDllInitialize(LdrEntry, NULL);
}
-
+
/* Go to the next driver */
NextEntry = NextEntry->Flink;
}
-
+
/* Loop the boot drivers */
ListHead = &KeLoaderBlock->BootDriverListHead;
NextEntry = ListHead->Flink;
BootEntry = CONTAINING_RECORD(NextEntry,
BOOT_DRIVER_LIST_ENTRY,
Link);
-
+
/* Get the driver loader entry */
LdrEntry = BootEntry->LdrEntry;
-
+
/* Allocate our internal accounting structure */
DriverInfo = ExAllocatePoolWithTag(PagedPool,
sizeof(DRIVER_INFORMATION),
RtlZeroMemory(DriverInfo, sizeof(DRIVER_INFORMATION));
InitializeListHead(&DriverInfo->Link);
DriverInfo->DataTableEntry = BootEntry;
-
+
/* Open the registry key */
Status = IopOpenRegistryKeyEx(&KeyHandle,
NULL,
&BootEntry->RegistryPath,
KEY_READ);
if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
- ((KeLoaderBlock->SetupLdrBlock) && (KeyHandle = (PVOID)1)))
+ ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
{
/* Save the handle */
DriverInfo->ServiceHandle = KeyHandle;
-
+
/* Get the group oder index */
Index = PpInitGetGroupOrderIndex(KeyHandle);
-
+
/* Get the tag position */
DriverInfo->TagPosition = PipGetDriverTagPriority(KeyHandle);
-
+
/* Insert it into the list, at the right place */
ASSERT(Index < IopGroupIndex);
NextEntry2 = IopGroupTable[Index].Flink;
DriverInfoTag = CONTAINING_RECORD(NextEntry2,
DRIVER_INFORMATION,
Link);
-
+
/* Check if we found the right tag position */
if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
{
/* We're done */
break;
}
-
+
/* Next entry */
NextEntry2 = NextEntry2->Flink;
}
-
+
/* Insert us right before the next entry */
NextEntry2 = NextEntry2->Blink;
InsertHeadList(NextEntry2, &DriverInfo->Link);
DriverInfo = CONTAINING_RECORD(NextEntry,
DRIVER_INFORMATION,
Link);
-
+
/* Get the driver loader entry */
LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
-
+
/* Initialize it */
IopInitializeBuiltinDriver(LdrEntry);
-
+
/* Next entry */
NextEntry = NextEntry->Flink;
}
}
-
+
/* In old ROS, the loader list became empty after this point. Simulate. */
InitializeListHead(&KeLoaderBlock->LoadOrderListHead);
}
VOID
FASTCALL
+INIT_FUNCTION
IopInitializeSystemDrivers(VOID)
{
PUNICODE_STRING *DriverList, *SavedList;
-
+
/* No system drivers on the boot cd */
if (KeLoaderBlock->SetupLdrBlock) return;
-
+
/* Get the driver list */
SavedList = DriverList = CmGetSystemDriverList();
ASSERT(DriverList);
-
+
/* Loop it */
while (*DriverList)
{
/* Load the driver */
ZwLoadDriver(*DriverList);
-
+
/* Free the entry */
RtlFreeUnicodeString(*DriverList);
ExFreePool(*DriverList);
-
+
/* Next entry */
InbvIndicateProgress();
DriverList++;
* Construct the driver object name
*/
- ObjectName.Length = (wcslen(Start) + 8) * sizeof(WCHAR);
+ ObjectName.Length = ((USHORT)wcslen(Start) + 8) * sizeof(WCHAR);
ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
if (!ObjectName.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
*/
/* 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);
IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
IN PDRIVER_INITIALIZE InitializationFunction,
IN PUNICODE_STRING RegistryPath,
- IN PVOID DllBase,
- IN ULONG SizeOfImage,
+ PLDR_DATA_TABLE_ENTRY ModuleObject,
OUT PDRIVER_OBJECT *pDriverObject)
{
WCHAR NameBuffer[100];
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;
-
+ DriverObject->DriverSection = ModuleObject;
/* Loop all Major Functions */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
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 = DllBase;
- DriverObject->DriverSize = SizeOfImage;
+ DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
+ DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
/* Finally, call its init function */
DPRINT("RegistryKey: %wZ\n", RegistryPath);
{
/* If it didn't work, then kill the object */
DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
+ 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++)
{
IN PDRIVER_INITIALIZE InitializationFunction)
{
PDRIVER_OBJECT DriverObject;
- return IopCreateDriver(DriverName, InitializationFunction, NULL, 0, 0, &DriverObject);
+ return IopCreateDriver(DriverName, InitializationFunction, NULL, NULL, &DriverObject);
}
/*
if (!Inserted)
{
/* Free the entry and fail */
- ExFreePool(NewDriverExtension);
+ ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
return STATUS_OBJECT_NAME_COLLISION;
}
cur--;
}
- IopDisplayLoadingMessage(&ServiceName);
-
/*
* Get service type.
*/
DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
DPRINT("Type: %lx\n", Type);
- /*
- * Create device node
- */
-
- /* Use IopRootDeviceNode for now */
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
-
/* Get existing DriverObject pointer (in case the driver has
already been loaded and initialized) */
Status = IopGetDriverObject(
* Load the driver module
*/
+ 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);
- IopFreeDeviceNode(DeviceNode);
LoadParams->Status = Status;
(VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
return;
}
- /*
- * Set a service name for the device node
- */
-
- RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer);
-
/*
* 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 = 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);
- LoadParams->Status = Status;
- (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
- return;
- }
+ DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
+ MmUnloadSystemImage(ModuleObject);
+ LoadParams->Status = Status;
+ (VOID)KeSetEvent(&LoadParams->Event, 0, FALSE);
+ return;
}
- /* Store its DriverSection, so that it could be unloaded */
- DriverObject->DriverSection = ModuleObject;
+ 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;
+ }
/* Initialize and start device */
IopInitializeDevice(DeviceNode, DriverObject);
else
{
DPRINT("DriverObject already exist in ObjectManager\n");
+ Status = STATUS_IMAGE_ALREADY_LOADED;
/* IopGetDriverObject references the DriverObject, so dereference it */
ObDereferenceObject(DriverObject);
-
- /* Free device node since driver loading failed */
- IopFreeDeviceNode(DeviceNode);
}
/* Pass status to the caller and signal the event */