Функция не прячет файлы в папке, когда только один файл
Есть драйвер-минифильтр который должен прятать файлы, когда в папке, есть только один файл, оно почему-то не прячет, в остальных случаях все работает корректно.
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 использую, для поиска ошибки