Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
171 views
in Technique[技术] by (71.8m points)

c++ - How retrieve complete filename with NtQueryDirectoryFile in recursive mode?

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>
", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName);

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...