+/**\r
+ Determin if a file name represents a unicode file.\r
+\r
+ @param[in] FileName Pointer to the filename to open.\r
+\r
+ @retval EFI_SUCCESS The file is a unicode file.\r
+ @return An error upon failure.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsUnicodeFile(\r
+ IN CONST CHAR16 *FileName\r
+ )\r
+{\r
+ SHELL_FILE_HANDLE Handle;\r
+ EFI_STATUS Status;\r
+ UINT64 OriginalFilePosition;\r
+ UINTN CharSize;\r
+ CHAR16 CharBuffer;\r
+\r
+ Status = gEfiShellProtocol->OpenFileByName(FileName, &Handle, EFI_FILE_MODE_READ);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+ gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);\r
+ gEfiShellProtocol->SetFilePosition(Handle, 0);\r
+ CharSize = sizeof(CHAR16);\r
+ Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
+ if (EFI_ERROR(Status) || CharBuffer != gUnicodeFileTag) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);\r
+ gEfiShellProtocol->CloseFile(Handle);\r
+ return (Status); \r
+}\r
+\r
+/**\r
+ Strips out quotes sections of a string.\r
+\r
+ All of the characters between quotes is replaced with spaces.\r
+\r
+ @param[in, out] TheString A pointer to the string to update.\r
+**/\r
+VOID\r
+EFIAPI\r
+StripQuotes (\r
+ IN OUT CHAR16 *TheString\r
+ )\r
+{\r
+ BOOLEAN RemoveNow;\r
+\r
+ for (RemoveNow = FALSE ; TheString != NULL && *TheString != CHAR_NULL ; TheString++) {\r
+ if (*TheString == L'^' && *(TheString + 1) == L'\"') {\r
+ TheString++;\r
+ } else if (*TheString == L'\"') {\r
+ RemoveNow = (BOOLEAN)!RemoveNow;\r
+ } else if (RemoveNow) {\r
+ *TheString = L' ';\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Calcualte the 32-bit CRC in a EFI table using the service provided by the\r
+ gRuntime service.\r
+\r
+ @param Hdr Pointer to an EFI standard header\r
+\r
+**/\r
+VOID\r
+CalculateEfiHdrCrc (\r
+ IN OUT EFI_TABLE_HEADER *Hdr\r
+ )\r
+{\r
+ UINT32 Crc;\r
+\r
+ Hdr->CRC32 = 0;\r
+\r
+ //\r
+ // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then\r
+ // Crc will come back as zero if we set it to zero here\r
+ //\r
+ Crc = 0;\r
+ gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);\r
+ Hdr->CRC32 = Crc;\r
+}\r
+\r
+/**\r
+ Fix a string to only have the file name, removing starting at the first space of whatever is quoted.\r
+\r
+ @param[in] FileName The filename to start with.\r
+\r
+ @retval NULL FileName was invalid.\r
+ @return The modified FileName.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+FixFileName (\r
+ IN CHAR16 *FileName\r
+ )\r
+{\r
+ CHAR16 *Copy;\r
+ CHAR16 *TempLocation;\r
+\r
+ if (FileName == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
+ if (FileName[0] == L'\"') {\r
+ Copy = FileName+1;\r
+ if ((TempLocation = StrStr(Copy , L"\"")) != NULL) {\r
+ TempLocation[0] = CHAR_NULL;\r
+ } \r
+ } else {\r
+ Copy = FileName;\r
+ while(Copy[0] == L' ') {\r
+ Copy++;\r
+ }\r
+ if ((TempLocation = StrStr(Copy , L" ")) != NULL) {\r
+ TempLocation[0] = CHAR_NULL;\r
+ } \r
+ }\r
+\r
+ if (Copy[0] == CHAR_NULL) {\r
+ return (NULL);\r
+ }\r
+\r
+ return (Copy);\r
+}\r
+\r
+/**\r
+ Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.\r
+\r
+ @param[in] FileName The filename to start with.\r
+\r
+ @retval NULL FileName was invalid.\r
+ @return The modified FileName.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+FixVarName (\r
+ IN CHAR16 *FileName\r
+ )\r
+{\r
+ CHAR16 *Copy;\r
+ CHAR16 *TempLocation;\r
+\r
+ Copy = FileName;\r
+\r
+ if (FileName[0] == L'%') {\r
+ Copy = FileName+1;\r
+ if ((TempLocation = StrStr(Copy , L"%")) != NULL) {\r
+ TempLocation[0] = CHAR_NULL;\r
+ } \r
+ }\r
+\r
+ return (FixFileName(Copy));\r
+}\r
+\r
+/**\r
+ Remove the unicode file tag from the begining of the file buffer since that will not be\r
+ used by StdIn.\r
+ \r
+ @param[in] Handle Pointer to the handle of the file to be processed.\r
+ \r
+ @retval EFI_SUCCESS The unicode file tag has been moved successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RemoveFileTag(\r
+ IN SHELL_FILE_HANDLE *Handle\r
+ )\r
+{\r
+ UINTN CharSize;\r
+ CHAR16 CharBuffer;\r
+\r
+ CharSize = sizeof(CHAR16);\r
+ CharBuffer = 0;\r
+ gEfiShellProtocol->ReadFile(*Handle, &CharSize, &CharBuffer);\r
+ if (CharBuffer != gUnicodeFileTag) {\r
+ gEfiShellProtocol->SetFilePosition(*Handle, 0);\r
+ }\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Write the unicode file tag to the specified file.\r
+\r
+ It is the caller's responsibility to ensure that\r
+ ShellInfoObject.NewEfiShellProtocol has been initialized before calling this\r
+ function.\r
+\r
+ @param[in] FileHandle The file to write the unicode file tag to.\r
+\r
+ @return Status code from ShellInfoObject.NewEfiShellProtocol->WriteFile.\r
+**/\r
+EFI_STATUS\r
+WriteFileTag (\r
+ IN SHELL_FILE_HANDLE FileHandle\r
+ )\r
+{\r
+ CHAR16 FileTag;\r
+ UINTN Size;\r
+ EFI_STATUS Status;\r
+\r
+ FileTag = gUnicodeFileTag;\r
+ Size = sizeof FileTag;\r
+ Status = ShellInfoObject.NewEfiShellProtocol->WriteFile (FileHandle, &Size,\r
+ &FileTag);\r
+ ASSERT (EFI_ERROR (Status) || Size == sizeof FileTag);\r
+ return Status;\r
+}\r
+\r
+\r