执行存储驱动程序数据集管理
从 Windows 7 开始,驱动程序可以对设备的数据集执行管理操作。 可在存储设备上执行的 数据集管理 (DSM) 操作 的列表由 Microsoft 定义。
使用 IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
DEVICE_DSM_ACTION常量指定操作。 此常量在IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES请求的系统缓冲区中包含的 DEVICE_DSM_INPUT 结构的 Action 成员中传递。 如果操作需要其他参数,则参数块将紧跟DEVICE_DSM_INPUT结构, ParameterBlockOffset 将指定参数块从DEVICE_DSM_INPUT结构开始的偏移量。 数据集范围(如果有)将紧跟参数块之后, DataSetRangesOffset 将指定范围 () 开始的DEVICE_DSM_INPUT结构开头的偏移量。 下图显示了系统缓冲区结构。
如果管理操作将返回输出,则会在 IOCTL 的 OutputBuffer 中传递指向 DEVICE_DSM_OUTPUT 结构的指针。 如果操作将返回其他特定于操作的输出,则输出块将紧跟DEVICE_DSM_OUTPUT结构, OutputBlockOffset 将指定参数块从DEVICE_DSM_OUTPUT结构开始处的偏移量。 下图显示了输出缓冲区结构。
DSM 操作的进程流
DSM 操作的进程流如下所述,其中 Sender 是操作请求者, Handler 处理请求的操作。 请注意,堆栈中可以有多个 处理程序 。
发送方 通过执行以下操作初始化 DSM 并将其发送到堆栈中的第一个 处理程序 :
- 使用与操作关联的定义分配和初始化 DEVICE_DSM_DEFINITION 结构。
- 调用 DeviceDsmGetInputLength 以确定操作的输入缓冲区所需的大小,然后为此缓冲区分配内存。
- 调用 DeviceDsmInitializeInput 以初始化 DSM_DEVICE_INPUT 结构,如果操作具有参数,则调用 参数块。 参数块格式取决于操作。 有关更多详细信息 ,请参阅DEVICE_DSM_ACTION说明 。
- 如果操作具有范围,请为每个范围调用 DeviceDsmAddDataSetRange ,以将 DEVICE_DSM_RANGE 结构 () 添加到输入缓冲区。
- 如果 DSM 具有输出,请调用 DeviceDsmGetOutputLength 以确定操作的输出缓冲区所需的大小,然后为此缓冲区分配内存。
- 发送 IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES 请求,在 IOCTL 的系统缓冲区中传递初始化的输入数据以及分配的输出缓冲区(如果有)。
处理程序 通过以下三种方式之一处理 DSM IOCTL 请求:
- 处理请求并返回输出(如果有)。
- 处理请求并将其转发到堆栈中的下一个较低驱动程序。
- 将请求转发到堆栈中的下一个下一个驱动程序,而无需处理 DSM。
注意
无论驱动程序是否处理 DSM, 仅当 设置了DEVICE_DSM_ACTION的最有效位 (DeviceDsmActionFlag_NonDestructive) 时,它才能安全地转发请求。 如果未设置DeviceDsmActionFlag_NonDestructive,驱动程序应改为返回并返回错误。
如果 Handler 确实处理了 DSM,它将执行以下步骤:
- 通过调用 DeviceDsmValidateInput 验证输入。
- 如果输入有效, 处理程序 将提取输入以获取操作。 如果操作具有参数块, Handler 将调用 DeviceDsmParameterBlock 以获取参数块。 如果操作包含范围数据, Handler 将调用 DeviceDsmDataSetRanges 以获取指向数据集范围块的指针,然后对该块执行常规处理。 此块位于 DataSetRangesOffset 中,由一个或多个格式化为 DEVICE_DSM_RANGE 结构的连续条目组成。 数据集范围的长度(以字节为单位)在 DEVICE_DSM_INPUT 的 DataSetRangesLength 成员中设置。
- 如果操作需要输出, Handler 会调用 DeviceDsmValidateOutputLength 来验证发送方提供的输出缓冲区。 如果有效,处理程序通过调用 DeviceDsmInitializeOutput 初始化输出缓冲区的DEVICE_DSM_OUTPUT部分,并使用特定于操作的输出(如果有)填充输出块。 处理程序随后完成 IOCTL,并将 IOCTL 返回或转发到堆栈中的下一个驱动程序。
处理 DSM 并将其返回到 发送方后, 发送方 通过调用 DeviceDsmValidateOutput 来验证输出(如果有)。 如果输出有效, 则发送方 通过调用 DeviceDsmOutputBlock 提取输出块(如果有)。
有关每个特定 DSM 操作的详细信息,请参阅 设备 DSM 操作说明。