Функция не прячет файлы в папке, когда только один файл

Есть драйвер-минифильтр который должен прятать файлы, когда в папке, есть только один файл, оно почему-то не прячет, в остальных случаях все работает корректно.

template <typename InfoType>
NTSTATUS hf(PVOID buff, UNICODE_STRING filePath)
{
    if (buff == NULL)
    {
        DbgPrint("BUFF IS NULL\n");
        return STATUS_SUCCESS;
    }
    //InfoType* DirBuff = (InfoType*)buff;
    InfoType* nextInfo = NULL;
    InfoType* prevInfo = NULL;
    InfoType* info = (InfoType*)(buff);
    UNICODE_STRING fileName, fullFileName;
    UINT32 offset, moveLength;
    BOOLEAN search=true;
    NTSTATUS status = STATUS_SUCCESS;
    offset = 0;
    do
    {
        fileName.Buffer = info->FileName;
        fileName.Length = (USHORT)info->FileNameLength;
        fileName.MaximumLength = (USHORT)info->FileNameLength;
        UNICODE_STRING sl;
        if (!compareNames(filePath.Buffer, L"*:\\")) {
            sl.Buffer = L"\\";
            sl.Length = 2;
            sl.MaximumLength = 2;
        }
        else
        {
            sl.Buffer = L"";
            sl.Length = 0;
            sl.MaximumLength = 0;
        }
        fullFileName.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, filePath.MaximumLength + sl.MaximumLength + fileName.MaximumLength + 2, ALLOCATION_TAG);
        if (fullFileName.Buffer == NULL)
            return STATUS_INSUFFICIENT_RESOURCES;
        fullFileName.MaximumLength = sl.MaximumLength + fileName.MaximumLength + filePath.MaximumLength + 2;
        fullFileName.Length = sl.MaximumLength + fileName.MaximumLength + filePath.Length + 2;
        RtlCopyUnicodeString(&fullFileName, &filePath);
        RtlAppendUnicodeStringToString(&fullFileName, &sl);
        RtlAppendUnicodeStringToString(&fullFileName, &fileName);

        if (isInList(masks, fileName) || isInList(masks, fullFileName))
        {
            BOOLEAN retn = FALSE;

            if (prevInfo != NULL)
            {
                if (info->NextEntryOffset != 0)
                {
                    prevInfo->NextEntryOffset += info->NextEntryOffset;
                    offset = info->NextEntryOffset;
                }
                else
                {
                    prevInfo->NextEntryOffset = 0;
                    status = STATUS_SUCCESS;
                    retn = TRUE;
                }
                RtlFillMemory(info, sizeof(InfoType), 0);
            }
            else
            {
                if (info->NextEntryOffset != 0)
                {
                    nextInfo = (InfoType*)((PUCHAR)info + info->NextEntryOffset);
                    moveLength = 0;
                    while (nextInfo->NextEntryOffset != 0)
                    {
                        moveLength += nextInfo->NextEntryOffset;
                        nextInfo = (InfoType*)((PUCHAR)nextInfo + nextInfo->NextEntryOffset);
                    }
                    moveLength += FIELD_OFFSET(InfoType, FileName) + nextInfo->FileNameLength;
                    RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue
                }
                else
                {
                    status = STATUS_NO_MORE_ENTRIES;
                    retn = TRUE;
                    RtlFillMemory(info, sizeof(InfoType), 0);
                    DbgPrint("%wZ", fileName);
                }
            }
            if (retn)
                return status;
            info = (InfoType*)((PCHAR)info + offset);
            continue;
        }
        offset = info->NextEntryOffset;
        prevInfo = info;
        info = (InfoType*)((PCHAR)info + offset);
        if (offset == 0)
            return STATUS_SUCCESS;
    } while (search);
    ExFreePoolWithTag(fullFileName.Buffer, ALLOCATION_TAG);
    return STATUS_SUCCESS; 
}

Здесь она вызывается:

FLT_POSTOP_CALLBACK_STATUS
PostDirectoryControlCallback(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _In_ PVOID CompletionContext,
    _In_ FLT_POST_OPERATION_FLAGS Flags
)
{
   
    PFLT_PARAMETERS params = &Data->Iopb->Parameters;
    NTSTATUS status = STATUS_SUCCESS;
    POBJECT_NAME_INFORMATION fileinf;

    if (!NT_SUCCESS(IoQueryFileDosDeviceName(FltObjects->FileObject, &fileinf)))
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
    if (!NT_SUCCESS(Data->IoStatus.Status) || !active)
        return FLT_POSTOP_FINISHED_PROCESSING;
  
        
      
      
    


        switch (params->DirectoryControl.QueryDirectory.FileInformationClass)
        {
        case FileDirectoryInformation:
            status=HideFile<FILE_DIRECTORY_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        case FileFullDirectoryInformation:
            status=HideFile<FILE_FULL_DIR_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        case FileBothDirectoryInformation:
            status=HideFile<FILE_BOTH_DIR_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        case FileNamesInformation:
            status= HideFile<FILE_NAMES_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        case FileIdBothDirectoryInformation: // Used by Vista and later explorer
            status= hf<FILE_ID_BOTH_DIR_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        case FileIdFullDirectoryInformation: // Used by Vista and later explorer
            status= HideFile<FILE_ID_FULL_DIR_INFORMATION>(params->DirectoryControl.QueryDirectory.DirectoryBuffer, fileinf->Name);
            break;
        default:break;
        }   
        Data->IoStatus.Status = status;
        ExFreePool(fileinf);

    return FLT_POSTOP_FINISHED_PROCESSING;
}

Это callbacks которые используются(она юзается в IRP_MJ_DIRECTORY_CONTROL)

CONST FLT_OPERATION_REGISTRATION g_callbacks[] =
{
    {
        IRP_MJ_CREATE,
        0,
        PreOperationCreate,
        PostOperationCreate
    },
     { IRP_MJ_DIRECTORY_CONTROL,
      0,
      PreDirectoryControlCallback,
      PostDirectoryControlCallback },
    { IRP_MJ_OPERATION_END }
};

Подскажите что делаю не так, и как исправить, чтобы прятало все файлы. Функции hf и HideFile одинаковые, просто hf использую, для поиска ошибки


Ответы (0 шт):