Как вывести список рекурсивных каталогов после отправки IRP?
Мне нужно рекурсивно перечислять все файлы и папки (а также подпапки) корневого каталога после отправки IRP, и удалять каждый найденный файл и папку, используя код, который также отправит IRP для этого. До сих пор я могу только перечислить содержимое корневого каталога с помощью следующего кода.
Некоторые идеи о том, как это сделать?
#include <ntddk.h>
#include <WinDef.h>
NTSTATUS EventCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PIO_STATUS_BLOCK lpiosb;
lpiosb = Irp->UserIosb;
lpiosb->Status = Irp->IoStatus.Status;
lpiosb->Information = Irp->IoStatus.Information;
KeSetEvent(Irp->UserEvent, 0, FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
typedef struct _FILE_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
typedef struct _DIRECTORY_INFO {
char FileName[50];
LARGE_INTEGER AllocationSize;
TIME_FIELDS CreationTime;
TIME_FIELDS LastAccessTime;
TIME_FIELDS LastWriteTime;
TIME_FIELDS ChangeTime;
ULONG FileAttributes;
}DIRECTORY_INFO, *PDIRECTORY_INFO;
PVOID GetDirectory(char *lpDirName, PULONG dwRetSize)
{
NTSTATUS status;
ULONG dwBytesReturned;
OBJECT_ATTRIBUTES oa;
PDEVICE_OBJECT lpDeviceObject;
KEVENT event;
IO_STACK_LOCATION iost;
PIO_STACK_LOCATION lpsp;
IO_STATUS_BLOCK ios;
PIRP lpirp = NULL;
HANDLE hFile;
PVOID lpSystemBuffer;
PFILE_DIRECTORY_INFORMATION lpInformation;
PFILE_DIRECTORY_INFORMATION lpRealInformation;
PDIRECTORY_INFO lpDirInfo;
PFILE_OBJECT lpFileObject;
UNICODE_STRING unFileName;
UNICODE_STRING UN;
ANSI_STRING anFileName;
CHAR buffer[1024];
PUCHAR lpNext;
dwBytesReturned = 0;
status = STATUS_UNSUCCESSFUL;
RtlZeroMemory(buffer, 1024);
strcpy(buffer, "\\DosDevices\\");
strcat(buffer, lpDirName);
RtlInitAnsiString(&anFileName, buffer);
RtlAnsiStringToUnicodeString(&unFileName, &anFileName, TRUE);
InitializeObjectAttributes(&oa, &unFileName, OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenFile(&hFile, FILE_LIST_DIRECTORY + SYNCHRONIZE + FILE_ANY_ACCESS, &oa, &ios, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(status))
{
DbgPrint("ZwOpenFile Success\n");
}
else
goto endcddir;
status = ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY + SYNCHRONIZE, 0, KernelMode, &lpFileObject, NULL);
if (!NT_SUCCESS(status))
{
ZwClose(hFile);
goto endcddir;
}
DbgPrint("open file object success\n");
lpDeviceObject = IoGetRelatedDeviceObject(lpFileObject);
lpirp = IoAllocateIrp(lpDeviceObject->StackSize, FALSE);
if (!lpirp)
{
DbgPrint("allocate irp failed\n");
ObDereferenceObject(lpFileObject);
ZwClose(hFile);
goto endcddir;
}
DbgPrint("allocate irp success\n");
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
lpInformation = ExAllocatePool(PagedPool, 655350);
lpSystemBuffer = ExAllocatePool(PagedPool, 655350);
RtlZeroMemory(lpSystemBuffer, 655350);
RtlZeroMemory(lpInformation, 655350);
lpirp->UserEvent = &event;
lpirp->UserBuffer = lpInformation;
lpirp->AssociatedIrp.SystemBuffer = lpInformation;
lpirp->MdlAddress = NULL;
lpirp->Flags = 0;
lpirp->UserIosb = &ios;
lpirp->Tail.Overlay.OriginalFileObject = lpFileObject;
lpirp->Tail.Overlay.Thread = PsGetCurrentThread();
lpirp->RequestorMode = KernelMode;
lpsp = IoGetNextIrpStackLocation(lpirp);
lpsp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
lpsp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
lpsp->FileObject = lpFileObject;
lpsp->DeviceObject = lpDeviceObject;
lpsp->Flags = SL_RESTART_SCAN;
lpsp->Control = 0;
lpsp->Parameters.QueryDirectory.FileIndex = 0;
lpsp->Parameters.QueryDirectory.FileInformationClass = FileDirectoryInformation;
lpsp->Parameters.QueryDirectory.FileName = NULL;
lpsp->Parameters.QueryDirectory.Length = 655350;
IoSetCompletionRoutine(lpirp, EventCompletion, 0, TRUE, TRUE, TRUE);
status = IoCallDriver(lpDeviceObject, lpirp);
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
lpDirInfo = (PDIRECTORY_INFO)lpSystemBuffer;
lpRealInformation = lpInformation;
while (1)
{
UN.Length = (USHORT)lpInformation->FileNameLength;
UN.MaximumLength = (USHORT)lpInformation->FileNameLength;
UN.Buffer = &(lpInformation->FileName[0]);
RtlUnicodeStringToAnsiString(&anFileName, &UN, TRUE);
strcpy(lpDirInfo->FileName, anFileName.Buffer);
KdPrint(("%s\n", anFileName.Buffer));
RtlFreeAnsiString(&anFileName);
lpDirInfo->AllocationSize = lpInformation->AllocationSize;
lpDirInfo->FileAttributes = lpInformation->FileAttributes;
RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime));
RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime));
RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime));
RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime));
lpDirInfo->FileAttributes = lpInformation->FileAttributes;
dwBytesReturned += sizeof(DIRECTORY_INFO);
if (lpInformation->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DbgPrint("Directory found!\n");
}
if (!lpInformation->NextEntryOffset) goto exit;
lpNext = (PUCHAR)lpInformation;
lpNext += lpInformation->NextEntryOffset;
lpInformation = (PFILE_DIRECTORY_INFORMATION)(lpNext);
lpDirInfo++;
}
endcddir:
RtlFreeUnicodeString(&unFileName);
return NULL;
exit:
ExFreePool(lpRealInformation);
ObDereferenceObject(lpFileObject);
ZwClose(hFile);
RtlFreeUnicodeString(&unFileName);
*dwRetSize = dwBytesReturned;
return lpSystemBuffer;
}
////////////// DriverEntry //////////////////
ULONG dwRetSize;
GetDirectory("C:\\MyDirectory", &dwRetSize);
ИЗДАНИЕ:
После предложения @RbMm, а также после того, как я нашел этот код (также ваше собственное авторство), я могу удалить все файлы:
#ifndef _REAL_DELETE_
else
#endif
{
DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName);
// Call to code that delete each file found
}
но, учитывая, что не возможно открыть каталог с DELETE
флаг, когда существует некоторый тип перехвата (обычно с использованием драйверов минифильтров FSD), у меня все еще есть трудности, чтобы найти способ удалить эти папки после удаления всех ваших файлов.
Как сделать это?