Проблема с IoCreateFile + NtQueryVolumeInformationFile

Тема в разделе "WASM.WIN32", создана пользователем BLExeR, 8 май 2007.

  1. BLExeR

    BLExeR New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    3
    Здравствуйте, уважаемые участники Форума! На вас - последняя надежда=)

    Предыстрория.

    По SST перехватывается NtCreateFile/NtOpenFile, в обработчике идет проверка имени (только имени, путь не имеет значения) файла, далее, если файл тот, который нужен, необходимо заблокировать доступ к нему, но - только если он находится на сьемном диске. Тип диска узнаю примерно по тому же алгоритму, что реализован в GetDriveType - открываю директорию, в которой лежит файл, и вызываю NtQueryVolumeInformationFile.

    Суть проблемы банальна - NtQueryVolumeInformationFile возвращает STATUS_ACCESS_VIOLATION...

    Код (Text):
    1. HANDLE Directory;
    2.  
    3. InitializeObjectAttributes(
    4.     &DirectoryAttributes,
    5.     &DirectoryName,
    6.     OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    7.     NULL,
    8.     NULL);
    9.  
    10. Status = IoCreateFile(
    11.     &Directory,
    12.     GENERIC_READ,
    13.     &DirectoryAttributes,
    14.     &IoStatusBlock,
    15.     0,
    16.     0,
    17.     FILE_SHARE_READ,
    18.     FILE_OPEN,
    19.     FILE_DIRECTORY_FILE,
    20.     NULL,
    21.     0,
    22.     CreateFileTypeNone,
    23.     NULL,
    24.     IO_FORCE_ACCESS_CHECK);
    25.  
    26. if (NT_SUCCESS(Status))
    27. {
    28.     // сюда мы доходим, но вот Status дальше получаем равным STATUS_ACCESS_VIOLATION 
    29.  
    30.     Status = NtQueryVolumeInformationFile(
    31.         RootDirectoryHandle,
    32.         &IoStatusBlock,
    33.         &FileFsDevice,
    34.         sizeof(FILE_FS_DEVICE_INFORMATION),
    35.         FileFsDeviceInformation);  
    36.  
    37.     if (NT_SUCCESS(Status))
    38.     {
    39.         ...
    40.     }
    41.     else
    42.         // это, своего рода, "грубая отладка":), т.к. нет возможности воспользоваться
    43.         // отладчиком
    44.         ExRaiseStatus(Status);
    45. }
    Может, кто-нибудь подскажет, что не так? Или, может быть, есть другой способ определения типа диска в ring0?

    P.S. Заранее благодарю и прошу прощения за возможную глупость ошибки или вопроса:)
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ZwQueryVolumeInformationFile?
     
  3. BLExeR

    BLExeR New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    3
    Zw версия дает тот же результат...
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Поищи по форуму.
    В похожей теме я и писал, что нужно чтобы IoStatusBlock и FileFsDevice лежали в usermode. Хотя там вроде для дургой функции это надо было, но думаю, что и для NtQueryVolumeInformationFile должно выполнятся такое условие.
     
  5. BLExeR

    BLExeR New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    3
    n0name
    Проблема решена: была она, оказывается, в том, что указан неверный запрашиваемый доступ в IoCreateFile (директории нельзя открывать с FILE_READ_DATA). Правда, IoCreateFile работать так и не захотел, в отличие от ZwCreateFile... Еще бы понять, почему...

    По поводу user-mode IoStatusBlock и FileFsDevice - а зачем, я же из kernel-mode вызываю ее? Если мапить (через mdl и т.п.) в user-mode, то привет BSOD'у KERNEL_MODE_EXCEPTION_NOT_HANDLED(STATUS_ACCESS_VIOLATION,...,...,...) при вызове NtQueryVolumeInformationFile:) Код про mdl брал отсюда.

    Код (Text):
    1. // это работает
    2.  
    3. Status = ZwCreateFile (
    4.          &Directory,
    5.          FILE_GENERIC_READ,
    6.          &DirectoryAttributes,
    7.          &IoStatusBlock,
    8.          NULL,
    9.          0,
    10.          FILE_SHARE_READ|FILE_SHARE_WRITE,
    11.          FILE_OPEN,
    12.          0,
    13.          NULL,
    14.          0);
    15.  
    16. // А вот это нет...
    17.  
    18. Status = IoCreateFile(
    19.     &Directory,
    20.     FILE_GENERIC_READ,
    21.     &DirectoryAttributes,
    22.     &IoStatusBlock,
    23.     0,
    24.     0,
    25.     FILE_SHARE_READ|FILE_SHARE_WRITE,
    26.     FILE_OPEN,
    27.     FILE_DIRECTORY_FILE,
    28.     NULL,
    29.     0,
    30.     CreateFileTypeNone,
    31.     NULL,
    32.     IO_FORCE_ACCESS_CHECK);
    33. // если IO_NO_PARAMETER_CHECKING, то STATUS_INVALID_PARAMETER, иначе STATUS_ACCESS_VIOLATION