]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/FileExplorerLib/FileExplorer.c
MdeModulePkg/VarCheckHiiLib: Replace EFI_D_INFO with DEBUG_INFO
[mirror_edk2.git] / MdeModulePkg / Library / FileExplorerLib / FileExplorer.c
index 9cd366ddf4f859c3c5c7d3928ab2ba97c7c6dc0a..9182751ad75bdaaee0f01a10bd132fc0bf4bc43b 100644 (file)
@@ -72,6 +72,25 @@ VOID                *mLibStartOpCodeHandle = NULL;
 VOID                *mLibEndOpCodeHandle = NULL;\r
 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
@@ -174,9 +193,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
@@ -188,7 +211,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
@@ -207,8 +278,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
@@ -657,7 +728,7 @@ LibAppendFileName (
       // 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
@@ -669,7 +740,7 @@ LibAppendFileName (
       // 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
@@ -984,6 +1055,72 @@ 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
@@ -1176,24 +1313,54 @@ 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
 \r
+  mQuestionIdUpdate += QUESTION_ID_UPDATE_STEP;\r
+\r
   for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
     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
       //\r
       HiiCreateActionOpCode (\r
         mLibStartOpCodeHandle,\r
-        (UINT16) (FILE_OPTION_OFFSET + Index),\r
+        (UINT16) (FILE_OPTION_OFFSET + Index + mQuestionIdUpdate),\r
         NewMenuEntry->DisplayStringToken,\r
         STRING_TOKEN (STR_NULL_STRING),\r
         EFI_IFR_FLAG_CALLBACK,\r
@@ -1209,7 +1376,7 @@ LibUpdateFileExplorePage (
         NewMenuEntry->DisplayStringToken,\r
         STRING_TOKEN (STR_NULL_STRING),\r
         EFI_IFR_FLAG_CALLBACK,\r
-        (UINT16) (FILE_OPTION_OFFSET + Index)\r
+        (UINT16) (FILE_OPTION_OFFSET + Index + mQuestionIdUpdate)\r
         );\r
     }\r
   }\r
@@ -1244,7 +1411,7 @@ LibUpdateFileExplorer (
   EFI_FILE_HANDLE FileHandle;\r
 \r
   Status = EFI_SUCCESS;\r
-  FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
+  FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate;\r
   NewMenuEntry   = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);\r
   NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
 \r
@@ -1279,7 +1446,7 @@ LibGetDevicePath (
   MENU_ENTRY      *NewMenuEntry;\r
   FILE_CONTEXT    *NewFileContext;\r
 \r
-  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
+  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate;\r
 \r
   NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);\r
 \r
@@ -1328,6 +1495,7 @@ ChooseFile (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  mQuestionIdUpdate = 0;\r
   FileName = NULL;\r
 \r
   gFileExplorerPrivate.RetDevicePath = NULL;\r