如何在递归模式下使用NtQueryDirectoryFile检索完整的文件名? [英] How retrieve complete filename with NtQueryDirectoryFile in recursive mode?
本文介绍了如何在递归模式下使用NtQueryDirectoryFile检索完整的文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在使用此代码来递归遍历所有文件和目录.
I'm using this code to go through all files and directories recursively.
现在我想知道如何提取完整的文件名(路径+文件名+扩展名)?以下行(也出现在参考代码上)仅给出文件名+扩展名(不带目录名).
Now i want know how extract complete filename (path + filename + extension)? the following line(also present on reference code) give only filename + exension (without directory name).
DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName);
谢谢.
推荐答案
如果我们不希望简单地枚举文件夹/文件而是使用全名,则需要编写适当的代码.例如:
if we want not simple enumerate folders/files but with full name, need write appropriate code. for example:
#define ALLOCSIZE PAGE_SIZE
// int nLevel, PSTR prefix for debug only
void ntTraverse(POBJECT_ATTRIBUTES poa, int nLevel, PSTR prefix)
{
if (IoGetRemainingStackSize() < PAGE_SIZE)
{
DbgPrint("no stack!\n");
return ;
}
if (!nLevel)
{
DbgPrint("!nLevel\n");
return ;
}
HANDLE hFile;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName, *pObjectName = poa->ObjectName;
DbgPrint("%s[<%wZ>]\n", prefix, pObjectName);
if (0 <= (status = NtOpenFile(&hFile, FILE_GENERIC_READ, poa, &iosb, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE)))
{
if (PVOID buffer = ExAllocatePool(PagedPool, ALLOCSIZE))
{
union {
PVOID pv;
PBYTE pb;
PFILE_DIRECTORY_INFORMATION DirInfo;
};
while (0 <= (status = NtQueryDirectoryFile(hFile, NULL, NULL, NULL, &iosb,
pv = buffer, ALLOCSIZE, FileDirectoryInformation, 0, NULL, FALSE)))
{
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
ObjectName.Buffer = DirInfo->FileName;
switch (ObjectName.Length = (USHORT)DirInfo->FileNameLength)
{
case 2*sizeof(WCHAR):
if (ObjectName.Buffer[1] != '.') break;
case sizeof(WCHAR):
if (ObjectName.Buffer[0] == '.') continue;
}
ObjectName.MaximumLength = ObjectName.Length;
USHORT Length = pObjectName->Length;
if (0 <= RtlAppendUnicodeToString(pObjectName, L"\\") &&
0 <= RtlAppendUnicodeStringToString(pObjectName, &ObjectName))
{
if (FILE_ATTRIBUTE_DIRECTORY == (DirInfo->FileAttributes &
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)))
{
ntTraverse(poa, nLevel - 1, prefix - 1);
}
else
{
DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, pObjectName);
}
pObjectName->Length = Length;
}
} while (NextEntryOffset = DirInfo->NextEntryOffset);
}
ExFreePool(buffer);
if (status == STATUS_NO_MORE_FILES)
{
status = STATUS_SUCCESS;
}
}
NtClose(hFile);
}
if (0 > status)
{
DbgPrint("---- %x %wZ\n", status, pObjectName);
}
}
void ntTraverse(PCWSTR path)
{
char prefix[MAXUCHAR + 1];
memset(prefix, '\t', MAXUCHAR);
prefix[MAXUCHAR] = 0;
UNICODE_STRING ObjectName = { 0, MAXUSHORT, (PWSTR)ExAllocatePool(PagedPool, MAXUSHORT) };
if (ObjectName.Buffer)
{
if (0 <= RtlAppendUnicodeToString(&ObjectName, path))
{
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
ntTraverse(&oa, MAXUCHAR, prefix + MAXUCHAR);
}
ExFreePool(ObjectName.Buffer);
}
}
ntTraverse(L"\\??\\c:\\users");
ntTraverse(L"\\systemroot");
这篇关于如何在递归模式下使用NtQueryDirectoryFile检索完整的文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文