Example #1
0
VOID
ClasspUninitializeRemoveTracking(
    _In_ PDEVICE_OBJECT DeviceObject
    )
{
    #if DBG
        PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
        PRTL_GENERIC_TABLE removeTrackingList = commonExtension->RemoveTrackingList;

        ASSERTMSG("Removing the device while still holding remove locks",
                   commonExtension->RemoveTrackingUntrackedCount == 0 &&
                   removeTrackingList != NULL ? RtlNumberGenericTableElements(removeTrackingList) == 0 : TRUE);

        if (removeTrackingList != NULL)
        {
            KIRQL oldIrql;
            KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock, &oldIrql);

            FREE_POOL(removeTrackingList);
            commonExtension->RemoveTrackingList = NULL;

            KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
        }

    #else

        UNREFERENCED_PARAMETER(DeviceObject);
    #endif
}
Example #2
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 #3
0
/*
 * @implemented
 */
VOID
NTAPI
FsRtlResetBaseMcb(IN PBASE_MCB OpaqueMcb)
{
    PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb;
    PLARGE_MCB_MAPPING_ENTRY Element;

    while (RtlNumberGenericTableElements(&Mcb->Mapping->Table) &&
           (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(&Mcb->Mapping->Table, 0)))
    {
        RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element);
    }

    Mcb->PairCount = 0;
    Mcb->MaximumPairCount = 0;
}
Example #4
0
ULONG
NTAPI
MiCacheEvictPages(PMM_SECTION_SEGMENT Segment,
                  ULONG Target)
{
    ULONG_PTR Entry;
    ULONG Result = 0, i, j;
    NTSTATUS Status;
    PFN_NUMBER Page;
    LARGE_INTEGER Offset;

    MmLockSectionSegment(Segment);

    for (i = 0; i < RtlNumberGenericTableElements(&Segment->PageTable); i++) {

        PCACHE_SECTION_PAGE_TABLE Element = RtlGetElementGenericTable(&Segment->PageTable,
                                                                      i);

        ASSERT(Element);

        Offset = Element->FileOffset;
        for (j = 0; j < ENTRIES_PER_ELEMENT; j++, Offset.QuadPart += PAGE_SIZE) {
            Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
            if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
                Page = PFN_FROM_SSE(Entry);
                MmUnlockSectionSegment(Segment);
                Status = MmpPageOutPhysicalAddress(Page);
                if (NT_SUCCESS(Status))
                    Result++;
                MmLockSectionSegment(Segment);
            }
        }
    }

    MmUnlockSectionSegment(Segment);

    return Result;
}
Example #5
0
/*
 * @implemented
 */
ULONG
NTAPI
FsRtlNumberOfRunsInBaseMcb(IN PBASE_MCB OpaqueMcb)
{
    PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb;
    LONGLONG LbnAtVbn0 = -1;
    ULONG Nodes = RtlNumberGenericTableElements(&Mcb->Mapping->Table);

    if (Nodes == 0) return 0;

    FsRtlLookupBaseMcbEntry(OpaqueMcb,
        0,                           /* Vbn */
        &LbnAtVbn0,                  /* Lbn */
        NULL, NULL, NULL, NULL);     /* 4 output arguments - not interested in them */


    /* Return the count */
    //return Mcb->PairCount;
	/* Return the number of 'real' and 'hole' runs.
	 * If we do not have sector 0 as 'real' emulate a 'hole' there.
	 */
	return Nodes * 2 - (LbnAtVbn0 != -1 ? 1 : 0);	/* include holes as runs */
}
Example #6
0
VOID
DumpVcb (
    IN ULONG Address,
    IN ULONG Options
    )

/*++

Routine Description:

    Dump a Vcb.

Arguments:

    Address - Gives the address of the Vcb to dump

    Options - If 1, we also dump the root Lcb and the Fcb table
              If 2, we dump everything for option 1, and also dump the Fcbs in the Fcb table

Return Value:

    None

--*/

{
    ULONG Result;
    PVCB pVcb;
    VCB Vcb;
    PFCB pFcb;
    FCB_TABLE_ELEMENT FcbTableElement;
    PFCB_TABLE_ELEMENT pFcbTableElement;
    RTL_GENERIC_TABLE FcbTable;
    PRTL_GENERIC_TABLE pFcbTable;
    PVOID RestartKey;

    dprintf( "\n    Vcb @ %08lx", Address );

    pVcb = (PVCB) Address;

    if ( !ReadMemory( (DWORD) pVcb,
                      &Vcb,
                      sizeof( Vcb ),
                      &Result) ) {
                      
        dprintf( "%08lx: Unable to read pVcb\n", pVcb );
        return;
    }

    if (Vcb.NodeTypeCode != NTFS_NTC_VCB) {
    
        dprintf( "\nVCB signature does not match, probably not a VCB" );
        return;
    }

    PrintState( VcbState, Vcb.VcbState );

    DUMP_WITH_OFFSET( VCB, Vcb, CleanupCount,         "CleanupCount:        " );
    DUMP_WITH_OFFSET( VCB, Vcb, CloseCount,           "CloseCount:          " );
    DUMP_WITH_OFFSET( VCB, Vcb, ReadOnlyCloseCount,   "ReadOnlyCloseCount:  " );
    DUMP_WITH_OFFSET( VCB, Vcb, SystemFileCloseCount, "SystemFileCloseCount:" );
    DUMP_WITH_OFFSET( VCB, Vcb, MftScb,               "MftScb:              " );
    DUMP_WITH_OFFSET( VCB, Vcb, Mft2Scb,              "Mft2Scb:             " );
    DUMP_WITH_OFFSET( VCB, Vcb, LogFileScb,           "LogFileScb:          " );
    DUMP_WITH_OFFSET( VCB, Vcb, VolumeDasdScb,        "VolumeDasdScb:       " );
    DUMP_WITH_OFFSET( VCB, Vcb, RootIndexScb,         "RootIndexScb:        " );
    DUMP_WITH_OFFSET( VCB, Vcb, BitmapScb,            "BitmapScb:           " );
    DUMP_WITH_OFFSET( VCB, Vcb, AttributeDefTableScb, "AttributeDefTableScb:" );
    DUMP_WITH_OFFSET( VCB, Vcb, UpcaseTableScb,       "UpcaseTableScb:      " );
    DUMP_WITH_OFFSET( VCB, Vcb, BadClusterFileScb,    "BadClusterFileScb:   " );
    DUMP_WITH_OFFSET( VCB, Vcb, QuotaTableScb,        "QuotaTableScb:       " );
    DUMP_WITH_OFFSET( VCB, Vcb, OwnerIdTableScb,      "OwnerIdTableScb:     " );
    DUMP_WITH_OFFSET( VCB, Vcb, MftBitmapScb,         "MftBitmapScb:        " );

    if (Options >= 1) {
    
        DumpLcb( (ULONG) Vcb.RootLcb, 0 );
    } else {
    
        DUMP_WITH_OFFSET( VCB, Vcb, RootLcb,         "RootLcb:             " );
    }

    //
    //  Dump the FcbTable
    //

    if (Options >= 1) {

        pFcbTable = &(pVcb->FcbTable);

        if ( !ReadMemory( (DWORD) pFcbTable,
                          &FcbTable,
                          sizeof( FcbTable ),
                          &Result) ) {
            dprintf( "%08lx: Unable to read pFcbTable\n", pFcbTable );
            return;
        }

        dprintf( "\n FcbTable @ %08lx", (DWORD) pFcbTable );
        dprintf( "\n FcbTable has %x elements", RtlNumberGenericTableElements( (PRTL_GENERIC_TABLE) &FcbTable ) );

        RestartKey = NULL;
        for (pFcbTableElement = (PFCB_TABLE_ELEMENT) KdEnumerateGenericTableWithoutSplaying(pFcbTable, &RestartKey);
             pFcbTableElement != NULL;
             pFcbTableElement = (PFCB_TABLE_ELEMENT) KdEnumerateGenericTableWithoutSplaying(pFcbTable, &RestartKey)) {

             if ( !ReadMemory( (DWORD) pFcbTableElement,
                               &FcbTableElement,
                               sizeof( FcbTableElement ),
                               &Result) ) {
                               
                dprintf( "%08lx: Unable to read pFcbTableElement\n", pFcbTableElement );
                return;
             }

             if (Options >= 2) {

                DumpFcb( (ULONG) FcbTableElement.Fcb, Options - 2 );
             } else {

                 dprintf( "\n      Fcb @ %08lx  for  FileReference(%x,%x) ", 
                          (DWORD) FcbTableElement.Fcb, 
                          FcbTableElement.FileReference.SegmentNumberHighPart,
                          FcbTableElement.FileReference.SegmentNumberLowPart );
             }
        }

    }

    dprintf( "\n" );

    return;
}
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;
}