August 30th, 2024

In the Windows kernel, what is a LUID, and what makes it loo-ey?

In the Windows kernel, you will see a thing called a LUID, commonly pronounced /loo-id/. The kernel documentation says

The LUID structure is an opaque structure that specifies an identifier that is guaranteed to be unique on the local machine. For more information, see the reference page for LUID in the Microsoft Windows SDK documentation.

If you go to the Windows SDK documentation, you get

Describes a local identifier for an adapter.

Remarks

This structure is used by the ID3D12Device::GetAdapterLuid and GetSharedResourceAdapterLuid methods.

Somehow, the display driver folks took over the LUID documentation and made it be all about display drivers. It’s as if the file system team had taken over the LARGE_INTEGER documentation and made it say “The LARGE_INTEGER structure holds the size of a file in bytes” because the Get­File­Size­Ex function uses the LARGE_INTEGER structure for that purpose.

Really, a LUID is a structure that holds a 64-bit integer (broken into two 32-bit parts). The 64-bit integer is “locally unique”, in the sense that it will not match any other LUID generated from the same system until the system is rebooted.

You can ask for a LUID to be generated for you by calling Allocate­Locally­Unique­Id.

Since LUIDs are only unique to the system, you probably shouldn’t send them to other systems (since they won’t be unique there). And since LUIDs lose uniqueness when the system reboots, you probably shouldn’t save them anywhere persistent, because they won’t make sense after a reboot. The purpose of a LUID is to let the system identify things whose lifetimes do not extend beyond a reboot.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

11 comments

Discussion is closed. Login to edit/delete existing comments.

  • Shawn Van Ness

    Some minor PTSD here .. LUID is defined as a struct of two 32-bit values, not a 64-bit int (or a union of those things like LARGE_INTEGER), so this can have an unexpected effect on packing and alignment when used in other structures, such as TOKEN_PRIVILEGES { DWORD count, LUID luid, DWORD attributes }

    Once had some C# code working ok on 32-bit OS but crashing on 64-bit.. took a little while to pinpoint this.

    <code>

    Read more
  • Peter Cooper Jr.

    The links to the kernel documentation and the SDK documentation go to the same place; I presume the latter is supposed to point somewhere else in the giant pile of documentation from Microsoft.

    Thanks.

  • Nick

    Can’t help but think that this could just be, more or less, somewhere in the kernel:

    static long long int s_luid = 0;
    static long long int Allocate­Locally­Unique­Id() { return s_luid++; }

    Making updates atomic is left as an exercise for the reader.

    (note: I am not a kernel developer and haven’t touched C in 15 years)

    • Paul Jackson · Edited

      That’s exactly how it’s done.
      x.com/0gtweet/status/1829576931496669207

    • Kyle Sluder

      See Shawn’s comment about the type actually being defined as a pair of 32-bit integers. Depending on the platform, the compiler may or may not lay out such a struct identically to a single 64-bit integer.

    • Shawn Van Ness

      Sometimes it’s important that IDs are not so easily guessable (not sure if that’s the case for LUID, but maybe).

      • 紅樓鍮 · Edited

        This can be done using a 64-bit block cipher with a 64-bit block size operated in CTR mode: you just successively encrypt 0, 1, 2, … with the block cipher to get the LUIDs. (Actually you should start from a random initialization vector instead of 0, but.)

        A 64-bit cipher is really weak however, so at the end of the day it might not be possible to make LUIDs cryptographically unpredictable. Edit: I confused the block...

        Read more
  • Erik Fjeldstrom

    So is this sort of an extension of RegisterWindowMessage, only more generic?

  • Rutger Ellen

    The until the system reboots is an additional specification that is not documented on either page, it could be considered an important property, however when thinking about it it is almost inevitable but I probably would have missed it if I had ever felt a need to use a luid

    • Joshua Hudson

      I have a copy of the documentation for the Windows NT 3.5 APIs. At that time it did say they only last until reboot.

      I was wondering, why does Raymond feel the need to write about this. But now I see. The MSDN documentation got trashed somewhere in the intervening years.

      • Tim Weis

        The uniqueness guarantees are documented under the documentation for AllocateLocallyUniqueId. The documentation links to the Security Glossary that repeats the guarantees.