summaryrefslogtreecommitdiffstats
path: root/private/ntos/ex/luid.c
blob: 7dcdc60016a277f22b7f9ba40358609cf6b6d44e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    luid.c

Abstract:

    This module implements the NT locally unique identifier services.

Author:

    Jim Kelly (JimK) 7-June-1990

Revision History:

--*/

#include "exp.h"

//
//  Global variables needed to support locally unique IDs.
//

LARGE_INTEGER ExpLuid;
LARGE_INTEGER ExpLuidIncrement;
extern KSPIN_LOCK ExpLuidLock;

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, ExLuidInitialization)
#pragma alloc_text(PAGE, NtAllocateLocallyUniqueId)
#endif

BOOLEAN
ExLuidInitialization (
    VOID
    )

/*++

Routine Description:

    This function initializes the locally unique identifier allocation.

    NOTE:  THE LUID ALLOCATION SERVICES ARE NEEDED BY SECURITY IN PHASE 0
           SYSTEM INITIALIZATION.  FOR THIS REASON, LUID INITIALIZATION IS
           PERFORMED AS PART OF PHASE 0 SECURITY INITIALIZATION.

Arguments:

    None.

Return Value:

    A value of TRUE is returned if the initialization is successfully
    completed.  Otherwise, a value of FALSE is returned.

--*/

{

    //
    // Initialize the LUID source value.
    //
    // The first 1000 values are reserved for static definition. This
    // value can be increased with later releases with no adverse impact.
    //
    // N.B. The LUID source always refers to the "next" allocatable LUID.
    //

    ExpLuid.LowPart = 1001;
    ExpLuid.HighPart = 0;
    KeInitializeSpinLock(&ExpLuidLock);
    ExpLuidIncrement.QuadPart = 1;
    return TRUE;
}

NTSTATUS
NtAllocateLocallyUniqueId (
    OUT PLUID Luid
    )

/*++

Routine Description:

    This function returns an LUID value that is unique since the system
    was last rebooted.  It is unique on the system it is generated on
    only (not network wide).

    There are no restrictions on who can allocate LUIDs.  The LUID space
    is large enough that this will never present a problem.  If one LUID
    is allocated every 100ns, they will not be exhausted for roughly
    15,000 years (100ns * 2^63).

Arguments:

    Luid - Supplies the address of a variable that will receive the
        new LUID.

Return Value:

    STATUS_SUCCESS is returned if the service is successfully executed.

    STATUS_ACCESS_VIOLATION is returned if the output parameter for the
        LUID cannot be written.

--*/

{

    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;

    //
    // Establish an exception handler and attempt to write the Luid
    // to the specified variable. If the write attempt fails, then return
    // the exception code as the service status. Otherwise return success
    // as the service status.
    //

    try {

        //
        // Get previous processor mode and probe argument if necessary.
        //

        PreviousMode = KeGetPreviousMode();
        if (PreviousMode != KernelMode) {
            ProbeForWrite((PVOID)Luid, sizeof(LUID), sizeof(ULONG));
        }

        //
        // Allocate and store a locally unique Id.
        //

        ExAllocateLocallyUniqueId(Luid);

    } except (ExSystemExceptionFilter()) {
        return GetExceptionCode();
    }

    return STATUS_SUCCESS;
}