]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/FileExplorerLib/FileExplorer.c
MdeModulePkg/FileExplorerLib: remove redundant null pointer check
[mirror_edk2.git] / MdeModulePkg / Library / FileExplorerLib / FileExplorer.c
index 315868a8bacdae1de5d0d04013649cbb7e461cbf..13a214b06af9fdc262fababe32abd614a0c4ed6c 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
 File explorer related functions.\r
 \r
-Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under\r
-the terms and conditions of the BSD License that accompanies this distribution.\r
-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
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -61,7 +55,7 @@ HII_VENDOR_DEVICE_PATH  FeHiiVendorDevicePath = {
   {\r
     END_DEVICE_PATH_TYPE,\r
     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-    { \r
+    {\r
       (UINT8) (END_DEVICE_PATH_LENGTH),\r
       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
     }\r
@@ -73,6 +67,24 @@ VOID                *mLibEndOpCodeHandle = NULL;
 EFI_IFR_GUID_LABEL  *mLibStartLabel = NULL;\r
 EFI_IFR_GUID_LABEL  *mLibEndLabel = NULL;\r
 UINT16              mQuestionIdUpdate;\r
+CHAR16  mNewFileName[MAX_FILE_NAME_LEN];\r
+CHAR16  mNewFolderName[MAX_FOLDER_NAME_LEN];\r
+UINTN  mNewFileQuestionId    = NEW_FILE_QUESTION_ID_BASE;\r
+UINTN  mNewFolderQuestionId  = NEW_FOLDER_QUESTION_ID_BASE;\r
+\r
+/**\r
+  Create a new file or folder in current directory.\r
+\r
+  @param FileName              Point to the fileNmae or folder.\r
+  @param CreateFile            CreateFile== TRUE  means create a new file.\r
+                               CreateFile== FALSE means create a new Folder.\r
+\r
+**/\r
+EFI_STATUS\r
+LibCreateNewFile (\r
+  IN CHAR16     *FileName,\r
+  IN BOOLEAN    CreateFile\r
+  );\r
 \r
 /**\r
   This function allows a caller to extract the current configuration for one\r
@@ -175,9 +187,13 @@ LibCallback (
 {\r
   EFI_STATUS    Status;\r
   BOOLEAN       NeedExit;\r
+  CHAR16        *NewFileName;\r
+  CHAR16        *NewFolderName;\r
 \r
   NeedExit = TRUE;\r
-  \r
+  NewFileName   = NULL;\r
+  NewFolderName = NULL;\r
+\r
   if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
     //\r
     // Do nothing for other UEFI Action. Only do call back when data is changed.\r
@@ -189,7 +205,55 @@ LibCallback (
     if ((Value == NULL) || (ActionRequest == NULL)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    \r
+\r
+    if (QuestionId == KEY_VALUE_CREATE_FILE_AND_EXIT) {\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+      if (!IsZeroBuffer (mNewFileName, sizeof (mNewFileName))) {\r
+        Status = LibCreateNewFile (mNewFileName,TRUE);\r
+        ZeroMem (mNewFileName,sizeof (mNewFileName));\r
+      }\r
+    }\r
+\r
+    if (QuestionId == KEY_VALUE_NO_CREATE_FILE_AND_EXIT) {\r
+      ZeroMem (mNewFileName,sizeof (mNewFileName));\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+    }\r
+\r
+    if (QuestionId == KEY_VALUE_CREATE_FOLDER_AND_EXIT) {\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+      if (!IsZeroBuffer (mNewFolderName, sizeof (mNewFolderName))) {\r
+        Status = LibCreateNewFile (mNewFolderName, FALSE);\r
+        ZeroMem (mNewFolderName,sizeof (mNewFolderName));\r
+      }\r
+    }\r
+\r
+    if (QuestionId == KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT) {\r
+      ZeroMem (mNewFolderName,sizeof (mNewFolderName));\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+    }\r
+\r
+    if (QuestionId == NEW_FILE_NAME_ID) {\r
+      NewFileName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);\r
+      if (NewFileName != NULL) {\r
+        StrCpyS (mNewFileName, MAX_FILE_NAME_LEN, NewFileName);\r
+        FreePool (NewFileName);\r
+        NewFileName = NULL;\r
+      } else {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
+    if (QuestionId == NEW_FOLDER_NAME_ID) {\r
+      NewFolderName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);\r
+      if (NewFolderName != NULL) {\r
+        StrCpyS (mNewFolderName, MAX_FOLDER_NAME_LEN, NewFolderName);\r
+        FreePool (NewFolderName);\r
+        NewFolderName = NULL;\r
+      } else {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
     if (QuestionId >= FILE_OPTION_OFFSET) {\r
       LibGetDevicePath(QuestionId);\r
 \r
@@ -208,8 +272,8 @@ LibCallback (
     if (Value == NULL) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    \r
     if (QuestionId >= FILE_OPTION_OFFSET) {\r
+      LibGetDevicePath(QuestionId);\r
       Status = LibUpdateFileExplorer (QuestionId);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
@@ -484,7 +548,7 @@ LibFileInfo (
 \r
   Buffer      = NULL;\r
   BufferSize  = 0;\r
-  \r
+\r
   Status = FHand->GetInfo (\r
                     FHand,\r
                     InfoType,\r
@@ -621,19 +685,19 @@ LibAppendFileName (
 \r
   Size1 = StrSize (Str1);\r
   Size2 = StrSize (Str2);\r
-  \r
+\r
   //\r
   // Check overflow\r
   //\r
   if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof(CHAR16))) {\r
     return NULL;\r
   }\r
-  \r
+\r
   MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16);\r
   Str   = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
   ASSERT (Str != NULL);\r
 \r
-  TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); \r
+  TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
   ASSERT (TmpStr != NULL);\r
 \r
   StrCpyS (Str, MaxLen, Str1);\r
@@ -654,11 +718,11 @@ LibAppendFileName (
       //\r
 \r
       //\r
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings \r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
       // that overlap.\r
       //\r
       StrCpyS (TmpStr, MaxLen, Ptr + 3);\r
-      StrCpyS (LastSlash, MaxLen - (UINTN) (LastSlash - Str), TmpStr);\r
+      StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
       //\r
@@ -666,11 +730,11 @@ LibAppendFileName (
       //\r
 \r
       //\r
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings \r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
       // that overlap.\r
       //\r
       StrCpyS (TmpStr, MaxLen, Ptr + 2);\r
-      StrCpyS (Ptr, MaxLen - (UINTN) (Ptr - Str), TmpStr);\r
+      StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\') {\r
       LastSlash = Ptr;\r
@@ -680,7 +744,7 @@ LibAppendFileName (
   }\r
 \r
   FreePool (TmpStr);\r
-  \r
+\r
   return Str;\r
 }\r
 \r
@@ -757,13 +821,9 @@ LibFindFileSystem (
       if (Info == NULL) {\r
         VolumeLabel = L"NO FILE SYSTEM INFO";\r
       } else {\r
-        if (Info->VolumeLabel == NULL) {\r
-          VolumeLabel = L"NULL VOLUME LABEL";\r
-        } else {\r
-          VolumeLabel = Info->VolumeLabel;\r
-          if (*VolumeLabel == 0x0000) {\r
-            VolumeLabel = L"NO VOLUME LABEL";\r
-          }\r
+        VolumeLabel = Info->VolumeLabel;\r
+        if (*VolumeLabel == 0x0000) {\r
+          VolumeLabel = L"NO VOLUME LABEL";\r
         }\r
       }\r
       MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);\r
@@ -775,7 +835,7 @@ LibFindFileSystem (
         VolumeLabel,\r
         MenuEntry->HelpString\r
         );\r
-         MenuEntry->DisplayStringToken = HiiSetString (\r
+      MenuEntry->DisplayStringToken = HiiSetString (\r
                                              gFileExplorerPrivate.FeHiiHandle,\r
                                              0,\r
                                              MenuEntry->DisplayString,\r
@@ -801,16 +861,16 @@ LibFindFileSystem (
 \r
 /**\r
   Find the file handle from the input menu info.\r
-  \r
+\r
   @param  MenuEntry        Input Menu info.\r
   @param  RetFileHandle    Return the file handle for the input device path.\r
-  \r
+\r
   @retval EFI_SUCESS       Find the file handle success.\r
   @retval Other            Find the file handle failure.\r
 **/\r
 EFI_STATUS\r
 LibGetFileHandleFromMenu (\r
-  IN  MENU_ENTRY                *MenuEntry,  \r
+  IN  MENU_ENTRY                *MenuEntry,\r
   OUT EFI_FILE_HANDLE           *RetFileHandle\r
   )\r
 {\r
@@ -847,18 +907,18 @@ LibGetFileHandleFromMenu (
 \r
 /**\r
   Find the file handle from the input device path info.\r
-  \r
+\r
   @param  RootDirectory    Device path info.\r
   @param  RetFileHandle    Return the file handle for the input device path.\r
   @param  ParentFileName   Parent file name.\r
   @param  DeviceHandle     Driver handle for this partition.\r
-  \r
+\r
   @retval EFI_SUCESS       Find the file handle success.\r
   @retval Other            Find the file handle failure.\r
 **/\r
 EFI_STATUS\r
 LibGetFileHandleFromDevicePath (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,  \r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,\r
   OUT EFI_FILE_HANDLE           *RetFileHandle,\r
   OUT UINT16                    **ParentFileName,\r
   OUT EFI_HANDLE                *DeviceHandle\r
@@ -883,12 +943,12 @@ LibGetFileHandleFromDevicePath (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Open the Volume to get the File System handle\r
   //\r
@@ -904,7 +964,7 @@ LibGetFileHandleFromDevicePath (
     *RetFileHandle = FileHandle;\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   //\r
   // Duplicate the device path to avoid the access to unaligned device path node.\r
   // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH\r
@@ -920,7 +980,7 @@ LibGetFileHandleFromDevicePath (
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
-        \r
+\r
   //\r
   // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the\r
   // directory information and filename can be seperate. The goal is to inch\r
@@ -985,13 +1045,79 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Create a new file or folder in current directory.\r
+\r
+  @param FileName              Point to the fileNmae or folder name.\r
+  @param CreateFile            CreateFile== TRUE  means create a new file.\r
+                               CreateFile== FALSE means create a new Folder.\r
+\r
+**/\r
+EFI_STATUS\r
+LibCreateNewFile (\r
+  IN CHAR16     *FileName,\r
+  IN BOOLEAN    CreateFile\r
+  )\r
+{\r
+  EFI_FILE_HANDLE      FileHandle;\r
+  EFI_FILE_HANDLE      NewHandle;\r
+  EFI_HANDLE           DeviceHandle;\r
+  EFI_STATUS           Status;\r
+  CHAR16               *ParentName;\r
+  CHAR16               *FullFileName;\r
+\r
+  NewHandle = NULL;\r
+  FullFileName = NULL;\r
+\r
+  LibGetFileHandleFromDevicePath(gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle);\r
+  FullFileName = LibAppendFileName (ParentName, FileName);\r
+  if (FullFileName == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  if (CreateFile) {\r
+    Status = FileHandle->Open(\r
+                          FileHandle,\r
+                          &NewHandle,\r
+                          FullFileName,\r
+                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
+                          0\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      FileHandle->Close (FileHandle);\r
+      return Status;\r
+    }\r
+  } else {\r
+    Status = FileHandle->Open(\r
+                          FileHandle,\r
+                          &NewHandle,\r
+                          FullFileName,\r
+                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
+                          EFI_FILE_DIRECTORY\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      FileHandle->Close (FileHandle);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  FileHandle->Close (FileHandle);\r
+\r
+  //\r
+  // Return the DevicePath of the new created file or folder.\r
+  //\r
+  gFileExplorerPrivate.RetDevicePath = FileDevicePath (DeviceHandle, FullFileName);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
 /**\r
   Find files under current directory.\r
-  \r
+\r
   All files and sub-directories in current directory\r
   will be stored in DirectoryMenu for future use.\r
 \r
-  @param FileHandle    Parent file handle. \r
+  @param FileHandle    Parent file handle.\r
   @param FileName      Parent file name.\r
   @param DeviceHandle  Driver handle for this partition.\r
 \r
@@ -1087,7 +1213,7 @@ LibFindFiles (
       } else {\r
         NewMenuEntry->DisplayString = LibStrDuplicate (DirInfo->FileName);\r
       }\r
-      \r
+\r
       NewMenuEntry->DisplayStringToken = HiiSetString (\r
                                            gFileExplorerPrivate.FeHiiHandle,\r
                                            0,\r
@@ -1177,9 +1303,11 @@ LibUpdateFileExplorePage (
   MENU_ENTRY      *NewMenuEntry;\r
   FILE_CONTEXT    *NewFileContext;\r
   MENU_OPTION     *MenuOption;\r
+  BOOLEAN         CreateNewFile;\r
 \r
   NewMenuEntry    = NULL;\r
   NewFileContext  = NULL;\r
+  CreateNewFile   = FALSE;\r
 \r
   LibRefreshUpdateData ();\r
   MenuOption = gFileExplorerPrivate.FsOptionMenu;\r
@@ -1190,6 +1318,32 @@ LibUpdateFileExplorePage (
     NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);\r
     NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
 \r
+    if (!NewFileContext->IsRoot && !CreateNewFile) {\r
+      HiiCreateGotoOpCode (\r
+        mLibStartOpCodeHandle,\r
+        FORM_ADD_NEW_FILE_ID,\r
+        STRING_TOKEN (STR_NEW_FILE),\r
+        STRING_TOKEN (STR_NEW_FILE_HELP),\r
+        EFI_IFR_FLAG_CALLBACK,\r
+        (UINT16) (mNewFileQuestionId++)\r
+        );\r
+      HiiCreateGotoOpCode (\r
+        mLibStartOpCodeHandle,\r
+        FORM_ADD_NEW_FOLDER_ID,\r
+        STRING_TOKEN (STR_NEW_FOLDER),\r
+        STRING_TOKEN (STR_NEW_FOLDER_HELP),\r
+        EFI_IFR_FLAG_CALLBACK,\r
+        (UINT16) (mNewFolderQuestionId++)\r
+        );\r
+      HiiCreateTextOpCode(\r
+        mLibStartOpCodeHandle,\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        0\r
+        );\r
+      CreateNewFile = TRUE;\r
+    }\r
+\r
     if (!NewFileContext->IsDir) {\r
       //\r
       // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.\r
@@ -1295,7 +1449,7 @@ LibGetDevicePath (
 }\r
 \r
 /**\r
-  Choose a file in the specified directory. \r
+  Choose a file in the specified directory.\r
 \r
   If user input NULL for the RootDirectory, will choose file in the system.\r
 \r
@@ -1448,7 +1602,7 @@ FileExplorerLibConstructor (
   //\r
   Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFileExplorerPrivate.FormBrowser2);\r
   ASSERT_EFI_ERROR (Status);\r
-    \r
+\r
   InitializeListHead (&gFileExplorerPrivate.FsOptionMenu->Head);\r
 \r
   return EFI_SUCCESS;\r
@@ -1483,8 +1637,9 @@ FileExplorerLibDestructor (
                     NULL\r
                     );\r
     ASSERT_EFI_ERROR (Status);\r
-    \r
+\r
     HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle);\r
+    gFileExplorerPrivate.FeDriverHandle = NULL;\r
   }\r
 \r
   FreePool (gHiiVendorDevicePath);\r