Windows内核编程基础篇之常见内核数据结构

青旅半醒 2022-08-04 12:59 304阅读 0赞

1,驱动框架常见数据结构有 驱动对象结构, 设备对象结构等。

A)驱动对象结构 (DRIVER_OBJECT)

每个驱动对象代表一个已加载的内核驱动程序,指向驱动对象结构的指针常常作为DriverEntry,AddDevice,Unload等函数的参数。驱动对象结构式半透明的。其中公开的域包括DeviceObject,DriverExtension,HardwareDatabase ,FastIoDispath,DriverInit,DriverStartIo,DriverUnload以及MajorFunction。

驱动对象的数据结构如下:

  1. typedef struct _DRIVER_OBJECT {
  2.   CSHORT Type;
  3.   CSHORT Size;
  4. //
  5.   // The following links all of the devices created by a single driver
  6.   // together on a list, and the Flags word provides an extensible flag
  7.   // location for driver objects.
  8.   //
  9. PDEVICE_OBJECT DeviceObject;
  10.   ULONG Flags;
  11. //
  12.   // The following section describes where the driver is loaded. The count
  13.   // field is used to count the number of times the driver has had its
  14.   // registered reinitialization routine invoked.
  15.   //
  16. PVOID DriverStart;
  17.   ULONG DriverSize;
  18.   PVOID DriverSection;
  19.   PDRIVER_EXTENSION DriverExtension;
  20. //
  21.   // The driver name field is used by the error log thread
  22.   // determine the name of the driver that an I/O request is/was bound.
  23.   //
  24. UNICODE_STRING DriverName;
  25. //
  26.   // The following section is for registry support. Thise is a pointer
  27.   // to the path to the hardware information in the registry
  28.   //
  29. PUNICODE_STRING HardwareDatabase;
  30. //
  31.   // The following section contains the optional pointer to an array of
  32.   // alternate entry points to a driver for "fast I/O" support. Fast I/O
  33.   // is performed by invoking the driver routine directly with separate
  34.   // parameters, rather than using the standard IRP call mechanism. Note
  35.   // that these functions may only be used for synchronous I/O, and when
  36.   // the file is cached.
  37.   //
  38. PFAST_IO_DISPATCH FastIoDispatch;
  39. //
  40.   // The following section describes the entry points to this particular
  41.   // driver. Note that the major function dispatch table must be the last
  42.   // field in the object so that it remains extensible.
  43.   //
  44. PDRIVER_INITIALIZE DriverInit;
  45.   PDRIVER_STARTIO DriverStartIo;
  46.   PDRIVER_UNLOAD DriverUnload;
  47.   PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
  48. } DRIVER_OBJECT;
  49.   typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; // ntndis

其中DeviceObject域指向由此驱动创建的设备对象:FastIoDispath域指向快速I/O 入口。DriverInit指向驱动入口点地址(DriverEntry):DriverUnload 指向驱动卸载程序:MajorFunction 是一张函数分发表,数组的所引致与IRP_MJ_Xxx相对应。

自己重新对上面的结构体认识了下,省略了部分,主要了解下面的:

  1. typedef struct _DRIVER_OBJECT{
  2. //结构的类型和大小
  3. CSHORT Type;
  4. CSHORT Size;
  5. //设备对象,这里实际上是一个设备对象的链表的开始。因为 DeviceObject 中有相关链表信息。
  6. PDEVICE_OBJECT DeviceObject;
  7. •••
  8. //这个内核模块在内核空间中的开始地址和大小
  9. PVOID DriverStart;
  10. ULONG DriverSize;
  11. •••
  12. //驱动的名字
  13. UNICODE_STRING DriverName;
  14. •••
  15. //快速IO分发函数
  16. PFAST_IO_DISPATCH FastIoDispatch;
  17. •••
  18. //驱动的卸载函数
  19. PDRIVER_UNLOAD.DriverUnload;
  20. //普通分发函数
  21. PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
  22. }DRIVER_OBJECT;

这样看起来是不是 少了很多呢, 上面做了注释的是 主要需要了解的。

-———————————————————————————————————————————————————

B)设备驱动程序(DEVICE_OBJECT)

系统使用设备对象来描述一个设备对象,数据结构如下:

  1. typedef struct _DEVICE_OBJECT {
  2. CSHORT Type;
  3. USHORT Size;
  4. LONG ReferenceCount;
  5. struct _DRIVER_OBJECT *DriverObject;
  6. struct _DEVICE_OBJECT *NextDevice;
  7. struct _DEVICE_OBJECT *AttachedDevice;
  8. struct _IRP *CurrentIrp;
  9. PIO_TIMER Timer;
  10. ULONG Flags;
  11. ULONG Characteristics;
  12. __volatile PVPB Vpb;
  13. PVOID DeviceExtension;
  14. DEVICE_TYPE DeviceType;
  15. CCHAR StackSize;
  16. union {
  17. LIST_ENTRY ListEntry;
  18. WAIT_CONTEXT_BLOCK Wcb;
  19. } Queue;
  20. ULONG AlignmentRequirement;
  21. KDEVICE_QUEUE DeviceQueue;
  22. KDPC Dpc;
  23. ULONG ActiveThreadCount;
  24. PSECURITY_DESCRIPTOR SecurityDescriptor;
  25. KEVENT DeviceLock;
  26. USHORT SectorSize;
  27. USHORT Spare1;
  28. struct _DEVOBJ_EXTENSION * DeviceObjectExtension;
  29. PVOID Reserved;
  30. } DEVICE_OBJECT, *PDEVICE_OBJECT;

其中,DriverObject 域指向创建次设备对象的驱动程序对象:NextDevice 域指向一个驱动程序创建的下一个设备对象:AttachedDevice 域指向绑定到此设备对象上的设备对象;Flags域指定了设备对象的标记,如该谁被是缓冲读写方式(DO_BUFFERED_IO)还是直接读写方式(DO_DIRECT_IO);Vpb 域指向此设备对象相关的卷参数块;DeviceExtension 域指向设备扩展,设备扩展中的内容由程序设计者自定义,往往用来记录域设备相关的一些信息。

这个结构体也很复杂,我自己总结了下,如下:

  1. typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
  2. _DEVICE_OBJECT{
  3. //结构的类型和大小
  4. CSHORT Type;
  5. CSHORT Size;
  6. //引用计数
  7. ULONG ReferenceCount;
  8. //这个设备所属的驱动对象
  9. struct _DRIVER_OBJECT *DriverObject;
  10. //下一个设备对象,在一个驱动对象中有N个设备,这些设备用这个指针连接起来作为一个单向的链表
  11. struct _DRIVER_OBJECT *NextDevice;
  12. //设备类型
  13. DEVICE_TYPE DeviceType;
  14. •••
  15. //IRP栈大小
  16. HAR StackSize;
  17. ••••••
  18. }DEVICE_OBJECT;

这样一来,就清晰很多啦 微笑

-—————————————————————————————————————————————————————————————-

2,进程域线程数据结构

A)执行体进程块(EXPROCESS)

执行体进程块是一个不透明的数据结构,用来描述一个进程对象。驱动程序可以用PsGetCurrentProcess函数获取指向当前进程的执行体进程进程块指针。

由于其数据结构不是透明的,想了好多办法,还是找到了啦:

  1. typedef struct _EPROCESS
  2. {
  3. KPROCESS Pcb;
  4. EX_PUSH_LOCK ProcessLock;
  5. LARGE_INTEGER CreateTime;
  6. LARGE_INTEGER ExitTime;
  7. EX_RUNDOWN_REF RundownProtect;
  8. HANDLE UniqueProcessId;
  9. LIST_ENTRY ActiveProcessLinks;
  10. SIZE_T QuotaUsage[PsQuotaTypes];
  11. SIZE_T QuotaPeak[PsQuotaTypes];
  12. SIZE_T CommitCharge;
  13. SIZE_T PeakVirtualSize;
  14. SIZE_T VirtualSize;
  15. LIST_ENTRY SessionProcessLinks;
  16. PVOID DebugPort;
  17. PVOID ExceptionPort;
  18. PHANDLE_TABLE ObjectTable;
  19. EX_FAST_REF Token;
  20. PFN_NUMBER WorkingSetPage;
  21. KGUARDED_MUTEX AddressCreationLock;
  22. KSPIN_LOCK HyperSpaceLock;
  23. struct _ETHREAD *ForkInProgress;
  24. ULONG_PTR HardwareTrigger;
  25. PMM_AVL_TABLE PhysicalVadRoot;
  26. PVOID CloneRoot;
  27. PFN_NUMBER NumberOfPrivatePages;
  28. PFN_NUMBER NumberOfLockedPages;
  29. PVOID Win32Process;
  30. struct _EJOB *Job;
  31. PVOID SectionObject;
  32. PVOID SectionBaseAddress;
  33. PEPROCESS_QUOTA_BLOCK QuotaBlock;
  34. PPAGEFAULT_HISTORY WorkingSetWatch;
  35. HANDLE Win32WindowStation;
  36. HANDLE InheritedFromUniqueProcessId;
  37. PVOID LdtInformation;
  38. PVOID VadFreeHint;
  39. PVOID VdmObjects;
  40. PVOID DeviceMap;
  41. PVOID Spare0[3];
  42. union
  43. {
  44. HARDWARE_PTE PageDirectoryPte;
  45. ULONGLONG Filler;
  46. };
  47. PVOID Session;
  48. UCHAR ImageFileName[ 16 ];
  49. LIST_ENTRY JobLinks;
  50. PVOID LockedPagesList;
  51. LIST_ENTRY ThreadListHead;
  52. PVOID SecurityPort;
  53. PVOID PaeTop;
  54. ULONG ActiveThreads;
  55. ACCESS_MASK GrantedAccess;
  56. ULONG DefaultHardErrorProcessing;
  57. NTSTATUS LastThreadExitStatus;
  58. PPEB Peb;
  59. EX_FAST_REF PrefetchTrace;
  60. LARGE_INTEGER ReadOperationCount;
  61. LARGE_INTEGER WriteOperationCount;
  62. LARGE_INTEGER OtherOperationCount;
  63. LARGE_INTEGER ReadTransferCount;
  64. LARGE_INTEGER WriteTransferCount;
  65. LARGE_INTEGER OtherTransferCount;
  66. SIZE_T CommitChargeLimit;
  67. SIZE_T CommitChargePeak;
  68. PVOID AweInfo;
  69. SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;
  70. MMSUPPORT Vm;
  71. LIST_ENTRY MmProcessLinks;
  72. ULONG ModifiedPageCount;
  73. ULONG JobStatus;
  74. union
  75. {
  76. ULONG Flags;
  77. struct {
  78. ULONG CreateReported : 1;
  79. ULONG NoDebugInherit : 1;
  80. ULONG ProcessExiting : 1;
  81. ULONG ProcessDelete : 1;
  82. ULONG Wow64SplitPages : 1;
  83. ULONG VmDeleted : 1;
  84. ULONG OutswapEnabled : 1;
  85. ULONG Outswapped : 1;
  86. ULONG ForkFailed : 1;
  87. ULONG Wow64VaSpace4Gb : 1;
  88. ULONG AddressSpaceInitialized : 2;
  89. ULONG SetTimerResolution : 1;
  90. ULONG BreakOnTermination : 1;
  91. ULONG SessionCreationUnderway : 1;
  92. ULONG WriteWatch : 1;
  93. ULONG ProcessInSession : 1;
  94. ULONG OverrideAddressSpace : 1;
  95. ULONG HasAddressSpace : 1;
  96. ULONG LaunchPrefetched : 1;
  97. ULONG InjectInpageErrors : 1;
  98. ULONG VmTopDown : 1;
  99. ULONG ImageNotifyDone : 1;
  100. ULONG PdeUpdateNeeded : 1; // NT32 only
  101. ULONG VdmAllowed : 1;
  102. ULONG SmapAllowed : 1;
  103. ULONG CreateFailed : 1;
  104. ULONG DefaultIoPriority : 3;
  105. ULONG Spare1 : 1;
  106. ULONG Spare2 : 1;
  107. };
  108. };
  109. NTSTATUS ExitStatus;
  110. USHORT NextPageColor;
  111. union
  112. {
  113. struct
  114. {
  115. UCHAR SubSystemMinorVersion;
  116. UCHAR SubSystemMajorVersion;
  117. };
  118. USHORT SubSystemVersion;
  119. };
  120. UCHAR PriorityClass;
  121. MM_AVL_TABLE VadRoot;
  122. ULONG Cookie;
  123. } EPROCESS, *PEPROCESS;

又是一大堆这么多复杂的代码。 这里 有详情解释。

B)内核进程块(KPROCESS)

执行进程块的第一个域Pcb描述了内核进程块,

  1. typedef struct _KPROCESS
  2. {
  3. DISPATCHER_HEADER Header;
  4. LIST_ENTRY ProfileListHead;
  5. ULONG DirectoryTableBase;
  6. ULONG Unused0;
  7. KGDTENTRY LdtDescriptor;
  8. KIDTENTRY Int21Descriptor;
  9. WORD IopmOffset;
  10. UCHAR Iopl;
  11. UCHAR Unused;
  12. ULONG ActiveProcessors;
  13. ULONG KernelTime;
  14. ULONG UserTime;
  15. LIST_ENTRY ReadyListHead;
  16. SINGLE_LIST_ENTRY SwapListEntry;
  17. PVOID VdmTrapcHandler;
  18. LIST_ENTRY ThreadListHead;
  19. ULONG ProcessLock;
  20. ULONG Affinity;
  21. union
  22. {
  23. ULONG AutoAlignment: 1;
  24. ULONG DisableBoost: 1;
  25. ULONG DisableQuantum: 1;
  26. ULONG ReservedFlags: 29;
  27. LONG ProcessFlags;
  28. };
  29. CHAR BasePriority;
  30. CHAR QuantumReset;
  31. UCHAR State;
  32. UCHAR ThreadSeed;
  33. UCHAR PowerState;
  34. UCHAR IdealNode;
  35. UCHAR Visited;
  36. union
  37. {
  38. KEXECUTE_OPTIONS Flags;
  39. UCHAR ExecuteOptions;
  40. };
  41. ULONG StackCount;
  42. LIST_ENTRY ProcessListEntry;
  43. UINT64 CycleTime;
  44. } KPROCESS, *PKPROCESS;

内核进程快主要是记录和处理器调度相关的一些信息。

C)执行体进程块(ETHREAD)

Executive Thread block( ETHREAD)与 EPROCESS 结构的情形类似,用来描述 thread 的相关信息的结构:
ETHREAD
KTHREAD
W32THREAD
Executive thread block(ETHREAD)应用在 executive 层,Kernel thread block(KTHREAD)应用在 kernel 层,它们都是在系统空间里,实际上 KTHREAD 结构是 ETHREAD 结构的一个子结构。
W32THREAD 结构由 windows subsystem 的 kernel 部分 Win32k.sys 来维护,同样是在系统空间里,Csrss.exe(windows subsystem process)是 windows subsystem 的 user-mode 组件,windows subsystem 组件为每个 thread 维护着 W32THREAD 结构。

另一个 thread 相关的结构是 Thread Environment Block(TEB)结构,它存在于用户进程空间。

D)内核线程块(KTHREAD)

执行进程结构的第一个域是Tcb描述了内核线程块,该模块也是不透明的。结构如下:

  1. kd> dt -r _kthread
  2. nt!_KTHREAD
  3. +0x000 Header : _DISPATCHER_HEADER
  4. +0x000 Type : UChar
  5. +0x001 Absolute : UChar
  6. +0x002 Size : UChar
  7. +0x003 Inserted : UChar
  8. +0x004 SignalState : Int4B
  9. +0x008 WaitListHead : _LIST_ENTRY
  10. +0x000 Flink : Ptr32 _LIST_ENTRY
  11. +0x004 Blink : Ptr32 _LIST_ENTRY
  12. +0x010 MutantListHead : _LIST_ENTRY
  13. +0x000 Flink : Ptr32 _LIST_ENTRY
  14. +0x000 Flink : Ptr32 _LIST_ENTRY
  15. +0x004 Blink : Ptr32 _LIST_ENTRY
  16. +0x004 Blink : Ptr32 _LIST_ENTRY
  17. +0x000 Flink : Ptr32 _LIST_ENTRY
  18. +0x004 Blink : Ptr32 _LIST_ENTRY
  19. +0x018 InitialStack : Ptr32 Void
  20. +0x01c StackLimit : Ptr32 Void
  21. +0x020 Teb : Ptr32 Void
  22. +0x024 TlsArray : Ptr32 Void
  23. +0x028 KernelStack : Ptr32 Void
  24. +0x02c DebugActive : UChar
  25. +0x02d State : UChar
  26. +0x02e Alerted : [2] UChar
  27. +0x030 Iopl : UChar
  28. +0x031 NpxState : UChar
  29. +0x032 Saturation : Char
  30. +0x033 Priority : Char
  31. +0x034 ApcState : _KAPC_STATE
  32. +0x000 ApcListHead : [2] _LIST_ENTRY
  33. +0x000 Flink : Ptr32 _LIST_ENTRY
  34. +0x004 Blink : Ptr32 _LIST_ENTRY
  35. +0x010 Process : Ptr32 _KPROCESS

其实Header 域保存了一个分发器头,表明线程对象(ETHREAD结构)也是基于分发器头的同步对象:InitialStack和StackLimit分别记录线程栈基址和栈边界地址;Teb保存了一个指向线程环境块的指针。

3 ,存储系统数据结构

A)参数模块(VPB)

详细如下:

  1. 1: kd> ?? fastfat!FatData
  2. struct _FAT_DATA
  3. +0x000 NodeTypeCode : 0x500
  4. +0x002 NodeByteSize : 304
  5. +0x008 LazyWriteThread : 0xfffffa80`037151a0
  6. +0x010 VcbQueue : _LIST_ENTRY [ 0xfffffa80`0384fa18 0xfffffa80`0384fa18 ]
  7. ……
  8. 1: kd> !list "-t nt!_LIST_ENTRY.Flink -e -x \"dd @$extret l4; dt fastfat!_VCB @$extret-0x58\" 0xfffffa80`0384fa18"
  9. dd @$extret l4; dt fastfat!_VCB @$extret-0x58
  10. fffffa80`0384fa18 070e34d0 fffff880 070e34d0 fffff880
  11. +0x000 VolumeFileHeader : _FSRTL_ADVANCED_FCB_HEADER
  12. +0x058 VcbLinks : _LIST_ENTRY [ 0xfffff880`070e34d0 – 0xfffff880`070e34d0 ]
  13. +0x068 TargetDeviceObject : 0xfffffa80`053c7040 _DEVICE_OBJECT
  14. +0x070 Vpb : 0xfffffa80`05b54a00 _VPB
  15. +0x078 VcbState : 0x101002
  16. +0x07c VcbCondition : 1 ( VcbGood )
  17. ……
  18. +0x410 SwapVpb : 0xfffffa80`056f19e0 _VPB
  19. +0x418 AsyncCloseList : _LIST_ENTRY [ 0xfffffa80`0384fdd8 – 0xfffffa80`0384fdd8 ]
  20. +0x428 DelayedCloseList : _LIST_ENTRY [ 0xfffff8a0`170d3880 – 0xfffff8a0`170d3880 ]
  21. +0x438 AdvancedFcbHeaderMutex : _FAST_MUTEX
  22. +0x470 CloseContext : 0xfffff8a0`0af0eef0 CLOSE_CONTEXT
  23. +0x478 CloseContextCount : 2
  24. 1: kd> dt _VPB 0xfffffa80`05b54a00
  25. nt!_VPB
  26. +0x000 Type : 10
  27. +0x002 Size : 96
  28. +0x004 Flags : 1
  29. +0x006 VolumeLabelLength : 0x10
  30. +0x008 DeviceObject : 0xfffffa80`0384f820 _DEVICE_OBJECT
  31. +0x010 RealDevice : 0xfffffa80`05bab060 _DEVICE_OBJECT
  32. +0x018 SerialNumber : 0x51e712c6
  33. +0x01c ReferenceCount : 9
  34. +0x020 VolumeLabel : [32] "CANON_DC"
  35. 1: kd> dt _VPB 0xfffffa80`056f19e0
  36. nt!_VPB
  37. +0x000 Type : 0
  38. +0x002 Size : 0
  39. +0x004 Flags : 0
  40. +0x006 VolumeLabelLength : 0
  41. +0x008 DeviceObject : (null)
  42. +0x010 RealDevice : (null)
  43. +0x018 SerialNumber : 0
  44. +0x01c ReferenceCount : 0
  45. +0x020 VolumeLabel : [32] ""
  46. 1: kd> !devobj 0xfffffa80`05bab060
  47. Device object (fffffa8005bab060) is for:
  48. HarddiskVolume18 \Driver\volmgr DriverObject fffffa8004086e70
  49. Current Irp 00000000 RefCount 9 Type 00000007 Flags 00003050
  50. Vpb fffffa8005b54a00 Dacl fffff9a1171d06c0 DevExt fffffa8005bab1b0 DevObjExt fffffa8005bab318 Dope fffffa8004fa7fa0 DevNode fffffa80055d9d90
  51. ExtensionFlags (0000000000)
  52. AttachedDevice (Upper) fffffa8005b4a040 \Driver\fvevol
  53. Device queue is not busy.
  54. 1: kd> dt _DEVICE_OBJECT 0xfffffa80`05bab060
  55. nt!_DEVICE_OBJECT
  56. +0x000 Type : 3
  57. +0x002 Size : 0x2b8
  58. +0x004 ReferenceCount : 9
  59. +0x008 DriverObject : 0xfffffa80`04086e70 _DRIVER_OBJECT
  60. +0x010 NextDevice : 0xfffffa80`045ed440 _DEVICE_OBJECT
  61. +0x018 AttachedDevice : 0xfffffa80`05b4a040 _DEVICE_OBJECT
  62. +0x020 CurrentIrp : (null)
  63. +0x028 Timer : (null)
  64. +0x030 Flags : 0x3050
  65. +0x034 Characteristics : 1
  66. +0x038 Vpb : 0xfffffa80`05b54a00 _VPB
  67. +0x040 DeviceExtension : 0xfffffa80`05bab1b0
  68. +0x048 DeviceType : 7
  69. +0x04c StackSize : 9 ”
  70. +0x050 Queue : <unnamed-tag>
  71. +0x098 AlignmentRequirement : 0
  72. +0x0a0 DeviceQueue : _KDEVICE_QUEUE
  73. +0x0c8 Dpc : _KDPC
  74. +0x108 ActiveThreadCount : 0
  75. +0x110 SecurityDescriptor : 0xfffff8a0`170b0620
  76. +0x118 DeviceLock : _KEVENT
  77. +0x130 SectorSize : 0x200
  78. +0x132 Spare1 : 1
  79. +0x138 DeviceObjectExtension : 0xfffffa80`05bab318 _DEVOBJ_EXTENSION
  80. +0x140 Reserved : (null)

又是一板的代码、、 唉。。 这个就不细说啦。 这哥们总结的非常好!

B) 文件对象(File_Object)

文件对象就是一个文件,设备,目录等对象的打开实例。在任何时候,针对一个共享文件可以有多个文件对象,即共享文件可以被多次打开,但是每一个文件对象只对应一个句柄。文件对象的数据结构如下所示:

  1. typedef struct _FILE_OBJECT {
  2. CSHORT Type;
  3. CSHORT Size;
  4. PDEVICE_OBJECT DeviceObject;
  5. PVPB Vpb;
  6. PVOID FsContext;
  7. PVOID FsContext2;
  8. PSECTION_OBJECT_POINTERS SectionObjectPointer;
  9. PVOID PrivateCacheMap;
  10. NTSTATUS FinalStatus;
  11. struct _FILE_OBJECT *RelatedFileObject;
  12. BOOLEAN LockOperation;
  13. BOOLEAN DeletePending;
  14. BOOLEAN ReadAccess;
  15. BOOLEAN WriteAccess;
  16. BOOLEAN DeleteAccess;
  17. BOOLEAN SharedRead;
  18. BOOLEAN SharedWrite;
  19. BOOLEAN SharedDelete;
  20. ULONG Flags;
  21. UNICODE_STRING FileName;
  22. LARGE_INTEGER CurrentByteOffset;
  23. __volatile ULONG Waiters;
  24. __volatile ULONG Busy;
  25. PVOID LastLock;
  26. KEVENT Lock;
  27. KEVENT Event;
  28. __volatile PIO_COMPLETION_CONTEXT CompletionContext;
  29. KSPIN_LOCK IrpListLock;
  30. LIST_ENTRY IrpList;
  31. __volatile PVOID FileObjectExtension;
  32. } FILE_OBJECT, *PFILE_OBJECT;

其中, DeviceObject域记录域所打开文件相关联的设备。Vpb记录参数块; FsContext及 FsContext2域是自定义指针; SectionObjectPointer 是一个内存区对象指针,指向数据控制区域或者映像控制区域; FileName记录文件名。

C) SCSI请求块(SRB)

SCSI请求块结构用来在存储类驱动和存储端口驱动间传输I/O请求。然后端口驱动再将SRB转发给小端口驱动。SRB的结构如下:

  1. typedef struct _SCSI_REQUEST_BLOCK {
  2. USHORT Length;
  3. UCHAR Function;
  4. UCHAR SrbStatus;
  5. UCHAR ScsiStatus;
  6. UCHAR PathId;
  7. UCHAR TargetId;
  8. UCHAR Lun;
  9. UCHAR QueueTag;
  10. UCHAR QueueAction;
  11. UCHAR CdbLength;
  12. UCHAR SenseInfoBufferLength;
  13. ULONG SrbFlags;
  14. ULONG DataTransferLength;
  15. ULONG TimeOutValue;
  16. PVOID DataBuffer;
  17. PVOID SenseInfoBuffer;
  18. struct _SCSI_REQUEST_BLOCK *NextSrb;
  19. PVOID OriginalRequest;
  20. PVOID SrbExtension;
  21. union {
  22. ULONG InternalStatus;
  23. ULONG QueueSortKey;
  24. ULONG LinkTimeoutValue;
  25. };
  26. #ifdef _WIN64
  27. ULONG Reserved;
  28. #endif
  29. UCHAR Cdb[16];
  30. } SCSI_REQUEST_BLOCK, *PSCSI_REQUEST_BLOCK;

Length 记录此数据结构的长度; Function记录执行的操作, SrbStatus记录请求完成时的状态, ScsiStatus记录 HBA 或者目标设备返回的 SCSI 状态, PathId 标识请求的 SISC端口或者总线; TargetId 标识目标i控制器或总线上的设备; Lun标识设备的逻辑单元号; CdbLength记录SCSI-2或者命令秒速块的大小; DataBuffer指向数据缓冲区; OriginalRequest指向原始的IRP 请求; SrbExtension指向Srb的扩展部分; Cdb指定要发送给目标设备的 SCSI-2或者命令描述符块。

发表评论

表情:
评论列表 (有 0 条评论,304人围观)

还没有评论,来说两句吧...

相关阅读