diff options
| author | Konstantin Aladyshev <aladyshev22@gmail.com> | 2022-02-25 15:39:26 +0300 | 
|---|---|---|
| committer | Konstantin Aladyshev <aladyshev22@gmail.com> | 2022-02-25 15:45:35 +0300 | 
| commit | cf884399031c711205f837a5b65eeeb26fee3258 (patch) | |
| tree | fdd7e34311adf1e33a5e753ecd02af260605d154 /Lessons | |
| parent | 68b64507709c0b4e57c9dda6c096bfa4a35b5973 (diff) | |
| download | UEFI-Lessons-cf884399031c711205f837a5b65eeeb26fee3258.tar.gz UEFI-Lessons-cf884399031c711205f837a5b65eeeb26fee3258.tar.bz2 UEFI-Lessons-cf884399031c711205f837a5b65eeeb26fee3258.zip  | |
Add lesson 61
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Diffstat (limited to 'Lessons')
| -rw-r--r-- | Lessons/Lesson_61/README.md | 420 | ||||
| -rw-r--r-- | Lessons/Lesson_61/UefiLessonsPkg/UefiLessonsPkg.dsc | 84 | ||||
| -rw-r--r-- | Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c | 123 | ||||
| -rw-r--r-- | Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf | 26 | ||||
| -rw-r--r-- | Lessons/Lesson_61/bootorder.png | bin | 0 -> 10651 bytes | |||
| -rw-r--r-- | Lessons/Lesson_61/hexedit_1.png | bin | 0 -> 5291 bytes | |||
| -rw-r--r-- | Lessons/Lesson_61/hexedit_2.png | bin | 0 -> 5255 bytes | |||
| -rw-r--r-- | Lessons/Lesson_61/hexedit_3.png | bin | 0 -> 5270 bytes | |||
| -rw-r--r-- | Lessons/Lesson_61/hexedit_help.png | bin | 0 -> 6684 bytes | 
9 files changed, 653 insertions, 0 deletions
diff --git a/Lessons/Lesson_61/README.md b/Lessons/Lesson_61/README.md new file mode 100644 index 0000000..f0ef50b --- /dev/null +++ b/Lessons/Lesson_61/README.md @@ -0,0 +1,420 @@ +UEFI shell has a `dmpstore` command that helps to see content of UEFI variables. + +If you'll look at the help of the `dmpstore` command you could see one more useful feature that this command presents. With this command it is possible to save UEFI variables to a file and load them back from such files: +``` +FS0:\> dmpstore -? +... +DMPSTORE [-all | ([variable] [-guid guid])] [-s file] +DMPSTORE [-all | ([variable] [-guid guid])] [-l file] +... +  -s       - Saves variables to a file. +  -l       - Loads and sets variables from a file. +... +``` +Let's try to use this mechanics to modify content of an existing UEFI variable. It can be a useful feature for the debug. + +In some earlier lesson we've created the `ShowBootVariables.efi` application that displays boot sources based on the content of UEFU boot variables: +``` +FS0:\> ShowBootVariables.efi +Boot0000 +UiApp +Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331) + +Boot0001 +UEFI QEMU DVD-ROM QM00003 +PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) + +Boot0002* +EFI Internal Shell +Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) + +Boot0003 +UEFI QEMU HARDDISK QM00001 +PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) +``` + +One of the variables that were parsed in this application is a `BootOrder` variable. Just in case you forgot: +``` +The BootOrder variable contains an array of UINT16’s that make up an ordered list of the Boot#### +options. The first element in the array is the value for the first logical boot option, the second element is +the value for the second logical boot option, etc. The BootOrder order list is used by the firmware’s +boot manager as the default boot order. +``` + +Print the content of the BootOrder variable +``` +FS0:\> dmpstore BootOrder +Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x08 +  00000000: 00 00 01 00 02 00 03 00-                         *........* +``` +This means that the order is: +``` +Boot0000 +Boot0001 +Boot0002 +Boot0003 +``` +Everything is like our `ShowBootVariables` application shows. + +With a help of the `dmpstore` command we can dump the content of a `BootOrder` variable to a file: +``` +FS0:\> dmpstore BootOrder -s BootOrder.bin +Save variable to file: BootOrder.bin. +Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08 +``` + +UEFI shell contains `hexedit` command in itself. With it we can see the content of a created file: + + + +`hexedit` is a hex editor, you can see its help message with a `Ctrl+E` command: + + + +Exit help with `Ctrl-W`. + +`dmpstore` command represents each variable with a following structure in a file: +``` +{ +  UINT32 NameSize;           // Size of the variable name in bytes +  UINT32 DataSize;           // Size of the variable data in bytes +  CHAR16 Name[NameSize/2];   // Variable name in CHAR16 +  EFI_GUID Guid;             // Variable GUID +  UINT32 Attributes;         // Variable attributes +  UINT8 Data[DataSize];      // Variable data +  UINT32 Crc;                // CRC32 checksum for the record +} +``` + +Here is a file content with a highlight for the structure fileds: + + + +Let's try to modify the file content changing the boot order to: +``` +Boot0001 +Boot0000 +Boot0002 +Boot0003 +``` + + + +Type `Ctrl+Q` to quit and enter `y` to save our modifications. + +If you'll try to load the changed settings you would get an error: +``` +FS0:\> dmpstore -l BootOrder.bin +Load and set variables from file: BootOrder.bin. +dmpstore: Incorrect file format. +dmpstore: No matching variables found. Guid 8BE4DF61-93CA-11D2-AA0D-00E098032B8C +``` +This is happening because `UINT32 Crc` field of the record is not longer valid for the current record content. + +Let's create an application `UpdateDmpstoreDump` to update CRC fields in the `dmpstore` dumps. + +Once again as we would parse command shell arguments it is better to create a shell application. We would read and write files, therefore include `ShellLib` to the `LibraryClasses`: +`UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf`: +``` +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = UpdateDmpstoreDump +  FILE_GUID                      = d14fe21b-7dbf-40ff-96cb-5d6f5b63cda6 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = ShellCEntryLib + +[Sources] +  UpdateDmpstoreDump.c + +[Packages] +  MdePkg/MdePkg.dec +  ShellPkg/ShellPkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellCEntryLib +  ShellLib +``` + +In the `UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c` we start from reading dump file name from the command argument and opening the file with read and write attributes: +``` +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellLib.h> +#include <Library/MemoryAllocationLib.h> + +VOID Usage() +{ +  Print(L"Recalculate CRCs for dmpstore command dump\n"); +  Print(L"\n"); +  Print(L"  UpdateDmpstoreDump <filename>\n"); +} + +INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv) +{ +  if (Argc!=2) { +    Usage(); +    return EFI_INVALID_PARAMETER; +  } + +  SHELL_FILE_HANDLE FileHandle; + +  CHAR16* Filename = Argv[1]; +  EFI_STATUS Status = ShellOpenFileByName( +    Filename, +    &FileHandle, +    EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, +    0 +  ); +  if (EFI_ERROR(Status)) { +    Print(L"Error! Can't open file %s\n", Filename); +    return Status; +  } + +  ... + +  Status = ShellCloseFile(&FileHandle); +  if (EFI_ERROR(Status)) { +    Print(L"Can't close file: %r\n", Status); +  } + +  return EFI_SUCCESS; +} +``` + +The dump file can have many records in itself and the size of a record is not a constant, but depends on the record fields. Therefore the only way to fix all record CRCs is to step throught the file records until the file end: +``` +  UINT64 FileSize; +  Status = ShellGetFileSize(FileHandle, &FileSize); +  if (EFI_ERROR(Status)) { +    Status = ShellCloseFile(&FileHandle); +    return SHELL_DEVICE_ERROR; +  } + +  UINT64 FilePos = 0; +  while (FilePos < FileSize) { +    ... +  } +``` + +Here is a code to read record data and calculate its CRC32. It is pretty similar to the one that `dmpstore` command has it its `LoadVariablesFromFilefunction` (https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c): +``` +UINTN ToReadSize; +UINT32 NameSize; +ToReadSize = sizeof(NameSize); +Status = ShellReadFile(FileHandle, &ToReadSize, &NameSize); +if (EFI_ERROR(Status) || (ToReadSize != sizeof(NameSize))) { +  Status = SHELL_VOLUME_CORRUPTED; +  break; +} +FilePos += ToReadSize; + +UINT32 DataSize; +ToReadSize = sizeof(DataSize); +Status = ShellReadFile(FileHandle, &ToReadSize, &DataSize); +if (EFI_ERROR(Status) || (ToReadSize != sizeof(DataSize))) { +  Status = SHELL_VOLUME_CORRUPTED; +  break; +} +FilePos += ToReadSize; + +UINTN RemainingSize = NameSize + +                      sizeof(EFI_GUID) + +                      sizeof(UINT32) + +                      DataSize; +UINT8* Buffer = AllocatePool(sizeof(NameSize) + sizeof(DataSize) + RemainingSize); +if (Buffer == NULL) { +  Status = SHELL_OUT_OF_RESOURCES; +  break; +} + +*(UINT32*)Buffer = NameSize; +*((UINT32*)Buffer + 1) = DataSize; + +ToReadSize = RemainingSize; +Status = ShellReadFile(FileHandle, &ToReadSize, (UINT32*)Buffer + 2); +if (EFI_ERROR(Status) || (ToReadSize != RemainingSize)) { +  Status = SHELL_VOLUME_CORRUPTED; +  FreePool (Buffer); +  break; +} +FilePos += ToReadSize; + + +UINT32 Crc32; +gBS->CalculateCrc32 ( +   Buffer, +   sizeof(NameSize) + sizeof(DataSize) + RemainingSize, +   &Crc32 +); + +... + +FreePool(Buffer); +``` + +To calculate the CRC32 checksum here we use `EFI_BOOT_SERVICES.CalculateCrc32()` function: +``` +EFI_BOOT_SERVICES.CalculateCrc32() + +Summary: +Computes and returns a 32-bit CRC for a data buffer. + +Prototype: +typedef +EFI_STATUS +(EFIAPI *EFI_CALCULATE_CRC32) + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +Parameters: +Data 		A pointer to the buffer on which the 32-bit CRC is to be computed. +DataSize 	The number of bytes in the buffer Data. +Crc32 		The 32-bit CRC that was computed for the data buffer specified by Data and DataSize. + +Description: +This function computes the 32-bit CRC for the data buffer specified by Data and DataSize. If the 32-bit CRC is computed, then it is returned in Crc32 and EFI_SUCCESS is returned. +``` + +When we have our CRC32 checksum we can update file content with a help of a `ShellWriteFile` function: +``` +UINTN ToWriteSize = sizeof(Crc32); +Status = ShellWriteFile( +  FileHandle, +  &ToWriteSize, +  &Crc32 +); +if (EFI_ERROR(Status) || (ToWriteSize != sizeof(Crc32))) { +  Print(L"Error! Not all data was written\n"); +  FreePool(Buffer); +  break; +} +FilePos += ToWriteSize; +``` + +Build our application and use it on the `dmpstore` dump: +``` +FS0:\> UpdateDmpstoreDump.efi BootOrder.bin +``` + +If you look at the file content again you would see that the CRC field has changed. + + + +Now `dmpstore -l` would finish without errors: +``` +FS0:\> dmpstore -l BootOrder.bin +Load and set variables from file: BootOrder.bin. +Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08 +``` + +You can see that variable content was modified: +``` +FS0:\> dmpstore BootOrder +Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x08 +  00000000: 01 00 00 00 02 00 03 00-                         *........* +``` + +You can also use our `ShowBootVariables.efi` application to see the changes: +``` +FS0:\> ShowBootVariables.efi +Boot0001 +UEFI QEMU DVD-ROM QM00003 +PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) + +Boot0000 +UiApp +Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331) + +Boot0002* +EFI Internal Shell +Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) + +Boot0003 +UEFI QEMU HARDDISK QM00001 +PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) +``` +__________________________ + +We can also verify that our program works in case when there are multiple variables in the dump file. + +Just in case you have some persistent variables from the previous lesson delete all the variables under our GUID with a `dmpstore -d -guid <GUID>` command: +``` +FS0:\> dmpstore -d -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 +dmpstore: No matching variables found. Guid 7C04A583-9E3E-4F1C-AD65-E05268D0B4D1 + +``` + +Create new variables and save them to a file: +``` +FS0:\> SetVariableExample.efi HelloVar nb "Hello World" +Variable HelloVar was successfully changed +FS0:\> SetVariableExample.efi ByeVar nbr "Bye World" +Variable ByeVar was successfully changed +FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 -s MyVar.bin +Save variable to file: MyVar.bin. +Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x16 +Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x1A +``` + +Use hexedit to modify `World` string in both records of a dump file. Here I've just increased each letter code with 1. + +Before: +``` +00000000 0E 00 00 00 14 00 00 00  42 00 79 00 65 00 56 00  ........B.y.e.V. +00000010 61 00 72 00 00 00 9F 82  2A BB 43 79 91 46 A0 3A  a.r...??*?Cy?F?: +00000020 F1 F4 85 19 D7 E6 07 00  00 00 42 00 79 00 65 00  ???.??....B.y.e. +00000030 20 00 57 00 6F 00 72 00  6C 00 64 00 00 00 EC 24   .W.o.r.l.d...?$ +00000040 78 CD 12 00 00 00 18 00  00 00 48 00 65 00 6C 00  x?........H.e.l. +00000050 6C 00 6F 00 56 00 61 00  72 00 00 00 9F 82 2A BB  l.o.V.a.r...??*? +00000060 43 79 91 46 A0 3A F1 F4  85 19 D7 E6 03 00 00 00  Cy?F?:???.??.... +00000070 48 00 65 00 6C 00 6C 00  6F 00 20 00 57 00 6F 00  H.e.l.l.o. .W.o. +00000080 72 00 6C 00 64 00 00 00  97 82 10 13              r.l.d...??.. +``` +After: +``` +00000000 0E 00 00 00 14 00 00 00  42 00 79 00 65 00 56 00  ........B.y.e.V. +00000010 61 00 72 00 00 00 9F 82  2A BB 43 79 91 46 A0 3A  a.r...??*?Cy?F?: +00000020 F1 F4 85 19 D7 E6 07 00  00 00 42 00 79 00 65 00  ???.??....B.y.e. +00000030 20 00 58 00 70 00 73 00  6D 00 65 00 00 00 EC 24   .X.p.s.m.e...?$ +00000040 78 CD 12 00 00 00 18 00  00 00 48 00 65 00 6C 00  x?........H.e.l. +00000050 6C 00 6F 00 56 00 61 00  72 00 00 00 9F 82 2A BB  l.o.V.a.r...??*? +00000060 43 79 91 46 A0 3A F1 F4  85 19 D7 E6 03 00 00 00  Cy?F?:???.??.... +00000070 48 00 65 00 6C 00 6C 00  6F 00 20 00 58 00 70 00  H.e.l.l.o. .X.p. +00000080 73 00 6D 00 65 00 00 00  97 82 10 13              s.m.e...??.. +``` + +Use our program to update checksums: +``` +FS0:\> UpdateDmpstoreDump.efi MyVar.bin +``` + +Now you can verify that our new dump indeed have changed both variables content: +``` +FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 +Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14 +  00000000: 42 00 79 00 65 00 20 00-57 00 6F 00 72 00 6C 00  *B.y.e. .W.o.r.l.* +  00000010: 64 00 00 00                                      *d...* +Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18 +  00000000: 48 00 65 00 6C 00 6C 00-6F 00 20 00 57 00 6F 00  *H.e.l.l.o. .W.o.* +  00000010: 72 00 6C 00 64 00 00 00-                         *r.l.d...* + +FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 -l MyVar.bin +Load and set variables from file: MyVar.bin. +Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14 +Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18 + +FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 +Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18 +  00000000: 48 00 65 00 6C 00 6C 00-6F 00 20 00 58 00 70 00  *H.e.l.l.o. .X.p.* +  00000010: 73 00 6D 00 65 00 00 00-                         *s.m.e...* +Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14 +  00000000: 42 00 79 00 65 00 20 00-58 00 70 00 73 00 6D 00  *B.y.e. .X.p.s.m.* +  00000010: 65 00 00 00                                      *e...* +``` + +Keep in mind that if you change size of the variable data, you need to change the `UINT32 DataSize` field as well. diff --git a/Lessons/Lesson_61/UefiLessonsPkg/UefiLessonsPkg.dsc b/Lessons/Lesson_61/UefiLessonsPkg/UefiLessonsPkg.dsc new file mode 100644 index 0000000..2180620 --- /dev/null +++ b/Lessons/Lesson_61/UefiLessonsPkg/UefiLessonsPkg.dsc @@ -0,0 +1,84 @@ +## +# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com> +# +# SPDX-License-Identifier: MIT +## + +[Defines] +  DSC_SPECIFICATION              = 0x0001001C +  PLATFORM_GUID                  = 3db7270f-ffac-4139-90a4-0ae68f3f8167 +  PLATFORM_VERSION               = 0.01 +  PLATFORM_NAME                  = UefiLessonsPkg +  SKUID_IDENTIFIER               = DEFAULT +  SUPPORTED_ARCHITECTURES        = X64 +  BUILD_TARGETS                  = RELEASE + + +[LibraryClasses] +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf +  DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf +  #PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf +  RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf +  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf   +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf +  #SimpleLibrary|UefiLessonsPkg/Library/SimpleLibrary/SimpleLibrary.inf +  #SimpleLibrary|UefiLessonsPkg/Library/SimpleLibraryWithConstructor/SimpleLibraryWithConstructor.inf +  SimpleLibrary|UefiLessonsPkg/Library/SimpleLibraryWithConstructorAndDestructor/SimpleLibraryWithConstructorAndDestructor.inf + +[Components] +  UefiLessonsPkg/SimplestApp/SimplestApp.inf +  UefiLessonsPkg/HelloWorld/HelloWorld.inf +  UefiLessonsPkg/ImageHandle/ImageHandle.inf +  UefiLessonsPkg/ImageInfo/ImageInfo.inf +  UefiLessonsPkg/MemoryInfo/MemoryInfo.inf +  UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf +  UefiLessonsPkg/ListVariables/ListVariables.inf +  UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf +  UefiLessonsPkg/InteractiveApp/InteractiveApp.inf +  UefiLessonsPkg/PCDLesson/PCDLesson.inf +  UefiLessonsPkg/SmbiosInfo/SmbiosInfo.inf +  UefiLessonsPkg/ShowTables/ShowTables.inf +  UefiLessonsPkg/AcpiInfo/AcpiInfo.inf +  UefiLessonsPkg/SaveBGRT/SaveBGRT.inf +  UefiLessonsPkg/ListPCI/ListPCI.inf +  UefiLessonsPkg/SimpleDriver/SimpleDriver.inf +  UefiLessonsPkg/PCIRomInfo/PCIRomInfo.inf +  UefiLessonsPkg/Library/SimpleLibrary/SimpleLibrary.inf +  UefiLessonsPkg/Library/SimpleLibraryWithConstructor/SimpleLibraryWithConstructor.inf +  UefiLessonsPkg/SimpleLibraryUser/SimpleLibraryUser.inf +  UefiLessonsPkg/SimpleClassProtocol/SimpleClassProtocol.inf +  UefiLessonsPkg/SimpleClassUser/SimpleClassUser.inf +  UefiLessonsPkg/HotKeyDriver/HotKeyDriver.inf +  UefiLessonsPkg/ShowHII/ShowHII.inf +  UefiLessonsPkg/HIIStringsC/HIIStringsC.inf +  UefiLessonsPkg/HIIStringsUNI/HIIStringsUNI.inf +  UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.inf +  UefiLessonsPkg/HIIStringsMan/HIIStringsMan.inf +  UefiLessonsPkg/HIIAddRussianFont/HIIAddRussianFont.inf +  UefiLessonsPkg/HIIAddLocalization/HIIAddLocalization.inf +  UefiLessonsPkg/AddNewLanguage/AddNewLanguage.inf +  UefiLessonsPkg/HIISimpleForm/HIISimpleForm.inf +  UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf +  UefiLessonsPkg/HIIStaticFormDriver/HIIStaticFormDriver.inf +  UefiLessonsPkg/DisplayHIIByGuid/DisplayHIIByGuid.inf +  UefiLessonsPkg/SetVariableExample/SetVariableExample.inf +  UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf + +[PcdsFixedAtBuild] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|44 + diff --git a/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c b/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c new file mode 100644 index 0000000..e926514 --- /dev/null +++ b/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com> + * + * SPDX-License-Identifier: MIT + */ + +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellLib.h> +#include <Library/MemoryAllocationLib.h> + +VOID Usage() +{ +  Print(L"Recalculate CRCs for dmpstore command dump\n"); +  Print(L"\n"); +  Print(L"  UpdateDmpstoreDump <filename>\n"); +} + +INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv) +{ +  if (Argc!=2) { +    Usage(); +    return EFI_INVALID_PARAMETER; +  } + +  SHELL_FILE_HANDLE FileHandle; + +  CHAR16* Filename = Argv[1]; +  EFI_STATUS Status = ShellOpenFileByName( +    Filename, +    &FileHandle, +    EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, +    0 +  ); +  if (EFI_ERROR(Status)) { +    Print(L"Error! Can't open file %s\n", Filename); +    return Status; +  } + +  UINT64 FileSize; +  Status = ShellGetFileSize(FileHandle, &FileSize); +  if (EFI_ERROR(Status)) { +    Status = ShellCloseFile(&FileHandle); +    return SHELL_DEVICE_ERROR; +  } + +  UINT64 FilePos = 0; +  while (FilePos < FileSize) { +    UINTN ToReadSize; +    UINT32 NameSize; +    ToReadSize = sizeof(NameSize); +    Status = ShellReadFile(FileHandle, &ToReadSize, &NameSize); +    if (EFI_ERROR(Status) || (ToReadSize != sizeof(NameSize))) { +      Status = SHELL_VOLUME_CORRUPTED; +      break; +    } +    FilePos += ToReadSize; + +    UINT32 DataSize; +    ToReadSize = sizeof(DataSize); +    Status = ShellReadFile(FileHandle, &ToReadSize, &DataSize); +    if (EFI_ERROR(Status) || (ToReadSize != sizeof(DataSize))) { +      Status = SHELL_VOLUME_CORRUPTED; +      break; +    } +    FilePos += ToReadSize; +     +    UINTN RemainingSize = NameSize + +                          sizeof(EFI_GUID) + +                          sizeof(UINT32) + +                          DataSize; +    UINT8* Buffer = AllocatePool(sizeof(NameSize) + sizeof(DataSize) + RemainingSize); +    if (Buffer == NULL) { +      Status = SHELL_OUT_OF_RESOURCES; +      break; +    } + +    *(UINT32*)Buffer = NameSize; +    *((UINT32*)Buffer + 1) = DataSize; +     +    ToReadSize = RemainingSize; +    Status = ShellReadFile(FileHandle, &ToReadSize, (UINT32*)Buffer + 2); +    if (EFI_ERROR(Status) || (ToReadSize != RemainingSize)) { +      Status = SHELL_VOLUME_CORRUPTED; +      FreePool (Buffer); +      break; +    } +    FilePos += ToReadSize; +     +     +    UINT32 Crc32; +    gBS->CalculateCrc32 ( +       Buffer, +       sizeof(NameSize) + sizeof(DataSize) + RemainingSize, +       &Crc32 +    ); + +    UINTN ToWriteSize = sizeof(Crc32); +    Status = ShellWriteFile( +      FileHandle, +      &ToWriteSize, +      &Crc32 +    ); +    if (EFI_ERROR(Status) || (ToWriteSize != sizeof(Crc32))) { +      Print(L"Error! Not all data was written\n"); +      FreePool(Buffer); +      break; +    } +    FilePos += ToWriteSize; +    FreePool(Buffer); +  } + +  if (EFI_ERROR(Status)) { +    Print(L"Error! %r\n", Status); +  } + +  Status = ShellCloseFile(&FileHandle); +  if (EFI_ERROR(Status)) { +    Print(L"Can't close file: %r\n", Status); +  } + +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf b/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf new file mode 100644 index 0000000..eef23cc --- /dev/null +++ b/Lessons/Lesson_61/UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf @@ -0,0 +1,26 @@ +## +# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com> +# +# SPDX-License-Identifier: MIT +## + +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = UpdateDmpstoreDump +  FILE_GUID                      = d14fe21b-7dbf-40ff-96cb-5d6f5b63cda6 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = ShellCEntryLib  + +[Sources] +  UpdateDmpstoreDump.c + +[Packages] +  MdePkg/MdePkg.dec +  ShellPkg/ShellPkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellCEntryLib +  ShellLib diff --git a/Lessons/Lesson_61/bootorder.png b/Lessons/Lesson_61/bootorder.png Binary files differnew file mode 100644 index 0000000..242d2b5 --- /dev/null +++ b/Lessons/Lesson_61/bootorder.png diff --git a/Lessons/Lesson_61/hexedit_1.png b/Lessons/Lesson_61/hexedit_1.png Binary files differnew file mode 100644 index 0000000..95d8def --- /dev/null +++ b/Lessons/Lesson_61/hexedit_1.png diff --git a/Lessons/Lesson_61/hexedit_2.png b/Lessons/Lesson_61/hexedit_2.png Binary files differnew file mode 100644 index 0000000..2048428 --- /dev/null +++ b/Lessons/Lesson_61/hexedit_2.png diff --git a/Lessons/Lesson_61/hexedit_3.png b/Lessons/Lesson_61/hexedit_3.png Binary files differnew file mode 100644 index 0000000..b5204ae --- /dev/null +++ b/Lessons/Lesson_61/hexedit_3.png diff --git a/Lessons/Lesson_61/hexedit_help.png b/Lessons/Lesson_61/hexedit_help.png Binary files differnew file mode 100644 index 0000000..fc04e4c --- /dev/null +++ b/Lessons/Lesson_61/hexedit_help.png  | 
