Beispiel #1
0
NTSTATUS
BlpGetBootOptionIntegerList (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PULONGLONG* Value,
    _Out_ PULONGLONG Count,
    _In_ BOOLEAN NoCopy
    )
{
    PBL_BCD_OPTION Option;
    BcdElementType ElementType;
    PULONGLONG ValueCopy;

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

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (!Option)
    {
        return STATUS_NOT_FOUND;
    }

    /* Check if a copy should be made of it */
    if (NoCopy)
    {
        /* Nope, return the raw value */
        *Value = (PULONGLONG)((ULONG_PTR)Option + Option->DataOffset);
    }
    else
    {
        /* Allocate a buffer for the copy */
        ValueCopy = BlMmAllocateHeap(Option->DataSize);
        if (!ValueCopy)
        {
            return STATUS_NO_MEMORY;
        }

        /* Copy the data in */
        RtlCopyMemory(ValueCopy,
                      (PVOID)((ULONG_PTR)Option + Option->DataOffset),
                      Option->DataSize);

        /* Return our copy */
        *Value = ValueCopy;
    }

    /* Return count and success */
    *Count = Option->DataSize / sizeof(ULONGLONG);
    return STATUS_SUCCESS;
}
Beispiel #2
0
NTSTATUS
BlGetBootOptionGuidList (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PGUID *Value,
    _In_ PULONG Count
    )
{
    NTSTATUS Status;
    PBL_BCD_OPTION Option;
    PGUID GuidCopy, Guid;
    ULONG GuidCount;
    BcdElementType ElementType;

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

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (!Option)
    {
        /* Set failure if no data exists */
        Status = STATUS_NOT_FOUND;
    }
    else
    {
        /* Get the GUIDs and allocate a copy for them */
        Guid = (PGUID)((ULONG_PTR)Option + Option->DataOffset);
        GuidCopy = BlMmAllocateHeap(Option->DataSize);
        if (GuidCopy)
        {
            /* Copy the GUIDs */
            RtlCopyMemory(GuidCopy, Guid, Option->DataSize);

            /* Return the number of GUIDs and the start of the array */
            GuidCount = Option->DataSize / sizeof(GUID);
            *Value = GuidCopy;
            *Count = GuidCount;
            Status = STATUS_SUCCESS;
        }
        else
        {
            /* No memory for the copy */
            Status = STATUS_NO_MEMORY;
        }
    }

    /* All good */
    return Status;
}
Beispiel #3
0
PBL_BCD_OPTION
MiscGetBootOption (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type
    )
{
    ULONG_PTR NextOption = 0, ListOption;
    PBL_BCD_OPTION Option, FoundOption;

    /* No options, bail out */
    if (!List)
    {
        return NULL;
    }

    /* Loop while we find an option */
    FoundOption = NULL;
    do
    {
        /* Get the next option and see if it matches the type */
        Option = (PBL_BCD_OPTION)((ULONG_PTR)List + NextOption);
        if ((Option->Type == Type) && !(Option->Empty))
        {
            FoundOption = Option;
            break;
        }

        /* Store the offset of the next option */
        NextOption = Option->NextEntryOffset;

        /* Failed to match. Check for list options */
        ListOption = Option->ListOffset;
        if (ListOption)
        {
            /* Try to get a match in the associated option */
            Option = MiscGetBootOption((PBL_BCD_OPTION)((ULONG_PTR)Option +
                                       ListOption),
                                       Type);
            if (Option)
            {
                /* Return it */
                FoundOption = Option;
                break;
            }
        }
    } while (NextOption);

    /* Return the option that was found, if any */
    return FoundOption;
}
Beispiel #4
0
NTSTATUS
BlGetBootOptionBoolean (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PBOOLEAN Value
    )
{
    NTSTATUS Status;
    PBL_BCD_OPTION Option;
    //PGUID AppIdentifier;
    BcdElementType ElementType;

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

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (Option)
    {
        *Value = *(PBOOLEAN)((ULONG_PTR)Option + Option->DataOffset);
    }

#ifdef _SECURE_BOOT_
    /* Filter out SecureBoot Options */
    AppIdentifier = BlGetApplicationIdentifier();
    Status = BlpBootOptionCallbackBoolean(AppIdentifier, Type, Value);
#else
    /* Option found */
    Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND;
#endif
    return Status;
}
Beispiel #5
0
NTSTATUS
BlGetBootOptionDevice (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PBL_DEVICE_DESCRIPTOR* Value,
    _In_opt_ PBL_BCD_OPTION* ExtraOptions
    )
{
    NTSTATUS Status;
    PBL_BCD_OPTION Option, ListData, ListCopy, SecureListData;
    PBCD_DEVICE_OPTION BcdDevice;
    ULONG DeviceSize, ListOffset, ListSize;
    PBL_DEVICE_DESCRIPTOR DeviceDescriptor, SecureDescriptor;
    //PGUID AppIdentifier;
    BcdElementType ElementType;

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

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (!Option)
    {
        /* Set failure if no data exists */
        Status = STATUS_NOT_FOUND;
    }
    else
    {
        /* Otherwise, read the size of the BCD device encoded */
        BcdDevice = (PBCD_DEVICE_OPTION)((ULONG_PTR)Option + Option->DataOffset);
        DeviceSize = BcdDevice->DeviceDescriptor.Size;

        /* Allocate a buffer to copy it into */
        DeviceDescriptor = BlMmAllocateHeap(DeviceSize);
        if (!DeviceDescriptor)
        {
            return STATUS_NO_MEMORY;
        }

        /* Copy it into that buffer */
        RtlCopyMemory(DeviceDescriptor, &BcdDevice->DeviceDescriptor, DeviceSize);
        Status = STATUS_SUCCESS;
    }

    /* Check if extra options were requested */
    if (ExtraOptions)
    {
        /* See where they are */
        ListOffset = Option->ListOffset;
        if (ListOffset)
        {
            /* See how big they are */
            ListData = (PBL_BCD_OPTION)((ULONG_PTR)Option + ListOffset);
            ListSize = BlGetBootOptionListSize(ListData);

            /* Allocate a buffer to hold them into */
            ListCopy = BlMmAllocateHeap(ListSize);
            if (!ListCopy)
            {
                Status = STATUS_NO_MEMORY;
                goto Quickie;
            }

            /* Copy them in there */
            RtlCopyMemory(ListCopy, ListData, ListSize);
        }
    }

#ifdef _SECURE_BOOT_
    /* Filter out SecureBoot Options */
    AppIdentifier = BlGetApplicationIdentifier();
    if (BlpBootOptionCallbacks)
    {
        DeviceCallback = BlpBootOptionCallbacks->Device;
        if (DeviceCallback)
        {
            Status = DeviceCallback(BlpBootOptionCallbackCookie,
                                    Status,
                                    0,
                                    AppIdentifier,
                                    Type,
                                    &SecureDescriptor,
                                    PtrOptionData);
        }
    }
#else
    /* No secure boot, so the secure descriptors are the standard ones */
    SecureDescriptor = DeviceDescriptor;
    SecureListData = ListCopy;
#endif

    /* Check if the data was read correctly */
    if (NT_SUCCESS(Status))
    {
        /* Check if we had a new descriptor after filtering */
        if (SecureDescriptor != DeviceDescriptor)
        {
            /* Yep -- if we had an old one, free it */
            if (DeviceDescriptor)
            {
                BlMmFreeHeap(DeviceDescriptor);
            }
        }

        /* Check if we had a new list after filtering */
        if (SecureListData != ListCopy)
        {
            /* Yep -- if we had an old list, free it */
            if (ListCopy)
            {
                BlMmFreeHeap(ListCopy);
            }
        }

        /* Finally, check if the caller wanted extra options */
        if (ExtraOptions)
        {
            /* Yep -- so pass the caller our copy */
            *ExtraOptions = ListCopy;
            ListCopy = NULL;
        }

        /* Caller always wants data back, so pass them our copy */
        *Value = DeviceDescriptor;
        DeviceDescriptor = NULL;
    }

Quickie:
    /* On the failure path, if these buffers are active, we should free them */
    if (ListCopy)
    {
        BlMmFreeHeap(ListCopy);
    }
    if (DeviceDescriptor)
    {
        BlMmFreeHeap(DeviceDescriptor);
    }

    /* All done */
    return Status;
}
Beispiel #6
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;
}
Beispiel #7
0
NTSTATUS
DsppReinitialize (
    _In_ ULONG Flags
    )
{
    PBL_TEXT_CONSOLE TextConsole;
    PBL_GRAPHICS_CONSOLE GraphicsConsole;
    NTSTATUS Status;
    ULONGLONG GraphicsResolution;
    BOOLEAN HighestMode;
    BL_DISPLAY_MODE CurrentResolution;

    /* Do we have local input yet? */
    if (!DspLocalInputConsole)
    {
        /* Create it now */
        ConsoleCreateLocalInputConsole();
    }

    /* If a graphics console is present without a remote console... */
    TextConsole = NULL;
    if (!(DspRemoteInputConsole) && (DspGraphicalConsole))
    {
        /* Try to create a remote console */
        ConsoleCreateRemoteConsole(&TextConsole);
    }

    /* All good for now */
    Status = STATUS_SUCCESS;

    /* Now check if we were able to create the remote console */
    if (TextConsole)
    {
        EfiPrintf(L"EMS not supported\r\n");
        return STATUS_NOT_IMPLEMENTED;
    }

    /* Set a local for the right cast */
    GraphicsConsole = DspGraphicalConsole;

    /* Nothing to do without a graphics console being reinitialized */
    if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) ||
        !(GraphicsConsole) ||
        !(((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->IsEnabled(GraphicsConsole)))
    {
        return Status;
    }

    /* Check if graphics are disabled in the BCD */
    if (DsppGraphicsDisabledByBcd())
    {
        /* Turn off the graphics console, switching back to text mode */
        Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->Enable(GraphicsConsole, FALSE);
    }

    /* Check if a custom graphics resolution is set */
    if (MiscGetBootOption(BlpApplicationEntry.BcdData,
                          BcdLibraryInteger_GraphicsResolution))
    {
        /* Check what it's set to */
        Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
                                        BcdLibraryInteger_GraphicsResolution,
                                        &GraphicsResolution);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }
        
        /* Now check our current graphical resolution */
        Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->GetGraphicalResolution(GraphicsConsole,
                                                                                                               &CurrentResolution);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }

        /* Remember that we're forcing a video mode */
        ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG;

        /* Check which resolution to set */
        if (!GraphicsResolution)
        {
            /* 1024x768 */
            EfiPrintf(L"Display selection not yet handled\r\n");
            return STATUS_NOT_IMPLEMENTED;
        }
        else if (GraphicsResolution == 1)
        {
            /* 800x600 */
            EfiPrintf(L"Display selection not yet handled\r\n");
            return STATUS_NOT_IMPLEMENTED;
        }
        else if (GraphicsResolution == 2)
        {
            /* 1024x600 */
            EfiPrintf(L"Display selection not yet handled\r\n");
            return STATUS_NOT_IMPLEMENTED;
        }
    }

    /* Check if the force highest mode setting is present */
    if (MiscGetBootOption(BlpApplicationEntry.BcdData,
                          BcdLibraryBoolean_GraphicsForceHighestMode))
    {
        /* Check what it's set to */
        Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
                                        BcdLibraryBoolean_GraphicsForceHighestMode,
                                        &HighestMode);
        if ((NT_SUCCESS(Status)) && (HighestMode))
        {
            /* Remember that high rest mode is being forced */
            ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG;

            /* Turn it on */
            //((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->SetGraphicalResolution(GraphicsConsole, 0, 0);

            /* All done now */
            ConsoleGraphicalResolutionListFlags |= ~BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG;
            EfiPrintf(L"High res mode not yet handled\r\n");
            Status = STATUS_NOT_IMPLEMENTED;
        }
    }

    /* Return back to the caller */
    return Status;
}