]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1.0.08 release
authorlongpanda <admin@ventoy.net>
Thu, 30 Apr 2020 14:40:40 +0000 (22:40 +0800)
committerlongpanda <admin@ventoy.net>
Thu, 30 Apr 2020 14:40:42 +0000 (22:40 +0800)
13 files changed:
GRUB2/grub-2.04/grub-core/fs/fat.c
GRUB2/grub-2.04/grub-core/normal/menu.c
GRUB2/grub-2.04/grub-core/ventoy/ventoy.c
GRUB2/grub-2.04/grub-core/ventoy/ventoy_def.h
IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh
IMG/cpio/ventoy/ventoy.sh
INSTALL/EFI/BOOT/grubx64_real.efi
INSTALL/Ventoy2Disk.sh
INSTALL/grub/grub.cfg
INSTALL/grub/i386-pc/core.img
INSTALL/grub/themes/ventoy/theme.txt
INSTALL/grub/x86_64-efi/normal.mod
INSTALL/ventoy/ventoy.cpio

index 6338d49e8df1894f2adcbbaccd00105cb862a7fc..6d4ce0d5f75af1fc0264e44af58032cb42e41a4b 100644 (file)
@@ -964,6 +964,12 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
 
       info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
       info.case_insensitive = 1;
 
       info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
       info.case_insensitive = 1;
+
+      #ifdef MODE_EXFAT
+      if (!info.dir)
+         info.size = ctxt.dir.file_size;
+      #endif
+      
 #ifdef MODE_EXFAT
       if (!ctxt.dir.have_stream)
        continue;
 #ifdef MODE_EXFAT
       if (!ctxt.dir.have_stream)
        continue;
@@ -1445,4 +1451,3 @@ END:
 }
 
 #endif
 }
 
 #endif
-
index 4df03bfde8424025e6232aac5346b97f6c9451f3..d39e19ac00f1d311cb4021bc692b31c70f5a4578 100644 (file)
 #include <grub/dl.h>
 #include <grub/env.h>
 
 #include <grub/dl.h>
 #include <grub/env.h>
 
+int g_ventoy_menu_refresh = 0;
+int g_ventoy_memdisk_mode = 0;
+int g_ventoy_iso_raw = 0;
+int g_ventoy_iso_uefi_drv = 0;
+int g_ventoy_last_entry = 0;
+
 /* Time to delay after displaying an error message about a default/fallback
    entry failing to boot.  */
 #define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
 /* Time to delay after displaying an error message about a default/fallback
    entry failing to boot.  */
 #define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
@@ -577,16 +583,20 @@ print_countdown (struct grub_term_coordinate *pos, int n)
 static int
 run_menu (grub_menu_t menu, int nested, int *auto_boot)
 {
 static int
 run_menu (grub_menu_t menu, int nested, int *auto_boot)
 {
+  const char *cmdstr;
   grub_uint64_t saved_time;
   grub_uint64_t saved_time;
-  int default_entry, current_entry;
+  int default_entry,current_entry;
   int timeout;
   enum timeout_style timeout_style;
 
   default_entry = get_entry_number (menu, "default");
   int timeout;
   enum timeout_style timeout_style;
 
   default_entry = get_entry_number (menu, "default");
-
+  
+  if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) {
+      default_entry = g_ventoy_last_entry;
+  } 
   /* If DEFAULT_ENTRY is not within the menu entries, fall back to
      the first entry.  */
   /* If DEFAULT_ENTRY is not within the menu entries, fall back to
      the first entry.  */
-  if (default_entry < 0 || default_entry >= menu->size)
+  else if (default_entry < 0 || default_entry >= menu->size)
     default_entry = 0;
 
   timeout = grub_menu_get_timeout ();
     default_entry = 0;
 
   timeout = grub_menu_get_timeout ();
@@ -787,34 +797,76 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
                }
              goto refresh;
 
                }
              goto refresh;
 
+        case GRUB_TERM_KEY_F2:
+            cmdstr = grub_env_get("VTOY_F2_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
+        case GRUB_TERM_KEY_F3:
+            cmdstr = grub_env_get("VTOY_F3_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
+        case GRUB_TERM_KEY_F4:
+            cmdstr = grub_env_get("VTOY_F4_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
+        case GRUB_TERM_KEY_F5:
+            cmdstr = grub_env_get("VTOY_F5_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
+        case GRUB_TERM_KEY_F6:
+            cmdstr = grub_env_get("VTOY_F6_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
+        case GRUB_TERM_KEY_F7:
+            cmdstr = grub_env_get("VTOY_F7_CMD");
+            if (cmdstr)
+            {
+                menu_fini ();
+                grub_script_execute_sourcecode(cmdstr);
+                goto refresh;
+            }
+            break;
         case GRUB_TERM_KEY_F1:
             menu_fini ();
         case GRUB_TERM_KEY_F1:
             menu_fini ();
-            if (grub_env_get("VTOY_MEM_DISK")) {
-                grub_env_unset("VTOY_MEM_DISK");
-            }else {
-                grub_env_set("VTOY_MEM_DISK", grub_env_get("VTOY_MEM_DISK_STR"));
-            }
-            grub_env_set("VTOY_MENU_REFRESH", "1");
+            g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode;
+            g_ventoy_menu_refresh = 1;
             goto refresh;
             
             goto refresh;
             
-        case GRUB_TERM_KEY_F3:
+        case (GRUB_TERM_CTRL | 'i'):
             menu_fini ();
             menu_fini ();
-            if (grub_env_get("VTOY_ISO_RAW")) {
-                grub_env_unset("VTOY_ISO_RAW");
-            }else {
-                grub_env_set("VTOY_ISO_RAW", grub_env_get("VTOY_ISO_RAW_STR"));
-            }
-            grub_env_set("VTOY_MENU_REFRESH", "1");
+            g_ventoy_iso_raw = 1 - g_ventoy_iso_raw;
+            g_ventoy_menu_refresh = 1;
             goto refresh;
             
             goto refresh;
             
-        case GRUB_TERM_KEY_F4:
+        case (GRUB_TERM_CTRL | 'u'):
             menu_fini ();
             menu_fini ();
-            if (grub_env_get("VTOY_ISO_UEFI_DRV")) {
-                grub_env_unset("VTOY_ISO_UEFI_DRV");
-            }else {
-                grub_env_set("VTOY_ISO_UEFI_DRV", grub_env_get("VTOY_ISO_UEFI_DRV_STR"));
-            }
-            grub_env_set("VTOY_MENU_REFRESH", "1");
+            g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv;
+            g_ventoy_menu_refresh = 1;
             goto refresh;
 
            default:
             goto refresh;
 
            default:
@@ -897,6 +949,8 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
       if (boot_entry < 0)
        break;
 
       if (boot_entry < 0)
        break;
 
+      g_ventoy_last_entry = boot_entry;
+
       e = grub_menu_get_entry (menu, boot_entry);
       if (! e)
        continue; /* Menu is empty.  */
       e = grub_menu_get_entry (menu, boot_entry);
       if (! e)
        continue; /* Menu is empty.  */
index ba1ec345f9903b7391d606f6cb01eb4d0556280c..97b349032e07af8cb62d1bf8153541cfbeb94a14 100644 (file)
@@ -52,11 +52,14 @@ int g_valid_initrd_count = 0;
 static grub_file_t g_old_file;
 
 char g_img_swap_tmp_buf[1024];
 static grub_file_t g_old_file;
 
 char g_img_swap_tmp_buf[1024];
-
+img_info g_img_swap_tmp;
 img_info *g_ventoy_img_list = NULL;
 int g_ventoy_img_count = 0;
 
 img_info *g_ventoy_img_list = NULL;
 int g_ventoy_img_count = 0;
 
+grub_device_t g_enum_dev = NULL;
+grub_fs_t g_enum_fs = NULL;
 img_iterator_node g_img_iterator_head;
 img_iterator_node g_img_iterator_head;
+img_iterator_node *g_img_iterator_tail = NULL;
 
 grub_uint8_t g_ventoy_break_level = 0;
 grub_uint8_t g_ventoy_debug_level = 0;
 
 grub_uint8_t g_ventoy_break_level = 0;
 grub_uint8_t g_ventoy_debug_level = 0;
@@ -71,6 +74,13 @@ ventoy_guid  g_ventoy_guid = VENTOY_GUID;
 
 ventoy_img_chunk_list g_img_chunk_list;
 
 
 ventoy_img_chunk_list g_img_chunk_list;
 
+static char *g_tree_script_buf = NULL;
+static int g_tree_script_pos = 0;
+
+static char *g_list_script_buf = NULL;
+static int g_list_script_pos = 0;
+
+
 void ventoy_debug(const char *fmt, ...)
 {
     va_list args;
 void ventoy_debug(const char *fmt, ...)
 {
     va_list args;
@@ -530,7 +540,7 @@ static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int ar
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
-static int ventoy_cmp_img(img_info *img1, img_info *img2)
+int ventoy_cmp_img(img_info *img1, img_info *img2)
 {
     char *s1, *s2;
     int c1 = 0;
 {
     char *s1, *s2;
     int c1 = 0;
@@ -560,15 +570,17 @@ static int ventoy_cmp_img(img_info *img1, img_info *img2)
     return (c1 - c2);
 }
 
     return (c1 - c2);
 }
 
-static void ventoy_swap_img(img_info *img1, img_info *img2)
+void ventoy_swap_img(img_info *img1, img_info *img2)
 {
 {
-    grub_memcpy(g_img_swap_tmp_buf, img1->name, sizeof(img1->name));
-    grub_memcpy(img1->name, img2->name, sizeof(img1->name));
-    grub_memcpy(img2->name, g_img_swap_tmp_buf, sizeof(img1->name));
+    grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info));
     
     
-    grub_memcpy(g_img_swap_tmp_buf, img1->path, sizeof(img1->path));
-    grub_memcpy(img1->path, img2->path, sizeof(img1->path));
-    grub_memcpy(img2->path, g_img_swap_tmp_buf, sizeof(img1->path));
+    grub_memcpy(img1, img2, sizeof(img_info));
+    img1->next = g_img_swap_tmp.next;
+    img1->prev = g_img_swap_tmp.prev;
+
+    g_img_swap_tmp.next = img2->next;
+    g_img_swap_tmp.prev = img2->prev;
+    grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info));
 }
 
 static int ventoy_img_name_valid(const char *filename, grub_size_t namelen)
 }
 
 static int ventoy_img_name_valid(const char *filename, grub_size_t namelen)
@@ -591,11 +603,27 @@ static int ventoy_img_name_valid(const char *filename, grub_size_t namelen)
     return 1;
 }
 
     return 1;
 }
 
+static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data)
+{
+    if (0 == info->dir)
+    {
+        if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13))
+        {
+            *((int *)data) = 1;
+            return 0;
+        }
+    }
+
+    return 0;
+}
+
 static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data)
 {
 static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data)
 {
+    int ignore = 0;
     grub_size_t len;
     img_info *img;
     img_info *tail;
     grub_size_t len;
     img_info *img;
     img_info *tail;
+    img_iterator_node *tmp;
     img_iterator_node *new_node;
     img_iterator_node *node = (img_iterator_node *)data;
 
     img_iterator_node *new_node;
     img_iterator_node *node = (img_iterator_node *)data;
 
@@ -609,14 +637,47 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
             return 0;
         }
 
             return 0;
         }
 
-        new_node = grub_malloc(sizeof(img_iterator_node));
+        if (!ventoy_img_name_valid(filename, len))
+        {
+            return 0;
+        }
+
+        if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12))
+        {
+            return 0;
+        }
+
+        new_node = grub_zalloc(sizeof(img_iterator_node));
         if (new_node)
         {
         if (new_node)
         {
+            new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename);
+
+            g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore);
+            if (ignore)
+            {
+                debug("Directory %s ignored...\n", new_node->dir);
+                grub_free(new_node);
+                return 0;
+            }
+
             new_node->tail = node->tail;
             new_node->tail = node->tail;
-            grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename);
 
 
-            new_node->next = g_img_iterator_head.next;
-            g_img_iterator_head.next = new_node;
+            new_node->parent = node;
+            if (!node->firstchild)
+            {
+                node->firstchild = new_node;
+            }
+
+            if (g_img_iterator_tail)
+            {
+                g_img_iterator_tail->next = new_node;
+                g_img_iterator_tail = new_node;
+            }
+            else
+            {
+                g_img_iterator_head.next = new_node;
+                g_img_iterator_tail = new_node;
+            }
         }
     }
     else
         }
     }
     else
@@ -646,6 +707,22 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
                 {
                     g_ventoy_img_list = img;
                 }
                 {
                     g_ventoy_img_list = img;
                 }
+
+                img->size = info->size;
+                img->id = g_ventoy_img_count;
+                img->parent = node;
+                if (node && NULL == node->firstiso)
+                {
+                    node->firstiso = img;
+                }
+
+                node->isocnt++;
+                tmp = node->parent;
+                while (tmp)
+                {
+                    tmp->isocnt++;
+                    tmp = tmp->parent;
+                }
                 
                 *((img_info **)(node->tail)) = img;
                 g_ventoy_img_count++;
                 
                 *((img_info **)(node->tail)) = img;
                 g_ventoy_img_count++;
@@ -734,6 +811,96 @@ int ventoy_fill_data(grub_uint32_t buflen, char *buffer)
     return len;
 }
 
     return len;
 }
 
+static img_info * ventoy_get_min_iso(img_iterator_node *node)
+{
+    img_info *minimg = NULL;
+    img_info *img = (img_info *)(node->firstiso);
+    
+    while (img && (img_iterator_node *)(img->parent) == node)
+    {
+        if (img->select == 0 && (NULL == minimg || grub_strcmp(img->name, minimg->name) < 0))
+        {
+            minimg = img;
+        }
+        img = img->next;
+    }
+
+    if (minimg)
+    {
+        minimg->select = 1;
+    }
+
+    return minimg;
+}
+
+static img_iterator_node * ventoy_get_min_child(img_iterator_node *node)
+{
+    img_iterator_node *Minchild = NULL;
+    img_iterator_node *child = node->firstchild;
+
+    while (child && child->parent == node)
+    {
+        if (child->select == 0 && (NULL == Minchild || grub_strcmp(child->dir, Minchild->dir) < 0))
+        {
+            Minchild = child;
+        }
+        child = child->next;
+    }
+
+    if (Minchild)
+    {
+        Minchild->select = 1;
+    }
+
+    return Minchild;
+}
+
+static int ventoy_dynamic_tree_menu(img_iterator_node *node)
+{
+    int offset = 1;
+    img_info *img;
+    img_iterator_node *child = NULL;
+
+    if (node->isocnt == 0 || node->done == 1)
+    {
+        return 0;
+    }
+
+    if (node->parent && node->parent->dirlen < node->dirlen)
+    {
+        offset = node->parent->dirlen;
+    }
+
+    if (node != &g_img_iterator_head)
+    {
+        node->dir[node->dirlen - 1] = 0;
+        g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, 
+                      "submenu \"%-10s [%s]\" {\n", "DIR", node->dir + offset);        
+    }
+
+    while ((child = ventoy_get_min_child(node)) != NULL)
+    {
+        ventoy_dynamic_tree_menu(child);
+    }
+
+    while ((img = ventoy_get_min_iso(node)) != NULL)
+    {
+        g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, 
+                  "menuentry \"%-10s %s\" --id=\"VID_%d\" {\n"
+                  "  common_menuentry \n" 
+                  "}\n", 
+                  grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), img->name, img->id);
+    }
+
+    if (node != &g_img_iterator_head)
+    {
+        g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, "}\n");        
+    }
+
+    node->done = 1;
+    return 0;    
+}
+
 static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
 {
     grub_fs_t fs;
 static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
 {
     grub_fs_t fs;
@@ -743,6 +910,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
     char *device_name = NULL;
     char buf[32];
     img_iterator_node *node = NULL;
     char *device_name = NULL;
     char buf[32];
     img_iterator_node *node = NULL;
+    img_iterator_node *tmp = NULL;
     
     (void)ctxt;
 
     
     (void)ctxt;
 
@@ -762,13 +930,13 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
         goto fail;
     }
 
         goto fail;
     }
 
-    dev = grub_device_open(device_name);
+    g_enum_dev = dev = grub_device_open(device_name);
     if (!dev)
     {
         goto fail;        
     }
 
     if (!dev)
     {
         goto fail;        
     }
 
-    fs = grub_fs_probe(dev);
+    g_enum_fs = fs = grub_fs_probe(dev);
     if (!fs)
     {
         goto fail;
     if (!fs)
     {
         goto fail;
@@ -776,20 +944,29 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
 
     grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head));
 
 
     grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head));
 
+    g_img_iterator_head.dirlen = 1;
     g_img_iterator_head.tail = &tail;
     g_img_iterator_head.tail = &tail;
-    grub_strcpy(g_img_iterator_head.dir, "/");    
+    grub_strcpy(g_img_iterator_head.dir, "/"); 
 
 
-    fs->fs_dir(dev, "/", ventoy_colect_img_files, &g_img_iterator_head);
+    for (node = &g_img_iterator_head; node; node = node->next)
+    {
+        fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node);        
+    }
 
 
-    while (g_img_iterator_head.next)
+    for (node = &g_img_iterator_head; node; node = node->next)
     {
     {
-        node = g_img_iterator_head.next;
-        g_img_iterator_head.next = node->next;
+        ventoy_dynamic_tree_menu(node);
+    }
 
 
-        fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node);
+    /* free node */
+    node = g_img_iterator_head.next;    
+    while (node)
+    {
+        tmp = node->next;
         grub_free(node);
         grub_free(node);
+        node = tmp;
     }
     }
-
+    
     /* sort image list by image name */
     for (cur = g_ventoy_img_list; cur; cur = cur->next)
     {
     /* sort image list by image name */
     for (cur = g_ventoy_img_list; cur; cur = cur->next)
     {
@@ -802,6 +979,16 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
         }
     }
 
         }
     }
 
+    for (cur = g_ventoy_img_list; cur; cur = cur->next)
+    {
+        g_list_script_pos += grub_snprintf(g_list_script_buf + g_list_script_pos, VTOY_MAX_SCRIPT_BUF - g_list_script_pos, 
+                  "menuentry \"%s\" --id=\"VID_%d\" {\n"
+                  "  common_menuentry \n" 
+                  "}\n", 
+                  cur->name, cur->id);
+    }
+    g_list_script_buf[g_list_script_pos] = 0;
+
     grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count);
     grub_env_set(args[1], buf);
 
     grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count);
     grub_env_set(args[1], buf);
 
@@ -876,7 +1063,9 @@ static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char
 
 static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args)
 {
 
 static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args)
 {
-    const char *name = NULL;
+    int img_id = 0;
+    char *pos = NULL;
+    const char *id = NULL;
     img_info *cur = g_ventoy_img_list;
 
     (void)ctxt;
     img_info *cur = g_ventoy_img_list;
 
     (void)ctxt;
@@ -886,13 +1075,22 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg
         return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name);
     }
 
         return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name);
     }
 
-    name = grub_env_get("chosen");
+    id = grub_env_get("chosen");
+
+    pos = grub_strstr(id, "VID_");
+    if (pos)
+    {
+        img_id = (int)grub_strtoul(pos + 4, NULL, 10);
+    }
+    else
+    {
+        img_id = (int)grub_strtoul(id, NULL, 10);
+    }
 
     while (cur)
     {
 
     while (cur)
     {
-        if (0 == grub_strcmp(name, cur->name))
+        if (img_id == cur->id)
         {
         {
-            grub_env_set(args[0], cur->path);
             break;
         }
         cur = cur->next;
             break;
         }
         cur = cur->next;
@@ -903,6 +1101,8 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg
         return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image");
     }
 
         return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image");
     }
 
+    grub_env_set(args[0], cur->path);
+
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
@@ -1138,6 +1338,146 @@ static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int ar
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
+static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    (void)ctxt;
+    (void)argc;
+    (void)args;
+
+    if (argc == 0)
+    {
+        grub_printf("List Mode: CurLen:%d  MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF);
+        grub_printf("%s", g_list_script_buf);
+    }
+    else
+    {
+        grub_printf("Tree Mode: CurLen:%d  MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF);
+        grub_printf("%s", g_tree_script_buf);        
+    }
+
+    return 0;
+}
+
+static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    (void)ctxt;
+    (void)argc;
+    (void)args;
+
+    if (argc != 1)
+    {
+        return 1;
+    }
+
+    if (args[0][0] == '0')
+    {
+        return g_ventoy_memdisk_mode ? 0 : 1;
+    }
+    else if (args[0][0] == '1')
+    {
+        return g_ventoy_iso_raw ? 0 : 1;
+    }
+    else if (args[0][0] == '2')
+    {
+        return g_ventoy_iso_uefi_drv ? 0 : 1;
+    }
+
+    return 1;
+}
+
+static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    char memfile[128] = {0};
+    
+    (void)ctxt;
+    (void)argc;
+    (void)args;
+
+    if (argc == 0)
+    {
+        grub_script_execute_sourcecode(g_list_script_buf);
+    }
+    else
+    {
+        g_ventoy_last_entry = -1;
+        grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", 
+            (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); 
+        grub_script_execute_sourcecode(memfile);
+    }
+    
+    return 0;
+}
+
+static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    int id = 0;
+    int find = 0;
+    grub_disk_t disk;
+    const char *isopath = NULL;
+    char hdname[32];
+    ventoy_mbr_head mbr;
+    
+    (void)ctxt;
+    (void)argc;
+
+    if (argc != 1)
+    {
+        return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); 
+    }
+
+    isopath = grub_env_get("iso_path");
+    if (!isopath)
+    {
+        debug("isopath is null %p\n", isopath);
+        return 0;
+    }
+
+    debug("isopath is %s\n", isopath);
+
+    for (id = 0; id < 30 && (find == 0); id++)
+    {
+        grub_snprintf(hdname, sizeof(hdname), "hd%d,", id);
+        if (grub_strstr(isopath, hdname))
+        {
+            debug("skip %s ...\n", hdname);
+            continue;
+        }
+
+        grub_snprintf(hdname, sizeof(hdname), "hd%d", id);
+        
+        disk = grub_disk_open(hdname);
+        if (!disk)
+        {
+            debug("%s not exist\n", hdname);
+            break;
+        }
+
+        grub_memset(&mbr, 0, sizeof(mbr));
+        if (0 == grub_disk_read(disk, 0, 0, 512, &mbr))
+        {
+            if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA)
+            {
+                if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 ||
+                    mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80)
+                {
+                    
+                    grub_env_set(args[0], hdname);
+                    find = 1;
+                }
+            }
+            debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable");
+        }
+        else
+        {
+            debug("read %s failed\n", hdname);
+        }
+
+        grub_disk_close(disk);
+    }
+
+    return 0;
+}
+
 grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...)
 {
     va_list ap;
 grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...)
 {
     va_list ap;
@@ -1189,6 +1529,10 @@ static int ventoy_env_init(void)
     char buf[64];
 
     grub_env_set("vtdebug_flag", "");
     char buf[64];
 
     grub_env_set("vtdebug_flag", "");
+    grub_env_export("vtdebug_flag");
+
+    g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
+    g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
 
     ventoy_filt_register(0, ventoy_wrapper_open);
 
 
     ventoy_filt_register(0, ventoy_wrapper_open);
 
@@ -1219,6 +1563,10 @@ static cmd_para ventoy_cmds[] =
     { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL },
     { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL },
     { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },
     { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL },
     { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL },
     { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },
+    { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL },
+    { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL },
+    { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL },
+    { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL },
 
     { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
     { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL },
 
     { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
     { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL },
index 8e2615064418ddc0cde786bffcabdc17aa0ac381..27a315131bb21aa220563ceac1cfe9f452dc6b45 100644 (file)
 #ifndef __VENTOY_DEF_H__
 #define __VENTOY_DEF_H__
 
 #ifndef __VENTOY_DEF_H__
 #define __VENTOY_DEF_H__
 
+#define VTOY_MAX_SCRIPT_BUF    (4 * 1024 * 1024)
+
 #define JSON_SUCCESS    0
 #define JSON_FAILED     1
 #define JSON_NOT_FOUND  2
 
 #define JSON_SUCCESS    0
 #define JSON_FAILED     1
 #define JSON_NOT_FOUND  2
 
+#define ulong unsigned long
 #define ulonglong  unsigned long long
 
 #define vtoy_to_upper(c) (((char)(c) >= 'a' && (char)(c) <= 'z') ? ((char)(c) - 'a' + 'A') : (char)(c))
 #define ulonglong  unsigned long long
 
 #define vtoy_to_upper(c) (((char)(c) >= 'a' && (char)(c) <= 'z') ? ((char)(c) - 'a' + 'A') : (char)(c))
@@ -115,11 +118,15 @@ typedef struct ventoy_udf_override
 
 #pragma pack()
 
 
 #pragma pack()
 
-
 typedef struct img_info
 {
     char path[512];
     char name[256];
 typedef struct img_info
 {
     char path[512];
     char name[256];
+    int id;
+    grub_uint64_t size;
+    int select;
+
+    void *parent;
 
     struct img_info *next;
     struct img_info *prev;
 
     struct img_info *next;
     struct img_info *prev;
@@ -130,8 +137,19 @@ typedef struct img_iterator_node
     struct img_iterator_node *next;
     img_info **tail;
     char dir[400];
     struct img_iterator_node *next;
     img_info **tail;
     char dir[400];
+    int dirlen;
+    int isocnt;
+    int done;
+    int select;
+
+    struct img_iterator_node *parent;
+    struct img_iterator_node *firstchild;
+    
+    void *firstiso;    
 }img_iterator_node;
 
 }img_iterator_node;
 
+
+
 typedef struct initrd_info
 {
     char name[256];
 typedef struct initrd_info
 {
     char name[256];
@@ -504,5 +522,41 @@ static inline int ventoy_is_word_end(int c)
     return (c == 0 || c == ',' || ventoy_isspace(c));    
 }
 
     return (c == 0 || c == ',' || ventoy_isspace(c));    
 }
 
+#pragma pack(1)
+typedef struct ventoy_part_table
+{
+    grub_uint8_t  Active; // 0x00  0x80
+
+    grub_uint8_t  StartHead;
+    grub_uint16_t StartSector : 6;
+    grub_uint16_t StartCylinder : 10;
+
+    grub_uint8_t  FsFlag;
+
+    grub_uint8_t  EndHead;
+    grub_uint16_t EndSector : 6;
+    grub_uint16_t EndCylinder : 10;
+
+    grub_uint32_t StartSectorId;
+    grub_uint32_t SectorCount;
+}ventoy_part_table;
+
+typedef struct ventoy_mbr_head
+{
+    grub_uint8_t BootCode[446];
+    ventoy_part_table PartTbl[4];
+    grub_uint8_t Byte55;
+    grub_uint8_t ByteAA;
+}ventoy_mbr_head;
+#pragma pack()
+
+extern int g_ventoy_last_entry;
+extern int g_ventoy_memdisk_mode;
+extern int g_ventoy_iso_raw;
+extern int g_ventoy_iso_uefi_drv;
+
+int ventoy_cmp_img(img_info *img1, img_info *img2);
+void ventoy_swap_img(img_info *img1, img_info *img2);
+
 #endif /* __VENTOY_DEF_H__ */
 
 #endif /* __VENTOY_DEF_H__ */
 
index aa1f7fc6f08f25a45e3a7fd596367a9581cd2ab3..705582bc9ea293e6c8c3bd3ef725fbcf72ee0bc1 100644 (file)
 #ventoy_systemd_udevd_work_around
 #ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
 
 #ventoy_systemd_udevd_work_around
 #ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
 
-$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0#" -i /lib/dracut-lib.sh
+if $GREP -q 'root=live' /proc/cmdline; then
+    $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0#" -i /lib/dracut-lib.sh
+else
+    $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0#" -i /lib/dracut-lib.sh
+fi
+
 ventoy_set_inotify_script  rhel7/ventoy-inotifyd-hook.sh
 
 ventoy_set_inotify_script  rhel7/ventoy-inotifyd-hook.sh
 
-$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh
+$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh
 
 # suppress write protected mount warning
 if [ -e /usr/sbin/anaconda-diskroot ]; then
 
 # suppress write protected mount warning
 if [ -e /usr/sbin/anaconda-diskroot ]; then
index 2517f0b12688713f8f3dc8efedea2d79adcca6dc..543543d9e1d921052f488dae435bdd1419ded613 100644 (file)
@@ -165,6 +165,12 @@ ventoy_get_os_type() {
         echo 'arch'; return
     fi
     
         echo 'arch'; return
     fi
     
+    if $GREP -q 'berry ' /proc/version; then
+        echo 'berry'; return
+    fi
+    
+    
+    
     echo "default"
 }
 
     echo "default"
 }
 
index 19c0ab098e5b004061df2861e63a5c3ede094ae6..f7179af24e9a11501b19a1e061eff2e307e96d0b 100644 (file)
Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ
index 1ebf05ccd601f6b8cee6f8c580199d6438ee8aca..8e05b586e7b887fbdb0a3d56126bdae569de7f31 100644 (file)
@@ -56,6 +56,15 @@ fi
 
 vtdebug "MODE=$MODE FORCE=$FORCE"
 
 
 vtdebug "MODE=$MODE FORCE=$FORCE"
 
+if ! [ -f ./boot/boot.img ]; then
+    if [ -d ./grub ]; then
+        vterr "Don't run me here, please download the released install package, and run there."
+    else
+        vterr "Please run under the right directory!" 
+    fi
+    exit 1
+fi
+
 #decompress tool
 cd tool
 chmod +x ./xzcat
 #decompress tool
 cd tool
 chmod +x ./xzcat
index 18b9b0502c008b647d0ed273a0b95afbbc67eec9..be1697a545b4c4535660318b31d4bb73606860d7 100644 (file)
 # 
 #************************************************************************************
 
 # 
 #************************************************************************************
 
-function ventoy_boot_from_hdd {
-    if [ "$grub_platform" = "pc" ]; then
-        if [ "$iso_path" = "(hd0,1)" ]; then
-            if [ -b (hd1) ]; then
-                set root=(hd1)
-                drivemap -s hd0 hd1
-                chainloader +1
-                boot
-            else
-                echo  "No local hdd found ..."
-                sleep 3
-            fi
-        else
-            set root=(hd0)
-            chainloader +1
-            boot
-        fi
-    else
-        exit
+function ventoy_power {
+    echo '<1>  Reboot'
+    echo '<2>  Halt'
+    echo '<0>  Return to menu'
+    echo -e '\nPlease enter your choice:'
+    
+    unset vtOpt
+    read vtOpt
+    
+    if [ "$vtOpt" = "1" ]; then
+        echo -e '\n\nSystem is rebooting ... \n'
+        sleep 1
+        reboot
+    elif [ "$vtOpt" = "2" ]; then
+        echo -e '\n\nSystem is halting ... \n'
+        sleep 1
+        halt
     fi
 }
 
     fi
 }
 
-function ventoy_reboot {
-    reboot
-}
-
-
 function get_os_type {
     set vtoy_os=Linux    
     for file in "efi/microsoft" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com"; do
 function get_os_type {
     set vtoy_os=Linux    
     for file in "efi/microsoft" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com"; do
@@ -115,6 +108,9 @@ function distro_specify_initrd_file {
 function distro_specify_initrd_file_phase2 {
     if [ -f (loop)/boot/initrd.img ]; then
         vt_linux_specify_initrd_file /boot/initrd.img
 function distro_specify_initrd_file_phase2 {
     if [ -f (loop)/boot/initrd.img ]; then
         vt_linux_specify_initrd_file /boot/initrd.img
+    elif [ -f (loop)/Setup/initrd.gz ]; then
+        vt_linux_specify_initrd_file /Setup/initrd.gz
+        
     fi
 }
 
     fi
 }
 
@@ -211,7 +207,7 @@ function uefi_iso_menu_func {
     if [ -n "$vtisouefi" ]; then
         set LoadIsoEfiDriver=on
         unset vtisouefi
     if [ -n "$vtisouefi" ]; then
         set LoadIsoEfiDriver=on
         unset vtisouefi
-    elif [ -n "$VTOY_ISO_UEFI_DRV" ]; then
+    elif vt_check_mode 2; then
         set LoadIsoEfiDriver=on
     else
         unset LoadIsoEfiDriver
         set LoadIsoEfiDriver=on
     else
         unset LoadIsoEfiDriver
@@ -239,7 +235,7 @@ function uefi_iso_menu_func {
     if [ -n "$vtcompat" ]; then
         set ventoy_compatible=YES
         unset vtcompat
     if [ -n "$vtcompat" ]; then
         set ventoy_compatible=YES
         unset vtcompat
-    elif [ -n "$VTOY_ISO_RAW" ]; then
+    elif vt_check_mode 1; then
         set ventoy_compatible=YES
     else
         vt_check_compatible (loop)
         set ventoy_compatible=YES
     else
         vt_check_compatible (loop)
@@ -274,8 +270,6 @@ function uefi_iso_memdisk {
 }
 
 
 }
 
 
-
-
 function legacy_windows_menu_func {
     vt_windows_reset
     
 function legacy_windows_menu_func {
     vt_windows_reset
     
@@ -383,7 +377,7 @@ function legacy_iso_menu_func {
     if [ -n "$vtcompat" ]; then
         set ventoy_compatible=YES
         unset vtcompat
     if [ -n "$vtcompat" ]; then
         set ventoy_compatible=YES
         unset vtcompat
-    elif [ -n "$VTOY_ISO_RAW" ]; then
+    elif vt_check_mode 1; then
         set ventoy_compatible=YES
     else
         vt_check_compatible (loop)
         set ventoy_compatible=YES
     else
         vt_check_compatible (loop)
@@ -413,6 +407,22 @@ function legacy_iso_memdisk {
     boot
 }
 
     boot
 }
 
+function common_menuentry {
+    if [ "$grub_platform" = "pc" ]; then
+        if vt_check_mode 0; then
+            legacy_iso_memdisk $iso_path
+        else
+            legacy_iso_menu_func $iso_path
+        fi
+    else
+        if vt_check_mode 0; then
+            uefi_iso_memdisk $iso_path 
+        else
+            uefi_iso_menu_func $iso_path                
+        fi
+    fi      
+}
+
 
 #############################################################
 #############################################################
 
 #############################################################
 #############################################################
@@ -422,7 +432,7 @@ function legacy_iso_memdisk {
 #############################################################
 #############################################################
 
 #############################################################
 #############################################################
 
-set VENTOY_VERSION="1.0.08b2"
+set VENTOY_VERSION="1.0.08"
 
 #disable timeout
 unset timeout
 
 #disable timeout
 unset timeout
@@ -431,8 +441,15 @@ set VTOY_MEM_DISK_STR="MEMDISK"
 set VTOY_ISO_RAW_STR="ISO RAW"
 set VTOY_ISO_UEFI_DRV_STR="UEFI FS"
 
 set VTOY_ISO_RAW_STR="ISO RAW"
 set VTOY_ISO_UEFI_DRV_STR="UEFI FS"
 
-set VTOY_F2_CMD="ventoy_boot_from_hdd"
-set VTOY_F3_CMD="ventoy_reboot"
+set VTOY_F2_CMD="ventoy_power"
+set VTOY_F3_CMD="vt_dynamic_menu tree"
+
+set VTOY_HOTKEY_TIP="F1:Memdisk  F2:Power  F3:TreeView"
+if [ "$grub_platform" = "pc" ]; then
+    set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS  www.ventoy.net"
+else
+    set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI  www.ventoy.net"
+fi
 
 vt_device $root  vtoy_dev
 
 
 vt_device $root  vtoy_dev
 
@@ -473,33 +490,12 @@ terminal_output  gfxterm
 set ventoy_img_count=0
 vt_list_img $iso_path ventoy_img_count
 
 set ventoy_img_count=0
 vt_list_img $iso_path ventoy_img_count
 
-#Dynamic menu for every iso file
-if vt_cmp $ventoy_img_count ne 0; then
-    set imgid=0
-    while vt_cmp $imgid lt $ventoy_img_count; do       
-        vt_img_name $imgid img_name
-        menuentry "$img_name" {  
-            if [ "$grub_platform" = "pc" ]; then
-                if [ -n "$VTOY_MEM_DISK" ]; then
-                    legacy_iso_memdisk $iso_path
-                else
-                    legacy_iso_menu_func $iso_path
-                fi
-            else
-                if [ -n "$VTOY_MEM_DISK" ]; then
-                    uefi_iso_memdisk $iso_path 
-                else
-                    uefi_iso_menu_func $iso_path                
-                fi
-            fi            
-        }
-        
-        vt_incr imgid 1
-    done
+#Main menu
+if [ $ventoy_img_count -gt 0 ]; then
+    vt_dynamic_menu
 else
     menuentry "No ISO files found (Press enter to reboot ...)" {
         echo -e "\n    Rebooting ... "
         reboot
     }
 fi
 else
     menuentry "No ISO files found (Press enter to reboot ...)" {
         echo -e "\n    Rebooting ... "
         reboot
     }
 fi
-
index 3e06b842ef8752912262027a9836aa9d4e57a518..d899233109d67e0b5cba5b8e4b0028ceed3cd9dd 100644 (file)
Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ
index 86f5ec3d2628e51a979efe9844ebea2ba58b6dcf..a605b434cda26bfe2ddfdead06eb9a8e7d4d7b0a 100644 (file)
@@ -19,7 +19,7 @@ terminal-box: "terminal_box_*.png"
   item_font = "ascii"  
   item_color = "#ffffff"  
   item_height = 30
   item_font = "ascii"  
   item_color = "#ffffff"  
   item_height = 30
-  item_icon_space = 1
+  
   item_spacing = 1
   item_padding = 1
 
   item_spacing = 1
   item_padding = 1
 
@@ -27,8 +27,7 @@ terminal-box: "terminal_box_*.png"
   selected_item_color= "#f2f2f2"
   selected_item_pixmap_style = "select_*.png"
 
   selected_item_color= "#f2f2f2"
   selected_item_pixmap_style = "select_*.png"
 
-  #icon_height = 30
-  #icon_width = 30
+  item_icon_space = 0
 
   scrollbar = true
   scrollbar_width = 10
 
   scrollbar = true
   scrollbar_width = 10
@@ -50,11 +49,11 @@ terminal-box: "terminal_box_*.png"
 }
 
 + hbox{ 
 }
 
 + hbox{ 
-    left = 40%
+    left = 30%
     top = 95%
     width = 10%
     height = 25
     top = 95%
     width = 10%
     height = 25
-    + label {text = "F1:Memdisk" color = "blue" align = "left"} 
+    + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} 
 }
 
 
 }
 
 
index db224dddad1c74aaa8405216ebd210aae55d3c78..9487e610bc946edc72ca8f548d1b8a69a8f063b7 100644 (file)
Binary files a/INSTALL/grub/x86_64-efi/normal.mod and b/INSTALL/grub/x86_64-efi/normal.mod differ
index c181fceca817949ec8a1b909d6306b2d92f4b8f9..bbaa290e1a9b27b7fbe346437a309ac1160f1d0e 100644 (file)
Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ