C# 从OpenFileById获取访问冲突

C# 从OpenFileById获取访问冲突,c#,.net,windows,filesystems,C#,.net,Windows,Filesystems,我试图仅使用唯一的文件ID获取NTFS文件系统上的文件信息。 我遇到的问题是从ID生成句柄,因为我的代码导致访问冲突,我不知道为什么 为了获得唯一的文件ID,我使用了源代码。我很确定问题出在描述符上。我读过(第一个答案第二个评论),我可以用一个长整数代替guid,但这似乎不起作用。但是我不知道如何用我的文件ID信息创建guid 这是我目前掌握的代码 public class WinAPI { [DllImport("ntdll.dll", SetLastError = true)]

我试图仅使用唯一的文件ID获取NTFS文件系统上的文件信息。 我遇到的问题是从ID生成句柄,因为我的代码导致访问冲突,我不知道为什么

为了获得唯一的文件ID,我使用了源代码。我很确定问题出在描述符上。我读过(第一个答案第二个评论),我可以用一个长整数代替guid,但这似乎不起作用。但是我不知道如何用我的文件ID信息创建guid

这是我目前掌握的代码

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

    }
}
公共类WinAPI
{
[DllImport(“ntdll.dll”,SetLastError=true)]
公共静态外部IntPtr NtQueryInformationFile(IntPtr文件句柄、ref IO_STATUS_块IoStatusBlock、IntPtr pInfoBlock、uint长度、文件信息_类文件信息);
公共结构IO_状态_块
{
uint状态;
乌龙信息;
}
公共结构文件内部信息
{
公共ulong指数编号;
}
//缩写后的值比显示的值多
公共枚举文件\u信息\u类
{
FileDirectoryInformation=1,//1
FileFullDirectoryInformation,//2
FileBothDirectoryInformation,//3
FileBasicInformation,//4
文件标准信息,//5
文件内部信息//6
}
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部bool GetFileInformationByHandle(IntPtr hFile,out BY_HANDLE_FILE_INFORMATION lpFileInformation);
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部IntPtr OpenFileById(IntPtr hFile、文件ID、描述符lpFileID、uint dwDesiredAccess、uint dwShareMode、uint dwFlagas);
[StructLayout(LayoutKind.Explicit)]
公共结构文件\u ID\u描述符
{
[FieldOffset(0)]公共uint dwSize;
[FieldOffset(4)]公共文件\u ID\u类型;
//[FieldOffset(8)]公共Guid;
[FieldOffset(8)]公共长文件引用编号;
}
公共枚举文件\u ID\u类型
{
FileIdType=0,
ObjectedType=1,
ExtendedFileIdType=2,
MaximumFileIdType
};
公共结构的句柄文件信息
{
公共uint文件属性;
公共文件时间创建时间;
公共文件时间LastAccessTime;
公共文件时间LastWriteTime;
公共单位卷序号;
公共单元文件大小高;
公共uint文件;
公共uint链接数;
公共uint文件索引高;
公共uint FileIndexLow;
}
}
公共类文件句柄
{
公共ulong Get_索引()
{
WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo=新的WinAPI.BY_HANDLE_FILE_INFORMATION();
FileInfo fi=newfileinfo(@“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正如我所说,使用来自pinvoke的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            File_Handle handle = new File_Handle();
            handle.Get_Index();
            handle.Retrieve_File();
        }
    }
    public class WinAPI
    {

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool GetFileInformationByHandle(IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);

        [DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]
        public static extern int OpenFile([System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]string lpFileName, out OFSTRUCT lpReOpenBuff,
           OpenFileStyle uStyle);

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

        [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
        public struct OFSTRUCT
        {
            public byte cBytes;
            public byte fFixedDisc;
            public UInt16 nErrCode;
            public UInt16 Reserved1;
            public UInt16 Reserved2;
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 128)]
            public string szPathName;
        }
        [Flags]
        public enum OpenFileStyle : uint
        {
            OF_CANCEL = 0x00000800,  // Ignored. For a dialog box with a Cancel button, use OF_PROMPT.
            OF_CREATE = 0x00001000,  // Creates a new file. If file exists, it is truncated to zero (0) length.
            OF_DELETE = 0x00000200,  // Deletes a file.
            OF_EXIST = 0x00004000,  // Opens a file and then closes it. Used to test that a file exists
            OF_PARSE = 0x00000100,  // Fills the OFSTRUCT structure, but does not do anything else.
            OF_PROMPT = 0x00002000,  // Displays a dialog box if a requested file does not exist 
            OF_READ = 0x00000000,  // Opens a file for reading only.
            OF_READWRITE = 0x00000002,  // Opens a file with read/write permissions.
            OF_REOPEN = 0x00008000,  // Opens a file by using information in the reopen buffer.

            // For MS-DOS–based file systems, opens a file with compatibility mode, allows any process on a 
            // specified computer to open the file any number of times.
            // Other efforts to open a file with other sharing modes fail. This flag is mapped to the 
            // FILE_SHARE_READ|FILE_SHARE_WRITE flags of the CreateFile function.
            OF_SHARE_COMPAT = 0x00000000,

            // Opens a file without denying read or write access to other processes.
            // On MS-DOS-based file systems, if the file has been opened in compatibility mode
            // by any other process, the function fails.
            // This flag is mapped to the FILE_SHARE_READ|FILE_SHARE_WRITE flags of the CreateFile function.
            OF_SHARE_DENY_NONE = 0x00000040,

            // Opens a file and denies read access to other processes.
            // On MS-DOS-based file systems, if the file has been opened in compatibility mode,
            // or for read access by any other process, the function fails.
            // This flag is mapped to the FILE_SHARE_WRITE flag of the CreateFile function.
            OF_SHARE_DENY_READ = 0x00000030,

            // Opens a file and denies write access to other processes.
            // On MS-DOS-based file systems, if a file has been opened in compatibility mode,
            // or for write access by any other process, the function fails.
            // This flag is mapped to the FILE_SHARE_READ flag of the CreateFile function.
            OF_SHARE_DENY_WRITE = 0x00000020,

            // Opens a file with exclusive mode, and denies both read/write access to other processes.
            // If a file has been opened in any other mode for read/write access, even by the current process,
            // the function fails.
            OF_SHARE_EXCLUSIVE = 0x00000010,

            // Verifies that the date and time of a file are the same as when it was opened previously.
            // This is useful as an extra check for read-only files.
            OF_VERIFY = 0x00000400,

            // Opens a file for write access only.
            OF_WRITE = 0x00000001
        }
    }

    public class File_Handle
    {

        public ulong Get_Index()
        {
            WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();

            FileInfo fi = new FileInfo(@"c:\Temp\Test.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()
        {

            WinAPI.OFSTRUCT ofStruct = new WinAPI.OFSTRUCT();
            int err = WinAPI.OpenFile(@"c:\Temp\Test.txt", out ofStruct, WinAPI.OpenFileStyle.OF_READ);

            return "Dummy";

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Runtime.InteropServices;
使用System.IO;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
File_Handle=new File_Handle();
handle.Get_Index();
handle.Retrieve_File();
}
}
公共类WinAPI
{
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部bool GetFileInformationByHandle(IntPtr hFile,out BY_HANDLE_FILE_INFORMATION lpFileInformation);
[DllImport(“kernel32.dll”,BestFitMapping=false,ThrowOnUnmappableChar=true)]
public static extern int OpenFile([System.Runtime.InteropServices.marshallas(System.Runtime.InteropServices.UnmanagedType.LPStr)]字符串lpFileName,结构外的lpreopbuff,
OpenFileStyle(自定义样式);
[StructLayout(LayoutKind.Explicit)]
公共结构文件\u ID\u描述符
{
[字段偏移量(0)]
公共单位面积;
[现场偏移(4)]
公共文件\u ID\u类型;
//[FieldOffset(8)]公共Guid;
[现场偏移(8)]
公共长文件引用编号;
}
公共枚举文件\u ID\u类型
{
FileIdType=0,
ObjectedType=1,
ExtendedFileIdType=2,
MaximumFileIdType
};
公共结构的句柄文件信息
{
公共uint文件属性;
公共文件时间创建时间;
公共文件时间LastAccessTime;
公共文件时间LastWriteTime;
公共单位卷序号;
公共单元文件大小高;
公共uint文件;
公共uint链接数;
公共uint文件索引高;
公共uint FileIndexLow;
}
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
结构的公共结构
{
公共字节;
公共字节fFixedDisc;
公共UInt16神经代码;
公共UInt16保留区1;
公共UInt16保留区2;
[System.Runtime.InteropServices.Marshallas(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst=128)]
公共字符串路径名;
}
[旗帜]
公共枚举OpenFileStyle:uint
{
OF_CANCEL=0x00000800,//已忽略。对于带有取消按钮的对话框,请使用_提示符。
OF_CREATE=0x00001000,//创建一个新文件。如果文件存在,它将被截断为零(0)长度。
OF_DELETE=0x00000200,//删除一个文件。
OF_EXIST=0x00004000,//打开一个文件,然后关闭它。用于测试文件是否存在
乌帕