I am trying to get file information on a NTFS filesystem using only the unique file ID. The problem I have is in generating a handle from the ID because my code is causing access violations and I do not know why.
To get the unique file ID I used the code from HERE. I am pretty sure the problem is the descriptor. I've read HERE (1st answer 2nd comment) I can use a long Integer instead of the guid but this seems not to work. But I don't know how to create a guid with my file ID information.
This is the code I have so far.
public class WinAPI
{
[DllImport("ntdll.dll", SetLastError = true)]
public static extern IntPtr NtQueryInformationFile(IntPtr fileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr pInfoBlock, uint length, FILE_INFORMATION_CLASS fileInformation);
public struct IO_STATUS_BLOCK
{
uint status;
ulong information;
}
public struct _FILE_INTERNAL_INFORMATION
{
public ulong IndexNumber;
}
// Abbreviated, there are more values than shown
public enum FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1, // 1
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4
FileStandardInformation, // 5
FileInternalInformation // 6
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenFileById(IntPtr hFile, FILE_ID_DESCRIPTOR lpFileID, uint dwDesiredAccess, uint dwShareMode, uint dwFlagas);
[StructLayout(LayoutKind.Explicit)]
public struct FILE_ID_DESCRIPTOR
{
[FieldOffset(0)] public uint dwSize;
[FieldOffset(4)] public FILE_ID_TYPE type;
// [FieldOffset(8)] public Guid guid;
[FieldOffset(8)] public long FileReferenceNumber;
}
public enum FILE_ID_TYPE
{
FileIdType = 0,
ObjectIdType = 1,
ExtendedFileIdType = 2,
MaximumFileIdType
};
public struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public FILETIME CreationTime;
public FILETIME LastAccessTime;
public FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
}
public class File_Handle
{
public ulong Get_Index()
{
WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();
FileInfo fi = new FileInfo(@"D:\Test\Testfile.txt");
FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
WinAPI.GetFileInformationByHandle(fs.Handle, out objectFileInfo);
fs.Close();
ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + (ulong)objectFileInfo.FileIndexLow;
return fileIndex;
}
public string Retrieve_File(ulong Index)
{
WinAPI.FILE_ID_DESCRIPTOR Descriptor = new WinAPI.FILE_ID_DESCRIPTOR { dwSize = 24, type = WinAPI.FILE_ID_TYPE.FileIdType, FileReferenceNumber = (long)Index };
FileInfo fi = new FileInfo(@"D:\Test\TestfileRef.txt");
FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
FileStream wf = new FileStream(WinAPI.OpenFileById(fs.Handle, Descriptor, 0, 0, 0x08000000), FileAccess.ReadWrite);
WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();
WinAPI.GetFileInformationByHandle(wf.Handle, out objectFileInfo);
fs.Close();
wf.Close();
return "Dummy";
}
}