VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/Library/CommonLib
diff options
context:
space:
mode:
authorAlex <kavsrf@gmail.com>2016-08-15 17:11:31 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2016-08-15 17:14:26 +0200
commitb87fc6b140772ba3017de311c7063c259424264c (patch)
tree41ad139e7469380704361ae757a155464e8b68e3 /Library/CommonLib
parent68ea2f72cfe6a9b34212ced97882e488c73c8f1d (diff)
downloadVeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.tar.gz
VeraCrypt-DCS-b87fc6b140772ba3017de311c7063c259424264c.zip
First public release. Used by VeraCrypt 1.18.VeraCrypt_1.18_PreRelease
Diffstat (limited to 'Library/CommonLib')
-rw-r--r--Library/CommonLib/CommonLib.inf65
-rw-r--r--Library/CommonLib/EfiAttrPrint.c477
-rw-r--r--Library/CommonLib/EfiBeep.c69
-rw-r--r--Library/CommonLib/EfiBio.c232
-rw-r--r--Library/CommonLib/EfiConsole.c347
-rw-r--r--Library/CommonLib/EfiExec.c88
-rw-r--r--Library/CommonLib/EfiFile.c350
-rw-r--r--Library/CommonLib/EfiMem.c74
-rw-r--r--Library/CommonLib/EfiTouch.c47
-rw-r--r--Library/CommonLib/EfiUsb.c88
-rw-r--r--Library/CommonLib/EfiVar.c228
-rw-r--r--Library/CommonLib/IA32/EfiCpuHalt.asm19
-rw-r--r--Library/CommonLib/X64/EfiCpuHalt.asm17
13 files changed, 2101 insertions, 0 deletions
diff --git a/Library/CommonLib/CommonLib.inf b/Library/CommonLib/CommonLib.inf
new file mode 100644
index 0000000..2c379b8
--- /dev/null
+++ b/Library/CommonLib/CommonLib.inf
@@ -0,0 +1,65 @@
+## @file
+# EFI common library (helpers)
+#
+# Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+# Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+#
+# The full text of the license may be found at
+# https://opensource.org/licenses/LGPL-3.0
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = CommonLib
+ MODULE_UNI_FILE = CommonLib.uni
+ FILE_GUID = F779769D-58F4-4A49-A7D7-59473BBD3CCE
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CommonLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ EfiMem.c
+ EfiBio.c
+ EfiVar.c
+ EfiFile.c
+ EfiConsole.c
+ EfiAttrPrint.c
+ EfiBeep.c
+ EfiExec.c
+ EfiUsb.c
+ EfiTouch.c
+
+[Sources.IA32]
+ IA32/EfiCpuHalt.asm
+
+[Sources.X64]
+ X64/EfiCpuHalt.asm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DcsPkg/DcsPkg.dec
+ ShellPkg/ShellPkg.dec
+
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ PrintLib
+ UefiUsbLib
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiUsbIoProtocolGuid
+ gEfiAbsolutePointerProtocolGuid
+ gEfiGraphicsOutputProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
diff --git a/Library/CommonLib/EfiAttrPrint.c b/Library/CommonLib/EfiAttrPrint.c
new file mode 100644
index 0000000..adcd606
--- /dev/null
+++ b/Library/CommonLib/EfiAttrPrint.c
@@ -0,0 +1,477 @@
+/** @file
+EFI console print with attribute (based on shell print)
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/EFiShell.h>
+#include <Protocol/EfiShellParameters.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Custom print based on shell print (copied here to avoid runtime limitation)
+//////////////////////////////////////////////////////////////////////////
+
+#define ATTRPRINT_BUFSIZE 4096
+
+BOOLEAN gShellReady = FALSE;
+EFI_SHELL_PARAMETERS_PROTOCOL* mEfiShellParametersProtocol = NULL;
+EFI_SHELL_PROTOCOL* mEfiShellProtocol = NULL;
+
+VOID
+SetShellAPI(
+ IN VOID* shellProtocol,
+ IN VOID* shellParametersProtocol) {
+ mEfiShellParametersProtocol = (EFI_SHELL_PARAMETERS_PROTOCOL*)shellParametersProtocol;
+ mEfiShellProtocol = (EFI_SHELL_PROTOCOL*)shellProtocol;
+}
+
+/**
+ Safely append with automatic string resizing given length of Destination and
+ desired length of copy from Source.
+
+ append the first D characters of Source to the end of Destination, where D is
+ the lesser of Count and the StrLen() of Source. If appending those D characters
+ will fit within Destination (whose Size is given as CurrentSize) and
+ still leave room for a NULL terminator, then those characters are appended,
+ starting at the original terminating NULL of Destination, and a new terminating
+ NULL is appended.
+
+ If appending D characters onto Destination will result in a overflow of the size
+ given in CurrentSize the string will be grown such that the copy can be performed
+ and CurrentSize will be updated to the new size.
+
+ If Source is NULL, there is nothing to append, just return the current buffer in
+ Destination.
+
+ if Destination is NULL, then ASSERT()
+ if Destination's current length (including NULL terminator) is already more then
+ CurrentSize, then ASSERT()
+
+ @param[in, out] Destination The String to append onto
+ @param[in, out] CurrentSize on call the number of bytes in Destination. On
+ return possibly the new size (still in bytes). if NULL
+ then allocate whatever is needed.
+ @param[in] Source The String to append from
+ @param[in] Count Maximum number of characters to append. if 0 then
+ all are appended.
+
+ @return Destination return the resultant string.
+**/
+CHAR16*
+EFIAPI
+StrnCatGrow2 (
+ IN OUT CHAR16 **Destination,
+ IN OUT UINTN *CurrentSize,
+ IN CONST CHAR16 *Source,
+ IN UINTN Count
+ )
+{
+ UINTN DestinationStartSize;
+ UINTN NewSize;
+
+ //
+ // ASSERTs
+ //
+ ASSERT(Destination != NULL);
+
+ //
+ // If there's nothing to do then just return Destination
+ //
+ if (Source == NULL) {
+ return (*Destination);
+ }
+
+ //
+ // allow for un-initialized pointers, based on size being 0
+ //
+ if (CurrentSize != NULL && *CurrentSize == 0) {
+ *Destination = NULL;
+ }
+
+ //
+ // allow for NULL pointers address as Destination
+ //
+ if (*Destination != NULL) {
+ ASSERT(CurrentSize != 0);
+ DestinationStartSize = StrSize(*Destination);
+ ASSERT(DestinationStartSize <= *CurrentSize);
+ } else {
+ DestinationStartSize = 0;
+// ASSERT(*CurrentSize == 0);
+ }
+
+ //
+ // Append all of Source?
+ //
+ if (Count == 0) {
+ Count = StrLen(Source);
+ }
+
+ //
+ // Test and grow if required
+ //
+ if (CurrentSize != NULL) {
+ NewSize = *CurrentSize;
+ if (NewSize < DestinationStartSize + (Count * sizeof(CHAR16))) {
+ while (NewSize < (DestinationStartSize + (Count*sizeof(CHAR16)))) {
+ NewSize += 2 * Count * sizeof(CHAR16);
+ }
+ *Destination = MEM_REALLOC(*CurrentSize, NewSize, *Destination);
+ *CurrentSize = NewSize;
+ }
+ } else {
+ NewSize = (Count+1)*sizeof(CHAR16);
+ *Destination = MEM_ALLOC(NewSize);
+ }
+
+ //
+ // Now use standard StrnCat on a big enough buffer
+ //
+ if (*Destination == NULL) {
+ return (NULL);
+ }
+
+ StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);
+ return *Destination;
+}
+
+
+/**
+ This is a find and replace function. Upon successful return the NewString is a copy of
+ SourceString with each instance of FindTarget replaced with ReplaceWith.
+
+ If SourceString and NewString overlap the behavior is undefined.
+
+ If the string would grow bigger than NewSize it will halt and return error.
+
+ @param[in] SourceString The string with source buffer.
+ @param[in, out] NewString The string with resultant buffer.
+ @param[in] NewSize The size in bytes of NewString.
+ @param[in] FindTarget The string to look for.
+ @param[in] ReplaceWith The string to replace FindTarget with.
+ @param[in] SkipPreCarrot If TRUE will skip a FindTarget that has a '^'
+ immediately before it.
+ @param[in] ParameterReplacing If TRUE will add "" around items with spaces.
+
+ @retval EFI_INVALID_PARAMETER SourceString was NULL.
+ @retval EFI_INVALID_PARAMETER NewString was NULL.
+ @retval EFI_INVALID_PARAMETER FindTarget was NULL.
+ @retval EFI_INVALID_PARAMETER ReplaceWith was NULL.
+ @retval EFI_INVALID_PARAMETER FindTarget had length < 1.
+ @retval EFI_INVALID_PARAMETER SourceString had length < 1.
+ @retval EFI_BUFFER_TOO_SMALL NewSize was less than the minimum size to hold
+ the new string (truncation occurred).
+ @retval EFI_SUCCESS The string was successfully copied with replacement.
+**/
+EFI_STATUS
+EFIAPI
+StrCopySearchAndReplace(
+ IN CHAR16 CONST *SourceString,
+ IN OUT CHAR16 *NewString,
+ IN UINTN NewSize,
+ IN CONST CHAR16 *FindTarget,
+ IN CONST CHAR16 *ReplaceWith,
+ IN CONST BOOLEAN SkipPreCarrot,
+ IN CONST BOOLEAN ParameterReplacing
+ )
+{
+ UINTN Size;
+ CHAR16 *Replace;
+
+ if ( (SourceString == NULL)
+ || (NewString == NULL)
+ || (FindTarget == NULL)
+ || (ReplaceWith == NULL)
+ || (StrLen(FindTarget) < 1)
+ || (StrLen(SourceString) < 1)
+ ){
+ return (EFI_INVALID_PARAMETER);
+ }
+ Replace = NULL;
+ if (StrStr(ReplaceWith, L" ") == NULL || !ParameterReplacing) {
+ Replace = StrnCatGrow2(&Replace, NULL, ReplaceWith, 0);
+ } else {
+ Replace = MEM_ALLOC(StrSize(ReplaceWith) + 2*sizeof(CHAR16));
+ if (Replace != NULL) {
+ UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith);
+ }
+ }
+ if (Replace == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ NewString = ZeroMem(NewString, NewSize);
+ while (*SourceString != CHAR_NULL) {
+ //
+ // if we find the FindTarget and either Skip == FALSE or Skip and we
+ // dont have a carrot do a replace...
+ //
+ if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0
+ && ((SkipPreCarrot && *(SourceString-1) != L'^') || !SkipPreCarrot)
+ ){
+ SourceString += StrLen(FindTarget);
+ Size = StrSize(NewString);
+ if ((Size + (StrLen(Replace)*sizeof(CHAR16))) > NewSize) {
+ MEM_FREE(Replace);
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ StrCatS(NewString, NewSize/sizeof(CHAR16), Replace);
+ } else {
+ Size = StrSize(NewString);
+ if (Size + sizeof(CHAR16) > NewSize) {
+ MEM_FREE(Replace);
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ StrnCatS(NewString, NewSize/sizeof(CHAR16), SourceString, 1);
+ SourceString++;
+ }
+ }
+ MEM_FREE(Replace);
+ return (EFI_SUCCESS);
+}
+
+/**
+ Internal worker function to output a string.
+
+ This function will output a string to the correct StdOut.
+
+ @param[in] String The string to print out.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval !EFI_SUCCESS The operation failed.
+**/
+EFI_STATUS
+EFIAPI
+AttrPrintTo (
+ IN CONST CHAR16 *String
+ )
+{
+ UINTN Size;
+ Size = StrSize(String) - sizeof(CHAR16);
+ if (Size == 0) {
+ return (EFI_SUCCESS);
+ }
+ if (mEfiShellParametersProtocol != NULL) {
+ return (mEfiShellProtocol->WriteFile(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String));
+ }
+ return gST->ConOut->OutputString(gST->ConOut, (CHAR16*)String);
+}
+
+/**
+ Print at a specific location on the screen.
+
+ This function will move the cursor to a given screen location and print the specified string
+
+ If -1 is specified for either the Row or Col the current screen location for BOTH
+ will be used.
+
+ if either Row or Col is out of range for the current console, then ASSERT
+ if Format is NULL, then ASSERT
+
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports
+ the following additional flags:
+ %N - Set output attribute to normal
+ %H - Set output attribute to highlight
+ %E - Set output attribute to error
+ %B - Set output attribute to blue color
+ %V - Set output attribute to green color
+
+ Note: The background color is controlled by the shell command cls.
+
+ @param[in] Col the column to print at
+ @param[in] Row the row to print at
+ @param[in] Format the format string
+ @param[in] Marker the marker for the variable argument list
+
+ @return EFI_SUCCESS The operation was successful.
+ @return EFI_DEVICE_ERROR The console device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+InternalAttrPrintWorker(
+ IN INT32 Col OPTIONAL,
+ IN INT32 Row OPTIONAL,
+ IN CONST CHAR16 *Format,
+ IN VA_LIST Marker
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ResumeLocation;
+ CHAR16 *FormatWalker;
+ UINTN OriginalAttribute;
+ CHAR16 *mPostReplaceFormat;
+ CHAR16 *mPostReplaceFormat2;
+
+ mPostReplaceFormat = (CHAR16*)MEM_ALLOC (ATTRPRINT_BUFSIZE);
+ mPostReplaceFormat2 = (CHAR16*)MEM_ALLOC (ATTRPRINT_BUFSIZE);
+
+ if (mPostReplaceFormat == NULL || mPostReplaceFormat2 == NULL) {
+ MEM_FREE(mPostReplaceFormat);
+ MEM_FREE(mPostReplaceFormat2);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ Status = EFI_SUCCESS;
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+
+ //
+ // Back and forth each time fixing up 1 of our flags...
+ //
+ Status = StrCopySearchAndReplace(Format, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%N", L"%%N", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat, mPostReplaceFormat2, ATTRPRINT_BUFSIZE, L"%E", L"%%E", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%H", L"%%H", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat, mPostReplaceFormat2, ATTRPRINT_BUFSIZE, L"%B", L"%%B", FALSE, FALSE);
+ Status = StrCopySearchAndReplace(mPostReplaceFormat2, mPostReplaceFormat, ATTRPRINT_BUFSIZE, L"%V", L"%%V", FALSE, FALSE);
+
+ //
+ // Use the last buffer from replacing to print from...
+ //
+ UnicodeVSPrint (mPostReplaceFormat2, ATTRPRINT_BUFSIZE, mPostReplaceFormat, Marker);
+
+ if (Col != -1 && Row != -1) {
+ Status = gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
+ }
+
+ FormatWalker = mPostReplaceFormat2;
+ while (*FormatWalker != CHAR_NULL) {
+ //
+ // Find the next attribute change request
+ //
+ ResumeLocation = StrStr(FormatWalker, L"%");
+ if (ResumeLocation != NULL) {
+ *ResumeLocation = CHAR_NULL;
+ }
+ //
+ // print the current FormatWalker string
+ //
+ if (StrLen(FormatWalker)>0) {
+ Status = AttrPrintTo(FormatWalker);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ //
+ // update the attribute
+ //
+ if (ResumeLocation != NULL) {
+ if (*(ResumeLocation-1) == L'^') {
+ //
+ // Move cursor back 1 position to overwrite the ^
+ //
+ gST->ConOut->SetCursorPosition(gST->ConOut, gST->ConOut->Mode->CursorColumn - 1, gST->ConOut->Mode->CursorRow);
+
+ //
+ // Print a simple '%' symbol
+ //
+ Status = AttrPrintTo(L"%");
+ ResumeLocation = ResumeLocation - 1;
+ } else {
+ switch (*(ResumeLocation+1)) {
+ case (L'N'):
+ gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);
+ break;
+ case (L'E'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'H'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'B'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ case (L'V'):
+ gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
+ break;
+ default:
+ //
+ // Print a simple '%' symbol
+ //
+ Status = AttrPrintTo(L"%");
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ ResumeLocation = ResumeLocation - 1;
+ break;
+ }
+ }
+ } else {
+ //
+ // reset to normal now...
+ //
+ break;
+ }
+
+ //
+ // update FormatWalker to Resume + 2 (skip the % and the indicator)
+ //
+ FormatWalker = ResumeLocation + 2;
+ }
+
+ gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);
+
+ MEM_FREE(mPostReplaceFormat);
+ MEM_FREE(mPostReplaceFormat2);
+ return (Status);
+}
+
+/**
+ Print at a specific location on the screen.
+
+ This function will move the cursor to a given screen location and print the specified string.
+
+ If -1 is specified for either the Row or Col the current screen location for BOTH
+ will be used.
+
+ If either Row or Col is out of range for the current console, then ASSERT.
+ If Format is NULL, then ASSERT.
+
+ In addition to the standard %-based flags as supported by UefiLib Print() this supports
+ the following additional flags:
+ %N - Set output attribute to normal
+ %H - Set output attribute to highlight
+ %E - Set output attribute to error
+ %B - Set output attribute to blue color
+ %V - Set output attribute to green color
+
+ Note: The background color is controlled by the shell command cls.
+
+ @param[in] Col the column to print at
+ @param[in] Row the row to print at
+ @param[in] Format the format string
+ @param[in] ... The variable argument list.
+
+ @return EFI_SUCCESS The printing was successful.
+ @return EFI_DEVICE_ERROR The console device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+AttrPrintEx(
+ IN INT32 Col OPTIONAL,
+ IN INT32 Row OPTIONAL,
+ IN CONST CHAR16 *Format,
+ ...
+ )
+{
+ VA_LIST Marker;
+ EFI_STATUS RetVal;
+ if (Format == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+ VA_START (Marker, Format);
+ RetVal = InternalAttrPrintWorker(Col, Row, Format, Marker);
+ VA_END(Marker);
+ return(RetVal);
+}
diff --git a/Library/CommonLib/EfiBeep.c b/Library/CommonLib/EfiBeep.c
new file mode 100644
index 0000000..2522078
--- /dev/null
+++ b/Library/CommonLib/EfiBeep.c
@@ -0,0 +1,69 @@
+/** @file
+EFI speaker beep helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Speaker.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Beep
+//////////////////////////////////////////////////////////////////////////
+EFI_HANDLE* gSpeakerHandles = NULL;
+UINTN gSpeakerCount = 0;
+EFI_SPEAKER_IF_PROTOCOL* gSpeaker = NULL;
+EFI_GUID gSpeakerGuid = EFI_SPEAKER_INTERFACE_PROTOCOL_GUID;
+
+// Beep defaults
+int gBeepEnabled = 1;
+BOOLEAN gBeepControlEnabled = 1;
+int gBeepDevice = -1;
+int gBeepNumberDefault = 1;
+int gBeepDurationDefault = 100;
+int gBeepIntervalDefault = 0;
+int gBeepToneDefault = 0x500;
+
+EFI_STATUS
+InitSpeaker() {
+ EFI_STATUS res;
+ // Init Console control if supported
+ res = EfiGetHandles(ByProtocol, &gSpeakerGuid, 0, &gSpeakerHandles, &gSpeakerCount);
+ if (gSpeakerCount > 0) {
+ return SpeakerSelect(gSpeakerCount - 1);
+ }
+ return res;
+}
+
+EFI_STATUS
+SpeakerSelect(
+ IN UINTN index) {
+ if (index < gSpeakerCount) {
+ return gBS->HandleProtocol(gSpeakerHandles[index], &gSpeakerGuid, (VOID**)&gSpeaker);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+SpeakerBeep(
+ IN UINT16 Tone,
+ IN UINTN NumberOfBeeps,
+ IN UINTN Duration,
+ IN UINTN Interval
+ )
+{
+ if (gSpeaker != NULL) {
+ gSpeaker->SetSpeakerToneFrequency(gSpeaker, Tone);
+ return gSpeaker->GenerateBeep(gSpeaker, NumberOfBeeps, Duration, Interval);
+ }
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Library/CommonLib/EfiBio.c b/Library/CommonLib/EfiBio.c
new file mode 100644
index 0000000..9577c08
--- /dev/null
+++ b/Library/CommonLib/EfiBio.c
@@ -0,0 +1,232 @@
+/** @file
+EFI block I/O helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/LoadedImage.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Print handle info
+//////////////////////////////////////////////////////////////////////////
+
+VOID
+EfiPrintDevicePath(
+ IN EFI_HANDLE handle)
+{
+ CHAR16 *StrPath;
+ EFI_DEVICE_PATH *DevicePath;
+ OUT_PRINT(L"(%0X): ", handle);
+ DevicePath = DevicePathFromHandle(handle);
+ if (DevicePath == NULL) {
+ ERR_PRINT(L"No path found");
+ return;
+ }
+ StrPath = ConvertDevicePathToText(DevicePath, FALSE, FALSE);
+ OUT_PRINT(StrPath);
+ MEM_FREE(StrPath);
+}
+
+VOID
+EfiPrintProtocols(
+ IN EFI_HANDLE handle)
+{
+ EFI_GUID **guids;
+ UINTN count;
+ EFI_STATUS status;
+ status = gBS->ProtocolsPerHandle(handle, &guids, &count);
+ if (!EFI_ERROR(status)) {
+ UINTN i;
+ for (i = 0; i < count; ++i) {
+ OUT_PRINT(L"%d: %g\n", i, guids[i]);
+ }
+ FreePool(guids);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Handles
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiGetHandles(
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol, OPTIONAL
+ IN VOID *SearchKey, OPTIONAL
+ OUT EFI_HANDLE **Buffer,
+ OUT UINTN *Count
+ )
+{
+ EFI_STATUS res = EFI_BUFFER_TOO_SMALL;
+ UINTN BufferSize;
+ if(*Buffer != NULL) MEM_FREE(*Buffer);
+ *Count = 0;
+ *Buffer = (EFI_HANDLE*) MEM_ALLOC(sizeof(EFI_HANDLE));
+ if (*Buffer) {
+ BufferSize = sizeof(EFI_HANDLE);
+ res = gBS->LocateHandle(SearchType, Protocol, SearchKey, &BufferSize, *Buffer);
+ if (res == RETURN_BUFFER_TOO_SMALL) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)MEM_ALLOC(BufferSize);
+ if (!Buffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ res = gBS->LocateHandle(SearchType, Protocol, SearchKey, &BufferSize, *Buffer);
+ if(res != EFI_SUCCESS) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)NULL;
+ return res;
+ }
+ } else if (EFI_ERROR(res)) {
+ MEM_FREE(*Buffer);
+ *Buffer = (EFI_HANDLE*)NULL;
+ return res;
+ }
+ *Count = (UINTN)(BufferSize / sizeof(EFI_HANDLE));
+ }
+ return res;
+}
+
+EFI_STATUS
+EfiGetStartDevice(
+ OUT EFI_HANDLE* handle)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ *handle = LoadedImage->DeviceHandle;
+ return Status;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Block I/O
+//////////////////////////////////////////////////////////////////////////
+
+EFI_BLOCK_IO_PROTOCOL*
+EfiGetBlockIO(
+ IN EFI_HANDLE handle
+ )
+{
+ EFI_STATUS res;
+ EFI_BLOCK_IO_PROTOCOL* blockIOProtocol = NULL;
+ res = gBS->HandleProtocol(handle, &gEfiBlockIoProtocolGuid, (VOID**)&blockIOProtocol);
+ if (res == RETURN_SUCCESS &&
+ blockIOProtocol != NULL &&
+ blockIOProtocol->Media->MediaPresent) {
+ return blockIOProtocol;
+ }
+ return NULL;
+}
+
+
+EFI_HANDLE* gBIOHandles;
+UINTN gBIOCount;
+
+EFI_STATUS
+InitBio() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiBlockIoProtocolGuid, 0, &gBIOHandles, &gBIOCount);
+ return res;
+}
+
+BOOLEAN
+EfiIsPartition(
+ IN EFI_HANDLE h
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ node = DevicePathFromHandle(h);
+ if (node == NULL) return FALSE;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ return TRUE;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return FALSE;
+}
+
+EFI_STATUS
+EfiGetPartDetails(
+ IN EFI_HANDLE h,
+ OUT HARDDRIVE_DEVICE_PATH* dpVolme,
+ OUT EFI_HANDLE* hDisk)
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ EFI_DEVICE_PATH_PROTOCOL* dpVolume;
+ EFI_DEVICE_PATH_PROTOCOL* dpDisk;
+ EFI_STATUS res;
+ dpVolume = DevicePathFromHandle(h);
+ dpDisk = DuplicateDevicePath(dpVolume);
+ node = (EFI_DEVICE_PATH_PROTOCOL *)dpDisk;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ CopyMem(dpVolme, node, sizeof(HARDDRIVE_DEVICE_PATH));
+ SetDevicePathEndNode(node);
+ res = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &dpDisk, hDisk);
+ return res;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EfiGetPartGUID(
+ IN EFI_HANDLE h,
+ OUT EFI_GUID* guid)
+{
+ EFI_DEVICE_PATH_PROTOCOL* node;
+ EFI_DEVICE_PATH_PROTOCOL* dpVolume;
+ if (guid == NULL) return EFI_INVALID_PARAMETER;
+ dpVolume = DevicePathFromHandle(h);
+ node = (EFI_DEVICE_PATH_PROTOCOL *)dpVolume;
+ while (!IsDevicePathEnd(node)) {
+ if (node->Type == MEDIA_DEVICE_PATH && node->SubType == MEDIA_HARDDRIVE_DP) {
+ HARDDRIVE_DEVICE_PATH* hdpNode = (HARDDRIVE_DEVICE_PATH*)node;
+ CopyMem(guid, hdpNode->Signature, sizeof(*guid));
+ return EFI_SUCCESS;
+ }
+ node = NextDevicePathNode(node);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EfiFindPartByGUID(
+ IN EFI_GUID* guid,
+ OUT EFI_HANDLE* h
+ )
+{
+ EFI_STATUS res;
+ EFI_GUID guidI;
+ UINTN i;
+ if (guid == NULL || h == NULL) return EFI_INVALID_PARAMETER;
+ for (i = 0; i < gBIOCount; ++i) {
+ res = EfiGetPartGUID(gBIOHandles[i], &guidI);
+ if (!EFI_ERROR(res)) {
+ if (CompareMem(&guidI, guid, sizeof(guidI)) == 0) {
+ *h = gBIOHandles[i];
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
diff --git a/Library/CommonLib/EfiConsole.c b/Library/CommonLib/EfiConsole.c
new file mode 100644
index 0000000..8a87ec8
--- /dev/null
+++ b/Library/CommonLib/EfiConsole.c
@@ -0,0 +1,347 @@
+/** @file
+EFI console helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/Speaker.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Print
+//////////////////////////////////////////////////////////////////////////
+
+VOID
+FlushInputDelay(
+ IN UINTN delay
+ )
+{
+ EFI_INPUT_KEY key;
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex = 0;
+
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, delay);
+ while (EventIndex == 0) {
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+ }
+ gBS->CloseEvent(InputEvents[1]);
+}
+
+VOID
+FlushInput() {
+ FlushInputDelay(1000000);
+}
+
+EFI_INPUT_KEY
+KeyWait(
+ CHAR16* Prompt,
+ UINTN mDelay,
+ UINT16 scanCode,
+ UINT16 unicodeChar)
+{
+ EFI_INPUT_KEY key;
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex;
+
+ FlushInput();
+ key.ScanCode = scanCode;
+ key.UnicodeChar = unicodeChar;
+
+ InputEvents[0] = gST->ConIn->WaitForKey;
+
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, 10000000);
+ while (mDelay > 0) {
+ OUT_PRINT(Prompt, mDelay);
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ break;
+ }
+ else {
+ mDelay--;
+ }
+ }
+ OUT_PRINT(Prompt, mDelay);
+ gBS->CloseEvent(InputEvents[1]);
+ return key;
+}
+
+EFI_INPUT_KEY
+GetKey(void)
+{
+ EFI_INPUT_KEY key;
+ UINTN EventIndex;
+
+ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &EventIndex);
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ return key;
+}
+
+VOID
+ConsoleShowTip(
+ IN CHAR16* tip,
+ IN UINTN delay)
+{
+ EFI_EVENT InputEvents[2];
+ UINTN EventIndex = 0;
+ UINTN i = 0;
+ EFI_INPUT_KEY key;
+ OUT_PRINT(L"%s", tip);
+
+ // delay
+ InputEvents[0] = gST->ConIn->WaitForKey;
+ gBS->CreateEvent(EVT_TIMER, 0, (EFI_EVENT_NOTIFY)NULL, NULL, &InputEvents[1]);
+ gBS->SetTimer(InputEvents[1], TimerPeriodic, delay);
+ gBS->WaitForEvent(2, InputEvents, &EventIndex);
+ if (EventIndex == 0) {
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
+ }
+
+ // remove tip
+ for (i = 0; i < StrLen(tip); ++i) {
+ OUT_PRINT(L"\b \b", tip);
+ }
+}
+
+
+VOID
+GetLine (
+ UINTN *length,
+ CHAR16 *line,
+ CHAR8 *asciiLine,
+ UINTN line_max,
+ UINT8 show)
+{
+ EFI_INPUT_KEY key;
+ UINT32 count = 0;
+
+ do {
+ key = GetKey();
+
+ if ((count >= line_max &&
+ key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED ||
+ key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ } else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ OUT_PRINT(L"\b \b");
+ if (line != NULL) line[--count] = '\0';
+ if (asciiLine != NULL) asciiLine[--count] = '\0';
+ continue;
+ }
+
+ // check size of line
+ if (count < line_max - 1) {
+ if (show) {
+ OUT_PRINT(L"%c", key.UnicodeChar);
+ }
+ else {
+ OUT_PRINT(L"*");
+ }
+ // save char
+ if (line != NULL) line[count++] = key.UnicodeChar;
+ if (asciiLine != NULL) asciiLine[count++] = (CHAR8)key.UnicodeChar;
+ }
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ OUT_PRINT(L"\n");
+ if (length != NULL) *length = count;
+ // Set end of line
+ if (line != NULL) line[count] = '\0';
+ if (asciiLine != NULL) asciiLine[count] = '\0';
+}
+
+int
+AskAsciiString(
+ CHAR8* prompt,
+ CHAR8* str,
+ UINTN max_len,
+ UINT8 visible)
+{
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, NULL, str, max_len, visible);
+ return (UINT32)len;
+}
+
+int
+AskInt(
+ CHAR8* prompt,
+ UINT8 visible)
+{
+ CHAR16 buf[32];
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, visible);
+ return (UINT32)StrDecimalToUintn(buf);
+}
+
+UINT8
+AskConfirm(
+ CHAR8* prompt,
+ UINT8 visible)
+{
+ CHAR16 buf[2];
+ UINTN len = 0;
+ OUT_PRINT(L"%a", prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, visible);
+ return (buf[0] == 'y') || (buf[0] == 'Y') ? 1 : 0;
+}
+
+UINT64
+AskUINT64(
+ IN char* prompt,
+ IN UINT64 def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[%lld] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : (UINT64)StrDecimalToUint64(buf);
+}
+
+UINT64
+AskHexUINT64(
+ IN char* prompt,
+ IN UINT64 def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[0x%llx] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : (UINT64)StrHexToUint64(buf);
+}
+
+UINTN
+AskUINTN(
+ IN char* prompt,
+ IN UINTN def)
+{
+ CHAR16 buf[128];
+ UINTN len = 0;
+ OUT_PRINT(L"[%d] %a", def, prompt);
+ GetLine(&len, buf, NULL, sizeof(buf) / 2, 1);
+ return (len == 0) ? def : StrDecimalToUintn(buf);
+}
+
+EFI_STATUS
+ConsoleGetOutput(
+ IN EFI_HANDLE handle,
+ OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL** io
+ ) {
+ return gBS->HandleProtocol(handle, &gEfiSimpleTextOutProtocolGuid, (VOID**)io);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Ascii converters
+//////////////////////////////////////////////////////////////////////////
+BOOLEAN
+AsciiHexToDigit(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ )
+{
+ CHAR8 ch;
+ ch = str[0];
+ if (ch >= '0' && ch <= '9') {
+ *b = ch - '0';
+ return TRUE;
+ }
+ else {
+ ch = ch & ~0x20;
+ if (ch >= 'A' && ch <= 'F') {
+ *b = ch - 'A' + 10;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOLEAN
+AsciiHexToByte(
+ OUT UINT8 *b,
+ IN CHAR8 *str
+ )
+{
+ UINT8 low = 0;
+ UINT8 high = 0;
+ BOOLEAN res;
+ res = AsciiHexToDigit(&high, str);
+ res = res && AsciiHexToDigit(&low, str + 1);
+ *b = low | high << 4;
+ return res;
+}
+
+BOOLEAN
+AsciiStrToGuid(
+ OUT EFI_GUID *guid,
+ IN CHAR8 *str
+ )
+{
+ UINT8 b[16];
+ BOOLEAN res = TRUE;
+ int i;
+ CHAR8* pos = str;
+ if (guid == NULL || str == NULL) return FALSE;
+ for (i = 0; i < 16; ++i) {
+ if (*pos == '-') pos++;
+ res = res && AsciiHexToByte(&b[i], pos);
+ pos += 2;
+ if (!res) return FALSE;
+ }
+ guid->Data1 = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
+ guid->Data2 = b[4] << 8 | b[5];
+ guid->Data3 = b[6] << 8 | b[7];
+ CopyMem(&guid->Data4, &b[8], 8);
+ return res;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Console control
+//////////////////////////////////////////////////////////////////////////
+
+EFI_HANDLE* gConsoleControlHandles = NULL;
+UINTN gConsoleControlCount = 0;
+
+EFI_STATUS
+InitConsoleControl() {
+ EFI_STATUS res;
+ // Init Console control if supported
+ EFI_GUID gConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+ EFI_CONSOLE_CONTROL_PROTOCOL* ConsoleControl;
+ res = EfiGetHandles(ByProtocol, &gConsoleControlProtocolGuid, 0, &gConsoleControlHandles, &gConsoleControlCount);
+ if (gConsoleControlCount > 0) {
+ res = gBS->HandleProtocol(gConsoleControlHandles[0], &gConsoleControlProtocolGuid, (VOID**)&ConsoleControl);
+ if (!EFI_ERROR(res)) {
+ // Unlock graphics
+ ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenGraphics);
+ }
+ }
+ return res;
+}
diff --git a/Library/CommonLib/EfiExec.c b/Library/CommonLib/EfiExec.c
new file mode 100644
index 0000000..ff0aa95
--- /dev/null
+++ b/Library/CommonLib/EfiExec.c
@@ -0,0 +1,88 @@
+/** @file
+EFI execute helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+EFI_STATUS
+EfiExec(
+ IN EFI_HANDLE deviceHandle,
+ IN CHAR16* path
+ )
+{
+ EFI_STATUS res;
+ EFI_DEVICE_PATH* DevicePath;
+ EFI_HANDLE ImageHandle;
+ UINTN ExitDataSize;
+ CHAR16 *ExitData;
+ if (deviceHandle == NULL) {
+ deviceHandle = gFileRootHandle;
+ }
+ if (!path || !deviceHandle) return EFI_INVALID_PARAMETER;
+ DevicePath = FileDevicePath(deviceHandle, path);
+
+ res = gBS->LoadImage(FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = gBS->StartImage(ImageHandle, &ExitDataSize, &ExitData);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return res;
+}
+
+/**
+This function will connect all current system handles recursively. The
+connection will finish until every handle's child handle created if it have.
+
+@retval EFI_SUCCESS All handles and it's child handle have been
+connected
+@retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+ConnectAllEfi(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+
+ Status = gBS->LocateHandleBuffer(
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->ConnectController(HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/Library/CommonLib/EfiFile.c b/Library/CommonLib/EfiFile.c
new file mode 100644
index 0000000..b1e2076
--- /dev/null
+++ b/Library/CommonLib/EfiFile.c
@@ -0,0 +1,350 @@
+/** @file
+EFI file system helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Library/BaseMemoryLib.h>
+
+//////////////////////////////////////////////////////////////////////////
+// EFI file
+//////////////////////////////////////////////////////////////////////////
+
+EFI_FILE* gFileRoot = NULL;
+EFI_HANDLE gFileRootHandle = NULL;
+
+EFI_HANDLE* gFSHandles = NULL;
+UINTN gFSCount = 0;
+
+EFI_STATUS
+InitFS() {
+ EFI_STATUS res;
+ EfiGetHandles(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, 0, &gFSHandles, &gFSCount);
+ res = EfiGetStartDevice(&gFileRootHandle);
+ if (!EFI_ERROR(res)) {
+ res = FileOpenRoot(gFileRootHandle, &gFileRoot);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileOpenRoot(
+ IN EFI_HANDLE rootHandle,
+ OUT EFI_FILE** rootFile)
+{
+ EFI_STATUS res = 0;
+ EFI_FILE_IO_INTERFACE* fSysProtocol = NULL;
+ res = gBS->HandleProtocol(rootHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&fSysProtocol);
+ if (res == RETURN_SUCCESS && fSysProtocol != NULL) {
+ res = fSysProtocol->OpenVolume(fSysProtocol, rootFile);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileOpen(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT EFI_FILE** file,
+ IN UINT64 mode,
+ IN UINT64 attributes
+ )
+{
+ EFI_STATUS res;
+
+ if (!name || !file) { return EFI_INVALID_PARAMETER; }
+ if (!root) root = gFileRoot;
+ if (!root) { return EFI_INVALID_PARAMETER; }
+ if (mode == 0) {
+ mode = EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE;
+ }
+ res = root->Open(root, file, name, mode , attributes);
+ return res;
+}
+
+EFI_STATUS
+FileClose(
+ IN EFI_FILE* f)
+{
+ if (!f) { return EFI_INVALID_PARAMETER; }
+ return f->Close(f);
+}
+
+EFI_STATUS
+FileDelete(
+ IN EFI_FILE* root,
+ IN CHAR16* name
+ )
+{
+ EFI_FILE* f;
+ EFI_STATUS res;
+ if (!name) { return EFI_INVALID_PARAMETER; }
+ res = FileOpen(root, name, &f, 0, 0);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ res = f->Delete(f);
+// f->Close(f);
+ return res;
+}
+
+EFI_STATUS
+FileRead(
+ IN EFI_FILE* f,
+ OUT VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position)
+{
+ EFI_STATUS res;
+
+ if (!f || !data || !bytes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (position != NULL) {
+ res = f->SetPosition(f, *position);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ }
+ res = f->Read(f, bytes, data);
+ if (position != NULL) {
+ f->GetPosition(f, position);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileWrite(
+ IN EFI_FILE* f,
+ IN VOID* data,
+ IN OUT UINTN* bytes,
+ IN OUT UINT64* position)
+{
+ EFI_STATUS res;
+
+ if (!f || !data || !bytes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (position != NULL) {
+ res = f->SetPosition(f, *position);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ }
+ res = f->Write(f, bytes, data);
+ if (position != NULL) {
+ f->GetPosition(f, position);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileGetInfo(
+ IN EFI_FILE* f,
+ OUT EFI_FILE_INFO** info,
+ OUT UINTN* size
+ )
+{
+ EFI_STATUS res;
+ UINTN sz = 0;
+ if (!f || !info) { return EFI_INVALID_PARAMETER; }
+ res = f->GetInfo(f, &gEfiFileInfoGuid, &sz, NULL);
+ if (res == RETURN_BUFFER_TOO_SMALL) {
+ *info = (EFI_FILE_INFO*)MEM_ALLOC(sz);
+ if (!(*info)) {
+ return res;
+ }
+ res = f->GetInfo(f, &gEfiFileInfoGuid, &sz, *info);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(*info);
+ *info = NULL;
+ sz = 0;
+ }
+ }
+ if (size) {
+ *size = sz;
+ }
+ return res;
+}
+
+EFI_STATUS
+FileGetSize(
+ IN EFI_FILE* f,
+ OUT UINTN* size
+ )
+{
+ EFI_STATUS res;
+ EFI_FILE_INFO* info = NULL;
+ if (!f || !size) { return EFI_INVALID_PARAMETER; }
+ res = FileGetInfo(f, &info, NULL);
+ if (!EFI_ERROR(res)) {
+ *size = (UINTN)info->FileSize;
+ MEM_FREE(info);
+ }
+ return res;
+}
+
+EFI_STATUS
+FileLoad(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ OUT VOID** data,
+ OUT UINTN* size
+ )
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ UINTN sz;
+ if (!data) {
+ return EFI_INVALID_PARAMETER;
+ }
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetSize(file, &sz);
+ if (EFI_ERROR(res)) {
+ FileClose(file);
+ return res;
+ }
+ *data = MEM_ALLOC(sz);
+ if (*data == NULL) {
+ FileClose(file);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ res = FileRead(file, *data, &sz, NULL);
+ if (EFI_ERROR(res)) {
+ FileClose(file);
+ MEM_FREE(*data);
+ return res;
+ }
+ FileClose(file);
+ if (size != NULL) {
+ *size = sz;
+ }
+ return res;
+}
+
+EFI_STATUS
+FileSave(
+ IN EFI_FILE* root,
+ IN CHAR16* name,
+ IN VOID* data,
+ IN UINTN size
+ )
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ UINTN sz = size;
+ if (!data || !name) { return EFI_INVALID_PARAMETER; }
+ FileDelete(root, name);
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileWrite(file, data, &sz, NULL);
+ FileClose(file);
+ return res;
+}
+
+EFI_STATUS
+FileExist(
+ IN EFI_FILE* root,
+ IN CHAR16* name)
+{
+ EFI_FILE* file;
+ EFI_STATUS res;
+ res = FileOpen(root, name, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ FileClose(file);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileRename(
+ IN EFI_FILE* root,
+ IN CHAR16* src,
+ IN CHAR16* dst)
+{
+ EFI_STATUS res;
+ EFI_FILE* file;
+ EFI_FILE_INFO* info = NULL;
+ UINTN sz;
+ EFI_FILE_INFO* dstinfo = NULL;
+ UINTN dstinfosz;
+
+ res = FileOpen(root, src, &file, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetInfo(file, &info, &sz);
+ if (EFI_ERROR(res)) return res;
+ dstinfosz = SIZE_OF_EFI_FILE_INFO + StrSize(dst);
+ dstinfo = (EFI_FILE_INFO*)MEM_ALLOC(dstinfosz);
+ if (dstinfo != NULL) {
+ CopyMem(dstinfo, info, SIZE_OF_EFI_FILE_INFO);
+ dstinfo->FileName[0] = 0;
+ StrCat(dstinfo->FileName, dst);
+ res = file->SetInfo(file, &gEfiFileInfoGuid, dstinfosz, dstinfo);
+ } else {
+ res = EFI_BUFFER_TOO_SMALL;
+ }
+
+ MEM_FREE(info);
+ MEM_FREE(dstinfo);
+ FileClose(file);
+ return res;
+}
+
+EFI_STATUS
+FileCopy(
+ IN EFI_FILE* srcroot,
+ IN CHAR16* src,
+ IN EFI_FILE* dstroot,
+ IN CHAR16* dst,
+ IN UINTN bufSz
+ )
+{
+ EFI_STATUS res;
+ EFI_FILE* srcfile = NULL;
+ EFI_FILE* dstfile = NULL;
+ UINTN remains;
+ CHAR8* data = NULL;
+ UINTN datasz = bufSz;
+
+ res = FileOpen(srcroot, src, &srcfile, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) return res;
+ res = FileGetSize(srcfile, &remains);
+ if (EFI_ERROR(res)) return res;
+
+ data = (CHAR8*)MEM_ALLOC(bufSz);
+ if (data == NULL) {
+ res = EFI_BUFFER_TOO_SMALL;
+ goto copyerr;
+ }
+
+ res = FileOpen(dstroot, dst, &dstfile, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(res)) goto copyerr;
+
+ do {
+ datasz = remains > bufSz ? bufSz : remains;
+ res =FileRead(srcfile, data, &datasz, NULL);
+ if (EFI_ERROR(res)) goto copyerr;
+ res = FileWrite(dstfile, data, &datasz, NULL);
+ if (EFI_ERROR(res)) goto copyerr;
+ remains -= datasz;
+ } while (remains > 0);
+
+copyerr:
+ MEM_FREE(data);
+ FileClose(srcfile);
+ FileClose(dstfile);
+ return res;
+}
diff --git a/Library/CommonLib/EfiMem.c b/Library/CommonLib/EfiMem.c
new file mode 100644
index 0000000..d9386c0
--- /dev/null
+++ b/Library/CommonLib/EfiMem.c
@@ -0,0 +1,74 @@
+/** @file
+EFI memory helpers routines/wrappers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Uefi.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "Library/CommonLib.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// Memory procedures wrappers
+//////////////////////////////////////////////////////////////////////////
+
+VOID*
+MemAlloc(
+ IN UINTN size
+ ) {
+ return AllocateZeroPool(size);
+}
+
+VOID*
+MemRealloc(
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ ) {
+ return ReallocatePool(OldSize, NewSize, OldBuffer);
+}
+
+VOID
+MemFree(
+ IN VOID* ptr
+ ) {
+ if(ptr != NULL) FreePool(ptr);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Memory mapped IO
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+PrepareMemory(
+ IN UINTN address,
+ IN UINTN len,
+ OUT VOID** mem)
+{
+ EFI_STATUS status;
+ EFI_PHYSICAL_ADDRESS ptr;
+ VOID* buf;
+ UINTN pages;
+ pages = ((len & ~0x0FFF) + 0x1000) >> 12;
+ ptr = address & ~0x0FFF;
+// OUT_PRINT(L"mem try %0x, %0x\n", pages, (UINTN)ptr);
+ status = gBS->AllocatePages(AllocateAddress, EfiMemoryMappedIO, pages, &ptr);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+ buf = (void*)(UINTN)ptr;
+ SetMem(buf, pages << 12, 0);
+ *mem = buf;
+ return status;
+}
diff --git a/Library/CommonLib/EfiTouch.c b/Library/CommonLib/EfiTouch.c
new file mode 100644
index 0000000..9009f82
--- /dev/null
+++ b/Library/CommonLib/EfiTouch.c
@@ -0,0 +1,47 @@
+/** @file
+EFI touch/absolute pointer helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/AbsolutePointer.h>
+
+EFI_HANDLE* gTouchHandles = NULL;
+UINTN gTouchCount = 0;
+int gTouchSimulate = 0;
+UINT32 gTouchSimulateStep = 1;
+
+EFI_ABSOLUTE_POINTER_PROTOCOL* gTouchPointer = NULL;
+
+EFI_STATUS
+InitTouch() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiAbsolutePointerProtocolGuid, 0, &gTouchHandles, &gTouchCount);
+ if (gTouchCount > 0) {
+ TouchGetIO(gTouchHandles[gTouchCount - 1], &gTouchPointer);
+ }
+ return res;
+}
+
+
+EFI_STATUS
+TouchGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_ABSOLUTE_POINTER_PROTOCOL** io
+ ) {
+ if (!io) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gBS->HandleProtocol(Handle, &gEfiAbsolutePointerProtocolGuid, (VOID**)io);
+}
+
diff --git a/Library/CommonLib/EfiUsb.c b/Library/CommonLib/EfiUsb.c
new file mode 100644
index 0000000..b5bdac5
--- /dev/null
+++ b/Library/CommonLib/EfiUsb.c
@@ -0,0 +1,88 @@
+/** @file
+EFI USB helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Protocol/UsbIo.h>
+
+EFI_HANDLE* gUSBHandles = NULL;
+UINTN gUSBCount = 0;
+
+EFI_STATUS
+InitUsb() {
+ EFI_STATUS res;
+ res = EfiGetHandles(ByProtocol, &gEfiUsbIoProtocolGuid, 0, &gUSBHandles, &gUSBCount);
+ return res;
+}
+
+EFI_STATUS
+UsbGetIO(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo
+ ) {
+ if (!UsbIo) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return gBS->HandleProtocol(Handle, &gEfiUsbIoProtocolGuid, (VOID**)UsbIo);
+}
+
+EFI_STATUS
+UsbGetIOwithDescriptor(
+ IN EFI_HANDLE Handle,
+ OUT EFI_USB_IO_PROTOCOL** UsbIo,
+ OUT EFI_USB_DEVICE_DESCRIPTOR* UsbDescriptor
+ ) {
+ EFI_STATUS res;
+ if (!UsbIo || !UsbDescriptor) {
+ return EFI_INVALID_PARAMETER;
+ }
+ res = UsbGetIO(Handle, UsbIo);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+ return (*UsbIo)->UsbGetDeviceDescriptor(*UsbIo, UsbDescriptor);
+}
+
+EFI_STATUS
+UsbGetId(
+ IN EFI_HANDLE Handle,
+ OUT CHAR8** id
+ )
+{
+ EFI_STATUS res;
+ EFI_USB_IO_PROTOCOL *usbIO = NULL;
+ EFI_USB_DEVICE_DESCRIPTOR usbDescriptor;
+ CHAR16* serial = NULL;
+ CHAR8* buff;
+ UINTN len;
+ res = UsbGetIOwithDescriptor(Handle, &usbIO, &usbDescriptor);
+ if (EFI_ERROR(res)) {
+ return res;
+ }
+// Print(L" %02x ", (UINTN)usbDescriptor.StrSerialNumber);
+ res = usbIO->UsbGetStringDescriptor(usbIO, 0x409, usbDescriptor.StrSerialNumber, &serial);
+ if (!EFI_ERROR(res)) {
+ len = 11 + StrLen(serial);
+ buff = (CHAR8*)MEM_ALLOC(len);
+ AsciiSPrint(buff, len, "%04x_%04x_%s", usbDescriptor.IdVendor, usbDescriptor.IdProduct, serial);
+ } else {
+// Print(L" %04x %r ", res, res);
+ len = 10;
+ buff = (CHAR8*)MEM_ALLOC(len);
+ AsciiSPrint(buff, len, "%04x_%04x", usbDescriptor.IdVendor, usbDescriptor.IdProduct);
+ }
+ *id = buff;
+ return EFI_SUCCESS;
+}
diff --git a/Library/CommonLib/EfiVar.c b/Library/CommonLib/EfiVar.c
new file mode 100644
index 0000000..2a6e59e
--- /dev/null
+++ b/Library/CommonLib/EfiVar.c
@@ -0,0 +1,228 @@
+/** @file
+EFI firmware variable helpers
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/CommonLib.h>
+
+#include <Uefi.h>
+#include <Guid/GlobalVariable.h>
+#include <Protocol/DevicePath.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//////////////////////////////////////////////////////////////////////////
+// Efi variables
+//////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+EfiGetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ OUT VOID** varValue,
+ OUT UINTN* varSize,
+ OUT UINT32* varAttr
+ ) {
+ EFI_STATUS Status;
+ CHAR8 *varData = NULL;
+ if (varSize == NULL) return EFI_INVALID_PARAMETER;
+ *varSize = 0;
+ if (varGuid == NULL) varGuid = &gEfiDcsVariableGuid;
+ Status = gST->RuntimeServices->GetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varData);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ varData = MEM_ALLOC(*varSize);
+ if (varData == NULL) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ Status = gST->RuntimeServices->GetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varData);
+ *varValue = varData;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+EfiSetVar(
+ IN CONST CHAR16* varName,
+ IN EFI_GUID* varGuid,
+ IN VOID* varValue,
+ IN UINTN varSize,
+ IN UINT32 varAttr
+ ) {
+ EFI_STATUS Status;
+ if (varGuid == NULL) varGuid = &gEfiDcsVariableGuid;
+ Status = gST->RuntimeServices->SetVariable((CHAR16*)varName, varGuid, varAttr, varSize, varValue);
+ return Status;
+}
+
+EFI_STATUS
+BootOrderInsert(
+ IN CHAR16 *OrderVarName,
+ IN UINTN index,
+ UINT16 value)
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT16* varBootOrderNew;
+ UINT16* varBootOrder;
+ UINTN varBootOrderSize;
+ UINT32 varBootOrderAttr;
+ UINTN BootOrderCount;
+ UINTN i;
+ UINTN j;
+ res = EfiGetVar(OrderVarName, &gEfiGlobalVariableGuid, &varBootOrder, &varBootOrderSize, &varBootOrderAttr);
+ if (EFI_ERROR(res)) return res;
+ BootOrderCount = varBootOrderSize / sizeof(UINT16);
+ varBootOrderNew = MEM_ALLOC((BootOrderCount + 1) * sizeof(UINT16));
+ if (BootOrderCount < index) index = BootOrderCount - 1;
+ for (j = 0, i = 0; i < BootOrderCount; ++i) {
+ if (j == index) {
+ varBootOrderNew[j] = value;
+ j++;
+ }
+ if (varBootOrder[i] == value) {
+ continue;
+ }
+ varBootOrderNew[j] = varBootOrder[i];
+ ++j;
+ }
+ BootOrderCount = j;
+
+ res = EfiSetVar(OrderVarName, &gEfiGlobalVariableGuid,
+ varBootOrderNew, BootOrderCount * sizeof(UINT16),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ MEM_FREE(varBootOrderNew);
+ MEM_FREE(varBootOrder);
+ return res;
+}
+
+EFI_STATUS
+BootOrderRemove(
+ IN CHAR16 *OrderVarName,
+ UINT16 value)
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT16* varBootOrderNew;
+ UINT16* varBootOrder;
+ UINTN varBootOrderSize;
+ UINT32 varBootOrderAttr;
+ UINTN BootOrderCount;
+ UINTN i;
+ UINTN j;
+
+ res = EfiGetVar(OrderVarName, &gEfiGlobalVariableGuid, &varBootOrder, &varBootOrderSize, &varBootOrderAttr);
+ if (EFI_ERROR(res)) return res;
+ BootOrderCount = varBootOrderSize / sizeof(UINT16);
+ varBootOrderNew = MEM_ALLOC((BootOrderCount + 1) * sizeof(UINT16));
+ for (j = 0, i = 0; i < BootOrderCount; ++i) {
+ if (varBootOrder[i] == value) {
+ continue;
+ }
+ varBootOrderNew[j] = varBootOrder[i];
+ ++j;
+ }
+ BootOrderCount = j;
+
+ res = EfiSetVar(OrderVarName, &gEfiGlobalVariableGuid,
+ varBootOrderNew, BootOrderCount * sizeof(UINT16),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+
+ MEM_FREE(varBootOrderNew);
+ MEM_FREE(varBootOrder);
+ return res;
+}
+
+EFI_STATUS
+BootMenuItemRemove(
+ IN CHAR16 *VarName
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ res = EfiSetVar(
+ VarName, &gEfiGlobalVariableGuid,
+ NULL, 0,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ return res;
+}
+
+EFI_STATUS
+BootMenuItemCreate(
+ IN CHAR16 *VarName,
+ IN CHAR16 *Desc,
+ IN EFI_HANDLE volumeHandle,
+ IN CHAR16 *Path,
+ IN BOOLEAN Reduced
+ )
+{
+ EFI_STATUS res = EFI_NOT_READY;
+ UINT8* varBoot;
+ UINT8* TempByteBuffer;
+ UINTN DescSize;
+ UINTN FilePathSize;
+ EFI_DEVICE_PATH_PROTOCOL* DevPath;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL* FileNode;
+ EFI_DEVICE_PATH_PROTOCOL* FilePath;
+
+ // Prepare
+ DevicePath = DevicePathFromHandle(volumeHandle);
+ if (Reduced) {
+ DevPath = DevicePath;
+ while (!IsDevicePathEnd(DevPath)) {
+ if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
+ (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
+
+ //
+ // If we find it use it instead
+ //
+ DevicePath = DevPath;
+ break;
+ }
+ DevPath = NextDevicePathNode(DevPath);
+ }
+ }
+ //
+ // append the file
+ //
+ FileNode = FileDevicePath(NULL, Path);
+ FilePath = AppendDevicePath(DevicePath, FileNode);
+ FreePool(FileNode);
+ //
+ // Add the option
+ //
+ DescSize = StrSize(Desc);
+ FilePathSize = GetDevicePathSize(FilePath);
+
+ varBoot = MEM_ALLOC(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);
+ if (varBoot != NULL) {
+ TempByteBuffer = varBoot;
+ *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
+ TempByteBuffer += sizeof(UINT32);
+
+ *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
+ TempByteBuffer += sizeof(UINT16);
+
+ CopyMem(TempByteBuffer, Desc, DescSize);
+ TempByteBuffer += DescSize;
+ CopyMem(TempByteBuffer, FilePath, FilePathSize);
+
+ res = EfiSetVar(VarName, &gEfiGlobalVariableGuid,
+ varBoot, sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+ }
+ else {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ MEM_FREE(varBoot);
+ return res;
+}
diff --git a/Library/CommonLib/IA32/EfiCpuHalt.asm b/Library/CommonLib/IA32/EfiCpuHalt.asm
new file mode 100644
index 0000000..3c5bb0d
--- /dev/null
+++ b/Library/CommonLib/IA32/EfiCpuHalt.asm
@@ -0,0 +1,19 @@
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; CpuHalt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiCpuHalt PROC
+ cli
+l: hlt
+ jmp l
+ ret
+EfiCpuHalt ENDP
+
+ END
diff --git a/Library/CommonLib/X64/EfiCpuHalt.asm b/Library/CommonLib/X64/EfiCpuHalt.asm
new file mode 100644
index 0000000..7893234
--- /dev/null
+++ b/Library/CommonLib/X64/EfiCpuHalt.asm
@@ -0,0 +1,17 @@
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; CpuHalt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+EfiCpuHalt PROC
+ cli
+l: hlt
+ jmp l
+ ret
+EfiCpuHalt ENDP
+
+ END