ACTIVE_PLATFROM = MdeModulePkg/MdeModulePkg.dsc # TARGET = RELEASE # TARGET_ARCH = X64 # DXE 64-, TOOL_CHAN_TAG = VS2013x86 # | VS2013 | GCC44 | ... | GCC49 | YOUR_FANCY_TOOLCHAIN,
Open another terminal in UDK2015 and in Linux / OSX, execute the command: . edksetup.sh BaseTools
In the case of Windows, the usual edksetup.bat without parameters is sufficient. - Done - Build end time: ... Build total time: ...
If instead of Done you see Failed , then something is wrong with your settings. I checked the above on VS2013x86 on Windows and GCC48 on Xubuntu 04/14/3 - MWRD . [Components] MdeModulePkg/Application/HelloWorld/HelloWorld.inf MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf ...
Add there your future .inf file along with the path to it relative to UDK2015 . I propose to create for it directly in MdeModulePkg the folder CrScreenshotDxe , and the INF file to call CrScreenshotDxe.inf . As you may have guessed, Cr is from CodeRush, and the author of this article is modesty itself. The result is something like this: [Components] MdeModulePkg/CrScreenshotDxe/CrScreenshotDxe.inf MdeModulePkg/Application/HelloWorld/HelloWorld.inf MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf ...
We save the changes and close the DSC-file, we will not change it again, if we don’t want to set up a debug output, but this is a completely different story. [Defines] # INF_VERSION = 0x00010005 # , 1.5 BASE_NAME = CrScreenshotDxe # FILE_GUID = cab058df-e938-4f85-8978-1f7e6aabdb96 # GUID MODULE_TYPE = DXE_DRIVER # VERSION_STRING = 1.0 # ENTRY_POINT = CrScreenshotDxeEntry # [Sources.common] # , common - CrScreenshotDxe.c # #... # , - , PNG, [Packages] # MdePkg/MdePkg.dec # , UEFI MdeModulePkg/MdeModulePkg.dec # , [LibraryClasses] # UefiBootServicesTableLib # UEFI Boot Services gBS UefiRuntimeServicesTableLib # UEFI Runtime services gRT UefiDriverEntryPoint # UEFI-, , DebugLib # DEBUG PrintLib # UnicodeSPrint, snprintf [Protocols] # gEfiGraphicsOutputProtocolGuid # gEfiSimpleTextInputExProtocolGuid # gEfiSimpleFileSystemProtocolGuid # [Depex] # , , gEfiGraphicsOutputProtocolGuid AND # , gEfiSimpleTextInputExProtocolGuid #
#include <Uefi.h> #include <Library/DebugLib.h> #include <Library/PrintLib.h> #include <Library/UefiDriverEntryPoint.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> #include <Protocol/GraphicsOutput.h> #include <Protocol/SimpleTextInEx.h> #include <Protocol/SimpleFileSystem.h> EFI_STATUS EFIAPI CrScreenshotDxeEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { return EFI_SUCCESS; }
EFI_STATUS EFIAPI CrScreenshotDxeEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_KEY_DATA KeyStroke; UINTN HandleCount; EFI_HANDLE *HandleBuffer = NULL; UINTN i; // Set keystroke to be LCtrl+LAlt+F12 KeyStroke.Key.ScanCode = SCAN_F12; KeyStroke.Key.UnicodeChar = 0; KeyStroke.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_LEFT_ALT_PRESSED; KeyStroke.KeyState.KeyToggleState = 0; // Locate all SimpleTextInEx protocols Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleTextInputExProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { DEBUG((-1, "CrScreenshotDxeEntry: gBS->LocateHandleBuffer returned %r\n", Status)); return EFI_UNSUPPORTED; } // For each instance for (i = 0; i < HandleCount; i++) { EFI_HANDLE Handle; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx; // Get protocol handle Status = gBS->HandleProtocol (HandleBuffer[i], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleTextInEx); if (EFI_ERROR (Status)) { DEBUG((-1, "CrScreenshotDxeEntry: gBS->HandleProtocol[%d] returned %r\n", i, Status)); continue; } // Register key notification function Status = SimpleTextInEx->RegisterKeyNotify( SimpleTextInEx, &KeyStroke, TakeScreenshot, &Handle); if (EFI_ERROR (Status)) { DEBUG((-1, "CrScreenshotDxeEntry: SimpleTextInEx->RegisterKeyNotify[%d] returned %r\n", i, Status)); } } // Free memory used for handle buffer if (HandleBuffer) gBS->FreePool(HandleBuffer); // Show driver loaded ShowStatus(0xFF, 0xFF, 0xFF); // White return EFI_SUCCESS; }
EFI_STATUS EFIAPI FindWritableFs ( OUT EFI_FILE_PROTOCOL **WritableFs ) { EFI_HANDLE *HandleBuffer = NULL; UINTN HandleCount; UINTN i; // Locate all the simple file system devices in the system EFI_STATUS Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (!EFI_ERROR (Status)) { EFI_FILE_PROTOCOL *Fs = NULL; // For each located volume for (i = 0; i < HandleCount; i++) { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs = NULL; EFI_FILE_PROTOCOL *File = NULL; // Get protocol pointer for current volume Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **) &SimpleFs); if (EFI_ERROR (Status)) { DEBUG((-1, "FindWritableFs: gBS->HandleProtocol[%d] returned %r\n", i, Status)); continue; } // Open the volume Status = SimpleFs->OpenVolume(SimpleFs, &Fs); if (EFI_ERROR (Status)) { DEBUG((-1, "FindWritableFs: SimpleFs->OpenVolume[%d] returned %r\n", i, Status)); continue; } // Try opening a file for writing Status = Fs->Open(Fs, &File, L"crsdtest.fil", EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); if (EFI_ERROR (Status)) { DEBUG((-1, "FindWritableFs: Fs->Open[%d] returned %r\n", i, Status)); continue; } // Writable FS found Fs->Delete(File); *WritableFs = Fs; Status = EFI_SUCCESS; break; } } // Free memory if (HandleBuffer) { gBS->FreePool(HandleBuffer); } return Status; }
EFI_STATUS EFIAPI TakeScreenshot ( IN EFI_KEY_DATA *KeyData ) { EFI_FILE_PROTOCOL *Fs = NULL; EFI_FILE_PROTOCOL *File = NULL; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Image = NULL; UINTN ImageSize; // Size in pixels UINT8 *PngFile = NULL; UINTN PngFileSize; // Size in bytes EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer = NULL; UINT32 ScreenWidth; UINT32 ScreenHeight; CHAR16 FileName[8+1+3+1]; // 0-terminated 8.3 file name EFI_TIME Time; UINTN i, j; // Find writable FS Status = FindWritableFs(&Fs); if (EFI_ERROR (Status)) { DEBUG((-1, "TakeScreenshot: Can't find writable FS\n")); ShowStatus(0xFF, 0xFF, 0x00); // Yellow return EFI_SUCCESS; } // Locate all instances of GOP Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { DEBUG((-1, "ShowStatus: Graphics output protocol not found\n")); return EFI_SUCCESS; } // For each GOP instance for (i = 0; i < HandleCount; i++) { do { // Break from do used instead of "goto error" // Handle protocol Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); if (EFI_ERROR (Status)) { DEBUG((-1, "ShowStatus: gBS->HandleProtocol[%d] returned %r\n", i, Status)); break; } // Set screen width, height and image size in pixels ScreenWidth = GraphicsOutput->Mode->Info->HorizontalResolution; ScreenHeight = GraphicsOutput->Mode->Info->VerticalResolution; ImageSize = ScreenWidth * ScreenHeight; // Get current time Status = gRT->GetTime(&Time, NULL); if (!EFI_ERROR(Status)) { // Set file name to current day and time UnicodeSPrint(FileName, 26, L"%02d%02d%02d%02d.png", Time.Day, Time.Hour, Time.Minute, Time.Second); } else { // Set file name to scrnshot.png UnicodeSPrint(FileName, 26, L"scrnshot.png"); } // Allocate memory for screenshot Status = gBS->AllocatePool(EfiBootServicesData, ImageSize * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL), (VOID **)&Image); if (EFI_ERROR(Status)) { DEBUG((-1, "TakeScreenshot: gBS->AllocatePool returned %r\n", Status)); break; } // Take screenshot Status = GraphicsOutput->Blt(GraphicsOutput, Image, EfiBltVideoToBltBuffer, 0, 0, 0, 0, ScreenWidth, ScreenHeight, 0); if (EFI_ERROR(Status)) { DEBUG((-1, "TakeScreenshot: GraphicsOutput->Blt returned %r\n", Status)); break; } // Check for pitch black image (it means we are using a wrong GOP) for (j = 0; j < ImageSize; j++) { if (Image[j].Red != 0x00 || Image[j].Green != 0x00 || Image[j].Blue != 0x00) break; } if (j == ImageSize) { DEBUG((-1, "TakeScreenshot: GraphicsOutput->Blt returned pitch black image, skipped\n")); ShowStatus(0x00, 0x00, 0xFF); // Blue break; } // Open or create output file Status = Fs->Open(Fs, &File, FileName, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0); if (EFI_ERROR (Status)) { DEBUG((-1, "TakeScreenshot: Fs->Open of %s returned %r\n", FileName, Status)); break; } // Convert BGR to RGBA with Alpha set to 0xFF for (j = 0; j < ImageSize; j++) { UINT8 Temp = Image[j].Blue; Image[j].Blue = Image[j].Red; Image[j].Red = Temp; Image[j].Reserved = 0xFF; } // Encode raw RGB image to PNG format j = lodepng_encode32(&PngFile, &PngFileSize, (CONST UINT8*)Image, ScreenWidth, ScreenHeight); if (j) { DEBUG((-1, "TakeScreenshot: lodepng_encode32 returned %d\n", j)); break; } // Write PNG image into the file and close it Status = File->Write(File, &PngFileSize, PngFile); File->Close(File); if (EFI_ERROR(Status)) { DEBUG((-1, "TakeScreenshot: File->Write returned %r\n", Status)); break; } // Show success ShowStatus(0x00, 0xFF, 0x00); // Green } while(0); // Free memory if (Image) gBS->FreePool(Image); if (PngFile) gBS->FreePool(PngFile); Image = NULL; PngFile = NULL; } // Show error if (EFI_ERROR(Status)) ShowStatus(0xFF, 0x00, 0x00); // Red return EFI_SUCCESS; }
#include <Uefi.h> // UEFI #define LODEPNG_NO_COMPILE_DECODER // PNG #define LODEPNG_NO_COMPILE_DISK // , .. fopen/fwrite #define LODEPNG_NO_COMPILE_ALLOCATORS // malloc/realloc/free, .. #define LODEPNG_NO_COMPILE_ERROR_TEXT // #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS // PNG, .. #if !defined(_MSC_VER) // size_t GCC, MS #define size_t UINTN #endif
And comment out the line with #include <string.h> , which we don't have either. You can, of course, create a local file with the same name, defining the type size_t there, but since we started to change it, we will change it. EFI_STATUS EFIAPI ShowStatus ( IN UINT8 Red, IN UINT8 Green, IN UINT8 Blue ) { // Determines the size of status square #define STATUS_SQUARE_SIDE 5 UINTN HandleCount; EFI_HANDLE *HandleBuffer = NULL; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Square[STATUS_SQUARE_SIDE * STATUS_SQUARE_SIDE]; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Backup[STATUS_SQUARE_SIDE * STATUS_SQUARE_SIDE]; UINTN i; // Locate all instances of GOP EFI_STATUS Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { DEBUG((-1, "ShowStatus: Graphics output protocol not found\n")); return EFI_UNSUPPORTED; } // Set square color for (i = 0 ; i < STATUS_SQUARE_SIDE * STATUS_SQUARE_SIDE; i++) { Square[i].Blue = Blue; Square[i].Green = Green; Square[i].Red = Red; Square[i].Reserved = 0x00; } // For each GOP instance for (i = 0; i < HandleCount; i ++) { // Handle protocol Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); if (EFI_ERROR (Status)) { DEBUG((-1, "ShowStatus: gBS->HandleProtocol[%d] returned %r\n", i, Status)); continue; } // Backup current image GraphicsOutput->Blt(GraphicsOutput, Backup, EfiBltVideoToBltBuffer, 0, 0, 0, 0, STATUS_SQUARE_SIDE, STATUS_SQUARE_SIDE, 0); // Draw the status square GraphicsOutput->Blt(GraphicsOutput, Square, EfiBltBufferToVideo, 0, 0, 0, 0, STATUS_SQUARE_SIDE, STATUS_SQUARE_SIDE, 0); // Wait 500ms gBS->Stall(500*1000); // Restore the backup GraphicsOutput->Blt(GraphicsOutput, Backup, EfiBltBufferToVideo, 0, 0, 0, 0, STATUS_SQUARE_SIDE, STATUS_SQUARE_SIDE, 0); } return EFI_SUCCESS; }
Source: https://habr.com/ru/post/274463/
All Articles