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 (для большей информации)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.