-
Notifications
You must be signed in to change notification settings - Fork 4
/
DumpHii.c
130 lines (108 loc) · 4.49 KB
/
DumpHii.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/** @file
Copyright (c) 2022, Peter Kirmeier <[email protected]>. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "DumpHii.h"
EFI_HII_DATABASE_PROTOCOL * pHiiDbProtocol;
/**
Main entry point of the dynamic Shell extension driver.
@param[in] ImageHandle The firmware allocated handle for the present driver UEFI image.
@param[in] *SystemTable A pointer to the EFI System table.
@retval EFI_SUCCESS The driver was initialized.
@retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated or
there was not enough memory in pool to install
the Shell Dynamic Command protocol.
@retval EFI_LOAD_ERROR Unable to add the HII package.
**/
EFI_STATUS
EFIAPI
DumpHiiEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_BOOT_SERVICES * pBS = SystemTable->BootServices;
EFI_STATUS Status;
UINTN HiiPkgListSize = 0;
EFI_HII_PACKAGE_LIST_HEADER * pHiiPkgLists = NULL;
EFI_HII_PACKAGE_LIST_HEADER * pHiiPkgListEntry;
UINTN PkgCount = 0;
UINTN PkgCountOk = 0;
DEBUG((EFI_D_INFO, "DumpHiiEntryPoint()\n"));
Print(L" Running Dump HII v1.1\n by Peter Kirmeier\n https://github.com/topeterk/DumpHii \n\n");
if (PcdGetBool(PcdShellLibAutoInitialize) == 0)
{
// We are most likely compiled within shell package, but we build an external application.
// So, if PCD is set to build shell internal tools, we have to call constructor on our own.
// Basically this allows us to build shell applications using ShellLib together with the shell.
ShellLibConstructorWorker(ImageHandle, SystemTable);
}
Status = pBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, &pHiiDbProtocol);
if (EFI_ERROR(Status))
{
DEBUG((EFI_D_WARN, "Cannot found HII database protocol - %r \n", Status));
return EFI_DEVICE_ERROR;
}
// 1st get all packages
Status = pHiiDbProtocol->ExportPackageLists(
pHiiDbProtocol,
NULL,
&HiiPkgListSize,
pHiiPkgLists);
if (EFI_BUFFER_TOO_SMALL != Status)
{
DEBUG((EFI_D_ERROR, "Could not get package list size %r\n", Status));
return EFI_PROTOCOL_ERROR;
}
Status = pBS->AllocatePool(EfiBootServicesData, HiiPkgListSize, &pHiiPkgLists);
if (EFI_ERROR(Status))
{
DEBUG((EFI_D_ERROR, "Could not allocate package list %r\n", Status));
return EFI_OUT_OF_RESOURCES;
}
Status = pHiiDbProtocol->ExportPackageLists(
pHiiDbProtocol,
NULL,
&HiiPkgListSize,
pHiiPkgLists);
if (EFI_ERROR(Status))
{
DEBUG((EFI_D_ERROR, "Could not receive package list %r\n", Status));
pBS->FreePool(pHiiPkgLists);
return EFI_PROTOCOL_ERROR;
}
// 2nd iterate packages and store them in files
for (pHiiPkgListEntry = pHiiPkgLists; (UINTN)pHiiPkgListEntry < ((UINTN)pHiiPkgLists) + HiiPkgListSize; pHiiPkgListEntry = (EFI_HII_PACKAGE_LIST_HEADER*)((UINTN)pHiiPkgListEntry + pHiiPkgListEntry->PackageLength))
{
SHELL_FILE_HANDLE FileHandle;
UINTN size = pHiiPkgListEntry->PackageLength - sizeof(*pHiiPkgListEntry);
CHAR16 FileName[64];
PkgCount++;
UnicodeSPrint(FileName, sizeof(FileName), L"HPK\\%g.hpk", &pHiiPkgListEntry->PackageListGuid);
Print(L"Dumping package to \"%s\"... ", FileName);
Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
if (EFI_ERROR(Status))
{
Print(L"Failed (Cannot open file for writing = %r)\n", Status);
DEBUG((EFI_D_ERROR, "Cannot open file for writing \"%s\" %r\n", FileName, Status));
continue;
}
Status = ShellWriteFile(FileHandle, &size, (UINTN*)(pHiiPkgListEntry+1));
if (EFI_ERROR(Status))
{
Print(L"Failed (Writing error = %r)\n", Status);
DEBUG((EFI_D_ERROR, "Cannot wrtie to file \"%s\" %r\n", FileName, Status));
}
ShellCloseFile(&FileHandle);
Print(L"Done!\n", Status);
PkgCountOk++;
}
pBS->FreePool(pHiiPkgLists);
Print(L"Result: %d of %d packages sucessfully dumped!\n", PkgCountOk, PkgCount);
return PkgCount == PkgCountOk ? EFI_SUCCESS : EFI_DEVICE_ERROR;
}