#include <Library/BaseMemoryLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Protocol/LoadedImage.h>\r
#include <Protocol/SimpleFileSystem.h>\r
#include <Protocol/ShellParameters.h>\r
+#include <Protocol/Shell.h>\r
#include <Guid/FileInfo.h>\r
-#include <Guid/Gpt.h>\r
-\r
-#define IS_HYPHEN(a) ((a) == L'-')\r
-#define IS_NULL(a) ((a) == L'\0')\r
-\r
-#define MAX_ARG_NUM 11\r
\r
UINTN Argc;\r
CHAR16 **Argv;\r
+EFI_SHELL_PROTOCOL *mShellProtocol = NULL;\r
\r
/**\r
\r
}\r
\r
/**\r
- Return File System Volume containing this shell application.\r
+ Get shell protocol.\r
\r
- @return File System Volume containing this shell application.\r
+ @return Pointer to shell protocol.\r
**/\r
-EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *\r
-GetMyVol (\r
+EFI_SHELL_PROTOCOL *\r
+GetShellProtocol (\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
-\r
- Status = gBS->HandleProtocol (\r
- gImageHandle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID **)&LoadedImage\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ EFI_STATUS Status;\r
\r
- Status = gBS->HandleProtocol (\r
- LoadedImage->DeviceHandle,\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- (VOID **)&Vol\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- return Vol;\r
+ if (mShellProtocol == NULL) {\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiShellProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mShellProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ mShellProtocol = NULL;\r
+ }\r
}\r
\r
- return NULL;\r
+ return mShellProtocol;\r
}\r
\r
/**\r
- Read a file from this volume.\r
+ Read a file.\r
\r
- @param[in] Vol File System Volume\r
@param[in] FileName The file to be read.\r
@param[out] BufferSize The file buffer size\r
@param[out] Buffer The file buffer\r
\r
@retval EFI_SUCCESS Read file successfully\r
- @retval EFI_NOT_FOUND File not found\r
+ @retval EFI_NOT_FOUND Shell protocol or file not found\r
+ @retval others Read file failed\r
**/\r
EFI_STATUS\r
-ReadFileFromVol (\r
- IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol,\r
- IN CHAR16 *FileName,\r
- OUT UINTN *BufferSize,\r
- OUT VOID **Buffer\r
+ReadFileToBuffer (\r
+ IN CHAR16 *FileName,\r
+ OUT UINTN *BufferSize,\r
+ OUT VOID **Buffer\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_FILE_HANDLE RootDir;\r
- EFI_FILE_HANDLE Handle;\r
- UINTN FileInfoSize;\r
- EFI_FILE_INFO *FileInfo;\r
+ EFI_SHELL_PROTOCOL *ShellProtocol;\r
+ SHELL_FILE_HANDLE Handle;\r
+ UINT64 FileSize;\r
UINTN TempBufferSize;\r
VOID *TempBuffer;\r
\r
- //\r
- // Open the root directory\r
- //\r
- Status = Vol->OpenVolume (Vol, &RootDir);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ ShellProtocol = GetShellProtocol();\r
+ if (ShellProtocol == NULL) {\r
+ return EFI_NOT_FOUND;\r
}\r
\r
//\r
- // Open the file\r
+ // Open file by FileName.\r
//\r
- Status = RootDir->Open (\r
- RootDir,\r
- &Handle,\r
- FileName,\r
- EFI_FILE_MODE_READ,\r
- 0\r
- );\r
+ Status = ShellProtocol->OpenFileByName (\r
+ FileName,\r
+ &Handle,\r
+ EFI_FILE_MODE_READ\r
+ );\r
if (EFI_ERROR (Status)) {\r
- RootDir->Close (RootDir);\r
return Status;\r
}\r
\r
- RootDir->Close (RootDir);\r
-\r
//\r
- // Get the file information\r
+ // Get the file size.\r
//\r
- FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;\r
-\r
- FileInfo = AllocateZeroPool (FileInfoSize);\r
- if (FileInfo == NULL) {\r
- Handle->Close (Handle);\r
+ Status = ShellProtocol->GetFileSize (Handle, &FileSize);\r
+ if (EFI_ERROR (Status)) {
+ ShellProtocol->CloseFile (Handle);\r
return Status;\r
}\r
\r
- Status = Handle->GetInfo (\r
- Handle,\r
- &gEfiFileInfoGuid,\r
- &FileInfoSize,\r
- FileInfo\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Handle->Close (Handle);\r
- gBS->FreePool (FileInfo);\r
- return Status;\r
- }\r
-\r
- //\r
- // Allocate buffer for the file data. The last CHAR16 is for L'\0'\r
- //\r
- TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);\r
+ TempBufferSize = (UINTN) FileSize;\r
TempBuffer = AllocateZeroPool (TempBufferSize);\r
if (TempBuffer == NULL) {\r
- Handle->Close (Handle);\r
- gBS->FreePool (FileInfo);\r
- return Status;\r
+ ShellProtocol->CloseFile (Handle);\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- gBS->FreePool (FileInfo);\r
-\r
//\r
// Read the file data to the buffer\r
//\r
- Status = Handle->Read (\r
- Handle,\r
- &TempBufferSize,\r
- TempBuffer\r
- );\r
+ Status = ShellProtocol->ReadFile (\r
+ Handle,\r
+ &TempBufferSize,\r
+ TempBuffer\r
+ );\r
if (EFI_ERROR (Status)) {\r
- Handle->Close (Handle);\r
- gBS->FreePool (TempBuffer);\r
+ ShellProtocol->CloseFile (Handle);\r
return Status;\r
}\r
\r
- Handle->Close (Handle);\r
+ ShellProtocol->CloseFile (Handle);\r
\r
*BufferSize = TempBufferSize;\r
*Buffer = TempBuffer;\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Read a file.\r
- If ScanFs is FLASE, it will use this Vol as default Fs.\r
- If ScanFs is TRUE, it will scan all FS and check the file.\r
- If there is only one file match the name, it will be read.\r
- If there is more than one file match the name, it will return Error.\r
-\r
- @param[in,out] ThisVol File System Volume\r
- @param[in] FileName The file to be read.\r
- @param[out] BufferSize The file buffer size\r
- @param[out] Buffer The file buffer\r
- @param[in] ScanFs Need Scan all FS\r
-\r
- @retval EFI_SUCCESS Read file successfully\r
- @retval EFI_NOT_FOUND File not found\r
- @retval EFI_NO_MAPPING There is duplicated files found\r
-**/\r
-EFI_STATUS\r
-ReadFileToBufferEx (\r
- IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **ThisVol,\r
- IN CHAR16 *FileName,\r
- OUT UINTN *BufferSize,\r
- OUT VOID **Buffer,\r
- IN BOOLEAN ScanFs\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
- UINTN TempBufferSize;\r
- VOID *TempBuffer;\r
- UINTN NoHandles;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN Index;\r
-\r
- //\r
- // Check parameters\r
- //\r
- if ((FileName == NULL) || (Buffer == NULL) || (ThisVol == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // not scan fs\r
- //\r
- if (!ScanFs) {\r
- if (*ThisVol == NULL) {\r
- *ThisVol = GetMyVol ();\r
- if (*ThisVol == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Read file directly from Vol\r
- //\r
- return ReadFileFromVol (*ThisVol, FileName, BufferSize, Buffer);\r
- }\r
-\r
- //\r
- // need scan fs\r
- //\r
-\r
- //\r
- // Get all Vol handle\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- NULL,\r
- &NoHandles,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status) && (NoHandles == 0)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Walk through each Vol\r
- //\r
- *ThisVol = NULL;\r
- *BufferSize = 0;\r
- *Buffer = NULL;\r
- for (Index = 0; Index < NoHandles; Index++) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- (VOID **)&Vol\r
- );\r
- if (EFI_ERROR(Status)) {\r
- continue;\r
- }\r
-\r
- Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Read file OK, check duplication\r
- //\r
- if (*ThisVol != NULL) {\r
- //\r
- // Find the duplicated file\r
- //\r
- gBS->FreePool (TempBuffer);\r
- gBS->FreePool (*Buffer);\r
- Print (L"Duplicated FileName found!\n");\r
- return EFI_NO_MAPPING;\r
- } else {\r
- //\r
- // Record value\r
- //\r
- *ThisVol = Vol;\r
- *BufferSize = TempBufferSize;\r
- *Buffer = TempBuffer;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Scan Fs done\r
- //\r
- if (*ThisVol == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Done\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read a file.\r
-\r
- @param[in] FileName The file to be read.\r
- @param[out] BufferSize The file buffer size\r
- @param[out] Buffer The file buffer\r
-\r
- @retval EFI_SUCCESS Read file successfully\r
- @retval EFI_NOT_FOUND File not found\r
-**/\r
-EFI_STATUS\r
-ReadFileToBuffer (\r
- IN CHAR16 *FileName,\r
- OUT UINTN *BufferSize,\r
- OUT VOID **Buffer\r
- )\r
-{\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
- Vol = NULL;\r
- return ReadFileToBufferEx(&Vol, FileName, BufferSize, Buffer, FALSE);\r
-}\r
-\r
/**\r
Write a file.\r
\r
@param[in] Buffer The file buffer\r
\r
@retval EFI_SUCCESS Write file successfully\r
+ @retval EFI_NOT_FOUND Shell protocol not found\r
+ @retval others Write file failed\r
**/\r
EFI_STATUS\r
WriteFileFromBuffer (\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_FILE_HANDLE RootDir;\r
- EFI_FILE_HANDLE Handle;\r
+ EFI_SHELL_PROTOCOL *ShellProtocol;\r
+ SHELL_FILE_HANDLE Handle;\r
+ EFI_FILE_INFO *FileInfo;\r
UINTN TempBufferSize;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
\r
- Vol = GetMyVol();\r
- if (Vol == NULL) {\r
+ ShellProtocol = GetShellProtocol();\r
+ if (ShellProtocol == NULL) {\r
return EFI_NOT_FOUND;\r
}\r
\r
//\r
- // Open the root directory\r
+ // Open file by FileName.\r
//\r
- Status = Vol->OpenVolume (Vol, &RootDir);\r
+ Status = ShellProtocol->OpenFileByName (\r
+ FileName,\r
+ &Handle,\r
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
//\r
- // Open the file\r
+ // Empty the file contents.\r
//\r
- Status = RootDir->Open (\r
- RootDir,\r
- &Handle,\r
- FileName,\r
- EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- RootDir->Close (RootDir);\r
- return Status;\r
- }\r
-\r
- //\r
- // Delete file\r
- //\r
- Status = Handle->Delete(Handle);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
+ FileInfo = ShellProtocol->GetFileInfo (Handle);\r
+ if (FileInfo == NULL) {\r
+ ShellProtocol->CloseFile (Handle);\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
//\r
- // Open the file again\r
+ // If the file size is already 0, then it has been empty.\r
//\r
- Status = RootDir->Open (\r
- RootDir,\r
- &Handle,\r
- FileName,\r
- EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- RootDir->Close (RootDir);\r
- return Status;\r
+ if (FileInfo->FileSize != 0) {\r
+ //\r
+ // Set the file size to 0.\r
+ //\r
+ FileInfo->FileSize = 0;\r
+ Status = ShellProtocol->SetFileInfo (Handle, FileInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (FileInfo);\r
+ ShellProtocol->CloseFile (Handle);\r
+ return Status;\r
+ }\r
}\r
-\r
- RootDir->Close (RootDir);\r
+ FreePool (FileInfo);\r
\r
//\r
// Write the file data from the buffer\r
//\r
TempBufferSize = BufferSize;\r
- Status = Handle->Write (\r
- Handle,\r
- &TempBufferSize,\r
- Buffer\r
- );\r
+ Status = ShellProtocol->WriteFile (\r
+ Handle,\r
+ &TempBufferSize,\r
+ Buffer\r
+ );\r
if (EFI_ERROR (Status)) {\r
- Handle->Close (Handle);\r
+ ShellProtocol->CloseFile (Handle);\r
return Status;\r
}\r
\r
- Handle->Close (Handle);\r
+ ShellProtocol->CloseFile (Handle);\r
\r
return EFI_SUCCESS;\r
}\r