I have written a program that queries the change journal records and lists them. The change journal returns:
1) filereferencenumber( combination of fileindex.high and fileindex.low) 2) parentfilereferencenumber(same as above except it is for directory) 3) szReason(Reason it appears in the change record) 4) Filename and Filelength.
I want to find the path of this file listed in the change journal. Most of the implementations I have seen keep track of all the filereferencenumber and query it to compare, or they use FindNextFile() functions ot traverse through the entire volume.
I came across a discussion where they say, they can open a file handle using just the filereferencenumber. http://www.tech-archive.net/Archive/Windows/microsoft.public.windows.file_system/2004-11/0244.html
The msdn article says, we have to load a library before calling Internal API's http://msdn.microsoft.com/en-us/library/bb432380%28v=vs.85%29.aspx
Can someone point me in the right direction and tell me exactly what to do? How do I use NtCreateFile()?
Or, is there a way to access file path using just the filereferencenumber?
Here is the code I used: http://www.ragestorm.net/blogs/?cat=7
#include windows.h
typedef ULONG (__stdcall *pNtCreateFile)(
PHANDLE FileHandle,
ULONG DesiredAccess,
PVOID ObjectAttributes,
PVOID IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength
);
typedef ULONG (__stdcall *pNtReadFile)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PVOID ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PVOID IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL );
typedef struct _UNICODE_STRING {
USHORT Length, MaximumLength;
PWCH Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define FILE_NON_DIRECTORY_FILE 0×00000040
#define FILE_OPEN_BY_FILE_ID 0×00002000
#define FILE_OPEN 0×00000001
int main(int argc, char* argv[])
{
HANDLE d = CreateFile(L"\\\\.\\c:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 );
BY_HANDLE_FILE_INFORMATION i;
HANDLE f = CreateFile(L"c:\\bla.bla", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ULONG bla;
WriteFile(f, "helloworld", 11, &bla, NULL);
printf("%x, %d\n", f, GetLastError());
GetFileInformationByHandle(f, &i);
printf("id:%08x-%08x\n", i.nFileIndexHigh, i.nFileIndexLow);
CloseHandle(f);
pNtCreateFile NtCreatefile = (pNtCreateFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile");
pNtReadFile NtReadFile = (pNtReadFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtReadFile");
ULONG fid[2] = {i.nFileIndexLow, i.nFileIndexHigh};
UNICODE_STRING fidstr = {8, 8, (PWSTR) fid};
OBJECT_ATTRIBUTES oa = {0};
InitializeObjectAttributes (&oa, &fidstr, OBJ_CASE_INSENSITIVE, d, NULL);
ULONG iosb[2];
ULONG status = NtCreatefile(&f, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID | FILE_NON_DIRECTORY_FILE, NULL, 0);
printf("status: %X, handle: %x\n", status, f);
UCHAR buf[11] = {0};
LONG Off[2] = {0};
status = NtReadFile(f, NULL, NULL, NULL, (PVOID)&iosb, (PVOID)buf, sizeof(buf), (PLARGE_INTEGER)&Off, NULL);
printf("status: %X, bytes: %d\n", status, iosb[1]);
printf("buf: %s\n", buf);
CloseHandle(f);
CloseHandle(d);
}
As you can see, once you give the fileindex.high and fileindex.low part of the filereferencenumber, it gives you a handle to that file. And I used getFileMapping function from psapi, to get the full path. Information for those curious: http://msdn.microsoft.com/en-us/library/aa366789.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With