/** Reads the contents of the NvVars file on the file system @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance @return EFI_STATUS based on the success or failure of the file read **/ EFI_STATUS ReadNvVarsFile ( IN EFI_HANDLE FsHandle ) { EFI_STATUS Status; EFI_FILE_HANDLE File; UINTN FileSize; BOOLEAN FileExists; VOID *FileContents; EFI_HANDLE SerializedVariables; Status = GetNvVarsFile (FsHandle, TRUE, &File); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n")); return Status; } NvVarsFileReadCheckup (File, &FileExists, &FileSize); if (FileSize == 0) { FileHandleClose (File); return EFI_UNSUPPORTED; } FileContents = FileHandleReadToNewBuffer (File, FileSize); if (FileContents == NULL) { FileHandleClose (File); return EFI_UNSUPPORTED; } DEBUG (( EFI_D_INFO, "FsAccess.c: Read %d bytes from NV Variables file\n", FileSize )); Status = SerializeVariablesNewInstanceFromBuffer ( &SerializedVariables, FileContents, FileSize ); if (!RETURN_ERROR (Status)) { Status = SerializeVariablesSetSerializedVariables (SerializedVariables); } FreePool (FileContents); FileHandleClose (File); return Status; }
INTN EFIAPI ShellAppMain (IN UINTN Argc, IN CHAR16 **Argv) { CHAR8 c; int i; CHAR8 s[2]; CHAR8 *source2 = source; EFI_FILE_HANDLE handle; UINTN size; for (i = 0; i < 4; i++) write_file(filenames[i], files[i]); ShellOpenFileByName(L"Quine.c", (void**)&handle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); while (c = *source2++, c) { if (36 == c) { print_escape(handle, files[i++-4]); } else if (126 == c) { print_escape(handle, source); } else { s[0] = c; s[1] = 0; size = AsciiStrSize(s) - 1; FileHandleWrite(handle, &size, s); } } FileHandleClose(handle); Print( L" _____ _____ ___ ___ _ \n" L"| ____| ___|_ _| / _ \\ _ _(_)_ __ ___ \n" L"| _| | |_ | | | | | | | | | | '_ \\ / _ \\\n" L"| |___| _| | | | |_| | |_| | | | | | __/\n" L"|_____|_| |___| \\__\\_\\\\__,_|_|_| |_|\\___|\n" ); return 0; }
void write_file(CHAR16 *filename, CHAR8 *source) { EFI_FILE_HANDLE handle; UINTN size = AsciiStrSize(source) - 1; ShellOpenFileByName(filename, (void**)&handle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); FileHandleWrite(handle, &size, source); FileHandleClose(handle); }
/** Saves the non-volatile variables into the NvVars file on the given file system. @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance @return EFI_STATUS based on the success or failure of load operation **/ EFI_STATUS SaveNvVarsToFs ( EFI_HANDLE FsHandle ) { EFI_STATUS Status; EFI_FILE_HANDLE File; UINTN WriteSize; UINTN VariableDataSize; VOID *VariableData; EFI_HANDLE SerializedVariables; SerializedVariables = NULL; Status = SerializeVariablesNewInstance (&SerializedVariables); if (EFI_ERROR (Status)) { return Status; } Status = SerializeVariablesIterateSystemVariables ( IterateVariablesCallbackAddAllNvVariables, (VOID*) SerializedVariables ); if (EFI_ERROR (Status)) { return Status; } VariableData = NULL; VariableDataSize = 0; Status = SerializeVariablesToBuffer ( SerializedVariables, NULL, &VariableDataSize ); if (Status == RETURN_BUFFER_TOO_SMALL) { VariableData = AllocatePool (VariableDataSize); if (VariableData == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = SerializeVariablesToBuffer ( SerializedVariables, VariableData, &VariableDataSize ); } } SerializeVariablesFreeInstance (SerializedVariables); if (EFI_ERROR (Status)) { return Status; } // // Open the NvVars file for writing. // Status = GetNvVarsFile (FsHandle, FALSE, &File); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n")); return Status; } // // Empty the starting file contents. // Status = FileHandleEmpty (File); if (EFI_ERROR (Status)) { FileHandleClose (File); return Status; } WriteSize = VariableDataSize; Status = FileHandleWrite (File, &WriteSize, VariableData); if (EFI_ERROR (Status)) { return Status; } FileHandleClose (File); if (!EFI_ERROR (Status)) { // // Write a variable to indicate we've already loaded the // variable data. If it is found, we skip the loading on // subsequent attempts. // SetNvVarsVariable(); DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n")); } return Status; }
/** Saves the non-volatile variables into the NvVars file on the given file system. @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance @return EFI_STATUS based on the success or failure of load operation **/ EFI_STATUS SaveNvVarsToFs ( EFI_HANDLE FsHandle ) { EFI_STATUS Status; EFI_FILE_HANDLE File; UINTN VariableNameBufferSize; UINTN VariableNameSize; CHAR16 *VariableName; EFI_GUID VendorGuid; UINTN VariableDataBufferSize; UINTN VariableDataSize; VOID *VariableData; UINT32 VariableAttributes; VOID *NewBuffer; // // Open the NvVars file for writing. // Status = GetNvVarsFile (FsHandle, FALSE, &File); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n")); return Status; } // // Empty the starting file contents. // Status = FileHandleEmpty (File); if (EFI_ERROR (Status)) { FileHandleClose (File); return Status; } // // Initialize the variable name and data buffer variables. // VariableNameBufferSize = sizeof (CHAR16); VariableName = AllocateZeroPool (VariableNameBufferSize); VariableDataBufferSize = 0; VariableData = NULL; for (;;) { // // Get the next variable name and guid // VariableNameSize = VariableNameBufferSize; Status = gRT->GetNextVariableName ( &VariableNameSize, VariableName, &VendorGuid ); if (Status == EFI_BUFFER_TOO_SMALL) { // // The currently allocated VariableName buffer is too small, // so we allocate a larger buffer, and copy the old buffer // to it. // NewBuffer = AllocatePool (VariableNameSize); if (NewBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } CopyMem (NewBuffer, VariableName, VariableNameBufferSize); if (VariableName != NULL) { FreePool (VariableName); } VariableName = NewBuffer; VariableNameBufferSize = VariableNameSize; // // Try to get the next variable name again with the larger buffer. // Status = gRT->GetNextVariableName ( &VariableNameSize, VariableName, &VendorGuid ); } if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND) { Status = EFI_SUCCESS; } break; } // // Get the variable data and attributes // VariableDataSize = VariableDataBufferSize; Status = gRT->GetVariable ( VariableName, &VendorGuid, &VariableAttributes, &VariableDataSize, VariableData ); if (Status == EFI_BUFFER_TOO_SMALL) { // // The currently allocated VariableData buffer is too small, // so we allocate a larger buffer. // if (VariableDataBufferSize != 0) { FreePool (VariableData); VariableData = NULL; VariableDataBufferSize = 0; } VariableData = AllocatePool (VariableDataSize); if (VariableData == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } VariableDataBufferSize = VariableDataSize; // // Try to read the variable again with the larger buffer. // Status = gRT->GetVariable ( VariableName, &VendorGuid, &VariableAttributes, &VariableDataSize, VariableData ); } if (EFI_ERROR (Status)) { break; } // // Skip volatile variables. We only preserve non-volatile variables. // if ((VariableAttributes & EFI_VARIABLE_NON_VOLATILE) == 0) { continue; } DEBUG (( EFI_D_INFO, "Saving variable %g:%s to file\n", &VendorGuid, VariableName )); // // Write the variable information out to the file // Status = PackVariableIntoFile ( File, VariableName, (UINT32) VariableNameSize, &VendorGuid, VariableAttributes, VariableData, (UINT32) VariableDataSize ); if (EFI_ERROR (Status)) { break; } } if (VariableName != NULL) { FreePool (VariableName); } if (VariableData != NULL) { FreePool (VariableData); } FileHandleClose (File); if (!EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n")); } return Status; }
/** Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the directory 'stack'. If the file is a directory, then append the '\' char at the end of name string. If it's not a directory, then the last '\' should not be added. if Handle is NULL, return EFI_INVALID_PARAMETER @param[in] Handle Handle to the Directory or File to create path to. @param[out] FullFileName pointer to pointer to generated full file name. It is the responsibility of the caller to free this memory with a call to FreePool(). @retval EFI_SUCCESS the operation was sucessful and the FullFileName is valid. @retval EFI_INVALID_PARAMETER Handle was NULL. @retval EFI_INVALID_PARAMETER FullFileName was NULL. @retval EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS EFIAPI FileHandleGetFileName ( IN CONST EFI_FILE_HANDLE Handle, OUT CHAR16 **FullFileName ) { EFI_STATUS Status; UINTN Size; EFI_FILE_HANDLE CurrentHandle; EFI_FILE_HANDLE NextHigherHandle; EFI_FILE_INFO *FileInfo; Size = 0; // // Check our parameters // if (FullFileName == NULL || Handle == NULL) { return (EFI_INVALID_PARAMETER); } *FullFileName = NULL; CurrentHandle = NULL; Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0); if (!EFI_ERROR(Status)) { // // Reverse out the current directory on the device // for (;;) { FileInfo = FileHandleGetInfo(CurrentHandle); if (FileInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } else { // // We got info... do we have a name? if yes precede the current path with it... // if (StrLen (FileInfo->FileName) == 0) { if (*FullFileName == NULL) { ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } FreePool(FileInfo); break; } else { if (*FullFileName == NULL) { ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); FreePool(FileInfo); } } // // Move to the parent directory // Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { break; } FileHandleClose(CurrentHandle); CurrentHandle = NextHigherHandle; } } else if (Status == EFI_NOT_FOUND) { Status = EFI_SUCCESS; ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL)); *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0); } if (*FullFileName != NULL && (*FullFileName)[StrLen(*FullFileName) - 1] == L'\\' && StrLen(*FullFileName) > 1 && FileHandleIsDirectory(Handle) == EFI_NOT_FOUND ) { (*FullFileName)[StrLen(*FullFileName) - 1] = CHAR_NULL; } if (CurrentHandle != NULL) { CurrentHandle->Close (CurrentHandle); } if (EFI_ERROR(Status) && *FullFileName != NULL) { FreePool(*FullFileName); } return (Status); }
/** Dump capsule information from disk. @param[in] Fs The device path of disk. @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation. @retval EFI_SUCCESS The capsule information is dumped. **/ EFI_STATUS DumpCapsuleFromDisk ( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs, IN BOOLEAN DumpCapsuleInfo ) { EFI_STATUS Status; EFI_FILE *Root; EFI_FILE *DirHandle; EFI_FILE *FileHandle; UINTN Index; UINTN FileSize; VOID *FileBuffer; EFI_FILE_INFO **FileInfoBuffer; EFI_FILE_INFO *FileInfo; UINTN FileCount; BOOLEAN NoFile; DirHandle = NULL; FileHandle = NULL; Index = 0; FileInfoBuffer = NULL; FileInfo = NULL; FileCount = 0; NoFile = FALSE; Status = Fs->OpenVolume (Fs, &Root); if (EFI_ERROR (Status)) { Print (L"Cannot open volume. Status = %r\n", Status); goto Done; } Status = Root->Open (Root, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE , 0); if (EFI_ERROR (Status)) { Print (L"Cannot open %s. Status = %r\n", EFI_CAPSULE_FILE_DIRECTORY, Status); goto Done; } // // Get file count first // do { Status = FileHandleFindFirstFile (DirHandle, &FileInfo); if (EFI_ERROR (Status) || FileInfo == NULL) { Print (L"Get File Info Fail. Status = %r\n", Status); goto Done; } if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) { FileCount++; } Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile); if (EFI_ERROR (Status)) { Print (L"Get Next File Fail. Status = %r\n", Status); goto Done; } } while (!NoFile); if (FileCount == 0) { Print (L"Error: No capsule file found!\n"); Status = EFI_NOT_FOUND; goto Done; } FileInfoBuffer = AllocateZeroPool (sizeof (FileInfo) * FileCount); if (FileInfoBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } NoFile = FALSE; // // Get all file info // do { Status = FileHandleFindFirstFile (DirHandle, &FileInfo); if (EFI_ERROR (Status) || FileInfo == NULL) { Print (L"Get File Info Fail. Status = %r\n", Status); goto Done; } if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) { FileInfoBuffer[Index++] = AllocateCopyPool ((UINTN)FileInfo->Size, FileInfo); } Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile); if (EFI_ERROR (Status)) { Print (L"Get Next File Fail. Status = %r\n", Status); goto Done; } } while (!NoFile); // // Sort FileInfoBuffer by alphabet order // PerformQuickSort ( FileInfoBuffer, FileCount, sizeof (FileInfo), (SORT_COMPARE) CompareFileNameInAlphabet ); Print (L"The capsules will be performed by following order:\n"); for (Index = 0; Index < FileCount; Index++) { Print (L" %d.%s\n", Index + 1, FileInfoBuffer[Index]->FileName); } if (!DumpCapsuleInfo) { Status = EFI_SUCCESS; goto Done; } Print(L"The infomation of the capsules:\n"); for (Index = 0; Index < FileCount; Index++) { FileHandle = NULL; Status = DirHandle->Open (DirHandle, &FileHandle, FileInfoBuffer[Index]->FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { goto Done; } Status = FileHandleGetSize (FileHandle, (UINT64 *) &FileSize); if (EFI_ERROR (Status)) { Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status); FileHandleClose (FileHandle); goto Done; } FileBuffer = AllocatePool (FileSize); if (FileBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } Status = FileHandleRead (FileHandle, &FileSize, FileBuffer); if (EFI_ERROR (Status)) { Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status); FileHandleClose (FileHandle); FreePool (FileBuffer); goto Done; } Print (L"**************************\n"); Print (L" %d.%s:\n", Index + 1, FileInfoBuffer[Index]->FileName); Print (L"**************************\n"); DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *) FileBuffer); FileHandleClose (FileHandle); FreePool (FileBuffer); } Done: if (FileInfoBuffer != NULL) { for (Index = 0; Index < FileCount; Index++) { if (FileInfoBuffer[Index] != NULL) { FreePool (FileInfoBuffer[Index]); } } FreePool (FileInfoBuffer); } return Status; }
static void ProcessRPM(const char *filename, PListEntry **files, PListEntry **dirs, char **ignore, const char *prefix, int stripcount) { int fd; FileHandle *in; PListEntry *last; if ((fd = open(filename, O_RDONLY, 0)) < 0) { perror(filename); exit(EXIT_FAILURE); } if (!IsRPMFile(fd)) { (void)fprintf(stderr, "%s: file is not an RPM package.\n", filename); exit(EXIT_FAILURE); } if ((in = OpenRPM(&fd)) == NULL) { (void)fprintf(stderr, "%s: cannot get RPM data.\n", filename); exit(EXIT_FAILURE); } if (fd >= 0) { (void)close(fd); fd = -1; } last = NULL; for (;;) { unsigned long fields[CPIO_NUM_HEADERS]; char *name; mode_t mode; unsigned long length; if (!GetCPIOHeader(in, fields, &name)) { (void)fprintf(stderr, "%s: error in cpio header.\n", filename); exit(EXIT_FAILURE); } if (strcmp(name, CPIO_END_MARKER) == 0) { free(name); break; } if (*name == '\0') fields[CPIO_HDR_MODE] = 0; if (ignore != NULL) { char **ptr; for (ptr = ignore; *ptr != NULL; ptr++) { if (CheckPrefix(*ptr, name)) { fields[CPIO_HDR_MODE] = 0; break; } } } if (fields[CPIO_HDR_MODE] != 0 && !StripPrefix(name, stripcount)) { (void)fprintf(stderr, "%s: Leading path to strip too " "big (-s %d)\n", filename, stripcount); exit(EXIT_FAILURE); } if (prefix != NULL) { char *fullname; fullname = StrCat(prefix, name); free(name); name = fullname; } mode = ConvertMode(fields[CPIO_HDR_MODE]); length = fields[CPIO_HDR_FILESIZE]; switch (fields[CPIO_HDR_MODE] & CP_IFMT) { case C_ISDIR: { PListEntry *dir; bool old_dir; if (length != 0) { (void)fprintf(stderr, "%s: error in cpio file.\n", filename); exit(EXIT_FAILURE); } if (!MakeTargetDir(name, dirs)) { (void)fprintf(stderr, "%s: can't create parent " "directories for \"%s\".\n", filename, name); exit(EXIT_FAILURE); } if (!MakeDir(name, mode, &old_dir)) { (void)fprintf(stderr, "%s: can't create directory " "\"%s\".\n", filename, name); exit(EXIT_FAILURE); } if (!old_dir) { dir = PListInsert(dirs, name); dir->pe_DirEmpty = true; } break; } case C_ISLNK: { char *link_target; if ((link_target = GetData(in, length)) == NULL) { (void)fprintf(stderr, "%s: error in cpio file.\n", filename); exit(EXIT_FAILURE); } if (!MakeTargetDir(name, dirs)) { (void)fprintf(stderr, "%s: can't create parent " "directories for \"%s\".\n", filename, name); exit(EXIT_FAILURE); } if (*link_target == '/') { char *ptr; (void)memmove(link_target, link_target + 1, strlen(link_target)); ptr = name; if (prefix != NULL) ptr += strlen(prefix); while ((ptr = strchr(ptr, '/')) != NULL) { char *new_link_target; new_link_target = StrCat("../", link_target); free(link_target); link_target = new_link_target; ptr++; } } if (!MakeSymLink(link_target, name)) { (void)fprintf(stderr, "%s: can't create symbolic link " "\"%s\".\n", filename, name); exit(EXIT_FAILURE); } PListInsert(files, name)->pe_Link = link_target; break; } case C_ISREG: if (!MakeTargetDir(name, dirs)) { (void)fprintf(stderr, "%s: can't create parent " "directories for \"%s\".\n", filename, name); exit(EXIT_FAILURE); } if ((last != NULL) && (last->pe_INode != fields[CPIO_HDR_INODE])) { last = NULL; } if (!WriteFile(in, name, mode, length, (last != NULL)? last->pe_Name : NULL)) { (void)fprintf(stderr, "%s: can't write file \"%s\".\n", filename, name); exit(EXIT_FAILURE); } last = PListInsert(files, name); last->pe_INode = fields[CPIO_HDR_INODE]; break; default: if (length > 0 && !SkipAndAlign(in, length)) { (void)fprintf(stderr, "%s: error in cpio file.\n", filename); exit(EXIT_FAILURE); } } free(name); } FileHandleClose(in); }