获取硬盘个数,及硬盘的分区情况。

// disk_drive_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <Winioctl.h>
#include <stdlib.h>

typedef struct PartitionInfo {
    char                    chDrive;
    PARTITION_INFORMATION    info;
} PartitionInfo, *LPPartitionInfo;


typedef struct DiskInfo {
    int                        iPartitionSize;
    PPARTITION_INFORMATION    pPartitions;
} DiskInfo, *LPDiskInfo;

void PrintDiskDrives();
int GetAllDiskPartitionInfo (LPDiskInfo* lpDisks);
int GetAllLogicalDriveInfo (LPPartitionInfo* lpPartions);


int main(int argc, char* argv[])
{
    PrintDiskDrives ();

    getchar ();
    return 0;
}

bool IsPartitionEqual( PPARTITION_INFORMATION pPart1, PPARTITION_INFORMATION pPart2 ) 
{
    if (pPart1->BootIndicator == pPart2->BootIndicator &&
        pPart1->HiddenSectors == pPart2->HiddenSectors &&
        pPart1->PartitionLength.QuadPart == pPart2->PartitionLength.QuadPart &&
        pPart1->PartitionNumber == pPart2->PartitionNumber &&
        pPart1->PartitionType == pPart2->PartitionType &&
        pPart1->RecognizedPartition == pPart2->RecognizedPartition &&
        pPart1->RewritePartition == pPart2->RewritePartition &&
        pPart1->StartingOffset.QuadPart == pPart2->StartingOffset.QuadPart)
    {
        return true;
    }

    return false;
}

void PrintDiskDrives()
{
    LPDiskInfo lpDisks = NULL;
    LPPartitionInfo lpPartitions = NULL;
    int iDisks = GetAllDiskPartitionInfo (&lpDisks);
    int iDrives = GetAllLogicalDriveInfo (&lpPartitions);

    for (int i = 0; i < iDisks; ++i) {
        printf("Disk%d:", i);
        for (int k = 0; k < lpDisks [i].iPartitionSize; ++k) {
            for (int j = 0; j < iDrives; ++j) {
                if (IsPartitionEqual (&lpDisks [i].pPartitions[k], &lpPartitions [j].info)) {
                printf ("%c, ", lpPartitions [j].chDrive);
                    break;
                }
            }
        }
        printf("\n");
    }

    
    // free memory
    for (int j = 0; j < iDisks; ++j) {
        free (lpDisks [j].pPartitions);
    }
    free (lpDisks);

    free (lpPartitions);
}

int GetAllDiskPartitionInfo( LPDiskInfo* lpDisks )
{
    HKEY    hKEY;
    long    lRet;
    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
        0, 
        KEY_READ,
        &hKEY);
    if (lRet != ERROR_SUCCESS) {
        return 0;
    }
    
    int        iSize = 0;
    DWORD    dwType;
    DWORD    dwValue;
    DWORD    dwBufLen = sizeof(DWORD);
    __try {
    lRet = ::RegQueryValueEx (hKEY, "Count", NULL, &dwType, (BYTE*)&dwValue, &dwBufLen);
    if(lRet != ERROR_SUCCESS)     
    {
        __leave;//失败
    }

    *lpDisks = (LPDiskInfo) malloc (dwValue * sizeof (DiskInfo));

    for (UINT i = 0; i < dwValue; i++)
    {
        char   szDiskPos [128] = {0};
        sprintf(szDiskPos, "\\\\.\\PHYSICALDRIVE%u", i);
        
        HANDLE    hDevice = NULL;
        DWORD    nDiskBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度      
        DWORD    nDiskBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + sizeof(PARTITION_INFORMATION) * 104;//26*4      
        PDRIVE_LAYOUT_INFORMATION lpDiskPartInfo = (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);     
        
        if(lpDiskPartInfo == NULL)     
        {
            free (lpDiskPartInfo);
            continue;     
        }
        
        //将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL 
        memset(lpDiskPartInfo, 0, nDiskBufferSize);
        
        //////////////////////获得所有分区的信息/////////////////////////////////////// 
        hDevice = CreateFile(szDiskPos,
            GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
        
        if(hDevice == NULL) {
            free (lpDiskPartInfo);
            continue; 
        }
        
        /////////////获得某磁盘上的所有分区信息/////////////////////////
        BOOL fRet = DeviceIoControl(
            hDevice,
            IOCTL_DISK_GET_DRIVE_LAYOUT,     
            NULL,     
            0,
            (LPVOID) lpDiskPartInfo,
            (DWORD) nDiskBufferSize,
            (LPDWORD) &nDiskBytesRead,
            NULL
            );
        
        if (!fRet)
        {
            LPVOID lpMsgBuf;
            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &lpMsgBuf,
                0,
                NULL 
                );
            LocalFree( lpMsgBuf );       
            free (lpDiskPartInfo);
            CloseHandle(hDevice);
            continue;
        }
        
        //////////////////////////////导出分区信息///////////////////////////////////////      
        DWORD dwPartitionCount = lpDiskPartInfo->PartitionCount;
        int iPartitions = dwPartitionCount / 4;
        (*lpDisks)[iSize].pPartitions = (PPARTITION_INFORMATION)malloc (iPartitions * sizeof (PARTITION_INFORMATION));
        (*lpDisks)[iSize].iPartitionSize = 0;

        //永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0      
        ///////////////////依次获取导出某分区信息,并与目的驱动器进行比较///////////////////////////////////      
        for (UINT j = 0;j < dwPartitionCount; j += 4)//+4是因为只有下标为4的整数倍的值才是正确的引用      
        {
            memcpy (&((*lpDisks)[iSize].pPartitions [(*lpDisks)[iSize].iPartitionSize++]), &lpDiskPartInfo->PartitionEntry [j], sizeof (PARTITION_INFORMATION));
        }
        free(lpDiskPartInfo);
        CloseHandle(hDevice);
        ++iSize;
    }
    } __finally {
        if (hKEY != NULL) {
            RegCloseKey(hKEY);
        }
    }

    return iSize;
}

int GetAllLogicalDriveInfo( LPPartitionInfo* lpPartions )
{
    int iSize = 0;
    char szBuf [1024];
    GetLogicalDriveStrings (1024, szBuf);

    *lpPartions = (LPPartitionInfo) malloc (sizeof (PartitionInfo) * 26); // 26 个英文字母

    char szDrive [64] = {0};
    for (char* pszDrive = (char*)szBuf; pszDrive != NULL && *pszDrive != 0; pszDrive += strlen (pszDrive) + 1) {
        (*lpPartions)[iSize].chDrive = *pszDrive;

        wsprintf(szDrive, "\\\\.\\%c:", *pszDrive);
        HANDLE hDevice = CreateFile(szDrive,
            GENERIC_READ,
            FILE_SHARE_WRITE | FILE_SHARE_READ,
            NULL, 
            OPEN_EXISTING,
            0,
            NULL);
        if (hDevice == INVALID_HANDLE_VALUE)
            continue;

        DWORD dwNum;
        DeviceIoControl(hDevice, 
            IOCTL_DISK_GET_PARTITION_INFO,
            NULL,
            0,
            &(*lpPartions)[iSize++].info,
            sizeof(PARTITION_INFORMATION),
            &dwNum,
            NULL);
        CloseHandle(hDevice);
    }

    return iSize;
}
原文地址:https://www.cnblogs.com/lin1270/p/2951420.html