Index: handle.c =================================================================== --- handle.c (revision 72609) +++ handle.c (working copy) @@ -323,9 +323,6 @@ /* FIXME: Charge quota */ } - /* Clear the table */ - RtlZeroMemory(HandleTable, sizeof(HANDLE_TABLE)); - /* Now allocate the first level structures */ HandleTableTable = ExpAllocateTablePagedPoolNoZero(Process, PAGE_SIZE); if (!HandleTableTable) @@ -335,6 +332,9 @@ return NULL; } + /* Clear the table */ + RtlZeroMemory(HandleTable, sizeof(HANDLE_TABLE)); + /* Write the pointer to our first level structures */ HandleTable->TableCode = (ULONG_PTR)HandleTableTable; @@ -653,21 +653,19 @@ /* Start allocation loop */ for (;;) { + /* Lock HandleTable */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTable->HandleTableLock[0]); + /* Get the current link */ OldValue = HandleTable->FirstFree; while (!OldValue) { - /* No free entries remain, lock the handle table */ - KeEnterCriticalRegion(); - ExAcquirePushLockExclusive(&HandleTable->HandleTableLock[0]); - /* Check the value again */ OldValue = HandleTable->FirstFree; if (OldValue) { /* Another thread has already created a new level, bail out */ - ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); - KeLeaveCriticalRegion(); break; } @@ -676,32 +674,29 @@ if (OldValue) { /* Another thread has already moved them, bail out */ - ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); - KeLeaveCriticalRegion(); break; } /* We're the first one through, so do the actual allocation */ Result = ExpAllocateHandleTableEntrySlow(HandleTable, TRUE); - - /* Unlock the table and get the value now */ - ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); - KeLeaveCriticalRegion(); OldValue = HandleTable->FirstFree; /* Check if allocation failed */ - if (!Result) + /* Check if nobody else went through here */ + if (!Result && !OldValue) { - /* Check if nobody else went through here */ - if (!OldValue) - { - /* We're still the only thread around, so fail */ - NewHandle->GenericHandleOverlay = NULL; - return NULL; - } + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + + /* We're still the only thread around, so fail */ + NewHandle->GenericHandleOverlay = NULL; + return NULL; } } + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + /* We made it, write the current value */ Handle.Value = (OldValue & FREE_HANDLE_MASK);