函数作用以及对应的数据结构值得参考
以下内容全部来自于MSDN,里面部分内容一时不知道怎么翻译,为了不浪费太多的时间,所以暂时用“暂缺”代替,以后有机会再补上。内容繁多,差错难免,不当之处,敬请指正。
一、DeviceIoControl()各参数的简单说明
利用DeviceIoControl()函数可以实现对系统硬件的操作,该函数通过向指定设备的驱动程序发送控制码从而让该设备执行相应的操作。函数原型为:
BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
参数说明
hDevice
[in] 通过CreateFile()打开的设备句柄。注意CreateFile()函数在打开设备时设备名称必须使用“\\.\DeviceName”格式。
dwIoControlCode
[in] 操作的控制码。该参数的有效取值列表将会在后面重点介绍。
lpInBuffer
[in] 指向包含有执行当前操作所需数据缓冲区的指针。该参数格式依赖于dwIoControlCode所取的值,详见后面dwIoControlCode参数的说明部分。
当dwIoControlCode所指定的操作不要求传入数据时,该参数可以为NULL。
nInBufferSize
[in] lpInBuffer所包含的字节数。
lpOutBuffer
[out] 指向接收当前操作返回数据缓冲区的指针。该参数格式依赖于dwIoControlCode所取的值,详见后面dwIoControlCode参数的说明部分。
当dwIoControlCode所指定的操作不返回数据时,该参数可以为NULL。
nOutBufferSize
[in] lpOutBuffer{zd0}可接收的字节数。
lpBytesReturned
[out] 用于存储 lpOutBuffer 中有效数据的字节数。
如果 lpOutBuffer 由于空间过于小而无法接收任何数据,函数的调用将会失败。调用GetLastError()会得到ERROR_INSUFFICIENT_BUFFER 的错误值。此时 lpBytesReturned 值为0。
如果 lpOutBuffer 由于空间过于小而无法接收所有数据,但可以容纳部分数据,有些设备将会返回部分数据以填充 lpOutBuffer。在这种情况下,函数的调用还是失败的,调用GetLastError()将会得到 ERROR_MORE_DATA 的错误值。此时 lpBytesReturned 值为 lpOutBuffer 中所接收的字节数。
如果 lpOverlapped 为NULL,lpBytesReturned 必须不为NULL。甚至当当前操作并不需要返回数据、lpOutBuffer也为NULL时DeviceIoControl还是会使用lpBytesReturned。在这种情况下,函数完成后lpBytesReturned 的值没有意义。
如果 lpOverlapped 不为NULL,lpBytesReturned 可以为NULL。如果这个参数不为NULL并且当前操作会返回数据时,lpBytesReturned 在异步操作完成之前是没有意义的。要得到返回的字节数,可调用GetOverlappedResult()函数。如果当前关联的设备是一个完成端口,可以通过调用 GetQueuedCompletionStatus() 函数来获取返回的字节数。
lpOverlapped
[in] 指向一个OVERLAPPED 结构。
如果hDevice所指向的设备在打开时没有指定 FILE_FLAG_OVERLAPPED,该参数将被忽略。
如果hDevice所指向的设备在打开时指定了 FILE_FLAG_OVERLAPPED,当前的操作将会以异步操作的方式执行,在这种情况下,lpOverlapped指向的必须是一个包含有有效事件对象(Event object :忘记行话怎么翻译了,以后再纠正)的OVERLAPPED 结构,否则将会发生不可预知的错误。
对于异步操作,当事件对象有信号时DeviceIoControl 会立即返回,否则,函数将会一直阻塞直到操作完成或者发生错误。
二、dwIoControlCode各取值的意义
1、通信控制码
● IOCTL_SERIAL_LSRMST_INSERT
该控制码允许/禁止线路状态和调制解调器状态发送到数据流中。应用程序可以通过ReadFile函数从数据流中获取这些状态。
当允许线路状态和调制解调器状态发送时,数据流中的状态值之前将会有一个转义字符。转义字符是可以自定义的。状态值一般由1—3个字节组成。
注意: 一个应用程序使用这种模式时必须检查数据流中的每个字符以确保调制解调器状态和线路状态确实存在于数据流中。如果打开 LSRMST_INSERT 模式,转义字符之后将会跟随以下数值:
SERIAL_LSRMST_ESCAPE 表示接收转义字符进入数据流中。
SERIAL_LSRMST_LSR_DATA 表示一个线路状态发生了改变,并且硬件缓冲区中的值已经被置为有效值。
SERIAL_LSRMST_LSR_NODATA 表示一个线路状态发生了改变,但在硬件缓冲区中没有有效值可用。
SERIAL_LSRMST_MST 表示一个调制解调器状态发生了改变。
lpInBuffer 指向一个有符号的字节变量。
如果该值不为0,则他表示转义字符。当前操作将会把线路状态和调制解调器状态的LSRMST_INSERT模式打开。
如果该值为0,当前操作将会把线路状态和调制解调器状态的LSRMST_INSERT模式关闭。
转义字符不能为XON/XOFF字符。
lpOutBuffer 无意义,设为NULL。
2、设备管理控制码
● 以下控制码用于修改设备
IOCTL_CHANGER_EXCHANGE_MEDIUM
暂缺
IOCTL_CHANGER_GET_ELEMENT_STATUS
暂缺
IOCTL_CHANGER_GET_PARAMETERS
该控制码用于返回指定设备的参数信息。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个 GET_CHANGER_PARAMETERS 结构的指针。
IOCTL_CHANGER_GET_PRODUCT_DATA
该控制码用于返回指定设备的产品信息。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个 CHANGER_PRODUCT_DATA 结构的指针。
IOCTL_CHANGER_GET_STATUS
该控制码用于返回指定设备当前状态。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_CHANGER_INITIALIZE_ELEMENT_STATUS
暂缺
IOCTL_CHANGER_MOVE_MEDIUM
暂缺
IOCTL_CHANGER_QUERY_VOLUME_TAGS
该控制码用于返回指定元件的卷标信息。
lpInBuffer 指向一个CHANGER_SEND_VOLUME_TAG_INFORMATION 结构的指针。
lpOutBuffer 指向一个READ_ELEMENT_ADDRESS_INFO 结构的指针。
IOCTL_CHANGER_REINITIALIZE_TRANSPORT
暂缺
IOCTL_CHANGER_SET_ACCESS
该控制码用于设置设备的输入/输出端口、键区等的状态。
lpInBuffer 指向一个 CHANGER_SET_ACCESS 结构的指针。
lpOutBuffer 无意义,设为NULL。
IOCTL_CHANGER_SET_POSITION
暂缺
● 以下控制码用于设备管理
IOCTL_STORAGE_CHECK_VERIFY
该控制码用于确定设备是否是可存取的。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_STORAGE_EJECT_MEDIA
暂缺
IOCTL_STORAGE_EJECTION_CONTROL
暂缺
IOCTL_STORAGE_GET_HOTPLUG_INFO
该控制码用于返回指定设备插塞配置。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个 STORAGE_HOTPLUG_INFO 结构的指针。
IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER
该控制码用于返回USB设备的序列号。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个 MEDIA_SERIAL_NUMBER_DATA 结构的指针。
IOCTL_STORAGE_GET_MEDIA_TYPES
该控制码用于返回设备的几何信息。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个 DISK_GEOMETRY 结构数组的指针。
IOCTL_STORAGE_GET_MEDIA_TYPES_EX
该控制码用于返回设备所支持的媒介类型
lpOutBuffer 无意义,设为NULL。
lpOutBuffer 指向一个GET_MEDIA_TYPES 结构的指针。
IOCTL_STORAGE_LOAD_MEDIA
该控制码用于向设备中载入指定媒介。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_STORAGE_MCN_CONTROL
该控制码用于打开/关闭媒体改变通知功能,关闭该功能将会阻止GUID_IO_MEDIA_ARRIVAL和GUID_IO_MEDIA_REMOVAL事件。
lpInBuffer 指向一个Boolean变量的指针,如果为该值为TRUE,则关闭改变通知功能,否则则打开改变通知功能。
lpOutBuffer 无意义,设为NULL。
IOCTL_STORAGE_MEDIA_REMOVAL
暂缺
IOCTL_STORAGE_SET_HOTPLUG_INFO
该控制码用设置指定设备的插塞配置。
lpInBuffer 指向 STORAGE_HOTPLUG_INFO 结构的指针。
lpOutBuffer 无意义,设为NULL。
3、目录管理控制码
● 以下控制码用于文件压缩/解压缩
FSCTL_GET_COMPRESSION
获取文件/文件夹的压缩状态(注意目标卷的文件系统是否支持压缩)
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个USHORT变量的指针。该参数可以为以下各值之一:
COMPRESSION_FORMAT_NONE 文件/文件夹未被压缩
COMPRESSION_FORMAT_LZNT1 文件/文件夹使用LZNT1f进行了压缩
all other values 保留
FSCTL_SET_COMPRESSION
设置文件/文件夹的压缩状态(注意目标卷的文件系统是否支持压缩)
lpInBuffer 指向一个USHORT变量的指针。该参数可以为以下各值之一:
COMPRESSION_FORMAT_NONE 解压缩文件/文件夹
COMPRESSION_FORMAT_DEFAULT 使用默认压缩算法压缩文件/文件夹
COMPRESSION_FORMAT_LZNT1 使用LZNT1f压缩算法压缩文件/文件夹
all other values 保留
lpOutBuffer 无意义,设为NULL。
● 以下控制码用于重解析点(Reparse Point)
FSCTL_DELETE_REPARSE_POINT
删除指定文件/文件夹的重解析点,该操作不会将文件/文件夹删除
lpInBuffer 指向一个REPARSE_GUID_DATA_BUFFER结构的指针。该结构中ReparseTag成员必须是要删除的重解析点的标识、ReparseGuid成员必须是要删除的重解析点的GUID,同时ReparseDataLength成员必须为0。
lpOutBuffer 无意义,设为NULL。
FSCTL_GET_REPARSE_POINT
获取指定文件/文件夹的重解析点
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个用于接收重解析点数据的指针。如果重解析标识是微软的重解析标识,该指针指向一个REPARSE_DATA_BUFFER结构,否则,该指针指向一个 REPARSE_GUID_DATA_BUFFER结构
FSCTL_SET_REPARSE_POINT
设置指定文件/文件夹重解析点
lpInBuffer 指向一个包含有重解析点信息的REPARSE_GUID_DATA_BUFFER结构的指针。
lpOutBuffer 无意义,设为NULL。
4、磁盘管理控制码
● 以下控制码用于磁盘管理
IOCTL_DISK_CREATE_DISK
利用CREATE_DISK结构中的信息对指定磁盘和磁盘分区进行初始化。
lpInBuffer 指向 CREATE_DISK 结构的指针。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_DELETE_DRIVE_LAYOUT
从主引导记录中删除引导信息,所以磁盘将会被从头到尾的格式化。扇区0中的分区信息也就不复存在了。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_FORMAT_TRACKS
格式化指定的、连续的软盘磁道。如果需要更多的功能请使用IOCTL_DISK_FORMAT_TRACKS_EX。
lpInBuffer 指向一个FORMAT_PARAMETERS结构的指针。
lpOutBuffer 指向一系列BAD_TRACK_NUMBER类型的变量。每个变量都包含有该坏磁道中的磁道数。
IOCTL_DISK_FORMAT_TRACKS_EX
格式化指定的、连续的软盘磁道。
lpInBuffer 指向一个 FORMAT_EX_PARAMETERS结构的指针。
lpOutBuffer 指向一系列BAD_TRACK_NUMBER类型的变量。每个变量都包含有该坏磁道中的磁道数。
IOCTL_DISK_GET_CACHE_INFORMATION
返回磁盘的高速缓存配置数据
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个用于接收高速缓存配置数据的DISK_CACHE_INFORMATION结构。
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
返回物理磁盘的扩展信息。包括:类型、柱面数量、每柱面磁道数、每磁道扇区数和每扇区字节数等。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个用于接收磁盘信息的DISK_GEOMETRY_EX结构。
IOCTL_DISK_GET_DRIVE_LAYOUT_EX
返回各分区的扩展信息以及这些分区的特性。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个用于接收磁盘分区信息的缓冲区。更多信息请参照DRIVE_LAYOUT_INFORMATION_EX结构。
IOCTL_DISK_GET_LENGTH_INFO
返回指定磁盘/卷/分区的大小信息
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个GET_LENGTH_INFORMATION结构。
IOCTL_DISK_GET_PARTITION_INFO_EX
返回指定分区的扩展信息。包括:分区类型、大小和种类。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个用于接收该分区信息的缓冲区。更多信息请参照PARTITION_INFORMATION_EX结构。
IOCTL_DISK_GROW_PARTITION
扩大指定分区。
lpInBuffer 指向一个DISK_GROW_PARTITION结构。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_IS_WRITABLE
确定指定磁盘是否可写。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_PERFORMANCE
启用并获取磁盘性能统计
lpInBuffer 无意义,设为NULL。
lpOutBuffer 指向一个DISK_PERFORMANCE结构。
IOCTL_DISK_PERFORMANCE_OFF
关闭磁盘性能统计
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_REASSIGN_BLOCKS
使磁盘设备影射一块区域做为它的备用存储块公用池(spare block pool)。
lpInBuffer 指向一个REASSIGN_BLOCKS结构。该结包含有重新分配存储块公用池所需的信息。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_SET_CACHE_INFORMATION
设置磁盘的配置信息
lpInBuffer 指向一个DISK_CACHE_INFORMATION结构的指针。
lpOutBuffer 指向一个DISK_CACHE_INFORMATION结构的指针。
IOCTL_DISK_SET_DRIVE_LAYOUT_EX
根据给定的磁盘信息对磁盘进行分区。
lpInBuffer 指向一个包含有磁盘分区信息的DRIVE_LAYOUT_INFORMATION_EX结构。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_SET_PARTITION_INFO_EX
设置指定分区的分区信息。包括AT和EFI (Extensible Firmware Interface)分区的布局信息。
lpInBuffer 指向一个包含有分区信息的PARTITION_INFORMATION_EX结构。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_UPDATE_PROPERTIES
使缓冲的分区表无效并重新获取一份。
lpInBuffer 无意义,设为NULL。
lpOutBuffer 无意义,设为NULL。
IOCTL_DISK_VERIFY
对指定磁盘进行逻辑格式化
lpInBuffer 指向一个VERIFY_INFORMATION结构。
lpOutBuffer 无意义,设为NULL。
● 以下控制码用于磁盘碎片整理
FSCTL_GET_RETRIEVAL_POINTERS
获取指定文件磁盘上被分配的存储单元以及其位置。
lpInBuffer 指向一个STARTING_VCN_INPUT_BUFFER结构。
lpOutBuffer 指向一个RETRIEVAL_POINTERS_BUFFER结构。注意该结构大小是可变的。
FSCTL_GET_VOLUME_BITMAP
返回一个用于描述指定卷的已用空间和可用空间的位图。
lpInBuffer 指向一个STARTING_LCN_INPUT_BUFFER结构。开始的LCN在输出缓冲区中有可能会被四舍五入。
lpOutBuffer 指向一个VOLUME_BITMAP_BUFFER结构。注意该结构大小是可变的。
FSCTL_MOVE_FILE
在同一卷内移动、整理指定文件。该操作在整理碎片时使用。
lpInBuffer 指向一个MOVE_FILE_DATA结构。
lpOutBuffer 无意义,设为NULL。
以下是已经废弃的控制码,忽略
IOCTL_DISK_CONTROLLER_NUMBER
IOCTL_DISK_GET_DRIVE_GEOMETRY
IOCTL_DISK_GET_DRIVE_LAYOUT
IOCTL_DISK_GET_PARTITION_INFO
IOCTL_DISK_HISTOGRAM_DATA
IOCTL_DISK_HISTOGRAM_RESET
IOCTL_DISK_HISTOGRAM_STRUCTURE
IOCTL_DISK_LOGGING
IOCTL_DISK_REQUEST_DATA
IOCTL_DISK_REQUEST_STRUCTURE
IOCTL_DISK_SET_DRIVE_LAYOUT
IOCTL_DISK_SET_PARTITION_INFO
5、文件管理控制码
……
工作原因,不能一气呵成,后续部分,以后补上,呵呵……
:)