]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
SemihostFs: Fix check for read-only file or file-open
[mirror_edk2.git] / ArmPkg / Filesystem / SemihostFs / Arm / SemihostFs.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Support a Semi Host file system over a debuggers JTAG\r
3\r
d6ebcab7 4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
09f2cf82 5 Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
c63626b7 6\r
d6ebcab7 7 This program and the accompanying materials\r
2ef2b01e
A
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Uefi.h>\r
18\r
19#include <Guid/FileInfo.h>\r
20#include <Guid/FileSystemInfo.h>\r
09f2cf82 21#include <Guid/FileSystemVolumeLabelInfo.h>\r
2ef2b01e
A
22\r
23#include <Library/BaseLib.h>\r
24#include <Library/BaseMemoryLib.h> \r
25#include <Library/DebugLib.h>\r
26#include <Library/MemoryAllocationLib.h>\r
27#include <Library/SemihostLib.h>\r
28#include <Library/UefiBootServicesTableLib.h>\r
29#include <Library/UefiLib.h>\r
30\r
31#include <Protocol/DevicePath.h>\r
32#include <Protocol/SimpleFileSystem.h>\r
33\r
34#include "SemihostFs.h"\r
35\r
09f2cf82 36#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"\r
37\r
38STATIC CHAR16 *mSemihostFsLabel;\r
2ef2b01e
A
39\r
40EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {\r
41 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,\r
42 VolumeOpen\r
43};\r
44\r
45EFI_FILE gSemihostFsFile = {\r
46 EFI_FILE_PROTOCOL_REVISION,\r
47 FileOpen,\r
48 FileClose,\r
49 FileDelete,\r
50 FileRead,\r
51 FileWrite,\r
52 FileGetPosition,\r
53 FileSetPosition,\r
54 FileGetInfo,\r
55 FileSetInfo,\r
56 FileFlush\r
57};\r
58\r
59//\r
60// Device path for SemiHosting. It contains our autogened Caller ID GUID.\r
61//\r
62typedef struct {\r
63 VENDOR_DEVICE_PATH Guid;\r
64 EFI_DEVICE_PATH_PROTOCOL End;\r
65} SEMIHOST_DEVICE_PATH;\r
66\r
67SEMIHOST_DEVICE_PATH gDevicePath = {\r
68 {\r
69 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0 },\r
70 EFI_CALLER_ID_GUID\r
71 },\r
72 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}\r
73};\r
74\r
75typedef struct {\r
09f2cf82 76 LIST_ENTRY Link;\r
77 UINT64 Signature;\r
78 EFI_FILE File;\r
79 CHAR8 *FileName;\r
80 UINT64 OpenMode;\r
81 UINT32 Position;\r
82 UINTN SemihostHandle;\r
83 BOOLEAN IsRoot;\r
84 EFI_FILE_INFO Info;\r
2ef2b01e
A
85} SEMIHOST_FCB;\r
86\r
87#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )\r
88#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)\r
89#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);\r
90\r
91EFI_HANDLE gInstallHandle = NULL;\r
92LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);\r
93\r
94SEMIHOST_FCB *\r
95AllocateFCB (\r
96 VOID\r
97 )\r
98{\r
99 SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));\r
100\r
101 if (Fcb != NULL) {\r
102 CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));\r
103 Fcb->Signature = SEMIHOST_FCB_SIGNATURE;\r
104 }\r
105\r
106 return Fcb;\r
107}\r
108\r
109VOID\r
110FreeFCB (\r
111 IN SEMIHOST_FCB *Fcb\r
112 )\r
113{\r
114 // Remove Fcb from gFileList.\r
115 RemoveEntryList (&Fcb->Link);\r
116\r
117 // To help debugging...\r
118 Fcb->Signature = 0;\r
119\r
120 FreePool (Fcb);\r
121}\r
122\r
123\r
124\r
125EFI_STATUS\r
126VolumeOpen (\r
127 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
128 OUT EFI_FILE **Root\r
129 )\r
130{\r
131 SEMIHOST_FCB *RootFcb = NULL;\r
132 \r
133 if (Root == NULL) {\r
134 return EFI_INVALID_PARAMETER;\r
135 }\r
136\r
137 RootFcb = AllocateFCB ();\r
138 if (RootFcb == NULL) {\r
139 return EFI_OUT_OF_RESOURCES;\r
140 }\r
141 \r
142 RootFcb->IsRoot = TRUE;\r
09f2cf82 143 RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;\r
2ef2b01e
A
144\r
145 InsertTailList (&gFileList, &RootFcb->Link);\r
146\r
147 *Root = &RootFcb->File;\r
148\r
149 return EFI_SUCCESS;\r
150}\r
151\r
152EFI_STATUS\r
153FileOpen (\r
154 IN EFI_FILE *File,\r
155 OUT EFI_FILE **NewHandle,\r
156 IN CHAR16 *FileName,\r
157 IN UINT64 OpenMode,\r
158 IN UINT64 Attributes\r
159 )\r
160{\r
161 SEMIHOST_FCB *FileFcb = NULL;\r
162 EFI_STATUS Status = EFI_SUCCESS;\r
c63626b7 163 UINTN SemihostHandle;\r
2ef2b01e 164 CHAR8 *AsciiFileName;\r
2ef2b01e
A
165 UINT32 SemihostMode;\r
166 BOOLEAN IsRoot;\r
09f2cf82 167 UINTN Length;\r
2ef2b01e
A
168\r
169 if ((FileName == NULL) || (NewHandle == NULL)) {\r
170 return EFI_INVALID_PARAMETER;\r
171 }\r
172\r
09f2cf82 173 // Semihosting does not support directories\r
174 if (Attributes & EFI_FILE_DIRECTORY) {\r
175 return EFI_UNSUPPORTED;\r
176 }\r
177\r
ed2405a0 178 // Semihost interface requires ASCII filenames\r
179 AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));\r
2ef2b01e
A
180 if (AsciiFileName == NULL) {\r
181 return EFI_OUT_OF_RESOURCES;\r
182 }\r
ed2405a0 183 UnicodeStrToAsciiStr (FileName, AsciiFileName);\r
2ef2b01e 184\r
1ea31716 185 if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||\r
186 (AsciiStrCmp (AsciiFileName, "/") == 0) ||\r
187 (AsciiStrCmp (AsciiFileName, "") == 0) ||\r
188 (AsciiStrCmp (AsciiFileName, ".") == 0)) {\r
189 // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory\r
2ef2b01e
A
190 IsRoot = TRUE;\r
191\r
192 // Root directory node doesn't have a name.\r
193 FreePool (AsciiFileName);\r
194 AsciiFileName = NULL;\r
195 } else {\r
196 // Translate EFI_FILE_MODE into Semihosting mode\r
197 if (OpenMode & EFI_FILE_MODE_WRITE) {\r
198 SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY;\r
199 } else if (OpenMode & EFI_FILE_MODE_READ) {\r
200 SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;\r
201 } else {\r
202 return EFI_UNSUPPORTED;\r
203 }\r
204\r
205 // Add the creation flag if necessary\r
206 if (OpenMode & EFI_FILE_MODE_CREATE) {\r
207 SemihostMode |= SEMIHOST_FILE_MODE_CREATE;\r
208 }\r
209\r
210 // Call the semihosting interface to open the file.\r
211 Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);\r
212 if (EFI_ERROR(Status)) {\r
213 return Status;\r
214 }\r
215 \r
216 IsRoot = FALSE;\r
217 }\r
218\r
219 // Allocate a control block and fill it\r
220 FileFcb = AllocateFCB ();\r
221 if (FileFcb == NULL) {\r
222 return EFI_OUT_OF_RESOURCES;\r
223 }\r
224\r
225 FileFcb->FileName = AsciiFileName;\r
226 FileFcb->SemihostHandle = SemihostHandle;\r
227 FileFcb->Position = 0;\r
228 FileFcb->IsRoot = IsRoot;\r
09f2cf82 229 FileFcb->OpenMode = OpenMode;\r
230\r
231 if (!IsRoot) {\r
232 Status = SemihostFileLength (SemihostHandle, &Length);\r
233 if (EFI_ERROR(Status)) {\r
234 return Status;\r
235 }\r
236\r
237 FileFcb->Info.FileSize = Length;\r
238 FileFcb->Info.PhysicalSize = Length;\r
239 FileFcb->Info.Attribute = Attributes;\r
240 }\r
2ef2b01e
A
241\r
242 InsertTailList (&gFileList, &FileFcb->Link);\r
243\r
244 *NewHandle = &FileFcb->File;\r
245\r
246 return Status;\r
247}\r
248\r
249\r
250EFI_STATUS\r
251FileClose (\r
252 IN EFI_FILE *File\r
253 )\r
254{\r
255 SEMIHOST_FCB *Fcb = NULL;\r
256 EFI_STATUS Status = EFI_SUCCESS;\r
257\r
258 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
259\r
260 if (Fcb->IsRoot == TRUE) {\r
261 FreeFCB (Fcb);\r
262 Status = EFI_SUCCESS;\r
263 } else {\r
264 Status = SemihostFileClose (Fcb->SemihostHandle);\r
265 if (!EFI_ERROR(Status)) {\r
266 FreePool (Fcb->FileName);\r
267 FreeFCB (Fcb);\r
268 }\r
269 }\r
270 \r
271 return Status;\r
272}\r
273\r
274EFI_STATUS\r
275FileDelete (\r
276 IN EFI_FILE *File\r
277 )\r
278{\r
279 SEMIHOST_FCB *Fcb = NULL;\r
280 EFI_STATUS Status;\r
281 CHAR8 *FileName;\r
282 UINTN NameSize;\r
283\r
284 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
285\r
3bb46df2 286 if (!Fcb->IsRoot) {\r
287 // Get the filename from the Fcb\r
288 NameSize = AsciiStrLen (Fcb->FileName);\r
289 FileName = AllocatePool (NameSize + 1);\r
2ef2b01e 290\r
3bb46df2 291 AsciiStrCpy (FileName, Fcb->FileName);\r
2ef2b01e 292\r
3bb46df2 293 // Close the file if it's open. Disregard return status,\r
294 // since it might give an error if the file isn't open.\r
295 File->Close (File);\r
296\r
297 // Call the semihost interface to delete the file.\r
298 Status = SemihostFileRemove (FileName);\r
09f2cf82 299 if (EFI_ERROR(Status)) {\r
300 Status = EFI_WARN_DELETE_FAILURE;\r
301 }\r
3bb46df2 302 } else {\r
09f2cf82 303 Status = EFI_WARN_DELETE_FAILURE;\r
3bb46df2 304 }\r
2ef2b01e
A
305\r
306 return Status;\r
307}\r
308\r
309EFI_STATUS\r
310FileRead (\r
311 IN EFI_FILE *File,\r
312 IN OUT UINTN *BufferSize,\r
313 OUT VOID *Buffer\r
314 )\r
315{\r
316 SEMIHOST_FCB *Fcb = NULL;\r
317 EFI_STATUS Status;\r
318\r
319 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
320\r
321 if (Fcb->IsRoot == TRUE) {\r
b1cab81f 322 // By design, the Semihosting feature does not allow to list files on the host machine.\r
2ef2b01e
A
323 Status = EFI_UNSUPPORTED;\r
324 } else {\r
325 Status = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);\r
326 if (!EFI_ERROR (Status)) {\r
327 Fcb->Position += *BufferSize;\r
328 }\r
329 }\r
330\r
331 return Status;\r
332}\r
333\r
334EFI_STATUS\r
335FileWrite (\r
336 IN EFI_FILE *File,\r
337 IN OUT UINTN *BufferSize,\r
338 IN VOID *Buffer\r
339 )\r
340{\r
341 SEMIHOST_FCB *Fcb = NULL;\r
342 EFI_STATUS Status;\r
343 UINTN WriteSize = *BufferSize;\r
344\r
345 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
346\r
09f2cf82 347 // We cannot write a read-only file\r
cc271ec3
OM
348 if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)\r
349 || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {\r
09f2cf82 350 return EFI_ACCESS_DENIED;\r
351 }\r
352\r
2ef2b01e
A
353 Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);\r
354\r
355 if (!EFI_ERROR(Status)) {\r
356 // Semihost write return the number of bytes *NOT* written.\r
357 *BufferSize -= WriteSize;\r
358 Fcb->Position += *BufferSize;\r
359 }\r
360 \r
361 return Status;\r
362}\r
363\r
364EFI_STATUS\r
365FileGetPosition (\r
366 IN EFI_FILE *File,\r
367 OUT UINT64 *Position\r
368 )\r
369{\r
370 SEMIHOST_FCB *Fcb = NULL;\r
371 \r
372 if (Position == NULL) {\r
373 return EFI_INVALID_PARAMETER;\r
374 }\r
375\r
376 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
377\r
378 *Position = Fcb->Position;\r
379\r
380 return EFI_SUCCESS;\r
381}\r
382\r
383EFI_STATUS\r
384FileSetPosition (\r
385 IN EFI_FILE *File,\r
386 IN UINT64 Position\r
387 )\r
388{\r
389 SEMIHOST_FCB *Fcb = NULL;\r
c63626b7 390 UINTN Length;\r
2ef2b01e
A
391 EFI_STATUS Status;\r
392\r
393 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
394\r
3bb46df2 395 if (!Fcb->IsRoot) {\r
396 Status = SemihostFileLength (Fcb->SemihostHandle, &Length);\r
397 if (!EFI_ERROR(Status) && (Length < Position)) {\r
398 Position = Length;\r
399 }\r
2ef2b01e 400\r
3bb46df2 401 Status = SemihostFileSeek (Fcb->SemihostHandle, (UINT32)Position);\r
402 if (!EFI_ERROR(Status)) {\r
403 Fcb->Position = Position;\r
404 }\r
405 } else {\r
2ef2b01e 406 Fcb->Position = Position;\r
3bb46df2 407 Status = EFI_SUCCESS;\r
2ef2b01e
A
408 }\r
409\r
410 return Status;\r
411}\r
412\r
413STATIC\r
414EFI_STATUS\r
415GetFileInfo (\r
416 IN SEMIHOST_FCB *Fcb,\r
417 IN OUT UINTN *BufferSize,\r
418 OUT VOID *Buffer\r
419 )\r
420{\r
421 EFI_FILE_INFO *Info = NULL;\r
422 UINTN NameSize = 0;\r
423 UINTN ResultSize;\r
424 UINTN Index;\r
2ef2b01e
A
425\r
426 if (Fcb->IsRoot == TRUE) {\r
427 ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);\r
428 } else {\r
429 NameSize = AsciiStrLen (Fcb->FileName) + 1;\r
430 ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);\r
431 }\r
432\r
433 if (*BufferSize < ResultSize) {\r
434 *BufferSize = ResultSize;\r
435 return EFI_BUFFER_TOO_SMALL;\r
436 }\r
437\r
438 Info = Buffer;\r
439\r
09f2cf82 440 // Copy the current file info\r
441 CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO);\r
2ef2b01e
A
442\r
443 // Fill in the structure\r
444 Info->Size = ResultSize;\r
445\r
446 if (Fcb->IsRoot == TRUE) {\r
2ef2b01e
A
447 Info->FileName[0] = L'\0';\r
448 } else {\r
2ef2b01e
A
449 for (Index = 0; Index < NameSize; Index++) {\r
450 Info->FileName[Index] = Fcb->FileName[Index]; \r
451 }\r
452 }\r
453\r
2ef2b01e
A
454 *BufferSize = ResultSize; \r
455\r
456 return EFI_SUCCESS;\r
457}\r
458\r
459STATIC\r
460EFI_STATUS\r
461GetFilesystemInfo (\r
462 IN SEMIHOST_FCB *Fcb,\r
463 IN OUT UINTN *BufferSize,\r
464 OUT VOID *Buffer\r
465 )\r
466{\r
467 EFI_FILE_SYSTEM_INFO *Info = NULL;\r
468 EFI_STATUS Status;\r
09f2cf82 469 UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (mSemihostFsLabel);\r
2ef2b01e 470 \r
09f2cf82 471 if (*BufferSize >= ResultSize) {\r
2ef2b01e
A
472 ZeroMem (Buffer, ResultSize);\r
473 Status = EFI_SUCCESS;\r
474 \r
475 Info = Buffer;\r
476\r
477 Info->Size = ResultSize;\r
478 Info->ReadOnly = FALSE;\r
479 Info->VolumeSize = 0;\r
480 Info->FreeSpace = 0;\r
481 Info->BlockSize = 0;\r
482\r
09f2cf82 483 StrCpy (Info->VolumeLabel, mSemihostFsLabel);\r
2ef2b01e
A
484 } else {\r
485 Status = EFI_BUFFER_TOO_SMALL;\r
486 }\r
487\r
488 *BufferSize = ResultSize; \r
489 return Status;\r
490}\r
491\r
492EFI_STATUS\r
493FileGetInfo (\r
494 IN EFI_FILE *File,\r
495 IN EFI_GUID *InformationType,\r
496 IN OUT UINTN *BufferSize,\r
497 OUT VOID *Buffer\r
498 )\r
499{\r
09f2cf82 500 SEMIHOST_FCB *Fcb;\r
501 EFI_STATUS Status;\r
502 UINTN ResultSize;\r
2ef2b01e
A
503 \r
504 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
505 \r
09f2cf82 506 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {\r
507 Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);\r
508 } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {\r
509 Status = GetFileInfo (Fcb, BufferSize, Buffer);\r
510 } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {\r
511 ResultSize = StrSize (mSemihostFsLabel);\r
512\r
513 if (*BufferSize >= ResultSize) {\r
514 StrCpy (Buffer, mSemihostFsLabel);\r
515 Status = EFI_SUCCESS;\r
516 } else {\r
517 Status = EFI_BUFFER_TOO_SMALL;\r
518 }\r
519\r
520 *BufferSize = ResultSize;\r
521 } else {\r
522 Status = EFI_UNSUPPORTED;\r
2ef2b01e 523 }\r
09f2cf82 524\r
2ef2b01e
A
525 return Status;\r
526}\r
527\r
528EFI_STATUS\r
529FileSetInfo (\r
530 IN EFI_FILE *File,\r
531 IN EFI_GUID *InformationType,\r
532 IN UINTN BufferSize,\r
533 IN VOID *Buffer\r
534 )\r
535{\r
09f2cf82 536 EFI_STATUS Status;\r
537\r
538 if (Buffer == NULL) {\r
539 return EFI_INVALID_PARAMETER;\r
540 }\r
541\r
542 Status = EFI_UNSUPPORTED;\r
543\r
544 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {\r
545 //Status = SetFilesystemInfo (Fcb, BufferSize, Buffer);\r
546 } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {\r
547 //Status = SetFileInfo (Fcb, BufferSize, Buffer);\r
548 } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {\r
549 if (StrSize (Buffer) > 0) {\r
550 FreePool (mSemihostFsLabel);\r
551 mSemihostFsLabel = AllocateCopyPool (StrSize (Buffer), Buffer);\r
552 Status = EFI_SUCCESS;\r
553 }\r
554 }\r
555\r
556 return Status;\r
2ef2b01e
A
557}\r
558\r
559EFI_STATUS\r
560FileFlush (\r
561 IN EFI_FILE *File\r
562 )\r
563{\r
09f2cf82 564 SEMIHOST_FCB *Fcb;\r
565\r
566 Fcb = SEMIHOST_FCB_FROM_THIS(File);\r
567\r
568 if (Fcb->IsRoot) {\r
569 return EFI_SUCCESS;\r
570 } else {\r
cc271ec3
OM
571 if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)\r
572 || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {\r
09f2cf82 573 return EFI_ACCESS_DENIED;\r
574 } else {\r
575 return EFI_SUCCESS;\r
576 }\r
577 }\r
2ef2b01e
A
578}\r
579\r
580EFI_STATUS\r
581SemihostFsEntryPoint (\r
582 IN EFI_HANDLE ImageHandle,\r
583 IN EFI_SYSTEM_TABLE *SystemTable\r
584 )\r
585{\r
09f2cf82 586 EFI_STATUS Status;\r
587\r
588 Status = EFI_NOT_FOUND;\r
2ef2b01e
A
589\r
590 if (SemihostConnectionSupported ()) {\r
09f2cf82 591 mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL);\r
592 if (mSemihostFsLabel == NULL) {\r
593 return EFI_OUT_OF_RESOURCES;\r
594 }\r
595\r
2ef2b01e
A
596 Status = gBS->InstallMultipleProtocolInterfaces (\r
597 &gInstallHandle, \r
598 &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs, \r
599 &gEfiDevicePathProtocolGuid, &gDevicePath,\r
600 NULL\r
601 );\r
09f2cf82 602\r
603 if (EFI_ERROR(Status)) {\r
604 FreePool (mSemihostFsLabel);\r
605 }\r
2ef2b01e
A
606 }\r
607 \r
608 return Status;\r
609}\r