Example #1
0
/*
 * @implemented
 */
VOID
NTAPI
FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb,
                       IN POOL_TYPE PoolType)
{
    PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb;

    if (PoolType == PagedPool)
    {
        Mcb->Mapping = ExAllocateFromPagedLookasideList(&FsRtlFirstMappingLookasideList);
    }
    else
    {
        Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE,
                                             sizeof(LARGE_MCB_MAPPING),
                                             'FSBC');
    }

    Mcb->PoolType = PoolType;
    Mcb->PairCount = 0;
    Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT;
    RtlInitializeGenericTable(&Mcb->Mapping->Table,
                              McbMappingCompare,
                              McbMappingAllocate,
                              McbMappingFree,
                              Mcb);
}
Example #2
0
VOID
ClasspInitializeRemoveTracking(
    _In_ PDEVICE_OBJECT DeviceObject
    )
{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;

    #if DBG
        KeInitializeSpinLock(&commonExtension->RemoveTrackingSpinlock);

        commonExtension->RemoveTrackingList = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RTL_GENERIC_TABLE), CLASS_TAG_LOCK_TRACKING);

        if (commonExtension->RemoveTrackingList != NULL)
        {
            RtlInitializeGenericTable(commonExtension->RemoveTrackingList,
                                      RemoveTrackingCompareRoutine,
                                      RemoveTrackingAllocateRoutine,
                                      RemoveTrackingFreeRoutine,
                                      NULL);
        }
    #else

        UNREFERENCED_PARAMETER(DeviceObject);

        commonExtension->RemoveTrackingSpinlock = (ULONG_PTR) -1;
        commonExtension->RemoveTrackingList = NULL;
    #endif
}
Example #3
0
VOID
NTAPI
MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment)
{
    RtlInitializeGenericTable(&Segment->PageTable,
                              MiSectionPageTableCompare,
                              MiSectionPageTableAllocate,
                              MiSectionPageTableFree,
                              NULL);

    DPRINT("MiInitializeSectionPageTable(%p)\n", &Segment->PageTable);
}
Example #4
0
VOID
RadixInitTable(
    IN PRTL_GENERIC_TABLE   Table
    )
{
    
    /*  initialize rafix generic table. */

    RtlInitializeGenericTable(
        Table,
        RadixCompareElement,
        RadixAllocateElement,
        RadixDestroyElement,
        NULL
        );
}
Example #5
0
static void RtlSplayTreeTest()
{
    ULONG i, del;
    PCHAR Ch;
    CHAR Text[] = "the quick_brown!fOx-jUmp3d/0vER+THe^lazy.D@g";
    CHAR NewE[] = "11111111111111111111111111111111110111111111";
    RTL_GENERIC_TABLE Table;
    RtlInitializeGenericTable
        (&Table,
         CompareCharTable,
         AllocRoutine,
         FreeRoutine,
         NULL);
    for (i = 0; Text[i]; i++) {
        BOOLEAN WasNew;
        Ch = (PCHAR)RtlInsertElementGenericTable
            (&Table,
             &Text[i],
             sizeof(Text[i]),
             &WasNew);
        ok(Ch && *Ch == Text[i], "Copy character into node\n");
        ok(WasNew == (NewE[i] == '1'),
           "Character newness didn't match for char %u: '%c'\n",
           i, Text[i]);
    }
    for (Ch = (PCHAR)RtlEnumerateGenericTable(&Table, TRUE), i = 0;
         Ch;
         Ch = (PCHAR)RtlEnumerateGenericTable(&Table, FALSE), i++) {
        ok(strchr(Text, *Ch) != NULL, "Nonexistent character\n");
    }
    ok(RtlNumberGenericTableElements(&Table) == strlen(Text) - 1, "Not the right number of elements\n");
    ok(RtlLookupElementGenericTable(&Table, "q") != NULL, "Could not lookup q\n");
    ok(!RtlLookupElementGenericTable(&Table, "#"), "Found a character that shouldn't appear\n");
    ok(strlen(Text) == i + 1, "Didn't enumerate enough characters\n");
    del = 0;
    for (i = 0; Text[i]; i++) {
        if (NewE[i] == '1') {
            BOOLEAN WasDeleted;
            WasDeleted = RtlDeleteElementGenericTable(&Table, &Text[i]);
            del += WasDeleted;
        }
    }
    ok(!RtlNumberGenericTableElements(&Table), "Not zero elements\n");
    ok(!RtlGetElementGenericTable(&Table, 0), "Elements left when we removed them all\n");
    ok(strlen(Text) == del + 1, "Deleted too many times\n");
    ok(IsListEmpty(&Allocations), "Didn't free all memory\n");
}
Example #6
0
VOID
NTAPI
NpInitializeVcb(VOID)
{
    PAGED_CODE();

    RtlZeroMemory(NpVcb, sizeof(*NpVcb));

    NpVcb->NodeType = NPFS_NTC_VCB;
    RtlInitializeUnicodePrefix(&NpVcb->PrefixTable);
    ExInitializeResourceLite(&NpVcb->Lock);
    RtlInitializeGenericTable(&NpVcb->EventTable,
                              NpEventTableCompareRoutine,
                              NpEventTableAllocate,
                              NpEventTableDeallocate,
                              0);
    NpInitializeWaitQueue(&NpVcb->WaitQueue);
}
Example #7
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
FsRtlPrivateLock(IN PFILE_LOCK FileLock,
                 IN PFILE_OBJECT FileObject,
                 IN PLARGE_INTEGER FileOffset,
                 IN PLARGE_INTEGER Length,
                 IN PEPROCESS Process,
                 IN ULONG Key,
                 IN BOOLEAN FailImmediately,
                 IN BOOLEAN ExclusiveLock,
                 OUT PIO_STATUS_BLOCK IoStatus,
                 IN PIRP Irp OPTIONAL,
                 IN PVOID Context OPTIONAL,
                 IN BOOLEAN AlreadySynchronized)
{
    NTSTATUS Status;
    COMBINED_LOCK_ELEMENT ToInsert;
    PCOMBINED_LOCK_ELEMENT Conflict;
    PLOCK_INFORMATION LockInfo;
    PLOCK_SHARED_RANGE NewSharedRange;
    BOOLEAN InsertedNew;
    ULARGE_INTEGER UnsignedStart;
    ULARGE_INTEGER UnsignedEnd;
    
    DPRINT("FsRtlPrivateLock(%wZ, Offset %08x%08x (%d), Length %08x%08x (%d), Key %x, FailImmediately %u, Exclusive %u)\n", 
           &FileObject->FileName, 
           FileOffset->HighPart,
           FileOffset->LowPart, 
           (int)FileOffset->QuadPart,
           Length->HighPart,
           Length->LowPart, 
           (int)Length->QuadPart,
           Key,
           FailImmediately, 
           ExclusiveLock);
    
    UnsignedStart.QuadPart = FileOffset->QuadPart;
    UnsignedEnd.QuadPart = FileOffset->QuadPart + Length->QuadPart;

    if (UnsignedEnd.QuadPart < UnsignedStart.QuadPart)
    {
        DPRINT("File offset out of range\n");
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        if (Irp)
        {
            DPRINT("Complete lock %p Status %x\n", Irp, IoStatus->Status);
            FsRtlCompleteLockIrpReal
                (FileLock->CompleteLockIrpRoutine,
                 Context,
                 Irp,
                 IoStatus->Status,
                 &Status,
                 FileObject);
        }
        return FALSE;
    }
    
    /* Initialize the lock, if necessary */
    if (!FileLock->LockInformation)
    {
        LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), TAG_FLOCK);
        if (!LockInfo)
        {
            IoStatus->Status = STATUS_NO_MEMORY;
            return FALSE;
        }
        FileLock->LockInformation = LockInfo;

        LockInfo->BelongsTo = FileLock;
        InitializeListHead(&LockInfo->SharedLocks);
        
        RtlInitializeGenericTable
            (&LockInfo->RangeTable,
             LockCompare,
             LockAllocate,
             LockFree,
             NULL);
        
        KeInitializeSpinLock(&LockInfo->CsqLock);
        InitializeListHead(&LockInfo->CsqList);
        
        IoCsqInitializeEx
            (&LockInfo->Csq, 
             LockInsertIrpEx,
             LockRemoveIrp,
             LockPeekNextIrp,
             LockAcquireQueueLock,
             LockReleaseQueueLock,
             LockCompleteCanceledIrp);
    }
    
    LockInfo = FileLock->LockInformation;
    ToInsert.Exclusive.FileLock.FileObject = FileObject;
    ToInsert.Exclusive.FileLock.StartingByte = *FileOffset;
    ToInsert.Exclusive.FileLock.EndingByte.QuadPart = FileOffset->QuadPart + Length->QuadPart;
    ToInsert.Exclusive.FileLock.ProcessId = Process->UniqueProcessId;
    ToInsert.Exclusive.FileLock.Key = Key;
    ToInsert.Exclusive.FileLock.ExclusiveLock = ExclusiveLock;

    Conflict = RtlInsertElementGenericTable
        (FileLock->LockInformation,
         &ToInsert,
         sizeof(ToInsert),
         &InsertedNew);

    if (Conflict && !InsertedNew)
    {
        if (Conflict->Exclusive.FileLock.ExclusiveLock || ExclusiveLock)
        {
            DPRINT("Conflict %08x%08x:%08x%08x Exc %u (Want Exc %u)\n",
                   Conflict->Exclusive.FileLock.StartingByte.HighPart,
                   Conflict->Exclusive.FileLock.StartingByte.LowPart,
                   Conflict->Exclusive.FileLock.EndingByte.HighPart,
                   Conflict->Exclusive.FileLock.EndingByte.LowPart,
                   Conflict->Exclusive.FileLock.ExclusiveLock,
                   ExclusiveLock);
            if (FailImmediately)
            {
                DPRINT("STATUS_FILE_LOCK_CONFLICT\n");
                IoStatus->Status = STATUS_FILE_LOCK_CONFLICT;
                if (Irp)
                {
                    DPRINT("STATUS_FILE_LOCK_CONFLICT: Complete\n");
                    FsRtlCompleteLockIrpReal
                        (FileLock->CompleteLockIrpRoutine,
                         Context,
                         Irp,
                         IoStatus->Status,
                         &Status,
                         FileObject);
                }
                return FALSE;
            }
            else
            {
                IoStatus->Status = STATUS_PENDING;
                if (Irp)
                {
                    Irp->IoStatus.Information = LockInfo->Generation;
                    IoMarkIrpPending(Irp);
                    IoCsqInsertIrpEx
                        (&LockInfo->Csq,
                         Irp,
                         NULL,
                         NULL);
                }
            }
            return FALSE;
        }
        else
        {
            ULONG i;
            /* We know of at least one lock in range that's shared.  We need to
             * find out if any more exist and any are exclusive. */
            for (i = 0; i < RtlNumberGenericTableElements(&LockInfo->RangeTable); i++)
            {
                Conflict = RtlGetElementGenericTable(&LockInfo->RangeTable, i);

                /* The first argument will be inserted as a shared range */
                if (Conflict && (LockCompare(&LockInfo->RangeTable, Conflict, &ToInsert) == GenericEqual))
                {
                    if (Conflict->Exclusive.FileLock.ExclusiveLock)
                    {
                        /* Found an exclusive match */
                        if (FailImmediately)
                        {
                            IoStatus->Status = STATUS_FILE_LOCK_CONFLICT;
                            DPRINT("STATUS_FILE_LOCK_CONFLICT\n");
                            if (Irp)
                            {
                                DPRINT("STATUS_FILE_LOCK_CONFLICT: Complete\n");
                                FsRtlCompleteLockIrpReal
                                    (FileLock->CompleteLockIrpRoutine,
                                     Context,
                                     Irp,
                                     IoStatus->Status,
                                     &Status,
                                     FileObject);
                            }
                        }
                        else
                        {
                            IoStatus->Status = STATUS_PENDING;
                            if (Irp)
                            {
                                IoMarkIrpPending(Irp);
                                IoCsqInsertIrpEx
                                    (&LockInfo->Csq,
                                     Irp,
                                     NULL,
                                     NULL);
                            }
                        }
                        return FALSE;
                    }
                }
            }
            
            DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n",
                   &FileObject->FileName,
                   Conflict->Exclusive.FileLock.StartingByte.HighPart,
                   Conflict->Exclusive.FileLock.StartingByte.LowPart,
                   Conflict->Exclusive.FileLock.EndingByte.HighPart,
                   Conflict->Exclusive.FileLock.EndingByte.LowPart);
            Conflict = FsRtlpRebuildSharedLockRange(FileLock,
                                                    LockInfo,
                                                    &ToInsert);
            if (!Conflict)
            {
                IoStatus->Status = STATUS_NO_MEMORY;
                if (Irp)
                {
                    FsRtlCompleteLockIrpReal
                        (FileLock->CompleteLockIrpRoutine,
                         Context,
                         Irp,
                         IoStatus->Status,
                         &Status,
                         FileObject);
                }
            }

            /* We got here because there were only overlapping shared locks */
            /* A shared lock is both a range *and* a list entry.  Insert the
               entry here. */
            
            DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
            NewSharedRange = 
                ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE);
            if (!NewSharedRange)
            {
                IoStatus->Status = STATUS_NO_MEMORY;
                if (Irp)
                {
                    FsRtlCompleteLockIrpReal
                        (FileLock->CompleteLockIrpRoutine,
                         Context,
                         Irp,
                         IoStatus->Status,
                         &Status,
                         FileObject);
                }
                return FALSE;
            }
            DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
            NewSharedRange->Start = *FileOffset;
            NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
            NewSharedRange->Key = Key;
            NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId;
            InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);

            DPRINT("Acquired shared lock %wZ %08x%08x %08x%08x\n",
                   &FileObject->FileName,
                   Conflict->Exclusive.FileLock.StartingByte.HighPart,
                   Conflict->Exclusive.FileLock.StartingByte.LowPart,
                   Conflict->Exclusive.FileLock.EndingByte.HighPart,
                   Conflict->Exclusive.FileLock.EndingByte.LowPart);
            IoStatus->Status = STATUS_SUCCESS;
            if (Irp)
            {
                FsRtlCompleteLockIrpReal
                    (FileLock->CompleteLockIrpRoutine,
                     Context,
                     Irp,
                     IoStatus->Status,
                     &Status,
                     FileObject);
            }
            return TRUE;
        }
    }
    else if (!Conflict)
    {
        /* Conflict here is (or would be) the newly inserted element, but we ran
         * out of space probably. */
        IoStatus->Status = STATUS_NO_MEMORY;
        if (Irp)
        {
            FsRtlCompleteLockIrpReal
                (FileLock->CompleteLockIrpRoutine,
                 Context,
                 Irp,
                 IoStatus->Status,
                 &Status,
                 FileObject);
        }
        return FALSE;
    }
    else
    {
        DPRINT("Inserted new lock %wZ %08x%08x %08x%08x exclusive %u\n",
               &FileObject->FileName,
               Conflict->Exclusive.FileLock.StartingByte.HighPart,
               Conflict->Exclusive.FileLock.StartingByte.LowPart,
               Conflict->Exclusive.FileLock.EndingByte.HighPart,
               Conflict->Exclusive.FileLock.EndingByte.LowPart,
               Conflict->Exclusive.FileLock.ExclusiveLock);
        if (!ExclusiveLock)
        {
            NewSharedRange = 
                ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE);
            if (!NewSharedRange)
            {
                IoStatus->Status = STATUS_NO_MEMORY;
                if (Irp)
                {
                    FsRtlCompleteLockIrpReal
                        (FileLock->CompleteLockIrpRoutine,
                         Context,
                         Irp,
                         IoStatus->Status,
                         &Status,
                         FileObject);
                }
                return FALSE;
            }
            DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
            NewSharedRange->Start = *FileOffset;
            NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
            NewSharedRange->Key = Key;
            NewSharedRange->ProcessId = Process->UniqueProcessId;
            InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);
        }
        
        /* Assume all is cool, and lock is set */
        IoStatus->Status = STATUS_SUCCESS;
        
        if (Irp)
        {
            /* Complete the request */
            FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine,
                                     Context,
                                     Irp,
                                     IoStatus->Status,
                                     &Status,
                                     FileObject);
            
            /* Update the status */
            IoStatus->Status = Status;
        }
    }
    
    return TRUE;
}