ReacOS源代码阅读之驱动--IoCreateDevice
来源:互联网 发布:linux怎么看内存大小 编辑:程序博客网 时间:2024/06/06 15:35
IoCreateDevice 是驱动程序创建设备时需要调用的,通过阅读IoCreateDevice函数,可以更好理解设备对象和驱动对象的关系,以及设备对象的各种成员是如何起作用的。
windgb中显示DeviceObject的成员。
kd> dt nt!_device_object +0x000 Type : Int2B +0x002 Size : Uint2B +0x004 ReferenceCount : Int4B +0x008 DriverObject : Ptr32 _DRIVER_OBJECT +0x00c NextDevice : Ptr32 _DEVICE_OBJECT +0x010 AttachedDevice : Ptr32 _DEVICE_OBJECT +0x014 CurrentIrp : Ptr32 _IRP +0x018 Timer : Ptr32 _IO_TIMER +0x01c Flags : Uint4B +0x020 Characteristics : Uint4B +0x024 Vpb : Ptr32 _VPB +0x028 DeviceExtension : Ptr32 Void +0x02c DeviceType : Uint4B +0x030 StackSize : Char +0x034 Queue : __unnamed +0x05c AlignmentRequirement : Uint4B +0x060 DeviceQueue : _KDEVICE_QUEUE +0x074 Dpc : _KDPC +0x094 ActiveThreadCount : Uint4B +0x098 SecurityDescriptor : Ptr32 Void +0x09c DeviceLock : _KEVENT +0x0ac SectorSize : Uint2B +0x0ae Spare1 : Uint2B +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION +0x0b4 Reserved : Ptr32 Void
该函数实现在 E:\Open_Source_Code\ReactOS\ntoskrnl\io\iomgr\device.c (E:\Open_Source_Code\ReactOS 保存ReactOS的源代码根目录)。原函数已经有必要的注释了。
NTSTATUSNTAPIIoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject){ WCHAR AutoNameBuffer[20]; UNICODE_STRING AutoName; PDEVICE_OBJECT CreatedDeviceObject; PDEVOBJ_EXTENSION DeviceObjectExtension; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; ULONG AlignedDeviceExtensionSize; ULONG TotalSize; HANDLE TempHandle; PAGED_CODE(); /* Check if we have to generate a name */ if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME) { /* Generate it 生成一个自动的设备名称 */ swprintf(AutoNameBuffer, L"\\Device\\%08lx", InterlockedIncrementUL(&IopDeviceObjectNumber)); /* Initialize the name */ RtlInitUnicodeString(&AutoName, AutoNameBuffer); DeviceName = &AutoName; } /* Initialize the Object Attributes */ InitializeObjectAttributes(&ObjectAttributes, DeviceName, OBJ_KERNEL_HANDLE, NULL, SePublicOpenUnrestrictedSd); /* Honor exclusive flag */ if (Exclusive) ObjectAttributes.Attributes |= OBJ_EXCLUSIVE; /* Create a permanent object for named devices */ if (DeviceName) ObjectAttributes.Attributes |= OBJ_PERMANENT; /* Align the Extension Size to 8-bytes 8字节对齐*/ AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7; /* Total Size */ TotalSize = AlignedDeviceExtensionSize + sizeof(DEVICE_OBJECT) + sizeof(EXTENDED_DEVOBJ_EXTENSION); /* Create the Device Object */ *DeviceObject = NULL; Status = ObCreateObject(KernelMode, IoDeviceObjectType, &ObjectAttributes, KernelMode, NULL, TotalSize, 0, 0, (PVOID*)&CreatedDeviceObject); if (!NT_SUCCESS(Status)) return Status; /* Clear the whole Object and extension so we don't null stuff manually */ RtlZeroMemory(CreatedDeviceObject, TotalSize); /* * Setup the Type and Size. Note that we don't use the aligned size, * because that's only padding for the DevObjExt and not part of the Object. */ CreatedDeviceObject->Type = IO_TYPE_DEVICE; CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + (USHORT)DeviceExtensionSize; /* The kernel extension is after the driver internal extension */ DeviceObjectExtension = (PDEVOBJ_EXTENSION) ((ULONG_PTR)(CreatedDeviceObject + 1) + AlignedDeviceExtensionSize); /* Set the Type and Size. Question: why is Size 0 on Windows? */ DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION; DeviceObjectExtension->Size = 0; /* Initialize with Power Manager */ PoInitializeDeviceObject(DeviceObjectExtension); /* Link the Object and Extension */ DeviceObjectExtension->DeviceObject = CreatedDeviceObject; CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension; /* Set Device Object Data */ CreatedDeviceObject->DeviceType = DeviceType; CreatedDeviceObject->Characteristics = DeviceCharacteristics; CreatedDeviceObject->DeviceExtension = DeviceExtensionSize ? CreatedDeviceObject + 1 : NULL; CreatedDeviceObject->StackSize = 1; CreatedDeviceObject->AlignmentRequirement = 0; /* Set the Flags */ CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING; if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE; if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME; /* Attach a Vpb for Disks and Tapes, and create the Device Lock */ if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE)) { /* Create Vpb */ Status = IopCreateVpb(CreatedDeviceObject); if (!NT_SUCCESS(Status)) { /* Dereference the device object and fail */ ObDereferenceObject(CreatedDeviceObject); return Status; } /* Initialize Lock Event */ KeInitializeEvent(&CreatedDeviceObject->DeviceLock, SynchronizationEvent, TRUE); } /* Set the right Sector Size */ switch (DeviceType) { /* All disk systems */ case FILE_DEVICE_DISK_FILE_SYSTEM: case FILE_DEVICE_DISK: case FILE_DEVICE_VIRTUAL_DISK: /* The default is 512 bytes */ CreatedDeviceObject->SectorSize = 512; break; /* CD-ROM file systems */ case FILE_DEVICE_CD_ROM_FILE_SYSTEM: /* The default is 2048 bytes */ CreatedDeviceObject->SectorSize = 2048; } /* Create the Device Queue */ if ((CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_FILE_SYSTEM) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) || (CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)) { /* Simple FS Devices, they don't need a real Device Queue */ InitializeListHead(&CreatedDeviceObject->Queue.ListEntry); } else { /* An actual Device, initialize its DQ */ KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue); } /* Insert the Object */ Status = ObInsertObject(CreatedDeviceObject, NULL, FILE_READ_DATA | FILE_WRITE_DATA, 1, (PVOID*)&CreatedDeviceObject, &TempHandle); if (!NT_SUCCESS(Status)) return Status; /* Now do the final linking */ ObReferenceObject(DriverObject); ASSERT((DriverObject->Flags & DRVO_UNLOAD_INVOKED) == 0); CreatedDeviceObject->DriverObject = DriverObject; IopEditDeviceList(DriverObject, CreatedDeviceObject, IopAdd); /* Link with the power manager */ if (CreatedDeviceObject->Vpb) PoVolumeDevice(CreatedDeviceObject); /* Close the temporary handle and return to caller */ ObCloseHandle(TempHandle, KernelMode); *DeviceObject = CreatedDeviceObject; return STATUS_SUCCESS;}
0 0
- ReacOS源代码阅读之驱动--IoCreateDevice
- ReacOS源代码阅读之驱动--atexit实现原理和机制
- ReacOS源代码阅读之进程间通信--SetEvent
- IoCreateDevice
- IoCreateDevice
- IoCreateDevice
- 转:驱动开发函数IoCreateDevice /IoCreateSymbolicLink / IoDeleteDevice
- RtlInitUnicodeString、IoCreateDevice、IoCreateSymbolicLink、IoDeleteDevice 四个 API 驱动函数的使用
- OpenJDK 源代码阅读之 TreeMap
- OpenJDK 源代码阅读之 HashMap
- OpenJDK 源代码阅读之 String
- OpenJDK 源代码阅读之 ArrayList
- OpenJDK 源代码阅读之 LinkedList
- OpenJDK 源代码阅读之 Arrays
- OpenJDK 源代码阅读之 BitSet
- OpenJDK 源代码阅读之 Collections
- OpenJDK 源代码阅读之 TimSort
- JDK源代码阅读之CharSequence
- NOIP2011 提高组 复赛 day1 hotel 选择客栈
- Sqlite3学习笔记
- 非线性单元
- 开发遇坑(一)
- 如何写出好的 JavaScript —— 浅谈 API 设计
- ReacOS源代码阅读之驱动--IoCreateDevice
- 【JZOJ3808】道路值守
- tomcat解析jsp错误
- jQuery-ui datepicker 日历选择器
- bash shell test条件测试[[ ]]和[ ]异同小结
- C++开发工程师课程第一周笔记 GeekBank
- 最短路模板
- SQL注入这个坑
- ECharts地图应用定位