Пример #1
0
NTSTATUS
BlGetBootOptionString (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PWCHAR* Value
    )
{
    NTSTATUS Status;
    PBL_BCD_OPTION Option;
    PWCHAR String, StringCopy;
    ULONG StringLength;
    BcdElementType ElementType;
    //PGUID AppIdentifier;

    /* Make sure this is a BCD_STRING */
    ElementType.PackedValue = Type;
    if (ElementType.Format != BCD_TYPE_STRING)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (Option)
    {
        /* Extract the string */
        String = (PWCHAR)((ULONG_PTR)Option + Option->DataOffset);
        Status = STATUS_SUCCESS;
    }
    else
    {
        /* No string is present */
        String = NULL;
        Status = STATUS_NOT_FOUND;
    }

    /* Compute the data size */
    StringLength = Option->DataSize / sizeof(WCHAR);

#ifdef _SECURE_BOOT_
    /* Filter out SecureBoot Options */
    AppIdentifier = BlGetApplicationIdentifier();
    Status = BlpBootOptionCallbackString(AppIdentifier, Type, String, StringLength, &String, &StringLength);
#else
#endif

    /* Make sure we have a valid, non-filtered string */
    if (NT_SUCCESS(Status))
    {
        /* Check if we have space for one more character */
        Status = RtlULongAdd(StringLength, 1, &StringLength);
        if (NT_SUCCESS(Status))
        {
            /* Check if it's safe to multiply by two */
            Status = RtlULongMult(StringLength, sizeof(WCHAR), &StringLength);
            if (NT_SUCCESS(Status))
            {
                /* Allocate a copy for the string */
                StringCopy = BlMmAllocateHeap(StringLength);
                if (StringCopy)
                {
                    /* NULL-terminate it */
                    RtlCopyMemory(StringCopy,
                                  String,
                                  StringLength - sizeof(UNICODE_NULL));
                    StringCopy[StringLength] = UNICODE_NULL;
                    *Value = StringCopy;
                    Status = STATUS_SUCCESS;
                }
                else
                {
                    /* No memory, fail */
                    Status = STATUS_NO_MEMORY;
                }
            }
        }
    }

    /* All done */
    return Status;
}
Пример #2
0
PDRIVE_LAYOUT_INFORMATION
DiskConvertExtendedToLayout(
    IN CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx
    )
{
    ULONG i;
    ULONG LayoutSize;
    PDRIVE_LAYOUT_INFORMATION Layout;
    PPARTITION_INFORMATION Partition;
    PPARTITION_INFORMATION_EX PartitionEx;
    NTSTATUS status;

    PAGED_CODE ();

    ASSERT ( LayoutEx );


    //
    // The only valid conversion is from an MBR extended layout structure to
    // the old structure.
    //

    if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR) {
        ASSERT ( FALSE );
        return NULL;
    }

    //
    // Use safe interger function
    //

    status = RtlULongMult(LayoutEx->PartitionCount,  sizeof(PARTITION_INFORMATION), &LayoutSize);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }
    status = RtlULongAdd(LayoutSize, FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]),
                         &LayoutSize);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }

    Layout = ExAllocatePoolWithTag (
                    NonPagedPool,
                    LayoutSize,
                    DISK_TAG_PART_LIST
                    );

    if ( Layout == NULL ) {
        return NULL;
    }

    Layout->Signature = LayoutEx->Mbr.Signature;
    Layout->PartitionCount = LayoutEx->PartitionCount;

    for (i = 0; i < LayoutEx->PartitionCount; i++) {

        Partition = &Layout->PartitionEntry[i];
        PartitionEx = &LayoutEx->PartitionEntry[i];

        Partition->StartingOffset = PartitionEx->StartingOffset;
        Partition->PartitionLength = PartitionEx->PartitionLength;
        Partition->RewritePartition = PartitionEx->RewritePartition;
        Partition->PartitionNumber = PartitionEx->PartitionNumber;

        Partition->PartitionType = PartitionEx->Mbr.PartitionType;
        Partition->BootIndicator = PartitionEx->Mbr.BootIndicator;
        Partition->RecognizedPartition = PartitionEx->Mbr.RecognizedPartition;
        Partition->HiddenSectors = PartitionEx->Mbr.HiddenSectors;
    }

    return Layout;
}
Пример #3
0
NTSTATUS
BiConvertBcdElements (
    _In_ PBCD_PACKED_ELEMENT Elements,
    _Out_opt_ PBCD_ELEMENT Buffer,
    _Inout_ PULONG BufferSize, 
    _Inout_ PULONG ElementCount
    )
{
    NTSTATUS Status;
    ULONG ElementSize, AlignedElementSize, AlignedDataSize;
    PBCD_ELEMENT_HEADER Header;
    PVOID Data;
    BOOLEAN Exists;
    ULONG i, j, Count;

    /* Local variable to keep track of objects */
    Count = 0;

    /* Safely compute the element bytes needed */
    Status = RtlULongMult(*ElementCount, sizeof(BCD_ELEMENT), &ElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely align the element size */
    Status = RtlULongAdd(ElementSize,
                         sizeof(ULONG) - 1,
                         &AlignedElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }
    AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);

    /* Do a safe version of Add2Ptr to figure out where the headers will start */
    Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
                            AlignedElementSize,
                            (PULONG_PTR)&Header);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely compute the header bytes needed */
    Status = RtlULongMult(*ElementCount,
                          sizeof(BCD_ELEMENT_HEADER),
                          &ElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely align the header size */
    Status = RtlULongAdd(ElementSize,
                         AlignedElementSize + sizeof(ULONG) - 1,
                         &AlignedElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }
    AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);

    /* Do a safe version of Add2Ptr */
    Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
                            AlignedElementSize,
                            (PULONG_PTR)&Data);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Iterate over every element */
    for (i = 0; i < *ElementCount; i++)
    {
        /* Safely align the element size */
        Status = RtlULongAdd(Elements->Size,
                             sizeof(ULONG) - 1,
                             &AlignedDataSize);
        if (!NT_SUCCESS(Status))
        {
            break;
        }
        AlignedDataSize = ALIGN_DOWN(AlignedDataSize, ULONG);

        /* Safely add the size of this data element */
        Status = RtlULongAdd(AlignedElementSize,
                             AlignedDataSize,
                             &AlignedElementSize);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        /* Do we have enough space left? */
        if (*BufferSize >= AlignedElementSize)
        {
            /* Check if our root is an inherited object */
            Exists = FALSE;
            if (Elements->RootType.PackedValue == BcdLibraryObjectList_InheritedObjects)
            {
                /* Yes, scan for us in the current buffer */
                for (j = 0; j < Count; j++)
                {
                    /* Do we already exist? */
                    while (Buffer[j].Header->Type == Elements->RootType.PackedValue)
                    {
                        /* Yep */
                        Exists = TRUE;
                        break;
                    }
                }
            }

            /* Have we already found ourselves? */
            if (!Exists)
            {
                /* Nope, one more entry */
                ++Count;

                /* Write out the unpacked object */
                Buffer->Body = Data;
                Buffer->Header = Header;

                /* Fill out its header */
                Header->Size = Elements->Size;
                Header->Type = Elements->Type;
                Header->Version = Elements->Version;

                /* And copy the data */
                RtlCopyMemory(Data, Elements->Data, Header->Size);

                /* Move to the next unpacked object and header */
                ++Buffer;
                ++Header;

                /* Move to the next data entry */
                Data = (PVOID)((ULONG_PTR)Data + AlignedDataSize);
            }
        }
        else
        {
            /* Nope, set failure code, but keep going so we can return count */
            Status = STATUS_BUFFER_TOO_SMALL;
        }

        /* Move to the next element entry */
        Elements = Elements->NextEntry;
    }

    /* Return the new final buffer size and count */
    *BufferSize = AlignedElementSize;
    *ElementCount = Count;
    return Status;
}
Пример #4
0
PDRIVE_LAYOUT_INFORMATION_EX
DiskConvertLayoutToExtended(
    IN CONST PDRIVE_LAYOUT_INFORMATION Layout
    )

/*++

Routine Description:

    Convert a DRIVE_LAYOUT_INFORMATION structure into a
    DRIVE_LAYOUT_INFORMATION_EX structure.

Arguments:

    Layout - The source DRIVE_LAYOUT_INFORMATION structure.

Return Values:

    The resultant DRIVE_LAYOUT_INFORMATION_EX structure. This buffer must
    be freed by the callee using ExFreePool.

--*/

{
    ULONG i;
    ULONG size;
    PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
    NTSTATUS status;

    PAGED_CODE ();

    ASSERT ( Layout != NULL );


    //
    // Allocate enough space for a DRIVE_LAYOUT_INFORMATION_EX structure
    // plus as many PARTITION_INFORMATION_EX structures as are in the
    // source array.
    //

    //
    // Use safe interger function
    //

    status = RtlULongMult(Layout->PartitionCount, sizeof(PARTITION_INFORMATION_EX), &size);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }
    status = RtlULongAdd(size, FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]),
                         &size);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }

    layoutEx = ExAllocatePoolWithTag(
                            NonPagedPool,
                            size,
                            DISK_TAG_PART_LIST
                            );

    if ( layoutEx == NULL ) {
        return NULL;
    }

    //
    // Convert the disk information.
    //

    layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
    layoutEx->PartitionCount = Layout->PartitionCount;
    layoutEx->Mbr.Signature = Layout->Signature;

    for (i = 0; i < Layout->PartitionCount; i++) {

        //
        // Convert each entry.
        //

        DiskConvertPartitionToExtended (
                &Layout->PartitionEntry[i],
                &layoutEx->PartitionEntry[i]
                );
    }

    return layoutEx;
}
Пример #5
0
PSURFACE
NTAPI
SURFACE_AllocSurface(
    _In_ USHORT iType,
    _In_ ULONG cx,
    _In_ ULONG cy,
    _In_ ULONG iFormat,
    _In_ ULONG fjBitmap,
    _In_opt_ ULONG cjWidth,
    _In_opt_ ULONG cjBufSize,
    _In_opt_ PVOID pvBits)
{
    ULONG cBitsPixel, cjBits, cjObject;
    PSURFACE psurf;
    SURFOBJ *pso;
    PVOID pvSection;

    NT_ASSERT(!pvBits || (iType == STYPE_BITMAP));
    NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0));
    NT_ASSERT((LONG)cy > 0);

    /* Verify format */
    if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
    {
        DPRINT1("Invalid bitmap format: %lu\n", iFormat);
        return NULL;
    }

    /* Get bits per pixel from the format */
    cBitsPixel = gajBitsPerFormat[iFormat];

    /* Are bits and a width in bytes given? */
    if (pvBits && cjWidth)
    {
        /* Align the width (Windows compatibility, drivers expect that) */
        cjWidth = WIDTH_BYTES_ALIGN32((cjWidth << 3) / cBitsPixel, cBitsPixel);
    }
    else
    {
        /* Calculate width from the bitmap width in pixels */
        cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
    }

    /* Is this an uncompressed format? */
    if (iFormat <= BMF_32BPP)
    {
        /* Calculate the correct bitmap size in bytes */
        if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits)))
        {
            DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n",
                    cjWidth, cy);
            return NULL;
        }

        /* Did we get a buffer and size? */
        if ((pvBits != NULL) && (cjBufSize != 0))
        {
            /* Make sure the buffer is large enough */
            if (cjBufSize < cjBits)
            {
                DPRINT1("Buffer is too small, required: %lu, got %lu\n",
                        cjBits, cjBufSize);
                return NULL;
            }
        }
    }
    else
    {
        /* Compressed format, use the provided size */
        NT_ASSERT(cjBufSize != 0);
        cjBits = cjBufSize;
    }

    /* Check if we need an extra large object */
    if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
        !(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION))
    {
        /* Allocate an object large enough to hold the bits */
        cjObject = sizeof(SURFACE) + cjBits;
    }
    else
    {
        /* Otherwise just allocate the SURFACE structure */
        cjObject = sizeof(SURFACE);
    }

    /* Check for arithmetic overflow */
    if (cjObject < sizeof(SURFACE))
    {
        /* Fail! */
        DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits);
        return NULL;
    }

    /* Allocate a SURFACE object */
    psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, cjObject);
    if (!psurf)
    {
        return NULL;
    }

    /* Initialize the basic fields */
    pso = &psurf->SurfObj;
    pso->hsurf = psurf->BaseObject.hHmgr;
    pso->sizlBitmap.cx = cx;
    pso->sizlBitmap.cy = cy;
    pso->iBitmapFormat = iFormat;
    pso->iType = iType;
    pso->fjBitmap = (USHORT)fjBitmap;
    pso->iUniq = InterlockedIncrement(&giUniqueSurface);
    pso->cjBits = cjBits;

    /* Check if we need a bitmap buffer */
    if (iType == STYPE_BITMAP)
    {
        /* Check if we got one or if we need to allocate one */
        if (pvBits != NULL)
        {
            /* Use the caller provided buffer */
            pso->pvBits = pvBits;
        }
        else if (fjBitmap & BMF_USERMEM)
        {
            /* User mode memory was requested */
            pso->pvBits = EngAllocUserMem(cjBits, 0);

            /* Check for failure */
            if (!pso->pvBits)
            {
                GDIOBJ_vDeleteObject(&psurf->BaseObject);
                return NULL;
            }
        }
        else if (fjBitmap & BMF_KMSECTION)
        {
            /* Use a kernel mode section */
            pso->pvBits = EngAllocSectionMem(&pvSection,
                                             (fjBitmap & BMF_NOZEROINIT) ?
                                                 0 : FL_ZERO_MEMORY,
                                             cjBits, TAG_DIB);

            /* Check for failure */
            if (!pso->pvBits)
            {
                GDIOBJ_vDeleteObject(&psurf->BaseObject);
                return NULL;
            }

            /* Free the section already, but keep the mapping */
            EngFreeSectionMem(pvSection, NULL);
        }
        else
        {
            /* Buffer is after the object */
            pso->pvBits = psurf + 1;

            /* Zero the buffer, except requested otherwise */
            if (!(fjBitmap & BMF_NOZEROINIT))
            {
                RtlZeroMemory(pso->pvBits, cjBits);
            }
        }

        /* Set pvScan0 and lDelta */
        if (fjBitmap & BMF_TOPDOWN)
        {
            /* Topdown is the normal way */
            pso->pvScan0 = pso->pvBits;
            pso->lDelta = cjWidth;
        }
        else
        {
            /* Inversed bitmap (bottom up) */
            pso->pvScan0 = ((PCHAR)pso->pvBits + pso->cjBits - cjWidth);
            pso->lDelta = -(LONG)cjWidth;
        }
    }
    else
    {
        /* There are no bitmap bits */
        pso->pvScan0 = pso->pvBits = NULL;
        pso->lDelta = 0;
    }

    /* Assign a default palette and increment its reference count */
    SURFACE_vSetPalette(psurf, appalSurfaceDefault[iFormat]);

    return psurf;
}