Господа, такая фигня происходит: Перехватываю ntQueryDirectoryFile, все вроде работает, система не падает и все скрывается как положено, НО: - Когда я пытаюсь скрыть один определенный каталог (D:\Test) или файл с тем же именем и путем то происходит нечто неоъяснимое для меня: исчезает все! Проверяю в Windows Commander и как только драйвер получает этот путь, то активная панель в WC моментально пустеет .... при этом если драйвер не деактивировать, то начинается полный армагеддон (т.к. блокируется похоже что все подряд, в т.ч. логичие диски(типа Диск D: или C: не найден)) и как результат - БСОД. Более того, код прячущий файлы/каталоги УПРАВЛЕНИЕ НЕ ПОЛУЧАЕТ! С чем это может быть связано. Если нужно код - выложу, просто он не маленький. Спасибо.
Вероятно, ошибка в перехвате, управление сразу же возвращается обратно. В WinDbg или айсе ставь бряк на перехватываемую функцию и по шагам смотри, куда она пойдет дальше
- Тогда почему только с одним путем? - К сожалению у меня нет отладчика... На всякий случай, вот код перехвата + процедурка сравнения перехваченных имен файлов/каталогов со связанным списком "запрещенных путей": Код (Text): typedef struct _HIDDEN_FILE_ENTRY { struct _HIDDEN_FILE_ENTRY *PrevEntry; struct _HIDDEN_FILE_ENTRY *NextEntry; ULONG Directory; ULONG FileNameLength; WCHAR FileName[1]; } HIDDEN_FILE_ENTRY, *PHIDDEN_FILE_ENTRY; BOOLEAN IsHidden (IN UNICODE_STRING uniFileName, IN ULONG uDir) { ULONG uPos; PHIDDEN_FILE_ENTRY pEntry; UNICODE_STRING uniHideDirFile; pEntry = pFirstEntry; for (uPos = 0; uPos < uEntriesCount; uPos++) { RtlInitUnicodeString(&uniHideDirFile, pEntry->FileName); if (RtlCompareUnicodeString(&uniFileName, &uniHideDirFile, TRUE ) == 0) { return TRUE; } if (pEntry->NextEntry != 0) pEntry=pEntry->NextEntry; else break; } return FALSE; } NTSTATUS NewNtQueryDirectoryFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformation, IN ULONG FileInformationLength, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery ) { ULONG Offset, Atr; NTSTATUS ns, RESULT; PWCHAR Name; UNICODE_STRING Last, Slash; SIZE_T neededSize; UNICODE_STRING uniFileName; PFILE_DIRECTORY_INFORMATION LastFileDirectoryInfo, FileDirectoryInfo; PFILE_FULL_DIRECTORY_INFORMATION LastFileFullDirectoryInfo, FileFullDirectoryInfo; PFILE_BOTH_DIRECTORY_INFORMATION LastFileBothDirectoryInfo, FileBothDirectoryInfo; PFILE_NAMES_INFORMATION LastFileNamesInfo, FileNamesInfo; char ParentDirectory[1024]; PUNICODE_STRING Parent=NULL; ULONG BytesReturned; UNICODE_STRING uDOSPath, uPath, uTail; PFILE_OBJECT file=0; wchar_t *uPos; RESULT=TrueNtQueryDirectoryFile(hFile,hEvent,IoApcRoutine,IoApcContext,pIoStatusBlock,FileInformation, FileInformationLength,FileInformationClass,bReturnOnlyOneEntry,PathMask,bRestartQuery); if (!NT_SUCCESS(RESULT)) return RESULT; ParentDirectory[0]='\0'; Parent=(PUNICODE_STRING)ParentDirectory; RtlInitUnicodeString (&uTail, L"\\DEVICE\\HARDDISKVOLUME"); ns=ObReferenceObjectByHandle(hFile,0,0,KernelMode,&file,NULL); if (!NT_SUCCESS(ns)) { DbgPrint ("Unable to finish first stage"); return RESULT; } else { ns = IoVolumeDeviceToDosName(file->DeviceObject, &uDOSPath); if (!NT_SUCCESS(ns)) { DbgPrint ("Unable to finish last stage"); return RESULT; } else { ns=ObQueryNameString(file, (POBJECT_NAME_INFORMATION)ParentDirectory, sizeof(ParentDirectory), &BytesReturned); if (!NT_SUCCESS(ns)) { DbgPrint ("Unable to finish second stage"); return RESULT; } else { RtlUpcaseUnicodeString(Parent, Parent, FALSE); uPos = wcsstr(Parent->Buffer, uTail.Buffer); if (uPos) { neededSize = (Parent->Length-23 + uDOSPath.Length + 2) * 2; Name = (wchar_t *)ExAllocatePool(PagedPool, neededSize); RtlZeroMemory(Name, neededSize); wcsncpy(Name, uDOSPath.Buffer, uDOSPath.Length); wcsncat(Name, Parent->Buffer+23, Parent->Length-23); RtlInitUnicodeString(&uPath,Name); } else { return RESULT; } } ExFreePool (uDOSPath.Buffer); } ObDereferenceObject(&file); } RtlInitUnicodeString (&Slash, L"\\"); Offset = 0; switch (FileInformationClass) { case FileDirectoryInformation: //Blah blah blah break; case FileFullhDirectoryInformation: //Blah blah blah break case FileBothDirectoryInformation: LastFileBothDirectoryInfo = FileBothDirectoryInfo = NULL; do { FileBothDirectoryInfo = (PFILE_BOTH_DIRECTORY_INFORMATION)((ULONG)FileInformation + Offset); neededSize = (uPath.Length + FileBothDirectoryInfo->FileNameLength + 2) * sizeof(wchar_t); Name = (wchar_t *)ExAllocatePool(PagedPool, neededSize); RtlZeroMemory(Name, neededSize); wcsncpy(Name, uPath.Buffer, uPath.Length / sizeof(wchar_t)); RtlInitUnicodeString(&Last, Name+((uPath.Length-1) / sizeof(wchar_t))); if (RtlCompareUnicodeString(&Last, &Slash, TRUE ) != 0) { wcsncat(Name, L"\\", 1); } wcsncat(Name, FileBothDirectoryInfo->FileName, FileBothDirectoryInfo->FileNameLength / sizeof(wchar_t)); Name[(uPath.Length + FileBothDirectoryInfo->FileNameLength + 2) / sizeof(wchar_t)] = 0; RtlInitUnicodeString(&uniFileName, Name); Atr=5; if ((FileBothDirectoryInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) Atr=10; if (IsHidden(uniFileName, Atr)) { DbgPrint("Hiding: %ws", uniFileName.Buffer); if (!FileBothDirectoryInfo->NextEntryOffset) { if (LastFileBothDirectoryInfo) { LastFileBothDirectoryInfo->NextEntryOffset = 0; } else { return STATUS_NO_SUCH_FILE; } } else { if (LastFileBothDirectoryInfo) { LastFileBothDirectoryInfo->NextEntryOffset += FileBothDirectoryInfo->NextEntryOffset; } } } else { LastFileBothDirectoryInfo = FileBothDirectoryInfo; } ExFreePool(Name); uniFileName.Buffer=0; Offset += FileBothDirectoryInfo->NextEntryOffset; } while (FileBothDirectoryInfo->NextEntryOffset); break; case FileNamesInformation: //Blah blah blah break; } return (RESULT); } Вот...