Как работает NtQueryDirectoryFile

Тема в разделе "WASM.WIN32", создана пользователем andrey_z, 17 авг 2007.

  1. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Не понятно следующее: я прочитал в свой буфер элемент из списка вызовом NtQueryDirectoryFile.
    Как мне получить (1) следующий, (2) предыдущий, (3) произвольно указывать (по индексу например), (4) запоминать, чтобы можно было продолжить перебор позднее? Где и как хранится (задается) эта информация?

    Работаю в usermode.
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    поле NextEntryOffset в структуре описывающий файл является смещением следующей структуры относительно данной.
    1. Прибавить поле NextEntryOffset к адресу текущей структуры
    2. никак
    3. пробежаться по списку с самого начала
    4. запомни адрес где остановился
     
  3. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    я прочитал один элемент

    непонятно написал. Я делаю вызов NtQueryDirectoryFile и указываю размер буфера, достаточный только для информации об одном файле, получаю информацию о первом(?) файле в директории
     
  4. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Ну а какое значение у тебя содержится в NextEntryOffset?
    Вообще, функция не должна отработать, если выделенного буфера ей не хватит для размещения всего, что она захотела туда разместить. Поэтому тут что-то не так:
     
  5. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Как я понял, в этом случае возвращается код ошибки, но буфер заплняется. Я прав?
    Иначе мне что, для того чтобы прочитать каталог с тысячами файлов нужно под это обязательно выделить громадный блок памяти?
     
  6. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    И для чего тогда нужен параметр RestartScan?
     
  7. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    В одной из тем по этой фукции приводились часть исходных текстов Win2k функции FindFirstFile вроде бы. Где можно посмотреть полностью исходные тексты по FindFirstFile, FindFirstFileEx, FindNextFile в A и W вариантах.
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Есть параметр - чтение одного файла. SingleEntry или как-то так. советую Неббета почитать.
     
  9. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Вот что там написано:
    ReturnSingleEntry
    Specifies whether a single entry should be returned. If false, as many entries as will fit
    in the FileInformation buffer are returned
    .

    Выделено - то, что "по теме". Больше я там ничего не увидел.
     
  10. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    andrey_z
    зачем тебе это? Ну будет в папке 5000 файлов. пусть на каждый блок уйдёт 1 кб(хотя на сколько помню на блок уходит гораздо меньше) Вот и выходит, что надо тебе 5 метров памяти. Прямо скажем не огромное число по нынешним меркам. Зато всего 1 переход в ядро и обратно, вместо 5000, если звать по разу на каждый файл(если это вообще можно)
     
  11. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Тут дело не в памяти.
    Например я начинаю выборку для хэндлу по маске, затем я хочу выделить выборку по другой маске, а затем вернуться к предыдущей маске и продолжить выборку.
    Пусть это можно сделать выделив большие буферы за один вызов функции на выборку.
    А если мой код, перехватывая эту функцию, делает выборки для другого кода по этому же хэндлу, и делать это надо прозрачно для предоставленного буфера в 4кБ?
     
  12. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Вот что нашел в IFS DDK - в Win2k/XP DDK этого я не увидел:
    (отдельные цитаты)

    RestartScan
    Set to TRUE if the scan is to start at the first entry in the directory. Set to FALSE if resuming the scan from a previous call. The caller must set this parameter to TRUE when calling ZwQueryDirectoryFile for the first time.

    If RestartScan is FALSE, the value of FileName is ignored.

    ZwQueryDirectoryFile also returns the number of bytes actually written to the given FileInformation buffer in the Information member of IoStatusBlock.

    The first call to ZwQueryDirectoryFile determines the set of entries to be included in the directory scan for all subsequent calls, based on the values of ReturnSingleEntry, FileName, and RestartScan.

    On each call, ZwQueryDirectoryFile returns as many FILE_XXX_INFORMATION structures (one per directory entry) as can be contained entirely in the buffer pointed to by FileInformation. As long as the output buffer contains at least one complete structure, the status value returned is STATUS_SUCCESS.

    The final call to ZwQueryDirectoryFile returns an empty output buffer and reports an appropriate status value such as STATUS_NO_MORE_FILES.

    Note: When ZwQueryDirectoryFile is called multiple times on the same directory, it is possible that the number of entries for which information is returned will be less than expected. This is because the set of entries to be included in the directory scan is fixed on the first call to ZwQueryDirectoryFile. In subsequent calls, ZwQueryDirectoryFile resumes the directory scan wherever it left off in this same enumeration. However, between calls to ZwQueryDirectoryFile, the actual directory entries can change so that they are no longer in sync with the original enumeration.
     
  13. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Как я понял, система где-то хранит выборку, соответствующую первому вызову.
    Как-нибудь можно освободить эту память, если она больше не нужна (без закрытия хэндла)?
     
  14. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    При некоторых вызовах возвращает 0x00000103 (STATUS_PENDING). Хотя в параметре Event передано NULL. Как дожидаться окончания в этом случае?
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а евент создать очень трудно чтоли?)
     
  16. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Да не трудно. Параметр помечен как optional, и как работать в случае Event=Null не ясно. Да и Find..File в WinAPI туда NULL вроде как передают, и STATUS_PENDING как-то обрабатывают...
     
  17. andrey_z

    andrey_z New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2007
    Сообщения:
    14
    Нашел: для этого хэндл должен быть открыт с правом SYNCHRONIZE и с create/open option FILE_SYNCHRONOUS_IO_NONALERT.