zoukankan      html  css  js  c++  java
  • windows的磁盘操作之四——根据逻辑分区号获得物理磁盘号(转)

    第一节中我们谈到了磁盘设备名称的两种形式:

    对于物理驱动器x,形式为\.PhysicalDriveX,编号从0开始,例如

    名称

    含义

    \.PhysicalDrive0

    打开第一个物理驱动器

    \.PhysicalDrive2

    打开第三个物理驱动器

    对于逻辑分区(卷),形式为\.X: ,例如

    名称

    含义

    \.A:

    打开A盘(软驱)

    \.C:

    打开C盘(磁盘逻辑分区)

     

    那么如何找出物理驱动器号0,1,2…… 和逻辑分区号C, D, E……之间的关系呢?本节讨论通过逻辑分区号获取所在物理驱动器号的方法,下一节讨论通过物理驱动器号找出其所包含的逻辑分区号的方法。当然,必定会存在其他思路实现同样的功能,欢迎大家补充。

    首先我们要明确,物理驱动器号和逻辑分区号应该是一对多的关系。例如disk0可能包含C, D, E三个分区。所以下面讨论的函数GetPhysicalDriveFromPartitionLetter返回一个单独的整型数。DeviceIoControl提供操作码IOCTL_STORAGE_GET_DEVICE_NUMBER,可以非常方便的获得打开设备的设备类型和设备号。

    代码如下

    /******************************************************************************

    * Function: get disk's physical number from its drive letter

    *           e.g. C-->0 (C: is on disk0)

    * input: letter, drive letter

    * output: N/A

    * return: Succeed, disk number

    *         Fail, -1

    ******************************************************************************/

    DWORD GetPhysicalDriveFromPartitionLetter(CHAR letter)

    {

        HANDLE hDevice;               // handle to the drive to be examined

        BOOL result;                 // results flag

        DWORD readed;                   // discard results

        STORAGE_DEVICE_NUMBER number;   //use this to get disk numbers

        CHAR path[DISK_PATH_LEN];

        sprintf(path, "\\.\%c:", letter);

        hDevice = CreateFile(path, // drive to open

                             GENERIC_READ | GENERIC_WRITE,    // access to the drive

                             FILE_SHARE_READ | FILE_SHARE_WRITE,    //share mode

                             NULL,             // default security attributes

                             OPEN_EXISTING,    // disposition

                             0,                // file attributes

                             NULL);            // do not copy file attribute

        if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

        {

            fprintf(stderr, "CreateFile() Error: %ld ", GetLastError());

            return DWORD(-1);

        }

        result = DeviceIoControl(

                    hDevice,                // handle to device

                    IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode

                    NULL,                            // lpInBuffer

                    0,                               // nInBufferSize

                    &number,           // output buffer

                    sizeof(number),         // size of output buffer

                    &readed,       // number of bytes returned

                    NULL      // OVERLAPPED structure

                );

        if (!result) // fail

        {

            fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld ", GetLastError());

            (void)CloseHandle(hDevice);

            return (DWORD)-1;

        }

        //printf("%d %d %d ", number.DeviceType, number.DeviceNumber, number.PartitionNumber);

        (void)CloseHandle(hDevice);

        return number.DeviceNumber;

    }

    代码分析:

    1. 根据分区号生成设备名称。

    2. 调用CreateFile打开设备并获得设备句柄。

    3. 调用操作码为IOCTL_STORAGE_GET_DEVICE_NUMBER的DeviceIoControl函数,输出为结构体变量STORAGE_DEVICE_NUMBER number。

    结构体STORAGE_DEVICE_NUMBER定义为

    typedef struct _STORAGE_DEVICE_NUMBER {

    DEVICE_TYPE  DeviceType;

    ULONG  DeviceNumber;

    ULONG  PartitionNumber;

    } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;

           其中DeviceNumber就是我们需要的物理磁盘号。

    4. 返回DeviceNumber。

  • 相关阅读:
    臭皮匠排序(Stooge Sort)----(排序算法十二)
    奇偶排序(OddEven Sort)----(排序算法十一)
    ArrayList,LinkList,HashMap
    简单实现 ArrayList
    java多态性理解
    this,super,和继承
    java内存分析
    java url生成二维码保存到本地
    spring开发中commons-logging.jar包的功能
    构建Mavne项目结构结构目录里只有src/main/resources
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/3387620.html
Copyright © 2011-2022 走看看