530 lines
13 KiB
C
530 lines
13 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1999 Intel Corporation
|
||
|
|
||
|
Module Name:
|
||
|
libFileImage.c
|
||
|
|
||
|
Abstract:
|
||
|
Definition of the File Image - the complete image of the file that
|
||
|
resides in memory
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _LIB_FILE_IMAGE
|
||
|
#define _LIB_FILE_IMAGE
|
||
|
|
||
|
#include "libMisc.h"
|
||
|
|
||
|
|
||
|
STATIC EFI_EDITOR_LINE* FileImageCreateNode (VOID);
|
||
|
STATIC VOID FileImageDeleteLines (VOID);
|
||
|
|
||
|
#define FILE_ATTRIBUTES EFI_FILE_MODE_READ | \
|
||
|
EFI_FILE_MODE_WRITE | \
|
||
|
EFI_FILE_MODE_CREATE
|
||
|
#define FILE_READ_WRITE EFI_FILE_MODE_READ | \
|
||
|
EFI_FILE_MODE_WRITE
|
||
|
#define FILE_CREATE EFI_FILE_MODE_READ | \
|
||
|
EFI_FILE_MODE_WRITE | \
|
||
|
EFI_FILE_MODE_CREATE
|
||
|
|
||
|
STATIC EFI_STATUS FileImageInit (EFI_HANDLE);
|
||
|
STATIC EFI_STATUS FileImageCleanup (VOID);
|
||
|
STATIC EFI_STATUS FileImageOpen (VOID);
|
||
|
STATIC EFI_STATUS FileImageRead (VOID);
|
||
|
STATIC EFI_STATUS FileImageClose (VOID);
|
||
|
STATIC EFI_STATUS FileImageWrite (VOID);
|
||
|
STATIC EFI_STATUS FileImageSetFilename (CHAR16*);
|
||
|
|
||
|
EFI_EDITOR_FILE_IMAGE FileImage = {
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0,
|
||
|
UNICODE_FILE,
|
||
|
USE_LF,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
FileImageCleanup,
|
||
|
FileImageInit,
|
||
|
FileImageOpen,
|
||
|
FileImageRead,
|
||
|
FileImageClose,
|
||
|
FileImageWrite,
|
||
|
FileImageSetFilename,
|
||
|
FALSE
|
||
|
};
|
||
|
|
||
|
EFI_EDITOR_FILE_IMAGE FileImageConst = {
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0,
|
||
|
UNICODE_FILE,
|
||
|
USE_LF,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
FileImageCleanup,
|
||
|
FileImageInit,
|
||
|
FileImageOpen,
|
||
|
FileImageRead,
|
||
|
FileImageClose,
|
||
|
FileImageWrite,
|
||
|
FileImageSetFilename,
|
||
|
FALSE
|
||
|
};
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageInit (
|
||
|
IN EFI_HANDLE ImageHandle
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_EDITOR_LINE *Line;
|
||
|
CHAR16 *CurDir;
|
||
|
UINTN i;
|
||
|
EFI_DEVICE_PATH *DevicePath;
|
||
|
|
||
|
CopyMem (&FileImage, &FileImageConst, sizeof(FileImage));
|
||
|
|
||
|
Status = BS->HandleProtocol (ImageHandle,&LoadedImageProtocol,&FileImage.LoadedImage);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
Print (L"Could not obtain Loaded Image Protocol\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
if (FileImage.LoadedImage->DeviceHandle != NULL) {
|
||
|
Status = BS->HandleProtocol (FileImage.LoadedImage->DeviceHandle,&DevicePathProtocol,&FileImage.DevicePath);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
Print (L"Could not obtain Device Path Protocol\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
|
||
|
Status = BS->HandleProtocol (FileImage.LoadedImage->DeviceHandle,&FileSystemProtocol,&FileImage.Vol);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
Print (L"Could not obtain File System Protocol\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
CurDir = ShellCurDir(NULL);
|
||
|
if (CurDir == NULL) {
|
||
|
Print (L"Could not get current working directory\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
for (i=0; i < StrLen(CurDir) && CurDir[i] != ':'; i++);
|
||
|
CurDir[i] = 0;
|
||
|
DevicePath = (EFI_DEVICE_PATH *)ShellGetMap (CurDir);
|
||
|
|
||
|
if (DevicePath == NULL) {
|
||
|
Print (L"Could not open volume for the filesystem\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
|
||
|
Status = LibDevicePathToInterface (&FileSystemProtocol, DevicePath, &FileImage.Vol);
|
||
|
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
Print (L"Could not obtain File System Protocol\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Status = FileImage.Vol->OpenVolume(FileImage.Vol,&FileImage.CurrentDir);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
Print (L"Could not open volume for the filesystem\n");
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
|
||
|
FileImage.FileName = PoolPrint(L"NewFile.txt");
|
||
|
|
||
|
FileImage.ListHead = AllocatePool(sizeof(LIST_ENTRY));
|
||
|
InitializeListHead(FileImage.ListHead);
|
||
|
|
||
|
Line = FileImageCreateNode();
|
||
|
MainEditor.FileBuffer->CurrentLine = FileImage.ListHead->Flink;
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageOpen (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
|
||
|
Status = FileImage.CurrentDir->Open (FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_ATTRIBUTES,0);
|
||
|
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
MainEditor.StatusBar->SetStatusString(L"File Could Not be Opened");
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
FileImage.FileIsOpen = TRUE;
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageCleanup (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_EDITOR_LINE *Blank;
|
||
|
|
||
|
FreePool (FileImage.FileName);
|
||
|
FileImageDeleteLines ();
|
||
|
|
||
|
Blank = LineCurrent();
|
||
|
RemoveEntryList(&Blank->Link);
|
||
|
FreePool(Blank->Buffer);
|
||
|
FreePool(Blank);
|
||
|
FreePool(FileImage.ListHead);
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageRead (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_EDITOR_LINE *Line = NULL;
|
||
|
UINTN i = 0;
|
||
|
UINTN LineSize;
|
||
|
VOID *FileBuffer;
|
||
|
CHAR16 *UnicodeBuffer;
|
||
|
CHAR8 *AsciiBuffer;
|
||
|
LIST_ENTRY *Blank;
|
||
|
UINTN FileSize = 0x100000;
|
||
|
|
||
|
FileBuffer = AllocatePool(FileSize);
|
||
|
|
||
|
if ( FileBuffer == NULL ) {
|
||
|
EditorError(EFI_OUT_OF_RESOURCES,L"Could not allocate File Buffer");
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
FileImage.FileHandle->Read(FileImage.FileHandle,&FileSize,FileBuffer);
|
||
|
|
||
|
if (FileSize == 0) {
|
||
|
FreePool (FileBuffer);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
AsciiBuffer = FileBuffer;
|
||
|
if (AsciiBuffer[0] == 0xff && AsciiBuffer[1] == 0xfe) {
|
||
|
FileImage.FileType = UNICODE_FILE;
|
||
|
FileSize /= 2;
|
||
|
UnicodeBuffer = FileBuffer;
|
||
|
++UnicodeBuffer;
|
||
|
FileSize--;
|
||
|
} else {
|
||
|
FileImage.FileType = ASCII_FILE;
|
||
|
}
|
||
|
|
||
|
FileImageDeleteLines ();
|
||
|
Blank = FileImage.ListHead->Flink;
|
||
|
RemoveEntryList (Blank);
|
||
|
|
||
|
for (i = 0; i < FileSize; i++) {
|
||
|
for (LineSize = i; LineSize < FileSize; LineSize++) {
|
||
|
if (FileImage.FileType == ASCII_FILE) {
|
||
|
if (AsciiBuffer[LineSize] == CHAR_CR) {
|
||
|
FileImage.NewLineType = USE_CRLF;
|
||
|
break;
|
||
|
} else if (AsciiBuffer[LineSize] == CHAR_LF) {
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
if (UnicodeBuffer[LineSize] == CHAR_CR) {
|
||
|
FileImage.NewLineType = USE_CRLF;
|
||
|
break;
|
||
|
} else if (UnicodeBuffer[LineSize] == CHAR_LF) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LineSize -= i;
|
||
|
|
||
|
Line = FileImageCreateNode ();
|
||
|
|
||
|
if (Line == NULL) {
|
||
|
EditorError(EFI_OUT_OF_RESOURCES,L"FileImageRead: Could Not Allocate another Line");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Line->Buffer = AllocateZeroPool(LineSize*2+2);
|
||
|
if (Line->Buffer == NULL) {
|
||
|
EditorError(EFI_OUT_OF_RESOURCES,L"FileImageRead: Could not allocate buffer");
|
||
|
RemoveEntryList(&Line->Link);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
for (Line->Size = 0; Line->Size < LineSize; Line->Size++) {
|
||
|
if (FileImage.FileType == ASCII_FILE) {
|
||
|
Line->Buffer[Line->Size] = (CHAR16)AsciiBuffer[i];
|
||
|
} else {
|
||
|
Line->Buffer[Line->Size] = UnicodeBuffer[i];
|
||
|
}
|
||
|
i++;
|
||
|
|
||
|
}
|
||
|
|
||
|
Line->Size++;
|
||
|
if (FileImage.NewLineType == USE_CRLF) {
|
||
|
++i;
|
||
|
}
|
||
|
|
||
|
Line->Buffer[LineSize] = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
FreePool (FileBuffer);
|
||
|
|
||
|
InsertTailList(FileImage.ListHead,Blank);
|
||
|
|
||
|
MainEditor.FileBuffer->FilePosition.Row = 1;
|
||
|
MainEditor.FileBuffer->FilePosition.Column = 1;
|
||
|
|
||
|
MainEditor.FileBuffer->CurrentLine = FileImage.ListHead->Flink;
|
||
|
|
||
|
MainEditor.StatusBar->SetPosition(1,1);
|
||
|
|
||
|
UnicodeBuffer = PoolPrint(L"%d Lines Read",FileImage.NumLines);
|
||
|
MainEditor.StatusBar->SetStatusString(UnicodeBuffer);
|
||
|
FreePool (UnicodeBuffer);
|
||
|
|
||
|
FileImage.FileHandle->Close(FileImage.FileHandle);
|
||
|
FileImage.FileIsOpen = FALSE;
|
||
|
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
VOID
|
||
|
GetNewLine (
|
||
|
CHAR8 *Buffer,
|
||
|
UINT8 *Size
|
||
|
)
|
||
|
{
|
||
|
UINT8 size = 0;
|
||
|
|
||
|
if (FileImage.NewLineType == USE_CRLF) {
|
||
|
Buffer[size] = 0x0d;
|
||
|
size++;
|
||
|
if (FileImage.FileType == UNICODE_FILE) {
|
||
|
Buffer[size] = 0x00;
|
||
|
size++;
|
||
|
}
|
||
|
}
|
||
|
Buffer[size] = 0x0a;
|
||
|
size++;
|
||
|
if (FileImage.FileType == UNICODE_FILE) {
|
||
|
Buffer[size] = 0x00;
|
||
|
size++;
|
||
|
}
|
||
|
*Size = size;
|
||
|
}
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageWrite (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
LIST_ENTRY *Link;
|
||
|
EFI_EDITOR_LINE *Line;
|
||
|
CHAR16 *Str;
|
||
|
VOID *Buffer;
|
||
|
|
||
|
EFI_STATUS Status;
|
||
|
UINTN Length = 0;
|
||
|
UINTN NumLines = 1;
|
||
|
CHAR8 NewLineBuffer[4];
|
||
|
UINT8 NewLineSize;
|
||
|
|
||
|
Status = FileImage.CurrentDir->Open (FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_READ_WRITE,0);
|
||
|
if (!EFI_ERROR(Status)) {
|
||
|
Status = FileImage.FileHandle->Delete (FileImage.FileHandle);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
EditorError(Status,L"Error Deleting File");
|
||
|
/* return EFI_SUCCESS; */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Status = FileImage.CurrentDir->Open(FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_CREATE,0);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
EditorError(Status,L"Error Accessing File");
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
GetNewLine(NewLineBuffer,&NewLineSize);
|
||
|
|
||
|
if (FileImage.FileType == UNICODE_FILE) {
|
||
|
UINT8 Marker1 = 0xff,Marker2 = 0xfe;
|
||
|
Length = 1;
|
||
|
FileImage.FileHandle->Write(FileImage.FileHandle,&Length,&Marker1);
|
||
|
Length = 1;
|
||
|
FileImage.FileHandle->Write(FileImage.FileHandle,&Length,&Marker2);
|
||
|
}
|
||
|
|
||
|
for (Link = FileImage.ListHead->Flink;
|
||
|
Link != FileImage.ListHead->Blink; Link = Link->Flink) {
|
||
|
Line = CR(Link,EFI_EDITOR_LINE,Link,EFI_EDITOR_LINE_LIST);
|
||
|
|
||
|
Line->Buffer[Line->Size-1] = 0;
|
||
|
if (FileImage.FileType == ASCII_FILE) {
|
||
|
(CHAR8*)Buffer = AllocatePool(Line->Size);
|
||
|
UnicodeToAscii(Line->Buffer,Line->Size,(CHAR8*)Buffer);
|
||
|
Length = Line->Size - 1;
|
||
|
} else {
|
||
|
Length = (Line->Size*2) - 2;
|
||
|
(CHAR16*)Buffer = PoolPrint(L"%s",Line->Buffer);
|
||
|
}
|
||
|
|
||
|
Status = FileImage.FileHandle->Write(FileImage.FileHandle,&Length,Buffer);
|
||
|
FreePool(Buffer);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
EditorError(Status,L"Error Writing File");
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
Length = NewLineSize;
|
||
|
Status = FileImage.FileHandle->Write(FileImage.FileHandle,&Length,NewLineBuffer);
|
||
|
if (EFI_ERROR(Status)) {
|
||
|
EditorError(Status,L"Error Writing Newline");
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
NumLines++;
|
||
|
}
|
||
|
|
||
|
MainEditor.FileModified = FALSE;
|
||
|
MainEditor.TitleBar->Refresh();
|
||
|
|
||
|
Str = PoolPrint(L"Wrote %d Lines",NumLines);
|
||
|
MainEditor.StatusBar->SetStatusString(Str);
|
||
|
FreePool(Str);
|
||
|
|
||
|
Status = FileImage.FileHandle->Close(FileImage.FileHandle);
|
||
|
if ( EFI_ERROR(Status) ) {
|
||
|
EditorError(Status,L"Error Closing File");
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageClose (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
FileImageDeleteLines ();
|
||
|
|
||
|
MainEditor.FileBuffer->FilePosition.Row = 1;
|
||
|
MainEditor.FileBuffer->FilePosition.Column = 1;
|
||
|
MainEditor.StatusBar->SetPosition(1,1);
|
||
|
MainEditor.FileBuffer->SetPosition(TEXT_START_ROW,TEXT_START_COLUMN);
|
||
|
|
||
|
MainEditor.FileModified = FALSE;
|
||
|
MainEditor.TitleBar->Refresh();
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
STATIC
|
||
|
EFI_STATUS
|
||
|
FileImageSetFilename (
|
||
|
IN CHAR16* Filename
|
||
|
)
|
||
|
{
|
||
|
if (Filename == NULL) {
|
||
|
return EFI_LOAD_ERROR;
|
||
|
}
|
||
|
if (FileImage.FileName != NULL) {
|
||
|
FreePool(FileImage.FileName);
|
||
|
}
|
||
|
|
||
|
FileImage.FileName = PoolPrint(L"%s",Filename);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
STATIC
|
||
|
VOID
|
||
|
FileImageDeleteLines (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_EDITOR_LINE *Line;
|
||
|
LIST_ENTRY *Blank;
|
||
|
LIST_ENTRY *Item;
|
||
|
|
||
|
Blank = FileImage.ListHead->Blink;
|
||
|
RemoveEntryList(Blank);
|
||
|
|
||
|
while (!IsListEmpty(FileImage.ListHead)) {
|
||
|
Item = FileImage.ListHead->Flink;
|
||
|
|
||
|
RemoveEntryList(Item);
|
||
|
|
||
|
Line = CR(Item,EFI_EDITOR_LINE,Link,EFI_EDITOR_LINE_LIST);
|
||
|
|
||
|
if (Line->Buffer != NULL && Line->Buffer != (CHAR16*)BAD_POINTER) {
|
||
|
FreePool(Line->Buffer);
|
||
|
}
|
||
|
|
||
|
FreePool (Line);
|
||
|
FileImage.NumLines--;
|
||
|
}
|
||
|
InsertTailList(FileImage.ListHead,Blank);
|
||
|
MainEditor.FileBuffer->CurrentLine = Blank;
|
||
|
FileImage.NumLines = 1;
|
||
|
}
|
||
|
|
||
|
STATIC
|
||
|
EFI_EDITOR_LINE*
|
||
|
FileImageCreateNode (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
EFI_EDITOR_LINE *Line;
|
||
|
|
||
|
Line = AllocatePool (sizeof(EFI_EDITOR_LINE));
|
||
|
|
||
|
if ( Line == NULL ) {
|
||
|
EditorError(EFI_OUT_OF_RESOURCES,L"FileImageCreateNode: Could not allocate Node");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
Line->Signature = EFI_EDITOR_LINE_LIST;
|
||
|
Line->Size = 1;
|
||
|
Line->Buffer = PoolPrint(L" \0");
|
||
|
FileImage.NumLines++;
|
||
|
|
||
|
InsertTailList(FileImage.ListHead,&Line->Link);
|
||
|
|
||
|
return Line;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif /* _LIB_FILE_IMAGE */
|