Поведение файла ZwQueryDirectoryFile

#c #winapi #api #filesystems

#c #winapi #API #файловые системы

Вопрос:

Я узнаю из документации msdn об использовании API-интерфейсов ZwQueryDirectoryFile. Я озадачен одной конкретной функциональностью в нем.

Пример: в моем приложении используются только API уровня NT. Я должен извлечь файлы и каталоги в указанном родительском каталоге с помощью ZwQueryDirectoryFile. Я должен выделить буфер с неизвестной длиной. Итак, я хотел бы сделать это, выделив 4096 и получив объекты, подходящие по размеру, и должен выделить дополнительные, чтобы получить оставшиеся до ERROR_NO_MORE_FILES. FindNextFile использует ту же концепцию, вызывая ZwQueryDirectoryFile поэтапно с длиной буфера 4096. Итак, я предположил, что требование определенно выполнимо через api querydirectoryfile. Моя проблема в том, что когда я вызываю запрос directory file во второй раз, я не знаю, как сообщить API ZwQueryDirectoryFile, чтобы он возобновил предыдущее состояние выборки.

Ответ №1:

Вам нужно передать FALSE в RestartScan аргументе. Из документации:

Перезапуск сканирования [in]

Установите значение TRUE , если сканирование должно начинаться с первой записи в каталоге. Устанавливается в FALSE при возобновлении сканирования с предыдущего вызова.

Комментарии:

1. @Rajakymar, первый вызов ZwQueryDirectoryFile() вернет результат только ERROR_SUCCESS в том случае, если буфер достаточно велик, чтобы вместить хотя бы одну запись. Если этого не происходит, вам следует выделить буфер большего размера. При последующих вызовах функция установит для Information элемента переданной IO_STATUS_BLOCK структуры значение 0 , если буфер недостаточно велик. Если вы будете следовать этим подсказкам, это должно сработать.

2. спасибо вам за ваш help.it для меня работает, у меня остаются сомнения в этом поведении api, именно там он должен был сохранить смещение последней записи данных при первом вызове zwquerydirectoryfile .. либо в реестре, либо в тех же аргументах fn? как он передает смещение данных для возобновления из предыдущего состояния во 2-м вызове zwquerydirectoryfile.. Дайте мне знать, если вам об этом известно..

3. @Rajakumar, если я правильно понимаю ваш комментарий, вам не нужно сохранять смещение ввода данных между вызовами, поскольку функция не будет заполнять буфер неполными записями. Он будет продолжать пытаться разместить текущую запись, пока вы не предоставите буфер, достаточно большой, чтобы вместить ее.

4. хорошо, тогда как можно получить нужное количество длины для выделения буфера, вызвав zwquerydirectoryfile (дважды).. один раз, чтобы узнать требуемую длину, и еще один вызов для извлечения полных данных в заданный length….is подобно обычным API, связанным с запросами, можно узнать длину буфера abt (обязательную), присвоив buffer значение NULL…

5. @Rajakumar, я понимаю, что ты имеешь в виду, но ZwQueryDirectoryFile() так не работает. Он не будет (и, вероятно, не сможет) сообщать вам размер буфера, необходимый для размещения оставшихся записей файловой системы. Возможно, вам захочется постепенно увеличивать буфер до тех пор, пока функция не завершится успешно. С другой стороны, 4096 байт должно быть более чем достаточно для размещения одной записи, поэтому вы можете использовать буфер фиксированного размера и обрабатывать записи одну за другой.