- Allocate Re-Init entries with a tag

- Fix IoAllocateDriverObjectExtension and IoGetDriverObjectExtension:
  - They were using the wrong structure (a made up one).
  - They were saving the extension where the Driver Object's base address should be.
  - Memory leaks.
  - Sometimes holding the lock too long.
- Created EXTENDED_DRIVER_OBJECT structure in NDK, since parts of the documented one are hidden (much like EXTENDED_DEVICE_OBJECT).
- Fixed IopDeleteDriver to free what it should.
- Fixed IoCreateDriver to handle more failure cases.

svn path=/trunk/; revision=22962
This commit is contained in:
Alex Ionescu 2006-07-09 00:01:31 +00:00
parent 2849b81889
commit 17c27b70cd
5 changed files with 314 additions and 233 deletions

View file

@ -1267,11 +1267,6 @@ typedef struct _GET_RETRIEVAL_DESCRIPTOR {
MAPPING_PAIR Pair[1]; MAPPING_PAIR Pair[1];
} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR; } GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR;
typedef struct _IO_CLIENT_EXTENSION {
struct _IO_CLIENT_EXTENSION *NextExtension;
PVOID ClientIdentificationAddress;
} IO_CLIENT_EXTENSION, *PIO_CLIENT_EXTENSION;
typedef struct _IO_COMPLETION_BASIC_INFORMATION { typedef struct _IO_COMPLETION_BASIC_INFORMATION {
LONG Depth; LONG Depth;
} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION; } IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION;

View file

@ -684,6 +684,15 @@ typedef struct _IO_TIMER
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
} IO_TIMER, *PIO_TIMER; } IO_TIMER, *PIO_TIMER;
//
// Driver Extension
//
typedef struct _IO_CLIENT_EXTENSION
{
struct _IO_CLIENT_EXTENSION *NextExtension;
PVOID ClientIdentificationAddress;
} IO_CLIENT_EXTENSION, *PIO_CLIENT_EXTENSION;
// //
// Device Node // Device Node
// //
@ -787,14 +796,17 @@ typedef struct _EXTENDED_DEVOBJ_EXTENSION
} EXTENDED_DEVOBJ_EXTENSION, *PEXTENDED_DEVOBJ_EXTENSION; } EXTENDED_DEVOBJ_EXTENSION, *PEXTENDED_DEVOBJ_EXTENSION;
// //
// Private Driver Extension Descriptor // Extended Driver Object Extension Structure
// //
typedef struct _PRIVATE_DRIVER_EXTENSIONS typedef struct _EXTENDED_DRIVER_EXTENSION
{ {
struct _PRIVATE_DRIVER_EXTENSIONS *Link; struct _DRIVER_OBJECT *DriverObject;
PVOID ClientIdentificationAddress; PDRIVER_ADD_DEVICE AddDevice;
CHAR Extension[1]; ULONG Count;
} PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS; UNICODE_STRING ServiceKeyName;
PIO_CLIENT_EXTENSION ClientDriverExtension;
PFS_FILTER_CALLBACKS FsFilterCallbacks;
} EXTENDED_DRIVER_EXTENSION, *PEXTENDED_DRIVER_EXTENSION;
// //
// Extended I/O Stack Location Structure // Extended I/O Stack Location Structure

View file

@ -86,6 +86,13 @@
((PEXTENDED_DEVOBJ_EXTENSION) \ ((PEXTENDED_DEVOBJ_EXTENSION) \
(DeviceObject->DeviceObjectExtension)) \ (DeviceObject->DeviceObjectExtension)) \
//
// Returns the internal Driver Object Extension
//
#define IoGetDrvObjExtension(DriverObject) \
((PEXTENDED_DRIVER_EXTENSION) \
(DriverObject->DriverExtension)) \
/* /*
* VOID * VOID
* IopDeviceNodeSetFlag( * IopDeviceNodeSetFlag(
@ -352,6 +359,17 @@ typedef struct _FS_CHANGE_NOTIFY_ENTRY
PDRIVER_FS_NOTIFICATION FSDNotificationProc; PDRIVER_FS_NOTIFICATION FSDNotificationProc;
} FS_CHANGE_NOTIFY_ENTRY, *PFS_CHANGE_NOTIFY_ENTRY; } FS_CHANGE_NOTIFY_ENTRY, *PFS_CHANGE_NOTIFY_ENTRY;
//
// Driver (Boot) Re-Initialization Entry
//
typedef struct _DRIVER_REINIT_ITEM
{
LIST_ENTRY ItemEntry;
PDRIVER_OBJECT DriverObject;
PDRIVER_REINITIALIZE ReinitRoutine;
PVOID Context;
} DRIVER_REINIT_ITEM, *PDRIVER_REINIT_ITEM;
// //
// Called on every visit of a node during a preorder-traversal of the device // Called on every visit of a node during a preorder-traversal of the device
// node tree. // node tree.

View file

@ -54,6 +54,7 @@
#define TAG_ERROR_LOG TAG('I', 'o', 'E', 'r') #define TAG_ERROR_LOG TAG('I', 'o', 'E', 'r')
#define TAG_EA TAG('I', 'o', 'E', 'a') #define TAG_EA TAG('I', 'o', 'E', 'a')
#define TAG_IO_NAME TAG('I', 'o', 'N', 'm') #define TAG_IO_NAME TAG('I', 'o', 'N', 'm')
#define TAG_REINIT TAG('I', 'o', 'R', 'i')
/* formerly located in io/work.c */ /* formerly located in io/work.c */
#define TAG_IOWI TAG('I', 'O', 'W', 'I') #define TAG_IOWI TAG('I', 'O', 'W', 'I')

View file

@ -1,11 +1,11 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel
* PROJECT: ReactOS kernel * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/driver.c * FILE: ntoskrnl/io/driver.c
* PURPOSE: Loading and unloading of drivers * PURPOSE: Driver Object Management
* * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMERS: David Welch (welch@cwcom.net) * Filip Navara (navaraf@reactos.org)
* Filip Navara (xnavara@volny.cz) * Hervé Poussineau (hpoussin@reactos.org)
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -43,14 +43,6 @@ typedef struct _SERVICE
/* BOOLEAN ServiceRunning;*/ // needed ?? /* BOOLEAN ServiceRunning;*/ // needed ??
} SERVICE, *PSERVICE; } SERVICE, *PSERVICE;
typedef struct _DRIVER_REINIT_ITEM
{
LIST_ENTRY ItemEntry;
PDRIVER_OBJECT DriverObject;
PDRIVER_REINITIALIZE ReinitRoutine;
PVOID Context;
} DRIVER_REINIT_ITEM, *PDRIVER_REINIT_ITEM;
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
static LIST_ENTRY DriverReinitListHead; static LIST_ENTRY DriverReinitListHead;
@ -135,29 +127,47 @@ IopInvalidDeviceRequest(
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
VOID STDCALL VOID
IopDeleteDriver(PVOID ObjectBody) NTAPI
IopDeleteDriver(IN PVOID ObjectBody)
{ {
PDRIVER_OBJECT Object = ObjectBody; PDRIVER_OBJECT DriverObject = ObjectBody;
KIRQL OldIrql; PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
PPRIVATE_DRIVER_EXTENSIONS DriverExtension, NextDriverExtension; PAGED_CODE();
DPRINT("IopDeleteDriver(ObjectBody 0x%p)\n", ObjectBody); /* Get the extension and loop them */
DriverExtension = IoGetDrvObjExtension(DriverObject)->
ClientDriverExtension;
while (DriverExtension)
{
/* Get the next one */
NextDriverExtension = DriverExtension->NextExtension;
ExFreePoolWithTag(DriverExtension, TAG_DRIVER_EXTENSION);
ExFreePool(Object->DriverExtension); /* Move on */
ExFreePool(Object->DriverName.Buffer); DriverExtension = NextDriverExtension;
}
OldIrql = KeRaiseIrqlToDpcLevel(); /* Check if the driver image is still loaded */
if (DriverObject->DriverSection)
{
/* Unload it */
LdrpUnloadImage(DriverObject->DriverSection);
}
for (DriverExtension = Object->DriverSection; /* Check if it has a name */
DriverExtension != NULL; if (DriverObject->DriverName.Buffer)
DriverExtension = NextDriverExtension) {
{ /* Free it */
NextDriverExtension = DriverExtension->Link; ExFreePool(DriverObject->DriverName.Buffer);
ExFreePoolWithTag(DriverExtension, TAG_DRIVER_EXTENSION); }
}
KfLowerIrql(OldIrql); /* Check if it has a service key name */
if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
{
/* Free it */
ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
}
} }
NTSTATUS FASTCALL NTSTATUS FASTCALL
@ -289,22 +299,11 @@ IopCreateDriverObject(
return Status; return Status;
} }
Status = ObInsertObject(Object,
NULL,
FILE_ALL_ACCESS,
0,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Create driver extension */ /* Create driver extension */
Object->DriverExtension = (PDRIVER_EXTENSION) Object->DriverExtension = (PDRIVER_EXTENSION)
ExAllocatePoolWithTag( ExAllocatePoolWithTag(
NonPagedPool, NonPagedPool,
sizeof(DRIVER_EXTENSION), sizeof(EXTENDED_DRIVER_EXTENSION),
TAG_DRIVER_EXTENSION); TAG_DRIVER_EXTENSION);
if (Object->DriverExtension == NULL) if (Object->DriverExtension == NULL)
@ -312,7 +311,7 @@ IopCreateDriverObject(
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION)); RtlZeroMemory(Object->DriverExtension, sizeof(EXTENDED_DRIVER_EXTENSION));
Object->Type = IO_TYPE_DRIVER; Object->Type = IO_TYPE_DRIVER;
@ -337,6 +336,18 @@ IopCreateDriverObject(
ExFreePool(Buffer); ExFreePool(Buffer);
} }
Status = ObInsertObject(Object,
NULL,
FILE_ALL_ACCESS,
0,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
*DriverObject = Object; *DriverObject = Object;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -1730,20 +1741,17 @@ IopReinitializeBootDrivers(VOID)
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
/* /*
* @implemented * @implemented
*/ */
NTSTATUS NTSTATUS
STDCALL NTAPI
IoCreateDriver ( IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
IN PUNICODE_STRING DriverName, OPTIONAL IN PDRIVER_INITIALIZE InitializationFunction)
IN PDRIVER_INITIALIZE InitializationFunction
)
{ {
WCHAR NameBuffer[100]; WCHAR NameBuffer[100];
USHORT NameLength; USHORT NameLength;
UNICODE_STRING LocalDriverName; /* To reduce code if no name given */ UNICODE_STRING LocalDriverName;
NTSTATUS Status; NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
ULONG ObjectSize; ULONG ObjectSize;
@ -1753,22 +1761,22 @@ IoCreateDriver (
ULONG i; ULONG i;
/* First, create a unique name for the driver if we don't have one */ /* First, create a unique name for the driver if we don't have one */
if (!DriverName) { if (!DriverName)
{
/* Create a random name and set up the string*/ /* Create a random name and set up the string*/
NameLength = swprintf(NameBuffer, L"\\Driver\\%08u", KeTickCount); NameLength = swprintf(NameBuffer, L"\\Driver\\%08u", KeTickCount);
LocalDriverName.Length = NameLength * sizeof(WCHAR); LocalDriverName.Length = NameLength * sizeof(WCHAR);
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL); LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
LocalDriverName.Buffer = NameBuffer; LocalDriverName.Buffer = NameBuffer;
}
} else { else
{
/* So we can avoid another code path, use a local var */ /* So we can avoid another code path, use a local var */
LocalDriverName = *DriverName; LocalDriverName = *DriverName;
} }
/* Initialize the Attributes */ /* Initialize the Attributes */
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION); ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&LocalDriverName, &LocalDriverName,
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
@ -1785,8 +1793,6 @@ IoCreateDriver (
0, 0,
0, 0,
(PVOID*)&DriverObject); (PVOID*)&DriverObject);
/* Return on failure */
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Set up the Object */ /* Set up the Object */
@ -1798,22 +1804,41 @@ IoCreateDriver (
DriverObject->DriverExtension->DriverObject = DriverObject; DriverObject->DriverExtension->DriverObject = DriverObject;
DriverObject->DriverInit = InitializationFunction; DriverObject->DriverInit = InitializationFunction;
/* Invalidate all Major Functions */ /* Loop all Major Functions */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{ {
/* Invalidate each function */
DriverObject->MajorFunction[i] = IopInvalidDeviceRequest; DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
} }
/* Set up the Service Key Name */ /* Set up the service key name buffer */
ServiceKeyName.Buffer = ExAllocatePool(PagedPool, LocalDriverName.Length + sizeof(WCHAR)); 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 */
ServiceKeyName.Length = LocalDriverName.Length; ServiceKeyName.Length = LocalDriverName.Length;
ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength; ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength;
RtlMoveMemory(ServiceKeyName.Buffer, LocalDriverName.Buffer, LocalDriverName.Length); RtlMoveMemory(ServiceKeyName.Buffer,
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = L'\0'; LocalDriverName.Buffer,
LocalDriverName.Length);
/* Null-terminate it and set it */
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName; DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
/* Also store it in the Driver Object. This is a bit of a hack. */ /* Also store it in the Driver Object. This is a bit of a hack. */
RtlMoveMemory(&DriverObject->DriverName, &ServiceKeyName, sizeof(UNICODE_STRING)); RtlMoveMemory(&DriverObject->DriverName,
&ServiceKeyName,
sizeof(UNICODE_STRING));
/* Add the Object and get its handle */ /* Add the Object and get its handle */
Status = ObInsertObject(DriverObject, Status = ObInsertObject(DriverObject,
@ -1822,8 +1847,6 @@ IoCreateDriver (
0, 0,
NULL, NULL,
&hDriver); &hDriver);
/* Return on Failure */
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Now reference it */ /* Now reference it */
@ -1833,12 +1856,21 @@ IoCreateDriver (
KernelMode, KernelMode,
(PVOID*)&DriverObject, (PVOID*)&DriverObject,
NULL); NULL);
if (!NT_SUCCESS(Status))
{
/* Fail */
ObMakeTemporaryObject(DriverObject);
ObDereferenceObject(DriverObject);
return Status;
}
/* Close the extra handle */
ZwClose(hDriver); ZwClose(hDriver);
/* Finally, call its init function */ /* Finally, call its init function */
Status = (*InitializationFunction)(DriverObject, NULL); Status = (*InitializationFunction)(DriverObject, NULL);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) { {
/* If it didn't work, then kill the object */ /* If it didn't work, then kill the object */
ObMakeTemporaryObject(DriverObject); ObMakeTemporaryObject(DriverObject);
ObDereferenceObject(DriverObject); ObDereferenceObject(DriverObject);
@ -1852,15 +1884,186 @@ IoCreateDriver (
* @implemented * @implemented
*/ */
VOID VOID
STDCALL NTAPI
IoDeleteDriver ( IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
IN PDRIVER_OBJECT DriverObject
)
{ {
/* Simply derefence the Object */ /* Simply derefence the Object */
ObDereferenceObject(DriverObject); ObDereferenceObject(DriverObject);
} }
/*
* @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 */
KfLowerIrql(OldIrql);
/* 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 */
KfLowerIrql(OldIrql);
/* Return nothing or the extension */
if (!DriverExtensions) return NULL;
return DriverExtensions + 1;
}
/* /*
* NtLoadDriver * NtLoadDriver
@ -1877,7 +2080,6 @@ IoDeleteDriver (
* Status * Status
* implemented * implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
NtLoadDriver(IN PUNICODE_STRING DriverServiceName) NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
{ {
@ -2079,151 +2281,4 @@ NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
return IopUnloadDriver(DriverServiceName, FALSE); return IopUnloadDriver(DriverServiceName, FALSE);
} }
/*
* IoRegisterDriverReinitialization
*
* Status
* @implemented
*/
VOID STDCALL
IoRegisterDriverReinitialization(
PDRIVER_OBJECT DriverObject,
PDRIVER_REINITIALIZE ReinitRoutine,
PVOID Context)
{
PDRIVER_REINIT_ITEM ReinitItem;
ReinitItem = ExAllocatePool(NonPagedPool, sizeof(DRIVER_REINIT_ITEM));
if (ReinitItem == NULL)
return;
ReinitItem->DriverObject = DriverObject;
ReinitItem->ReinitRoutine = ReinitRoutine;
ReinitItem->Context = Context;
DriverObject->Flags |= DRVO_REINIT_REGISTERED;
ExInterlockedInsertTailList(
&DriverReinitListHead,
&ReinitItem->ItemEntry,
&DriverReinitListLock);
}
/*
* @implemented
*/
VOID
STDCALL
IoRegisterBootDriverReinitialization(
IN PDRIVER_OBJECT DriverObject,
IN PDRIVER_REINITIALIZE DriverReinitializationRoutine,
IN PVOID Context
)
{
PDRIVER_REINIT_ITEM ReinitItem;
ReinitItem = ExAllocatePool(NonPagedPool, sizeof(DRIVER_REINIT_ITEM));
if (ReinitItem == NULL)
return;
ReinitItem->DriverObject = DriverObject;
ReinitItem->ReinitRoutine = DriverReinitializationRoutine;
ReinitItem->Context = Context;
DriverObject->Flags |= DRVO_BOOTREINIT_REGISTERED;
ExInterlockedInsertTailList(
&DriverBootReinitListHead,
&ReinitItem->ItemEntry,
&DriverBootReinitListLock);
}
/*
* IoAllocateDriverObjectExtension
*
* Status
* @implemented
*/
NTSTATUS STDCALL
IoAllocateDriverObjectExtension(
PDRIVER_OBJECT DriverObject,
PVOID ClientIdentificationAddress,
ULONG DriverObjectExtensionSize,
PVOID *DriverObjectExtension)
{
KIRQL OldIrql;
PPRIVATE_DRIVER_EXTENSIONS DriverExtensions;
PPRIVATE_DRIVER_EXTENSIONS NewDriverExtension;
NewDriverExtension = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(PRIVATE_DRIVER_EXTENSIONS) - sizeof(CHAR) +
DriverObjectExtensionSize,
TAG_DRIVER_EXTENSION);
if (NewDriverExtension == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
OldIrql = KeRaiseIrqlToDpcLevel();
NewDriverExtension->Link = DriverObject->DriverSection;
NewDriverExtension->ClientIdentificationAddress = ClientIdentificationAddress;
for (DriverExtensions = DriverObject->DriverSection;
DriverExtensions != NULL;
DriverExtensions = DriverExtensions->Link)
{
if (DriverExtensions->ClientIdentificationAddress ==
ClientIdentificationAddress)
{
KfLowerIrql(OldIrql);
return STATUS_OBJECT_NAME_COLLISION;
}
}
DriverObject->DriverSection = NewDriverExtension;
KfLowerIrql(OldIrql);
*DriverObjectExtension = &NewDriverExtension->Extension;
return STATUS_SUCCESS;
}
/*
* IoGetDriverObjectExtension
*
* Status
* @implemented
*/
PVOID STDCALL
IoGetDriverObjectExtension(
PDRIVER_OBJECT DriverObject,
PVOID ClientIdentificationAddress)
{
KIRQL OldIrql;
PPRIVATE_DRIVER_EXTENSIONS DriverExtensions;
OldIrql = KeRaiseIrqlToDpcLevel();
for (DriverExtensions = DriverObject->DriverSection;
DriverExtensions != NULL &&
DriverExtensions->ClientIdentificationAddress !=
ClientIdentificationAddress;
DriverExtensions = DriverExtensions->Link)
;
KfLowerIrql(OldIrql);
if (DriverExtensions == NULL)
return NULL;
return &DriverExtensions->Extension;
}
/* EOF */ /* EOF */