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