]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c
3a47de6ad021272f39e9d261fe59277143686f91
[Ventoy.git] / GRUB2 / MOD_SRC / grub-2.04 / grub-core / ventoy / ventoy_plugin.c
1 /******************************************************************************
2 * ventoy_plugin.c
3 *
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20 #include <grub/types.h>
21 #include <grub/misc.h>
22 #include <grub/mm.h>
23 #include <grub/err.h>
24 #include <grub/dl.h>
25 #include <grub/disk.h>
26 #include <grub/device.h>
27 #include <grub/term.h>
28 #include <grub/partition.h>
29 #include <grub/file.h>
30 #include <grub/normal.h>
31 #include <grub/extcmd.h>
32 #include <grub/datetime.h>
33 #include <grub/i18n.h>
34 #include <grub/net.h>
35 #include <grub/crypto.h>
36 #include <grub/time.h>
37 #include <grub/font.h>
38 #include <grub/ventoy.h>
39 #include "ventoy_def.h"
40
41 GRUB_MOD_LICENSE ("GPLv3+");
42
43 char g_arch_mode_suffix[64];
44 static char g_iso_disk_name[128];
45 static vtoy_password g_boot_pwd;
46 static vtoy_password g_file_type_pwd[img_type_max];
47 static install_template *g_install_template_head = NULL;
48 static dud *g_dud_head = NULL;
49 static menu_password *g_pwd_head = NULL;
50 static persistence_config *g_persistence_head = NULL;
51 static menu_tip *g_menu_tip_head = NULL;
52 static menu_alias *g_menu_alias_head = NULL;
53 static menu_class *g_menu_class_head = NULL;
54 static custom_boot *g_custom_boot_head = NULL;
55 static injection_config *g_injection_head = NULL;
56 static auto_memdisk *g_auto_memdisk_head = NULL;
57 static image_list *g_image_list_head = NULL;
58 static conf_replace *g_conf_replace_head = NULL;
59
60 static int g_theme_num = 0;
61 static theme_list *g_theme_head = NULL;
62 static int g_theme_random = vtoy_theme_random_boot_second;
63 static char g_theme_single_file[256];
64
65 static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath)
66 {
67 if (patlen > 1)
68 {
69 if (isopath[patlen] == '/' && ventoy_strncmp(pat, isopath, patlen) == 0 &&
70 grub_strchr(isopath + patlen + 1, '/') == NULL)
71 {
72 return 1;
73 }
74 }
75 else
76 {
77 if (pat[0] == '/' && grub_strchr(isopath + 1, '/') == NULL)
78 {
79 return 1;
80 }
81 }
82
83 return 0;
84 }
85
86 static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
87 {
88 int rc = 0;
89 VTOY_JSON *pNode = NULL;
90 VTOY_JSON *pChild = NULL;
91
92 (void)isodisk;
93
94 if (json->enDataType != JSON_TYPE_ARRAY)
95 {
96 grub_printf("Not array type %d\n", json->enDataType);
97 return 1;
98 }
99
100 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
101 {
102 if (pNode->enDataType == JSON_TYPE_OBJECT)
103 {
104 pChild = pNode->pstChild;
105 if (pChild->enDataType == JSON_TYPE_STRING)
106 {
107 if (grub_strcmp(pChild->pcName, "VTOY_DEFAULT_IMAGE") == 0)
108 {
109 grub_printf("%s: %s [%s]\n", pChild->pcName, pChild->unData.pcStrVal,
110 ventoy_check_file_exist("%s%s", isodisk, pChild->unData.pcStrVal) ? "OK" : "NOT EXIST");
111 }
112 else
113 {
114 grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
115 }
116 }
117 else
118 {
119 grub_printf("%s is NOT string type\n", pChild->pcName);
120 rc = 1;
121 }
122 }
123 else
124 {
125 grub_printf("%s is not an object\n", pNode->pcName);
126 rc = 1;
127 }
128 }
129
130 return rc;
131 }
132
133 static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
134 {
135 VTOY_JSON *pNode = NULL;
136 VTOY_JSON *pChild = NULL;
137
138 (void)isodisk;
139
140 if (json->enDataType != JSON_TYPE_ARRAY)
141 {
142 debug("Not array %d\n", json->enDataType);
143 return 0;
144 }
145
146 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
147 {
148 if (pNode->enDataType == JSON_TYPE_OBJECT)
149 {
150 pChild = pNode->pstChild;
151 if (pChild->enDataType == JSON_TYPE_STRING && pChild->pcName && pChild->unData.pcStrVal)
152 {
153 ventoy_set_env(pChild->pcName, pChild->unData.pcStrVal);
154 }
155 }
156 }
157
158 return 0;
159 }
160
161 static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
162 {
163 int exist = 0;
164 const char *value;
165 VTOY_JSON *node;
166
167 value = vtoy_json_get_string_ex(json->pstChild, "file");
168 if (value)
169 {
170 grub_printf("file: %s\n", value);
171 if (value[0] == '/')
172 {
173 exist = ventoy_is_file_exist("%s%s", isodisk, value);
174 }
175 else
176 {
177 exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
178 }
179
180 if (exist == 0)
181 {
182 grub_printf("Theme file %s does NOT exist\n", value);
183 return 1;
184 }
185 }
186 else
187 {
188 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file");
189 if (node)
190 {
191 for (node = node->pstChild; node; node = node->pstNext)
192 {
193 value = node->unData.pcStrVal;
194 grub_printf("file: %s\n", value);
195 if (value[0] == '/')
196 {
197 exist = ventoy_is_file_exist("%s%s", isodisk, value);
198 }
199 else
200 {
201 exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
202 }
203
204 if (exist == 0)
205 {
206 grub_printf("Theme file %s does NOT exist\n", value);
207 return 1;
208 }
209 }
210
211 value = vtoy_json_get_string_ex(json->pstChild, "random");
212 if (value)
213 {
214 grub_printf("random: %s\n", value);
215 }
216 }
217 }
218
219 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
220 if (value)
221 {
222 grub_printf("gfxmode: %s\n", value);
223 }
224
225 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
226 if (value)
227 {
228 grub_printf("display_mode: %s\n", value);
229 }
230
231 value = vtoy_json_get_string_ex(json->pstChild, "serial_param");
232 if (value)
233 {
234 grub_printf("serial_param %s\n", value);
235 }
236
237 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
238 if (value)
239 {
240 grub_printf("ventoy_left: %s\n", value);
241 }
242
243 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
244 if (value)
245 {
246 grub_printf("ventoy_top: %s\n", value);
247 }
248
249 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
250 if (value)
251 {
252 grub_printf("ventoy_color: %s\n", value);
253 }
254
255 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts");
256 if (node)
257 {
258 for (node = node->pstChild; node; node = node->pstNext)
259 {
260 if (node->enDataType == JSON_TYPE_STRING)
261 {
262 if (ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal))
263 {
264 grub_printf("%s [OK]\n", node->unData.pcStrVal);
265 }
266 else
267 {
268 grub_printf("%s [NOT EXIST]\n", node->unData.pcStrVal);
269 }
270 }
271 }
272 }
273 else
274 {
275 grub_printf("fonts NOT found\n");
276 }
277
278 return 0;
279 }
280
281 static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
282 {
283 const char *value;
284 char filepath[256];
285 VTOY_JSON *node = NULL;
286 theme_list *tail = NULL;
287 theme_list *themenode = NULL;
288
289 value = vtoy_json_get_string_ex(json->pstChild, "file");
290 if (value)
291 {
292 if (value[0] == '/')
293 {
294 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value);
295 }
296 else
297 {
298 grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value);
299 }
300
301 if (ventoy_check_file_exist(filepath) == 0)
302 {
303 debug("Theme file %s does not exist\n", filepath);
304 return 0;
305 }
306
307 debug("vtoy_theme %s\n", filepath);
308 ventoy_env_export("vtoy_theme", filepath);
309 grub_snprintf(g_theme_single_file, sizeof(g_theme_single_file), "%s", filepath);
310 }
311 else
312 {
313 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file");
314 if (node)
315 {
316 for (node = node->pstChild; node; node = node->pstNext)
317 {
318 value = node->unData.pcStrVal;
319 if (value[0] == '/')
320 {
321 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value);
322 }
323 else
324 {
325 grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value);
326 }
327
328 if (ventoy_check_file_exist(filepath) == 0)
329 {
330 continue;
331 }
332
333 themenode = grub_zalloc(sizeof(theme_list));
334 if (themenode)
335 {
336 grub_snprintf(themenode->theme.path, sizeof(themenode->theme.path), "%s", filepath);
337 if (g_theme_head)
338 {
339 tail->next = themenode;
340 }
341 else
342 {
343 g_theme_head = themenode;
344 }
345 tail = themenode;
346 g_theme_num++;
347 }
348 }
349
350 ventoy_env_export("vtoy_theme", "random");
351 value = vtoy_json_get_string_ex(json->pstChild, "random");
352 if (value)
353 {
354 if (grub_strcmp(value, "boot_second") == 0)
355 {
356 g_theme_random = vtoy_theme_random_boot_second;
357 }
358 else if (grub_strcmp(value, "boot_day") == 0)
359 {
360 g_theme_random = vtoy_theme_random_boot_day;
361 }
362 else if (grub_strcmp(value, "boot_month") == 0)
363 {
364 g_theme_random = vtoy_theme_random_boot_month;
365 }
366 }
367 }
368 }
369
370 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
371 if (value)
372 {
373 debug("vtoy_gfxmode %s\n", value);
374 ventoy_env_export("vtoy_gfxmode", value);
375 }
376
377 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
378 if (value)
379 {
380 debug("display_mode %s\n", value);
381 ventoy_env_export("vtoy_display_mode", value);
382 }
383
384 value = vtoy_json_get_string_ex(json->pstChild, "serial_param");
385 if (value)
386 {
387 debug("serial_param %s\n", value);
388 ventoy_env_export("vtoy_serial_param", value);
389 }
390
391 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
392 if (value)
393 {
394 ventoy_env_export("VTLE_LFT", value);
395 }
396
397 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
398 if (value)
399 {
400 ventoy_env_export("VTLE_TOP", value);
401 }
402
403 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
404 if (value)
405 {
406 ventoy_env_export("VTLE_CLR", value);
407 }
408
409 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts");
410 if (node)
411 {
412 for (node = node->pstChild; node; node = node->pstNext)
413 {
414 if (node->enDataType == JSON_TYPE_STRING &&
415 ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal))
416 {
417 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, node->unData.pcStrVal);
418 grub_font_load(filepath);
419 }
420 }
421 }
422
423 return 0;
424 }
425
426 static int ventoy_plugin_check_path(const char *path, const char *file)
427 {
428 if (file[0] != '/')
429 {
430 grub_printf("%s is NOT begin with '/' \n", file);
431 return 1;
432 }
433
434 if (grub_strchr(file, '\\'))
435 {
436 grub_printf("%s contains invalid '\\' \n", file);
437 return 1;
438 }
439
440 if (grub_strstr(file, "//"))
441 {
442 grub_printf("%s contains invalid double slash\n", file);
443 return 1;
444 }
445
446 if (grub_strstr(file, "../"))
447 {
448 grub_printf("%s contains invalid '../' \n", file);
449 return 1;
450 }
451
452 if (!ventoy_is_file_exist("%s%s", path, file))
453 {
454 grub_printf("%s%s does NOT exist\n", path, file);
455 return 1;
456 }
457
458 return 0;
459 }
460
461 static int ventoy_plugin_check_fullpath
462 (
463 VTOY_JSON *json,
464 const char *isodisk,
465 const char *key,
466 int *pathnum
467 )
468 {
469 int rc = 0;
470 int ret = 0;
471 int cnt = 0;
472 VTOY_JSON *node = json;
473 VTOY_JSON *child = NULL;
474
475 while (node)
476 {
477 if (0 == grub_strcmp(key, node->pcName))
478 {
479 break;
480 }
481 node = node->pstNext;
482 }
483
484 if (!node)
485 {
486 return 1;
487 }
488
489 if (JSON_TYPE_STRING == node->enDataType)
490 {
491 cnt = 1;
492 ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
493 grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
494 }
495 else if (JSON_TYPE_ARRAY == node->enDataType)
496 {
497 for (child = node->pstChild; child; child = child->pstNext)
498 {
499 if (JSON_TYPE_STRING != child->enDataType)
500 {
501 grub_printf("Non string json type\n");
502 }
503 else
504 {
505 rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
506 grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
507 ret += rc;
508 cnt++;
509 }
510 }
511 }
512
513 *pathnum = cnt;
514 return ret;
515 }
516
517 static int ventoy_plugin_parse_fullpath
518 (
519 VTOY_JSON *json,
520 const char *isodisk,
521 const char *key,
522 file_fullpath **fullpath,
523 int *pathnum
524 )
525 {
526 int rc = 1;
527 int count = 0;
528 VTOY_JSON *node = json;
529 VTOY_JSON *child = NULL;
530 file_fullpath *path = NULL;
531
532 while (node)
533 {
534 if (0 == grub_strcmp(key, node->pcName))
535 {
536 break;
537 }
538 node = node->pstNext;
539 }
540
541 if (!node)
542 {
543 return 1;
544 }
545
546 if (JSON_TYPE_STRING == node->enDataType)
547 {
548 debug("%s is string type data\n", node->pcName);
549
550 if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal)))
551 {
552 debug("%s%s file not found\n", isodisk, node->unData.pcStrVal);
553 return 1;
554 }
555
556 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath));
557 if (path)
558 {
559 grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal);
560 *fullpath = path;
561 *pathnum = 1;
562 rc = 0;
563 }
564 }
565 else if (JSON_TYPE_ARRAY == node->enDataType)
566 {
567 for (child = node->pstChild; child; child = child->pstNext)
568 {
569 if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/'))
570 {
571 debug("Invalid data type:%d\n", child->enDataType);
572 return 1;
573 }
574 count++;
575 }
576 debug("%s is array type data, count=%d\n", node->pcName, count);
577
578 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count);
579 if (path)
580 {
581 *fullpath = path;
582
583 for (count = 0, child = node->pstChild; child; child = child->pstNext)
584 {
585 if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal))
586 {
587 grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal);
588 path++;
589 count++;
590 }
591 }
592
593 *pathnum = count;
594 rc = 0;
595 }
596 }
597
598 return rc;
599 }
600
601 static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk)
602 {
603 int pathnum = 0;
604 int autosel = 0;
605 int timeout = 0;
606 char *pos = NULL;
607 const char *iso = NULL;
608 VTOY_JSON *pNode = NULL;
609
610 if (json->enDataType != JSON_TYPE_ARRAY)
611 {
612 grub_printf("Not array type %d\n", json->enDataType);
613 return 1;
614 }
615
616 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
617 {
618 if (pNode->enDataType != JSON_TYPE_OBJECT)
619 {
620 grub_printf("NOT object type\n");
621 }
622
623 if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "image")) != NULL)
624 {
625 pos = grub_strchr(iso, '*');
626 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
627 {
628 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
629 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum);
630
631 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
632 {
633 if (autosel >= 0 && autosel <= pathnum)
634 {
635 grub_printf("autosel: %d [OK]\n", autosel);
636 }
637 else
638 {
639 grub_printf("autosel: %d [FAIL]\n", autosel);
640 }
641 }
642
643 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
644 {
645 if (timeout >= 0)
646 {
647 grub_printf("timeout: %d [OK]\n", timeout);
648 }
649 else
650 {
651 grub_printf("timeout: %d [FAIL]\n", timeout);
652 }
653 }
654 }
655 else
656 {
657 grub_printf("image: %s [FAIL]\n", iso);
658 }
659 }
660 else if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "parent")) != NULL)
661 {
662 if (ventoy_is_dir_exist("%s%s", isodisk, iso))
663 {
664 grub_printf("parent: %s [OK]\n", iso);
665 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum);
666
667 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
668 {
669 if (autosel >= 0 && autosel <= pathnum)
670 {
671 grub_printf("autosel: %d [OK]\n", autosel);
672 }
673 else
674 {
675 grub_printf("autosel: %d [FAIL]\n", autosel);
676 }
677 }
678
679 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
680 {
681 if (timeout >= 0)
682 {
683 grub_printf("timeout: %d [OK]\n", timeout);
684 }
685 else
686 {
687 grub_printf("timeout: %d [FAIL]\n", timeout);
688 }
689 }
690 }
691 else
692 {
693 grub_printf("parent: %s [FAIL]\n", iso);
694 }
695 }
696 else
697 {
698 grub_printf("image not found\n");
699 }
700 }
701
702 return 0;
703 }
704
705 static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk)
706 {
707 int type = 0;
708 int pathnum = 0;
709 int autosel = 0;
710 int timeout = 0;
711 const char *iso = NULL;
712 VTOY_JSON *pNode = NULL;
713 install_template *node = NULL;
714 install_template *next = NULL;
715 file_fullpath *templatepath = NULL;
716
717 if (json->enDataType != JSON_TYPE_ARRAY)
718 {
719 debug("Not array %d\n", json->enDataType);
720 return 0;
721 }
722
723 if (g_install_template_head)
724 {
725 for (node = g_install_template_head; node; node = next)
726 {
727 next = node->next;
728 grub_check_free(node->templatepath);
729 grub_free(node);
730 }
731
732 g_install_template_head = NULL;
733 }
734
735 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
736 {
737 type = auto_install_type_file;
738 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
739 if (!iso)
740 {
741 type = auto_install_type_parent;
742 iso = vtoy_json_get_string_ex(pNode->pstChild, "parent");
743 }
744
745 if (iso && iso[0] == '/')
746 {
747 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum))
748 {
749 node = grub_zalloc(sizeof(install_template));
750 if (node)
751 {
752 node->type = type;
753 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
754 node->templatepath = templatepath;
755 node->templatenum = pathnum;
756
757 node->autosel = -1;
758 node->timeout = -1;
759 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
760 {
761 if (autosel >= 0 && autosel <= pathnum)
762 {
763 node->autosel = autosel;
764 }
765 }
766
767 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
768 {
769 if (timeout >= 0)
770 {
771 node->timeout = timeout;
772 }
773 }
774
775 if (g_install_template_head)
776 {
777 node->next = g_install_template_head;
778 }
779
780 g_install_template_head = node;
781 }
782 }
783 }
784 }
785
786 return 0;
787 }
788
789 static int ventoy_plugin_dud_check(VTOY_JSON *json, const char *isodisk)
790 {
791 int pathnum = 0;
792 char *pos = NULL;
793 const char *iso = NULL;
794 VTOY_JSON *pNode = NULL;
795
796 if (json->enDataType != JSON_TYPE_ARRAY)
797 {
798 grub_printf("Not array type %d\n", json->enDataType);
799 return 1;
800 }
801
802 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
803 {
804 if (pNode->enDataType != JSON_TYPE_OBJECT)
805 {
806 grub_printf("NOT object type\n");
807 }
808
809 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
810 if (iso)
811 {
812 pos = grub_strchr(iso, '*');
813 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
814 {
815 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
816 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "dud", &pathnum);
817 }
818 else
819 {
820 grub_printf("image: %s [FAIL]\n", iso);
821 }
822 }
823 else
824 {
825 grub_printf("image not found\n");
826 }
827 }
828
829 return 0;
830 }
831
832 static int ventoy_plugin_dud_entry(VTOY_JSON *json, const char *isodisk)
833 {
834 int pathnum = 0;
835 const char *iso = NULL;
836 VTOY_JSON *pNode = NULL;
837 dud *node = NULL;
838 dud *next = NULL;
839 file_fullpath *dudpath = NULL;
840
841 if (json->enDataType != JSON_TYPE_ARRAY)
842 {
843 debug("Not array %d\n", json->enDataType);
844 return 0;
845 }
846
847 if (g_dud_head)
848 {
849 for (node = g_dud_head; node; node = next)
850 {
851 next = node->next;
852 grub_check_free(node->dudpath);
853 grub_free(node);
854 }
855
856 g_dud_head = NULL;
857 }
858
859 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
860 {
861 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
862 if (iso && iso[0] == '/')
863 {
864 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "dud", &dudpath, &pathnum))
865 {
866 node = grub_zalloc(sizeof(dud));
867 if (node)
868 {
869 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
870 node->dudpath = dudpath;
871 node->dudnum = pathnum;
872 node->files = grub_zalloc(sizeof(dudfile) * pathnum);
873
874 if (node->files)
875 {
876 if (g_dud_head)
877 {
878 node->next = g_dud_head;
879 }
880
881 g_dud_head = node;
882 }
883 else
884 {
885 grub_free(node);
886 }
887 }
888 }
889 }
890 }
891
892 return 0;
893 }
894
895 static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd)
896 {
897 int i;
898 int len;
899 char ch;
900 char *pos;
901 char bytes[3];
902 vtoy_password tmpPwd;
903
904 len = (int)grub_strlen(pwdstr);
905 if (len > 64)
906 {
907 if (NULL == pwd) grub_printf("Password too long %d\n", len);
908 return 1;
909 }
910
911 grub_memset(&tmpPwd, 0, sizeof(tmpPwd));
912
913 if (grub_strncmp(pwdstr, "txt#", 4) == 0)
914 {
915 tmpPwd.type = VTOY_PASSWORD_TXT;
916 grub_snprintf(tmpPwd.text, sizeof(tmpPwd.text), "%s", pwdstr + 4);
917 }
918 else if (grub_strncmp(pwdstr, "md5#", 4) == 0)
919 {
920 if ((len - 4) == 32)
921 {
922 for (i = 0; i < 16; i++)
923 {
924 bytes[0] = pwdstr[4 + i * 2];
925 bytes[1] = pwdstr[4 + i * 2 + 1];
926 bytes[2] = 0;
927
928 if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
929 {
930 tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
931 }
932 else
933 {
934 if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
935 return 1;
936 }
937 }
938 tmpPwd.type = VTOY_PASSWORD_MD5;
939 }
940 else if ((len - 4) > 32)
941 {
942 pos = grub_strchr(pwdstr + 4, '#');
943 if (!pos)
944 {
945 if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
946 return 1;
947 }
948
949 if (len - 1 - (int)(long)(pos - pwdstr) != 32)
950 {
951 if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr);
952 return 1;
953 }
954
955 ch = *pos;
956 *pos = 0;
957 grub_snprintf(tmpPwd.salt, sizeof(tmpPwd.salt), "%s", pwdstr + 4);
958 *pos = ch;
959
960 pos++;
961 for (i = 0; i < 16; i++)
962 {
963 bytes[0] = pos[i * 2];
964 bytes[1] = pos[i * 2 + 1];
965 bytes[2] = 0;
966
967 if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
968 {
969 tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
970 }
971 else
972 {
973 if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
974 return 1;
975 }
976 }
977
978 tmpPwd.type = VTOY_PASSWORD_SALT_MD5;
979 }
980 else
981 {
982 if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
983 return 1;
984 }
985 }
986 else
987 {
988 if (NULL == pwd) grub_printf("Invalid password format %s\n", pwdstr);
989 return 1;
990 }
991
992 if (pwd)
993 {
994 grub_memcpy(pwd, &tmpPwd, sizeof(tmpPwd));
995 }
996
997 return 0;
998 }
999
1000 static int ventoy_plugin_get_pwd_type(const char *pwd)
1001 {
1002 int i;
1003 char pwdtype[64];
1004
1005 for (i = 0; pwd && i < (int)ARRAY_SIZE(g_menu_prefix); i++)
1006 {
1007 grub_snprintf(pwdtype, sizeof(pwdtype), "%spwd", g_menu_prefix[i]);
1008 if (grub_strcmp(pwdtype, pwd) == 0)
1009 {
1010 return img_type_start + i;
1011 }
1012 }
1013
1014 return -1;
1015 }
1016
1017 static int ventoy_plugin_pwd_entry(VTOY_JSON *json, const char *isodisk)
1018 {
1019 int type = -1;
1020 const char *iso = NULL;
1021 const char *pwd = NULL;
1022 VTOY_JSON *pNode = NULL;
1023 VTOY_JSON *pCNode = NULL;
1024 menu_password *node = NULL;
1025 menu_password *tail = NULL;
1026 menu_password *next = NULL;
1027
1028 (void)isodisk;
1029
1030 if (json->enDataType != JSON_TYPE_OBJECT)
1031 {
1032 debug("Not object %d\n", json->enDataType);
1033 return 0;
1034 }
1035
1036 if (g_pwd_head)
1037 {
1038 for (node = g_pwd_head; node; node = next)
1039 {
1040 next = node->next;
1041 grub_free(node);
1042 }
1043
1044 g_pwd_head = NULL;
1045 }
1046
1047 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1048 {
1049 if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
1050 {
1051 ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, &g_boot_pwd);
1052 }
1053 else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0)
1054 {
1055 ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, g_file_type_pwd + type);
1056 }
1057 else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
1058 {
1059 for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext)
1060 {
1061 if (pCNode->enDataType != JSON_TYPE_OBJECT)
1062 {
1063 continue;
1064 }
1065
1066 type = vtoy_menu_pwd_file;
1067 iso = vtoy_json_get_string_ex(pCNode->pstChild, "file");
1068 if (!iso)
1069 {
1070 type = vtoy_menu_pwd_parent;
1071 iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent");
1072 }
1073
1074 pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
1075 if (iso && pwd && iso[0] == '/')
1076 {
1077 node = grub_zalloc(sizeof(menu_password));
1078 if (node)
1079 {
1080 node->type = type;
1081 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
1082
1083 if (ventoy_plugin_parse_pwdstr((char *)pwd, &(node->password)))
1084 {
1085 grub_free(node);
1086 continue;
1087 }
1088
1089 if (g_pwd_head)
1090 {
1091 tail->next = node;
1092 }
1093 else
1094 {
1095 g_pwd_head = node;
1096 }
1097 tail = node;
1098 }
1099 }
1100 }
1101 }
1102 }
1103
1104 return 0;
1105 }
1106
1107 static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk)
1108 {
1109 int type = -1;
1110 char *pos = NULL;
1111 const char *iso = NULL;
1112 const char *pwd = NULL;
1113 VTOY_JSON *pNode = NULL;
1114 VTOY_JSON *pCNode = NULL;
1115
1116 if (json->enDataType != JSON_TYPE_OBJECT)
1117 {
1118 grub_printf("Not object %d\n", json->enDataType);
1119 return 0;
1120 }
1121
1122 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1123 {
1124 if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
1125 {
1126 if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL))
1127 {
1128 grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal);
1129 }
1130 else
1131 {
1132 grub_printf("Invalid bootpwd.\n");
1133 }
1134 }
1135 else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0)
1136 {
1137 if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL))
1138 {
1139 grub_printf("%s:<%s>\n", pNode->pcName, pNode->unData.pcStrVal);
1140 }
1141 else
1142 {
1143 grub_printf("Invalid pwd <%s>\n", pNode->unData.pcStrVal);
1144 }
1145 }
1146 else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
1147 {
1148 grub_printf("\n");
1149 for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext)
1150 {
1151 if (pCNode->enDataType != JSON_TYPE_OBJECT)
1152 {
1153 grub_printf("Not object %d\n", pCNode->enDataType);
1154 continue;
1155 }
1156
1157 if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "file")) != NULL)
1158 {
1159 pos = grub_strchr(iso, '*');
1160 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
1161 {
1162 pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
1163
1164 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL))
1165 {
1166 grub_printf("file:<%s> [%s]\n", iso, (pos ? "*" : "OK"));
1167 grub_printf("pwd:<%s>\n\n", pwd);
1168 }
1169 else
1170 {
1171 grub_printf("Invalid password for <%s>\n", iso);
1172 }
1173 }
1174 else
1175 {
1176 grub_printf("<%s%s> not found\n", isodisk, iso);
1177 }
1178 }
1179 else if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent")) != NULL)
1180 {
1181 if (ventoy_is_dir_exist("%s%s", isodisk, iso))
1182 {
1183 pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
1184 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL))
1185 {
1186 grub_printf("dir:<%s> [%s]\n", iso, (pos ? "*" : "OK"));
1187 grub_printf("pwd:<%s>\n\n", pwd);
1188 }
1189 else
1190 {
1191 grub_printf("Invalid password for <%s>\n", iso);
1192 }
1193 }
1194 else
1195 {
1196 grub_printf("<%s%s> not found\n", isodisk, iso);
1197 }
1198 }
1199 else
1200 {
1201 grub_printf("No file item found in json.\n");
1202 }
1203 }
1204 }
1205 }
1206
1207 return 0;
1208 }
1209
1210 static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
1211 {
1212 int autosel = 0;
1213 int timeout = 0;
1214 int pathnum = 0;
1215 char *pos = NULL;
1216 const char *iso = NULL;
1217 VTOY_JSON *pNode = NULL;
1218
1219 if (json->enDataType != JSON_TYPE_ARRAY)
1220 {
1221 grub_printf("Not array type %d\n", json->enDataType);
1222 return 1;
1223 }
1224
1225 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1226 {
1227 if (pNode->enDataType != JSON_TYPE_OBJECT)
1228 {
1229 grub_printf("NOT object type\n");
1230 }
1231
1232 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
1233 if (iso)
1234 {
1235 pos = grub_strchr(iso, '*');
1236 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
1237 {
1238 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
1239 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend", &pathnum);
1240
1241 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
1242 {
1243 if (autosel >= 0 && autosel <= pathnum)
1244 {
1245 grub_printf("autosel: %d [OK]\n", autosel);
1246 }
1247 else
1248 {
1249 grub_printf("autosel: %d [FAIL]\n", autosel);
1250 }
1251 }
1252
1253 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
1254 {
1255 if (timeout >= 0)
1256 {
1257 grub_printf("timeout: %d [OK]\n", timeout);
1258 }
1259 else
1260 {
1261 grub_printf("timeout: %d [FAIL]\n", timeout);
1262 }
1263 }
1264 }
1265 else
1266 {
1267 grub_printf("image: %s [FAIL]\n", iso);
1268 }
1269 }
1270 else
1271 {
1272 grub_printf("image not found\n");
1273 }
1274 }
1275
1276 return 0;
1277 }
1278
1279 static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
1280 {
1281 int autosel = 0;
1282 int timeout = 0;
1283 int pathnum = 0;
1284 const char *iso = NULL;
1285 VTOY_JSON *pNode = NULL;
1286 persistence_config *node = NULL;
1287 persistence_config *next = NULL;
1288 file_fullpath *backendpath = NULL;
1289
1290 (void)isodisk;
1291
1292 if (json->enDataType != JSON_TYPE_ARRAY)
1293 {
1294 debug("Not array %d\n", json->enDataType);
1295 return 0;
1296 }
1297
1298 if (g_persistence_head)
1299 {
1300 for (node = g_persistence_head; node; node = next)
1301 {
1302 next = node->next;
1303 grub_check_free(node->backendpath);
1304 grub_free(node);
1305 }
1306
1307 g_persistence_head = NULL;
1308 }
1309
1310 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1311 {
1312 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
1313 if (iso && iso[0] == '/')
1314 {
1315 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum))
1316 {
1317 node = grub_zalloc(sizeof(persistence_config));
1318 if (node)
1319 {
1320 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
1321 node->backendpath = backendpath;
1322 node->backendnum = pathnum;
1323
1324 node->autosel = -1;
1325 node->timeout = -1;
1326 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
1327 {
1328 if (autosel >= 0 && autosel <= pathnum)
1329 {
1330 node->autosel = autosel;
1331 }
1332 }
1333
1334 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
1335 {
1336 if (timeout >= 0)
1337 {
1338 node->timeout = timeout;
1339 }
1340 }
1341
1342 if (g_persistence_head)
1343 {
1344 node->next = g_persistence_head;
1345 }
1346
1347 g_persistence_head = node;
1348 }
1349 }
1350 }
1351 }
1352
1353 return 0;
1354 }
1355
1356 static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
1357 {
1358 int type;
1359 const char *path = NULL;
1360 const char *alias = NULL;
1361 VTOY_JSON *pNode = NULL;
1362
1363 (void)isodisk;
1364
1365 if (json->enDataType != JSON_TYPE_ARRAY)
1366 {
1367 grub_printf("Not array %d\n", json->enDataType);
1368 return 1;
1369 }
1370
1371 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1372 {
1373 type = vtoy_alias_image_file;
1374 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1375 if (!path)
1376 {
1377 path = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1378 type = vtoy_alias_directory;
1379 }
1380
1381 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
1382 if (path && path[0] == '/' && alias)
1383 {
1384 if (vtoy_alias_image_file == type)
1385 {
1386 if (grub_strchr(path, '*'))
1387 {
1388 grub_printf("image: <%s> [ * ]\n", path);
1389 }
1390 else if (ventoy_is_file_exist("%s%s", isodisk, path))
1391 {
1392 grub_printf("image: <%s> [ OK ]\n", path);
1393 }
1394 else
1395 {
1396 grub_printf("image: <%s> [ NOT EXIST ]\n", path);
1397 }
1398 }
1399 else
1400 {
1401 if (ventoy_is_dir_exist("%s%s", isodisk, path))
1402 {
1403 grub_printf("dir: <%s> [ OK ]\n", path);
1404 }
1405 else
1406 {
1407 grub_printf("dir: <%s> [ NOT EXIST ]\n", path);
1408 }
1409 }
1410
1411 grub_printf("alias: <%s>\n\n", alias);
1412 }
1413 }
1414
1415 return 0;
1416 }
1417
1418 static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk)
1419 {
1420 int type;
1421 const char *path = NULL;
1422 const char *alias = NULL;
1423 VTOY_JSON *pNode = NULL;
1424 menu_alias *node = NULL;
1425 menu_alias *next = NULL;
1426
1427 (void)isodisk;
1428
1429 if (json->enDataType != JSON_TYPE_ARRAY)
1430 {
1431 debug("Not array %d\n", json->enDataType);
1432 return 0;
1433 }
1434
1435 if (g_menu_alias_head)
1436 {
1437 for (node = g_menu_alias_head; node; node = next)
1438 {
1439 next = node->next;
1440 grub_free(node);
1441 }
1442
1443 g_menu_alias_head = NULL;
1444 }
1445
1446 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1447 {
1448 type = vtoy_alias_image_file;
1449 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1450 if (!path)
1451 {
1452 path = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1453 type = vtoy_alias_directory;
1454 }
1455
1456 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
1457 if (path && path[0] == '/' && alias)
1458 {
1459 node = grub_zalloc(sizeof(menu_alias));
1460 if (node)
1461 {
1462 node->type = type;
1463 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path);
1464 grub_snprintf(node->alias, sizeof(node->alias), "%s", alias);
1465
1466 if (g_menu_alias_head)
1467 {
1468 node->next = g_menu_alias_head;
1469 }
1470
1471 g_menu_alias_head = node;
1472 }
1473 }
1474 }
1475
1476 return 0;
1477 }
1478
1479 static int ventoy_plugin_menutip_check(VTOY_JSON *json, const char *isodisk)
1480 {
1481 const char *path = NULL;
1482 const char *tip = NULL;
1483 VTOY_JSON *pNode = NULL;
1484
1485 (void)isodisk;
1486
1487 if (json->enDataType != JSON_TYPE_OBJECT)
1488 {
1489 grub_printf("Not object %d\n", json->enDataType);
1490 return 1;
1491 }
1492
1493 tip = vtoy_json_get_string_ex(json->pstChild, "left");
1494 if (tip)
1495 {
1496 grub_printf("left: <%s>\n", tip);
1497 }
1498
1499 tip = vtoy_json_get_string_ex(json->pstChild, "top");
1500 if (tip)
1501 {
1502 grub_printf("top: <%s>\n", tip);
1503 }
1504
1505 tip = vtoy_json_get_string_ex(json->pstChild, "color");
1506 if (tip)
1507 {
1508 grub_printf("color: <%s>\n", tip);
1509 }
1510
1511 pNode = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips");
1512 for (pNode = pNode->pstChild; pNode; pNode = pNode->pstNext)
1513 {
1514 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1515 if (path && path[0] == '/')
1516 {
1517 if (grub_strchr(path, '*'))
1518 {
1519 grub_printf("image: <%s> [ * ]\n", path);
1520 }
1521 else if (ventoy_check_file_exist("%s%s", isodisk, path))
1522 {
1523 grub_printf("image: <%s> [ OK ]\n", path);
1524 }
1525 else
1526 {
1527 grub_printf("image: <%s> [ NOT EXIST ]\n", path);
1528 }
1529
1530 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip");
1531 if (tip)
1532 {
1533 grub_printf("tip: <%s>\n", tip);
1534 }
1535 else
1536 {
1537 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip1");
1538 if (tip)
1539 grub_printf("tip1: <%s>\n", tip);
1540 else
1541 grub_printf("tip1: <NULL>\n");
1542
1543 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip2");
1544 if (tip)
1545 grub_printf("tip2: <%s>\n", tip);
1546 else
1547 grub_printf("tip2: <NULL>\n");
1548 }
1549 }
1550 else
1551 {
1552 grub_printf("image: <%s> [ INVALID ]\n", path);
1553 }
1554 }
1555
1556 return 0;
1557 }
1558
1559 static int ventoy_plugin_menutip_entry(VTOY_JSON *json, const char *isodisk)
1560 {
1561 const char *path = NULL;
1562 const char *tip = NULL;
1563 VTOY_JSON *pNode = NULL;
1564 menu_tip *node = NULL;
1565 menu_tip *next = NULL;
1566
1567 (void)isodisk;
1568
1569 if (json->enDataType != JSON_TYPE_OBJECT)
1570 {
1571 debug("Not object %d\n", json->enDataType);
1572 return 0;
1573 }
1574
1575 pNode = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips");
1576 if (pNode == NULL)
1577 {
1578 debug("Not tips found\n");
1579 return 0;
1580 }
1581
1582 if (g_menu_tip_head)
1583 {
1584 for (node = g_menu_tip_head; node; node = next)
1585 {
1586 next = node->next;
1587 grub_free(node);
1588 }
1589
1590 g_menu_tip_head = NULL;
1591 }
1592
1593 tip = vtoy_json_get_string_ex(json->pstChild, "left");
1594 if (tip)
1595 {
1596 grub_env_set("VTOY_TIP_LEFT", tip);
1597 }
1598
1599 tip = vtoy_json_get_string_ex(json->pstChild, "top");
1600 if (tip)
1601 {
1602 grub_env_set("VTOY_TIP_TOP", tip);
1603 }
1604
1605 tip = vtoy_json_get_string_ex(json->pstChild, "color");
1606 if (tip)
1607 {
1608 grub_env_set("VTOY_TIP_COLOR", tip);
1609 }
1610
1611 for (pNode = pNode->pstChild; pNode; pNode = pNode->pstNext)
1612 {
1613 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1614 if (path && path[0] == '/')
1615 {
1616 node = grub_zalloc(sizeof(menu_tip));
1617 if (node)
1618 {
1619 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path);
1620
1621 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip");
1622 if (tip)
1623 {
1624 grub_snprintf(node->tip1, 1000, "%s", tip);
1625 }
1626 else
1627 {
1628 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip1");
1629 if (tip)
1630 grub_snprintf(node->tip1, 1000, "%s", tip);
1631
1632 tip = vtoy_json_get_string_ex(pNode->pstChild, "tip2");
1633 if (tip)
1634 grub_snprintf(node->tip2, 1000, "%s", tip);
1635 }
1636
1637 if (g_menu_tip_head)
1638 {
1639 node->next = g_menu_tip_head;
1640 }
1641
1642 g_menu_tip_head = node;
1643 }
1644 }
1645 }
1646
1647 return 0;
1648 }
1649
1650 static int ventoy_plugin_injection_check(VTOY_JSON *json, const char *isodisk)
1651 {
1652 int type = 0;
1653 const char *path = NULL;
1654 const char *archive = NULL;
1655 VTOY_JSON *pNode = NULL;
1656
1657 (void)isodisk;
1658
1659 if (json->enDataType != JSON_TYPE_ARRAY)
1660 {
1661 grub_printf("Not array %d\n", json->enDataType);
1662 return 0;
1663 }
1664
1665 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1666 {
1667 type = injection_type_file;
1668 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1669 if (!path)
1670 {
1671 type = injection_type_parent;
1672 path = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1673 if (!path)
1674 {
1675 grub_printf("image/parent not found\n");
1676 continue;
1677 }
1678 }
1679
1680 archive = vtoy_json_get_string_ex(pNode->pstChild, "archive");
1681 if (!archive)
1682 {
1683 grub_printf("archive not found\n");
1684 continue;
1685 }
1686
1687 if (type == injection_type_file)
1688 {
1689 if (grub_strchr(path, '*'))
1690 {
1691 grub_printf("image: <%s> [*]\n", path);
1692 }
1693 else
1694 {
1695 grub_printf("image: <%s> [%s]\n", path, ventoy_check_file_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST");
1696 }
1697 }
1698 else
1699 {
1700 grub_printf("parent: <%s> [%s]\n", path,
1701 ventoy_is_dir_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST");
1702 }
1703
1704 grub_printf("archive: <%s> [%s]\n\n", archive, ventoy_check_file_exist("%s%s", isodisk, archive) ? "OK" : "NOT EXIST");
1705 }
1706
1707 return 0;
1708 }
1709
1710 static int ventoy_plugin_injection_entry(VTOY_JSON *json, const char *isodisk)
1711 {
1712 int type = 0;
1713 const char *path = NULL;
1714 const char *archive = NULL;
1715 VTOY_JSON *pNode = NULL;
1716 injection_config *node = NULL;
1717 injection_config *next = NULL;
1718
1719 (void)isodisk;
1720
1721 if (json->enDataType != JSON_TYPE_ARRAY)
1722 {
1723 debug("Not array %d\n", json->enDataType);
1724 return 0;
1725 }
1726
1727 if (g_injection_head)
1728 {
1729 for (node = g_injection_head; node; node = next)
1730 {
1731 next = node->next;
1732 grub_free(node);
1733 }
1734
1735 g_injection_head = NULL;
1736 }
1737
1738 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1739 {
1740 type = injection_type_file;
1741 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1742 if (!path)
1743 {
1744 type = injection_type_parent;
1745 path = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1746 }
1747
1748 archive = vtoy_json_get_string_ex(pNode->pstChild, "archive");
1749 if (path && path[0] == '/' && archive && archive[0] == '/')
1750 {
1751 node = grub_zalloc(sizeof(injection_config));
1752 if (node)
1753 {
1754 node->type = type;
1755 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path);
1756 grub_snprintf(node->archive, sizeof(node->archive), "%s", archive);
1757
1758 if (g_injection_head)
1759 {
1760 node->next = g_injection_head;
1761 }
1762
1763 g_injection_head = node;
1764 }
1765 }
1766 }
1767
1768 return 0;
1769 }
1770
1771 static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk)
1772 {
1773 int type;
1774 int parent = 0;
1775 const char *key = NULL;
1776 const char *class = NULL;
1777 VTOY_JSON *pNode = NULL;
1778 menu_class *tail = NULL;
1779 menu_class *node = NULL;
1780 menu_class *next = NULL;
1781
1782 (void)isodisk;
1783
1784 if (json->enDataType != JSON_TYPE_ARRAY)
1785 {
1786 debug("Not array %d\n", json->enDataType);
1787 return 0;
1788 }
1789
1790 if (g_menu_class_head)
1791 {
1792 for (node = g_menu_class_head; node; node = next)
1793 {
1794 next = node->next;
1795 grub_free(node);
1796 }
1797
1798 g_menu_class_head = NULL;
1799 }
1800
1801 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1802 {
1803 parent = 0;
1804 type = vtoy_class_image_file;
1805 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1806 if (!key)
1807 {
1808 key = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1809 if (key)
1810 {
1811 parent = 1;
1812 }
1813 else
1814 {
1815 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1816 type = vtoy_class_directory;
1817 }
1818 }
1819
1820 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1821 if (key && class)
1822 {
1823 node = grub_zalloc(sizeof(menu_class));
1824 if (node)
1825 {
1826 node->type = type;
1827 node->parent = parent;
1828 node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key);
1829 grub_snprintf(node->class, sizeof(node->class), "%s", class);
1830
1831 if (g_menu_class_head)
1832 {
1833 tail->next = node;
1834 }
1835 else
1836 {
1837 g_menu_class_head = node;
1838 }
1839 tail = node;
1840 }
1841 }
1842 }
1843
1844 return 0;
1845 }
1846
1847 static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk)
1848 {
1849 const char *name = NULL;
1850 const char *key = NULL;
1851 const char *class = NULL;
1852 VTOY_JSON *pNode = NULL;
1853
1854 (void)isodisk;
1855
1856 if (json->enDataType != JSON_TYPE_ARRAY)
1857 {
1858 grub_printf("Not array %d\n", json->enDataType);
1859 return 1;
1860 }
1861
1862 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1863 {
1864 name = "key";
1865 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1866 if (!key)
1867 {
1868 name = "parent";
1869 key = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1870 if (!key)
1871 {
1872 name = "dir";
1873 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1874 }
1875 }
1876
1877 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1878 if (key && class)
1879 {
1880 grub_printf("%s: <%s>\n", name, key);
1881 grub_printf("class: <%s>\n\n", class);
1882 }
1883 }
1884
1885 return 0;
1886 }
1887
1888 static int ventoy_plugin_custom_boot_entry(VTOY_JSON *json, const char *isodisk)
1889 {
1890 int type;
1891 int len;
1892 const char *key = NULL;
1893 const char *cfg = NULL;
1894 VTOY_JSON *pNode = NULL;
1895 custom_boot *tail = NULL;
1896 custom_boot *node = NULL;
1897 custom_boot *next = NULL;
1898
1899 (void)isodisk;
1900
1901 if (json->enDataType != JSON_TYPE_ARRAY)
1902 {
1903 debug("Not array %d\n", json->enDataType);
1904 return 0;
1905 }
1906
1907 if (g_custom_boot_head)
1908 {
1909 for (node = g_custom_boot_head; node; node = next)
1910 {
1911 next = node->next;
1912 grub_free(node);
1913 }
1914
1915 g_custom_boot_head = NULL;
1916 }
1917
1918 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1919 {
1920 type = vtoy_custom_boot_image_file;
1921 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1922 if (!key)
1923 {
1924 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1925 type = vtoy_custom_boot_directory;
1926 }
1927
1928 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1929 if (key && cfg)
1930 {
1931 node = grub_zalloc(sizeof(custom_boot));
1932 if (node)
1933 {
1934 node->type = type;
1935 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", key);
1936 len = (int)grub_snprintf(node->cfg, sizeof(node->cfg), "%s", cfg);
1937
1938 if (len >= 5 && grub_strncmp(node->cfg + len - 5, ".vcfg", 5) == 0)
1939 {
1940 if (g_custom_boot_head)
1941 {
1942 tail->next = node;
1943 }
1944 else
1945 {
1946 g_custom_boot_head = node;
1947 }
1948 tail = node;
1949 }
1950 else
1951 {
1952 grub_free(node);
1953 }
1954 }
1955 }
1956 }
1957
1958 return 0;
1959 }
1960
1961 static int ventoy_plugin_custom_boot_check(VTOY_JSON *json, const char *isodisk)
1962 {
1963 int type;
1964 int len;
1965 const char *key = NULL;
1966 const char *cfg = NULL;
1967 VTOY_JSON *pNode = NULL;
1968
1969 (void)isodisk;
1970
1971 if (json->enDataType != JSON_TYPE_ARRAY)
1972 {
1973 grub_printf("Not array %d\n", json->enDataType);
1974 return 1;
1975 }
1976
1977 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1978 {
1979 type = vtoy_custom_boot_image_file;
1980 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1981 if (!key)
1982 {
1983 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1984 type = vtoy_custom_boot_directory;
1985 }
1986
1987 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1988 len = (int)grub_strlen(cfg);
1989 if (key && cfg)
1990 {
1991 if (len < 5 || grub_strncmp(cfg + len - 5, ".vcfg", 5))
1992 {
1993 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg);
1994 }
1995 else
1996 {
1997 grub_printf("%s: <%s>\n", (type == vtoy_custom_boot_directory) ? "dir" : "file", key);
1998 grub_printf("vcfg: <%s>\n\n", cfg);
1999 }
2000 }
2001 }
2002
2003 return 0;
2004 }
2005
2006 static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk)
2007 {
2008 int img = 0;
2009 const char *isof = NULL;
2010 const char *orgf = NULL;
2011 const char *newf = NULL;
2012 VTOY_JSON *pNode = NULL;
2013 conf_replace *tail = NULL;
2014 conf_replace *node = NULL;
2015 conf_replace *next = NULL;
2016
2017 (void)isodisk;
2018
2019 if (json->enDataType != JSON_TYPE_ARRAY)
2020 {
2021 debug("Not array %d\n", json->enDataType);
2022 return 0;
2023 }
2024
2025 if (g_conf_replace_head)
2026 {
2027 for (node = g_conf_replace_head; node; node = next)
2028 {
2029 next = node->next;
2030 grub_free(node);
2031 }
2032
2033 g_conf_replace_head = NULL;
2034 }
2035
2036 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2037 {
2038 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
2039 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
2040 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
2041 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
2042 {
2043 node = grub_zalloc(sizeof(conf_replace));
2044 if (node)
2045 {
2046 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "img", &img))
2047 {
2048 node->img = img;
2049 }
2050
2051 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof);
2052 grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf);
2053 grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf);
2054
2055 if (g_conf_replace_head)
2056 {
2057 tail->next = node;
2058 }
2059 else
2060 {
2061 g_conf_replace_head = node;
2062 }
2063 tail = node;
2064 }
2065 }
2066 }
2067
2068 return 0;
2069 }
2070
2071 static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk)
2072 {
2073 int img = 0;
2074 const char *isof = NULL;
2075 const char *orgf = NULL;
2076 const char *newf = NULL;
2077 VTOY_JSON *pNode = NULL;
2078 grub_file_t file = NULL;
2079 char cmd[256];
2080
2081 (void)isodisk;
2082
2083 if (json->enDataType != JSON_TYPE_ARRAY)
2084 {
2085 grub_printf("Not array %d\n", json->enDataType);
2086 return 1;
2087 }
2088
2089 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2090 {
2091 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
2092 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
2093 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
2094 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
2095 {
2096 if (ventoy_check_file_exist("%s%s", isodisk, isof))
2097 {
2098 grub_printf("iso:<%s> [OK]\n", isof);
2099
2100 grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof);
2101 grub_script_execute_sourcecode(cmd);
2102
2103 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
2104 if (file)
2105 {
2106 if (grub_strcmp(file->fs->name, "iso9660") == 0)
2107 {
2108 grub_printf("org:<%s> [OK]\n", orgf);
2109 }
2110 else
2111 {
2112 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf);
2113 }
2114 grub_file_close(file);
2115 }
2116 else
2117 {
2118 grub_printf("org:<%s> [NOT Exist]\n", orgf);
2119 }
2120
2121 grub_script_execute_sourcecode("loopback -d vtisocheck");
2122 }
2123 else if (grub_strchr(isof, '*'))
2124 {
2125 grub_printf("iso:<%s> [*]\n", isof);
2126 grub_printf("org:<%s>\n", orgf);
2127 }
2128 else
2129 {
2130 grub_printf("iso:<%s> [NOT Exist]\n", isof);
2131 grub_printf("org:<%s>\n", orgf);
2132 }
2133
2134 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf);
2135 if (file)
2136 {
2137 if (file->size > vtoy_max_replace_file_size)
2138 {
2139 grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size);
2140 }
2141 else
2142 {
2143 grub_printf("new1:<%s> [OK]\n", newf);
2144 }
2145 grub_file_close(file);
2146 }
2147 else
2148 {
2149 grub_printf("new:<%s> [NOT Exist]\n", newf);
2150 }
2151
2152 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "img", &img))
2153 {
2154 grub_printf("img:<%d>\n", img);
2155 }
2156
2157 grub_printf("\n");
2158 }
2159 }
2160
2161 return 0;
2162 }
2163
2164 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
2165 {
2166 VTOY_JSON *pNode = NULL;
2167 auto_memdisk *node = NULL;
2168 auto_memdisk *next = NULL;
2169
2170 (void)isodisk;
2171
2172 if (json->enDataType != JSON_TYPE_ARRAY)
2173 {
2174 debug("Not array %d\n", json->enDataType);
2175 return 0;
2176 }
2177
2178 if (g_auto_memdisk_head)
2179 {
2180 for (node = g_auto_memdisk_head; node; node = next)
2181 {
2182 next = node->next;
2183 grub_free(node);
2184 }
2185
2186 g_auto_memdisk_head = NULL;
2187 }
2188
2189 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2190 {
2191 if (pNode->enDataType == JSON_TYPE_STRING)
2192 {
2193 node = grub_zalloc(sizeof(auto_memdisk));
2194 if (node)
2195 {
2196 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
2197
2198 if (g_auto_memdisk_head)
2199 {
2200 node->next = g_auto_memdisk_head;
2201 }
2202
2203 g_auto_memdisk_head = node;
2204 }
2205 }
2206 }
2207
2208 return 0;
2209 }
2210
2211 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk)
2212 {
2213 VTOY_JSON *pNode = NULL;
2214
2215 if (json->enDataType != JSON_TYPE_ARRAY)
2216 {
2217 grub_printf("Not array %d\n", json->enDataType);
2218 return 1;
2219 }
2220
2221 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2222 {
2223 if (pNode->enDataType == JSON_TYPE_STRING)
2224 {
2225 grub_printf("<%s> ", pNode->unData.pcStrVal);
2226
2227 if (grub_strchr(pNode->unData.pcStrVal, '*'))
2228 {
2229 grub_printf(" [*]\n");
2230 }
2231 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
2232 {
2233 grub_printf(" [OK]\n");
2234 }
2235 else
2236 {
2237 grub_printf(" [NOT EXIST]\n");
2238 }
2239 }
2240 }
2241
2242 return 0;
2243 }
2244
2245 static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk)
2246 {
2247 VTOY_JSON *pNode = NULL;
2248 image_list *node = NULL;
2249 image_list *next = NULL;
2250 image_list *tail = NULL;
2251
2252 (void)isodisk;
2253
2254 if (json->enDataType != JSON_TYPE_ARRAY)
2255 {
2256 debug("Not array %d\n", json->enDataType);
2257 return 0;
2258 }
2259
2260 if (g_image_list_head)
2261 {
2262 for (node = g_image_list_head; node; node = next)
2263 {
2264 next = node->next;
2265 grub_free(node);
2266 }
2267
2268 g_image_list_head = NULL;
2269 }
2270
2271 if (grub_strncmp(json->pcName, "image_blacklist", 15) == 0)
2272 {
2273 g_plugin_image_list = VENTOY_IMG_BLACK_LIST;
2274 }
2275 else
2276 {
2277 g_plugin_image_list = VENTOY_IMG_WHITE_LIST;
2278 }
2279
2280 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2281 {
2282 if (pNode->enDataType == JSON_TYPE_STRING)
2283 {
2284 node = grub_zalloc(sizeof(image_list));
2285 if (node)
2286 {
2287 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
2288
2289 if (g_image_list_head)
2290 {
2291 tail->next = node;
2292 }
2293 else
2294 {
2295 g_image_list_head = node;
2296 }
2297 tail = node;
2298 }
2299 }
2300 }
2301
2302 return 0;
2303 }
2304
2305 static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk)
2306 {
2307 VTOY_JSON *pNode = NULL;
2308
2309 if (json->enDataType != JSON_TYPE_ARRAY)
2310 {
2311 grub_printf("Not array %d\n", json->enDataType);
2312 return 1;
2313 }
2314
2315 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
2316 {
2317 if (pNode->enDataType == JSON_TYPE_STRING)
2318 {
2319 grub_printf("<%s> ", pNode->unData.pcStrVal);
2320
2321 if (grub_strchr(pNode->unData.pcStrVal, '*'))
2322 {
2323 grub_printf(" [*]\n");
2324 }
2325 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
2326 {
2327 grub_printf(" [OK]\n");
2328 }
2329 else
2330 {
2331 grub_printf(" [NOT EXIST]\n");
2332 }
2333 }
2334 }
2335
2336 return 0;
2337 }
2338
2339 static plugin_entry g_plugin_entries[] =
2340 {
2341 { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check, 0 },
2342 { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check, 0 },
2343 { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check, 0 },
2344 { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check, 0 },
2345 { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check, 0 },
2346 { "menu_tip", ventoy_plugin_menutip_entry, ventoy_plugin_menutip_check, 0 },
2347 { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check, 0 },
2348 { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check, 0 },
2349 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check, 0 },
2350 { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check, 0 },
2351 { "image_blacklist", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check, 0 },
2352 { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check, 0 },
2353 { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check, 0 },
2354 { "password", ventoy_plugin_pwd_entry, ventoy_plugin_pwd_check, 0 },
2355 { "custom_boot", ventoy_plugin_custom_boot_entry, ventoy_plugin_custom_boot_check, 0 },
2356 };
2357
2358 static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
2359 {
2360 int i;
2361 char key[128];
2362 VTOY_JSON *cur = NULL;
2363
2364 grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
2365
2366 for (cur = json; cur; cur = cur->pstNext)
2367 {
2368 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
2369 {
2370 grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, g_arch_mode_suffix);
2371 if (g_plugin_entries[i].flag == 0 && grub_strcmp(key, cur->pcName) == 0)
2372 {
2373 debug("Plugin entry for %s\n", g_plugin_entries[i].key);
2374 g_plugin_entries[i].entryfunc(cur, isodisk);
2375 g_plugin_entries[i].flag = 1;
2376 break;
2377 }
2378 }
2379
2380 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
2381 {
2382 if (g_plugin_entries[i].flag == 0 && grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0)
2383 {
2384 debug("Plugin entry for %s\n", g_plugin_entries[i].key);
2385 g_plugin_entries[i].entryfunc(cur, isodisk);
2386 g_plugin_entries[i].flag = 1;
2387 break;
2388 }
2389 }
2390 }
2391
2392 return 0;
2393 }
2394
2395 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args)
2396 {
2397 int ret = 0;
2398 char *buf = NULL;
2399 grub_file_t file;
2400 VTOY_JSON *json = NULL;
2401
2402 (void)ctxt;
2403 (void)argc;
2404
2405 grub_env_set("VTOY_TIP_LEFT", "10%");
2406 grub_env_set("VTOY_TIP_TOP", "80%+5");
2407 grub_env_set("VTOY_TIP_COLOR", "blue");
2408 grub_env_set("VTOY_TIP_ALIGN", "left");
2409
2410 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
2411 if (!file)
2412 {
2413 return GRUB_ERR_NONE;
2414 }
2415
2416 debug("json configuration file size %d\n", (int)file->size);
2417
2418 buf = grub_malloc(file->size + 1);
2419 if (!buf)
2420 {
2421 grub_file_close(file);
2422 return 1;
2423 }
2424
2425 buf[file->size] = 0;
2426 grub_file_read(file, buf, file->size);
2427 grub_file_close(file);
2428
2429 json = vtoy_json_create();
2430 if (!json)
2431 {
2432 return 1;
2433 }
2434
2435
2436
2437 ret = vtoy_json_parse(json, buf);
2438 if (ret)
2439 {
2440 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2441 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2442
2443 debug("Failed to parse json string %d\n", ret);
2444 grub_free(buf);
2445 return 1;
2446 }
2447
2448 ventoy_parse_plugin_config(json->pstChild, args[0]);
2449
2450 vtoy_json_destroy(json);
2451
2452 grub_free(buf);
2453
2454 if (g_boot_pwd.type)
2455 {
2456 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2457 if (ventoy_check_password(&g_boot_pwd, 3))
2458 {
2459 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2460 grub_refresh();
2461 grub_sleep(5);
2462 grub_exit();
2463 }
2464 }
2465
2466 if (g_menu_tip_head)
2467 {
2468 grub_env_set("VTOY_MENU_TIP_ENABLE", "1");
2469 }
2470 else
2471 {
2472 grub_env_unset("VTOY_MENU_TIP_ENABLE");
2473 }
2474
2475 VENTOY_CMD_RETURN(GRUB_ERR_NONE);
2476 }
2477
2478 void ventoy_plugin_dump_injection(void)
2479 {
2480 injection_config *node = NULL;
2481
2482 for (node = g_injection_head; node; node = node->next)
2483 {
2484 grub_printf("\n%s:<%s>\n", (node->type == injection_type_file) ? "IMAGE" : "PARENT", node->isopath);
2485 grub_printf("ARCHIVE:<%s>\n", node->archive);
2486 }
2487
2488 return;
2489 }
2490
2491
2492 void ventoy_plugin_dump_auto_install(void)
2493 {
2494 int i;
2495 install_template *node = NULL;
2496
2497 for (node = g_install_template_head; node; node = node->next)
2498 {
2499 grub_printf("\n%s:<%s> <%d>\n",
2500 (node->type == auto_install_type_file) ? "IMAGE" : "PARENT",
2501 node->isopath, node->templatenum);
2502 for (i = 0; i < node->templatenum; i++)
2503 {
2504 grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path);
2505 }
2506 }
2507
2508 return;
2509 }
2510
2511 void ventoy_plugin_dump_persistence(void)
2512 {
2513 int rc;
2514 int i = 0;
2515 persistence_config *node = NULL;
2516 ventoy_img_chunk_list chunk_list;
2517
2518 for (node = g_persistence_head; node; node = node->next)
2519 {
2520 grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum);
2521
2522 for (i = 0; i < node->backendnum; i++)
2523 {
2524 grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path);
2525 rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list);
2526 if (rc == 0)
2527 {
2528 grub_printf(" [ SUCCESS ]\n");
2529 grub_free(chunk_list.chunk);
2530 }
2531 else
2532 {
2533 grub_printf(" [ FAILED ]\n");
2534 }
2535 }
2536 }
2537
2538 return;
2539 }
2540
2541 install_template * ventoy_plugin_find_install_template(const char *isopath)
2542 {
2543 int len;
2544 install_template *node = NULL;
2545
2546 if (!g_install_template_head)
2547 {
2548 return NULL;
2549 }
2550
2551 len = (int)grub_strlen(isopath);
2552 for (node = g_install_template_head; node; node = node->next)
2553 {
2554 if (node->type == auto_install_type_file)
2555 {
2556 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2557 {
2558 return node;
2559 }
2560 }
2561 }
2562
2563 for (node = g_install_template_head; node; node = node->next)
2564 {
2565 if (node->type == auto_install_type_parent)
2566 {
2567 if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath))
2568 {
2569 return node;
2570 }
2571 }
2572 }
2573
2574 return NULL;
2575 }
2576
2577 char * ventoy_plugin_get_cur_install_template(const char *isopath)
2578 {
2579 install_template *node = NULL;
2580
2581 node = ventoy_plugin_find_install_template(isopath);
2582 if ((!node) || (!node->templatepath))
2583 {
2584 return NULL;
2585 }
2586
2587 if (node->cursel < 0 || node->cursel >= node->templatenum)
2588 {
2589 return NULL;
2590 }
2591
2592 return node->templatepath[node->cursel].path;
2593 }
2594
2595 persistence_config * ventoy_plugin_find_persistent(const char *isopath)
2596 {
2597 int len;
2598 persistence_config *node = NULL;
2599
2600 if (!g_persistence_head)
2601 {
2602 return NULL;
2603 }
2604
2605 len = (int)grub_strlen(isopath);
2606 for (node = g_persistence_head; node; node = node->next)
2607 {
2608 if ((len == node->pathlen) && (ventoy_strcmp(node->isopath, isopath) == 0))
2609 {
2610 return node;
2611 }
2612 }
2613
2614 return NULL;
2615 }
2616
2617 int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
2618 {
2619 int rc = 1;
2620 grub_uint64_t start = 0;
2621 grub_file_t file = NULL;
2622 persistence_config *node = NULL;
2623
2624 node = ventoy_plugin_find_persistent(isopath);
2625 if ((!node) || (!node->backendpath))
2626 {
2627 return 1;
2628 }
2629
2630 if (index < 0)
2631 {
2632 index = node->cursel;
2633 }
2634
2635 if (index < 0 || index >= node->backendnum)
2636 {
2637 return 1;
2638 }
2639
2640 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path);
2641 if (!file)
2642 {
2643 debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path);
2644 goto end;
2645 }
2646
2647 grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list));
2648 chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
2649 if (NULL == chunk_list->chunk)
2650 {
2651 goto end;
2652 }
2653
2654 chunk_list->max_chunk = DEFAULT_CHUNK_NUM;
2655 chunk_list->cur_chunk = 0;
2656
2657 start = file->device->disk->partition->start;
2658 ventoy_get_block_list(file, chunk_list, start);
2659
2660 if (0 != ventoy_check_block_list(file, chunk_list, start))
2661 {
2662 grub_free(chunk_list->chunk);
2663 chunk_list->chunk = NULL;
2664 goto end;
2665 }
2666
2667 rc = 0;
2668
2669 end:
2670 if (file)
2671 grub_file_close(file);
2672
2673 return rc;
2674 }
2675
2676 const char * ventoy_plugin_get_injection(const char *isopath)
2677 {
2678 int len;
2679 injection_config *node = NULL;
2680
2681 if (!g_injection_head)
2682 {
2683 return NULL;
2684 }
2685
2686 len = (int)grub_strlen(isopath);
2687 for (node = g_injection_head; node; node = node->next)
2688 {
2689 if (node->type == injection_type_file)
2690 {
2691 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2692 {
2693 return node->archive;
2694 }
2695 }
2696 }
2697
2698 for (node = g_injection_head; node; node = node->next)
2699 {
2700 if (node->type == injection_type_parent)
2701 {
2702 if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath))
2703 {
2704 return node->archive;
2705 }
2706 }
2707 }
2708
2709 return NULL;
2710 }
2711
2712 const char * ventoy_plugin_get_menu_alias(int type, const char *isopath)
2713 {
2714 int len;
2715 menu_alias *node = NULL;
2716
2717 if (!g_menu_alias_head)
2718 {
2719 return NULL;
2720 }
2721
2722 len = (int)grub_strlen(isopath);
2723 for (node = g_menu_alias_head; node; node = node->next)
2724 {
2725 if (node->type == type && node->pathlen &&
2726 node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2727 {
2728 return node->alias;
2729 }
2730 }
2731
2732 return NULL;
2733 }
2734
2735 const menu_tip * ventoy_plugin_get_menu_tip(const char *isopath)
2736 {
2737 int len;
2738 menu_tip *node = NULL;
2739
2740 if (!g_menu_tip_head)
2741 {
2742 return NULL;
2743 }
2744
2745 len = (int)grub_strlen(isopath);
2746 for (node = g_menu_tip_head; node; node = node->next)
2747 {
2748 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2749 {
2750 return node;
2751 }
2752 }
2753
2754 return NULL;
2755 }
2756
2757 const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path)
2758 {
2759 int namelen;
2760 int pathlen;
2761 menu_class *node = NULL;
2762
2763 if (!g_menu_class_head)
2764 {
2765 return NULL;
2766 }
2767
2768 namelen = (int)grub_strlen(name);
2769 pathlen = (int)grub_strlen(path);
2770
2771 if (vtoy_class_image_file == type)
2772 {
2773 for (node = g_menu_class_head; node; node = node->next)
2774 {
2775 if (node->type != type)
2776 {
2777 continue;
2778 }
2779
2780 if (node->parent == 0)
2781 {
2782 if ((node->patlen < namelen) && grub_strstr(name, node->pattern))
2783 {
2784 return node->class;
2785 }
2786 }
2787 }
2788
2789 for (node = g_menu_class_head; node; node = node->next)
2790 {
2791 if (node->type != type)
2792 {
2793 continue;
2794 }
2795
2796 if (node->parent)
2797 {
2798 if ((node->patlen < pathlen) && ventoy_plugin_is_parent(node->pattern, node->patlen, path))
2799 {
2800 return node->class;
2801 }
2802 }
2803 }
2804 }
2805 else
2806 {
2807 for (node = g_menu_class_head; node; node = node->next)
2808 {
2809 if (node->type == type && node->patlen == namelen && grub_strncmp(name, node->pattern, namelen) == 0)
2810 {
2811 return node->class;
2812 }
2813 }
2814 }
2815
2816 return NULL;
2817 }
2818
2819 int ventoy_plugin_add_custom_boot(const char *vcfgpath)
2820 {
2821 int len;
2822 custom_boot *node = NULL;
2823
2824 node = grub_zalloc(sizeof(custom_boot));
2825 if (node)
2826 {
2827 node->type = vtoy_custom_boot_image_file;
2828 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", vcfgpath);
2829 grub_snprintf(node->cfg, sizeof(node->cfg), "%s", vcfgpath);
2830
2831 /* .vcfg */
2832 len = node->pathlen - 5;
2833 node->path[len] = 0;
2834 node->pathlen = len;
2835
2836 if (g_custom_boot_head)
2837 {
2838 node->next = g_custom_boot_head;
2839 }
2840 g_custom_boot_head = node;
2841 }
2842
2843 return 0;
2844 }
2845
2846 const char * ventoy_plugin_get_custom_boot(const char *isopath)
2847 {
2848 int i;
2849 int len;
2850 custom_boot *node = NULL;
2851
2852 if (!g_custom_boot_head)
2853 {
2854 return NULL;
2855 }
2856
2857 len = (int)grub_strlen(isopath);
2858
2859 for (node = g_custom_boot_head; node; node = node->next)
2860 {
2861 if (node->type == vtoy_custom_boot_image_file)
2862 {
2863 if (node->pathlen == len && grub_strncmp(isopath, node->path, len) == 0)
2864 {
2865 return node->cfg;
2866 }
2867 }
2868 else
2869 {
2870 if (node->pathlen < len && isopath[node->pathlen] == '/' &&
2871 grub_strncmp(isopath, node->path, node->pathlen) == 0)
2872 {
2873 for (i = node->pathlen + 1; i < len; i++)
2874 {
2875 if (isopath[i] == '/')
2876 {
2877 break;
2878 }
2879 }
2880
2881 if (i >= len)
2882 {
2883 return node->cfg;
2884 }
2885 }
2886 }
2887 }
2888
2889 return NULL;
2890 }
2891
2892 grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args)
2893 {
2894 custom_boot *node = NULL;
2895
2896 (void)argc;
2897 (void)ctxt;
2898 (void)args;
2899
2900 for (node = g_custom_boot_head; node; node = node->next)
2901 {
2902 grub_printf("[%s] <%s>:<%s>\n", (node->type == vtoy_custom_boot_directory) ? "dir" : "file",
2903 node->path, node->cfg);
2904 }
2905
2906 return 0;
2907 }
2908
2909 int ventoy_plugin_check_memdisk(const char *isopath)
2910 {
2911 int len;
2912 auto_memdisk *node = NULL;
2913
2914 if (!g_auto_memdisk_head)
2915 {
2916 return 0;
2917 }
2918
2919 len = (int)grub_strlen(isopath);
2920 for (node = g_auto_memdisk_head; node; node = node->next)
2921 {
2922 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
2923 {
2924 return 1;
2925 }
2926 }
2927
2928 return 0;
2929 }
2930
2931 int ventoy_plugin_get_image_list_index(int type, const char *name)
2932 {
2933 int len;
2934 int index = 1;
2935 image_list *node = NULL;
2936
2937 if (!g_image_list_head)
2938 {
2939 return 0;
2940 }
2941
2942 len = (int)grub_strlen(name);
2943
2944 for (node = g_image_list_head; node; node = node->next, index++)
2945 {
2946 if (vtoy_class_directory == type)
2947 {
2948 if (len < node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2949 {
2950 return index;
2951 }
2952 }
2953 else
2954 {
2955 if (len == node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2956 {
2957 return index;
2958 }
2959 }
2960 }
2961
2962 return 0;
2963 }
2964
2965 conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
2966 {
2967 int len;
2968 conf_replace *node;
2969
2970 if (!g_conf_replace_head)
2971 {
2972 return NULL;
2973 }
2974
2975 len = (int)grub_strlen(iso);
2976
2977 for (node = g_conf_replace_head; node; node = node->next)
2978 {
2979 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
2980 {
2981 return node;
2982 }
2983 }
2984
2985 return NULL;
2986 }
2987
2988 dud * ventoy_plugin_find_dud(const char *iso)
2989 {
2990 int len;
2991 dud *node;
2992
2993 if (!g_dud_head)
2994 {
2995 return NULL;
2996 }
2997
2998 len = (int)grub_strlen(iso);
2999 for (node = g_dud_head; node; node = node->next)
3000 {
3001 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
3002 {
3003 return node;
3004 }
3005 }
3006
3007 return NULL;
3008 }
3009
3010 int ventoy_plugin_load_dud(dud *node, const char *isopart)
3011 {
3012 int i;
3013 char *buf;
3014 grub_file_t file;
3015
3016 for (i = 0; i < node->dudnum; i++)
3017 {
3018 if (node->files[i].size > 0)
3019 {
3020 debug("file %d has been loaded\n", i);
3021 continue;
3022 }
3023
3024 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path);
3025 if (file)
3026 {
3027 buf = grub_malloc(file->size);
3028 if (buf)
3029 {
3030 grub_file_read(file, buf, file->size);
3031 node->files[i].size = (int)file->size;
3032 node->files[i].buf = buf;
3033 }
3034 grub_file_close(file);
3035 }
3036 }
3037
3038 return 0;
3039 }
3040
3041 static const vtoy_password * ventoy_plugin_get_password(const char *isopath)
3042 {
3043 int i;
3044 int len;
3045 const char *pos = NULL;
3046 menu_password *node = NULL;
3047
3048 if (!isopath)
3049 {
3050 return NULL;
3051 }
3052
3053 if (g_pwd_head)
3054 {
3055 len = (int)grub_strlen(isopath);
3056 for (node = g_pwd_head; node; node = node->next)
3057 {
3058 if (node->type == vtoy_menu_pwd_file)
3059 {
3060 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
3061 {
3062 return &(node->password);
3063 }
3064 }
3065 }
3066
3067 for (node = g_pwd_head; node; node = node->next)
3068 {
3069 if (node->type == vtoy_menu_pwd_parent)
3070 {
3071 if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath))
3072 {
3073 return &(node->password);
3074 }
3075 }
3076 }
3077 }
3078
3079 while (*isopath)
3080 {
3081 if (*isopath == '.')
3082 {
3083 pos = isopath;
3084 }
3085 isopath++;
3086 }
3087
3088 if (pos)
3089 {
3090 for (i = 0; i < (int)ARRAY_SIZE(g_menu_prefix); i++)
3091 {
3092 if (g_file_type_pwd[i].type && 0 == grub_strcasecmp(pos + 1, g_menu_prefix[i]))
3093 {
3094 return g_file_type_pwd + i;
3095 }
3096 }
3097 }
3098
3099 return NULL;
3100 }
3101
3102 grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args)
3103 {
3104 int ret;
3105 const vtoy_password *pwd = NULL;
3106
3107 (void)ctxt;
3108 (void)argc;
3109
3110 pwd = ventoy_plugin_get_password(args[0]);
3111 if (pwd)
3112 {
3113 if (0 == ventoy_check_password(pwd, 1))
3114 {
3115 ret = 1;
3116 }
3117 else
3118 {
3119 ret = 0;
3120 }
3121 }
3122 else
3123 {
3124 ret = 1;
3125 }
3126
3127 grub_errno = 0;
3128 return ret;
3129 }
3130
3131 grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
3132 {
3133 int i = 0;
3134 int ret = 0;
3135 char *buf = NULL;
3136 char key[128];
3137 grub_file_t file;
3138 VTOY_JSON *node = NULL;
3139 VTOY_JSON *json = NULL;
3140
3141 (void)ctxt;
3142
3143 if (argc != 3)
3144 {
3145 return 0;
3146 }
3147
3148 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
3149 if (!file)
3150 {
3151 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
3152 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
3153 goto end;
3154 }
3155
3156 buf = grub_malloc(file->size + 1);
3157 if (!buf)
3158 {
3159 grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
3160 goto end;
3161 }
3162
3163 buf[file->size] = 0;
3164 grub_file_read(file, buf, file->size);
3165
3166 json = vtoy_json_create();
3167 if (!json)
3168 {
3169 grub_printf("Failed to create json\n");
3170 goto end;
3171 }
3172
3173 ret = vtoy_json_parse(json, buf);
3174 if (ret)
3175 {
3176 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
3177 goto end;
3178 }
3179
3180 grub_snprintf(key, sizeof(key), "%s_%s", args[1], g_arch_mode_suffix);
3181 for (node = json->pstChild; node; node = node->pstNext)
3182 {
3183 if (grub_strcmp(node->pcName, args[1]) == 0 || grub_strcmp(node->pcName, key) == 0)
3184 {
3185 break;
3186 }
3187 }
3188
3189 if (!node)
3190 {
3191 grub_printf("%s is NOT found in ventoy.json\n", args[1]);
3192 goto end;
3193 }
3194
3195 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
3196 {
3197 if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
3198 {
3199 if (g_plugin_entries[i].checkfunc)
3200 {
3201 ret = g_plugin_entries[i].checkfunc(node, args[2]);
3202 }
3203 break;
3204 }
3205 }
3206
3207 end:
3208 check_free(file, grub_file_close);
3209 check_free(json, vtoy_json_destroy);
3210 grub_check_free(buf);
3211
3212 return 0;
3213 }
3214
3215 grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args)
3216 {
3217 grub_uint32_t i = 0;
3218 grub_uint32_t mod = 0;
3219 theme_list *node = g_theme_head;
3220 struct grub_datetime datetime;
3221
3222 (void)argc;
3223 (void)args;
3224 (void)ctxt;
3225
3226 if (g_theme_single_file[0])
3227 {
3228 debug("single theme %s\n", g_theme_single_file);
3229 grub_env_set("theme", g_theme_single_file);
3230 goto end;
3231 }
3232
3233 debug("g_theme_num = %d\n", g_theme_num);
3234
3235 if (g_theme_num == 0)
3236 {
3237 goto end;
3238 }
3239
3240 grub_memset(&datetime, 0, sizeof(datetime));
3241 grub_get_datetime(&datetime);
3242
3243 if (g_theme_random == vtoy_theme_random_boot_second)
3244 {
3245 grub_divmod32((grub_uint32_t)datetime.second, (grub_uint32_t)g_theme_num, &mod);
3246 }
3247 else if (g_theme_random == vtoy_theme_random_boot_day)
3248 {
3249 grub_divmod32((grub_uint32_t)datetime.day, (grub_uint32_t)g_theme_num, &mod);
3250 }
3251 else if (g_theme_random == vtoy_theme_random_boot_month)
3252 {
3253 grub_divmod32((grub_uint32_t)datetime.month, (grub_uint32_t)g_theme_num, &mod);
3254 }
3255
3256 debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n",
3257 datetime.year, datetime.month, datetime.day,
3258 datetime.hour, datetime.minute, datetime.second,
3259 g_theme_random, mod);
3260
3261 for (i = 0; i < mod && node; i++)
3262 {
3263 node = node->next;
3264 }
3265
3266 debug("random theme %s\n", node->theme.path);
3267 grub_env_set("theme", node->theme.path);
3268
3269 end:
3270 VENTOY_CMD_RETURN(GRUB_ERR_NONE);
3271 }
3272
3273