Comment dresser la liste des disques physiques dans Windows ? Pour obtenir une liste des "\\\\.\PhysicalDrive0"
disponible.
-1 Ne répond pas à la question, qui est de savoir comment le faire en C.
Comment dresser la liste des disques physiques dans Windows ? Pour obtenir une liste des "\\\\.\PhysicalDrive0"
disponible.
wmic diskdrive list
fournir une liste (trop) détaillée, par exemple
pour moins d'informations
wmic diskdrive list brief
En C :
system("wmic diskdrive list");
Comme indiqué, vous pouvez également appeler la WinAPI, mais... comme indiqué dans " Comment obtenir des données de WMI à l'aide d'une application C ? "Il s'agit d'une opération assez complexe (et généralement réalisée en C++, et non en C).
Get-WmiObject Win32_DiskDrive
Mise à jour février 2022, Microsoft annonce dans " Les fonctionnalités de Windows 10 que nous ne développons plus "
L'outil WMIC est obsolète dans Windows 10, la version 21H1 et la version 21H1 General Availability Channel de Windows Server.
Cet outil est remplacé par Windows PowerShell pour WMI .
Note : Cette dépréciation ne s'applique qu'à l'option outil de gestion en ligne de commande . WMI lui-même n'est pas affecté.
Une façon de procéder :
Énumérer les lecteurs logiques à l'aide de GetLogicalDrives
Pour chaque lecteur logique, ouvrez un fichier nommé "\\.\X:"
(sans les guillemets) où X est la lettre du lecteur logique.
Llame a DeviceIoControl
en passant l'identifiant du fichier ouvert à l'étape précédente, et la fonction dwIoControlCode
paramètre réglé sur IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
:
HANDLE hHandle;
VOLUME_DISK_EXTENTS diskExtents;
DWORD dwSize;
[...]
iRes = DeviceIoControl(
hHandle,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
(LPVOID) &diskExtents,
(DWORD) sizeof(diskExtents),
(LPDWORD) &dwSize,
NULL);
Cette fonction renvoie des informations sur l'emplacement physique d'un volume logique, sous la forme d'un VOLUME_DISK_EXTENTS
structure.
Dans le cas simple où le volume réside sur un seul lecteur physique, le numéro du lecteur physique est disponible dans la rubrique diskExtents.Extents[0].DiskNumber
Il convient de noter que la mise en œuvre de DeviceIoControl(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)
échouera si un volume s'étend sur plusieurs disques. En d'autres termes, vous devez d'abord demander DeviceIoControl
pour la taille de VOLUME_DISK_EXTENTS
puis alloue cette quantité de mémoire, et enfin l'appelle à nouveau avec la mémoire tampon allouée. Cette méthode fonctionne de la manière indiquée ci-dessus parce que la plupart des volumes résident sur un seul disque.
Désolé, je ne peux pas ouvrir le fichier " \\.\C :" en utilisant CreateFile((_T(" \\.\C :"), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,///*FILE_FLAG_WRITE_THROUGH |*/FILE_FLAG_NO_BUFFERING, NULL) ; Pourriez-vous résoudre mon problème ?
C'est peut-être 5 ans trop tard :). Mais comme je ne vois pas de réponse pour l'instant, j'ajoute ceci.
Nous pouvons utiliser Mise en place des API pour obtenir la liste des disques, c'est-à-dire des périphériques dans le système mettant en œuvre GUID_DEVINTERFACE_DISK
.
Une fois que nous disposons des chemins d'accès de leurs appareils, nous pouvons émettre des IOCTL_STORAGE_GET_DEVICE_NUMBER
pour construire "\\.\PHYSICALDRIVE%d"
avec STORAGE_DEVICE_NUMBER.DeviceNumber
Voir aussi SetupDiGetClassDevs
fonction
#include <Windows.h>
#include <Setupapi.h>
#include <Ntddstor.h>
#pragma comment( lib, "setupapi.lib" )
#include <iostream>
#include <string>
using namespace std;
#define START_ERROR_CHK() \
DWORD error = ERROR_SUCCESS; \
DWORD failedLine; \
string failedApi;
#define CHK( expr, api ) \
if ( !( expr ) ) { \
error = GetLastError( ); \
failedLine = __LINE__; \
failedApi = ( api ); \
goto Error_Exit; \
}
#define END_ERROR_CHK() \
error = ERROR_SUCCESS; \
Error_Exit: \
if ( ERROR_SUCCESS != error ) { \
cout << failedApi << " failed at " << failedLine << " : Error Code - " << error << endl; \
}
int main( int argc, char **argv ) {
HDEVINFO diskClassDevices;
GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
DWORD requiredSize;
DWORD deviceIndex;
HANDLE disk = INVALID_HANDLE_VALUE;
STORAGE_DEVICE_NUMBER diskNumber;
DWORD bytesReturned;
START_ERROR_CHK();
//
// Get the handle to the device information set for installed
// disk class devices. Returns only devices that are currently
// present in the system and have an enabled disk device
// interface.
//
diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
NULL,
NULL,
DIGCF_PRESENT |
DIGCF_DEVICEINTERFACE );
CHK( INVALID_HANDLE_VALUE != diskClassDevices,
"SetupDiGetClassDevs" );
ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
deviceIndex = 0;
while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
NULL,
&diskClassDeviceInterfaceGuid,
deviceIndex,
&deviceInterfaceData ) ) {
++deviceIndex;
SetupDiGetDeviceInterfaceDetail( diskClassDevices,
&deviceInterfaceData,
NULL,
0,
&requiredSize,
NULL );
CHK( ERROR_INSUFFICIENT_BUFFER == GetLastError( ),
"SetupDiGetDeviceInterfaceDetail - 1" );
deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
CHK( NULL != deviceInterfaceDetailData,
"malloc" );
ZeroMemory( deviceInterfaceDetailData, requiredSize );
deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );
CHK( SetupDiGetDeviceInterfaceDetail( diskClassDevices,
&deviceInterfaceData,
deviceInterfaceDetailData,
requiredSize,
NULL,
NULL ),
"SetupDiGetDeviceInterfaceDetail - 2" );
disk = CreateFile( deviceInterfaceDetailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
CHK( INVALID_HANDLE_VALUE != disk,
"CreateFile" );
CHK( DeviceIoControl( disk,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL,
0,
&diskNumber,
sizeof( STORAGE_DEVICE_NUMBER ),
&bytesReturned,
NULL ),
"IOCTL_STORAGE_GET_DEVICE_NUMBER" );
CloseHandle( disk );
disk = INVALID_HANDLE_VALUE;
cout << deviceInterfaceDetailData->DevicePath << endl;
cout << "\\\\?\\PhysicalDrive" << diskNumber.DeviceNumber << endl;
cout << endl;
}
CHK( ERROR_NO_MORE_ITEMS == GetLastError( ),
"SetupDiEnumDeviceInterfaces" );
END_ERROR_CHK();
Exit:
if ( INVALID_HANDLE_VALUE != diskClassDevices ) {
SetupDiDestroyDeviceInfoList( diskClassDevices );
}
if ( INVALID_HANDLE_VALUE != disk ) {
CloseHandle( disk );
}
return error;
}
Ajout d'un autre lien (je n'avais pas assez de rep pour le poster dans la réponse) Fonctions de l'API de configuration
Noter que ces fonctions de l'interface SetupAPI pas seulement liste tous physique mais aussi des disques virtuels - en fait tous lecteur de disque enregistré interface sera listée, il me semble que cette peut L'utilisation de SetupAPI est beaucoup plus complexe que ce qui est suggéré dans cette réponse.
J'ai modifié un programme open-source appelé "dskwipe" afin d'en extraire les informations relatives au disque. Dskwipe est écrit en C, et vous pouvez en tirer cette fonction. Le binaire et les sources sont disponibles ici : dskwipe 0.3 est disponible
Les informations renvoyées ressembleront à ceci :
Device Name Size Type Partition Type
------------------------------ --------- --------- --------------------
\\.\PhysicalDrive0 40.0 GB Fixed
\\.\PhysicalDrive1 80.0 GB Fixed
\Device\Harddisk0\Partition0 40.0 GB Fixed
\Device\Harddisk0\Partition1 40.0 GB Fixed NTFS
\Device\Harddisk1\Partition0 80.0 GB Fixed
\Device\Harddisk1\Partition1 80.0 GB Fixed NTFS
\\.\C: 80.0 GB Fixed NTFS
\\.\D: 2.1 GB Fixed FAT32
\\.\E: 40.0 GB Fixed NTFS
GetLogicalDrives() énumère toutes les partitions de disque montées, pas les lecteurs physiques.
Vous pouvez énumérer les lettres de lecteur avec (ou sans) GetLogicalDrives, puis appeler QueryDosDevice() pour savoir à quel lecteur physique la lettre est associée.
Vous pouvez également décoder les informations dans le registre à l'adresse HKEY_LOCAL_MACHINE \SYSTEM\MountedDevices. Le codage des données binaires n'est cependant pas évident. Si vous disposez d'un exemplaire du livre de Russinovich et Solomon, Microsoft Windows Internals, cette ruche de registre est abordée au chapitre 10.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.