zoukankan      html  css  js  c++  java
  • 获取硬盘个数,及硬盘的分区情况。

    // 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;
    }
  • 相关阅读:
    linux磁盘挂载
    3个方法解决百度网盘限速 (2018-07-20)
    mysql状态分析之show global status
    Cgroups子系统介绍
    Go语言 关键字:defer
    Go语言 map的实现
    Go语言 基本类型
    MySQL 监控指标
    sshpass的使用方法
    C++11 std::ref使用场景
  • 原文地址:https://www.cnblogs.com/lin1270/p/2951420.html
Copyright © 2011-2022 走看看