From 17c27b70cdc12e617989894ea3612a43842acf15 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 9 Jul 2006 00:01:31 +0000 Subject: [PATCH] - 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 --- reactos/include/ddk/ntifs.h | 5 - reactos/include/ndk/iotypes.h | 24 +- reactos/ntoskrnl/include/internal/io.h | 18 + reactos/ntoskrnl/include/internal/tag.h | 1 + reactos/ntoskrnl/io/iomgr/driver.c | 499 +++++++++++++----------- 5 files changed, 314 insertions(+), 233 deletions(-) diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 5d92865d254..4ac5b41dc0f 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -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; diff --git a/reactos/include/ndk/iotypes.h b/reactos/include/ndk/iotypes.h index b7b769f67a5..a78a49ce13c 100644 --- a/reactos/include/ndk/iotypes.h +++ b/reactos/include/ndk/iotypes.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 581d8e758c5..8fce2a91a7c 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -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. diff --git a/reactos/ntoskrnl/include/internal/tag.h b/reactos/ntoskrnl/include/internal/tag.h index c1bc278bd12..d7657d295cc 100644 --- a/reactos/ntoskrnl/include/internal/tag.h +++ b/reactos/ntoskrnl/include/internal/tag.h @@ -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') diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index f9c6684c5f0..e7b4d4a0bc8 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -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 */