[NTOSKRNL] Rewrite/fix our UUID generation implementation

So that it matches Windows behavior
Also implement ExUuidCreate that will generate UUID version 1

The implementation is based on the RFC 4122
This commit is contained in:
Pierre Schweitzer 2019-02-27 21:12:32 +01:00
parent 2d9673c68f
commit eb8b481cd4
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
5 changed files with 327 additions and 165 deletions

View file

@ -711,7 +711,11 @@ ExpInitSystemPhase1(VOID)
} }
/* Initialize UUIDs */ /* Initialize UUIDs */
ExpInitUuids(); if (ExpUuidInitialization() == FALSE)
{
DPRINT1("Executive: Uuid initialization failed\n");
return FALSE;
}
/* Initialize keyed events */ /* Initialize keyed events */
if (ExpInitializeKeyedEventImplementation() == FALSE) if (ExpInitializeKeyedEventImplementation() == FALSE)

View file

@ -5,6 +5,7 @@
* PURPOSE: UUID generator * PURPOSE: UUID generator
* PROGRAMMERS: Eric Kohl * PROGRAMMERS: Eric Kohl
* Thomas Weidenmueller * Thomas Weidenmueller
* Pierre Schweitzer
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -25,75 +26,81 @@
#define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY) #define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY)
#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC) #define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC)
/* 10000 in 100-ns model = 0,1 microsecond */
#define TIME_FRAME 10000
#if defined (ALLOC_PRAGMA) #if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, ExpInitUuids) #pragma alloc_text(INIT, ExpUuidInitialization)
#pragma alloc_text(INIT, ExLuidInitialization)
#endif #endif
/* GLOBALS ****************************************************************/ /* GLOBALS ****************************************************************/
static FAST_MUTEX ExpUuidLock; FAST_MUTEX ExpUuidLock;
static ULARGE_INTEGER UuidLastTime; LARGE_INTEGER ExpUuidLastTimeAllocated;
static ULONG UuidSequence; ULONG ExpUuidSequenceNumber = 0;
static BOOLEAN UuidSequenceInitialized = FALSE; BOOLEAN ExpUuidSequenceNumberValid;
static BOOLEAN UuidSequenceChanged = FALSE; BOOLEAN ExpUuidSequenceNumberNotSaved = FALSE;
static UCHAR UuidSeed[SEED_BUFFER_SIZE]; UUID_CACHED_VALUES_STRUCT ExpUuidCachedValues = {0ULL, 0xFFFFFFFF, 0, 0, { 0x80, 0x6E, 0x6F, 0x6E, 0x69, 0x63}};
static ULONG UuidCount; BOOLEAN ExpUuidCacheValid = FALSE;
static LARGE_INTEGER LuidIncrement; ULONG ExpLuidIncrement = 1;
static LARGE_INTEGER LuidValue; LARGE_INTEGER ExpLuid = {.LowPart = 0x3e9, .HighPart = 0x0};
UUID_CACHED_VALUES_STRUCT ExpUuidCachedValues = { 0ULL, 0xFFFFFFFF, 0, 0, { 0x80, 0x6E, 0x6F, 0x6E, 0x69, 0x63 } };
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
VOID /*
* @implemented
*/
BOOLEAN
INIT_FUNCTION INIT_FUNCTION
NTAPI NTAPI
ExpInitUuids(VOID) ExpUuidInitialization(VOID)
{ {
ExInitializeFastMutex(&ExpUuidLock); ExInitializeFastMutex(&ExpUuidLock);
KeQuerySystemTime((PLARGE_INTEGER)&UuidLastTime); ExpUuidSequenceNumberValid = FALSE;
UuidLastTime.QuadPart += TICKS_15_OCT_1582_TO_1601; KeQuerySystemTime(&ExpUuidLastTimeAllocated);
UuidCount = TICKS_PER_CLOCK_TICK; return TRUE;
RtlZeroMemory(UuidSeed, SEED_BUFFER_SIZE);
} }
#define VALUE_BUFFER_SIZE 256 /*
* @implemented
*/
#define VALUE_BUFFER_SIZE 20
static NTSTATUS static NTSTATUS
ExpLoadUuidSequence(PULONG Sequence) ExpUuidLoadSequenceNumber(PULONG Sequence)
{ {
UCHAR ValueBuffer[VALUE_BUFFER_SIZE]; UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name; UNICODE_STRING KeyName, ValueName;
HANDLE KeyHandle; HANDLE KeyHandle;
ULONG ValueLength; ULONG ValueLength;
NTSTATUS Status; NTSTATUS Status;
RtlInitUnicodeString(&Name, PAGED_CODE();
L"\\Registry\\Machine\\Software\\Microsoft\\Rpc");
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\Microsoft\\Rpc");
RtlInitUnicodeString(&ValueName, L"UuidSequenceNumber");
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&Name, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL,
NULL); NULL);
Status = ZwOpenKey(&KeyHandle, Status = ZwOpenKey(&KeyHandle, GENERIC_READ, &ObjectAttributes);
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ZwOpenKey() failed (Status %lx)\n", Status); DPRINT("ZwOpenKey() failed (Status %lx)\n", Status);
return Status; return Status;
} }
RtlInitUnicodeString(&Name, L"UuidSequenceNumber");
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
Status = ZwQueryValueKey(KeyHandle, Status = ZwQueryValueKey(KeyHandle,
&Name, &ValueName,
KeyValuePartialInformation, KeyValuePartialInformation,
ValueBuffer, ValueBuffer,
VALUE_BUFFER_SIZE, VALUE_BUFFER_SIZE,
@ -105,6 +112,11 @@ ExpLoadUuidSequence(PULONG Sequence)
return Status; return Status;
} }
if (ValueInfo->Type != REG_DWORD || ValueInfo->DataLength != sizeof(DWORD))
{
return STATUS_UNSUCCESSFUL;
}
*Sequence = *((PULONG)ValueInfo->Data); *Sequence = *((PULONG)ValueInfo->Data);
DPRINT("Loaded sequence %lx\n", *Sequence); DPRINT("Loaded sequence %lx\n", *Sequence);
@ -113,24 +125,29 @@ ExpLoadUuidSequence(PULONG Sequence)
} }
#undef VALUE_BUFFER_SIZE #undef VALUE_BUFFER_SIZE
/*
* @implemented
*/
static NTSTATUS static NTSTATUS
ExpSaveUuidSequence(PULONG Sequence) ExpUuidSaveSequenceNumber(PULONG Sequence)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name; UNICODE_STRING KeyName, ValueName;
HANDLE KeyHandle; HANDLE KeyHandle;
NTSTATUS Status; NTSTATUS Status;
RtlInitUnicodeString(&Name, PAGED_CODE();
L"\\Registry\\Machine\\Software\\Microsoft\\Rpc");
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\Microsoft\\Rpc");
RtlInitUnicodeString(&ValueName, L"UuidSequenceNumber");
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&Name, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL,
NULL); NULL);
Status = ZwOpenKey(&KeyHandle, Status = ZwOpenKey(&KeyHandle,
KEY_SET_VALUE, GENERIC_READ | GENERIC_WRITE,
&ObjectAttributes); &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -138,9 +155,8 @@ ExpSaveUuidSequence(PULONG Sequence)
return Status; return Status;
} }
RtlInitUnicodeString(&Name, L"UuidSequenceNumber");
Status = ZwSetValueKey(KeyHandle, Status = ZwSetValueKey(KeyHandle,
&Name, &ValueName,
0, 0,
REG_DWORD, REG_DWORD,
Sequence, Sequence,
@ -154,98 +170,196 @@ ExpSaveUuidSequence(PULONG Sequence)
return Status; return Status;
} }
/*
* @implemented
* Warning! This function must be called
* with ExpUuidLock held!
*/
static VOID static VOID
ExpGetRandomUuidSequence(PULONG Sequence) ExpUuidSaveSequenceNumberIf(VOID)
{ {
LARGE_INTEGER Counter; NTSTATUS Status;
LARGE_INTEGER Frequency;
ULONG Value;
Counter = KeQueryPerformanceCounter(&Frequency); PAGED_CODE();
Value = Counter.u.LowPart ^ Counter.u.HighPart;
*Sequence = *Sequence ^ Value; /* Only save sequence if it has to */
if (ExpUuidSequenceNumberNotSaved == TRUE)
DPRINT("Sequence %lx\n", *Sequence);
}
static NTSTATUS
ExpCreateUuids(PULARGE_INTEGER Time,
PULONG Range,
PULONG Sequence)
{
/*
* Generate time element of the UUID. Account for going faster
* than our clock as well as the clock going backwards.
*/
while (1)
{ {
KeQuerySystemTime((PLARGE_INTEGER)Time); Status = ExpUuidSaveSequenceNumber(&ExpUuidSequenceNumber);
Time->QuadPart += TICKS_15_OCT_1582_TO_1601; if (NT_SUCCESS(Status))
if (Time->QuadPart > UuidLastTime.QuadPart)
{ {
UuidCount = 0; ExpUuidSequenceNumberNotSaved = FALSE;
break;
}
if (Time->QuadPart < UuidLastTime.QuadPart)
{
(*Sequence)++;
UuidSequenceChanged = TRUE;
UuidCount = 0;
break;
}
if (UuidCount < TICKS_PER_CLOCK_TICK)
{
UuidCount++;
break;
} }
} }
}
UuidLastTime.QuadPart = Time->QuadPart; /*
Time->QuadPart += UuidCount; * @implemented
* Warning! This function must be called
* with ExpUuidLock held!
*/
static NTSTATUS
ExpAllocateUuids(PULARGE_INTEGER Time,
PULONG Range,
PULONG Sequence)
{
NTSTATUS Status;
LARGE_INTEGER Counter, Frequency, CurrentTime, TimeDiff, ClockDiff;
*Range = 10000; /* What does this mean? Ticks per millisecond?*/ PAGED_CODE();
/* Initialize sequence number */
if (!ExpUuidSequenceNumberValid)
{
/* Try to load sequence number */
Status = ExpUuidLoadSequenceNumber(&ExpUuidSequenceNumber);
if (NT_SUCCESS(Status))
{
++ExpUuidSequenceNumber;
}
else
{
/* If we cannot, generate a "true" random */
Counter = KeQueryPerformanceCounter(&Frequency);
ExpUuidSequenceNumber ^= (ULONG_PTR)&Status ^ (ULONG_PTR)Sequence ^ Counter.LowPart ^ Counter.HighPart;
}
/* It's valid and to be saved */
ExpUuidSequenceNumberValid = TRUE;
ExpUuidSequenceNumberNotSaved = TRUE;
}
KeQuerySystemTime(&CurrentTime);
TimeDiff.QuadPart = CurrentTime.QuadPart - ExpUuidLastTimeAllocated.QuadPart;
/* If time went backwards, change sequence (see RFC example) */
if (TimeDiff.QuadPart < 0)
{
++ExpUuidSequenceNumber;
TimeDiff.QuadPart = 2 * TIME_FRAME;
/* It's to be saved */
ExpUuidSequenceNumberNotSaved = TRUE;
ExpUuidLastTimeAllocated.QuadPart = CurrentTime.QuadPart - 2 * TIME_FRAME;
}
if (TimeDiff.QuadPart == 0)
{
return STATUS_RETRY;
}
/* If time diff > 0,1ms, squash it to reduce it to keep our clock resolution */
if (TimeDiff.HighPart > 0 || TimeDiff.QuadPart > TICKS_PER_CLOCK_TICK * TIME_FRAME)
{
TimeDiff.QuadPart = TICKS_PER_CLOCK_TICK * TIME_FRAME;
}
if (TimeDiff.HighPart < 0 || TimeDiff.QuadPart <= TIME_FRAME)
{
*Range = TimeDiff.QuadPart;
ClockDiff.QuadPart = 0LL;
}
else
{
*Range = TIME_FRAME;
ClockDiff.QuadPart -= TIME_FRAME;
--ClockDiff.HighPart;
}
Time->QuadPart = CurrentTime.QuadPart - *Range - ClockDiff.QuadPart;
ExpUuidLastTimeAllocated.QuadPart = CurrentTime.QuadPart - ClockDiff.QuadPart;
*Sequence = ExpUuidSequenceNumber;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
VOID /*
INIT_FUNCTION * @implemented
NTAPI * Warning! This function must be called
ExpInitLuid(VOID) * with ExpUuidLock held!
*/
static NTSTATUS
ExpUuidGetValues(PUUID_CACHED_VALUES_STRUCT CachedValues)
{ {
LUID DummyLuidValue = SYSTEM_LUID; NTSTATUS Status;
ULARGE_INTEGER Time;
ULONG Range;
ULONG Sequence;
LuidValue.u.HighPart = DummyLuidValue.HighPart; PAGED_CODE();
LuidValue.u.LowPart = DummyLuidValue.LowPart;
LuidIncrement.QuadPart = 1; /* Allocate UUIDs */
Status = ExpAllocateUuids(&Time, &Range, &Sequence);
if (Status == STATUS_RETRY)
{
return Status;
}
if (!NT_SUCCESS(Status))
{
return STATUS_NO_MEMORY;
}
/* We need at least one UUID */
ASSERT(Range != 0);
/* Set up our internal cache
* See format_uuid_v1 in RFC4122 for magic values
*/
CachedValues->ClockSeqLow = Sequence;
CachedValues->ClockSeqHiAndReserved = (Sequence & 0x3F00) >> 8;
CachedValues->ClockSeqHiAndReserved |= 0x80;
CachedValues->AllocatedCount = Range;
/*
* Time is relative to UUID time
* And we set last time range for all the possibly
* returnable UUID
*/
Time.QuadPart += TICKS_15_OCT_1582_TO_1601;
CachedValues->Time = Time.QuadPart + (Range - 1);
return STATUS_SUCCESS;
} }
/*
* @implemented
*/
BOOLEAN
INIT_FUNCTION
NTAPI
ExLuidInitialization(VOID)
{
return TRUE;
}
/*
* @implemented
*/
VOID VOID
NTAPI NTAPI
ExAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) ExAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
{ {
LARGE_INTEGER NewLuid, PrevLuid; LARGE_INTEGER PrevLuid;
LONGLONG NewLuid, CompLuid;
/* atomically increment the luid */ /* Atomically increment the luid */
do PrevLuid.QuadPart = ExpLuid.QuadPart;
for (NewLuid = ExpLuid.QuadPart + ExpLuidIncrement; ;
NewLuid = PrevLuid.QuadPart + ExpLuidIncrement)
{ {
PrevLuid = LuidValue; CompLuid = InterlockedCompareExchange64(&ExpLuid.QuadPart,
NewLuid = RtlLargeIntegerAdd(PrevLuid, NewLuid,
LuidIncrement); PrevLuid.QuadPart);
} while(ExInterlockedCompareExchange64(&LuidValue.QuadPart, if (CompLuid == PrevLuid.QuadPart)
&NewLuid.QuadPart, {
&PrevLuid.QuadPart, break;
NULL) != PrevLuid.QuadPart); }
LocallyUniqueId->LowPart = NewLuid.u.LowPart; PrevLuid.QuadPart = CompLuid;
LocallyUniqueId->HighPart = NewLuid.u.HighPart; }
LocallyUniqueId->LowPart = PrevLuid.LowPart;
LocallyUniqueId->HighPart = PrevLuid.HighPart;
} }
@ -256,9 +370,7 @@ NTSTATUS
NTAPI NTAPI
NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
{ {
LUID NewLuid;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
/* Probe if user mode */ /* Probe if user mode */
@ -279,35 +391,91 @@ NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
} }
/* Do the allocation */ /* Do the allocation */
ExAllocateLocallyUniqueId(&NewLuid); ExAllocateLocallyUniqueId(LocallyUniqueId);
Status = STATUS_SUCCESS; return STATUS_SUCCESS;
/* Write back LUID to caller */
_SEH2_TRY
{
*LocallyUniqueId = NewLuid;
}
_SEH2_EXCEPT(ExSystemExceptionFilter())
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
return Status;
} }
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
ExUuidCreate(OUT UUID *Uuid) ExUuidCreate(OUT UUID *Uuid)
{ {
UNIMPLEMENTED; NTSTATUS Status;
return FALSE; LONG AllocatedCount;
LARGE_INTEGER Time;
BOOLEAN Valid;
PAGED_CODE();
Status = STATUS_SUCCESS;
/* Loop until we have an UUID to return */
while (TRUE)
{
/* Try to gather node values */
do
{
Time.QuadPart = ExpUuidCachedValues.Time;
RtlCopyMemory(&Uuid->Data4[0],
&ExpUuidCachedValues.NodeId[0],
SEED_BUFFER_SIZE);
Valid = ExpUuidCacheValid;
AllocatedCount = InterlockedDecrement(&ExpUuidCachedValues.AllocatedCount);
}
/* Loop till we can do it without being disturbed */
while (Time.QuadPart != ExpUuidCachedValues.Time);
/* We have more than an allocated UUID left, that's OK to return! */
if (AllocatedCount >= 0)
{
break;
}
/*
* Here, we're out of UUIDs, we need to allocate more
* We need to be alone to do it, so lock the mutex
*/
ExAcquireFastMutex(&ExpUuidLock);
if (Time.QuadPart == ExpUuidCachedValues.Time)
{
/* If allocation fails, bail out! */
Status = ExpUuidGetValues(&ExpUuidCachedValues);
if (Status != STATUS_SUCCESS)
{
ExReleaseFastMutex(&ExpUuidLock);
return Status;
}
/* Save our current sequence if changed */
ExpUuidSaveSequenceNumberIf();
}
ExReleaseFastMutex(&ExpUuidLock);
}
/*
* Once here, we've got an UUID to return
* But, if our init wasn't sane, then, make
* sure it's only used locally
*/
if (!Valid)
{
Status = RPC_NT_UUID_LOCAL_ONLY;
}
/* Set our timestamp - see RFC4211 */
Time.QuadPart -= AllocatedCount;
Uuid->Data1 = Time.LowPart;
Uuid->Data2 = Time.HighPart;
/* We also set the bit for GUIDv1 */
Uuid->Data3 = ((Time.HighPart >> 16) & 0x0FFF) | 0x1000;
return Status;
} }
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -317,7 +485,7 @@ NtAllocateUuids(OUT PULARGE_INTEGER Time,
OUT PUCHAR Seed) OUT PUCHAR Seed)
{ {
ULARGE_INTEGER IntTime; ULARGE_INTEGER IntTime;
ULONG IntRange; ULONG IntRange, IntSequence;
NTSTATUS Status; NTSTATUS Status;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
@ -352,40 +520,22 @@ NtAllocateUuids(OUT PULARGE_INTEGER Time,
_SEH2_END; _SEH2_END;
} }
/* During allocation we must be alone */
ExAcquireFastMutex(&ExpUuidLock); ExAcquireFastMutex(&ExpUuidLock);
if (!UuidSequenceInitialized) Status = ExpAllocateUuids(&IntTime,
{ &IntRange,
Status = ExpLoadUuidSequence(&UuidSequence); &IntSequence);
if (NT_SUCCESS(Status))
{
UuidSequence++;
}
else
{
ExpGetRandomUuidSequence(&UuidSequence);
}
UuidSequenceInitialized = TRUE;
UuidSequenceChanged = TRUE;
}
Status = ExpCreateUuids(&IntTime,
&IntRange,
&UuidSequence);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExReleaseFastMutex(&ExpUuidLock); ExReleaseFastMutex(&ExpUuidLock);
return Status; return Status;
} }
if (UuidSequenceChanged) /* If sequence number was changed, save it */
{ ExpUuidSaveSequenceNumberIf();
Status = ExpSaveUuidSequence(&UuidSequence);
if (NT_SUCCESS(Status))
UuidSequenceChanged = FALSE;
}
/* Allocation done, so we can release */
ExReleaseFastMutex(&ExpUuidLock); ExReleaseFastMutex(&ExpUuidLock);
/* Write back UUIDs to caller */ /* Write back UUIDs to caller */
@ -393,10 +543,10 @@ NtAllocateUuids(OUT PULARGE_INTEGER Time,
{ {
Time->QuadPart = IntTime.QuadPart; Time->QuadPart = IntTime.QuadPart;
*Range = IntRange; *Range = IntRange;
*Sequence = UuidSequence; *Sequence = IntSequence;
RtlCopyMemory(Seed, RtlCopyMemory(Seed,
UuidSeed, &ExpUuidCachedValues.NodeId[0],
SEED_BUFFER_SIZE); SEED_BUFFER_SIZE);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
@ -453,7 +603,15 @@ NtSetUuidSeed(IN PUCHAR Seed)
/* Check for buffer validity and then copy it to our seed */ /* Check for buffer validity and then copy it to our seed */
ProbeForRead(Seed, SEED_BUFFER_SIZE, sizeof(UCHAR)); ProbeForRead(Seed, SEED_BUFFER_SIZE, sizeof(UCHAR));
RtlCopyMemory(UuidSeed, Seed, SEED_BUFFER_SIZE); RtlCopyMemory(&ExpUuidCachedValues.NodeId[0], Seed, SEED_BUFFER_SIZE);
/*
* According to RFC 4122, UUID seed is based on MAC addresses
* If it is randomly set, then, it must have its multicast be set
* to be valid and avoid collisions
* Reflect it here
*/
ExpUuidCacheValid = ~(*Seed >> 7) & 1;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }

View file

@ -236,9 +236,14 @@ NTAPI
ExpInitializeCallbacks(VOID); ExpInitializeCallbacks(VOID);
INIT_FUNCTION INIT_FUNCTION
VOID BOOLEAN
NTAPI NTAPI
ExpInitUuids(VOID); ExpUuidInitialization(VOID);
INIT_FUNCTION
BOOLEAN
NTAPI
ExLuidInitialization(VOID);
INIT_FUNCTION INIT_FUNCTION
VOID VOID

View file

@ -248,11 +248,6 @@ BOOLEAN
NTAPI NTAPI
SeInitSystem(VOID); SeInitSystem(VOID);
INIT_FUNCTION
VOID
NTAPI
ExpInitLuid(VOID);
INIT_FUNCTION INIT_FUNCTION
VOID VOID
NTAPI NTAPI

View file

@ -97,7 +97,7 @@ SepInitializationPhase0(VOID)
{ {
PAGED_CODE(); PAGED_CODE();
ExpInitLuid(); if (!ExLuidInitialization()) return FALSE;
if (!SepInitSecurityIDs()) return FALSE; if (!SepInitSecurityIDs()) return FALSE;
if (!SepInitDACLs()) return FALSE; if (!SepInitDACLs()) return FALSE;
if (!SepInitSDs()) return FALSE; if (!SepInitSDs()) return FALSE;