Не понятно следующее: я прочитал в свой буфер элемент из списка вызовом NtQueryDirectoryFile. Как мне получить (1) следующий, (2) предыдущий, (3) произвольно указывать (по индексу например), (4) запоминать, чтобы можно было продолжить перебор позднее? Где и как хранится (задается) эта информация? Работаю в usermode.
поле NextEntryOffset в структуре описывающий файл является смещением следующей структуры относительно данной. 1. Прибавить поле NextEntryOffset к адресу текущей структуры 2. никак 3. пробежаться по списку с самого начала 4. запомни адрес где остановился
я прочитал один элемент непонятно написал. Я делаю вызов NtQueryDirectoryFile и указываю размер буфера, достаточный только для информации об одном файле, получаю информацию о первом(?) файле в директории
Ну а какое значение у тебя содержится в NextEntryOffset? Вообще, функция не должна отработать, если выделенного буфера ей не хватит для размещения всего, что она захотела туда разместить. Поэтому тут что-то не так:
Как я понял, в этом случае возвращается код ошибки, но буфер заплняется. Я прав? Иначе мне что, для того чтобы прочитать каталог с тысячами файлов нужно под это обязательно выделить громадный блок памяти?
В одной из тем по этой фукции приводились часть исходных текстов Win2k функции FindFirstFile вроде бы. Где можно посмотреть полностью исходные тексты по FindFirstFile, FindFirstFileEx, FindNextFile в A и W вариантах.
Вот что там написано: ReturnSingleEntry Specifies whether a single entry should be returned. If false, as many entries as will fit in the FileInformation buffer are returned. Выделено - то, что "по теме". Больше я там ничего не увидел.
andrey_z зачем тебе это? Ну будет в папке 5000 файлов. пусть на каждый блок уйдёт 1 кб(хотя на сколько помню на блок уходит гораздо меньше) Вот и выходит, что надо тебе 5 метров памяти. Прямо скажем не огромное число по нынешним меркам. Зато всего 1 переход в ядро и обратно, вместо 5000, если звать по разу на каждый файл(если это вообще можно)
Тут дело не в памяти. Например я начинаю выборку для хэндлу по маске, затем я хочу выделить выборку по другой маске, а затем вернуться к предыдущей маске и продолжить выборку. Пусть это можно сделать выделив большие буферы за один вызов функции на выборку. А если мой код, перехватывая эту функцию, делает выборки для другого кода по этому же хэндлу, и делать это надо прозрачно для предоставленного буфера в 4кБ?
Вот что нашел в 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.
Как я понял, система где-то хранит выборку, соответствующую первому вызову. Как-нибудь можно освободить эту память, если она больше не нужна (без закрытия хэндла)?
При некоторых вызовах возвращает 0x00000103 (STATUS_PENDING). Хотя в параметре Event передано NULL. Как дожидаться окончания в этом случае?
Да не трудно. Параметр помечен как optional, и как работать в случае Event=Null не ясно. Да и Find..File в WinAPI туда NULL вроде как передают, и STATUS_PENDING как-то обрабатывают...
Нашел: для этого хэндл должен быть открыт с правом SYNCHRONIZE и с create/open option FILE_SYNCHRONOUS_IO_NONALERT.