#define FILE EFI_LIST_ENTRY
#define MAX_FILE_LIST_POINT_BUFF_SIZE 256
FILE FileList_Buffer[MAX_FILE_LIST_POINT_BUFF_SIZE];
UINTN FileList_Count = 0;
/*************************************************************************/
FILE *fopen(const char *filename, const char *mode )
{
FILE *ptr_file_list = &FileList_Buffer[FileList_Count];
EFI_STATUS Status;
CHAR16 VarStr[256];
CHAR16 ModeStr[256];
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
if (FileList_Count >= MAX_FILE_LIST_POINT_BUFF_SIZE)
return NULL;
ascii_str_to_unicode_str((CHAR8 *)mode, ModeStr);
if ((strcmp (mode, "w") != 0) && (strcmp (mode, "a") != 0) && (strcmp (mode, "r") != 0)) {
Print (L"=>No Supported this mode(%s)\n", ModeStr);
return NULL;
}
InitializeListHead (ptr_file_list);
ascii_str_to_unicode_str((CHAR8 *)filename, VarStr);
Status = ShellFileMetaArg (VarStr, ptr_file_list);
if (EFI_ERROR (Status) || IsListEmpty (ptr_file_list)) {
Print (L"=>fopen error(%x)\n", Status);
return NULL;
}
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
if ((Arg->Status == EFI_NOT_FOUND) && ((strcmp (mode, "w") == 0) || (strcmp (mode, "a") == 0))) {
Status = Arg->Parent->Open (
Arg->Parent,
HiiHandle,
Arg->FileName,
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
0 /*Directory:EFI_FILE_DIRECTORY or file:0*/
);
if (!EFI_ERROR (Status)) {
ShellFreeFileList (ptr_file_list);
Status = ShellFileMetaArg (VarStr, ptr_file_list);
if (EFI_ERROR (Status)) {
Print (L"=>Can't create the file(%s).\n", VarStr);
return NULL;
}
} else {
Print (L"=>Parent Can't create the file(%s).\n", Arg->FileName);
return NULL;
}
} if ((Arg->Status == EFI_NOT_FOUND) && (strcmp (mode, "r") == 0)) {
ShellFreeFileList (ptr_file_list);
return NULL;
}
}
} else {
Status = EFI_REDIRECTION_SAME;
}
FileList_Count ++;
return EFI_ERROR(Status) ? NULL : ptr_file_list;
}
/*************************************************************************/
int fclose(FILE *ptr_file_list)
{
ShellFreeFileList (ptr_file_list);
return 0;
}
/*************************************************************************/
long fseek( FILE *ptr_file_list, long offset, int where )
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
UINT64 CurrentPosition = 0;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = Arg->Status;
if (!EFI_ERROR (Status)) {
EFI_FILE_HANDLE Handle;
Handle = Arg->Handle;
switch(where) {
case SEEK_SET:
Handle->SetPosition (Handle, offset);
break;
case SEEK_CUR:
Handle->GetPosition (Handle, &CurrentPosition);
Handle->SetPosition (Handle, CurrentPosition + offset);
break;
case SEEK_END:
Handle->SetPosition (Handle, Arg->Info->FileSize - offset);
break;
default:
Status = EFI_INVALID_PARAMETER;
break;
}
}
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
EFI_STATUS
test_WriteFile (
SHELL_FILE_ARG *Arg,
const void *buf,
UINTN Size
)
{
EFI_STATUS Status;
CHAR16 *Buffer = (CHAR16 *)buf;
EFI_FILE_HANDLE Handle;
Status = Arg->Status;
if (!EFI_ERROR (Status) && (Size > 0)) {
if (Arg->Info->Attribute & EFI_FILE_DIRECTORY) {
Print (L"=>Write Attribute(%x)\n", Arg->Info->Attribute);
return Status;
}
Handle = Arg->Handle;
Status = Handle->Write (Handle, &Size, Buffer);
Status = Handle->Flush (Handle);
}
return Status;
}
int fwrite(
const void *buf,
unsigned long elsize,
unsigned long nelem,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = test_WriteFile (Arg, buf, (UINTN)(elsize * nelem));
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
EFI_STATUS
test_ReadFile (
SHELL_FILE_ARG *Arg,
const void *buf,
UINTN Size
)
{
EFI_STATUS Status;
CHAR16 *Buffer = (CHAR16 *)buf;
EFI_FILE_HANDLE Handle;
Status = Arg->Status;
if (!EFI_ERROR (Status) && (Size > 0)) {
if (Arg->Info->Attribute & EFI_FILE_DIRECTORY) {
Print (L"=>Read Attribute(%x)\n", Arg->Info->Attribute);
return Status;
}
Handle = Arg->Handle;
Status = Handle->Read (Handle, &Size, Buffer);
}
return Status;
}
int fread(
const void *buf,
unsigned long elsize,
unsigned long nelem,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = test_ReadFile (Arg, buf, (UINTN)(elsize * nelem));
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
long ftell(FILE *ptr_file_list)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
UINTN FileSize = 0;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = Arg->Status;
if (!EFI_ERROR (Status)) {
FileSize = (UINTN) Arg->Info->FileSize;
}
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (long)FileSize;
}
test_WriteFile (
SHELL_FILE_ARG *Arg,
const void *buf,
UINTN Size
)
{
EFI_STATUS Status;
CHAR16 *Buffer = (CHAR16 *)buf;
EFI_FILE_HANDLE Handle;
Status = Arg->Status;
if (!EFI_ERROR (Status) && (Size > 0)) {
if (Arg->Info->Attribute & EFI_FILE_DIRECTORY) {
Print (L"=>Write Attribute(%x)\n", Arg->Info->Attribute);
return Status;
}
Handle = Arg->Handle;
Status = Handle->Write (Handle, &Size, Buffer);
Status = Handle->Flush (Handle);
}
return Status;
}
int fwrite(
const void *buf,
unsigned long elsize,
unsigned long nelem,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = test_WriteFile (Arg, buf, (UINTN)(elsize * nelem));
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
EFI_STATUS
test_ReadFile (
SHELL_FILE_ARG *Arg,
const void *buf,
UINTN Size
)
{
EFI_STATUS Status;
CHAR16 *Buffer = (CHAR16 *)buf;
EFI_FILE_HANDLE Handle;
Status = Arg->Status;
if (!EFI_ERROR (Status) && (Size > 0)) {
if (Arg->Info->Attribute & EFI_FILE_DIRECTORY) {
Print (L"=>Read Attribute(%x)\n", Arg->Info->Attribute);
return Status;
}
Handle = Arg->Handle;
Status = Handle->Read (Handle, &Size, Buffer);
}
return Status;
}
int fread(
const void *buf,
unsigned long elsize,
unsigned long nelem,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = test_ReadFile (Arg, buf, (UINTN)(elsize * nelem));
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
long ftell(FILE *ptr_file_list)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
UINTN FileSize = 0;
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = Arg->Status;
if (!EFI_ERROR (Status)) {
FileSize = (UINTN) Arg->Info->FileSize;
}
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (long)FileSize;
}
/*************************************************************************/
int fputc(
int c,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
//
// Expand each arg and type each file
//
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = MV_WriteFile (Arg, (void *)&c, (UINTN)1);
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
int fgetc(
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
int c = -1;
//
// Expand each arg and type each file
//
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = MV_ReadFile (Arg, (void *)&c, (UINTN)1);
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? c : -1;
}
/*************************************************************************/
int fputc(
int c,
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
//
// Expand each arg and type each file
//
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = MV_WriteFile (Arg, (void *)&c, (UINTN)1);
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? 0 : -1;
}
/*************************************************************************/
int fgetc(
FILE *ptr_file_list
) {
EFI_STATUS Status = EFI_SUCCESS;
EFI_LIST_ENTRY *Link;
SHELL_FILE_ARG *Arg;
UINTN Index;
BOOLEAN IsSameFile;
int c = -1;
//
// Expand each arg and type each file
//
IsSameFile = FALSE;
for (Link = ptr_file_list->Flink; Link != ptr_file_list && SI->RedirArgc; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
IsSameFile = FALSE;
for (Index = 1; Index < SI->RedirArgc; Index += 2) {
if (!EFI_ERROR (LibCompareFile (Arg->FullName, SI->RedirArgv[Index], &IsSameFile)) && IsSameFile) {
break;
}
}
if (IsSameFile) {
break;
}
}
if (!IsSameFile) {
for (Link = ptr_file_list->Flink; Link != ptr_file_list; Link = Link->Flink) {
BREAK_LOOP_ON_ESC ();
Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
Status = MV_ReadFile (Arg, (void *)&c, (UINTN)1);
}
} else {
Status = EFI_REDIRECTION_SAME;
}
return (!EFI_ERROR (Status)) ? c : -1;
}
/*************************************************************************/
沒有留言:
張貼留言