来自NtCreateFile的STATUS_INVALID_PARAMETER

时间:2013-01-07 09:15:29

标签: c++ windows winapi

以下是我正在使用的代码:

std::wstring GetPathFromFileReference (DWORDLONG frn)
{
    if (frn != 0)
    {
        HANDLE handle = NULL;

        wchar_t file_buffer[2048] = { NULL };
        wchar_t unicode_buffer[8] = { NULL };
        UNICODE_STRING unicodeString;

        unicodeString.Length = 8;
        unicodeString.MaximumLength = 8;
        unicodeString.Buffer = unicode_buffer;

        OBJECT_ATTRIBUTES objAttributes = { NULL };
        InitializeObjectAttributes(&objAttributes, &unicodeString, OBJ_CASE_INSENSITIVE, _root, NULL); 

        IO_STATUS_BLOCK ioStatusBlock = { NULL };

        LARGE_INTEGER allocSize = { NULL };
        int _result = NtCreateFile(&handle, GENERIC_ALL /*FILE_TRAVERSE*/ /* FILE_READ_DATA */, &objAttributes, &ioStatusBlock, /*&allocSize*/  NULL , NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID | FILE_NON_DIRECTORY_FILE /*FILE_OPEN_FOR_BACKUP_INTENT*/, NULL, NULL);
        if (_result == S_OK)
        {
            typedef NTSTATUS (NTAPI *LPFN_NtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, int);
            LPFN_NtQueryInformationFile pfnNtQueryInformationFile = (LPFN_NtQueryInformationFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationFile");

            _result = pfnNtQueryInformationFile(handle, &ioStatusBlock, file_buffer, 4096, 9);
            if (_result == S_OK)
            {
                return std::wstring(file_buffer + 2);
            }
        }
    }
    return L"";
}

NtCreateFileSTATUS_INVALID_PARAMETER的调用失败。该调用中注释掉的代码显示了我尝试过的其他内容。

RootDirectory句柄肯定是在objAttributes中设置的(到0x30)。我在代码中的其他地方使用相同的句柄,它工作得很好。而且frn也很好看。

我不知道还有什么可以尝试或如何进一步缩小原因:(任何帮助将不胜感激。

编辑:我忘了提到我想在这里实现的目标。抱歉!该frn来自USN Change Journal。我已经使用我的根句柄成功阅读了Change Journal(因此我认为它是正确的),并且对于每个条目我都有一个frn和parent_frn。我想获得文件的完整路径,下面的代码是我尝试将frn转换为路径的方式。 frn和parent_frn都提供相同的STATUS_INVALID_PARAMETER返回码。

1 个答案:

答案 0 :(得分:4)

NtCreateFile文档的评论说:

  

如果使用FILE_OPEN_BY_FILE_ID,则必须使用卷的句柄填充ObjectAttributes.RootDirectory句柄,否则您将获得STATUS_INVALID_PARAMETER。

要打开卷的句柄,您可以使用CreateFile路径使用\\.\X:,其中X是驱动器号。请注意,没有尾随反斜杠。 CreateFile文档包含有关它的信息(查找字符串“打开C:卷”。)