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