下面来分析函数IoAllocateDriverObjectExtension的实现,这个函数主要实现创建驱动程序扩展内存。
#001 NTSTATUS
#002 NTAPI
#003 IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject,
#004 IN PVOID ClientIdentificationAddress,
#005 IN ULONG DriverObjectExtensionSize,
#006 OUT PVOID *DriverObjectExtension)
#007 {
#008 KIRQL OldIrql;
#009 PIO_CLIENT_EXTENSION DriverExtensions,NewDriverExtension;
#010 BOOLEAN Inserted = FALSE;
#011
首先假定分配扩展驱动程序对象失败。
#012 /* Assume failure */
#013 *DriverObjectExtension = NULL;
#014
为扩展驱动程序对象分配新的内存。
#015 /* Allocate the extension */
#016 NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
#017 sizeof(IO_CLIENT_EXTENSION) +
#018 DriverObjectExtensionSize,
#019 TAG_DRIVER_EXTENSION);
如果分配内存失败,就直接返回。
#020 if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
#021
清空扩展区对象的内存空间。
#022 /* Clear the extension for teh caller */
#023 RtlZeroMemory(NewDriverExtension,
#024 sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
#025
获取DPC级别锁,以便操作扩展对象。
#026 /* Acqure lock */
#027 OldIrql = KeRaiseIrqlToDpcLevel();
#028
填写扩展对象。
#029 /* Fill out the extension */
#030 NewDriverExtension->ClientIdentificationAddress = ClientIdentificationAddress;
#031
查找到当前扩展对象,并判断是否有冲突。
#032 /* Loop the current extensions */
#033 DriverExtensions = IoGetDrvObjExtension(DriverObject)->
#034 ClientDriverExtension;
#035 while (DriverExtensions)
#036 {
#037 /* Check if the identifier matches */
#038 if (DriverExtensions->ClientIdentificationAddress ==
#039 ClientIdentificationAddress)
#040 {
这里发现有冲突的ID,就跳出循环,返回失败。
#041 /* We have a collision,break out */
#042 break;
#043 }
#044
#045 /* Go to the next one */
#046 DriverExtensions = DriverExtensions->NextExtension;
#047 }
#048
如果没有冲突的驱动程序扩展,就创建一个新的扩展。
#049 /* Check if we didn't collide */
#050 if (!DriverExtensions)
#051 {
#052 /* Link this one in */
#053 NewDriverExtension->NextExtension =
#054 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
#055 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
#056 NewDriverExtension;
标记已经插入到扩展。
#057 Inserted = TRUE;
#058 }
#059
#060 /* Release the lock */
#061 KeLowerIrql(OldIrql);
#062
如果没有插入到驱动程序扩展,说明有冲突,因此删除之前分配的内存。
#063 /* Check if insertion Failed */
#064 if (!Inserted)
#065 {
#066 /* Free the entry and fail */
#067 ExFreePool(NewDriverExtension);
#068 return STATUS_OBJECT_NAME_COLLISION;
#069 }
#070
返回驱动程序扩展的开始位置。
#071 /* Otherwise,return the pointer */
#072 *DriverObjectExtension = NewDriverExtension + 1;
#073 return STATUS_SUCCESS;
#074 }
#075
有了驱动程序的扩展,就可以填写用户编写驱动程序保存数据的地方了。比如驱动程序锁、列表、还有驱动程序要访问的IO资源等等。