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

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

        A)驱动对象结构  (DRIVER_OBJECT)

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

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

typedef struct _DRIVER_OBJECT {
  CSHORT Type;
  CSHORT Size;
//
  // The following links all of the devices created by a single driver
  // together on a list, and the Flags word provides an extensible flag
  // location for driver objects.
  //
PDEVICE_OBJECT DeviceObject;
  ULONG Flags;
//
  // The following section describes where the driver is loaded. The count
  // field is used to count the number of times the driver has had its
  // registered reinitialization routine invoked.
  //
PVOID DriverStart;
  ULONG DriverSize;
  PVOID DriverSection;
  PDRIVER_EXTENSION DriverExtension;
//
  // The driver name field is used by the error log thread
  // determine the name of the driver that an I/O request is/was bound.
  //
UNICODE_STRING DriverName;
//
  // The following section is for registry support. Thise is a pointer
  // to the path to the hardware information in the registry
  //
PUNICODE_STRING HardwareDatabase;
//
  // The following section contains the optional pointer to an array of
  // alternate entry points to a driver for "fast I/O" support. Fast I/O
  // is performed by invoking the driver routine directly with separate
  // parameters, rather than using the standard IRP call mechanism. Note
  // that these functions may only be used for synchronous I/O, and when
  // the file is cached.
  //
PFAST_IO_DISPATCH FastIoDispatch;
//
  // The following section describes the entry points to this particular
  // driver. Note that the major function dispatch table must be the last
  // field in the object so that it remains extensible.
  //
PDRIVER_INITIALIZE DriverInit;
  PDRIVER_STARTIO DriverStartIo;
  PDRIVER_UNLOAD DriverUnload;
  PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;
  typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; // ntndis


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

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

typedef struct _DRIVER_OBJECT{
       //结构的类型和大小
       CSHORT  Type;
       CSHORT  Size;
       //设备对象,这里实际上是一个设备对象的链表的开始。因为 DeviceObject 中有相关链表信息。
       PDEVICE_OBJECT  DeviceObject;
       •••
       //这个内核模块在内核空间中的开始地址和大小
       PVOID  DriverStart;
       ULONG  DriverSize;
       •••
       //驱动的名字
       UNICODE_STRING  DriverName;
       •••
       //快速IO分发函数
       PFAST_IO_DISPATCH  FastIoDispatch;
       •••
       //驱动的卸载函数
       PDRIVER_UNLOAD.DriverUnload;
       //普通分发函数
       PDRIVER_DISPATCH  MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
}DRIVER_OBJECT;
     这样看起来是不是 少了很多呢, 上面做了注释的是 主要需要了解的。


-------------------------------------------------------------------------------------------------------

       B)设备驱动程序(DEVICE_OBJECT)

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

typedef struct _DEVICE_OBJECT {
  CSHORT                      Type;
  USHORT                      Size;
  LONG                        ReferenceCount;
  struct _DRIVER_OBJECT  *DriverObject;
  struct _DEVICE_OBJECT  *NextDevice;
  struct _DEVICE_OBJECT  *AttachedDevice;
  struct _IRP  *CurrentIrp;
  PIO_TIMER                   Timer;
  ULONG                       Flags;
  ULONG                       Characteristics;
  __volatile PVPB             Vpb;
  PVOID                       DeviceExtension;
  DEVICE_TYPE                 DeviceType;
  CCHAR                       StackSize;
  union {
    LIST_ENTRY         ListEntry;
    WAIT_CONTEXT_BLOCK Wcb;
  } Queue;
  ULONG                       AlignmentRequirement;
  KDEVICE_QUEUE               DeviceQueue;
  KDPC                        Dpc;
  ULONG                       ActiveThreadCount;
  PSECURITY_DESCRIPTOR        SecurityDescriptor;
  KEVENT                      DeviceLock;
  USHORT                      SectorSize;
  USHORT                      Spare1;
  struct _DEVOBJ_EXTENSION  *  DeviceObjectExtension;
  PVOID                       Reserved;
} DEVICE_OBJECT, *PDEVICE_OBJECT;

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

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

typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
_DEVICE_OBJECT{

       //结构的类型和大小
       CSHORT  Type;
       CSHORT  Size;

       //引用计数
       ULONG  ReferenceCount;

       //这个设备所属的驱动对象
       struct  _DRIVER_OBJECT  *DriverObject;

       //下一个设备对象,在一个驱动对象中有N个设备,这些设备用这个指针连接起来作为一个单向的链表
       struct  _DRIVER_OBJECT  *NextDevice;

       //设备类型
      DEVICE_TYPE  DeviceType;
       •••
       //IRP栈大小
       HAR  StackSize;
       ••••••

}DEVICE_OBJECT;
    这样一来,就清晰很多啦 

----------------------------------------------------------------------------------------------------------------------------

2,进程域线程数据结构

    A)执行体进程块(EXPROCESS)

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

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

typedef struct _EPROCESS 
{
    KPROCESS Pcb; 

    EX_PUSH_LOCK ProcessLock;

    LARGE_INTEGER CreateTime;
    LARGE_INTEGER ExitTime; 

    EX_RUNDOWN_REF RundownProtect;

    HANDLE UniqueProcessId; 

    LIST_ENTRY ActiveProcessLinks; 

    SIZE_T QuotaUsage[PsQuotaTypes];
    SIZE_T QuotaPeak[PsQuotaTypes];
    SIZE_T CommitCharge; 

    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;

    LIST_ENTRY SessionProcessLinks;

    PVOID DebugPort;
    PVOID ExceptionPort;
    PHANDLE_TABLE ObjectTable; 

    EX_FAST_REF Token;

    PFN_NUMBER WorkingSetPage;
    KGUARDED_MUTEX AddressCreationLock;
    KSPIN_LOCK HyperSpaceLock;

    struct _ETHREAD *ForkInProgress;
    ULONG_PTR HardwareTrigger;

    PMM_AVL_TABLE PhysicalVadRoot;
    PVOID CloneRoot;
    PFN_NUMBER NumberOfPrivatePages;
    PFN_NUMBER NumberOfLockedPages;
    PVOID Win32Process;
    struct _EJOB *Job;
    PVOID SectionObject;

    PVOID SectionBaseAddress;

    PEPROCESS_QUOTA_BLOCK QuotaBlock;

    PPAGEFAULT_HISTORY WorkingSetWatch;
    HANDLE Win32WindowStation;
    HANDLE InheritedFromUniqueProcessId;

    PVOID LdtInformation;
    PVOID VadFreeHint;
    PVOID VdmObjects;
    PVOID DeviceMap;

    PVOID Spare0[3];
    union 
    {
        HARDWARE_PTE PageDirectoryPte;
        ULONGLONG Filler;
    };
    PVOID Session;
    UCHAR ImageFileName[ 16 ];

    LIST_ENTRY JobLinks;
    PVOID LockedPagesList;

    LIST_ENTRY ThreadListHead; 

    PVOID SecurityPort; 
    PVOID PaeTop; 

    ULONG ActiveThreads;

    ACCESS_MASK GrantedAccess;

    ULONG DefaultHardErrorProcessing;

    NTSTATUS LastThreadExitStatus; 

    PPEB Peb; 

    EX_FAST_REF PrefetchTrace;

    LARGE_INTEGER ReadOperationCount;
    LARGE_INTEGER WriteOperationCount;
    LARGE_INTEGER OtherOperationCount;
    LARGE_INTEGER ReadTransferCount;
    LARGE_INTEGER WriteTransferCount;
    LARGE_INTEGER OtherTransferCount;

    SIZE_T CommitChargeLimit;
    SIZE_T CommitChargePeak;

    PVOID AweInfo; 

    SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;

    MMSUPPORT Vm;
 
    LIST_ENTRY MmProcessLinks; 

    ULONG ModifiedPageCount; 

    ULONG JobStatus; 
 
    union 
    { 
        ULONG Flags; 

        struct {
            ULONG CreateReported            : 1;
            ULONG NoDebugInherit            : 1;
            ULONG ProcessExiting            : 1;
            ULONG ProcessDelete             : 1;
            ULONG Wow64SplitPages           : 1;
            ULONG VmDeleted                 : 1;
            ULONG OutswapEnabled            : 1;
            ULONG Outswapped                : 1;
            ULONG ForkFailed                : 1;
            ULONG Wow64VaSpace4Gb           : 1;
            ULONG AddressSpaceInitialized   : 2;
            ULONG SetTimerResolution        : 1;
            ULONG BreakOnTermination        : 1;
            ULONG SessionCreationUnderway   : 1;
            ULONG WriteWatch                : 1;
            ULONG ProcessInSession          : 1;
            ULONG OverrideAddressSpace      : 1;
            ULONG HasAddressSpace           : 1;
            ULONG LaunchPrefetched          : 1;
            ULONG InjectInpageErrors        : 1;
            ULONG VmTopDown                 : 1;
            ULONG ImageNotifyDone           : 1;
            ULONG PdeUpdateNeeded           : 1;    // NT32 only
            ULONG VdmAllowed                : 1;
            ULONG SmapAllowed               : 1;
            ULONG CreateFailed              : 1;
            ULONG DefaultIoPriority         : 3;
            ULONG Spare1                    : 1;
            ULONG Spare2                    : 1;
        };
    };

    NTSTATUS ExitStatus;

    USHORT NextPageColor;
    union 
    {
        struct 
    {
            UCHAR SubSystemMinorVersion;
            UCHAR SubSystemMajorVersion;
        };
        USHORT SubSystemVersion;
    };
    UCHAR PriorityClass;

    MM_AVL_TABLE VadRoot;

    ULONG Cookie;

} EPROCESS, *PEPROCESS;
      又是一大堆这么多复杂的代码。 这里 有详情解释。

      B)内核进程块(KPROCESS

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

typedef struct _KPROCESS
{
     DISPATCHER_HEADER Header;
     LIST_ENTRY ProfileListHead;
     ULONG DirectoryTableBase;
     ULONG Unused0;
     KGDTENTRY LdtDescriptor;
     KIDTENTRY Int21Descriptor;
     WORD IopmOffset;
     UCHAR Iopl;
     UCHAR Unused;
     ULONG ActiveProcessors;
     ULONG KernelTime;
     ULONG UserTime;
     LIST_ENTRY ReadyListHead;
     SINGLE_LIST_ENTRY SwapListEntry;
     PVOID VdmTrapcHandler;
     LIST_ENTRY ThreadListHead;
     ULONG ProcessLock;
     ULONG Affinity;
     union
     {
          ULONG AutoAlignment: 1;
          ULONG DisableBoost: 1;
          ULONG DisableQuantum: 1;
          ULONG ReservedFlags: 29;
          LONG ProcessFlags;
     };
     CHAR BasePriority;
     CHAR QuantumReset;
     UCHAR State;
     UCHAR ThreadSeed;
     UCHAR PowerState;
     UCHAR IdealNode;
     UCHAR Visited;
     union
     {
          KEXECUTE_OPTIONS Flags;
          UCHAR ExecuteOptions;
     };
     ULONG StackCount;
     LIST_ENTRY ProcessListEntry;
     UINT64 CycleTime;
} 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描述了内核线程块,该模块也是不透明的。结构如下:

kd> dt -r _kthread
nt!_KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
      +0x000 Type             : UChar
      +0x001 Absolute         : UChar
      +0x002 Size             : UChar
      +0x003 Inserted         : UChar
      +0x004 SignalState      : Int4B
      +0x008 WaitListHead     : _LIST_ENTRY
         +0x000 Flink            : Ptr32 _LIST_ENTRY
         +0x004 Blink            : Ptr32 _LIST_ENTRY
   +0x010 MutantListHead   : _LIST_ENTRY
      +0x000 Flink            : Ptr32 _LIST_ENTRY
         +0x000 Flink            : Ptr32 _LIST_ENTRY
         +0x004 Blink            : Ptr32 _LIST_ENTRY
      +0x004 Blink            : Ptr32 _LIST_ENTRY
         +0x000 Flink            : Ptr32 _LIST_ENTRY
         +0x004 Blink            : Ptr32 _LIST_ENTRY
   +0x018 InitialStack     : Ptr32 Void
   +0x01c StackLimit       : Ptr32 Void
   +0x020 Teb              : Ptr32 Void
   +0x024 TlsArray         : Ptr32 Void
   +0x028 KernelStack      : Ptr32 Void
   +0x02c DebugActive      : UChar
   +0x02d State            : UChar
   +0x02e Alerted          : [2] UChar
   +0x030 Iopl             : UChar
   +0x031 NpxState         : UChar
   +0x032 Saturation       : Char
   +0x033 Priority         : Char
   +0x034 ApcState         : _KAPC_STATE
      +0x000 ApcListHead      : [2] _LIST_ENTRY
         +0x000 Flink            : Ptr32 _LIST_ENTRY
         +0x004 Blink            : Ptr32 _LIST_ENTRY
      +0x010 Process          : Ptr32 _KPROCESS

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

       3 ,存储系统数据结构

     A)参数模块(VPB

      详细如下:

1: kd> ?? fastfat!FatData 
struct _FAT_DATA 
   +0x000 NodeTypeCode     : 0x500 
   +0x002 NodeByteSize     : 304 
   +0x008 LazyWriteThread  : 0xfffffa80`037151a0 
   +0x010 VcbQueue         : _LIST_ENTRY [ 0xfffffa80`0384fa18 – 0xfffffa80`0384fa18 ] 
    ……
1: kd> !list "-t nt!_LIST_ENTRY.Flink -e -x \"dd @$extret l4;  dt fastfat!_VCB @$extret-0x58\"  0xfffffa80`0384fa18" 
dd @$extret l4;  dt fastfat!_VCB @$extret-0x58 
fffffa80`0384fa18  070e34d0 fffff880 070e34d0 fffff880 
   +0x000 VolumeFileHeader : _FSRTL_ADVANCED_FCB_HEADER 
   +0x058 VcbLinks         : _LIST_ENTRY [ 0xfffff880`070e34d0 – 0xfffff880`070e34d0 ] 
   +0x068 TargetDeviceObject : 0xfffffa80`053c7040 _DEVICE_OBJECT 
   +0x070 Vpb              : 0xfffffa80`05b54a00 _VPB 
   +0x078 VcbState         : 0x101002 
   +0x07c VcbCondition     : 1 ( VcbGood ) 
     …… 
   +0x410 SwapVpb          : 0xfffffa80`056f19e0 _VPB 
   +0x418 AsyncCloseList   : _LIST_ENTRY [ 0xfffffa80`0384fdd8 – 0xfffffa80`0384fdd8 ] 
   +0x428 DelayedCloseList : _LIST_ENTRY [ 0xfffff8a0`170d3880 – 0xfffff8a0`170d3880 ] 
   +0x438 AdvancedFcbHeaderMutex : _FAST_MUTEX 
   +0x470 CloseContext     : 0xfffff8a0`0af0eef0 CLOSE_CONTEXT 
   +0x478 CloseContextCount : 2
1: kd> dt _VPB 0xfffffa80`05b54a00 
nt!_VPB 
   +0x000 Type             : 10 
   +0x002 Size             : 96 
   +0x004 Flags            : 1 
   +0x006 VolumeLabelLength : 0x10 
   +0x008 DeviceObject     : 0xfffffa80`0384f820 _DEVICE_OBJECT 
   +0x010 RealDevice       : 0xfffffa80`05bab060 _DEVICE_OBJECT 
   +0x018 SerialNumber     : 0x51e712c6 
   +0x01c ReferenceCount   : 9 
   +0x020 VolumeLabel      : [32]  "CANON_DC"
1: kd> dt _VPB 0xfffffa80`056f19e0 
nt!_VPB 
   +0x000 Type             : 0 
   +0x002 Size             : 0 
   +0x004 Flags            : 0 
   +0x006 VolumeLabelLength : 0 
   +0x008 DeviceObject     : (null) 
   +0x010 RealDevice       : (null) 
   +0x018 SerialNumber     : 0 
   +0x01c ReferenceCount   : 0 
   +0x020 VolumeLabel      : [32]  ""
1: kd> !devobj 0xfffffa80`05bab060 
Device object (fffffa8005bab060) is for: 
HarddiskVolume18 \Driver\volmgr DriverObject fffffa8004086e70 
Current Irp 00000000 RefCount 9 Type 00000007 Flags 00003050 
Vpb fffffa8005b54a00 Dacl fffff9a1171d06c0 DevExt fffffa8005bab1b0 DevObjExt fffffa8005bab318 Dope fffffa8004fa7fa0 DevNode fffffa80055d9d90 
ExtensionFlags (0000000000)  
AttachedDevice (Upper) fffffa8005b4a040 \Driver\fvevol 
Device queue is not busy. 
1: kd> dt _DEVICE_OBJECT 0xfffffa80`05bab060 
nt!_DEVICE_OBJECT 
   +0x000 Type             : 3 
   +0x002 Size             : 0x2b8 
   +0x004 ReferenceCount   : 9 
   +0x008 DriverObject     : 0xfffffa80`04086e70 _DRIVER_OBJECT 
   +0x010 NextDevice       : 0xfffffa80`045ed440 _DEVICE_OBJECT 
   +0x018 AttachedDevice   : 0xfffffa80`05b4a040 _DEVICE_OBJECT 
   +0x020 CurrentIrp       : (null) 
   +0x028 Timer            : (null) 
   +0x030 Flags            : 0x3050 
   +0x034 Characteristics  : 1 
   +0x038 Vpb              : 0xfffffa80`05b54a00 _VPB 
   +0x040 DeviceExtension  : 0xfffffa80`05bab1b0 
   +0x048 DeviceType       : 7 
   +0x04c StackSize        : 9 ” 
   +0x050 Queue            :  
   +0x098 AlignmentRequirement : 0 
   +0x0a0 DeviceQueue      : _KDEVICE_QUEUE 
   +0x0c8 Dpc              : _KDPC 
   +0x108 ActiveThreadCount : 0 
   +0x110 SecurityDescriptor : 0xfffff8a0`170b0620 
   +0x118 DeviceLock       : _KEVENT 
   +0x130 SectorSize       : 0x200 
   +0x132 Spare1           : 1 
   +0x138 DeviceObjectExtension : 0xfffffa80`05bab318 _DEVOBJ_EXTENSION 
   +0x140 Reserved         : (null)
      又是一板的代码、、 唉。。 这个就不细说啦。 这哥们总结的非常好!

      B) 文件对象(File_Object

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

typedef struct _FILE_OBJECT {
  CSHORT                            Type;
  CSHORT                            Size;
  PDEVICE_OBJECT                    DeviceObject;
  PVPB                              Vpb;
  PVOID                             FsContext;
  PVOID                             FsContext2;
  PSECTION_OBJECT_POINTERS          SectionObjectPointer;
  PVOID                             PrivateCacheMap;
  NTSTATUS                          FinalStatus;
  struct _FILE_OBJECT  *RelatedFileObject;
  BOOLEAN                           LockOperation;
  BOOLEAN                           DeletePending;
  BOOLEAN                           ReadAccess;
  BOOLEAN                           WriteAccess;
  BOOLEAN                           DeleteAccess;
  BOOLEAN                           SharedRead;
  BOOLEAN                           SharedWrite;
  BOOLEAN                           SharedDelete;
  ULONG                             Flags;
  UNICODE_STRING                    FileName;
  LARGE_INTEGER                     CurrentByteOffset;
  __volatile ULONG                  Waiters;
  __volatile ULONG                  Busy;
  PVOID                             LastLock;
  KEVENT                            Lock;
  KEVENT                            Event;
  __volatile PIO_COMPLETION_CONTEXT CompletionContext;
  KSPIN_LOCK                        IrpListLock;
  LIST_ENTRY                        IrpList;
  __volatile PVOID                  FileObjectExtension;
} FILE_OBJECT, *PFILE_OBJECT;
     其中, DeviceObject域记录域所打开文件相关联的设备。Vpb记录参数块; FsContextFsContext2域是自定义指针; SectionObjectPointer 是一个内存区对象指针,指向数据控制区域或者映像控制区域; FileName记录文件名。

     C) SCSI请求块(SRB

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

typedef struct _SCSI_REQUEST_BLOCK {
  USHORT                     Length;
  UCHAR                      Function;
  UCHAR                      SrbStatus;
  UCHAR                      ScsiStatus;
  UCHAR                      PathId;
  UCHAR                      TargetId;
  UCHAR                      Lun;
  UCHAR                      QueueTag;
  UCHAR                      QueueAction;
  UCHAR                      CdbLength;
  UCHAR                      SenseInfoBufferLength;
  ULONG                      SrbFlags;
  ULONG                      DataTransferLength;
  ULONG                      TimeOutValue;
  PVOID                      DataBuffer;
  PVOID                      SenseInfoBuffer;
  struct _SCSI_REQUEST_BLOCK  *NextSrb;
  PVOID                      OriginalRequest;
  PVOID                      SrbExtension;
  union {
    ULONG InternalStatus;
    ULONG QueueSortKey;
    ULONG LinkTimeoutValue;
  };
#ifdef _WIN64
  ULONG                      Reserved;
#endif 
  UCHAR                      Cdb[16];
} 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或者命令描述符块。

 

你可能感兴趣的:(windows驱动开发)