00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 luid.c 00008 00009 Abstract: 00010 00011 This module implements the NT locally unique identifier services. 00012 00013 Author: 00014 00015 Jim Kelly (JimK) 7-June-1990 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "exp.h" 00022 00023 // 00024 // Global variables needed to support locally unique IDs. 00025 // 00026 00027 LARGE_INTEGER ExpLuid; 00028 LARGE_INTEGER ExpLuidIncrement; 00029 extern KSPIN_LOCK ExpLuidLock; 00030 00031 #ifdef ALLOC_PRAGMA 00032 #pragma alloc_text(INIT, ExLuidInitialization) 00033 #pragma alloc_text(PAGE, NtAllocateLocallyUniqueId) 00034 #endif 00035 00036 BOOLEAN 00037 ExLuidInitialization ( 00038 VOID 00039 ) 00040 00041 /*++ 00042 00043 Routine Description: 00044 00045 This function initializes the locally unique identifier allocation. 00046 00047 NOTE: THE LUID ALLOCATION SERVICES ARE NEEDED BY SECURITY IN PHASE 0 00048 SYSTEM INITIALIZATION. FOR THIS REASON, LUID INITIALIZATION IS 00049 PERFORMED AS PART OF PHASE 0 SECURITY INITIALIZATION. 00050 00051 Arguments: 00052 00053 None. 00054 00055 Return Value: 00056 00057 A value of TRUE is returned if the initialization is successfully 00058 completed. Otherwise, a value of FALSE is returned. 00059 00060 --*/ 00061 00062 { 00063 00064 // 00065 // Initialize the LUID source value. 00066 // 00067 // The first 1000 values are reserved for static definition. This 00068 // value can be increased with later releases with no adverse impact. 00069 // 00070 // N.B. The LUID source always refers to the "next" allocatable LUID. 00071 // 00072 00073 ExpLuid.LowPart = 1001; 00074 ExpLuid.HighPart = 0; 00075 KeInitializeSpinLock(&ExpLuidLock); 00076 ExpLuidIncrement.QuadPart = 1; 00077 return TRUE; 00078 } 00079 00080 NTSTATUS 00081 NtAllocateLocallyUniqueId ( 00082 OUT PLUID Luid 00083 ) 00084 00085 /*++ 00086 00087 Routine Description: 00088 00089 This function returns an LUID value that is unique since the system 00090 was last rebooted. It is unique on the system it is generated on 00091 only (not network wide). 00092 00093 There are no restrictions on who can allocate LUIDs. The LUID space 00094 is large enough that this will never present a problem. If one LUID 00095 is allocated every 100ns, they will not be exhausted for roughly 00096 15,000 years (100ns * 2^63). 00097 00098 Arguments: 00099 00100 Luid - Supplies the address of a variable that will receive the 00101 new LUID. 00102 00103 Return Value: 00104 00105 STATUS_SUCCESS is returned if the service is successfully executed. 00106 00107 STATUS_ACCESS_VIOLATION is returned if the output parameter for the 00108 LUID cannot be written. 00109 00110 --*/ 00111 00112 { 00113 00114 KPROCESSOR_MODE PreviousMode; 00115 NTSTATUS Status; 00116 00117 // 00118 // Establish an exception handler and attempt to write the Luid 00119 // to the specified variable. If the write attempt fails, then return 00120 // the exception code as the service status. Otherwise return success 00121 // as the service status. 00122 // 00123 00124 try { 00125 00126 // 00127 // Get previous processor mode and probe argument if necessary. 00128 // 00129 00130 PreviousMode = KeGetPreviousMode(); 00131 if (PreviousMode != KernelMode) { 00132 ProbeForWrite((PVOID)Luid, sizeof(LUID), sizeof(ULONG)); 00133 } 00134 00135 // 00136 // Allocate and store a locally unique Id. 00137 // 00138 00139 ExAllocateLocallyUniqueId(Luid); 00140 00141 } except (ExSystemExceptionFilter()) { 00142 return GetExceptionCode(); 00143 } 00144 00145 return STATUS_SUCCESS; 00146 }