30#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
32STATIC CHAR16 *mSemihostFsLabel;
35 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
40 EFI_FILE_PROTOCOL_REVISION,
83#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
84#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)
85#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);
99 CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
100 Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
129 return EFI_INVALID_PARAMETER;
132 RootFcb = AllocateFCB ();
133 if (RootFcb ==
NULL) {
134 return EFI_OUT_OF_RESOURCES;
137 RootFcb->IsRoot =
TRUE;
138 RootFcb->Info.
Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
142 *Root = &RootFcb->File;
183 RETURN_STATUS Return;
185 UINTN SemihostHandle;
186 CHAR8 *AsciiFileName;
190 if ((FileName ==
NULL) || (NewHandle ==
NULL)) {
191 return EFI_INVALID_PARAMETER;
194 if ((OpenMode != EFI_FILE_MODE_READ) &&
195 (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
196 (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)))
198 return EFI_INVALID_PARAMETER;
201 if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) &&
202 ((Attributes & EFI_FILE_DIRECTORY) != 0))
204 return EFI_WRITE_PROTECTED;
207 Length =
StrLen (FileName) + 1;
209 if (AsciiFileName ==
NULL) {
210 return EFI_OUT_OF_RESOURCES;
222 return (VolumeOpen (&gSemihostFs, NewHandle));
234 if (OpenMode == EFI_FILE_MODE_READ) {
235 SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;
237 SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
240 Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
243 if ((OpenMode & EFI_FILE_MODE_CREATE) != 0) {
249 Return = SemihostFileOpen (
251 SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE,
255 Status = EFI_DEVICE_ERROR;
259 Status = EFI_NOT_FOUND;
265 FileFcb = AllocateFCB ();
266 if (FileFcb ==
NULL) {
267 Status = EFI_OUT_OF_RESOURCES;
271 FileFcb->FileName = AsciiFileName;
272 FileFcb->SemihostHandle = SemihostHandle;
273 FileFcb->Position = 0;
275 FileFcb->OpenMode = OpenMode;
277 Return = SemihostFileLength (SemihostHandle, &Length);
279 Status = EFI_DEVICE_ERROR;
286 FileFcb->Info.
Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ?
291 *NewHandle = &FileFcb->File;
320 RETURN_STATUS Return;
327 Status = EFI_DEVICE_ERROR;
331 Return = SemihostFileOpen (
333 SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,
341 if (Buffer ==
NULL) {
342 Status = EFI_OUT_OF_RESOURCES;
348 while (Remaining > 0) {
350 Return = SemihostFileRead (FileHandle, &ToRead, Buffer + Read);
359 Return = SemihostFileClose (FileHandle);
365 Return = SemihostFileOpen (
367 SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY,
375 Return = SemihostFileWrite (FileHandle, &Size, Buffer);
385 if (FileHandle != 0) {
386 SemihostFileClose (FileHandle);
389 if (Buffer !=
NULL) {
414 return EFI_INVALID_PARAMETER;
417 Fcb = SEMIHOST_FCB_FROM_THIS (This);
420 SemihostFileClose (Fcb->SemihostHandle);
455 RETURN_STATUS Return;
460 return EFI_INVALID_PARAMETER;
463 Fcb = SEMIHOST_FCB_FROM_THIS (This);
477 Return = SemihostFileRemove (FileName);
479 return EFI_WARN_DELETE_FAILURE;
484 return EFI_WARN_DELETE_FAILURE;
515 RETURN_STATUS Return;
517 if ((This ==
NULL) || (BufferSize ==
NULL) || (Buffer ==
NULL)) {
518 return EFI_INVALID_PARAMETER;
521 Fcb = SEMIHOST_FCB_FROM_THIS (This);
525 Status = EFI_UNSUPPORTED;
528 if (Fcb->Position >= Fcb->Info.
FileSize) {
530 if (Fcb->Position > Fcb->Info.
FileSize) {
531 Status = EFI_DEVICE_ERROR;
534 Return = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);
536 Status = EFI_DEVICE_ERROR;
538 Fcb->Position += *BufferSize;
565 RETURN_STATUS Return;
567 CHAR8 WriteBuffer[128];
571 Return = SemihostFileSeek (Fcb->SemihostHandle, Fcb->Info.FileSize);
573 return EFI_DEVICE_ERROR;
577 ZeroMem (WriteBuffer,
sizeof (WriteBuffer));
578 while (Remaining > 0) {
579 WriteNb =
MIN (Remaining,
sizeof (WriteBuffer));
581 Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
583 return EFI_DEVICE_ERROR;
586 Remaining -= WriteNb;
619 RETURN_STATUS Return;
622 if ((This ==
NULL) || (BufferSize ==
NULL) || (Buffer ==
NULL)) {
623 return EFI_INVALID_PARAMETER;
626 Fcb = SEMIHOST_FCB_FROM_THIS (This);
629 if ( (Fcb->Info.
Attribute & EFI_FILE_READ_ONLY)
630 || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE))
632 return EFI_ACCESS_DENIED;
640 if (Fcb->Position > Fcb->Info.
FileSize) {
642 if (EFI_ERROR (Status)) {
649 WriteSize = *BufferSize;
650 Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
652 return EFI_DEVICE_ERROR;
655 Fcb->Position += *BufferSize;
656 if (Fcb->Position > Fcb->Info.
FileSize) {
660 Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
662 return EFI_DEVICE_ERROR;
689 if ((This ==
NULL) || (Position ==
NULL)) {
690 return EFI_INVALID_PARAMETER;
693 Fcb = SEMIHOST_FCB_FROM_THIS (This);
695 *Position = Fcb->Position;
721 RETURN_STATUS Return;
724 return EFI_INVALID_PARAMETER;
727 Fcb = SEMIHOST_FCB_FROM_THIS (This);
731 return EFI_UNSUPPORTED;
739 if (Position == 0xFFFFFFFFFFFFFFFF) {
743 Return = SemihostFileSeek (Fcb->SemihostHandle,
MIN (Position, Fcb->Info.
FileSize));
745 return EFI_DEVICE_ERROR;
749 Fcb->Position = Position;
788 if (*BufferSize < ResultSize) {
789 *BufferSize = ResultSize;
790 return EFI_BUFFER_TOO_SMALL;
799 Info->
Size = ResultSize;
804 for (Index = 0; Index < NameSize; Index++) {
805 Info->
FileName[Index] = Fcb->FileName[Index];
809 *BufferSize = ResultSize;
843 StringSize =
StrSize (mSemihostFsLabel);
846 if (*BufferSize >= ResultSize) {
852 Info->
Size = ResultSize;
860 Status = EFI_BUFFER_TOO_SMALL;
863 *BufferSize = ResultSize;
901 if ((This ==
NULL) ||
902 (InformationType ==
NULL) ||
903 (BufferSize ==
NULL) ||
904 ((Buffer ==
NULL) && (*BufferSize > 0)))
906 return EFI_INVALID_PARAMETER;
909 Fcb = SEMIHOST_FCB_FROM_THIS (This);
911 if (
CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
913 }
else if (
CompareGuid (InformationType, &gEfiFileInfoGuid)) {
915 }
else if (
CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
916 ResultSize =
StrSize (mSemihostFsLabel);
918 if (*BufferSize >= ResultSize) {
919 CopyMem (Buffer, mSemihostFsLabel, ResultSize);
922 Status = EFI_BUFFER_TOO_SMALL;
925 *BufferSize = ResultSize;
927 Status = EFI_UNSUPPORTED;
962 RETURN_STATUS Return;
963 BOOLEAN FileSizeIsDifferent;
964 BOOLEAN FileNameIsDifferent;
965 BOOLEAN ReadOnlyIsDifferent;
966 CHAR8 *AsciiFileName;
969 UINTN SemihostHandle;
975 if (((Info->Attribute & EFI_FILE_DIRECTORY) != 0) != Fcb->IsRoot) {
976 return EFI_ACCESS_DENIED;
979 Length =
StrLen (Info->FileName) + 1;
981 if (AsciiFileName ==
NULL) {
982 return EFI_OUT_OF_RESOURCES;
987 FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize);
988 FileNameIsDifferent = (
AsciiStrCmp (AsciiFileName, Fcb->FileName) != 0);
991 &Fcb->Info.CreateTime,
1001 if ((Fcb->OpenMode == EFI_FILE_MODE_READ) ||
1002 (Fcb->Info.Attribute & EFI_FILE_READ_ONLY))
1004 if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) {
1005 Status = EFI_ACCESS_DENIED;
1010 if (ReadOnlyIsDifferent) {
1011 Status = EFI_WRITE_PROTECTED;
1015 Status = EFI_DEVICE_ERROR;
1017 if (FileSizeIsDifferent) {
1018 FileSize = Info->FileSize;
1019 if (Fcb->Info.FileSize < FileSize) {
1020 Status =
ExtendFile (Fcb, FileSize - Fcb->Info.FileSize);
1021 if (EFI_ERROR (Status)) {
1031 if (Fcb->Position < FileSize) {
1036 Fcb->Info.FileSize = FileSize;
1038 Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
1043 Fcb->Info.PhysicalSize = Length;
1051 Fcb->Info.Attribute = Info->Attribute;
1053 if (FileNameIsDifferent) {
1054 Return = SemihostFileOpen (
1056 SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,
1060 SemihostFileClose (SemihostHandle);
1061 Status = EFI_ACCESS_DENIED;
1071 Fcb->FileName = AsciiFileName;
1072 AsciiFileName =
NULL;
1078 if (AsciiFileName !=
NULL) {
1128 CHAR16 *VolumeLabel;
1130 if ((This ==
NULL) || (InformationType ==
NULL) || (Buffer ==
NULL)) {
1131 return EFI_INVALID_PARAMETER;
1134 Fcb = SEMIHOST_FCB_FROM_THIS (This);
1136 if (
CompareGuid (InformationType, &gEfiFileInfoGuid)) {
1139 return EFI_INVALID_PARAMETER;
1142 if (BufferSize < Info->Size) {
1143 return EFI_BAD_BUFFER_SIZE;
1147 }
else if (
CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
1148 SystemInfo = Buffer;
1149 if (SystemInfo->
Size <
1152 return EFI_INVALID_PARAMETER;
1155 if (BufferSize < SystemInfo->Size) {
1156 return EFI_BAD_BUFFER_SIZE;
1163 if (VolumeLabel !=
NULL) {
1165 mSemihostFsLabel = VolumeLabel;
1168 return EFI_OUT_OF_RESOURCES;
1171 return EFI_INVALID_PARAMETER;
1173 }
else if (!
CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
1174 return EFI_UNSUPPORTED;
1176 return EFI_UNSUPPORTED;
1187 Fcb = SEMIHOST_FCB_FROM_THIS (File);
1192 if ( (Fcb->Info.
Attribute & EFI_FILE_READ_ONLY)
1193 || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE))
1195 return EFI_ACCESS_DENIED;
1203SemihostFsEntryPoint (
1210 Status = EFI_NOT_FOUND;
1212 if (SemihostConnectionSupported ()) {
1214 if (mSemihostFsLabel ==
NULL) {
1215 return EFI_OUT_OF_RESOURCES;
1218 Status =
gBS->InstallMultipleProtocolInterfaces (
1220 &gEfiSimpleFileSystemProtocolGuid,
1222 &gEfiDevicePathProtocolGuid,
1227 if (EFI_ERROR (Status)) {
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define HARDWARE_DEVICE_PATH
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define SIZE_OF_EFI_FILE_INFO
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
#define RETURN_ERROR(StatusCode)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS FileOpen(IN EFI_FILE *This, OUT EFI_FILE **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes)
STATIC EFI_STATUS GetFileInfo(IN SEMIHOST_FCB *Fcb, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
EFI_STATUS FileClose(IN EFI_FILE *This)
EFI_STATUS FileSetInfo(IN EFI_FILE *This, IN EFI_GUID *InformationType, IN UINTN BufferSize, IN VOID *Buffer)
EFI_STATUS FileDelete(IN EFI_FILE *This)
STATIC EFI_STATUS ExtendFile(IN SEMIHOST_FCB *Fcb, IN UINTN Size)
EFI_STATUS FileRead(IN EFI_FILE *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
EFI_STATUS FileSetPosition(IN EFI_FILE *This, IN UINT64 Position)
STATIC EFI_STATUS GetFilesystemInfo(IN SEMIHOST_FCB *Fcb, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
STATIC EFI_STATUS SetFileInfo(IN SEMIHOST_FCB *Fcb, IN EFI_FILE_INFO *Info)
EFI_STATUS FileGetInfo(IN EFI_FILE *This, IN EFI_GUID *InformationType, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
EFI_STATUS FileWrite(IN EFI_FILE *This, IN OUT UINTN *BufferSize, IN VOID *Buffer)
EFI_STATUS FileGetPosition(IN EFI_FILE *This, OUT UINT64 *Position)
STATIC EFI_STATUS TruncateFile(IN CHAR8 *FileName, IN UINTN Size)
RETURN_STATUS SemihostFileRename(IN CHAR8 *FileName, IN CHAR8 *NewFileName)