Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, 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 (для большей информации)