Reputation: 1838
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
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