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!
");
return ;
}
if (!nLevel)
{
DbgPrint("!nLevel
");
return ;
}
HANDLE hFile;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName, *pObjectName = poa->ObjectName;
DbgPrint("%s[<%wZ>]
", 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>
", 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
", status, pObjectName);
}
}
void ntTraverse(PCWSTR path)
{
char prefix[MAXUCHAR + 1];
memset(prefix, ' ', 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");
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…