mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 05:35:06 +00:00
- 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:
parent
2849b81889
commit
17c27b70cd
|
@ -1267,11 +1267,6 @@ typedef struct _GET_RETRIEVAL_DESCRIPTOR {
|
|||
MAPPING_PAIR Pair[1];
|
||||
} 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 {
|
||||
LONG Depth;
|
||||
} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION;
|
||||
|
|
|
@ -684,6 +684,15 @@ typedef struct _IO_TIMER
|
|||
PDEVICE_OBJECT DeviceObject;
|
||||
} 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
|
||||
//
|
||||
|
@ -787,14 +796,17 @@ typedef struct _EXTENDED_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;
|
||||
PVOID ClientIdentificationAddress;
|
||||
CHAR Extension[1];
|
||||
} PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS;
|
||||
struct _DRIVER_OBJECT *DriverObject;
|
||||
PDRIVER_ADD_DEVICE AddDevice;
|
||||
ULONG Count;
|
||||
UNICODE_STRING ServiceKeyName;
|
||||
PIO_CLIENT_EXTENSION ClientDriverExtension;
|
||||
PFS_FILTER_CALLBACKS FsFilterCallbacks;
|
||||
} EXTENDED_DRIVER_EXTENSION, *PEXTENDED_DRIVER_EXTENSION;
|
||||
|
||||
//
|
||||
// Extended I/O Stack Location Structure
|
||||
|
|
|
@ -86,6 +86,13 @@
|
|||
((PEXTENDED_DEVOBJ_EXTENSION) \
|
||||
(DeviceObject->DeviceObjectExtension)) \
|
||||
|
||||
//
|
||||
// Returns the internal Driver Object Extension
|
||||
//
|
||||
#define IoGetDrvObjExtension(DriverObject) \
|
||||
((PEXTENDED_DRIVER_EXTENSION) \
|
||||
(DriverObject->DriverExtension)) \
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeSetFlag(
|
||||
|
@ -352,6 +359,17 @@ typedef struct _FS_CHANGE_NOTIFY_ENTRY
|
|||
PDRIVER_FS_NOTIFICATION FSDNotificationProc;
|
||||
} 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
|
||||
// node tree.
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#define TAG_ERROR_LOG TAG('I', 'o', 'E', 'r')
|
||||
#define TAG_EA TAG('I', 'o', 'E', 'a')
|
||||
#define TAG_IO_NAME TAG('I', 'o', 'N', 'm')
|
||||
#define TAG_REINIT TAG('I', 'o', 'R', 'i')
|
||||
|
||||
/* formerly located in io/work.c */
|
||||
#define TAG_IOWI TAG('I', 'O', 'W', 'I')
|
||||
|
|
|
@ -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
|
||||
* PURPOSE: Loading and unloading of drivers
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
||||
* Filip Navara (xnavara@volny.cz)
|
||||
* PURPOSE: Driver Object Management
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Filip Navara (navaraf@reactos.org)
|
||||
* Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
@ -43,14 +43,6 @@ typedef struct _SERVICE
|
|||
/* BOOLEAN ServiceRunning;*/ // needed ??
|
||||
} 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 ********************************************************************/
|
||||
|
||||
static LIST_ENTRY DriverReinitListHead;
|
||||
|
@ -135,29 +127,47 @@ IopInvalidDeviceRequest(
|
|||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
IopDeleteDriver(PVOID ObjectBody)
|
||||
VOID
|
||||
NTAPI
|
||||
IopDeleteDriver(IN PVOID ObjectBody)
|
||||
{
|
||||
PDRIVER_OBJECT Object = ObjectBody;
|
||||
KIRQL OldIrql;
|
||||
PPRIVATE_DRIVER_EXTENSIONS DriverExtension, NextDriverExtension;
|
||||
PDRIVER_OBJECT DriverObject = ObjectBody;
|
||||
PIO_CLIENT_EXTENSION 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);
|
||||
ExFreePool(Object->DriverName.Buffer);
|
||||
/* Move on */
|
||||
DriverExtension = NextDriverExtension;
|
||||
}
|
||||
|
||||
OldIrql = KeRaiseIrqlToDpcLevel();
|
||||
/* Check if the driver image is still loaded */
|
||||
if (DriverObject->DriverSection)
|
||||
{
|
||||
/* Unload it */
|
||||
LdrpUnloadImage(DriverObject->DriverSection);
|
||||
}
|
||||
|
||||
for (DriverExtension = Object->DriverSection;
|
||||
DriverExtension != NULL;
|
||||
DriverExtension = NextDriverExtension)
|
||||
{
|
||||
NextDriverExtension = DriverExtension->Link;
|
||||
ExFreePoolWithTag(DriverExtension, TAG_DRIVER_EXTENSION);
|
||||
}
|
||||
/* Check if it has a name */
|
||||
if (DriverObject->DriverName.Buffer)
|
||||
{
|
||||
/* Free it */
|
||||
ExFreePool(DriverObject->DriverName.Buffer);
|
||||
}
|
||||
|
||||
KfLowerIrql(OldIrql);
|
||||
/* Check if it has a service key name */
|
||||
if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
|
||||
{
|
||||
/* Free it */
|
||||
ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
|
@ -289,22 +299,11 @@ IopCreateDriverObject(
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ObInsertObject(Object,
|
||||
NULL,
|
||||
FILE_ALL_ACCESS,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create driver extension */
|
||||
Object->DriverExtension = (PDRIVER_EXTENSION)
|
||||
ExAllocatePoolWithTag(
|
||||
NonPagedPool,
|
||||
sizeof(DRIVER_EXTENSION),
|
||||
sizeof(EXTENDED_DRIVER_EXTENSION),
|
||||
TAG_DRIVER_EXTENSION);
|
||||
|
||||
if (Object->DriverExtension == NULL)
|
||||
|
@ -312,7 +311,7 @@ IopCreateDriverObject(
|
|||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
|
||||
RtlZeroMemory(Object->DriverExtension, sizeof(EXTENDED_DRIVER_EXTENSION));
|
||||
|
||||
Object->Type = IO_TYPE_DRIVER;
|
||||
|
||||
|
@ -337,6 +336,18 @@ IopCreateDriverObject(
|
|||
ExFreePool(Buffer);
|
||||
}
|
||||
|
||||
|
||||
Status = ObInsertObject(Object,
|
||||
NULL,
|
||||
FILE_ALL_ACCESS,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
*DriverObject = Object;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -1730,20 +1741,17 @@ IopReinitializeBootDrivers(VOID)
|
|||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IoCreateDriver (
|
||||
IN PUNICODE_STRING DriverName, OPTIONAL
|
||||
IN PDRIVER_INITIALIZE InitializationFunction
|
||||
)
|
||||
NTAPI
|
||||
IoCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
|
||||
IN PDRIVER_INITIALIZE InitializationFunction)
|
||||
{
|
||||
WCHAR NameBuffer[100];
|
||||
USHORT NameLength;
|
||||
UNICODE_STRING LocalDriverName; /* To reduce code if no name given */
|
||||
UNICODE_STRING LocalDriverName;
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
ULONG ObjectSize;
|
||||
|
@ -1753,22 +1761,22 @@ IoCreateDriver (
|
|||
ULONG i;
|
||||
|
||||
/* 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*/
|
||||
NameLength = swprintf(NameBuffer, L"\\Driver\\%08u", KeTickCount);
|
||||
LocalDriverName.Length = NameLength * sizeof(WCHAR);
|
||||
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
|
||||
LocalDriverName.Buffer = NameBuffer;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* So we can avoid another code path, use a local var */
|
||||
LocalDriverName = *DriverName;
|
||||
}
|
||||
|
||||
/* Initialize the Attributes */
|
||||
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION);
|
||||
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&LocalDriverName,
|
||||
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
||||
|
@ -1785,8 +1793,6 @@ IoCreateDriver (
|
|||
0,
|
||||
0,
|
||||
(PVOID*)&DriverObject);
|
||||
|
||||
/* Return on failure */
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Set up the Object */
|
||||
|
@ -1798,22 +1804,41 @@ IoCreateDriver (
|
|||
DriverObject->DriverExtension->DriverObject = DriverObject;
|
||||
DriverObject->DriverInit = InitializationFunction;
|
||||
|
||||
/* Invalidate all Major Functions */
|
||||
/* Loop all Major Functions */
|
||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||
{
|
||||
/* Invalidate each function */
|
||||
DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
|
||||
}
|
||||
|
||||
/* Set up the Service Key Name */
|
||||
ServiceKeyName.Buffer = ExAllocatePool(PagedPool, LocalDriverName.Length + sizeof(WCHAR));
|
||||
/* 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 */
|
||||
ServiceKeyName.Length = LocalDriverName.Length;
|
||||
ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength;
|
||||
RtlMoveMemory(ServiceKeyName.Buffer, LocalDriverName.Buffer, LocalDriverName.Length);
|
||||
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = L'\0';
|
||||
RtlMoveMemory(ServiceKeyName.Buffer,
|
||||
LocalDriverName.Buffer,
|
||||
LocalDriverName.Length);
|
||||
|
||||
/* Null-terminate it and set it */
|
||||
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
|
||||
|
||||
/* 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 */
|
||||
Status = ObInsertObject(DriverObject,
|
||||
|
@ -1822,8 +1847,6 @@ IoCreateDriver (
|
|||
0,
|
||||
NULL,
|
||||
&hDriver);
|
||||
|
||||
/* Return on Failure */
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Now reference it */
|
||||
|
@ -1833,12 +1856,21 @@ IoCreateDriver (
|
|||
KernelMode,
|
||||
(PVOID*)&DriverObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Fail */
|
||||
ObMakeTemporaryObject(DriverObject);
|
||||
ObDereferenceObject(DriverObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close the extra handle */
|
||||
ZwClose(hDriver);
|
||||
|
||||
/* Finally, call its init function */
|
||||
Status = (*InitializationFunction)(DriverObject, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* If it didn't work, then kill the object */
|
||||
ObMakeTemporaryObject(DriverObject);
|
||||
ObDereferenceObject(DriverObject);
|
||||
|
@ -1852,15 +1884,186 @@ IoCreateDriver (
|
|||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
IoDeleteDriver (
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
)
|
||||
NTAPI
|
||||
IoDeleteDriver(IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
/* Simply derefence the Object */
|
||||
/* Simply derefence the Object */
|
||||
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
|
||||
|
@ -1877,7 +2080,6 @@ IoDeleteDriver (
|
|||
* Status
|
||||
* implemented
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
|
||||
{
|
||||
|
@ -2079,151 +2281,4 @@ NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
|
|||
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 */
|
||||
|
|
Loading…
Reference in a new issue