-
Есть например логический диск "C" или "E"
нужно определить номер физического диска, соответствующего этой букве спасибо
-
DeviceIoControl + IOCTL_STORAGE_GET_DEVICE_NUMBER ?
-
> DVM © (17.02.13 18:10) [1]
привет приведи пожалуйста более полный код я знаю, у тебя дофига опыта работы с внутренностями Windows )
-
procedure _GetLogicalDrives;
var
max: byte;
ld: DWORD;
i: integer;
letter: string;
hDevice,
BytesReturned: DWord;
DeviceInfo: Packed Record
DeviceType,
DeviceNumber,
PartitionNumber: DWord;
End;
VolumeName: array [0..MAX_PATH-1] of Char;
FileSystemName : array [0..MAX_PATH-1] of Char;
VolumeSerialNo : DWord;
MaxComponentLength : DWord;
FileSystemFlags : DWord;
begin
SetLength(LogicalDrives, 0);
ld := GetLogicalDrives;
for i := 0 to 25 do
if (ld and (1 shl i)) <> 0 then
begin
SetLength(LogicalDrives, High(LogicalDrives)+2);
letter:= Char(Ord('A') + i) + ':';
max:= High(LogicalDrives);
LogicalDrives[max].Letter:= letter[1];
SplashForm.LoadProgress('Iieo?aai eioi?iaoe? ii aeneo ' + letter);
ZeroMemory(@DeviceInfo, SizeOf(DeviceInfo));
hDevice := CreateFile(PChar('\\.\' + letter), GENERIC_READ,
FILE_SHARE_READ, Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hDevice <> INVALID_HANDLE_VALUE) and DeviceIoControl(hDevice,
IOCTL_STORAGE_GET_DEVICE_NUMBER, Nil, 0, @DeviceInfo,
SizeOf(DeviceInfo), BytesReturned, Nil) Then
begin
LogicalDrives[max].DeviceType:= DeviceInfo.DeviceType;
LogicalDrives[max].DeviceNumber:= DeviceInfo.DeviceNumber;
LogicalDrives[max].PartitionNumber:= DeviceInfo.PartitionNumber;
CloseHandle(hDevice);
end
else
begin
LogicalDrives[max].Error:= True;
end;
if not Windows.GetDiskFreeSpaceEx(PChar(letter), LogicalDrives[max].FreeBytesAvailableToCaller,
LogicalDrives[max].TotalNumberOfBytes, @LogicalDrives[max].TotalNumberOfFreeBytes) then LogicalDrives[max].Error:= True;
if Windows.GetVolumeInformation(PChar(letter + '\'), VolumeName, MAX_PATH, @VolumeSerialNo, MaxComponentLength,
FileSystemFlags, FileSystemName, MAX_PATH) then
begin
LogicalDrives[max].SerialNo:= IntToHex(Integer(VolumeSerialNo), 8);
LogicalDrives[max].Name:= VolumeName;
end
else
LogicalDrives[max].Error:= True;
end;
end; выдирай нужное
-
> DevilDevil © (17.02.13 18:30) [2]
как то так:
function GetDeviceNumberByLetter(ALetter: Char): Integer;
const
IOCTL_STORAGE_GET_DEVICE_NUMBER = $2D1080;
type
TDeviceInfo = packed record
DeviceType, DeviceNumber, PartitionNumber :dword
end;
var
hDevice: THandle;
BytesReturned: DWORD;
DeviceInfo: TDeviceInfo;
begin
Result := -1;
hDevice := CreateFile(PChar('\\.\' + ALetter + ':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
Win32Check(hDevice <> INVALID_HANDLE_VALUE);
try
Win32Check(DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @DeviceInfo, SizeOf(TDeviceInfo), BytesReturned, nil));
Result := DeviceInfo.DeviceNumber;
finally
CloseHandle(hDevice);
end;
end;
Но в обязательном порядке будет требовать запуска под Администратором. Для съемных дисков там по другому несколько.
-
обращаю внимание на DeviceInfo.PartitionNumber
-
> brother © (17.02.13 19:14) [5]
спасибо ! а почему DeviceInfo.PartitionNumber ?
-
> DVM © (17.02.13 19:12) [4]
я ж говорил, ты профи ) да, спасибо, работает. сейчас возьму именно этот вариант
-
> а почему DeviceInfo.PartitionNumber ?
на устройстве может быть несколько партиций, контролируй этот момент...
-
> brother © (17.02.13 19:28) [8]
мне надо именно DeviceNumber спасиб
-
Кстати одной букве может соответствовать несколько физических дисков. Правда это редкость.
-
Составной том - это динамический том, состоящий из дискового пространства на нескольких физических дисках.
-
> [11] Pavia © (17.02.13 19:57)
Ну так ещё в папку можно назначить диск.
-
> Pavia ©
прикольно )
-
> Pavia © (17.02.13 19:57) [11] > Составной том - это динамический том, состоящий из дискового > пространства на нескольких физических дисках.
этот составной том, как и raid массив считается одним физическим диском для системы
-
кстати, IOCTL_STORAGE_GET_DEVICE_NUMBER не определяет для диска C: (диск занят) ...
-
> brother © (19.02.13 13:10) [15]
у меня определяет (Win7), запускай под админом явно.
-
w7x64 d7 в коде ZeroMemory(@DeviceInfo, SizeOf(DeviceInfo));
hDevice := CreateFile(PChar('\\.\' + letter), GENERIC_READ,
FILE_SHARE_READ, Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hDevice <> INVALID_HANDLE_VALUE) and DeviceIoControl(hDevice,
IOCTL_STORAGE_GET_DEVICE_NUMBER, Nil, 0, @DeviceInfo,
SizeOf(DeviceInfo), BytesReturned, Nil) Then
begin
LogicalDrives[max].DeviceType:= DeviceInfo.DeviceType;
LogicalDrives[max].DeviceNumber:= DeviceInfo.DeviceNumber;
LogicalDrives[max].PartitionNumber:= DeviceInfo.PartitionNumber;
CloseHandle(hDevice);
end
else
begin
ShowMessage(SysErrorMessage(GetLastError));
LogicalDrives[max].Error:= True;
end; ругается: процесс не может получить доступ к файлу, тк этот файл занят другим процессом запускаю явно от админа
-
> brother © (19.02.13 15:22) [17]
а если FILE_ATTRIBUTE_NORMAL убрать? И после letter двоеточие есть?
-
|