niemiro
niemiro

Reputation: 1838

STATUS_INVALID_PARAMETER from NtCreateFile

Here is the code I am using:

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

The call to NtCreateFile is failing with STATUS_INVALID_PARAMETER. The commented out bits of code in that call show other things I have tried.

The RootDirectory handle is definitely getting set in objAttributes (to 0x30). I am using this same handle elsewhere in the code, and it is working perfectly. And the frn looks good too.

I have no idea what else to try or how to narrow the cause down any further :( Any help would be greatly appreciated.

EDIT: I forgot to mention what I am trying to achieve here. Sorry! The frn comes from the USN Change Journal. I have successfully read the Change Journal using my root handle (hence I believe it is correct), and for each entry I have got an frn and parent_frn. I want to get the full path to the file, and the code below is how I am trying to convert frn to path. Both frn and parent_frn give the same STATUS_INVALID_PARAMETER return code.

Upvotes: 1

Views: 2970

Answers (1)

Steve
Steve

Reputation: 7271

A comment on the documentation for NtCreateFile says that:

If using FILE_OPEN_BY_FILE_ID, the ObjectAttributes.RootDirectory handle MUST be filled in with a handle to the volume, otherwise you will get STATUS_INVALID_PARAMETER.

To open a handle to a volume you can use CreateFile using a path of \\.\X: where X is the drive letter. Note there is no trailing backslash. The CreateFile documentation has info about it (look for the string "Opens the C: volume.")

Upvotes: 4

Related Questions