X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPkg%2FFilesystem%2FSemihostFs%2FArm%2FSemihostFs.c;fp=ArmPkg%2FFilesystem%2FSemihostFs%2FArm%2FSemihostFs.c;h=39a30533ee5778b48d7b4f81a85f27be912277ef;hp=c5036b7b5c708f183185dfa9de94fb775903320d;hb=429309e0c6b74792d679681a8edd0d5ae0ff850c;hpb=7c2a6033c149625482a18cd51b65513c8fb8fe15 diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c index c5036b7b5c..39a30533ee 100644 --- a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c +++ b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c @@ -27,16 +27,16 @@ #include "SemihostFs.h" -#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs" +#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs" -STATIC CHAR16 *mSemihostFsLabel; +STATIC CHAR16 *mSemihostFsLabel; -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = { +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, VolumeOpen }; -EFI_FILE gSemihostFsFile = { +EFI_FILE gSemihostFsFile = { EFI_FILE_PROTOCOL_REVISION, FileOpen, FileClose, @@ -54,43 +54,45 @@ EFI_FILE gSemihostFsFile = { // Device path for semi-hosting. It contains our auto-generated Caller ID GUID. // typedef struct { - VENDOR_DEVICE_PATH Guid; - EFI_DEVICE_PATH_PROTOCOL End; + VENDOR_DEVICE_PATH Guid; + EFI_DEVICE_PATH_PROTOCOL End; } SEMIHOST_DEVICE_PATH; -SEMIHOST_DEVICE_PATH gDevicePath = { +SEMIHOST_DEVICE_PATH gDevicePath = { { - { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } }, + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } + }, EFI_CALLER_ID_GUID }, - { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } } + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } }; typedef struct { - LIST_ENTRY Link; - UINT64 Signature; - EFI_FILE File; - CHAR8 *FileName; - UINT64 OpenMode; - UINT32 Position; - UINTN SemihostHandle; - BOOLEAN IsRoot; - EFI_FILE_INFO Info; + LIST_ENTRY Link; + UINT64 Signature; + EFI_FILE File; + CHAR8 *FileName; + UINT64 OpenMode; + UINT32 Position; + UINTN SemihostHandle; + BOOLEAN IsRoot; + EFI_FILE_INFO Info; } SEMIHOST_FCB; -#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' ) -#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE) -#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE); +#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' ) +#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE) +#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE); EFI_HANDLE gInstallHandle = NULL; -LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList); +LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList); SEMIHOST_FCB * AllocateFCB ( VOID ) { - SEMIHOST_FCB *Fcb; + SEMIHOST_FCB *Fcb; Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB)); if (Fcb != NULL) { @@ -103,7 +105,7 @@ AllocateFCB ( VOID FreeFCB ( - IN SEMIHOST_FCB *Fcb + IN SEMIHOST_FCB *Fcb ) { // Remove Fcb from gFileList. @@ -115,15 +117,13 @@ FreeFCB ( FreePool (Fcb); } - - EFI_STATUS VolumeOpen ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE **Root + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE **Root ) { - SEMIHOST_FCB *RootFcb; + SEMIHOST_FCB *RootFcb; if (Root == NULL) { return EFI_INVALID_PARAMETER; @@ -134,7 +134,7 @@ VolumeOpen ( return EFI_OUT_OF_RESOURCES; } - RootFcb->IsRoot = TRUE; + RootFcb->IsRoot = TRUE; RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; InsertTailList (&gFileList, &RootFcb->Link); @@ -191,29 +191,33 @@ FileOpen ( return EFI_INVALID_PARAMETER; } - if ( (OpenMode != EFI_FILE_MODE_READ) && - (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) && - (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) { + if ((OpenMode != EFI_FILE_MODE_READ) && + (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) && + (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE))) + { return EFI_INVALID_PARAMETER; } if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && - ((Attributes & EFI_FILE_DIRECTORY) != 0)) { + ((Attributes & EFI_FILE_DIRECTORY) != 0)) + { return EFI_WRITE_PROTECTED; } - Length = StrLen (FileName) + 1; + Length = StrLen (FileName) + 1; AsciiFileName = AllocatePool (Length); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } + UnicodeStrToAsciiStrS (FileName, AsciiFileName, Length); // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0) || - (AsciiStrCmp (AsciiFileName, ".") == 0) ) { + (AsciiStrCmp (AsciiFileName, ".") == 0)) + { FreePool (AsciiFileName); return (VolumeOpen (&gSemihostFs, NewHandle)); } @@ -232,6 +236,7 @@ FileOpen ( } else { SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE; } + Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle); if (RETURN_ERROR (Return)) { @@ -279,7 +284,7 @@ FileOpen ( FileFcb->Info.FileSize = Length; FileFcb->Info.PhysicalSize = Length; FileFcb->Info.Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ? - Attributes : 0; + Attributes : 0; InsertTailList (&gFileList, &FileFcb->Link); @@ -308,7 +313,7 @@ STATIC EFI_STATUS TruncateFile ( IN CHAR8 *FileName, - IN UINTN Size + IN UINTN Size ) { EFI_STATUS Status; @@ -338,7 +343,7 @@ TruncateFile ( goto Error; } - Read = 0; + Read = 0; Remaining = Size; while (Remaining > 0) { ToRead = Remaining; @@ -346,11 +351,12 @@ TruncateFile ( if (RETURN_ERROR (Return)) { goto Error; } + Remaining -= ToRead; Read += ToRead; } - Return = SemihostFileClose (FileHandle); + Return = SemihostFileClose (FileHandle); FileHandle = 0; if (RETURN_ERROR (Return)) { goto Error; @@ -379,12 +385,12 @@ Error: if (FileHandle != 0) { SemihostFileClose (FileHandle); } + if (Buffer != NULL) { FreePool (Buffer); } return (Status); - } /** @@ -402,13 +408,13 @@ FileClose ( IN EFI_FILE *This ) { - SEMIHOST_FCB *Fcb; + SEMIHOST_FCB *Fcb; if (This == NULL) { return EFI_INVALID_PARAMETER; } - Fcb = SEMIHOST_FCB_FROM_THIS(This); + Fcb = SEMIHOST_FCB_FROM_THIS (This); if (!Fcb->IsRoot) { SemihostFileClose (Fcb->SemihostHandle); @@ -420,6 +426,7 @@ FileClose ( if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) { TruncateFile (Fcb->FileName, Fcb->Info.FileSize); } + FreePool (Fcb->FileName); } @@ -441,7 +448,7 @@ FileClose ( **/ EFI_STATUS FileDelete ( - IN EFI_FILE *This + IN EFI_FILE *This ) { SEMIHOST_FCB *Fcb; @@ -471,6 +478,7 @@ FileDelete ( if (RETURN_ERROR (Return)) { return EFI_WARN_DELETE_FAILURE; } + return EFI_SUCCESS; } else { return EFI_WARN_DELETE_FAILURE; @@ -566,14 +574,15 @@ ExtendFile ( } Remaining = Size; - SetMem (WriteBuffer, 0, sizeof(WriteBuffer)); + SetMem (WriteBuffer, 0, sizeof (WriteBuffer)); while (Remaining > 0) { - WriteNb = MIN (Remaining, sizeof(WriteBuffer)); + WriteNb = MIN (Remaining, sizeof (WriteBuffer)); WriteSize = WriteNb; - Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer); + Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } + Remaining -= WriteNb; } @@ -599,9 +608,9 @@ ExtendFile ( **/ EFI_STATUS FileWrite ( - IN EFI_FILE *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer + IN EFI_FILE *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer ) { SEMIHOST_FCB *Fcb; @@ -617,8 +626,9 @@ FileWrite ( Fcb = SEMIHOST_FCB_FROM_THIS (This); // We cannot write a read-only file - if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY) - || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) { + if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) + || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) + { return EFI_ACCESS_DENIED; } @@ -632,11 +642,12 @@ FileWrite ( if (EFI_ERROR (Status)) { return Status; } + Fcb->Info.FileSize = Fcb->Position; } WriteSize = *BufferSize; - Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer); + Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } @@ -650,6 +661,7 @@ FileWrite ( if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } + Fcb->Info.PhysicalSize = Length; return EFI_SUCCESS; @@ -668,17 +680,17 @@ FileWrite ( **/ EFI_STATUS FileGetPosition ( - IN EFI_FILE *This, - OUT UINT64 *Position + IN EFI_FILE *This, + OUT UINT64 *Position ) { - SEMIHOST_FCB *Fcb; + SEMIHOST_FCB *Fcb; if ((This == NULL) || (Position == NULL)) { return EFI_INVALID_PARAMETER; } - Fcb = SEMIHOST_FCB_FROM_THIS(This); + Fcb = SEMIHOST_FCB_FROM_THIS (This); *Position = Fcb->Position; @@ -701,8 +713,8 @@ FileGetPosition ( **/ EFI_STATUS FileSetPosition ( - IN EFI_FILE *This, - IN UINT64 Position + IN EFI_FILE *This, + IN UINT64 Position ) { SEMIHOST_FCB *Fcb; @@ -718,8 +730,7 @@ FileSetPosition ( if (Position != 0) { return EFI_UNSUPPORTED; } - } - else { + } else { // // UEFI Spec section 12.5: // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to @@ -728,6 +739,7 @@ FileSetPosition ( if (Position == 0xFFFFFFFFFFFFFFFF) { Position = Fcb->Info.FileSize; } + Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize)); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; @@ -760,14 +772,14 @@ GetFileInfo ( OUT VOID *Buffer ) { - EFI_FILE_INFO *Info; - UINTN NameSize; - UINTN ResultSize; - UINTN Index; + EFI_FILE_INFO *Info; + UINTN NameSize; + UINTN ResultSize; + UINTN Index; if (Fcb->IsRoot) { - NameSize = 0; - ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); + NameSize = 0; + ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16); } else { NameSize = AsciiStrLen (Fcb->FileName) + 1; ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16); @@ -787,7 +799,7 @@ GetFileInfo ( Info->Size = ResultSize; if (Fcb->IsRoot) { - Info->FileName[0] = L'\0'; + Info->FileName[0] = L'\0'; } else { for (Index = 0; Index < NameSize; Index++) { Info->FileName[Index] = Fcb->FileName[Index]; @@ -818,9 +830,9 @@ GetFileInfo ( STATIC EFI_STATUS GetFilesystemInfo ( - IN SEMIHOST_FCB *Fcb, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer + IN SEMIHOST_FCB *Fcb, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer ) { EFI_FILE_SYSTEM_INFO *Info; @@ -882,18 +894,19 @@ FileGetInfo ( OUT VOID *Buffer ) { - SEMIHOST_FCB *Fcb; - EFI_STATUS Status; - UINTN ResultSize; + SEMIHOST_FCB *Fcb; + EFI_STATUS Status; + UINTN ResultSize; if ((This == NULL) || (InformationType == NULL) || (BufferSize == NULL) || - ((Buffer == NULL) && (*BufferSize > 0)) ) { + ((Buffer == NULL) && (*BufferSize > 0))) + { return EFI_INVALID_PARAMETER; } - Fcb = SEMIHOST_FCB_FROM_THIS(This); + Fcb = SEMIHOST_FCB_FROM_THIS (This); if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { Status = GetFilesystemInfo (Fcb, BufferSize, Buffer); @@ -963,11 +976,12 @@ SetFileInfo ( return EFI_ACCESS_DENIED; } - Length = StrLen (Info->FileName) + 1; + Length = StrLen (Info->FileName) + 1; AsciiFileName = AllocatePool (Length); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } + UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, Length); FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize); @@ -985,7 +999,8 @@ SetFileInfo ( // description. // if ((Fcb->OpenMode == EFI_FILE_MODE_READ) || - (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) ) { + (Fcb->Info.Attribute & EFI_FILE_READ_ONLY)) + { if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) { Status = EFI_ACCESS_DENIED; goto Error; @@ -1006,6 +1021,7 @@ SetFileInfo ( if (EFI_ERROR (Status)) { goto Error; } + // // The read/write position from the host file system point of view // is at the end of the file. If the position from this module @@ -1016,12 +1032,14 @@ SetFileInfo ( FileSetPosition (&Fcb->File, Fcb->Position); } } + Fcb->Info.FileSize = FileSize; Return = SemihostFileLength (Fcb->SemihostHandle, &Length); if (RETURN_ERROR (Return)) { goto Error; } + Fcb->Info.PhysicalSize = Length; } @@ -1048,6 +1066,7 @@ SetFileInfo ( if (RETURN_ERROR (Return)) { goto Error; } + FreePool (Fcb->FileName); Fcb->FileName = AsciiFileName; AsciiFileName = NULL; @@ -1119,19 +1138,24 @@ FileSetInfo ( if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) { return EFI_INVALID_PARAMETER; } + if (BufferSize < Info->Size) { return EFI_BAD_BUFFER_SIZE; } + return SetFileInfo (Fcb, Info); } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { SystemInfo = Buffer; if (SystemInfo->Size < - (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) { + (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) + { return EFI_INVALID_PARAMETER; } + if (BufferSize < SystemInfo->Size) { return EFI_BAD_BUFFER_SIZE; } + Buffer = SystemInfo->VolumeLabel; if (StrSize (Buffer) > 0) { @@ -1155,18 +1179,19 @@ FileSetInfo ( EFI_STATUS FileFlush ( - IN EFI_FILE *File + IN EFI_FILE *File ) { - SEMIHOST_FCB *Fcb; + SEMIHOST_FCB *Fcb; - Fcb = SEMIHOST_FCB_FROM_THIS(File); + Fcb = SEMIHOST_FCB_FROM_THIS (File); if (Fcb->IsRoot) { return EFI_SUCCESS; } else { - if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY) - || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) { + if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) + || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) + { return EFI_ACCESS_DENIED; } else { return EFI_SUCCESS; @@ -1176,11 +1201,11 @@ FileFlush ( EFI_STATUS SemihostFsEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + EFI_STATUS Status; Status = EFI_NOT_FOUND; @@ -1192,12 +1217,14 @@ SemihostFsEntryPoint ( Status = gBS->InstallMultipleProtocolInterfaces ( &gInstallHandle, - &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs, - &gEfiDevicePathProtocolGuid, &gDevicePath, + &gEfiSimpleFileSystemProtocolGuid, + &gSemihostFs, + &gEfiDevicePathProtocolGuid, + &gDevicePath, NULL ); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { FreePool (mSemihostFsLabel); } }