获取硬盘信息

#ifndef DISKINFORMATION_H
#define DISKINFORMATION_H

#include "stdafx.h"
#include <windows.h>
#include <vector>
#include <bitset>
#include <iostream>
#include <algorithm>
#include <utility>
#include <Winioctl.h>
#include <string>
#include <map>
#include "const.h"
using namespace std;

namespace NXJ
{
    typedef struct tagDiskInfomation
    {
        string m_strDiskName;
        string m_strTypeName;
        string m_strFileSystem;
        DWORD m_dwTotalMBytes;
        DWORD m_dwFreeMBytes;

        struct tagDiskInfomation()
        {
            m_dwFreeMBytes = 0;
            m_dwTotalMBytes = 0;
        }
    }DiskInfomation, * PDiskInfomation;

    class DiskInfo
    {
    public:
        BOOL MkDiskInfomation();
        vector<DiskInfomation> ReturnVecData() const;
        BOOL ReturnLastVolume(DiskInfomation &rDiskInformation) const;
        BOOL GetDskSize(ULONGLONG &llOfSectors, DWORD dwDiskNum = 0);
        BOOL GetDskSize2(ULONGLONG &llOfSectors, DWORD dwDiskNum = 0);
        BOOL GetVolSize(ULONGLONG &llOfSectors, string strVolName);
        DWORD GetDrvNum();
        string GetDrvTypeItem(string dir);
        FS GetFileSystemType(string dir);
        BOOL GetFreSpa(string dir, __int64 &ri64FreeBytesToCaller, __int64 &ri64TotalBytes);
    private:
        vector<DiskInfomation> m_vecDskInf;
    private:
        BOOL ParseDrvString(IN DWORD dwDrvNum,OUT vector<string> &rvecDrvString);
    };
}

#endif

#include "DiskInformation.h"
using namespace NXJ;

BOOL NXJ::DiskInfo::MkDiskInfomation()
{
    DWORD dwDrvNum = GetDrvNum();
    vector<string> vecDrvString;
    if (ParseDrvString(dwDrvNum, vecDrvString))
    {
        for (vector<string>::const_iterator cit = vecDrvString.begin(); cit != vecDrvString.end(); ++ cit)
        {
            //deal every driver
            NXJ::DiskInfomation dskinf;

            //add disk name
            dskinf.m_strDiskName = *cit;
            //add disk type
            dskinf.m_strTypeName = GetDrvTypeItem(*cit);
            //add filesystem type
            switch(GetFileSystemType(*cit))
            {
            case FAT32:
                dskinf.m_strFileSystem = "FAT32";
                break;
            case NTFS:
                dskinf.m_strFileSystem = "NTFS";
                break;
            default:
                dskinf.m_strFileSystem = "OTHER";
                break;
            }
            //add space information
            if (dskinf.m_strTypeName == "磁盘分区" && dskinf.m_strFileSystem != "OTHER")
            {
                __int64 i64TotalBytes = 0, i64FreeBytes = 0;
                if (GetFreSpa(*cit, i64FreeBytes, i64TotalBytes))
                {
                    dskinf.m_dwFreeMBytes = i64FreeBytes / 1000 / 1000;
                    dskinf.m_dwTotalMBytes = i64TotalBytes / 1000 / 1000;
                }
                else
                {
                    dskinf.m_dwFreeMBytes = 0;
                    dskinf.m_dwTotalMBytes = 0;
                }
                //make vector data
                m_vecDskInf.push_back(dskinf);
            }
        }
        return TRUE;
    }

    return FALSE;
}

vector<NXJ::DiskInfomation> NXJ::DiskInfo::ReturnVecData() const
{
    return m_vecDskInf;
}

DWORD NXJ::DiskInfo::GetDrvNum()
{
    DWORD dwDrvNum = GetLogicalDrives();
    bitset<32> bitDrvNum(dwDrvNum);
    dwDrvNum = bitDrvNum.count();
    //cout << "there are " << dwDrvNum << " drivers in your machine !" << endl;

    return dwDrvNum;
}

//n个driver,以A:/null的形式存放的话,需4n个字符的数组,猜想,实际获得4n+1个字符的数组,可见末尾是以nullnull结束字符数组
BOOL NXJ::DiskInfo::ParseDrvString(IN DWORD dwDrvNum,OUT vector<string> &rvecDrvString)
{
    //通过GetLogicalDriveStrings()函数获取所有驱动器字符串信息长度。
    DWORD dwLength = GetLogicalDriveStrings(0,NULL);

    //用获取的长度在堆区创建一个c风格的字符串数组
    char* DStr = new char[dwLength];
    dwLength = GetLogicalDriveStrings(dwLength,(LPTSTR)DStr);
    if (!dwLength)
    {
        delete [] DStr;
        return FALSE;
    }

    DWORD dwIndex = 0;
    while (dwIndex < dwDrvNum)
    {
        string tmp = DStr + 4 * dwIndex;
        rvecDrvString.push_back(tmp);
        dwIndex ++;
    }
    delete [] DStr;
    return TRUE;
}

string NXJ::DiskInfo::GetDrvTypeItem(string dir)
{
    UINT uiType = GetDriveType(dir.c_str());
    switch(uiType)
    {
    case DRIVE_UNKNOWN:
        return "未知设备";
    case DRIVE_REMOVABLE:
        return "可移动设备";
    case DRIVE_FIXED:
        return "磁盘分区";
    case DRIVE_REMOTE:
        return "网络磁盘";
    case DRIVE_CDROM:
        return "光驱";
    case DRIVE_RAMDISK:
        return "虚拟磁盘";
    default:
        return "无效路径";
    }
}

NXJ::FS NXJ::DiskInfo::GetFileSystemType(string dir)
{
    //对于光驱信息的需排除之
    dir = dir[0];
    dir += ":";
    dir = ".//" + dir;

    HANDLE hVolum = CreateFile(dir.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE ,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hVolum)
    {
        return OTHER;
    }

    FILESYSTEM_STATISTICS FSS;
    DWORD dwBytesReturned = 0;
    BOOL bIsOk = DeviceIoControl(hVolum, FSCTL_FILESYSTEM_GET_STATISTICS, NULL, 0,
        &FSS, sizeof(FSS), &dwBytesReturned, NULL);
    if (!bIsOk && GetLastError() != ERROR_MORE_DATA)
    {
        if (INVALID_HANDLE_VALUE != hVolum)
        {
            CloseHandle(hVolum);
        }
        return OTHER;
    }
    {
        if(FSS.FileSystemType == FILESYSTEM_STATISTICS_TYPE_FAT)
        {
            if (INVALID_HANDLE_VALUE != hVolum)
            {
                CloseHandle(hVolum);
            }
            return FAT32;
        }
        else
        {
            if (INVALID_HANDLE_VALUE != hVolum)
            {
                CloseHandle(hVolum);
            }
            return NTFS;
        }
    }
}

BOOL NXJ::DiskInfo::GetFreSpa(string dir, __int64 &ri64FreeBytesToCaller, __int64 &ri64TotalBytes)
{
    typedef BOOL (WINAPI *PGETDISKFREESPACEEX)(LPCSTR,
        PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);

    PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
    __int64 i64FreeBytes;

    BOOL fResult;

    pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress(
        GetModuleHandle("kernel32.dll"),
        "GetDiskFreeSpaceExA");

    if (pGetDiskFreeSpaceEx)
    {
        fResult = pGetDiskFreeSpaceEx (dir.c_str(), (PULARGE_INTEGER)&ri64FreeBytesToCaller,
            (PULARGE_INTEGER)&ri64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes);
        // Process GetDiskFreeSpaceEx results.
        /*
        if(fResult)
        {
            printf("Total free bytes = %I64d/n", i64FreeBytes);
            printf("Total FreeBytesToCaller = %I64d/n", ri64FreeBytesToCaller);
            printf("Total TotalBytes = %I64d/n", ri64TotalBytes);
        }
        */
        return fResult;
    }
    else
    {
        return FALSE;
    }
}

BOOL NXJ::DiskInfo::ReturnLastVolume(NXJ::DiskInfomation &DiskInformation) const
{
    map<LONGLONG, string> mapVolumeByStartAddress;
    vector<NXJ::DiskInfomation>::const_iterator cit = m_vecDskInf.begin();
    for (; cit != m_vecDskInf.end(); ++ cit)
    {
        //such as "//./C"
        string strVolNam = cit -> m_strDiskName;

        strVolNam = strVolNam[0];
        strVolNam += ":";
        strVolNam = ".//" + strVolNam;

        HANDLE hVolum = CreateFile(strVolNam.c_str(), GENERIC_READ | GENERIC_WRITE,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING,
                                   0, NULL);
        if (INVALID_HANDLE_VALUE == hVolum)
        {
            return FALSE;
        }
       
        BOOL bIsOk;
        DWORD dwReturnBytes = 0;
        VOLUME_DISK_EXTENTS vde;
       
        bIsOk = DeviceIoControl(hVolum, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS , NULL, 0,
            &vde, sizeof(vde), &dwReturnBytes, NULL);
        if (bIsOk)
        {
            mapVolumeByStartAddress.insert(make_pair(vde.Extents[0].StartingOffset.QuadPart, cit -> m_strDiskName));
        }
        else if (GetLastError() == ERROR_MORE_DATA)
        {
            mapVolumeByStartAddress.insert(make_pair(vde.Extents[0].StartingOffset.QuadPart, cit -> m_strDiskName));
        }
        else
        {
            if (hVolum != INVALID_HANDLE_VALUE)
            {
                CloseHandle(hVolum);
            }
            return FALSE;
        }

        if (hVolum != INVALID_HANDLE_VALUE)
        {
            CloseHandle(hVolum);
        }
    }

    for (cit = m_vecDskInf.begin(); cit != m_vecDskInf.end(); ++ cit)
    {
        if (cit -> m_strDiskName == mapVolumeByStartAddress.rbegin() -> second)
        {
            DiskInformation = *cit;
        }
    }

    return TRUE;
}

BOOL NXJ::DiskInfo::GetDskSize(ULONGLONG &llOfSectors, DWORD dwDiskNum/* = */)
{
    string strDiskName = ".//PHYSICALDRIVE";
    char szindx[2] = {'/0', '/0'};
    _itoa_s(dwDiskNum, szindx, 2, 10);
    strDiskName += szindx;

    HANDLE hDisk = CreateFile(strDiskName.c_str(), GENERIC_READ | GENERIC_WRITE,
                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                              OPEN_EXISTING, NULL, NULL);
    if (INVALID_HANDLE_VALUE == hDisk)
    {
        GetLastError();
        return FALSE;
    }

    BOOL bIsOk;
    DWORD dwReturnBytes = 0;
    GET_LENGTH_INFORMATION gli;

    bIsOk = DeviceIoControl(hDisk, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), &dwReturnBytes, NULL);
    if (!bIsOk)
    {
        GetLastError();
        if (INVALID_HANDLE_VALUE != hDisk)
        {
            CloseHandle(hDisk);
        }
        return FALSE;
    }

    llOfSectors = gli.Length.QuadPart / 512;

    if (INVALID_HANDLE_VALUE != hDisk)
    {
        CloseHandle(hDisk);
    }
    return TRUE;
}

BOOL NXJ::DiskInfo::GetDskSize2(ULONGLONG &llOfSectors, DWORD dwDiskNum /* = 0 */)
{
    string strDiskName = ".//PHYSICALDRIVE";
    char szindx[2] = {'/0', '/0'};
    _itoa_s(dwDiskNum, szindx, 2, 10);
    strDiskName += szindx;

    HANDLE hDisk = CreateFile(strDiskName.c_str(), GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
        OPEN_EXISTING, NULL, NULL);
    if (INVALID_HANDLE_VALUE == hDisk)
    {
        GetLastError();
        return FALSE;
    }

    BOOL bIsOk;
    DWORD dwReturnBytes = 0;
    DISK_GEOMETRY_EX dge;

    bIsOk = DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &dge, sizeof(dge), &dwReturnBytes, NULL);
    if (!bIsOk)
    {
        if(GetLastError() != ERROR_MORE_DATA)
        {
                if (INVALID_HANDLE_VALUE != hDisk)
            {
                CloseHandle(hDisk);
            }
            return FALSE;
        }
    }

    llOfSectors = dge.DiskSize.QuadPart / 512;

    if (INVALID_HANDLE_VALUE != hDisk)
    {
        CloseHandle(hDisk);
    }
    return TRUE;
}

BOOL NXJ::DiskInfo::GetVolSize(ULONGLONG &llOfSectors, string strVolName)
{
    char szchar[2] = {strVolName[0], '/0'};
    string strVolumeName = szchar;
    strVolumeName = ".//" + strVolumeName;
    strVolumeName += ":";
   
    HANDLE hVolume = CreateFile(strVolumeName.c_str(), GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
        OPEN_EXISTING, NULL, NULL);
    if (INVALID_HANDLE_VALUE == hVolume)
    {
        GetLastError();
        return FALSE;
    }

    BOOL bIsOk;
    DWORD dwReturnBytes = 0;
    GET_LENGTH_INFORMATION gli;

    bIsOk = DeviceIoControl(hVolume, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli),&dwReturnBytes, NULL);
    if (!bIsOk)
    {
        GetLastError();
        if (INVALID_HANDLE_VALUE != hVolume)
        {
            CloseHandle(hVolume);
        }
        return FALSE;
    }

    llOfSectors = gli.Length.QuadPart / 512;

    if (INVALID_HANDLE_VALUE != hVolume)
    {
        CloseHandle(hVolume);
    }
    return TRUE;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值