-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUtil.c
186 lines (150 loc) · 3.84 KB
/
Util.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "Util.h"
#include <Protocol/LoadedImage.h>
#include <Protocol/SimpleFileSystem.h>
#include <Guid/FileInfo.h>
#include <Library/DevicePathLib.h>
void WaitForESC(EFI_SYSTEM_TABLE* systab)
{
for (;;)
{
UINTN idx;
systab->BootServices->WaitForEvent(1, systab->ConIn->WaitForKey, &idx);
EFI_INPUT_KEY key;
systab->ConIn->ReadKeyStroke(systab->ConIn, &key);
if (key.ScanCode == SCAN_ESC)
{
break;
}
}
}
void* Allocate(UINTN size, EFI_SYSTEM_TABLE* systab)
{
void* data;
EFI_STATUS res = systab->BootServices->AllocatePool(EfiLoaderData, size,
&data);
if (res)
{
return NULL ;
}
else
{
return data;
}
}
void* AllocateACPI(UINTN size, EFI_SYSTEM_TABLE* systab)
{
void* data;
EFI_STATUS res = systab->BootServices->AllocatePool(EfiACPIReclaimMemory,
size, &data);
if (res)
{
return NULL ;
}
else
{
return data;
}
}
void Free(void* mem, EFI_SYSTEM_TABLE* systab)
{
systab->BootServices->FreePool(mem);
}
EFI_STATUS LoadFile(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* systab,
CHAR16* filename, VOID** dataPtr, UINTN* size,
EFI_DEVICE_PATH_PROTOCOL** dev_path)
{
EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID FileInfoGuid = EFI_FILE_INFO_ID;
EFI_GUID FileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
EFI_STATUS res;
EFI_BOOT_SERVICES* BS = systab->BootServices;
//get image info
EFI_LOADED_IMAGE_PROTOCOL* img_proto;
res = BS->HandleProtocol(ImageHandle, &LoadedImageProtocolGuid,
(void**) &img_proto);
if (res)
{
ErrorPrint(L"Failed to get image protocol. (Error %d)\r\n", res);
return EFI_LOAD_ERROR ;
}
EFI_HANDLE img_device_handle = img_proto->DeviceHandle;
//Get filesystem protocol from device
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs_proto;
res = BS->HandleProtocol(img_device_handle, &FileSystemGuid,
(VOID**) &fs_proto);
if (res)
{
ErrorPrint(L"Failed to get file system protocol. (Error %d)\r\n", res);
return EFI_LOAD_ERROR ;
}
//open volume
EFI_FILE_PROTOCOL* volume;
res = fs_proto->OpenVolume(fs_proto, &volume);
if (res)
{
ErrorPrint(L"Failed to open file volume. (Error %d)\r\n", res);
return EFI_LOAD_ERROR ;
}
//open file
EFI_FILE_PROTOCOL* file;
res = volume->Open(volume, &file, filename, EFI_FILE_MODE_READ, 0);
if (res)
{
//don't print error here
//ErrorPrint(L"Failed to open file '%s'. (Error %d)\r\n", filename, res);
return EFI_NOT_FOUND ;
}
//get file info, two try process
EFI_FILE_INFO* file_info = NULL;
UINTN file_info_size = 0;
res = file->GetInfo(file, &FileInfoGuid, &file_info_size, NULL );
if (res != EFI_BUFFER_TOO_SMALL )
{
ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res);
return EFI_NOT_FOUND ;
}
res = BS->AllocatePool(EfiLoaderData, file_info_size, (void**) &file_info);
if (res)
{
ErrorPrint(L"Failed to allocate file info memory. (Error %d)\r\n", res);
return EFI_OUT_OF_RESOURCES ;
}
res = file->GetInfo(file, &FileInfoGuid, &file_info_size,
(void*) file_info);
if (res)
{
BS->FreePool(file_info);
ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res);
return EFI_NOT_FOUND ;
}
if (dev_path != NULL )
{
*dev_path = FileDevicePath(img_device_handle, filename);
}
UINT64 file_size = file_info->FileSize;
BS->FreePool(file_info);
file_info = NULL;
void* data = NULL;
res = BS->AllocatePool(EfiLoaderData, file_size, (void**) &data);
if (res)
{
ErrorPrint(L"Failed to allocate file data memory. (Error %d)\r\n", res);
return EFI_OUT_OF_RESOURCES ;
}
//read the file
res = file->Read(file, &file_size, (void*) data);
if (res)
{
BS->FreePool(data);
ErrorPrint(L"Failed to read file '%s'. (Error %d)\r\n", filename, res);
return EFI_NOT_FOUND ;
}
//close the file
file->Close(file);
volume->Close(volume);
//set the pointer and data size
*dataPtr = data;
*size = file_size;
//return success
return EFI_SUCCESS;
}