STATIC BUFFER_LIST mFileHandleList;\r
\r
// global variables required by library class.\r
-EFI_SHELL_PROTOCOL *gEfiShellProtocol = NULL;\r
-EFI_SHELL_PARAMETERS_PROTOCOL *gEfiShellParametersProtocol = NULL;\r
EFI_UNICODE_COLLATION_PROTOCOL *gUnicodeCollation = NULL;\r
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *gDevPathToText = NULL;\r
SHELL_MAP_LIST gShellMapList;\r
)\r
{\r
EFI_STATUS Status;\r
- if (gEfiShellParametersProtocol == NULL) {\r
- Status = gBS->OpenProtocol(gImageHandle,\r
- &gEfiShellParametersProtocolGuid,\r
- (VOID **)&gEfiShellParametersProtocol,\r
- gImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return (EFI_DEVICE_ERROR);\r
- }\r
- }\r
- if (gEfiShellProtocol == NULL) {\r
- Status = gBS->LocateProtocol(&gEfiShellProtocolGuid, NULL, (VOID**)&gEfiShellProtocol);\r
- if (EFI_ERROR(Status)) {\r
- return (EFI_DEVICE_ERROR);\r
- }\r
- }\r
if (gUnicodeCollation == NULL) {\r
Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);\r
if (EFI_ERROR(Status)) {\r
FreePool(mProfileList);\r
}\r
\r
- gEfiShellProtocol = NULL;\r
- gEfiShellParametersProtocol = NULL;\r
gUnicodeCollation = NULL;\r
gDevPathToText = NULL;\r
gShellCurDir = NULL;\r
return (EFI_SUCCESS);\r
}\r
\r
-/**\r
- Function to make sure all directory delimeters are backslashes.\r
-\r
- @param[in,out] Path The path to modify.\r
-\r
- @return Path.\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-ShellCommandCleanPath (\r
- IN OUT CHAR16 *Path\r
- )\r
-{\r
- CHAR16 *Path2;\r
-\r
- for (Path2 = Path ; Path2 != NULL && *Path2 != CHAR_NULL ; Path2++) {\r
- if (*Path2 == L'/') {\r
- *Path2 = L'\\';\r
- }\r
- }\r
-\r
- return (Path);\r
-}\r
-\r
/**\r
Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.\r
\r
return (RetVal);\r
}\r
\r
-/**\r
- Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned\r
- buffer. The returned buffer must be callee freed.\r
-\r
- If the position upon start is 0, then the Ascii Boolean will be set. This should be\r
- maintained and not changed for all operations with the same file.\r
-\r
- @param[in] Handle SHELL_FILE_HANDLE to read from.\r
- @param[in,out] Ascii Boolean value for indicating whether the file is\r
- Ascii (TRUE) or UCS2 (FALSE).\r
-\r
- @return The line of text from the file.\r
-\r
- @sa ShellFileHandleReadLine\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-ShellFileHandleReturnLine(\r
- IN SHELL_FILE_HANDLE Handle,\r
- IN OUT BOOLEAN *Ascii\r
- )\r
-{\r
- CHAR16 *RetVal;\r
- UINTN Size;\r
- EFI_STATUS Status;\r
-\r
- Size = 0;\r
- RetVal = NULL;\r
-\r
- Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- RetVal = AllocateZeroPool(Size);\r
- Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
- }\r
- ASSERT_EFI_ERROR(Status);\r
- if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
- FreePool(RetVal);\r
- RetVal = NULL;\r
- }\r
- return (RetVal);\r
-}\r
-\r
-/**\r
- Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE.\r
-\r
- If the position upon start is 0, then the Ascii Boolean will be set. This should be\r
- maintained and not changed for all operations with the same file.\r
-\r
- @param[in] Handle SHELL_FILE_HANDLE to read from.\r
- @param[in,out] Buffer The pointer to buffer to read into.\r
- @param[in,out] Size The pointer to number of bytes in Buffer.\r
- @param[in] Truncate If the buffer is large enough, this has no effect.\r
- If the buffer is is too small and Truncate is TRUE,\r
- the line will be truncated.\r
- If the buffer is is too small and Truncate is FALSE,\r
- then no read will occur.\r
-\r
- @param[in,out] Ascii Boolean value for indicating whether the file is\r
- Ascii (TRUE) or UCS2 (FALSE).\r
-\r
- @retval EFI_SUCCESS The operation was successful. The line is stored in\r
- Buffer.\r
- @retval EFI_INVALID_PARAMETER Handle was NULL.\r
- @retval EFI_INVALID_PARAMETER Size was NULL.\r
- @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.\r
- Size was updated to the minimum space required.\r
- @sa ShellFileHandleRead\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellFileHandleReadLine(\r
- IN SHELL_FILE_HANDLE Handle,\r
- IN OUT CHAR16 *Buffer,\r
- IN OUT UINTN *Size,\r
- IN BOOLEAN Truncate,\r
- IN OUT BOOLEAN *Ascii\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 CharBuffer;\r
- UINTN CharSize;\r
- UINTN CountSoFar;\r
- UINT64 OriginalFilePosition;\r
-\r
-\r
- if (Handle == NULL\r
- ||Size == NULL\r
- ){\r
- return (EFI_INVALID_PARAMETER);\r
- }\r
- if (Buffer == NULL) {\r
- ASSERT(*Size == 0);\r
- } else {\r
- *Buffer = CHAR_NULL;\r
- }\r
- gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);\r
- if (OriginalFilePosition == 0) {\r
- CharSize = sizeof(CHAR16);\r
- Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
- ASSERT_EFI_ERROR(Status);\r
- if (CharBuffer == gUnicodeFileTag) {\r
- *Ascii = FALSE;\r
- } else {\r
- *Ascii = TRUE;\r
- gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
- }\r
- }\r
-\r
- for (CountSoFar = 0;;CountSoFar++){\r
- CharBuffer = 0;\r
- if (*Ascii) {\r
- CharSize = sizeof(CHAR8);\r
- } else {\r
- CharSize = sizeof(CHAR16);\r
- }\r
- Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
- if ( EFI_ERROR(Status)\r
- || CharSize == 0\r
- || (CharBuffer == L'\n' && !(*Ascii))\r
- || (CharBuffer == '\n' && *Ascii)\r
- ){\r
- break;\r
- }\r
- //\r
- // if we have space save it...\r
- //\r
- if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
- ASSERT(Buffer != NULL);\r
- ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
- ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
- }\r
- }\r
-\r
- //\r
- // if we ran out of space tell when...\r
- //\r
- if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
- *Size = (CountSoFar+1)*sizeof(CHAR16);\r
- if (!Truncate) {\r
- gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
- } else {\r
- DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));\r
- }\r
- return (EFI_BUFFER_TOO_SMALL);\r
- }\r
- while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
- Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
- }\r
-\r
- return (Status);\r
-}\r
/**\r
Frees any BUFFER_LIST defined type.\r
\r
}\r
}\r
\r
-/**\r
- Chops off last directory or file entry in a path leaving the trailing slash\r
-\r
- @param[in,out] PathToReturn The path to modify.\r
-\r
- @retval FALSE No directory was found to chop off.\r
- @retval TRUE A directory was chopped off.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-ChopLastSlash(\r
- IN OUT CHAR16 *PathToReturn\r
- )\r
-{\r
- CHAR16 *Walker;\r
- CHAR16 *LastSlash;\r
- //\r
- // get directory name from path... ('chop' off extra)\r
- //\r
- for ( Walker = PathToReturn, LastSlash = NULL\r
- ; Walker != NULL && *Walker != CHAR_NULL\r
- ; Walker++\r
- ){\r
- if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {\r
- LastSlash = Walker+1;\r
- }\r
- }\r
- if (LastSlash != NULL) {\r
- *LastSlash = CHAR_NULL;\r
- return (TRUE);\r
- }\r
- return (FALSE);\r
-}\r
-\r
-/**\r
- Function to clean up paths. Removes the following items:\r
- single periods in the path (no need for the current directory tag)\r
- double periods in the path and removes a single parent directory.\r
-\r
- This will be done inline and the resultant string may be be 'too big'.\r
-\r
- @param[in] PathToReturn The pointer to the string containing the path.\r
-\r
- @return PathToReturn is always returned.\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-CleanPath(\r
- IN CHAR16 *PathToReturn\r
- )\r
-{\r
- CHAR16 *TempString;\r
- UINTN TempSize;\r
- if (PathToReturn==NULL) {\r
- return(NULL);\r
- }\r
- //\r
- // Fix up the directory name\r
- //\r
- while ((TempString = StrStr(PathToReturn, L"\\..\\")) != NULL) {\r
- *TempString = CHAR_NULL;\r
- TempString += 4;\r
- ChopLastSlash(PathToReturn);\r
- TempSize = StrSize(TempString);\r
- CopyMem(PathToReturn+StrLen(PathToReturn), TempString, TempSize);\r
- }\r
- if ((TempString = StrStr(PathToReturn, L"\\..")) != NULL && *(TempString + 3) == CHAR_NULL) {\r
- *TempString = CHAR_NULL;\r
- ChopLastSlash(PathToReturn);\r
- }\r
- while ((TempString = StrStr(PathToReturn, L"\\.\\")) != NULL) {\r
- *TempString = CHAR_NULL;\r
- TempString += 2;\r
- TempSize = StrSize(TempString);\r
- CopyMem(PathToReturn+StrLen(PathToReturn), TempString, TempSize);\r
- }\r
- if ((TempString = StrStr(PathToReturn, L"\\.")) != NULL && *(TempString + 2) == CHAR_NULL) {\r
- *TempString = CHAR_NULL;\r
- }\r
- return (PathToReturn);\r
-}\r
-\r