WEB开发网
开发学院软件开发汇编语言 实战DeviceIoControl系列之二:获取软盘/硬盘/光盘... 阅读

实战DeviceIoControl系列之二:获取软盘/硬盘/光盘的参数

 2010-01-10 09:37:32 来源:WEB开发网   
核心提示:Q 调用方法我了解了,请用 VC举个例子来实现我所期待已久的功能吧?A 好,实战DeviceIoControl系列之二:获取软盘/硬盘/光盘的参数(2),现在就演示 一下如何取软盘/硬盘/光盘的参数,测试时, GetDiskGeometry.h //#if !defined(GET_DISK_GEOMETRY_H__)

Q 调用方法我了解了,请用 VC举个例子来实现我所期待已久的功能吧? 

A 好,现在就演示 一下如何取软盘/硬盘/光盘的参数。测试时,记得要有软盘/

光盘插在驱动器里喔! 

首 先,用 MFC AppWizard 生成一个单文档的应用程序,取名为DiskGeometry,让它的 View基于 CEditView。 

然后,添加以下的.h 和.cpp 文件。 

/////////////////////////////////////////////////////////////////////
/////////
// GetDiskGeometry.h /////////////////////////////////////////////////////////////////////
/////////

#if !defined(GET_DISK_GEOMETRY_H__)
#define GET_DISK_GEOMETRY_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <winioctl.h>

BOOL GetDriveGeometry(const char* filename, DISK_GEOMETRY *pdg);

#endif // !defined(GET_DISK_GEOMETRY_H__)

/////////////////////////////////////////////////////////////////////
/////////
// GetDiskGeometry.cpp
/////////////////////////////////////////////////////////////////////
/////////

#include "stdafx.h"
#include "GetDiskGeometry.h"

// IOCTL_STORAGE_GET_MEDIA_TYPES_EX可能返回不止一条DEVICE_MEDIA_INFO,
故定义足够的 空间
#define MEDIA_INFO_SIZE  
sizeof(GET_MEDIA_TYPES)+15*sizeof (DEVICE_MEDIA_INFO)  
// filename -- 用于设备的文件名
// pdg -- 参数缓冲区指针
BOOL GetDriveGeometry(const char* filename, DISK_GEOMETRY *pdg)
{
   HANDLE hDevice;     // 设备句柄
  BOOL bResult;      // DeviceIoControl 的 返回结果
  GET_MEDIA_TYPES *pmt;  // 内部用的输出缓冲区
  DWORD dwOutBytes;     // 输出数据长度

  // 打开设备
  hDevice = ::CreateFile(filename,       // 文件名
    GENERIC_READ,             // 软驱需要读盘
    FILE_SHARE_READ | FILE_SHARE_WRITE,  // 共享方式
    NULL,                  // 默认的安全描述符
    OPEN_EXISTING,              // 创建方式
    0,                   // 不需设置文件属性
    NULL);                 // 不需参照模板文件

  if (hDevice == INVALID_HANDLE_VALUE)
  {
    // 设备无法打开...
     return FALSE;
  }

  // 用 IOCTL_DISK_GET_DRIVE_GEOMETRY 取磁盘参数
  bResult = ::DeviceIoControl(hDevice,    // 设备句柄
     IOCTL_DISK_GET_DRIVE_GEOMETRY,     // 取磁盘参数
    NULL, 0,                 // 不需要输入数据
     pdg, sizeof(DISK_GEOMETRY),      // 输出数据 缓冲区
    &dwOutBytes,              // 输出数据长度
     (LPOVERLAPPED)NULL);          // 用同步 I/O

  // 如果失败,再用 IOCTL_STORAGE_GET_MEDIA_TYPES_EX 取介质类型参数
  if (!bResult)
  {
     pmt = (GET_MEDIA_TYPES *)new BYTE[MEDIA_INFO_SIZE];

    bResult = ::DeviceIoControl(hDevice,  // 设备句柄
       IOCTL_STORAGE_GET_MEDIA_TYPES_EX,  // 取介质类型参数
      NULL, 0,               // 不需要输入数据
      pmt, MEDIA_INFO_SIZE,        // 输出数据缓冲区
      &dwOutBytes,            // 输出数据长度
      (LPOVERLAPPED)NULL);        // 用同步 I/O

    if (bResult)
    {
      // 注意到结构 DEVICE_MEDIA_INFO 是在结构 DISK_GEOMETRY 的基础上扩充的
      // 为简化程序,用 memcpy 代替如下多条赋值语句 :
      // pdg->MediaType =
(MEDIA_TYPE)pmt->MediaInfo [0].DeviceSpecific.DiskInfo.MediaType;
      // pdg->Cylinders =
pmt- >MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
      // pdg- >TracksPerCylinder =
pmt->MediaInfo [0].DeviceSpecific.DiskInfo.TracksPerCylinder;
      // ... ...
       ::memcpy(pdg, pmt->MediaInfo, sizeof(DISK_GEOMETRY));     }

     delete pmt;
  }

  // 关闭设备句柄
  ::CloseHandle(hDevice);

  return (bResult);
}

Tags:实战 DeviceIoControl 系列

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接