OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
ext4read.c
Go to the documentation of this file.
1
6#include <Ext4Dxe.h>
7
8#include <string.h>
9#include <UserFile.h>
10#include <UserGlobalVar.h>
11#include <UserMemory.h>
13
14STATIC FILE *mImageFp;
15STATIC UINT64 mImageSize;
16STATIC EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mEfiSfsInterface;
17
18void
20 const void *data,
21 size_t size
22 )
23{
24 char ascii[17];
25 size_t i, j;
26
27 ascii[16] = '\0';
28 for (i = 0; i < size; ++i) {
29 printf ("%02X ", ((unsigned char *)data)[i]);
30 if ((((unsigned char *)data)[i] >= ' ') && (((unsigned char *)data)[i] <= '~')) {
31 ascii[i % 16] = ((unsigned char *)data)[i];
32 } else {
33 ascii[i % 16] = '.';
34 }
35
36 if (((i + 1) % 8 == 0) || (i + 1 == size)) {
37 printf (" ");
38 if ((i + 1) % 16 == 0) {
39 printf ("| %s \n", ascii);
40 } else if (i + 1 == size) {
41 ascii[(i + 1) % 16] = '\0';
42 if ((i + 1) % 16 <= 8) {
43 printf (" ");
44 }
45
46 for (j = (i + 1) % 16; j < 16; ++j) {
47 printf (" ");
48 }
49
50 printf ("| %s \n", ascii);
51 }
52 }
53 }
54}
55
65EFI_STATUS
67 EFI_HANDLE DriverHandle
68 )
69{
71 return EFI_SUCCESS;
72}
73
85INTN
87 IN CHAR16 *Str1,
88 IN CHAR16 *Str2
89 )
90{
91 return EngStriColl (NULL, Str1, Str2);
92}
93
94EFI_STATUS
95EFIAPI
97 IN OUT EFI_HANDLE *Handle,
98 ...
99 )
100{
101 VA_LIST Args;
102 EFI_STATUS Status;
103 EFI_GUID *Protocol;
104 VOID *Interface;
105
106 if (Handle == NULL) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 VA_START (Args, Handle);
111 for (Status = EFI_SUCCESS; !EFI_ERROR (Status);) {
112 //
113 // If protocol is NULL, then it's the end of the list
114 //
115 Protocol = VA_ARG (Args, EFI_GUID *);
116 if (Protocol == NULL) {
117 break;
118 }
119
120 Interface = VA_ARG (Args, VOID *);
121
122 //
123 // If this is Sfs protocol then save interface into global state
124 //
126 mEfiSfsInterface = Interface;
127 }
128 }
129
130 VA_END (Args);
131
132 return Status;
133}
134
135VOID
137 IN CHAR16 *FileName,
138 IN EXT4_PARTITION *Part
139 )
140{
141 FreePool (FileName);
142
143 if (Part != NULL) {
144 if (Part->DiskIo != NULL) {
145 FreePool (Part->DiskIo);
146 }
147
148 if (Part->BlockIo != NULL) {
149 if (Part->BlockIo->Media != NULL) {
150 FreePool (Part->BlockIo->Media);
151 }
152
153 FreePool (Part->BlockIo);
154 }
155
156 if (Part->Root != NULL) {
157 Ext4UnmountAndFreePartition (Part);
158 } else if (Part != NULL) {
159 FreePool (Part);
160 }
161 }
162}
163
164EFI_STATUS
165EFIAPI
167 IN EFI_DISK_IO_PROTOCOL *This,
168 IN UINT32 MediaId,
169 IN UINT64 Offset,
170 IN UINTN BufferSize,
171 OUT VOID *Buffer
172 )
173{
174 if (Buffer == NULL) {
175 return EFI_INVALID_PARAMETER;
176 }
177
178 if (Offset > mImageSize) {
179 return EFI_INVALID_PARAMETER;
180 }
181
182 if ((mImageSize - Offset) < BufferSize) {
183 return EFI_INVALID_PARAMETER;
184 }
185
186 if (fseek (mImageFp, Offset, SEEK_SET) != 0) {
187 return EFI_VOLUME_CORRUPTED;
188 }
189
190 if (fread (Buffer, BufferSize, 1, mImageFp) != 1) {
191 return EFI_VOLUME_CORRUPTED;
192 }
193
194 return EFI_SUCCESS;
195}
196
197int
199 int argc,
200 char **argv
201 )
202{
203 FILE *ImageFp;
204 UINT64 ImageSize;
205 EFI_STATUS Status;
206 EFI_FILE_INFO *Info;
207 UINTN Len;
208 CHAR16 *FileName;
209 EFI_FILE_PROTOCOL *This;
210 EFI_DISK_IO_PROTOCOL *DiskIo;
211 EFI_BLOCK_IO_PROTOCOL *BlockIo;
212 EFI_HANDLE DeviceHandle;
213 EXT4_PARTITION *Part;
214 UINTN BufferSize;
215 VOID *Buffer;
216 VOID *TmpBuffer;
217 EFI_FILE_PROTOCOL *NewHandle;
218
219 SetPoolAllocationSizeLimit (BASE_1GB | BASE_2GB);
220
221 DeviceHandle = (EFI_HANDLE)0xDEADBEAFULL;
222
223 gBS->InstallMultipleProtocolInterfaces = WrapInstallMultipleProtocolInterfaces;
224
225 if ((argc < 2) || (argc != 3)) {
226 DEBUG ((DEBUG_ERROR, "Usage: ./ext4read ([image path] [file path])*\n"));
227 return -1;
228 }
229
230 //
231 // Open Ext4 user image
232 //
233 ImageFp = fopen (argv[1], "rb");
234
235 if (ImageFp == NULL) {
236 DEBUG ((DEBUG_ERROR, "Can't open image file\n"));
237 return EXIT_FAILURE;
238 }
239
240 if (fseek (ImageFp, 0, SEEK_END) != 0) {
241 DEBUG ((DEBUG_ERROR, "Can't set file position\n"));
242 fclose (ImageFp);
243 return EXIT_FAILURE;
244 }
245
246 ImageSize = ftell (ImageFp);
247 if (ImageSize <= 0) {
248 DEBUG ((DEBUG_ERROR, "Incorrect file size\n"));
249 fclose (ImageFp);
250 return EXIT_FAILURE;
251 }
252
253 if (fseek (ImageFp, 0, SEEK_SET) != 0) {
254 DEBUG ((DEBUG_ERROR, "Can't rewind file position to the start\n"));
255 fclose (ImageFp);
256 return EXIT_FAILURE;
257 }
258
259 mImageFp = ImageFp;
260 mImageSize = ImageSize;
261
262 //
263 // Prepare Filename to read from partition
264 //
265 FileName = AllocateZeroPool (strlen (argv[2]) * sizeof (CHAR16) + 1);
266
267 if (FileName == NULL) {
268 DEBUG ((DEBUG_ERROR, "Can't allocate space for unicode filename\n"));
269 return EXIT_FAILURE;
270 }
271
272 Status = AsciiStrToUnicodeStrS (argv[2], FileName, strlen (argv[2]) + 1);
273 if (EFI_ERROR (Status)) {
274 DEBUG ((DEBUG_ERROR, "Can't convert given filename into UnicodeStr\n"));
275 fclose (ImageFp);
276 FreePool (FileName);
277 return EXIT_FAILURE;
278 }
279
280 //
281 // Construct BlockIo and DiskIo interfaces
282 //
283 DiskIo = AllocateZeroPool (sizeof (EFI_DISK_IO_PROTOCOL));
284 if (DiskIo == NULL) {
285 fclose (ImageFp);
286 FreePool (FileName);
287 return EXIT_FAILURE;
288 }
289
290 DiskIo->ReadDisk = UserReadDisk;
291
292 BlockIo = AllocateZeroPool (sizeof (EFI_BLOCK_IO_PROTOCOL));
293 if (BlockIo == NULL) {
294 fclose (ImageFp);
295 FreePool (FileName);
296 FreePool (DiskIo);
297 return EXIT_FAILURE;
298 }
299
300 BlockIo->Media = AllocateZeroPool (sizeof (EFI_BLOCK_IO_MEDIA));
301 if (BlockIo->Media == NULL) {
302 fclose (ImageFp);
303 FreePool (FileName);
304 FreePool (DiskIo);
305 FreePool (BlockIo);
306 return EXIT_FAILURE;
307 }
308
309 //
310 // Check Ext4 SuperBlock magic like it done
311 // in Ext4IsBindingSupported routine
312 //
313 if (!Ext4SuperblockCheckMagic (DiskIo, BlockIo)) {
314 DEBUG ((DEBUG_WARN, "[ext4] Superblock contains bad magic \n"));
315 return EXIT_FAILURE;
316 }
317
318 //
319 // Open partition
320 //
321 Status = Ext4OpenPartition (DeviceHandle, DiskIo, NULL, BlockIo);
322
323 if (EFI_ERROR (Status)) {
324 DEBUG ((DEBUG_ERROR, "[ext4] Error mounting: %r\n", Status));
325 fclose (ImageFp);
326 FreePool (FileName);
327 FreePool (BlockIo->Media);
328 FreePool (BlockIo);
329 FreePool (DiskIo);
330 return EXIT_FAILURE;
331 }
332
333 Part = (EXT4_PARTITION *)mEfiSfsInterface;
334
335 This = (EFI_FILE_PROTOCOL *)Part->Root;
336
337 Status = Ext4Open (This, &NewHandle, FileName, EFI_FILE_MODE_READ, 0);
338 if (EFI_ERROR (Status)) {
339 DEBUG ((DEBUG_ERROR, "[ext4] Couldn't open file %s \n", FileName));
340 return EXIT_FAILURE;
341 }
342
343 //
344 // Get FileInfo
345 //
346 Len = 0;
347 Info = NULL;
348 Status = Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info);
349 if (Status == EFI_BUFFER_TOO_SMALL) {
350 Info = AllocateZeroPool (Len);
351 if (Info == NULL) {
352 fclose (ImageFp);
353 FreeAll (FileName, Part);
354 return EXIT_FAILURE;
355 }
356
357 Status = Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info);
358 if (EFI_ERROR (Status)) {
359 DEBUG ((DEBUG_ERROR, "Couldn't get file information \n"));
360 FreePool (Info);
361 fclose (ImageFp);
362 FreeAll (FileName, Part);
363 return EXIT_FAILURE;
364 }
365 }
366
367 Buffer = AllocateZeroPool (Info->FileSize);
368 BufferSize = Info->FileSize;
369 if (Buffer == NULL) {
370 FreePool (Info);
371 fclose (ImageFp);
372 FreeAll (FileName, Part);
373 return EXIT_FAILURE;
374 }
375
376 //
377 // Read file from image
378 //
379 Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer);
380 if (Status == EFI_BUFFER_TOO_SMALL) {
381 TmpBuffer = ReallocatePool (Info->FileSize, BufferSize, Buffer);
382 if (TmpBuffer == NULL) {
383 FreePool (Buffer);
384 FreePool (Info);
385 fclose (ImageFp);
386 FreeAll (FileName, Part);
387 return EXIT_FAILURE;
388 }
389
390 Buffer = TmpBuffer;
391
392 Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer);
393 if (EFI_ERROR (Status)) {
394 DEBUG ((DEBUG_WARN, "Couldn't read file with Status: %r \n", Status));
395 FreePool (Info);
396 fclose (ImageFp);
397 FreeAll (FileName, Part);
398 return EXIT_FAILURE;
399 }
400 }
401
402 FreePool (Info);
403
404 //
405 // Print file contents
406 //
407 if (Buffer != NULL) {
408 PrintHex (Buffer, BufferSize);
409 }
410
411 FreePool (Buffer);
412 fclose (ImageFp);
413 FreeAll (FileName, Part);
414 return EXIT_SUCCESS;
415}
UINT32 size
EFI_BOOT_SERVICES * gBS
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
VOID OcUnicodeCollationInitializeMappingTables(VOID)
INTN EFIAPI EngStriColl(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *Str1, IN CHAR16 *Str2)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_GUID gEfiFileInfoGuid
EFI_GUID gEfiSimpleFileSystemProtocolGuid
VOID SetPoolAllocationSizeLimit(UINTN AllocationSize)
#define Len
Definition deflate.h:82
STATIC EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * mEfiSfsInterface
Definition ext4read.c:16
STATIC FILE * mImageFp
Definition ext4read.c:14
void PrintHex(const void *data, size_t size)
Definition ext4read.c:19
EFI_STATUS EFIAPI WrapInstallMultipleProtocolInterfaces(IN OUT EFI_HANDLE *Handle,...)
Definition ext4read.c:96
EFI_STATUS Ext4InitialiseUnicodeCollation(EFI_HANDLE DriverHandle)
Definition ext4read.c:66
STATIC UINT64 mImageSize
Definition ext4read.c:15
EFI_STATUS EFIAPI UserReadDisk(IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN UINTN BufferSize, OUT VOID *Buffer)
Definition ext4read.c:166
VOID FreeAll(IN CHAR16 *FileName, IN EXT4_PARTITION *Part)
Definition ext4read.c:136
INTN Ext4StrCmpInsensitive(IN CHAR16 *Str1, IN CHAR16 *Str2)
Definition ext4read.c:86
int ENTRY_POINT(void)