Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kernel32.FILE_ID_128.Identifier returns incorrect values #427

Closed
B-Hulse opened this issue Sep 14, 2023 · 0 comments
Closed

Kernel32.FILE_ID_128.Identifier returns incorrect values #427

B-Hulse opened this issue Sep 14, 2023 · 0 comments

Comments

@B-Hulse
Copy link

B-Hulse commented Sep 14, 2023

Describe the bug and how to reproduce

When using GetFileInformationByHandleEx to query the FILE_ID_INFO of a file, the returned FILE_ID_INFO reports the incorrect File ID if you use the Identifier getter of the FILE_ID_128 member.

This is a code sample from a command line exe that will report the File ID of a given file.

if (args.Length != 1)
{
    Console.WriteLine("No file path provided");
    return;
}

string fileName = args[0];

var fHandle = CreateFile(fileName, FileAccess.FILE_GENERIC_READ, FileShare.None, null, FileMode.Open, 0, IntPtr.Zero);
var fileIdInfo = GetFileInformationByHandleEx<FILE_ID_INFO>(fHandle, FILE_INFO_BY_HANDLE_CLASS.FileIdInfo);

Console.WriteLine("File ID: {0}", string.Join(", ", fileIdInfo.FileId.Identifier));
Console.WriteLine("Volume Serial Number: {0}", fileIdInfo.VolumeSerialNumber);

In a debugger the private members id0 and id1, which represent the low and high bits of the 128 bit identifier, are set as expected. These values are correct for the File ID of the file in question.
But Identifier is showing that the high bits (id1) have values other than 0.
image

What code is involved

Vanara.PInvoke.Kernel32.FILE_ID_128.Identifier getter.

/// <summary>
/// <para>Defines a 128-bit file identifier.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_file_id_128 typedef struct _FILE_ID_128 { BYTE
// Identifier[16]; } FILE_ID_128, *PFILE_ID_128;
[PInvokeData("winnt.h", MSDNShortId = "254ea6a9-e1dd-4b97-91f7-2693065c4bb8")]
[StructLayout(LayoutKind.Sequential)]
public struct FILE_ID_128
{
    private readonly ulong id0;
    private readonly ulong id1;
    
    /// <summary>
    /// <para>A byte array containing the 128 bit identifier.</para>
    /// </summary>
    public byte[] Identifier
    {
        get
        {
            using PinnedObject pin = new(id0);
            return ((IntPtr)pin).ToArray<byte>(16);
        }
        set
        {
	    using PinnedObject pin = new(id0);
	    Marshal.Copy(value, 0, pin, 16);
        }
    }
}

Expected behavior

The value returned by FILE_ID_128.Identifier should be an array of 16 bytes, where the first 8 are the byte representation of id0 and the later 8 bytes are the byte representation of id1.

@dahall dahall closed this as completed in 52a5454 Sep 15, 2023
dahall added a commit that referenced this issue Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant