在MSDN的那个demo中,将设备名换成“A:”取 A 盘参数,先用资源管理器读一下盘,再运行这个程序可以成功,但换一张盘后就失败;换成“CDROM0” 取CDROM参数,无论如何都不行。这个问题如何解决呢? A 取软盘参数是从软盘上读取格式化后的信息,也就是必须执行读操作,这一点与硬盘不同。将CreateFile中的访问方式改为GENERIC_READ就行了。 IOCTL_DISK_GET_DRIVE_GEOMETRY这个 I/O 控制码,对软盘和硬盘有效,但对一些可移动媒介如CD/DVD-ROM、TAPE等就不管用了。要取CDROM参数,还得另辟蹊径。IOCTL_STORAGE_GET_MEDIA_TYPES_EX能够帮我们解决问题。 Q 使用这些 I/O 控制码,需要什么样的输入输出数据格式呢? A DeviceIoControl使用这两个控制码时,都不 需要输入数据。 IOCTL_DISK_GET_DRIVE_GEOMETRY直接输出一个 DISK_GEOMETRY结构: - typedef struct _DISK_GEOMETRY {
- LARGE_INTEGER Cylinders; // 柱面数
- MEDIA_TYPE MediaType; // 介质类型
- DWORD TracksPerCylinder; // 每 柱面的磁道数
- DWORD SectorsPerTrack; // 每磁道的扇区数
- DWORD BytesPerSector; // 每扇区的字节数
- } DISK_GEOMETRY;
- IOCTL_STORAGE_GET_MEDIA_TYPES_EX 输出一个 GET_MEDIA_TYPES结构:
- typedef struct _GET_MEDIA_TYPES {
- DWORD DeviceType; // 设备类型
- DWORD MediaInfoCount; // 介质信息条数
- DEVICE_MEDIA_INFO MediaInfo[1]; // 介质 信息
- } GET_MEDIA_TYPES;
- 让我们来看一下 DEVICE_MEDIA_INFO 结构的定义:
- typedef struct _DEVICE_MEDIA_INFO {
- union {
- struct {
- LARGE_INTEGER Cylinders; // 柱面数
- STORAGE_MEDIA_TYPE MediaType; // 介质类型
- DWORD TracksPerCylinder; // 每柱面的磁道数
- DWORD SectorsPerTrack; // 每磁道的扇区数
- DWORD BytesPerSector; // 每扇区的字节数
- DWORD NumberMediaSides; // 介质面数
- DWORD MediaCharacteristics; // 介质特性
- } DiskInfo; // 硬盘信息 struct {
- LARGE_INTEGER Cylinders; // 柱面数
- STORAGE_MEDIA_TYPE MediaType; // 介质类型
- DWORD TracksPerCylinder; // 每柱面的磁道数
- DWORD SectorsPerTrack; // 每磁道的扇区数
- DWORD BytesPerSector; // 每扇区的字节数
- DWORD NumberMediaSides; // 介质面数
- DWORD MediaCharacteristics; // 介质特性
- } RemovableDiskInfo; // “可移动盘”信息
- struct {
- STORAGE_MEDIA_TYPE MediaType; // 介质类型
- DWORD MediaCharacteristics; // 介质特性
- DWORD CurrentBlockSize; // 块的大小
- } TapeInfo; // 磁带信息
- } DeviceSpecific;
- } DEVICE_MEDIA_INFO;
复制代码 其中 CD-ROM属于“ 可移动盘”的范围。请注意,GET_MEDIA_TYPES结构本身只定义了一条 DEVICE_MEDIA_INFO,额外 的DEVICE_MEDIA_INFO 需要紧接此结构的另外的空间。
|