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