522 lines
11 KiB
C
522 lines
11 KiB
C
/** @file
|
|
SnapScree driver for capature screen image to BMP file.
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
|
|
#include "SnapDialog.h"
|
|
#include "SnapLib.h"
|
|
#include "SnapWin.h"
|
|
|
|
//#include EFI_PROTOCOL_DEFINITION (FileInfo)
|
|
//#include EFI_PROTOCOL_DEFINITION (FileSystemInfo)
|
|
//#include EFI_PROTOCOL_DEFINITION (SimpleFileSystem)
|
|
|
|
#include <Guid/FileInfo.h>
|
|
#include <Guid/FileSystemInfo.h>
|
|
#include <Protocol/SimpleFileSystem.h>
|
|
|
|
|
|
#define DIALOG_NORMAL_ATTR EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLUE)
|
|
#define DIALOG_ACCENT_ATTR EFI_TEXT_ATTR (EFI_WHITE, EFI_CYAN)
|
|
|
|
#define MSG_DIALOG_HEIGHT 3
|
|
|
|
#define MAX_DISK_NAME_SIZE 256
|
|
|
|
#define MAX_DIALOG_ITEM 10
|
|
|
|
#define FS_ITEM_SIGNATURE SIGNATURE_32('D','I','A','i')
|
|
#define FS_ITEM_FROM_LINK(a) CR(a, FS_ITEM, Link, SIGNATURE_32('D','I','A','i'));
|
|
|
|
//
|
|
// Global variable
|
|
//
|
|
FS_DIALOG gFsDialog;
|
|
|
|
CHAR16 *gDiskTypeStr[] = {
|
|
L" IDE",
|
|
L"SCSI",
|
|
L" USB",
|
|
L"AHCI",
|
|
L"UNKN"
|
|
};
|
|
|
|
CHAR16 *
|
|
MakeFsName (
|
|
UINTN AIndex,
|
|
DISK_TYPE DiskType,
|
|
CHAR16 *ADiskName,
|
|
CHAR16 *AVolumeName,
|
|
CHAR16 *AVolumeSize
|
|
)
|
|
{
|
|
CHAR16 *FsName;
|
|
CHAR16 *FsSeparate = L":";
|
|
CHAR16 *DsSeparate = L"\\";
|
|
CHAR16 FsIndexStr[3] = L" 1";
|
|
CHAR16 DiskName[13] = L" ";
|
|
CHAR16 VolumeName[12] = L" ";
|
|
CHAR16 VolumeSize[12] = L" MB ";
|
|
CHAR16 *DiskTypeStr;
|
|
UINTN FsNameSize;
|
|
UINTN Index;
|
|
UINTN Len;
|
|
UINTN FsNameLen;
|
|
|
|
|
|
FsIndexStr[1] = (CHAR16) (FsIndexStr[1] + AIndex);
|
|
|
|
DiskTypeStr = gDiskTypeStr[DiskType];
|
|
|
|
if (ADiskName != NULL) {
|
|
StrnCpyS (DiskName, sizeof (DiskName) / sizeof (CHAR16), ADiskName, 12);
|
|
}
|
|
|
|
if (AVolumeName != NULL) {
|
|
StrnCpyS (VolumeName, sizeof (VolumeName) / sizeof (CHAR16), AVolumeName, 11);
|
|
}
|
|
|
|
if (AVolumeSize != NULL) {
|
|
Len = StrLen (AVolumeSize);
|
|
|
|
if (Len > 9) {
|
|
Len = 9;
|
|
}
|
|
|
|
Index = 9 - Len;
|
|
StrnCpyS (&VolumeSize[Index], sizeof (VolumeName) / sizeof (CHAR16) - Index, AVolumeSize, 9-Index);
|
|
}
|
|
|
|
// 1: AHCI\JetFlash \MURPHY_128M 120.5 MB
|
|
// 2: IDE \ST300845AS \WINDOW2008 1 TB
|
|
FsNameLen = 2+ 4 + 12 + 11 + 11 + 3;
|
|
FsNameSize = (FsNameLen + 1) * sizeof(CHAR16);
|
|
|
|
FsName = AllocatePool(FsNameSize);
|
|
|
|
if (FsName == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
for (Index=0; Index < FsNameLen; Index++)
|
|
FsName[Index] = L' ';
|
|
|
|
StrCpyS (FsName, FsNameLen + 1, FsIndexStr); // FS1
|
|
StrCatS (FsName, FsNameLen + 1, FsSeparate); // FS1:
|
|
StrCatS (FsName, FsNameLen + 1, DiskTypeStr); // FS1: USB
|
|
StrCatS (FsName, FsNameLen + 1, DsSeparate); // FS1: USB/
|
|
StrCatS (FsName, FsNameLen + 1, DiskName); // FS1: USB/JetFlash
|
|
StrCatS (FsName, FsNameLen + 1, DsSeparate); // FS1: USB/JetFlash /
|
|
StrCatS (FsName, FsNameLen + 1, VolumeName); // FS1: USB/JetFlash /MURPHY_128M
|
|
|
|
Len = StrLen (FsName);
|
|
for (Index = Len; Index < 32; Index++)
|
|
FsName[Index] = L' ';
|
|
FsName[Index] = 0;
|
|
|
|
StrCatS (FsName, FsNameLen + 1, VolumeSize); // FS1: USB/JetFlash /MURPHY_128M 120.8 MB
|
|
|
|
return FsName;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TFsDialogAddItem (
|
|
FS_DIALOG *FsDialog,
|
|
EFI_HANDLE FsHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE ParentHandle;
|
|
DISK_TYPE DiskType = DT_UNKNOW;
|
|
CHAR16 *DiskName = NULL;
|
|
CHAR16 *VolumnName = NULL;
|
|
CHAR16 *VolumnSize = NULL;
|
|
FS_ITEM *FsItem;
|
|
|
|
Status = GetParentHandle (FsHandle, &ParentHandle);
|
|
if (EFI_ERROR(Status))
|
|
return EFI_UNSUPPORTED;
|
|
|
|
if (IsRecordableDevice (ParentHandle) == FALSE)
|
|
return EFI_UNSUPPORTED;
|
|
|
|
if (Status == EFI_SUCCESS) {
|
|
DiskType = GetDiskInfoType (ParentHandle);
|
|
DiskName = GetDiskInfoName (ParentHandle);
|
|
}
|
|
else {
|
|
ParentHandle = NULL;
|
|
}
|
|
|
|
VolumnName = GetVolumnName ( FsHandle);
|
|
VolumnSize = GetVolumnSizeAsString ( FsHandle);
|
|
|
|
FsItem = (FS_ITEM *) AllocateZeroPool (sizeof(FS_ITEM));
|
|
|
|
if (FsItem != NULL) {
|
|
FsItem->Signature = FS_ITEM_SIGNATURE;
|
|
FsItem->FsHandle = FsHandle;
|
|
FsItem->ParentHandle = ParentHandle;
|
|
FsItem->Title = MakeFsName (FsDialog->ItemCount, DiskType, DiskName, VolumnName, VolumnSize);
|
|
InsertTailList(&FsDialog->ItemHead, &FsItem->Link);
|
|
FsDialog->ItemCount++;
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
else {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
if (DiskName != NULL)
|
|
FreePool (DiskName);
|
|
|
|
if (VolumnName != NULL)
|
|
FreePool (VolumnName);
|
|
|
|
if (VolumnSize != NULL)
|
|
FreePool (VolumnSize);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TFsDialogCreate (
|
|
UINT16 X,
|
|
UINT16 Y,
|
|
CHAR16 *Title,
|
|
DIALOG_PROC DialogProc,
|
|
FS_DIALOG **AFsDialog
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN HandleCount;
|
|
UINTN Index;
|
|
UINTN Len;
|
|
UINTN MaxLen = 0;
|
|
FS_DIALOG *FsDialog;
|
|
FS_ITEM *FsItem;
|
|
LIST_ENTRY *Link;
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiSimpleFileSystemProtocolGuid,
|
|
NULL,
|
|
&HandleCount,
|
|
&HandleBuffer
|
|
);
|
|
|
|
if (EFI_ERROR(Status))
|
|
return Status;
|
|
|
|
FsDialog = (FS_DIALOG *) AllocateZeroPool (sizeof(FS_DIALOG));
|
|
|
|
if (FsDialog == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
|
|
InitializeListHead(&FsDialog->ItemHead);
|
|
|
|
FsDialog->DialogProc = DialogProc;
|
|
|
|
// Add Item to FsDialog
|
|
for (Index=0; Index < HandleCount; Index++) {
|
|
|
|
Status = TFsDialogAddItem (FsDialog, HandleBuffer[Index]);
|
|
|
|
if (FsDialog->ItemCount >= MAX_DIALOG_ITEM)
|
|
break;
|
|
}
|
|
|
|
if (FsDialog->ItemCount == 0) {
|
|
FreePool (FsDialog);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
// looking for max string length
|
|
Link = FsDialog->ItemHead.ForwardLink;
|
|
while (Link != &FsDialog->ItemHead) {
|
|
|
|
FsItem = FS_ITEM_FROM_LINK(Link);
|
|
Len = StrLen (FsItem->Title);
|
|
|
|
if (Len > MaxLen)
|
|
MaxLen = Len;
|
|
|
|
Link = Link->ForwardLink;
|
|
}
|
|
|
|
// initialize default item as selection
|
|
FsDialog->Index = 0;
|
|
FsDialog->CurrLink = FsDialog->ItemHead.ForwardLink;
|
|
|
|
// Create a window object
|
|
Status = TWinCreate (
|
|
X,
|
|
Y,
|
|
(UINT16) MaxLen,
|
|
(UINT16) FsDialog->ItemCount,
|
|
TRUE,
|
|
Title,
|
|
&FsDialog->Win
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
TFsDialogDestroy (FsDialog);
|
|
}
|
|
else {
|
|
*AFsDialog = FsDialog;
|
|
}
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
TFsDialogPrintItem (
|
|
FS_DIALOG *Dialog,
|
|
UINTN Index,
|
|
UINTN Attribute
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
FS_ITEM *FsItem;
|
|
UINT16 Y;
|
|
|
|
if (Index >= Dialog->ItemCount)
|
|
return;
|
|
|
|
Y = (UINT16) Index;
|
|
|
|
Link = Dialog->ItemHead.ForwardLink;
|
|
|
|
while (Index > 0) {
|
|
Link = Link->ForwardLink;
|
|
Index--;
|
|
}
|
|
|
|
FsItem = FS_ITEM_FROM_LINK (Link);
|
|
|
|
TWinSetAttribue (Dialog->Win, Attribute);
|
|
TWinPrintAt (Dialog->Win, 0, Y, L"%s", FsItem->Title);
|
|
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
TFsDialogExec (
|
|
FS_DIALOG *Dialog,
|
|
EFI_HANDLE *Result
|
|
)
|
|
{
|
|
UINTN Index;
|
|
TWINDOW *Win;
|
|
EFI_INPUT_KEY EfiKey;
|
|
INT16 OldIndex;
|
|
FS_ITEM *FsItem;
|
|
|
|
Win = Dialog->Win;
|
|
|
|
TWinShow (Win);
|
|
|
|
// Print all item
|
|
for (Index = 0; Index < Dialog->ItemCount; Index++) {
|
|
TFsDialogPrintItem (Dialog, Index, DIALOG_NORMAL_ATTR);
|
|
}
|
|
|
|
TFsDialogPrintItem (Dialog, Dialog->Index, DIALOG_ACCENT_ATTR);
|
|
|
|
OldIndex = Dialog->Index;
|
|
|
|
while (TRUE) {
|
|
GetKey(&EfiKey);
|
|
|
|
switch (EfiKey.ScanCode) {
|
|
case SCAN_UP :
|
|
Dialog->Index--;
|
|
Dialog->CurrLink = Dialog->CurrLink->BackLink;
|
|
if (Dialog->Index < 0) {
|
|
Dialog->Index = (INT16)(Dialog->ItemCount - 1);
|
|
Dialog->CurrLink = Dialog->ItemHead.BackLink;
|
|
}
|
|
break;
|
|
|
|
case SCAN_DOWN :
|
|
Dialog->Index++;
|
|
Dialog->CurrLink = Dialog->CurrLink->ForwardLink;
|
|
|
|
if (Dialog->Index >= (INT16)Dialog->ItemCount) {
|
|
|
|
Dialog->Index = 0;
|
|
Dialog->CurrLink = Dialog->ItemHead.ForwardLink;
|
|
}
|
|
break;
|
|
|
|
case SCAN_ESC :
|
|
return EFI_ABORTED;
|
|
|
|
default :
|
|
if (EfiKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
|
|
FsItem = FS_ITEM_FROM_LINK(Dialog->CurrLink);
|
|
*Result = FsItem->FsHandle;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (Dialog->Index != OldIndex) {
|
|
TFsDialogPrintItem (Dialog, OldIndex, DIALOG_NORMAL_ATTR);
|
|
TFsDialogPrintItem (Dialog, Dialog->Index, DIALOG_ACCENT_ATTR);
|
|
OldIndex = Dialog->Index;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
TFsDialogDestroy (
|
|
FS_DIALOG *FsDialog
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
FS_ITEM *FsItem;
|
|
|
|
Link = FsDialog->ItemHead.ForwardLink;
|
|
|
|
while (Link != &FsDialog->ItemHead) {
|
|
|
|
FsItem = FS_ITEM_FROM_LINK(Link);
|
|
|
|
Link = Link->ForwardLink;
|
|
|
|
RemoveEntryList (&(FsItem->Link));
|
|
|
|
if (FsItem->Title != NULL)
|
|
FreePool (FsItem->Title);
|
|
|
|
FreePool (FsItem);
|
|
}
|
|
|
|
TWinDestroy (FsDialog->Win);
|
|
|
|
FreePool (FsDialog);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TMsgDialogCreate (
|
|
CHAR16 *MessageStr,
|
|
MSG_DIALOG **AMsgDialog
|
|
)
|
|
{
|
|
TWINDOW *Win;
|
|
MSG_DIALOG *MsgDialog;
|
|
UINT16 Width;
|
|
UINT16 Height;
|
|
UINTN BufferSize;
|
|
|
|
Width = (UINT16)(StrLen(MessageStr) + 2);
|
|
Height = MSG_DIALOG_HEIGHT;
|
|
|
|
BufferSize = sizeof (MSG_DIALOG) + Width * sizeof(CHAR16);
|
|
MsgDialog = (MSG_DIALOG *) AllocateZeroPool (BufferSize);
|
|
|
|
if (MsgDialog == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
|
|
MsgDialog->Message = (CHAR16 *)((UINT8 *)MsgDialog + sizeof (MSG_DIALOG));
|
|
|
|
StrCpyS (MsgDialog->Message, Width, MessageStr);
|
|
|
|
TWinCreate(WIN_SCR_CENTER, WIN_SCR_CENTER, Width, Height, TRUE, L"Message", &Win);
|
|
|
|
MsgDialog->Win = Win;
|
|
|
|
*AMsgDialog = MsgDialog;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TMsgDialogShow (
|
|
MSG_DIALOG *MsgDialog
|
|
)
|
|
{
|
|
if (MsgDialog->IsShow == TRUE)
|
|
return EFI_SUCCESS;
|
|
|
|
MsgDialog->IsShow = TRUE;
|
|
|
|
TWinShow (MsgDialog->Win);
|
|
TWinPrintAt ( MsgDialog->Win, 1, 1, L"%s", MsgDialog->Message);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TMsgDialogRun (
|
|
MSG_DIALOG *MsgDialog
|
|
)
|
|
{
|
|
EFI_INPUT_KEY Key;
|
|
|
|
if (MsgDialog->IsShow == FALSE) {
|
|
TMsgDialogShow (MsgDialog);
|
|
}
|
|
|
|
GetKey(&Key);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
TMsgDialogDestroy (
|
|
MSG_DIALOG *MsgDialog
|
|
)
|
|
{
|
|
|
|
if (MsgDialog != NULL) {
|
|
TWinDestroy (MsgDialog->Win);
|
|
FreePool (MsgDialog);
|
|
}
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PopUpMessage (
|
|
CHAR16 *MessageStr
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
MSG_DIALOG *MsgDialog;
|
|
|
|
Status = TMsgDialogCreate ( MessageStr, &MsgDialog);
|
|
if (EFI_ERROR(Status))
|
|
return Status;
|
|
|
|
TMsgDialogRun( MsgDialog);
|
|
|
|
Status = TMsgDialogDestroy (MsgDialog);
|
|
|
|
return Status;
|
|
}
|
|
|