4#include "Stroika/Foundation/StroikaPreComp.h"
6#if qStroika_Foundation_Common_Platform_Windows
21using namespace Stroika::Foundation::IO;
30#ifndef qCaptureDiskDeviceInfoWindows_
31#define qCaptureDiskDeviceInfoWindows_ 0
34#if qCaptureDiskDeviceInfoWindows_
38#pragma comment(lib, "Setupapi.lib")
39DEFINE_GUID (GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
51 sb <<
"Device-Name: "sv << fDeviceName;
53 sb <<
", Device-Kind: '"sv << *fDeviceKind <<
"'"sv;
56 sb <<
", Size-In-Bytes: "sv << *fSizeInBytes;
67#if qCaptureDiskDeviceInfoWindows_
69 list<wstring> GetPhysicalDiskDeviceInfo_ ()
71 HDEVINFO hDeviceInfoSet;
79 hDeviceInfoSet = ::SetupDiGetClassDevs (&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
80 if (hDeviceInfoSet == INVALID_HANDLE_VALUE) {
89 SP_DEVINFO_DATA deviceInfoData;
90 deviceInfoData.cbSize =
sizeof (SP_DEVINFO_DATA);
91 if (!::SetupDiEnumDeviceInfo (hDeviceInfoSet, ulMemberIndex, &deviceInfoData)) {
92 if (::GetLastError () == ERROR_NO_MORE_ITEMS) {
99 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
105 SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
106 deviceInterfaceData.cbSize =
sizeof (SP_DEVICE_INTERFACE_DATA);
107 if (!::SetupDiEnumDeviceInterfaces (hDeviceInfoSet, NULL, &GUID_DEVINTERFACE_DISK, ulMemberIndex, &deviceInterfaceData)) {
108 if (::GetLastError () == ERROR_NO_MORE_ITEMS) {
115 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
124 ULONG ulPropertyRegDataType = 0;
125 ULONG ulRequiredSize = 0;
126 ULONG ulBufferSize = 0;
127 BYTE* pbyBuffer = NULL;
128 if (!::SetupDiGetDeviceRegistryProperty (hDeviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, &ulPropertyRegDataType, NULL, 0, &ulRequiredSize)) {
129 if (::GetLastError () == ERROR_INSUFFICIENT_BUFFER) {
130 pbyBuffer = (BYTE*)::malloc (ulRequiredSize);
131 ulBufferSize = ulRequiredSize;
132 if (!::SetupDiGetDeviceRegistryProperty (hDeviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, &ulPropertyRegDataType,
133 pbyBuffer, ulBufferSize, &ulRequiredSize)) {
136 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
144 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
151 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
156 LPCWSTR pszHardwareId = (LPCWSTR)pbyBuffer;
160 SP_DEVICE_INTERFACE_DETAIL_DATA* pDeviceInterfaceDetailData = NULL;
161 ULONG ulDeviceInterfaceDetailDataSize = 0;
163 bOk = ::SetupDiGetDeviceInterfaceDetail (hDeviceInfoSet, &deviceInterfaceData, pDeviceInterfaceDetailData,
164 ulDeviceInterfaceDetailDataSize, &ulRequiredSize, NULL);
166 ulErrorCode = ::GetLastError ();
167 if (ulErrorCode == ERROR_INSUFFICIENT_BUFFER) {
170 pDeviceInterfaceDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)::malloc (ulRequiredSize);
171 pDeviceInterfaceDetailData->cbSize =
sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
172 ulDeviceInterfaceDetailDataSize = ulRequiredSize;
173 deviceInfoData.cbSize =
sizeof (SP_DEVINFO_DATA);
174 bOk = ::SetupDiGetDeviceInterfaceDetail (hDeviceInfoSet, &deviceInterfaceData, pDeviceInterfaceDetailData,
175 ulDeviceInterfaceDetailDataSize, &ulRequiredSize, &deviceInfoData);
176 ulErrorCode = ::GetLastError ();
183 ::free (pDeviceInterfaceDetailData);
184 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
192 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
196 disks.push_back (pDeviceInterfaceDetailData->DevicePath);
199 ::free (pDeviceInterfaceDetailData);
206 ::SetupDiDestroyDeviceInfoList (hDeviceInfoSet);
214 filesystem::path GetPhysNameForDriveNumber_ (
unsigned int i)
219 return "\\\\.\\PhysicalDrive{}"_f(i).As<filesystem::path> ();
226#if qStroika_Foundation_Common_Platform_Windows
227#if qCaptureDiskDeviceInfoWindows_ && 0
228 for (
const auto& s : GetPhysicalDiskDeviceInfo_ ()) {
233 for (
int i = 0; i < 64; ++i) {
234 HANDLE hHandle = ::CreateFileW (GetPhysNameForDriveNumber_ (i).c_str (), GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING,
235 FILE_ATTRIBUTE_NORMAL,
nullptr);
236 if (hHandle == INVALID_HANDLE_VALUE) {
239 GET_LENGTH_INFORMATION li{};
241 DWORD dwBytesReturned{};
242 BOOL bResult = ::DeviceIoControl (hHandle, IOCTL_DISK_GET_LENGTH_INFO,
nullptr, 0, &li,
sizeof (li), &dwBytesReturned,
nullptr);
244 DbgTrace (
"failed - DeviceIoControl - IOCTL_DISK_GET_LENGTH_INFO - ignored"_f);
248 DISK_GEOMETRY driveInfo{};
250 DWORD dwBytesReturned{};
252 ::DeviceIoControl (hHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY,
nullptr, 0, &driveInfo,
sizeof (driveInfo), &dwBytesReturned,
nullptr);
254 DbgTrace (
"failed - DeviceIoControl - IOCTL_DISK_GET_DRIVE_GEOMETRY - ignored"_f);
258 ::CloseHandle (hHandle);
263 optional<BlockDeviceKind> deviceKind;
264 switch (driveInfo.MediaType) {
272 DiskInfoType di{GetPhysNameForDriveNumber_ (i), deviceKind,
static_cast<uint64_t
> (li.Length.QuadPart)};
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
a cross between Mapping<KEY, T> and Collection<T> and Set<T>
Containers::KeyedCollection< DiskInfoType, filesystem::path > GetAvailableDisks()
nonvirtual String ToString() const