Прочитать NT-like путь к разделу из символьной ссылки \SystemRoot, после чего найти в \GLOBAL?? символьную ссылку с буквой для этого пути. Но возможно, есть и более адекватный способ (например, с перечислением точек монтирования через IOCTL запросы к mount manager-у or something). UPD: Есть функция IoQueryFileDosDeviceName() которой можно скормить файл, открытый по NT-like пути и получить букву раздела.
Чем тебе IoQueryFileDosDeviceName не угодил? 1. Открываешь \SystemRoot\system32\ntdll.dll 2. Передаёшь File Object в IoQueryFileDosDeviceName. Всё.
Могу предложить крестьянское решение. Получи переменную windir откинь лишнее и останется буква. Если, конечно, тебе можно вызывать соотв. апи.
IoQueryFileDosDeviceName() Требует на вход FILE_OBJECT, как надо файл открывать, что бы его получить? или это HANDLE?
Попробовал следующее Открыть блокнот через ссылку на SystemRoot и узнать полное Дос имя файла Notepad.exe, но не удается сформировать Дос имя, где то ошибаюсь. Вечно либо BSOD или Exception Код (Text): void GetSystemDisk () { HANDLE hFile; OBJECT_ATTRIBUTES oaFileAttr; IO_STATUS_BLOCK iosb; UNICODE_STRING usFileName; NTSTATUS ntsRetStatus; PVOID foBuffer; OBJECT_NAME_INFORMATION** oniFileNameInfo; UNICODE_STRING usDriveLetter = {0}; PDEVICE_OBJECT pDev; RtlInitUnicodeString(&usFileName,L"\\SystemRoot\\Notepad.exe"); InitializeObjectAttributes(&oaFileAttr,&usFileName,OBJ_CASE_INSENSITIVE,NULL,NULL); ntsRetStatus = ZwOpenFile(&hFile,GENERIC_ALL,&oaFileAttr,&iosb,FILE_SHARE_READ,FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT); DbgPrint("ZwOpenFile status code 0x%x\n",ntsRetStatus); if (ntsRetStatus!=STATUS_SUCCESS) { return; } ntsRetStatus = ObReferenceObjectByHandle(hFile,FILE_ALL_ACCESS,*IoFileObjectType,KernelMode,&foBuffer,NULL); DbgPrint("ObReferenceObjectByHandle status code 0x%x\n",ntsRetStatus); if (ntsRetStatus!=STATUS_SUCCESS) { ZwClose(hFile); return; } __try{ if (PASSIVE_LEVEL == KeGetCurrentIrql()); { pDev = IoGetRelatedDeviceObject((PFILE_OBJECT)foBuffer); IFDEBUG(DbgPrint("pDev = 0x%x\n",pDev)); ntsRetStatus = IoVolumeDeviceToDosName(pDev,&usDriveLetter); //ntsRetStatus = IoQueryFileDosDeviceName(&foBuffer,oniFileNameInfo); //DbgPrint("IoVolumeDeviceToDosName status code 0x%x\n",ntsRetStatus); if (ntsRetStatus!=STATUS_SUCCESS) { ZwClose(hFile); return; } //DbgPrint("Drive Letter %S\n",usDriveLetter.Buffer); } } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("Exception Handled\n"); } ZwClose(hFile); return; }
Честно говоря, хз. Выглядит правильно, за исключением отсутствия ObDereferenceObject и ExFreePool, но это не должно быть причиной. Давай сюда !analyse -v чтоле.
drem1lin Для начала, вместо IoGetRelatedDeviceObject() попробуй тупо взять девайс из pFileObject -> DeviceObject. Если всё равно будет падать, покажи анализ дампа. Дальше видно будет.