60人参与 • 2025-03-14 • Windows
实现代码
cdiskdriveutils.h
#pragma once #include <wtypesbase.h> #include <string> #include <tchar.h> #include <vector> #include <map> #ifdef _unicode using _tstring = std::wstring; #else using _tstring = std::string; #endif namespace cdiskdriveutils { enum epartitionstyle { epartitionmbr, epartitiongpt, epartitionraw }; enum edrivetype { edriveunknown, edrivenorootdir, edriveremovable, edrivefixed, edriveremote, edrivecdrom, edriveramdisk }; enum estoragebustype { ebusunknown, ebusscsi, ebusatapi, ebusata, ebus1394, ebusssa, ebusfibre, ebususb, ebusraid, ebusiscsi, ebussas, ebussata, ebussd, ebusmmc, ebusvirtual, ebusfilebackedvirtual, ebusspaces, ebusnvme, ebusscm, ebusufs, ebusmax, ebusmaxreserved = 0x7f }; typedef struct _disk_partion_info { _tstring pathname; _tstring volumename; uint64_t startingoffset; uint64_t partitionlength; uint64_t freebytes; uint32_t partitionnumber; epartitionstyle partitionstyle; edrivetype drivetype; _disk_partion_info() : partitionnumber(0), partitionlength(0), startingoffset(0), freebytes(0), partitionstyle(epartitionstyle::epartitionraw), drivetype(edrivetype::edriveunknown) { } }disk_partion_info; typedef struct _logical_volume_info { _tstring pathname; _tstring volumename; _tstring filesystemname; uint64_t startingoffset; uint64_t extentlength; uint64_t freebytes; uint32_t disknumber; edrivetype drivetype; _logical_volume_info() : disknumber(0), startingoffset(0), extentlength(0), freebytes(0), drivetype(edrivetype::edriveunknown) { } }logical_volume_info; typedef struct _disk_info { _tstring devicepath; _tstring productid; _tstring serialnumber; _tstring adapterserialnumber; _tstring productrevision; _tstring bustypename; uint64_t disksize; uint64_t attributes; estoragebustype bustype; int16_t temperature; bool fremovablemedia; std::vector<disk_partion_info> partitions; _disk_info() : temperature(0), bustype(estoragebustype::ebusunknown), disksize(0), attributes(0), fremovablemedia(false) { } }disk_drive_info; std::map<uint32_t, disk_drive_info> getdiskdriveinfos(); bool getdiskdriveinfo(dword nindex, disk_drive_info& info); bool getlogicalvolumeinfo(std::vector<logical_volume_info>& vvolumeinfo); }
cdiskdriveutils.cpp
#include "cdiskdriveutils.h" #include <winioctl.h> #include <strsafe.h> #include <cstdint> namespace cdiskdriveutils { std::string _wstrtomultistr(uint codepage, const std::wstring& str) { int cbmultibyte = ::widechartomultibyte(codepage, 0, str.c_str(), -1, null, 0, null, null); std::string strresult(cbmultibyte, 0); size_t nconverted = ::widechartomultibyte(codepage, 0, str.c_str(), (int)str.size(), &strresult[0], (int)strresult.size(), null, null); strresult.resize(nconverted); return strresult; } std::wstring _multistrtowstr(uint codepage, const std::string& str) { int cchwidechar = ::multibytetowidechar(codepage, 0, str.c_str(), -1, null, 0); std::wstring strresult(cchwidechar, 0); size_t nconverted = ::multibytetowidechar(codepage, 0, str.c_str(), (int)str.size(), &strresult[0], (int)strresult.size()); strresult.resize(nconverted); return strresult; } _tstring wstrtotstr(const std::wstring& str) { #ifdef _unicode return str; #else return _wstrtomultistr(cp_acp, str); #endif } _tstring astrtotstr(const std::string& str) { #ifdef _unicode return _multistrtowstr(cp_acp, str); #else return str; #endif } std::map<uint32_t, disk_drive_info> getdiskdriveinfos() { std::map<uint32_t, disk_drive_info> result; for (int i = 0; i < 1000; i++) { disk_drive_info info; if (getdiskdriveinfo(i, info)) { result.emplace(i, info); } } return result; } void removebackspace(_tstring& strname) { size_t nlength = strname.size(); for (auto it = strname.crbegin(); it != strname.crend(); it++) { if (_t(' ') == *it) { nlength--; } else { break; } } strname.resize(nlength); } bool getdiskdriveinfo(dword nindex, disk_drive_info& info) { tchar szfilename[max_path] = { 0 }; handle hfile = invalid_handle_value; dword dwbytesreturned = 0; bool bsuccess = false; do { (void)::stringcchprintf(szfilename, _countof(szfilename), _t(r"(\\.\physicaldrive%d)"), nindex); dword dwdesiredaccess = generic_read | generic_write; dword dwsharemode = file_share_read | file_share_write | file_share_delete; hfile = ::createfile(szfilename, dwdesiredaccess, dwsharemode, null, open_existing, 0, null); if (invalid_handle_value == hfile) { break; } storage_property_query storagequery = { }; storagequery.propertyid = storagedeviceproperty; storagequery.querytype = propertystandardquery; std::vector<uint8_t> outbuffer(1024 * 64); info.devicepath = szfilename; if (::deviceiocontrol(hfile, ioctl_storage_query_property, &storagequery, sizeof(storagequery), outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pstorage_device_descriptor pdesc = (pstorage_device_descriptor)outbuffer.data(); info.productid = astrtotstr((lpcstr)((lpbyte)pdesc + pdesc->productidoffset)); info.productrevision = astrtotstr((lpcstr)((lpbyte)pdesc + pdesc->productrevisionoffset)); info.serialnumber = astrtotstr((lpcstr)((lpbyte)pdesc + pdesc->serialnumberoffset)); info.bustype = (estoragebustype)pdesc->bustype; info.fremovablemedia = pdesc->removablemedia; removebackspace(info.productid); } storagequery.propertyid = storagedevicetemperatureproperty; if (::deviceiocontrol(hfile, ioctl_storage_query_property, &storagequery, sizeof(storagequery), outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pstorage_temperature_data_descriptor pdesc = (pstorage_temperature_data_descriptor)outbuffer.data(); info.temperature = pdesc->temperatureinfo->temperature; } storagequery.propertyid = storageadapterserialnumberproperty; if (::deviceiocontrol(hfile, ioctl_storage_query_property, &storagequery, sizeof(storagequery), outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pstorage_adapter_serial_number pdesc = (pstorage_adapter_serial_number)outbuffer.data(); info.adapterserialnumber = wstrtotstr(pdesc->serialnumber); } if (::deviceiocontrol(hfile, ioctl_disk_get_drive_geometry_ex, null, 0, outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pdisk_geometry_ex pdesc = (pdisk_geometry_ex)outbuffer.data(); info.disksize = *(unsigned long long*) & pdesc->disksize; } if (::deviceiocontrol(hfile, ioctl_disk_get_drive_layout_ex, null, 0, outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pdrive_layout_information_ex pdesc = (pdrive_layout_information_ex)outbuffer.data(); for (dword i = 0; i < pdesc->partitioncount; i++) { ppartition_information_ex ppartinfo = &pdesc->partitionentry[i]; if (0 == ppartinfo->partitionnumber) { continue; } disk_partion_info partioninfo; partioninfo.partitionstyle = (epartitionstyle)ppartinfo->partitionstyle; partioninfo.partitionlength = ppartinfo->partitionlength.quadpart; partioninfo.partitionnumber = ppartinfo->partitionnumber; partioninfo.startingoffset = ppartinfo->startingoffset.quadpart; info.partitions.push_back(partioninfo); } } if (::deviceiocontrol(hfile, ioctl_disk_get_disk_attributes, null, 0, outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pget_disk_attributes pdesc = (pget_disk_attributes)outbuffer.data(); info.attributes = pdesc->attributes; } if (::deviceiocontrol(hfile, ioctl_disk_get_cache_information, null, 0, outbuffer.data(), outbuffer.size(), &dwbytesreturned, null)) { pdisk_cache_information pdesc = (pdisk_cache_information)outbuffer.data(); pdesc = (pdisk_cache_information)outbuffer.data(); } // 从卷信息设置分区信息 std::vector<logical_volume_info> vvolumeinfo; (void)getlogicalvolumeinfo(vvolumeinfo); for (auto& partition : info.partitions) { for (const auto& volume : vvolumeinfo) { if (nindex == volume.disknumber && partition.startingoffset == volume.startingoffset) { partition.pathname = volume.pathname; partition.volumename = volume.volumename; partition.freebytes = volume.freebytes; partition.drivetype = volume.drivetype; break; } } } bsuccess = true; } while (false); if (invalid_handle_value != hfile) { ::closehandle(hfile); } return bsuccess; } bool getlogicalvolumeinfo(std::vector<logical_volume_info>& vvolumeinfo) { char szoutbuffer[1024] = { 0 }; tchar szbuf[max_path] = { 0 }; dword dwbytesreturned = 0; if (0 == getlogicaldrivestrings(_countof(szbuf), szbuf)) { return false; } lpctstr lpdrivestring = szbuf; while (_t('\0') != *lpdrivestring) { tchar szdevicebuf[max_path] = { 0 }; handle hdevice = invalid_handle_value; ::stringcchcopy(szdevicebuf, _countof(szdevicebuf), _t(r"(\\.\)")); ::stringcchcatn(szdevicebuf, _countof(szdevicebuf), lpdrivestring, 2); hdevice = ::createfile(szdevicebuf, generic_read | generic_write, file_share_read | file_share_write, null, open_existing, file_flag_sequential_scan, null); if (invalid_handle_value == hdevice) { lpdrivestring += 4; continue; } if (::deviceiocontrol(hdevice, ioctl_volume_get_volume_disk_extents, null, 0, &szoutbuffer, sizeof(szoutbuffer), &dwbytesreturned, null)) { pvolume_disk_extents pdesc = (pvolume_disk_extents)szoutbuffer; //当用户尝试获取有关没有软盘的软盘驱动器或没有光盘的 cd-rom 驱动器的信息时, //系统会显示一个消息框, 防止系统显示此消息框 (void)::seterrormode(sem_failcriticalerrors); //获取卷信息 (卷中的磁盘数可以跨多个磁盘) 。 for (dword i = 0; i < pdesc->numberofdiskextents; i++) { pdisk_extent pdiskextent = &pdesc->extents[i]; tchar szvolumename[max_path] = { 0 }; dword dwvolumeserialnumber = 0; dword dwmaximumcomponentlength = 0; dword dwfilesystemflags = 0; tchar szfilesystemname[max_path] = { 0 }; ::getvolumeinformation(lpdrivestring, szvolumename, _countof(szvolumename), &dwvolumeserialnumber, &dwmaximumcomponentlength, &dwfilesystemflags, szfilesystemname, _countof(szfilesystemname) ); ularge_integer freebytesavailabletocaller = { 0 }; ularge_integer totalnumberofbytes = { 0 }; ularge_integer totalnumberoffreebytes = { 0 }; getdiskfreespaceex(lpdrivestring, &freebytesavailabletocaller, &totalnumberofbytes, &totalnumberoffreebytes); logical_volume_info info; info.pathname = _tstring(lpdrivestring).substr(0, 2); info.volumename = szvolumename; info.filesystemname = szfilesystemname; info.disknumber = pdiskextent->disknumber; info.startingoffset = *(unsigned long long*) & pdiskextent->startingoffset; info.extentlength = *(unsigned long long*) & pdiskextent->extentlength; info.freebytes = totalnumberoffreebytes.quadpart; info.drivetype = (edrivetype)::getdrivetype(lpdrivestring); vvolumeinfo.push_back(info); } } ::closehandle(hdevice); lpdrivestring += 4; } return true; } }
main.cpp
#include <locale.h> #include <tchar.h> #include "win32utils/cdiskdriveutils.h" int _tmain(int argc, lpctstr argv[]) { setlocale(lc_all, ""); std::map<uint32_t, cdiskdriveutils::disk_drive_info> diskinfolist = cdiskdriveutils::getdiskdriveinfos(); return 0; }
结果如下
以上就是win32下c++实现快速获取硬盘分区信息的详细内容,更多关于c++获取硬盘分区信息的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论