Как вывести список рекурсивных каталогов после отправки 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), у меня все еще есть трудности, чтобы найти способ удалить эти папки после удаления всех ваших файлов.

Как сделать это?

0 ответов

Другие вопросы по тегам