Beispiel #1
0
VOID
NTAPI
INIT_FUNCTION
CmpInitializeCache(VOID)
{
    ULONG Length, i;

    /* Calculate length for the table */
    Length = CmpHashTableSize * sizeof(CM_KEY_HASH_TABLE_ENTRY);

    /* Allocate it */
    CmpCacheTable = CmpAllocate(Length, TRUE, TAG_CM);
    if (!CmpCacheTable)
    {
        /* Take the system down */
        KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 1, 0, 0);
    }

    /* Zero out the table */
    RtlZeroMemory(CmpCacheTable, Length);

    /* Initialize the locks */
    for (i = 0; i < CmpHashTableSize; i++)
    {
        /* Setup the pushlock */
        ExInitializePushLock(&CmpCacheTable[i].Lock);
    }

    /* Calculate length for the name cache */
    Length = CmpHashTableSize * sizeof(CM_NAME_HASH_TABLE_ENTRY);

    /* Now allocate the name cache table */
    CmpNameCacheTable = CmpAllocate(Length, TRUE, TAG_CM);
    if (!CmpNameCacheTable)
    {
        /* Take the system down */
        KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 3, 0, 0);
    }

    /* Zero out the table */
    RtlZeroMemory(CmpNameCacheTable, Length);

    /* Initialize the locks */
    for (i = 0; i < CmpHashTableSize; i++)
    {
        /* Setup the pushlock */
        ExInitializePushLock(&CmpNameCacheTable[i].Lock);
    }

    /* Setup the delayed close table */
    CmpInitializeDelayedCloseTable();
}
Beispiel #2
0
PGDI_POOL
NTAPI
GdiPoolCreate(
    ULONG cjAllocSize,
    ULONG ulTag)
{
    PGDI_POOL pPool;

    /* Allocate a pool object */
    pPool = EngAllocMem(0, sizeof(GDI_POOL), 'lopG');
    if (!pPool) return NULL;

    /* Initialize the object */
    ExInitializePushLock(&pPool->pushlock);
    InitializeListHead(&pPool->leInUseList);
    InitializeListHead(&pPool->leReadyList);
    InitializeListHead(&pPool->leEmptyList);
    pPool->cEmptySections = 0;
    pPool->cjAllocSize = cjAllocSize;
    pPool->ulTag = ulTag;
    pPool->cjSectionSize = GDI_POOL_ALLOCATION_GRANULARITY;
    pPool->cSlotsPerSection = pPool->cjSectionSize / cjAllocSize;
    DBG_INITLOG(&pPool->slhLog);

    return pPool;
}
Beispiel #3
0
void
RtlpInitializeLockAtomTable(
    IN OUT PRTL_ATOM_TABLE AtomTable
    )
{
    ExInitializePushLock( &AtomTable->PushLock );
    return;
}
Beispiel #4
0
VOID
NTAPI
INIT_FUNCTION
ExpInitializeHandleTables(VOID)
{
    /* Initialize the list of handle tables and the lock */
    InitializeListHead(&HandleTableListHead);
    ExInitializePushLock(&HandleTableListLock);
}
Beispiel #5
0
VOID
ExpInitializePushLocks (
    VOID
    )
/*++

Routine Description:

    Calculates the value of the pushlock spin count

Arguments:

    None

Return Value:

    None

--*/
{

#if defined(_AMD64_)
    EX_PUSH_LOCK ScratchPushLock;
#endif

#if !NT_UP
    if (KeNumberProcessors > 1) {
        ExPushLockSpinCount = 1024;
    } else {
        ExPushLockSpinCount = 0;
    }
#endif

    //
    // Exercise the following routines early, in order to patch any
    // prefetchw instructions therein.
    // 

#if defined(_AMD64_)

    ExInitializePushLock( &ScratchPushLock );

    ExfAcquirePushLockShared( &ScratchPushLock );
    ExfReleasePushLock( &ScratchPushLock );

    ExfAcquirePushLockShared( &ScratchPushLock );
    ExfReleasePushLockShared( &ScratchPushLock );

    ExfAcquirePushLockExclusive( &ScratchPushLock );
    ExfReleasePushLockExclusive( &ScratchPushLock );

#endif
}
Beispiel #6
0
VOID KphTestPushLock()
{
    ULONG i;
    
    ExInitializePushLock(&TestLock);
    
    for (i = 0; i < 10; i++)
    {
        HANDLE threadHandle;
        OBJECT_ATTRIBUTES objectAttributes;
        
        InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
        PsCreateSystemThread(&threadHandle, 0, &objectAttributes, NULL, NULL, KphpTestPushLockThreadStart, NULL);
    }
}
Beispiel #7
0
NTSTATUS
NTAPI
INIT_FUNCTION
ObpInitSdCache(VOID)
{
    ULONG i;

    /* Loop each cache entry */
    for (i = 0; i < SD_CACHE_ENTRIES; i++)
    {
        /* Initialize the lock and the list */
        InitializeListHead(&ObsSecurityDescriptorCache[i].Head);
        ExInitializePushLock(&ObsSecurityDescriptorCache[i].PushLock);
    }

    /* Return success */
    return STATUS_SUCCESS;
}
Beispiel #8
0
NTSTATUS
NTAPI
CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                  IN ULONG OperationType,
                  IN ULONG HiveFlags,
                  IN ULONG FileType,
                  IN PVOID HiveData OPTIONAL,
                  IN HANDLE Primary,
                  IN HANDLE Log,
                  IN HANDLE External,
                  IN PCUNICODE_STRING FileName OPTIONAL,
                  IN ULONG CheckFlags)
{
    PCMHIVE Hive;
    FILE_STANDARD_INFORMATION FileInformation;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileSizeInformation;
    NTSTATUS Status;
    ULONG Cluster;

    /* Assume failure */
    *RegistryHive = NULL;

    /*
     * The following are invalid:
     * An external hive that is also internal.
     * A log hive that's not a primary hive too.
     * A volatile hive that's linked to permanent storage.
     * An in-memory initialization without hive data.
     * A log hive that's not linked to a correct file type.
     */
    if (((External) && ((Primary) || (Log))) ||
        ((Log) && !(Primary)) ||
        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
        ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
        ((Log) && (FileType != HFILE_TYPE_LOG)))
    {
        /* Fail the request */
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if this is a primary hive */
    if (Primary)
    {
        /* Get the cluster size */
        Status = ZwQueryVolumeInformationFile(Primary,
                                              &IoStatusBlock,
                                              &FileSizeInformation,
                                              sizeof(FILE_FS_SIZE_INFORMATION),
                                              FileFsSizeInformation);
        if (!NT_SUCCESS(Status)) return Status;

        /* Make sure it's not larger then the block size */
        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
        {
            /* Fail */
            return STATUS_REGISTRY_IO_FAILED;
        }

        /* Otherwise, calculate the cluster */
        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
        Cluster = max(1, Cluster);
    }
    else
    {
        /* Otherwise use cluster 1 */
        Cluster = 1;
    }

    /* Allocate the hive */
    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CMHIVE);
    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;

    /* Setup null fields */
    Hive->UnloadEvent = NULL;
    Hive->RootKcb = NULL;
    Hive->Frozen = FALSE;
    Hive->UnloadWorkItem = NULL;
    Hive->GrowOnlyMode = FALSE;
    Hive->GrowOffset = 0;
    Hive->CellRemapArray = NULL;
    Hive->UseCountLog.Next = 0;
    Hive->LockHiveLog.Next = 0;
    Hive->FileObject = NULL;
    Hive->NotifyList.Flink = NULL;
    Hive->NotifyList.Blink = NULL;

    /* Set loading flag */
    Hive->HiveIsLoading = TRUE;

    /* Set the current thread as creator */
    Hive->CreatorOwner = KeGetCurrentThread();

    /* Initialize lists */
    InitializeListHead(&Hive->KcbConvertListHead);
    InitializeListHead(&Hive->KnodeConvertListHead);
    InitializeListHead(&Hive->TrustClassEntry);

    /* Allocate the view log */
    Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(KGUARDED_MUTEX),
                                           TAG_CMHIVE);
    if (!Hive->ViewLock)
    {
        /* Cleanup allocation and fail */
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Allocate the flush lock */
    Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                              sizeof(ERESOURCE),
                                              TAG_CMHIVE);
    if (!Hive->FlusherLock)
    {
        /* Cleanup allocations and fail */
        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Setup the handles */
    Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
    Hive->FileHandles[HFILE_TYPE_LOG] = Log;
    Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External;

    /* Initailize the guarded mutex */
    KeInitializeGuardedMutex(Hive->ViewLock);
    Hive->ViewLockOwner = NULL;

    /* Initialize the flush lock */
    ExInitializeResourceLite(Hive->FlusherLock);

    /* Setup hive locks */
    ExInitializePushLock(&Hive->HiveLock);
    Hive->HiveLockOwner = NULL;
    ExInitializePushLock(&Hive->WriterLock);
    Hive->WriterLockOwner = NULL;
    ExInitializePushLock(&Hive->SecurityLock);
    Hive->HiveSecurityLockOwner = NULL;

    /* Clear file names */
    RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
    RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);

    /* Initialize the view list */
    CmpInitHiveViewList(Hive);

    /* Initailize the security cache */
    CmpInitSecurityCache(Hive);

    /* Setup flags */
    Hive->Flags = 0;
    Hive->FlushCount = 0;

    /* Set flags */
    Hive->Flags = HiveFlags;

    /* Check if this is a primary */
    if (Primary)
    {
        /* Check how large the file is */
        ZwQueryInformationFile(Primary,
                               &IoStatusBlock,
                               &FileInformation,
                               sizeof(FileInformation),
                               FileStandardInformation);
        Cluster = FileInformation.EndOfFile.LowPart;
    }

    /* Initialize it */
    Status = HvInitialize(&Hive->Hive,
                          OperationType,
                          FileType,
                          HiveFlags,
                          HiveData,
                          CmpAllocate,
                          CmpFree,
                          CmpFileSetSize,
                          CmpFileWrite,
                          CmpFileRead,
                          CmpFileFlush,
                          Cluster,
                          FileName);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup allocations and fail */
        ExDeleteResourceLite(Hive->FlusherLock);
        ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
        ExFreePoolWithTag(Hive, TAG_CMHIVE);
        return Status;
    }

    /* Check if we should verify the registry */
    if ((OperationType == HINIT_FILE) ||
        (OperationType == HINIT_MEMORY) ||
        (OperationType == HINIT_MEMORY_INPLACE) ||
        (OperationType == HINIT_MAPFILE))
    {
        /* Verify integrity */
        ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags);
        if (CheckStatus != 0)
        {
            /* Cleanup allocations and fail */
            ExDeleteResourceLite(Hive->FlusherLock);
            ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
            ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
            ExFreePoolWithTag(Hive, TAG_CMHIVE);
            return STATUS_REGISTRY_CORRUPT;
        }
    }

    /* Lock the hive list */
    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);

    /* Insert this hive */
    InsertHeadList(&CmpHiveListHead, &Hive->HiveList);

    /* Release the lock */
    ExReleasePushLock(&CmpHiveListHeadLock);

    /* Return the hive and success */
    *RegistryHive = (PCMHIVE)Hive;
    return STATUS_SUCCESS;
}
Beispiel #9
0
NTKERNELAPI
PEX_PUSH_LOCK_CACHE_AWARE
ExAllocateCacheAwarePushLock (
     VOID
     )
/*++

Routine Description:

    Allocate a cache aware (cache friendly) push lock

Arguments:

    None

Return Value:

    None

--*/
{
    PEX_PUSH_LOCK_CACHE_AWARE PushLockCacheAware;
    PEX_PUSH_LOCK_CACHE_AWARE_PADDED PaddedPushLock;
    ULONG i, j, MaxLine;

    PushLockCacheAware = ExAllocatePoolWithTag (PagedPool,
                                                sizeof (EX_PUSH_LOCK_CACHE_AWARE),
                                                'pclP');
    if (PushLockCacheAware != NULL) {
        //
        // If we are a non-numa machine then allocate the padded push locks as a single block
        //
        if (KeNumberNodes == 1) {
            PaddedPushLock = ExAllocatePoolWithTag (PagedPool,
                                                    sizeof (EX_PUSH_LOCK_CACHE_AWARE_PADDED)*
                                                       EX_PUSH_LOCK_FANNED_COUNT,
                                                    'lclP');
            if (PaddedPushLock == NULL) {
                ExFreePool (PushLockCacheAware);
                return NULL;
            }
            for (i = 0; i < EX_PUSH_LOCK_FANNED_COUNT; i++) {
                PaddedPushLock->Single = TRUE;
                ExInitializePushLock (&PaddedPushLock->Lock);
                PushLockCacheAware->Locks[i] = &PaddedPushLock->Lock;
                PaddedPushLock++;
            }
        } else {
            //
            // Allocate a different block for each lock and set affinity
            // so the allocation comes from that node's memory.
            //
            MaxLine = KeNumberProcessors;
            if (MaxLine > EX_PUSH_LOCK_FANNED_COUNT) {
                MaxLine = EX_PUSH_LOCK_FANNED_COUNT;
            }

            for (i = 0; i < MaxLine; i++) {
                KeSetSystemAffinityThread (AFFINITY_MASK (i));
                PaddedPushLock = ExAllocatePoolWithTag (PagedPool,
                                                        sizeof (EX_PUSH_LOCK_CACHE_AWARE_PADDED),
                                                        'lclP');
                if (PaddedPushLock == NULL) {
                    for (j = 0; j < i; j++) {
                        ExFreePool (PushLockCacheAware->Locks[j]);
                    }
                    KeRevertToUserAffinityThread ();

                    ExFreePool (PushLockCacheAware);
                    return NULL;
                }
                PaddedPushLock->Single = FALSE;
                ExInitializePushLock (&PaddedPushLock->Lock);
                PushLockCacheAware->Locks[i] = &PaddedPushLock->Lock;
            }
            KeRevertToUserAffinityThread ();
        }
        
    }
    return PushLockCacheAware;
}
Beispiel #10
0
BOOLEAN
ExpInitializeCallbacks (
    )

/*++

Routine Description:

    This function creates the callback object type descriptor at system
    initialization and stores the address of the object type descriptor
    in local static storage.

Arguments:

    None.

Return Value:

    A value of TRUE is returned if the timer object type descriptor is
    successfully initialized. Otherwise a value of FALSE is returned.

--*/

{
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    UNICODE_STRING unicodeString;
    ULONG           i;
    HANDLE          handle;

    //
    // Initialize the slow referencing lock
    //
    ExInitializePushLock (&ExpCallBackFlush);

    //
    // Initialize string descriptor.
    //

    RtlInitUnicodeString(&unicodeString, L"Callback");

    //
    // Create timer object type descriptor.
    //

    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObjectTypeInitializer.GenericMapping = ExpCallbackMapping;
    ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback;
    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS;
    Status = ObCreateObjectType(&unicodeString,
                                &ObjectTypeInitializer,
                                (PSECURITY_DESCRIPTOR)NULL,
                                &ExCallbackObjectType);

    if (!NT_SUCCESS(Status)) {
        return FALSE;
    }

    RtlInitUnicodeString( &unicodeString, ExpWstrCallback );
    InitializeObjectAttributes(
        &ObjectAttributes,
        &unicodeString,
        OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
        NULL,
        SePublicDefaultSd
        );

    Status = NtCreateDirectoryObject(
                &handle,
                DIRECTORY_ALL_ACCESS,
                &ObjectAttributes
            );

    if (!NT_SUCCESS(Status)) {
        return FALSE;
    }

    NtClose (handle);

    //
    // Initialize event to wait on for Unregisters which occur while
    // notifications are in progress
    //

    KeInitializeEvent (&ExpCallbackEvent, NotificationEvent, 0);

    //
    // Initialize NT global callbacks
    //

    for (i=0; ExpInitializeCallback[i].CallBackObject; i++) {

        //
        // Create named calledback
        //

        RtlInitUnicodeString(&unicodeString, ExpInitializeCallback[i].CallbackName);


        InitializeObjectAttributes(
            &ObjectAttributes,
            &unicodeString,
            OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
            NULL,
            NULL
        );

        Status = ExCreateCallback (
                        ExpInitializeCallback[i].CallBackObject,
                        &ObjectAttributes,
                        TRUE,
                        TRUE
                        );

        if (!NT_SUCCESS(Status)) {
            return FALSE;
        }
    }

    return TRUE;
}