EFI_STATUS EFIAPI efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { EFI_INPUT_KEY efi_input_key; int a = 10, b = 20; InitializeLib(ImageHandle, SystemTable); //Print(L"Hello, world!\n"); terra_main(L"Hello, Terra from C!\n"); Print(L"%d + %d = %d\n", a, b, terra_add(a,b)); Print(L"%s\n", SystemTable->FirmwareVendor); EFI_STATUS status; EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; status = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop); if(EFI_ERROR(status)) return status; status = uefi_call_wrapper(SystemTable->BootServices->LocateProtocol, 3, &GraphicsOutputProtocol, NULL, &gop); Print(L"Framebuffer base is at %lx\n", gop->Mode->FrameBufferBase); print_modes(gop); Print(L"\n\n\nHit any key\n"); WaitForSingleEvent(SystemTable->ConIn->WaitForKey, 0); status = uefi_call_wrapper(SystemTable->ConIn->ReadKeyStroke, 2, SystemTable->ConIn, &efi_input_key); paint_screen(gop, (UINT32)0x00FF0000); uefi_call_wrapper(BS->Stall, 1, 2 * 1000 * 1000); paint_screen(gop, (UINT32)0x0000FF00); uefi_call_wrapper(BS->Stall, 1, 2 * 1000 * 1000); paint_screen(gop, (UINT32)0x000000FF0); // FROM: https://github.com/vathpela/gnu-efi/blob/master/apps/t7.c Print(L"\n\n\nHit any key to exit this image\n"); WaitForSingleEvent(SystemTable->ConIn->WaitForKey, 0); uefi_call_wrapper(SystemTable->ConOut->OutputString, 2, SystemTable->ConOut, L"\n\n"); status = uefi_call_wrapper(SystemTable->ConIn->ReadKeyStroke, 2, SystemTable->ConIn, &efi_input_key); Print(L"ScanCode: %xh UnicodeChar: %xh\n", efi_input_key.ScanCode, efi_input_key.UnicodeChar); 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; }
VOID efi_pause () { EFI_INPUT_KEY Key; WaitForSingleEvent (ST->ConIn->WaitForKey, 0); uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &Key); }
//获得键盘输入扫描码 UINT16 keyGetInput(){ EFI_INPUT_KEY Key; EFI_STATUS Status; WaitForSingleEvent (ST->ConIn->WaitForKey, 0); Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key); if(Key.UnicodeChar == 0xD) //enter return KEY_ENTER; else return Key.ScanCode; }
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { InitializeLib(image, systab); Print(L"HelloLib application started\n"); Print(L"\n\n\nHit any key to exit this image\n"); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n"); return EFI_SUCCESS; }
VOID WaitForEventWithTimeout ( IN EFI_EVENT Event, IN UINTN Timeout, IN UINTN Row, IN UINTN Column, IN CHAR16 *String, IN EFI_INPUT_KEY TimeoutKey, OUT EFI_INPUT_KEY *Key ) /*++ Routine Description: function prints a string for the given number of seconds until either the timeout expires, or the user presses a key. Arguments: Event - The event to wait for Timeout - A timeout value in 1 second units. Row - A row to print String Column - A column to print String String - The string to display on the standard output device TimeoutKey - The key to return in Key if a timeout occurs Key - Either the key the user pressed or TimeoutKey if the Timeout expired. Returns: none --*/ { EFI_STATUS Status; while (Timeout > 0) { PrintAt (Column, Row, String, Timeout); Status = WaitForSingleEvent (Event, 10000000); if (Status == EFI_SUCCESS) { if (!EFI_ERROR(tST->ConIn->ReadKeyStroke (tST->ConIn, Key))) { return; } } Timeout--; } *Key = TimeoutKey; }
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_INPUT_KEY efi_input_key; EFI_STATUS efi_status; InitializeLib(image, systab); Print(L"HelloLib application started\n"); Print(L"\n\n\nHit any key to exit this image\n"); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n"); efi_status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &efi_input_key); Print(L"ScanCode: %xh UnicodeChar: %xh CallRtStatus: %x\n", efi_input_key.ScanCode, efi_input_key.UnicodeChar, efi_status); return EFI_SUCCESS; }
VOID WaitForEventWithTimeout ( IN EFI_EVENT Event, IN UINTN Timeout, IN UINTN Row, IN UINTN Column, IN CHAR16 *String, IN EFI_INPUT_KEY TimeoutKey, OUT EFI_INPUT_KEY *Key ) { EFI_STATUS Status; do { PrintAt (Column, Row, String, Timeout); Status = WaitForSingleEvent (Event, 10000000); if (Status == EFI_SUCCESS) { if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) { return; } } } while (Timeout > 0); CopyMem(Key, &TimeoutKey, sizeof(EFI_INPUT_KEY)); }
/** Function show progress bar to wait for user input. @param TimeoutDefault The fault time out value before the system continue to boot. @retval EFI_SUCCESS User pressed some key except "Enter" @retval EFI_TIME_OUT Timeout expired or user press "Enter" **/ EFI_STATUS ShowProgress ( IN UINT16 TimeoutDefault ) { CHAR16 *TmpStr; UINT16 TimeoutRemain; EFI_STATUS Status; EFI_INPUT_KEY Key; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; if (TimeoutDefault != 0) { DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n")); SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION)); if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { // // Clear the progress status bar first // if (TmpStr != NULL) { PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0); } } TimeoutRemain = TimeoutDefault; while (TimeoutRemain != 0) { DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain)); Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND); if (Status != EFI_TIMEOUT) { break; } TimeoutRemain--; if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { // // Show progress // if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault), 0 ); } } } if (TmpStr != NULL) { gBS->FreePool (TmpStr); } // // Timeout expired // if (TimeoutRemain == 0) { return EFI_TIMEOUT; } } // // User pressed some key // if (!PcdGetBool (PcdConInConnectOnDemand)) { Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); if (EFI_ERROR (Status)) { return Status; } if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { // // User pressed enter, equivalent to select "continue" // return EFI_TIMEOUT; } } return EFI_SUCCESS; }
EFI_STATUS pciUtilAdv( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Collect PCI Data Arguments: Returns: --*/ { BOOLEAN isWaiting; UINT8 *Value8; UINT16 BarRow; UINT16 BarOffset; UINT16 BarStartPosition; UINT16 BarEndPosition; UINT16 PciDeviceNumber; UINT16 ConfCol; UINT16 ConfColStart; UINT16 ConfColEnd; UINT16 ConfColOffset; UINT16 ConfRow; UINT16 ConfRowEnd; UINT16 ConfRowStart; UINT16 ConfRowOffset; CHAR16 StrInput[3]; SHELL_MODE Mode; // EFI_STATUS Status; EFI_INPUT_KEY KeyBuffer; PCITable PciTable[30]; // UINTN V; InitializeShellApplication(ImageHandle, SystemTable); isWaiting = 1; PciDeviceNumber = 0; BarStartPosition = 0; BarRow = 0; BarOffset = 2; ConfColOffset = 3; ConfCol = 0; ConfColStart = 0; ConfColEnd = ConfColStart + 15; ConfRow = 0; ConfRowOffset = 1; ConfRowEnd = 15; ConfRowStart = 0; Mode = DEVICE_LIST_MODE; ReadoutPCI(&PciDeviceNumber, PciTable ); BarEndPosition = BarRow + PciDeviceNumber; // Print(L"%d\n\r", PciDeviceNumber); DumpPCI(PciDeviceNumber, PciTable); while(isWaiting){ // Block Wait for Key WaitForSingleEvent (ST->ConIn->WaitForKey, 100); ST->ConIn->ReadKeyStroke (ST->ConIn, &KeyBuffer); switch ( KeyBuffer.ScanCode + Mode ) { // // Press ESC // case 0x117: ST->ConOut->OutputString(ST->ConOut,L"hello, world\n\r"); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLACK ); ST->ConOut->ClearScreen(ST->ConOut); isWaiting = 0; break; // // Press ESC // case 0x217: ST->ConOut->OutputString(ST->ConOut,L"hello, world\n\r"); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLACK ); ST->ConOut->ClearScreen(ST->ConOut); isWaiting = 0; break; // // Press Move Up 1 Row - DEVICE_LIST_MODE // case 0x101: if (BarRow == BarStartPosition){ BarRow = BarStartPosition; } else BarRow--; ST->ConOut->ClearScreen(ST->ConOut); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0); DumpPCI(PciDeviceNumber, PciTable); ST->ConOut->SetCursorPosition(ST->ConOut, 0, BarRow + BarOffset); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_GREEN ); // ST->ConOut->OutputString(ST->ConOut,L"hello, Rachel\n\r"); Print(L" %-02x ", PciTable[ BarRow - BarStartPosition].Bus ); Print(L"%-02x ", PciTable[ BarRow - BarStartPosition].Device ); Print(L"%-02x ", PciTable[ BarRow - BarStartPosition].Func ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Hdr.VendorId ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Hdr.DeviceId ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemVendorID ); Print(L"%-04x", PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemID ); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLACK ); ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY ); break; // // Press Move Down 1 Row - DEVICE_LIST_MODE // case 0x102: BarRow++; if (BarRow >= BarEndPosition){ BarRow = BarEndPosition - 1; } ST->ConOut->ClearScreen(ST->ConOut); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0); DumpPCI(PciDeviceNumber, PciTable); ST->ConOut->SetCursorPosition(ST->ConOut, 0, BarRow + BarOffset); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_GREEN ); // ST->ConOut->OutputString(ST->ConOut,L"hello, Rachel\n\r"); Print(L" %-02x ", PciTable[ BarRow - BarStartPosition].Bus ); Print(L"%-02x ", PciTable[ BarRow - BarStartPosition].Device ); Print(L"%-02x ", PciTable[ BarRow - BarStartPosition].Func ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Hdr.VendorId ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Hdr.DeviceId ); Print(L"%-04x ", PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemVendorID ); Print(L"%-04x", PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemID ); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLACK ); ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTGRAY ); break; // // Press Move Up 1 Row - CONF_MODE // case 0x201: if (ConfRow == ConfRowStart){ ConfRow = ConfRowStart; } else ConfRow--; DumpPciConfigureSpace( BarRow, PciTable); ST->ConOut->SetAttribute(ST->ConOut, EFI_RED ); ST->ConOut->SetCursorPosition( ST->ConOut, ConfCol * 3 + ConfColOffset, ConfRow + ConfRowOffset ); Value8 = (UINT8*) (PciTable + BarRow); Print(L"%-02x", *(Value8 + ( ConfRow * 16) + ConfCol) ); //Print(L" Row = %d", ConfRow); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLUE ); break; // // Press Move Down 1 Row - CONF_MODE // case 0x202: ConfRow++; if (ConfRow >= ConfRowEnd){ ConfRow = ConfRowEnd; } ST->ConOut->ClearScreen(ST->ConOut); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0); DumpPciConfigureSpace(BarRow, PciTable); ST->ConOut->SetAttribute(ST->ConOut, EFI_RED ); ST->ConOut->SetCursorPosition(ST->ConOut, ConfCol * 3 + ConfColOffset, ConfRow + ConfRowOffset ); Value8 = (UINT8*) (PciTable + BarRow); Print(L"%-02x", *(Value8 + (ConfRow * 16 + ConfCol)) ); //Print(L" Row = %d", ConfRow); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLUE ); break; // // Press Move Right - CONF MODE // case 0x203: ConfCol++; if (ConfCol >= ConfColEnd){ ConfCol= ConfColEnd; } ST->ConOut->ClearScreen(ST->ConOut); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0); DumpPciConfigureSpace(BarRow, PciTable); ST->ConOut->SetAttribute(ST->ConOut, EFI_RED ); ST->ConOut->SetCursorPosition(ST->ConOut, ConfCol *3 + ConfColOffset, ConfRow + ConfRowOffset ); Value8 = (UINT8*) (PciTable + BarRow); Print(L"%-02x", *(Value8 + (ConfRow * 16 + ConfCol)) ); // Print(L" Col = %d", ConfCol); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLUE ); break; // // Press Move Left - CONF_MODE // case 0x204: if (ConfCol == ConfColStart){ ConfCol= ConfColStart; } else ConfCol--; ST->ConOut->ClearScreen(ST->ConOut); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0); DumpPciConfigureSpace(BarRow, PciTable); ST->ConOut->SetAttribute(ST->ConOut, EFI_RED ); ST->ConOut->SetCursorPosition(ST->ConOut, ConfCol * 3 + ConfColOffset, ConfRow + ConfRowOffset ); Value8 = (UINT8*) (PciTable + BarRow); Print(L"%-02x", *(Value8 + (ConfRow * 16 + ConfCol)) ); // Print(L" Col = %d", ConfCol); ST->ConOut->SetAttribute(ST->ConOut, EFI_BACKGROUND_BLUE ); break; // // Press F1 - Dump PCI // case 0x20B: DumpPCI(1, PciTable); Mode = DEVICE_LIST_MODE; break; // // Press F2 - Dump Conf Space // case 0x10C: // DrawDumpPciConfigureSpaceBorder(); DumpPciConfigureSpace(BarRow, PciTable); Mode = CONFIGURE_SPACE_MODE; break; // // Press "F3" - CONF_MODE // case 0x20D: DumpPciConfigureSpaceWord(BarRow, PciTable ); Mode = CONFIGURE_SPACE_MODE; break; default: break; } // // Press "Enter" - DEVICE_LIST_MODE // if ( (KeyBuffer.UnicodeChar == 0x000D) && ( Mode == DEVICE_LIST_MODE) ){ Mode = CONFIGURE_SPACE_MODE; DumpPciConfigureSpace( BarRow, PciTable); } // // Press "Enter" - CONF_MODEs // else if( (KeyBuffer.UnicodeChar == 0x000D) && (Mode == CONFIGURE_SPACE_MODE) ) { // Mode = DEVICE_LIST_MODE; ST->ConOut->SetAttribute(ST->ConOut, EFI_RED ); ST->ConOut->SetCursorPosition(ST->ConOut, 0, 22 ); Input( L"Modify Value to :", StrInput, sizeof(StrInput)/sizeof(CHAR16) ); // V = xtoi(StrInput); WriteValueToPciConfigSpace8(StrInput, PciTable, BarRow, ConfRow *16 + ConfCol ); DumpPciConfigureSpace( BarRow, PciTable); /* ST->ConOut->SetCursorPosition(ST->ConOut, 0, 22 ); Print(L"%-02x", V); */ } } return EFI_SUCCESS; }
void WaitKey(void) { ST->ConIn->Reset(ST->ConIn, FALSE); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); }
EFI_STATUS EfiMain(EFI_HANDLE hImage, EFI_SYSTEM_TABLE *pST) { EFI_LOADED_IMAGE *pImage; EFI_STATUS nStatus; EFI_HANDLE hDriver, *hBlkDevs; UINTN nBlkDevs; EFI_DEVICE_PATH *pBootPart, *pBootDisk = NULL; g_hImage = hImage; InitializeLib(hImage, pST); Print(L"%H\n*** UEFI:NTFS multiboot ***"); if (EFI_ERROR((nStatus = BS->OpenProtocol(hImage, &LoadedImageProtocol, &pImage, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) { Print(L"%E\nUnable to convert handle to interface: %r\n", nStatus); goto end; } pBootPart = DevicePathFromHandle(pImage->DeviceHandle); pBootDisk = GetParentDevice(pBootPart); CHAR16 *pszDev = DevicePathToStr(pBootDisk); Print(L"%N\nDisk: %s\n", pszDev); FreePool(pszDev); Print(L"%H\n[ INFO ] Disconnecting problematic File System drivers\n"); DisconnectBlockingDrivers(); Print(L"%H\n[ WAIT ] Loading NTFS driver"); EFI_DEVICE_PATH *pDrvPath = FileDevicePath(pImage->DeviceHandle, DriverPath); if (pDrvPath == NULL) { Print(L"%E\r[ FAIL ] Unable to construct path to NTFS driver\n"); goto end; } nStatus = BS->LoadImage(FALSE, hImage, pDrvPath, NULL, 0, &hDriver); FreePool(pDrvPath); if (EFI_ERROR(nStatus)) { Print(L"%E\r[ FAIL ] Unable to load NTFS driver: %r\n", nStatus); goto end; } if (EFI_ERROR((nStatus = BS->StartImage(hDriver, NULL, NULL)))) { Print(L"%E\r[ FAIL ] Unable to start NTFS driver: %r\n", nStatus); goto end; } Print(L"%H\r[ OK ] NTFS driver loaded and started\n"); LINKED_LOADER_PATH_LIST_NODE *list = NULL; EFI_DEVICE_PATH *ldr; if (EFI_ERROR((nStatus = BS->LocateHandleBuffer(ByProtocol, &BlockIoProtocol, NULL, &nBlkDevs, &hBlkDevs)))) { Print(L"%E\r[ FAIL ] Unable to enumerate block devices: %r\n", nStatus); goto end; } for (UINTN i = 0; i < nBlkDevs; i++) { EFI_DEVICE_PATH *pDevice = DevicePathFromHandle(hBlkDevs[i]); pszDev = DevicePathToStr(pDevice); Print(L"%N\r[ INFO ] Probing %d devices... [%d] %s", nBlkDevs, i + 1, pszDev); FreePool(pszDev); if (CompareDevicePaths(pDevice, pBootPart) == 0) continue; if (CompareDevicePaths(pDevice, pBootDisk) == 0) continue; EFI_DEVICE_PATH *pDisk = GetParentDevice(pDevice); _Bool probe = CompareDevicePaths(pDisk, pBootDisk) == 0; FreePool(pDisk); #if !defined(_DEBUG) if (!probe) continue; #endif EFI_BLOCK_IO *blkIo; if (EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &BlockIoProtocol, &blkIo, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) { Print(L"%E\n[ WARN ] Unable to open block device, skipping: %r\n", nStatus); continue; } //No media or not a partition. if ((blkIo->Media == NULL) || (!blkIo->Media->LogicalPartition)) continue; CHAR8 *buffer = AllocatePool(blkIo->Media->BlockSize); if (buffer == NULL) { Print(L"%E\n[ WARN ] Unable to allocate buffer of size %d\n", blkIo->Media->BlockSize); continue; } nStatus = blkIo->ReadBlocks(blkIo, blkIo->Media->MediaId, 0, blkIo->Media->BlockSize, buffer); _Bool isNTFS = CompareMem(&buffer[3], NTFSMagic, sizeof(NTFSMagic)) == 0; FreePool(buffer); if (EFI_ERROR(nStatus)) { Print(L"%E\n[ WARN ] Unable to read block device, skipping: %r\n", nStatus); continue; } if (!isNTFS) continue; Print(L"%H\n[ WAIT ] Attaching NTFS driver to device"); EFI_FILE_IO_INTERFACE *fs; nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, NULL, hImage, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); if (nStatus == EFI_UNSUPPORTED) { nStatus = BS->ConnectController(hBlkDevs[i], NULL, NULL, TRUE); } for (UINTN j = 0; j < NUM_RETRIES; j++) { if ((!EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, &fs, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))) { break; } Print(L"."); BS->Stall(DELAY * 1000000); } if(EFI_ERROR(nStatus)) { Print(L"%E\r[ WARN ] Unable to attach NTFS driver, skipping: %r\n", nStatus); continue; } Print(L"%H\r[ OK ] NTFS driver attached to current device\n"); Print(L"%H\r[ WAIT ] Locating EFI boot loader"); EFI_FILE *fsRoot; if (EFI_ERROR((nStatus = fs->OpenVolume(fs, &fsRoot)))) { Print(L"%E\r[ WARN ] Unable to open root directory, skipping: %r\n", nStatus); continue; } CHAR16 *loader = StrDuplicate(LoaderPath); if (EFI_ERROR((nStatus = SetPathCase(fsRoot, loader)))) { FreePool(loader); Print(L"%E\r[ WARN ] Unable to locate EFI boot loader on this device: %r\n", nStatus); continue; } Print(L"%H\r[ OK ] EFI boot loader located at %s\n", loader); ldr = FileDevicePath(hBlkDevs[i], loader); ListAppend(&list, ldr); FreePool(loader); } UINTN nListEntries = 0, nBootEntry = 0, nPage = 0, nTotalPage = 0; EFI_INPUT_KEY key; _Bool interactive = FALSE; ListTraverse(&list, CountEntries, 0, 0, &nListEntries); switch (nListEntries) { case 0: Print(L"%E\n[ FAIL ] No bootable partition\n", nStatus); nStatus = EFI_NOT_FOUND; goto end; case 1: goto boot; default: nTotalPage = (nListEntries - 1) / PAGE_SIZE + 1; while (1) { ST->ConOut->ClearScreen(ST->ConOut); Print(L"%H*** UEFI:NTFS Multiboot ***\n"); pszDev = DevicePathToStr(pBootDisk); Print(L"%NDisk: %s\n\n%H", pszDev); FreePool(pszDev); ListTraverse(&list, DisplayEntries, nPage * PAGE_SIZE, PAGE_SIZE, NULL); Print(L"%N\nPage %hd / %hd, %hd entries\n", nPage + 1, nTotalPage, nListEntries); Print(L"%H\n[F1 - F8] [1 - 8] %N Boot corresponding entry"); Print(L"%H\n[PgUp] [<] [-] %N Previous page"); Print(L"%H\n[PgDn] [>] [+] %N Next page"); if (!interactive) { INTN nCountDown = AUTOBOOT_TIME; Print(L"%N\n\n"); while (nCountDown >= 0) { Print(L"\rWill automatically boot the first entry in %d seconds...", nCountDown); if (WaitForSingleEvent(ST->ConIn->WaitForKey, 1000 * 1000 * 10) != EFI_TIMEOUT) { interactive = TRUE; break; } nCountDown--; } if (!interactive) { goto boot; } } else { WaitForSingleEvent(ST->ConIn->WaitForKey, 0); } ST->ConIn->ReadKeyStroke(ST->ConIn, &key); switch (key.UnicodeChar) { case L'1':case L'2':case L'3':case L'4':case L'5':case L'6':case L'7':case L'8': nBootEntry = nPage * PAGE_SIZE + (key.UnicodeChar - L'1'); goto boot; case L'+':case L'=':case L'>':case L'.': if ((nPage + 1) != nTotalPage) { nPage++; } break; case L'-':case L'_': case L'<': case L',': if (nPage != 0) { nPage--; } break; default: switch (key.ScanCode) { case 0x09: if (nPage != 0) { nPage--; } break; case 0x0a: if ((nPage + 1) != nTotalPage) { nPage++; } break; case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: nBootEntry = nPage * PAGE_SIZE + (key.ScanCode - 0x0b); goto boot; } } } } boot: ldr = NULL; Print(L"%H"); ST->ConOut->ClearScreen(ST->ConOut); ListTraverse(&list, ReadEntry, nBootEntry, 1, &ldr); ListTraverse(&list, DisplayEntries, nBootEntry, 1, NULL); if (ldr == NULL) { Print(L"%E\n[ FAIL ] No such boot entry\n", nStatus); nStatus = EFI_NOT_FOUND; goto end; } ldr = DuplicateDevicePath(ldr); ListTraverse(&list, DestroyEntries, 0, 0, NULL); ListDestroy(&list); EFI_HANDLE hChain; nStatus = BS->LoadImage(FALSE, hImage, ldr, NULL, 0, &hChain); FreePool(ldr); if (EFI_ERROR(nStatus)) { Print(L"%E\n[ FAIL ] Unable to load boot loader: %r\n", nStatus); goto end; } Print(L"%N"); if (EFI_ERROR((nStatus = BS->StartImage(hChain, NULL, NULL)))) { Print(L"%E\n[ FAIL ] Unable to start boot loader: %r\n", nStatus); goto end; } end: if (pBootDisk) FreePool(pBootDisk); if (EFI_ERROR(nStatus)) { Print(L"Press any key to exit\n"); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); ST->ConIn->ReadKeyStroke(ST->ConIn, &key); } return nStatus; }
EFI_STATUS MainInputBarRefresh ( VOID ) /*++ Routine Description: refresh function for MainInputBar, it will wait for user input Arguments: VOID Returns: EFI_SUCCESS --*/ { EFI_EDITOR_COLOR_UNION Orig; EFI_EDITOR_COLOR_UNION New; EFI_INPUT_KEY Key; UINTN Size; EFI_STATUS Status; BOOLEAN NoDisplay; UINTN Limit; UINTN PromptLen; // // variable initialization // Size = 0; Status = EFI_SUCCESS; // // free status string // EditorFreePool (MainEditor.StatusBar->StatusString); MainEditor.StatusBar->StatusString = PoolPrint (L""); if (MainEditor.StatusBar->StatusString == NULL) { return EFI_OUT_OF_RESOURCES; } // // back up the old screen attributes // Orig = MainEditor.ColorAttributes; New.Colors.Foreground = Orig.Colors.Background; New.Colors.Background = Orig.Colors.Foreground; Out->SetAttribute (Out, New.Data); // // clear input bar // EditorClearLine (INPUT_BAR_LOCATION); Out->SetCursorPosition (Out, 0, INPUT_BAR_LOCATION - 1); PrintToken (STRING_TOKEN (STR_EDIT_LIBINPUTBAR_MAININPUTBAR), HiiHandle, MainInputBar.Prompt); // // that's the maximum input length that can be displayed on screen // PromptLen = StrLen (MainInputBar.Prompt); Limit = MainEditor.ScreenSize.Column - PromptLen; // // this is a selection prompt, cursor will stay in edit area // actually this is for search , search/replace // if (StrStr (MainInputBar.Prompt, L"Yes/No")) { NoDisplay = TRUE; FileBufferRestorePosition (); Out->SetAttribute (Out, Orig.Data); } else { NoDisplay = FALSE; } // // wait for user input // for (;;) { WaitForSingleEvent (In->WaitForKey, 0); Status = In->ReadKeyStroke (In, &Key); if (EFI_ERROR (Status)) { continue; } // // pressed ESC // if (Key.ScanCode == SCAN_CODE_ESC) { Size = 0; Status = EFI_NOT_READY; break; } // // return pressed // if (Key.UnicodeChar == CHAR_LF || Key.UnicodeChar == CHAR_CR) { break; } else if (Key.UnicodeChar == CHAR_BS) { // // backspace // if (Size > 0) { Size--; MainInputBar.ReturnString[Size] = L'\0'; if (!NoDisplay) { MainInputBarPrintInput (); } } } else if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) { // // VALID ASCII char pressed // MainInputBar.ReturnString[Size] = Key.UnicodeChar; // // should be less than specified length // if (Size >= MainInputBar.StringSize) { continue; } Size++; MainInputBar.ReturnString[Size] = L'\0'; if (!NoDisplay) { MainInputBarPrintInput (); } else { // // if just choose yes/no // break; } } } MainInputBar.ReturnString[Size] = 0; FileBufferRestorePosition (); // // restore screen attributes // Out->SetAttribute (Out, Orig.Data); StatusBarNeedRefresh = TRUE; return Status; }