如何获取文件夹的NTFS文件ID

时间:2013-03-22 09:38:58

标签: c# winapi io pinvoke ntfs

如何在c#中获取文件夹的唯一NTFS文件ID?

1 个答案:

答案 0 :(得分:5)

    internal static Int64 GetDirectoryId(string dir)
    {
        var handle = CreateFile(dir, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, 0x02000000 | 0x00000080, IntPtr.Zero);
        var fileStruct = new FILE_ID_BOTH_DIR_INFO();
        GetFileInformationByHandleEx(handle, FILE_INFO_BY_HANDLE_CLASS.FileIdBothDirectoryInfo, out fileStruct, (uint)Marshal.SizeOf(fileStruct));
        CloseHandle(handle);
        var win32Error = Marshal.GetLastWin32Error();
        if (win32Error != 0)
            throw new Win32Exception();

        return fileStruct.FileId.QuadPart;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool GetFileInformationByHandleEx(
        IntPtr hFile,
        FILE_INFO_BY_HANDLE_CLASS infoClass,
        out FILE_ID_BOTH_DIR_INFO dirInfo,
        uint dwBufferSize);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CloseHandle(
        IntPtr handle);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CreateFile(
        string lpFileName,
        [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
        [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
        IntPtr lpSecurityAttributes,
        [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct FILE_ID_BOTH_DIR_INFO
    {
        public uint NextEntryOffset;
        public uint FileIndex;
        public LARGE_INTEGER CreationTime;
        public LARGE_INTEGER LastAccessTime;
        public LARGE_INTEGER LastWriteTime;
        public LARGE_INTEGER ChangeTime;
        public LARGE_INTEGER EndOfFile;
        public LARGE_INTEGER AllocationSize;
        public uint FileAttributes;
        public uint FileNameLength;
        public uint EaSize;
        public char ShortNameLength;
        [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 12)]
        public string ShortName;
        public LARGE_INTEGER FileId;
        [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
        public string FileName;
    }

    [StructLayout(LayoutKind.Explicit, Size=8)]
    private struct LARGE_INTEGER
    {
        [FieldOffset(0)]public Int64 QuadPart;
        [FieldOffset(0)]public UInt32 LowPart;
        [FieldOffset(4)]public Int32 HighPart;
    }

    private enum FILE_INFO_BY_HANDLE_CLASS
    {
        FileIdBothDirectoryInfo = 10
    }