EFI_STATUS readFile( IN EFI_FILE *dir, IN INT32 index, IN EFI_SYSTEM_TABLE *systab, IN VOID *buf ) { EFI_STATUS status; EFI_FILE *file; CHAR16 filename[10]; // Allow up to 9999 stories (Probably going to have to increase buffer size when this engine gets super popular :) INT32 index tostring(index, filename); Status=dir->Open(dir, &file, filename, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); // open the file EFI_FILE_INFO *fileinfo; UINTN infosize = SIZE_OF_EFI_FILE_INFO; EFI_GUID info_type = EFI_FILE_INFO_ID; status = file->GetInfo(file, &info_type, &infosize, NULL); // get the info size of file systab->BootServices->AllocatePool(AllocateAnyPages, infosize, (VOID **)&fileinfo); status=file->GetInfo(file, &info_type, &infosize, fileinfo); // get info of file UINTN filesize = fileinfo->FileSize; // get filesize from info systab->BootServices->AllocatePool(AllocateAnyPages, filesize, (VOID **)&buf); // Allocate some room status=file->Read(file, &filesize, buf); systab->BootServices->FreePool(buf); systab->BootServices->FreePool(fileinfo); return EFI_SUCCESS; }
EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab) { InitializeLib(image_handle, systab); EFI_STATUS Status; systab->ConOut->ClearScreen(systab->ConOut); // CLEAR! EFI_GUID simplefs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; // a simple file system protocol in efi // (different from UEFI specification. In specification, this is called EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID ) EFI_FILE_IO_INTERFACE *simplefs; // the simple file system's interface // (different from UEFI specification. In specification, this is called EFI_SIMPLE_FILE_SYSTEM_PROTOCOL) EFI_FILE *root; // root directory EFI_FILE *dir; CHAR16 *dirname=L"\\stories"; // name of the directory where bmp pictures are put status=systab->BootServices->LocateProtocol(&simplefs_guid, NULL, (VOID **)&simplefs); if(EFI_ERROR(status)) Print(L"locate protocol failed \n"); status=simplefs->OpenVolume(simplefs, &root); if(EFI_ERROR(status)) Print(L"open volume failed\n"); status=root->Open(root, &dir, dirname, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); if(EFI_ERROR(status)) Print(L"open directory failed\n"); VOID *buf; INT32 index=1; status = readFile(dir, index, systab, buf); // Put the contents of 1.story into buf Print(L"%s", buf); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &Key); return Status; }
static int efifs_readdir(struct open_file *f, struct dirent *d) { EFI_FILE *file = f->f_fsdata; union fileinfo fi; EFI_STATUS status; UINTN sz; int i; if (file == NULL) return (EBADF); sz = sizeof(fi); status = file->Read(file, &sz, &fi); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); if (sz == 0) return (ENOENT); d->d_fileno = 0; d->d_reclen = sizeof(*d); if (fi.info.Attribute & EFI_FILE_DIRECTORY) d->d_type = DT_DIR; else d->d_type = DT_REG; for (i = 0; fi.info.FileName[i] != 0; i++) d->d_name[i] = fi.info.FileName[i]; d->d_name[i] = 0; d->d_namlen = i; return (0); }
static int efifs_stat(struct open_file *f, struct stat *sb) { EFI_FILE *file = f->f_fsdata; union fileinfo fi; EFI_STATUS status; UINTN sz; if (file == NULL) return (EBADF); bzero(sb, sizeof(*sb)); sz = sizeof(fi); status = file->GetInfo(file, &fi_guid, &sz, &fi); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); sb->st_mode = S_IRUSR | S_IRGRP | S_IROTH; if ((fi.info.Attribute & EFI_FILE_READ_ONLY) == 0) sb->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; if (fi.info.Attribute & EFI_FILE_DIRECTORY) sb->st_mode |= S_IFDIR; else sb->st_mode |= S_IFREG; sb->st_nlink = 1; sb->st_atime = efi_time(&fi.info.LastAccessTime); sb->st_mtime = efi_time(&fi.info.ModificationTime); sb->st_ctime = efi_time(&fi.info.CreateTime); sb->st_size = fi.info.FileSize; sb->st_blocks = fi.info.PhysicalSize / S_BLKSIZE; sb->st_blksize = S_BLKSIZE; sb->st_birthtime = sb->st_ctime; return (0); }
static int efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid) { EFI_FILE *file = f->f_fsdata; EFI_STATUS status; UINTN sz = size; char *bufp; if (file == NULL) return (EBADF); bufp = buf; while (size > 0) { sz = size; if (sz > EFI_BLOCK_SIZE) sz = EFI_BLOCK_SIZE; status = file->Write(file, &sz, bufp); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); if (sz == 0) break; size -= sz; bufp += sz; } if (resid) *resid = size; return (0); }
/* * Print information about disks */ static void efifs_dev_print(int verbose) { union { EFI_FILE_SYSTEM_INFO info; char buffer[1024]; } fi; char line[80]; EFI_FILE_IO_INTERFACE *fsif; EFI_FILE *volume; EFI_HANDLE h; EFI_STATUS status; UINTN sz; int i, unit; for (unit = 0, h = efi_find_handle(&efifs_dev, 0); h != NULL; h = efi_find_handle(&efifs_dev, ++unit)) { sprintf(line, " %s%d: ", efifs_dev.dv_name, unit); pager_output(line); status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif); if (EFI_ERROR(status)) goto err; status = fsif->OpenVolume(fsif, &volume); if (EFI_ERROR(status)) goto err; sz = sizeof(fi); status = volume->GetInfo(volume, &fs_guid, &sz, &fi); volume->Close(volume); if (EFI_ERROR(status)) goto err; if (fi.info.ReadOnly) pager_output("[RO] "); else pager_output(" "); for (i = 0; fi.info.VolumeLabel[i] != 0; i++) fi.buffer[i] = fi.info.VolumeLabel[i]; fi.buffer[i] = 0; if (fi.buffer[0] != 0) pager_output(fi.buffer); else pager_output("EFI filesystem"); pager_output("\n"); continue; err: sprintf(line, "[--] error %d: unable to obtain information\n", efi_status_to_errno(status)); pager_output(line); } }
static int efifs_close(struct open_file *f) { EFI_FILE *file = f->f_fsdata; if (file == NULL) return (EBADF); file->Close(file); f->f_fsdata = NULL; return (0); }
static off_t efifs_seek(struct open_file *f, off_t offset, int where) { EFI_FILE *file = f->f_fsdata; EFI_STATUS status; UINT64 base; if (file == NULL) return (EBADF); switch (where) { case SEEK_SET: break; case SEEK_END: status = file->SetPosition(file, ~0ULL); if (EFI_ERROR(status)) return (-1); /* FALLTHROUGH */ case SEEK_CUR: status = file->GetPosition(file, &base); if (EFI_ERROR(status)) return (-1); offset = (off_t)(base + offset); break; default: return (-1); } if (offset < 0) return (-1); status = file->SetPosition(file, (UINT64)offset); return (EFI_ERROR(status) ? -1 : offset); }
EFI_STATUS EFIAPI EBounceMain (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS Status; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; EFI_CONSOLE_CONTROL_SCREEN_MODE currentMode; EFI_LOADED_IMAGE *SelfLoadedImage; EFI_FILE *RootDir; EFI_FILE *BootFile; EFI_DEVICE_PATH *DevicePath; CHAR16 *DevicePathAsString; CHAR16 DirName[256]; CHAR16 FileName[256]; UINTN i, FileNameIndex; EFI_HANDLE LoaderHandle; InitializeLib(ImageHandle, SystemTable); // switch to text mode if (BS->LocateProtocol(&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl) == EFI_SUCCESS) { ConsoleControl->GetMode(ConsoleControl, ¤tMode, NULL, NULL); if (currentMode == EfiConsoleControlScreenGraphics) ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText); } /// load elilo.efi or e.efi from the same directory // get loaded image protocol for ourselves if (BS->HandleProtocol(ImageHandle, &LoadedImageProtocol, (VOID*)&SelfLoadedImage) != EFI_SUCCESS) { Print(L"Can not retrieve a LoadedImageProtocol handle for ImageHandle\n"); return EFI_NOT_FOUND; } // open volume RootDir = LibOpenRoot(SelfLoadedImage->DeviceHandle); if (RootDir == NULL) { Print(L"Can't open volume.\n"); return EFI_NOT_FOUND; } // find the current directory DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath); if (DevicePathAsString != NULL) { StrCpy(DirName, DevicePathAsString); FreePool(DevicePathAsString); for (i = StrLen(DirName) - 1; i > 0 && DirName[i] != '\\'; i--) ; DirName[i++] = '\\'; DirName[i] = 0; } else { StrCpy(DirName, L"\\"); } for (FileNameIndex = 0; FileNames[FileNameIndex]; FileNameIndex++) { // build full absolute path name StrCpy(FileName, DirName); StrCat(FileName, FileNames[FileNameIndex]); // check for presence of the file if (RootDir->Open(RootDir, &BootFile, FileName, EFI_FILE_MODE_READ, 0) != EFI_SUCCESS) continue; BootFile->Close(BootFile); // make a full device path for the image file DevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, FileName); // load the image into memory Status = BS->LoadImage(FALSE, ImageHandle, DevicePath, NULL, 0, &LoaderHandle); FreePool(DevicePath); if (EFI_ERROR(Status)) { Print(L"Can not load the file %s\n", FileName); return Status; } // start it! BS->StartImage(LoaderHandle, NULL, NULL); // just in case we get control back... break; } return EFI_SUCCESS; }
/** 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; }