номер устройства по имени диска
От: ДимДимыч Украина http://klug.org.ua
Дата: 04.02.04 13:38
Оценка:
Привет всем.
Подскажите плиз, есть ли стандартные средства, чтобы по имеющемуся имени диска ("c:","d:" и т.д.) определить, на каком физическом IDE-устройстве (IDE0, IDE1 и т.д.) этот диск находится?
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: номер устройства по имени диска
От: MShura  
Дата: 04.02.04 14:36
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Привет всем.

ДД>Подскажите плиз, есть ли стандартные средства, чтобы по имеющемуся имени диска ("c:","d:" и т.д.) определить, на каком физическом IDE-устройстве (IDE0, IDE1 и т.д.) этот диск находится?
Есть, но они сильно зависят от OS.
Re[2]: номер устройства по имени диска
От: ДимДимыч Украина http://klug.org.ua
Дата: 04.02.04 15:01
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Есть, но они сильно зависят от OS.


сорри, забыл указать: интересует для Windows NT, ядро 5.0 и выше.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[3]: номер устройства по имени диска
От: MShura  
Дата: 04.02.04 16:44
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, MShura, Вы писали:


MS>>Есть, но они сильно зависят от OS.


ДД>сорри, забыл указать: интересует для Windows NT, ядро 5.0 и выше.


Один из вариантов (юзать имена напрямую, см WinObj):

QueryDosDevice( "C:\", ... )
Получаешь строку вида

"\Device\HardDiskVolume1"



Затем перебираешь имена (см ниже) вида:
"\Device\HardDisk(N)\Partition(M)", где N — 0,1,2 — физические диски, M = 1,2,3, номера разделов на этих дисках.

Для каждого из имен получаешь линк того-же вида

"\Device\HardDiskVolume(X)", где X — 1,2,3, — номер тома в системе

Как только линк совпал с заданным, у тебя есть и N и M.

Перебирать имена надо с помощью функций из ntdll
Вот, например, моя функция:

///////////////////////////////////////////////////////////////////////////////////////////
// This function reads symbolic link
// pDirectory - Root ( f.e. L"\\Device\\HardDisk0" )
// pName      - Value( f.e. L"Partition0" )
// pLink      - returned value
// dwMaxSize  - the size in symbols for in bytes
///////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS NtGetSymLink( IN WCHAR* pDirectory, IN WCHAR* pName,
                       OUT WCHAR* pLink, IN DWORD dwMaxSize )
{
  HANDLE            hDevice;
  UNICODE_STRING    uString;
  OBJECT_ATTRIBUTES ObjectAttributes;
  NTSTATUS          ntStatus;

  RtlInitUnicodeString( &uString, pDirectory );

  InitializeObjectAttributes ( &ObjectAttributes,
                               &uString,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL );

  ntStatus = NtOpenDirectoryObject( &hDevice, 1, &ObjectAttributes );
  if ( NT_SUCCESS( ntStatus ) )
  {
    HANDLE handle;

    RtlInitUnicodeString( &uString, pName );

    InitializeObjectAttributes ( &ObjectAttributes,
                                 &uString,
                                 OBJ_CASE_INSENSITIVE,
                                 hDevice,
                                 NULL );
    ntStatus = NtOpenSymbolicLinkObject( &handle, 1, &ObjectAttributes );
    if ( NT_SUCCESS( ntStatus ) )
    {
      ULONG  uLen;
      UNICODE_STRING uLink;
      uLink.Length        = 0;
      uLink.MaximumLength = (USHORT)(dwMaxSize / sizeof(WCHAR));
      uLink.Buffer        = pLink;
      ntStatus = NtQuerySymbolicLinkObject( handle, &uLink, &uLen );
      NtClose( handle );
    }
    NtClose( hDevice );
  }
  SetLastError( RtlNtStatusToDosError( ntStatus ) );
  return ntStatus;
}



Другой вариант более простой:
— открываешь раздел CreateFile( )
— юзаешь IOCTL_STORAGE_GET_DEVICE_NUMBER + IOCTL_DISK_GET_PARTITION_INFO (для большей информации)
Re[4]: номер устройства по имени диска
От: ДимДимыч Украина http://klug.org.ua
Дата: 04.02.04 17:19
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Другой вариант более простой:

MS>- открываешь раздел CreateFile( )
MS>- юзаешь IOCTL_STORAGE_GET_DEVICE_NUMBER + IOCTL_DISK_GET_PARTITION_INFO (для большей информации)

"Другой" вариант — то самое, что надо.
Огромное спасибо!
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[5]: номер устройства по имени диска
От: Аноним  
Дата: 05.02.04 11:12
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, MShura, Вы писали:


MS>>Другой вариант более простой:

MS>>- открываешь раздел CreateFile( )
MS>>- юзаешь IOCTL_STORAGE_GET_DEVICE_NUMBER + IOCTL_DISK_GET_PARTITION_INFO (для большей информации)

ДД>"Другой" вариант — то самое, что надо.

ДД>Огромное спасибо!

покажите плиз как этим IOCTL_STORAGE_GET_DEVICE_NUMBER пользоваться.
Re[6]: номер устройства по имени диска
От: MShura  
Дата: 05.02.04 12:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, ДимДимыч, Вы писали:


ДД>>Здравствуйте, MShura, Вы писали:


MS>>>Другой вариант более простой:

MS>>>- открываешь раздел CreateFile( )
MS>>>- юзаешь IOCTL_STORAGE_GET_DEVICE_NUMBER + IOCTL_DISK_GET_PARTITION_INFO (для большей информации)

ДД>>"Другой" вариант — то самое, что надо.

ДД>>Огромное спасибо!

А>покажите плиз как этим IOCTL_STORAGE_GET_DEVICE_NUMBER пользоваться.


Примерно так:

  HANDLE                hPart;
  DWORD                 Tmp;
  STORAGE_DEVICE_NUMBER Info;


  // Open partition
  hPart = CreateFileW( L"\\\\.\\G:", GENERIC_READ|GENERIC_WRITE,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
                        NULL );
  if ( INVALID_HANDLE_VALUE == hPart )
    dwErr = GetLastError();
  else if ( !DeviceIoControl( hPart, IOCTL_STORAGE_GET_DEVICE_NUMBER,
                              NULL, 0, 
                              &Info, sizeof(Info),
                              &dwTmp, NULL ) )
    ;// Error
  else if ( Tmp == sizeof(Info) )
  {
     // Use Info ...
  }
Re[6]: номер устройства по имени диска
От: ДимДимыч Украина http://klug.org.ua
Дата: 05.02.04 12:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>покажите плиз как этим IOCTL_STORAGE_GET_DEVICE_NUMBER пользоваться.


Вот кусок кода для примера:

const IOCTL_STORAGE_GET_DEVICE_NUMBER = $2D1080;
var Drives:packed array[0..127] of char;
    hDevice:dword;
    DrivePtr:integer;
    DeviceInfo:packed record  // структура для получения информации о диске
       DeviceType:dword;      // тип устройства
       DeviceNumber:dword;    // номер устройства
       PartitionNumber:dword; // номер партиции
    end;
    Result:string;
    BytesReturned:dword;
begin
     Result:='';
     // получаем список логических дисков
     if GetLogicalDriveStrings(128,Drives)=0 then Exit;
     DrivePtr:=0;
     // берем из списка по одному
     while boolean(Drives[DrivePtr]) do
     begin
          // выбираем из них фиксированные
          if GetDriveType(@Drives[DrivePtr])=DRIVE_FIXED then
          begin
               // получаем дескриптор на диск
               hDevice:=CreateFile(PChar('\\.\'+Drives[DrivePtr]+':'),
                                   GENERIC_READ or GENERIC_WRITE,
                                   FILE_SHARE_READ or FILE_SHARE_WRITE,
                                   nil, OPEN_EXISTING, 0, 0);
               if hDevice<>INVALID_HANDLE_VALUE then
                  // получаем информацию о диске
                  if DeviceIoControl(hDevice,
                                     IOCTL_STORAGE_GET_DEVICE_NUMBER,
                                     nil,0,@DeviceInfo,SizeOf(DeviceInfo),
                                     BytesReturned,nil) then
                  begin
                    Result:=Result+PChar(@Drives[DrivePtr])+#9+
                        'Device: '+IntToStr(DeviceInfo.DeviceNumber)+' / '+
                        'Patrition: '+IntToStr(DeviceInfo.PartitionNumber)+#13;
                    CloseHandle(hDevice);
                  end;
                end;
          // переходим на начало следующей записи
          while boolean(Drives[DrivePtr]) do Inc(DrivePtr);
          Inc(DrivePtr);
     end;
     MessageBox(0,PChar(Result),'Disk Info',MB_OK);
end.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[7]: номер устройства по имени диска
От: ДимДимыч Украина http://klug.org.ua
Дата: 05.02.04 13:05
Оценка: 1 (1)
Здравствуйте, ДимДимыч, Вы писали:

ДД> hDevice:=CreateFile(PChar('\\.\'+Drives[DrivePtr]+':'),

ДД> GENERIC_READ or GENERIC_WRITE,
ДД> FILE_SHARE_READ or FILE_SHARE_WRITE,
ДД> nil, OPEN_EXISTING, 0, 0);

еще: здесь лучше вместо "GENERIC_READ or GENERIC_WRITE" передавать 0, чтобы работало не только под администратором.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.