/** @file\r
Main file for DmpStore shell Debug1 function.\r
\r
- Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
+ Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "UefiShellDebug1CommandsLib.h"\r
\r
-STATIC CHAR16 *AttrType[] = {\r
- L"invalid", // 000\r
- L"invalid", // 001\r
- L"BS", // 010\r
- L"NV+BS", // 011\r
- L"RT+BS", // 100\r
- L"NV+RT+BS", // 101\r
- L"RT+BS", // 110\r
- L"NV+RT+BS", // 111\r
-};\r
+typedef enum {\r
+ DmpStoreDisplay,\r
+ DmpStoreDelete,\r
+ DmpStoreSave,\r
+ DmpStoreLoad\r
+} DMP_STORE_TYPE;\r
\r
-SHELL_STATUS\r
-EFIAPI\r
-ProcessVariables (\r
- IN CONST CHAR16 *VariableName OPTIONAL,\r
- IN CONST EFI_GUID *Guid OPTIONAL,\r
- IN BOOLEAN Delete\r
+typedef struct {\r
+ UINT32 Signature;\r
+ CHAR16 *Name;\r
+ EFI_GUID Guid;\r
+ UINT32 Attributes;\r
+ UINT32 DataSize;\r
+ UINT8 *Data;\r
+ LIST_ENTRY Link;\r
+} DMP_STORE_VARIABLE;\r
+\r
+#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
+\r
+/**\r
+ Base on the input attribute value to return the attribute string.\r
+\r
+ @param[in] Atts The input attribute value\r
+\r
+ @retval The attribute string info.\r
+**/\r
+CHAR16 *\r
+GetAttrType (\r
+ IN CONST UINT32 Atts\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT64 MaxStorSize;\r
- UINT64 RemStorSize;\r
- UINT64 MaxVarSize;\r
- CHAR16 *FoundVarName;\r
- UINTN Size;\r
- EFI_GUID FoundVarGuid;\r
- UINT8 *DataBuffer;\r
- UINTN DataSize;\r
- UINT32 Atts;\r
- SHELL_STATUS ShellStatus;\r
+ UINTN BufLen;\r
+ CHAR16 *RetString;\r
\r
- ShellStatus = SHELL_SUCCESS;\r
- Size = PcdGet16(PcdShellFileOperationSize);\r
- FoundVarName = AllocatePool(Size);\r
+ BufLen = 0;\r
+ RetString = NULL;\r
\r
- if (FoundVarName == NULL) {\r
- return (SHELL_OUT_OF_RESOURCES);\r
+ if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+NV", 0);\r
+ }\r
+ if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+RT+BS", 0);\r
+ } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+BS", 0);\r
+ }\r
+ if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+HR", 0);\r
+ }\r
+ if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+AW", 0);\r
+ }\r
+ if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ StrnCatGrow (&RetString, &BufLen, L"+AT", 0);\r
}\r
- FoundVarName[0] = CHAR_NULL;\r
\r
- Status = gRT->QueryVariableInfo(EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS|EFI_VARIABLE_NON_VOLATILE, &MaxStorSize, &RemStorSize, &MaxVarSize);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (RetString == NULL) {\r
+ RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0);\r
+ }\r
\r
- DataSize = (UINTN)MaxVarSize;\r
- DataBuffer = AllocatePool(DataSize);\r
- if (DataBuffer == NULL) {\r
- FreePool(FoundVarName);\r
- return (SHELL_OUT_OF_RESOURCES);\r
+ if ((RetString != NULL) && (RetString[0] == L'+')) {\r
+ CopyMem(RetString, RetString + 1, StrSize(RetString + 1));\r
}\r
\r
- for (;;){\r
- if (ShellGetExecutionBreakFlag()) {\r
- ShellStatus = SHELL_ABORTED;\r
+ return RetString;\r
+}\r
+\r
+/**\r
+ Convert binary to hex format string.\r
+\r
+ @param[in] Buffer The binary data.\r
+ @param[in] BufferSize The size in bytes of the binary data.\r
+ @param[in, out] HexString Hex format string.\r
+ @param[in] HexStringSize The size in bytes of the string.\r
+\r
+ @return The hex format string.\r
+**/\r
+CHAR16*\r
+BinaryToHexString (\r
+ IN VOID *Buffer,\r
+ IN UINTN BufferSize,\r
+ IN OUT CHAR16 *HexString,\r
+ IN UINTN HexStringSize\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINTN StringIndex;\r
+\r
+ ASSERT (Buffer != NULL);\r
+ ASSERT ((BufferSize * 2 + 1) * sizeof (CHAR16) <= HexStringSize);\r
+\r
+ for (Index = 0, StringIndex = 0; Index < BufferSize; Index += 1) {\r
+ StringIndex +=\r
+ UnicodeSPrint (\r
+ &HexString[StringIndex],\r
+ HexStringSize - StringIndex * sizeof (CHAR16),\r
+ L"%02x",\r
+ ((UINT8 *) Buffer)[Index]\r
+ );\r
+ }\r
+ return HexString;\r
+}\r
+\r
+/**\r
+ Load the variable data from file and set to variable data base.\r
+\r
+ @param[in] FileHandle The file to be read.\r
+ @param[in] Name The name of the variables to be loaded.\r
+ @param[in] Guid The guid of the variables to be loaded.\r
+ @param[out] Found TRUE when at least one variable was loaded and set.\r
+\r
+ @retval SHELL_DEVICE_ERROR Cannot access the file.\r
+ @retval SHELL_VOLUME_CORRUPTED The file is in bad format.\r
+ @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
+ @retval SHELL_SUCCESS Successfully load and set the variables.\r
+**/\r
+SHELL_STATUS\r
+LoadVariablesFromFile (\r
+ IN SHELL_FILE_HANDLE FileHandle,\r
+ IN CONST CHAR16 *Name,\r
+ IN CONST EFI_GUID *Guid,\r
+ OUT BOOLEAN *Found\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SHELL_STATUS ShellStatus;\r
+ UINT32 NameSize;\r
+ UINT32 DataSize;\r
+ UINTN BufferSize;\r
+ UINTN RemainingSize;\r
+ UINT64 Position;\r
+ UINT64 FileSize;\r
+ LIST_ENTRY List;\r
+ DMP_STORE_VARIABLE *Variable;\r
+ LIST_ENTRY *Link;\r
+ CHAR16 *Attributes;\r
+ UINT8 *Buffer;\r
+ UINT32 Crc32;\r
+\r
+ Status = ShellGetFileSize (FileHandle, &FileSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return SHELL_DEVICE_ERROR;\r
+ }\r
+\r
+ ShellStatus = SHELL_SUCCESS;\r
+\r
+ InitializeListHead (&List);\r
+\r
+ Position = 0;\r
+ while (Position < FileSize) {\r
+ //\r
+ // NameSize\r
+ //\r
+ BufferSize = sizeof (NameSize);\r
+ Status = ShellReadFile (FileHandle, &BufferSize, &NameSize);\r
+ if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) {\r
+ ShellStatus = SHELL_VOLUME_CORRUPTED;\r
break;\r
}\r
- Size = (UINTN)PcdGet16(PcdShellFileOperationSize);\r
- DataSize = (UINTN)MaxVarSize;\r
\r
- Status = gRT->GetNextVariableName(&Size, FoundVarName, &FoundVarGuid);\r
- if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // DataSize\r
+ //\r
+ BufferSize = sizeof (DataSize);\r
+ Status = ShellReadFile (FileHandle, &BufferSize, &DataSize);\r
+ if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) {\r
+ ShellStatus = SHELL_VOLUME_CORRUPTED;\r
break;\r
}\r
- ASSERT_EFI_ERROR(Status);\r
\r
- Status = gRT->GetVariable(FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
- ASSERT_EFI_ERROR(Status);\r
+ //\r
+ // Name, Guid, Attributes, Data, Crc32\r
+ //\r
+ RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32);\r
+ BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize;\r
+ Buffer = AllocatePool (BufferSize);\r
+ if (Buffer == NULL) {\r
+ ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+ BufferSize = RemainingSize;\r
+ Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2);\r
+ if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) {\r
+ ShellStatus = SHELL_VOLUME_CORRUPTED;\r
+ FreePool (Buffer);\r
+ break;\r
+ }\r
\r
//\r
- // Check if it matches\r
+ // Check Crc32\r
//\r
- if (VariableName != NULL) {\r
- if (!gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName)) {\r
- continue;\r
+ * (UINT32 *) Buffer = NameSize;\r
+ * ((UINT32 *) Buffer + 1) = DataSize;\r
+ BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32);\r
+ gBS->CalculateCrc32 (\r
+ Buffer,\r
+ BufferSize,\r
+ &Crc32\r
+ );\r
+ if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) {\r
+ FreePool (Buffer);\r
+ ShellStatus = SHELL_VOLUME_CORRUPTED;\r
+ break;\r
+ }\r
+\r
+ Position += BufferSize + sizeof (Crc32);\r
+\r
+ Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize);\r
+ if (Variable == NULL) {\r
+ FreePool (Buffer);\r
+ ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+ Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE;\r
+ Variable->Name = (CHAR16 *) (Variable + 1);\r
+ Variable->DataSize = DataSize;\r
+ Variable->Data = (UINT8 *) Variable->Name + NameSize;\r
+ CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize);\r
+ CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID));\r
+ CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32));\r
+ CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize);\r
+\r
+ InsertTailList (&List, &Variable->Link);\r
+ FreePool (Buffer);\r
+ }\r
+\r
+ if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle, L"dmpstore");\r
+ if (Position != FileSize) {\r
+ ShellStatus = SHELL_VOLUME_CORRUPTED;\r
+ }\r
+ }\r
+\r
+ for ( Link = GetFirstNode (&List)\r
+ ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)\r
+ ; Link = GetNextNode (&List, Link)\r
+ ) {\r
+ Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
+\r
+ if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) &&\r
+ ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid))\r
+ ) {\r
+ Attributes = GetAttrType (Variable->Attributes);\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
+ Attributes, &Variable->Guid, Variable->Name, Variable->DataSize\r
+ );\r
+ SHELL_FREE_NON_NULL(Attributes);\r
+\r
+ *Found = TRUE;\r
+ Status = gRT->SetVariable (\r
+ Variable->Name,\r
+ &Variable->Guid,\r
+ Variable->Attributes,\r
+ Variable->DataSize,\r
+ Variable->Data\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", Variable->Name, Status);\r
}\r
}\r
- if (Guid != NULL) {\r
- if (!CompareGuid(&FoundVarGuid, Guid)) {\r
- continue;\r
+ }\r
+\r
+ for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) {\r
+ Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
+ Link = RemoveEntryList (&Variable->Link);\r
+ FreePool (Variable);\r
+ }\r
+\r
+ return ShellStatus;\r
+}\r
+\r
+/**\r
+ Append one variable to file.\r
+\r
+ @param[in] FileHandle The file to be appended.\r
+ @param[in] Name The variable name.\r
+ @param[in] Guid The variable GUID.\r
+ @param[in] Attributes The variable attributes.\r
+ @param[in] DataSize The variable data size.\r
+ @param[in] Data The variable data.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
+ @retval EFI_SUCCESS The variable is appended to file successfully.\r
+ @retval others Failed to append the variable to file.\r
+**/\r
+EFI_STATUS\r
+AppendSingleVariableToFile (\r
+ IN SHELL_FILE_HANDLE FileHandle,\r
+ IN CONST CHAR16 *Name,\r
+ IN CONST EFI_GUID *Guid,\r
+ IN UINT32 Attributes,\r
+ IN UINT32 DataSize,\r
+ IN CONST UINT8 *Data\r
+ )\r
+{\r
+ UINT32 NameSize;\r
+ UINT8 *Buffer;\r
+ UINT8 *Ptr;\r
+ UINTN BufferSize;\r
+ EFI_STATUS Status;\r
+\r
+ NameSize = (UINT32) StrSize (Name);\r
+ BufferSize = sizeof (NameSize) + sizeof (DataSize)\r
+ + sizeof (*Guid)\r
+ + sizeof (Attributes)\r
+ + NameSize + DataSize\r
+ + sizeof (UINT32);\r
+\r
+ Buffer = AllocatePool (BufferSize);\r
+ if (Buffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Ptr = Buffer;\r
+ //\r
+ // NameSize and DataSize\r
+ //\r
+ * (UINT32 *) Ptr = NameSize;\r
+ Ptr += sizeof (NameSize);\r
+ *(UINT32 *) Ptr = DataSize;\r
+ Ptr += sizeof (DataSize);\r
+\r
+ //\r
+ // Name\r
+ //\r
+ CopyMem (Ptr, Name, NameSize);\r
+ Ptr += NameSize;\r
+\r
+ //\r
+ // Guid\r
+ //\r
+ CopyMem (Ptr, Guid, sizeof (*Guid));\r
+ Ptr += sizeof (*Guid);\r
+\r
+ //\r
+ // Attributes\r
+ //\r
+ * (UINT32 *) Ptr = Attributes;\r
+ Ptr += sizeof (Attributes);\r
+\r
+ //\r
+ // Data\r
+ //\r
+ CopyMem (Ptr, Data, DataSize);\r
+ Ptr += DataSize;\r
+\r
+ //\r
+ // Crc32\r
+ //\r
+ gBS->CalculateCrc32 (Buffer, (UINTN) Ptr - (UINTN) Buffer, (UINT32 *) Ptr);\r
+\r
+ Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);\r
+ FreePool (Buffer);\r
+\r
+ if (!EFI_ERROR (Status) &&\r
+ (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32))\r
+ ) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Recursive function to display or delete variables.\r
+\r
+ This function will call itself to create a stack-based list of allt he variables to process,\r
+ then fromt he last to the first, they will do either printing or deleting.\r
+\r
+ This is necessary since once a delete happens GetNextVariableName() will work.\r
+\r
+ @param[in] Name The variable name of the EFI variable (or NULL).\r
+ @param[in] Guid The GUID of the variable set (or NULL).\r
+ @param[in] Type The operation type.\r
+ @param[in] FileHandle The file to operate on (or NULL).\r
+ @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.\r
+ @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.\r
+ @param[in] FoundOne If a VariableName or Guid was specified and one was printed or\r
+ deleted, then set this to TRUE, otherwise ignored.\r
+ @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+ @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
+ @retval SHELL_ABORTED The abort message was received.\r
+ @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
+ @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
+**/\r
+SHELL_STATUS\r
+CascadeProcessVariables (\r
+ IN CONST CHAR16 *Name OPTIONAL,\r
+ IN CONST EFI_GUID *Guid OPTIONAL,\r
+ IN DMP_STORE_TYPE Type,\r
+ IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,\r
+ IN CONST CHAR16 * CONST PrevName,\r
+ IN EFI_GUID FoundVarGuid,\r
+ IN BOOLEAN *FoundOne,\r
+ IN BOOLEAN StandardFormatOutput\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *FoundVarName;\r
+ UINT8 *DataBuffer;\r
+ UINTN DataSize;\r
+ UINT32 Atts;\r
+ SHELL_STATUS ShellStatus;\r
+ UINTN NameSize;\r
+ CHAR16 *AttrString;\r
+ CHAR16 *HexString;\r
+ EFI_STATUS SetStatus;\r
+ CONST CHAR16 *GuidName;\r
+\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ return (SHELL_ABORTED);\r
+ }\r
+\r
+ NameSize = 0;\r
+ FoundVarName = NULL;\r
+\r
+ if (PrevName!=NULL) {\r
+ StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
+ } else {\r
+ FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
+ NameSize = sizeof(CHAR16);\r
+ }\r
+\r
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ FoundVarName = AllocateZeroPool (NameSize);\r
+ if (FoundVarName != NULL) {\r
+ if (PrevName != NULL) {\r
+ StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1);\r
}\r
+\r
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
+ } else {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
}\r
+ }\r
+\r
+ //\r
+ // No more is fine.\r
+ //\r
+ if (Status == EFI_NOT_FOUND) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ return (SHELL_SUCCESS);\r
+ } else if (EFI_ERROR(Status)) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ return (SHELL_DEVICE_ERROR);\r
+ }\r
+\r
+ //\r
+ // Recurse to the next iteration. We know "our" variable's name.\r
+ //\r
+ ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne, StandardFormatOutput);\r
+\r
+ if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) {\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+ return (SHELL_ABORTED);\r
+ }\r
\r
+ //\r
+ // No matter what happened we process our own variable\r
+ // Only continue if Guid and VariableName are each either NULL or a match\r
+ //\r
+ if ( ( Name == NULL\r
+ || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
+ && ( Guid == NULL\r
+ || CompareGuid(&FoundVarGuid, Guid) )\r
+ ) {\r
+ DataSize = 0;\r
+ DataBuffer = NULL;\r
//\r
// do the print or delete\r
//\r
- if (!Delete) {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
- gShellDebug1HiiHandle,\r
- AttrType[Atts & 7],\r
- &FoundVarGuid,\r
- FoundVarName,\r
- DataSize);\r
- DumpHex(2, 0, DataSize, DataBuffer);\r
- } else {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),\r
- gShellDebug1HiiHandle,\r
- &FoundVarGuid,\r
- FoundVarName);\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN(STR_DMPSTORE_DELETE_DONE),\r
- gShellDebug1HiiHandle,\r
- gRT->SetVariable(FoundVarName, &FoundVarGuid, Atts, 0, NULL));\r
+ *FoundOne = TRUE;\r
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ SHELL_FREE_NON_NULL (DataBuffer);\r
+ DataBuffer = AllocatePool (DataSize);\r
+ if (DataBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
+ }\r
}\r
+ //\r
+ // Last error check then print this variable out.\r
+ //\r
+ if (Type == DmpStoreDisplay) {\r
+ if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
+ AttrString = GetAttrType(Atts);\r
+ if (StandardFormatOutput) {\r
+ HexString = AllocatePool ((DataSize * 2 + 1) * sizeof (CHAR16));\r
+ if (HexString != NULL) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_VAR_SFO), gShellDebug1HiiHandle,\r
+ FoundVarName, &FoundVarGuid, Atts, DataSize,\r
+ BinaryToHexString (\r
+ DataBuffer, DataSize, HexString, (DataSize * 2 + 1) * sizeof (CHAR16)\r
+ )\r
+ );\r
+ FreePool (HexString);\r
+ } else {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ }\r
+ } else {\r
+ Status = gEfiShellProtocol->GetGuidName(&FoundVarGuid, &GuidName);\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
+ AttrString, &FoundVarGuid, FoundVarName, DataSize\r
+ );\r
+ } else {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE2), gShellDebug1HiiHandle,\r
+ AttrString, GuidName, FoundVarName, DataSize\r
+ );\r
+ }\r
+ DumpHex (2, 0, DataSize, DataBuffer);\r
+ }\r
+ SHELL_FREE_NON_NULL (AttrString);\r
+ }\r
+ } else if (Type == DmpStoreSave) {\r
+ if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
+ AttrString = GetAttrType (Atts);\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
+ AttrString, &FoundVarGuid, FoundVarName, DataSize\r
+ );\r
+ Status = AppendSingleVariableToFile (\r
+ FileHandle,\r
+ FoundVarName,\r
+ &FoundVarGuid,\r
+ Atts,\r
+ (UINT32) DataSize,\r
+ DataBuffer\r
+ );\r
+ SHELL_FREE_NON_NULL (AttrString);\r
+ }\r
+ } else if (Type == DmpStoreDelete) {\r
+ //\r
+ // We only need name to delete it...\r
+ //\r
+ SetStatus = gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL);\r
+ if (StandardFormatOutput) {\r
+ if (SetStatus == EFI_SUCCESS) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_NG_SFO), gShellDebug1HiiHandle,\r
+ FoundVarName, &FoundVarGuid\r
+ );\r
+ }\r
+ } else {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_DELETE_LINE), gShellDebug1HiiHandle,\r
+ &FoundVarGuid, FoundVarName, SetStatus\r
+ );\r
+ }\r
+ }\r
+ SHELL_FREE_NON_NULL(DataBuffer);\r
}\r
\r
- if (FoundVarName != NULL) {\r
- FreePool(FoundVarName);\r
+ SHELL_FREE_NON_NULL(FoundVarName);\r
+\r
+ if (Status == EFI_DEVICE_ERROR) {\r
+ ShellStatus = SHELL_DEVICE_ERROR;\r
+ } else if (Status == EFI_SECURITY_VIOLATION) {\r
+ ShellStatus = SHELL_SECURITY_VIOLATION;\r
+ } else if (EFI_ERROR(Status)) {\r
+ ShellStatus = SHELL_NOT_READY;\r
}\r
- if (DataBuffer != NULL) {\r
- FreePool(DataBuffer);\r
+\r
+ return (ShellStatus);\r
+}\r
+\r
+/**\r
+ Function to display or delete variables. This will set up and call into the recursive function.\r
+\r
+ @param[in] Name The variable name of the EFI variable (or NULL).\r
+ @param[in] Guid The GUID of the variable set (or NULL).\r
+ @param[in] Type The operation type.\r
+ @param[in] FileHandle The file to save or load variables.\r
+ @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+ @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
+ @retval SHELL_ABORTED The abort message was received.\r
+ @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
+ @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
+**/\r
+SHELL_STATUS\r
+ProcessVariables (\r
+ IN CONST CHAR16 *Name OPTIONAL,\r
+ IN CONST EFI_GUID *Guid OPTIONAL,\r
+ IN DMP_STORE_TYPE Type,\r
+ IN SHELL_FILE_HANDLE FileHandle OPTIONAL,\r
+ IN BOOLEAN StandardFormatOutput\r
+ )\r
+{\r
+ SHELL_STATUS ShellStatus;\r
+ BOOLEAN Found;\r
+ EFI_GUID FoundVarGuid;\r
+\r
+ Found = FALSE;\r
+ ShellStatus = SHELL_SUCCESS;\r
+ ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
+\r
+ if (StandardFormatOutput) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"dmpstore");\r
+ }\r
+\r
+ if (Type == DmpStoreLoad) {\r
+ ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
+ } else {\r
+ ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found, StandardFormatOutput);\r
}\r
\r
- return (SHELL_UNSUPPORTED);\r
+ if (!Found) {\r
+ if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore");\r
+ return (ShellStatus);\r
+ } else if (Name != NULL && Guid == NULL) {\r
+ if (StandardFormatOutput) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N_SFO), gShellDebug1HiiHandle, Name);\r
+ } else {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, L"dmpstore", Name);\r
+ }\r
+ } else if (Name != NULL && Guid != NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name);\r
+ } else if (Name == NULL && Guid == NULL) {\r
+ if (StandardFormatOutput) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_SFO), gShellDebug1HiiHandle);\r
+ } else {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle, L"dmpstore");\r
+ }\r
+ } else if (Name == NULL && Guid != NULL) {\r
+ if (StandardFormatOutput) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G_SFO), gShellDebug1HiiHandle, Guid);\r
+ } else {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, L"dmpstore", Guid);\r
+ }\r
+ }\r
+ return (SHELL_NOT_FOUND);\r
+ }\r
+ return (ShellStatus);\r
}\r
\r
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
{L"-d", TypeFlag},\r
- {L"-l", TypeFlag},\r
- {L"-s", TypeFlag},\r
+ {L"-l", TypeValue},\r
+ {L"-s", TypeValue},\r
{L"-all", TypeFlag},\r
{L"-guid", TypeValue},\r
+ {L"-sfo", TypeFlag},\r
{NULL, TypeMax}\r
};\r
\r
+/**\r
+ Function for 'dmpstore' command.\r
+\r
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
+**/\r
SHELL_STATUS\r
EFIAPI\r
ShellCommandRunDmpStore (\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Package;\r
- CHAR16 *ProblemParam;\r
- SHELL_STATUS ShellStatus;\r
- CONST CHAR16 *Temp;\r
- EFI_GUID *Guid;\r
- EFI_GUID GuidData;\r
- CONST CHAR16 *VariableName;\r
+ EFI_STATUS Status;\r
+ RETURN_STATUS RStatus;\r
+ LIST_ENTRY *Package;\r
+ CHAR16 *ProblemParam;\r
+ SHELL_STATUS ShellStatus;\r
+ CONST CHAR16 *GuidStr;\r
+ CONST CHAR16 *File;\r
+ EFI_GUID *Guid;\r
+ EFI_GUID GuidData;\r
+ CONST CHAR16 *Name;\r
+ DMP_STORE_TYPE Type;\r
+ SHELL_FILE_HANDLE FileHandle;\r
+ EFI_FILE_INFO *FileInfo;\r
+ BOOLEAN StandardFormatOutput;\r
\r
- ShellStatus = SHELL_SUCCESS;\r
- Package = NULL;\r
+ ShellStatus = SHELL_SUCCESS;\r
+ Package = NULL;\r
+ FileHandle = NULL;\r
+ File = NULL;\r
+ Type = DmpStoreDisplay;\r
+ StandardFormatOutput = FALSE;\r
\r
Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
if (EFI_ERROR(Status)) {\r
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam);\r
FreePool(ProblemParam);\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
} else {\r
ASSERT(FALSE);\r
}\r
} else {\r
- if (ShellCommandLineGetCount(Package) < 1) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
- ShellStatus = SHELL_INVALID_PARAMETER;\r
- } else if (ShellCommandLineGetCount(Package) > 2) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
+ if (ShellCommandLineGetCount(Package) > 2) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore");\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
} else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-all", L"-guid");\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s");\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
} else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l or -s", L"-d");\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-sfo")) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-sfo");\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
} else {\r
+ //\r
+ // Determine the GUID to search for based on -all and -guid parameters\r
+ //\r
if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
- Temp = ShellCommandLineGetValue(Package, L"-guid");\r
- if (Temp != NULL) {\r
- Status = ConvertStringToGuid(Temp, &GuidData);\r
- if (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"-guid");\r
+ GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
+ if (GuidStr != NULL) {\r
+ RStatus = StrToGuid (GuidStr, &GuidData);\r
+ if (RETURN_ERROR (RStatus) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr);\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
}\r
Guid = &GuidData;\r
} else {\r
Guid = &gEfiGlobalVariableGuid;\r
}\r
- VariableName = ShellCommandLineGetRawValue(Package, 2);\r
} else {\r
- VariableName = NULL;\r
- Guid = NULL;\r
+ Guid = NULL;\r
}\r
+\r
+ //\r
+ // Get the Name of the variable to find\r
+ //\r
+ Name = ShellCommandLineGetRawValue(Package, 1);\r
+\r
if (ShellStatus == SHELL_SUCCESS) {\r
- if (ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) {\r
- ///@todo fix this after Jordan makes lib...\r
- ShellPrintEx(-1, -1, L"Not implemeneted yet (ASSERT follows).\r\n");\r
- ShellStatus = SHELL_INVALID_PARAMETER;\r
- ASSERT(FALSE);\r
- } else {\r
- ShellStatus = ProcessVariables (VariableName, Guid, ShellCommandLineGetFlag(Package, L"-d"));\r
+ if (ShellCommandLineGetFlag(Package, L"-s")) {\r
+ Type = DmpStoreSave;\r
+ File = ShellCommandLineGetValue(Package, L"-s");\r
+ if (File == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Delete existing file, but do not delete existing directory\r
+ //\r
+ FileInfo = ShellGetFileInfo (FileHandle);\r
+ if (FileInfo == NULL) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ Status = EFI_DEVICE_ERROR;\r
+ } else {\r
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ Status = EFI_INVALID_PARAMETER;\r
+ } else {\r
+ Status = ShellDeleteFile (&FileHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ }\r
+ }\r
+ FreePool (FileInfo);\r
+ }\r
+ } else if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // Good when file doesn't exist\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ //\r
+ // Otherwise it's bad.\r
+ //\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
+ Type = DmpStoreLoad;\r
+ File = ShellCommandLineGetValue(Package, L"-l");\r
+ if (File == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ FileInfo = ShellGetFileInfo (FileHandle);\r
+ if (FileInfo == NULL) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ ShellStatus = SHELL_DEVICE_ERROR;\r
+ } else {\r
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ FreePool (FileInfo);\r
+ }\r
+ }\r
+ }\r
+ } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
+ Type = DmpStoreDelete;\r
+ }\r
+\r
+ if (ShellCommandLineGetFlag (Package,L"-sfo")) {\r
+ StandardFormatOutput = TRUE;\r
+ }\r
+ }\r
+\r
+ if (ShellStatus == SHELL_SUCCESS) {\r
+ if (Type == DmpStoreSave) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
+ } else if (Type == DmpStoreLoad) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
+ }\r
+ ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput);\r
+ if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
+ ShellCloseFile (&FileHandle);\r
}\r
}\r
}\r