Ситуация такая: В отличие от fat32, в ntfs explorer запрашивает ZwQueryDirectoryFile с флагом ReturnSingleEntry при перечислении объектов в корне диска. Запрос с ReturnSingleEntry==TRUE происходит только один раз, для первого по алфавиту объекта в корне диска. Возможно, для него это способ определиться, есть что-либо в разделе или нет. Если пытаться скрыть первый по алфавиту объект, то explorer считает (imho), что там вообще ничего нет, и последующих вызовов для этого диска не присылает, т.е. перестает видеть вообще весь диск Если скрывать любой другой, кроме первого - все нормально скрывается. Как обмануть? Вообще, возможно скрыть первый объект, чтобы остальные оставались видимыми? Спасибо.
Код (Text): NTSTATUS __stdcall NewZwQueryDirectoryFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG FileInformationLength, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan) { NTSTATUS status = TrueZwQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, FileInformationLength, FileInformationClass, ReturnSingleEntry, FileName, RestartScan); if (NT_SUCCESS(status)) { PFILE_DIRECTORY_INFORMATION FileDirectoryInfo, LastFileDirectoryInfo; ULONG Offset = 0; ULONG NameLength; PWCHAR FileName; if (ReturnSingleEntry) { while (NT_SUCCESS(status)) { GetFileName(FileInformation, FileInformationClass, &FileName, &NameLength); if (!RkIsFileHidden(FileName, NameLength)) break; if (RestartScan) return STATUS_NO_MORE_FILES; status = TrueZwQueryDirectoryFile(FileHandle, NULL, NULL, NULL, IoStatusBlock, FileInformation, FileInformationLength, FileInformationClass, TRUE, NULL, FALSE); } } else
Значит, вместо эксплорера самому вызвать wQueryDirectoryFile для следующего за скрываемым? Понял, спасибо P.S. Кстати, насколько обязательно модифицировать возвращаемый IoStatusBlock? Его кто-нибудь проверяет?
Если напишу... Что-то повторный вызов ZwQueryDirectoryFile с ReturnSingleEntry постоянно возвращает C0000003 для любых передаваемых параметров, в т.ч. и с RestartScan==TRUE
Повторный вызов делаю так: Код (Text): if (pInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY){ uStr.Length = (USHORT)pInfo->FileNameLength; uStr.MaximumLength = uStr.Length + 2; uStr.Buffer = &pInfo->FileName[0]; if ( ToHide(FileHandle, &uStr, IsParentProcess) ){ if (ReturnSingleEntry) { if (RestartScan) { IoStatusBlock->Status = STATUS_NO_MORE_FILES; IoStatusBlock->Information = 0; Status = STATUS_NO_MORE_FILES; goto _ret; } _asm { push 0 push 0 push 1 push dword ptr [ebp+36] push dword ptr [ebp+32] push dword ptr [ebp+28] push dword ptr [ebp+24] push 0 push 0 push 0 push dword ptr [ebp+8] call dword ptr [TrueZwQueryDirectoryFile] mov [Status],eax } DbgPrint("Status = %08X", Status); goto _ret; } Пока сделал половинчатое решение: если ReturnSingleEntry был TRUE, сбрасываю его в FALSE, делаю первый вызов TrueZwQueryDirectoryFile, и затем вручную затираю выходной массив, так что в нем остается только один (следующий за скрываемым) объект. Папка видна, но недоступна ни для каких действий с ней (удаление, переименование, копирование, открытие)