Знаю, этот вопрос поднимался неоднократно, но поиски по форуму не дали мне ответов. Перехватываю функцию NtQueryDirectoryFile. Обрабатываю когда FileInformationClass имеет следующие значения: FileDirectoryInformation, FileFullDirectoryInformation, FileBothDirectoryInformation, FileNamesInformation. Код обработчика для этих 4-х ситуаций одинаковый, поэтому я приведу только для FileBothDirectoryInformation. А проблема вот в чем: у меня на рабочем столе есть файлы, допустим 1.exe, 1.exe1, DriverStudio 3.2, Shortcut to TOTALCMD.EXE.lnk, New Wordpad Document.doc. Но у меня происходит такая ситуация: 1. Скрываю только 1.exe - то все работает замечательно 2. Скрыть только 1.exe1 - то опять же - работает безупречно. 3. Скрываю 1.exe и 1.exe1 - скрывается только 1.exe 4. Скрываю 1.exe и DriverStudio 3.2 и Shortcut to TOTALCMD.EXE.lnk - бузепречно 5. Скрываю New Wordpad Document.doc и Shortcut to TOTALCMD.EXE.lnk - скрывается только New Wordpad Document.doc Т.е. я как понял, если идут скрываемые файлы подряд в FileInformation - то скрывается только первый из них... Хотя отладчик на _asm int 3; вылетает как положено, на всех скрываемых файлах: Код (Text): case FileBothDirectoryInformation:{ // Получение структуры и информацией о файлах name2 = FileInformation; // Если нужно скрыть первый элемент то До тех пор пока первый элемент соответствует нашей строке while (FilesListIsAdded(HidenFiles, name2->FileNameLength, name2->FileName)){ name2_2 = name2; //Получаем длину перемещаемых файлов if (name2->NextEntryOffset == 0) return STATUS_NO_SUCH_FILE; // Если это единственный элемент то просто возвращаем инф-ию что файлов не найдено // Орпеделяем позицию последней записи while (name2->NextEntryOffset > 0) (ULONG)name2 += name2->NextEntryOffset; // Перемещаем все данные со второго и до последнего элемента на самое начало FileInformation, затирая первый элемент RtlMoveMemory(FileInformation,(PVOID)name2_2->NextEntryOffset,(ULONG)name2 - (ULONG)FileInformation); name2 = FileInformation; } // Скрываем файлы если они не первые Выполняем цикл по всем элементам while (name2->NextEntryOffset > 0){ _asm int 3; // Если очередной элемент оказался нашим, тогда if (FilesListIsAdded(HidenFiles, name2->FileNameLength, name2->FileName)){ name2_2->Unknown = name2->Unknown; // Если очередной найденный элемент оказался последним, тогда просто его отбрасываем, указав в предыдущей записи что она последняя if (name2->NextEntryOffset == 0) name2_2->NextEntryOffset = 0; // Иначе, если это не последний, тогда поле указатель на следующиу запись предыдущей записи перенаправляем на следующую запись а не на скрываемую else name2_2->NextEntryOffset += name2->NextEntryOffset; } (ULONG)name2_2 = (ULONG)name2; (ULONG)name2 += name2->NextEntryOffset; } break;}
Код (Text): while (name2->NextEntryOffset > 0) (ULONG)name2 += name2->NextEntryOffset; Здесь точно ошибка, потому что для последней записи нельзя узнать ее длину, там NextEntryOffset == 0. Если отрабатывает первый цикл, то список искажается, из-за этого могут проявляться разные косяки
Да, цикл неверный... он не считает последнюю запись... Но дело не в нем - он управление в моем случае не получает...
Ой, походу я понял - проблема в этом: Код (Text): if (FilesListIsAdded(HidenFiles, name2->FileNameLength, name2->FileName)){ name2_2->Unknown = name2->Unknown; // Если очередной найденный элемент оказался последним, тогда просто его отбрасываем, указав в предыдущей записи что она последняя if (name2->NextEntryOffset == 0) name2_2->NextEntryOffset = 0; // Иначе, если это не последний, тогда поле указатель на следующиу запись предыдущей записи перенаправляем на следующую запись а не на скрываемую else name2_2->NextEntryOffset += name2->NextEntryOffset; } Если скрывается один элемент, то все нормально - исправляе предыдущую запись на следующую, а если второй по списку элемент оказался скрываемым, то сдесь по ошибке я исправляю NextEntryOffset уже скрытого элемента а не того который перед ним