]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c
cd1d1e38eabc822c2c31018faf73d6840af510f0
[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 install_template *g_install_template_head = NULL;
47 static dud *g_dud_head = NULL;
48 static menu_password *g_pwd_head = NULL;
49 static persistence_config *g_persistence_head = NULL;
50 static menu_alias *g_menu_alias_head = NULL;
51 static menu_class *g_menu_class_head = NULL;
52 static custom_boot *g_custom_boot_head = NULL;
53 static injection_config *g_injection_head = NULL;
54 static auto_memdisk *g_auto_memdisk_head = NULL;
55 static image_list *g_image_list_head = NULL;
56 static conf_replace *g_conf_replace_head = NULL;
57
58 static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
59 {
60 int rc = 0;
61 VTOY_JSON *pNode = NULL;
62 VTOY_JSON *pChild = NULL;
63
64 (void)isodisk;
65
66 if (json->enDataType != JSON_TYPE_ARRAY)
67 {
68 grub_printf("Not array type %d\n", json->enDataType);
69 return 1;
70 }
71
72 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
73 {
74 if (pNode->enDataType == JSON_TYPE_OBJECT)
75 {
76 pChild = pNode->pstChild;
77 if (pChild->enDataType == JSON_TYPE_STRING)
78 {
79 if (grub_strcmp(pChild->pcName, "VTOY_DEFAULT_IMAGE") == 0)
80 {
81 grub_printf("%s: %s [%s]\n", pChild->pcName, pChild->unData.pcStrVal,
82 ventoy_check_file_exist("%s%s", isodisk, pChild->unData.pcStrVal) ? "OK" : "NOT EXIST");
83 }
84 else
85 {
86 grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
87 }
88 }
89 else
90 {
91 grub_printf("%s is NOT string type\n", pChild->pcName);
92 rc = 1;
93 }
94 }
95 else
96 {
97 grub_printf("%s is not an object\n", pNode->pcName);
98 rc = 1;
99 }
100 }
101
102 return rc;
103 }
104
105 static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
106 {
107 VTOY_JSON *pNode = NULL;
108 VTOY_JSON *pChild = NULL;
109
110 (void)isodisk;
111
112 if (json->enDataType != JSON_TYPE_ARRAY)
113 {
114 debug("Not array %d\n", json->enDataType);
115 return 0;
116 }
117
118 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
119 {
120 if (pNode->enDataType == JSON_TYPE_OBJECT)
121 {
122 pChild = pNode->pstChild;
123 if (pChild->enDataType == JSON_TYPE_STRING && pChild->pcName && pChild->unData.pcStrVal)
124 {
125 ventoy_set_env(pChild->pcName, pChild->unData.pcStrVal);
126 }
127 }
128 }
129
130 return 0;
131 }
132
133 static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
134 {
135 int exist = 0;
136 const char *value;
137 VTOY_JSON *node;
138
139 value = vtoy_json_get_string_ex(json->pstChild, "file");
140 if (value)
141 {
142 grub_printf("file: %s\n", value);
143 if (value[0] == '/')
144 {
145 exist = ventoy_is_file_exist("%s%s", isodisk, value);
146 }
147 else
148 {
149 exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
150 }
151
152 if (exist == 0)
153 {
154 grub_printf("Theme file %s does NOT exist\n", value);
155 return 1;
156 }
157 }
158
159 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
160 if (value)
161 {
162 grub_printf("gfxmode: %s\n", value);
163 }
164
165 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
166 if (value)
167 {
168 grub_printf("display_mode: %s\n", value);
169 }
170
171 value = vtoy_json_get_string_ex(json->pstChild, "serial_param");
172 if (value)
173 {
174 grub_printf("serial_param %s\n", value);
175 }
176
177 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
178 if (value)
179 {
180 grub_printf("ventoy_left: %s\n", value);
181 }
182
183 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
184 if (value)
185 {
186 grub_printf("ventoy_top: %s\n", value);
187 }
188
189 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
190 if (value)
191 {
192 grub_printf("ventoy_color: %s\n", value);
193 }
194
195 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts");
196 if (node)
197 {
198 for (node = node->pstChild; node; node = node->pstNext)
199 {
200 if (node->enDataType == JSON_TYPE_STRING)
201 {
202 if (ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal))
203 {
204 grub_printf("%s [OK]\n", node->unData.pcStrVal);
205 }
206 else
207 {
208 grub_printf("%s [NOT EXIST]\n", node->unData.pcStrVal);
209 }
210 }
211 }
212 }
213 else
214 {
215 grub_printf("fonts NOT found\n");
216 }
217
218 return 0;
219 }
220
221 static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
222 {
223 const char *value;
224 char filepath[256];
225 VTOY_JSON *node;
226
227 value = vtoy_json_get_string_ex(json->pstChild, "file");
228 if (value)
229 {
230 if (value[0] == '/')
231 {
232 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value);
233 }
234 else
235 {
236 grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value);
237 }
238
239 if (ventoy_is_file_exist(filepath) == 0)
240 {
241 debug("Theme file %s does not exist\n", filepath);
242 return 0;
243 }
244
245 debug("vtoy_theme %s\n", filepath);
246 grub_env_set("vtoy_theme", filepath);
247 }
248
249 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
250 if (value)
251 {
252 debug("vtoy_gfxmode %s\n", value);
253 grub_env_set("vtoy_gfxmode", value);
254 }
255
256 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
257 if (value)
258 {
259 debug("display_mode %s\n", value);
260 grub_env_set("vtoy_display_mode", value);
261 }
262
263 value = vtoy_json_get_string_ex(json->pstChild, "serial_param");
264 if (value)
265 {
266 debug("serial_param %s\n", value);
267 grub_env_set("vtoy_serial_param", value);
268 }
269
270 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
271 if (value)
272 {
273 grub_env_set("VTLE_LFT", value);
274 }
275
276 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
277 if (value)
278 {
279 grub_env_set("VTLE_TOP", value);
280 }
281
282 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
283 if (value)
284 {
285 grub_env_set("VTLE_CLR", value);
286 }
287
288 node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts");
289 if (node)
290 {
291 for (node = node->pstChild; node; node = node->pstNext)
292 {
293 if (node->enDataType == JSON_TYPE_STRING &&
294 ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal))
295 {
296 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, node->unData.pcStrVal);
297 grub_font_load(filepath);
298 }
299 }
300 }
301
302 return 0;
303 }
304
305 static int ventoy_plugin_check_path(const char *path, const char *file)
306 {
307 if (file[0] != '/')
308 {
309 grub_printf("%s is NOT begin with '/' \n", file);
310 return 1;
311 }
312
313 if (grub_strchr(file, '\\'))
314 {
315 grub_printf("%s contains invalid '\\' \n", file);
316 return 1;
317 }
318
319 if (grub_strstr(file, "//"))
320 {
321 grub_printf("%s contains invalid double slash\n", file);
322 return 1;
323 }
324
325 if (grub_strstr(file, "../"))
326 {
327 grub_printf("%s contains invalid '../' \n", file);
328 return 1;
329 }
330
331 if (!ventoy_is_file_exist("%s%s", path, file))
332 {
333 grub_printf("%s%s does NOT exist\n", path, file);
334 return 1;
335 }
336
337 return 0;
338 }
339
340 static int ventoy_plugin_check_fullpath
341 (
342 VTOY_JSON *json,
343 const char *isodisk,
344 const char *key,
345 int *pathnum
346 )
347 {
348 int rc = 0;
349 int ret = 0;
350 int cnt = 0;
351 VTOY_JSON *node = json;
352 VTOY_JSON *child = NULL;
353
354 while (node)
355 {
356 if (0 == grub_strcmp(key, node->pcName))
357 {
358 break;
359 }
360 node = node->pstNext;
361 }
362
363 if (!node)
364 {
365 return 1;
366 }
367
368 if (JSON_TYPE_STRING == node->enDataType)
369 {
370 cnt = 1;
371 ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
372 grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
373 }
374 else if (JSON_TYPE_ARRAY == node->enDataType)
375 {
376 for (child = node->pstChild; child; child = child->pstNext)
377 {
378 if (JSON_TYPE_STRING != child->enDataType)
379 {
380 grub_printf("Non string json type\n");
381 }
382 else
383 {
384 rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
385 grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
386 ret += rc;
387 cnt++;
388 }
389 }
390 }
391
392 *pathnum = cnt;
393 return ret;
394 }
395
396 static int ventoy_plugin_parse_fullpath
397 (
398 VTOY_JSON *json,
399 const char *isodisk,
400 const char *key,
401 file_fullpath **fullpath,
402 int *pathnum
403 )
404 {
405 int rc = 1;
406 int count = 0;
407 VTOY_JSON *node = json;
408 VTOY_JSON *child = NULL;
409 file_fullpath *path = NULL;
410
411 while (node)
412 {
413 if (0 == grub_strcmp(key, node->pcName))
414 {
415 break;
416 }
417 node = node->pstNext;
418 }
419
420 if (!node)
421 {
422 return 1;
423 }
424
425 if (JSON_TYPE_STRING == node->enDataType)
426 {
427 debug("%s is string type data\n", node->pcName);
428
429 if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal)))
430 {
431 debug("%s%s file not found\n", isodisk, node->unData.pcStrVal);
432 return 1;
433 }
434
435 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath));
436 if (path)
437 {
438 grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal);
439 *fullpath = path;
440 *pathnum = 1;
441 rc = 0;
442 }
443 }
444 else if (JSON_TYPE_ARRAY == node->enDataType)
445 {
446 for (child = node->pstChild; child; child = child->pstNext)
447 {
448 if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/'))
449 {
450 debug("Invalid data type:%d\n", child->enDataType);
451 return 1;
452 }
453 count++;
454 }
455 debug("%s is array type data, count=%d\n", node->pcName, count);
456
457 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count);
458 if (path)
459 {
460 *fullpath = path;
461
462 for (count = 0, child = node->pstChild; child; child = child->pstNext)
463 {
464 if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal))
465 {
466 grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal);
467 path++;
468 count++;
469 }
470 }
471
472 *pathnum = count;
473 rc = 0;
474 }
475 }
476
477 return rc;
478 }
479
480 static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk)
481 {
482 int pathnum = 0;
483 int autosel = 0;
484 char *pos = NULL;
485 const char *iso = NULL;
486 VTOY_JSON *pNode = NULL;
487
488 if (json->enDataType != JSON_TYPE_ARRAY)
489 {
490 grub_printf("Not array type %d\n", json->enDataType);
491 return 1;
492 }
493
494 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
495 {
496 if (pNode->enDataType != JSON_TYPE_OBJECT)
497 {
498 grub_printf("NOT object type\n");
499 }
500
501 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
502 if (iso)
503 {
504 pos = grub_strchr(iso, '*');
505 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
506 {
507 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
508 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum);
509
510 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
511 {
512 if (autosel >= 0 && autosel <= pathnum)
513 {
514 grub_printf("autosel: %d [OK]\n", autosel);
515 }
516 else
517 {
518 grub_printf("autosel: %d [FAIL]\n", autosel);
519 }
520 }
521 }
522 else
523 {
524 grub_printf("image: %s [FAIL]\n", iso);
525 }
526 }
527 else
528 {
529 grub_printf("image not found\n");
530 }
531 }
532
533 return 0;
534 }
535
536 static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk)
537 {
538 int pathnum = 0;
539 int autosel = 0;
540 const char *iso = NULL;
541 VTOY_JSON *pNode = NULL;
542 install_template *node = NULL;
543 install_template *next = NULL;
544 file_fullpath *templatepath = NULL;
545
546 if (json->enDataType != JSON_TYPE_ARRAY)
547 {
548 debug("Not array %d\n", json->enDataType);
549 return 0;
550 }
551
552 if (g_install_template_head)
553 {
554 for (node = g_install_template_head; node; node = next)
555 {
556 next = node->next;
557 grub_check_free(node->templatepath);
558 grub_free(node);
559 }
560
561 g_install_template_head = NULL;
562 }
563
564 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
565 {
566 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
567 if (iso && iso[0] == '/')
568 {
569 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum))
570 {
571 node = grub_zalloc(sizeof(install_template));
572 if (node)
573 {
574 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
575 node->templatepath = templatepath;
576 node->templatenum = pathnum;
577
578 node->autosel = -1;
579 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
580 {
581 if (autosel >= 0 && autosel <= pathnum)
582 {
583 node->autosel = autosel;
584 }
585 }
586
587 if (g_install_template_head)
588 {
589 node->next = g_install_template_head;
590 }
591
592 g_install_template_head = node;
593 }
594 }
595 }
596 }
597
598 return 0;
599 }
600
601 static int ventoy_plugin_dud_check(VTOY_JSON *json, const char *isodisk)
602 {
603 int pathnum = 0;
604 char *pos = NULL;
605 const char *iso = NULL;
606 VTOY_JSON *pNode = NULL;
607
608 if (json->enDataType != JSON_TYPE_ARRAY)
609 {
610 grub_printf("Not array type %d\n", json->enDataType);
611 return 1;
612 }
613
614 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
615 {
616 if (pNode->enDataType != JSON_TYPE_OBJECT)
617 {
618 grub_printf("NOT object type\n");
619 }
620
621 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
622 if (iso)
623 {
624 pos = grub_strchr(iso, '*');
625 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
626 {
627 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
628 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "dud", &pathnum);
629 }
630 else
631 {
632 grub_printf("image: %s [FAIL]\n", iso);
633 }
634 }
635 else
636 {
637 grub_printf("image not found\n");
638 }
639 }
640
641 return 0;
642 }
643
644 static int ventoy_plugin_dud_entry(VTOY_JSON *json, const char *isodisk)
645 {
646 int pathnum = 0;
647 const char *iso = NULL;
648 VTOY_JSON *pNode = NULL;
649 dud *node = NULL;
650 dud *next = NULL;
651 file_fullpath *dudpath = NULL;
652
653 if (json->enDataType != JSON_TYPE_ARRAY)
654 {
655 debug("Not array %d\n", json->enDataType);
656 return 0;
657 }
658
659 if (g_dud_head)
660 {
661 for (node = g_dud_head; node; node = next)
662 {
663 next = node->next;
664 grub_check_free(node->dudpath);
665 grub_free(node);
666 }
667
668 g_dud_head = NULL;
669 }
670
671 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
672 {
673 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
674 if (iso && iso[0] == '/')
675 {
676 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "dud", &dudpath, &pathnum))
677 {
678 node = grub_zalloc(sizeof(dud));
679 if (node)
680 {
681 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
682 node->dudpath = dudpath;
683 node->dudnum = pathnum;
684 node->files = grub_zalloc(sizeof(dudfile) * pathnum);
685
686 if (node->files)
687 {
688 if (g_dud_head)
689 {
690 node->next = g_dud_head;
691 }
692
693 g_dud_head = node;
694 }
695 else
696 {
697 grub_free(node);
698 }
699 }
700 }
701 }
702 }
703
704 return 0;
705 }
706
707 static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd)
708 {
709 int i;
710 int len;
711 char ch;
712 char *pos;
713 char bytes[3];
714 vtoy_password tmpPwd;
715
716 len = (int)grub_strlen(pwdstr);
717 if (len > 64)
718 {
719 if (NULL == pwd) grub_printf("Password too long %d\n", len);
720 return 1;
721 }
722
723 grub_memset(&tmpPwd, 0, sizeof(tmpPwd));
724
725 if (grub_strncmp(pwdstr, "txt#", 4) == 0)
726 {
727 tmpPwd.type = VTOY_PASSWORD_TXT;
728 grub_snprintf(tmpPwd.text, sizeof(tmpPwd.text), "%s", pwdstr + 4);
729 }
730 else if (grub_strncmp(pwdstr, "md5#", 4) == 0)
731 {
732 if ((len - 4) == 32)
733 {
734 for (i = 0; i < 16; i++)
735 {
736 bytes[0] = pwdstr[4 + i * 2];
737 bytes[1] = pwdstr[4 + i * 2 + 1];
738 bytes[2] = 0;
739
740 if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
741 {
742 tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
743 }
744 else
745 {
746 if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
747 return 1;
748 }
749 }
750 tmpPwd.type = VTOY_PASSWORD_MD5;
751 }
752 else if ((len - 4) > 32)
753 {
754 pos = grub_strchr(pwdstr + 4, '#');
755 if (!pos)
756 {
757 if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
758 return 1;
759 }
760
761 if (len - 1 - (int)(long)(pos - pwdstr) != 32)
762 {
763 if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr);
764 return 1;
765 }
766
767 ch = *pos;
768 *pos = 0;
769 grub_snprintf(tmpPwd.salt, sizeof(tmpPwd.salt), "%s", pwdstr + 4);
770 *pos = ch;
771
772 pos++;
773 for (i = 0; i < 16; i++)
774 {
775 bytes[0] = pos[i * 2];
776 bytes[1] = pos[i * 2 + 1];
777 bytes[2] = 0;
778
779 if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1]))
780 {
781 tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16);
782 }
783 else
784 {
785 if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i);
786 return 1;
787 }
788 }
789
790 tmpPwd.type = VTOY_PASSWORD_SALT_MD5;
791 }
792 else
793 {
794 if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr);
795 return 1;
796 }
797 }
798 else
799 {
800 if (NULL == pwd) grub_printf("Invalid password format %s\n", pwdstr);
801 return 1;
802 }
803
804 if (pwd)
805 {
806 grub_memcpy(pwd, &tmpPwd, sizeof(tmpPwd));
807 }
808
809 return 0;
810 }
811
812 static int ventoy_plugin_pwd_entry(VTOY_JSON *json, const char *isodisk)
813 {
814 const char *iso = NULL;
815 const char *pwd = NULL;
816 VTOY_JSON *pNode = NULL;
817 VTOY_JSON *pCNode = NULL;
818 menu_password *node = NULL;
819 menu_password *tail = NULL;
820 menu_password *next = NULL;
821
822 (void)isodisk;
823
824 if (json->enDataType != JSON_TYPE_OBJECT)
825 {
826 debug("Not object %d\n", json->enDataType);
827 return 0;
828 }
829
830 if (g_pwd_head)
831 {
832 for (node = g_pwd_head; node; node = next)
833 {
834 next = node->next;
835 grub_free(node);
836 }
837
838 g_pwd_head = NULL;
839 }
840
841 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
842 {
843 if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
844 {
845 ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, &g_boot_pwd);
846 }
847 else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
848 {
849 for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext)
850 {
851 if (pCNode->enDataType != JSON_TYPE_OBJECT)
852 {
853 continue;
854 }
855
856 iso = vtoy_json_get_string_ex(pCNode->pstChild, "file");
857 pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
858 if (iso && pwd && iso[0] == '/')
859 {
860 node = grub_zalloc(sizeof(menu_password));
861 if (node)
862 {
863 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
864
865 if (ventoy_plugin_parse_pwdstr((char *)pwd, &(node->password)))
866 {
867 grub_free(node);
868 continue;
869 }
870
871 if (g_pwd_head)
872 {
873 tail->next = node;
874 }
875 else
876 {
877 g_pwd_head = node;
878 }
879 tail = node;
880 }
881 }
882 }
883 }
884 }
885
886 return 0;
887 }
888
889 static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk)
890 {
891 char *pos = NULL;
892 const char *iso = NULL;
893 const char *pwd = NULL;
894 VTOY_JSON *pNode = NULL;
895 VTOY_JSON *pCNode = NULL;
896
897 if (json->enDataType != JSON_TYPE_OBJECT)
898 {
899 grub_printf("Not object %d\n", json->enDataType);
900 return 0;
901 }
902
903 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
904 {
905 if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0)
906 {
907 if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL))
908 {
909 grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal);
910 }
911 else
912 {
913 grub_printf("Invalid bootpwd.\n");
914 }
915 }
916 else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0)
917 {
918 grub_printf("\n");
919 for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext)
920 {
921 if (pCNode->enDataType != JSON_TYPE_OBJECT)
922 {
923 grub_printf("Not object %d\n", pCNode->enDataType);
924 continue;
925 }
926
927 iso = vtoy_json_get_string_ex(pCNode->pstChild, "file");
928 if (iso)
929 {
930 pos = grub_strchr(iso, '*');
931 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
932 {
933 pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd");
934
935 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL))
936 {
937 grub_printf("file:<%s> [%s]\n", iso, (pos ? "*" : "OK"));
938 grub_printf("pwd:<%s>\n\n", pwd);
939 }
940 else
941 {
942 grub_printf("Invalid password for <%s>\n", iso);
943 }
944 }
945 else
946 {
947 grub_printf("<%s%s> not found\n", isodisk, iso);
948 }
949 }
950 else
951 {
952 grub_printf("No file item found in json.\n");
953 }
954 }
955 }
956 }
957
958 return 0;
959 }
960
961 static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
962 {
963 int autosel = 0;
964 int pathnum = 0;
965 char *pos = NULL;
966 const char *iso = NULL;
967 VTOY_JSON *pNode = NULL;
968
969 if (json->enDataType != JSON_TYPE_ARRAY)
970 {
971 grub_printf("Not array type %d\n", json->enDataType);
972 return 1;
973 }
974
975 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
976 {
977 if (pNode->enDataType != JSON_TYPE_OBJECT)
978 {
979 grub_printf("NOT object type\n");
980 }
981
982 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
983 if (iso)
984 {
985 pos = grub_strchr(iso, '*');
986 if (pos || 0 == ventoy_plugin_check_path(isodisk, iso))
987 {
988 grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK"));
989 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend", &pathnum);
990
991 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
992 {
993 if (autosel >= 0 && autosel <= pathnum)
994 {
995 grub_printf("autosel: %d [OK]\n", autosel);
996 }
997 else
998 {
999 grub_printf("autosel: %d [FAIL]\n", autosel);
1000 }
1001 }
1002 }
1003 else
1004 {
1005 grub_printf("image: %s [FAIL]\n", iso);
1006 }
1007 }
1008 else
1009 {
1010 grub_printf("image not found\n");
1011 }
1012 }
1013
1014 return 0;
1015 }
1016
1017 static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
1018 {
1019 int autosel = 0;
1020 int pathnum = 0;
1021 const char *iso = NULL;
1022 VTOY_JSON *pNode = NULL;
1023 persistence_config *node = NULL;
1024 persistence_config *next = NULL;
1025 file_fullpath *backendpath = NULL;
1026
1027 (void)isodisk;
1028
1029 if (json->enDataType != JSON_TYPE_ARRAY)
1030 {
1031 debug("Not array %d\n", json->enDataType);
1032 return 0;
1033 }
1034
1035 if (g_persistence_head)
1036 {
1037 for (node = g_persistence_head; node; node = next)
1038 {
1039 next = node->next;
1040 grub_check_free(node->backendpath);
1041 grub_free(node);
1042 }
1043
1044 g_persistence_head = NULL;
1045 }
1046
1047 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1048 {
1049 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
1050 if (iso && iso[0] == '/')
1051 {
1052 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum))
1053 {
1054 node = grub_zalloc(sizeof(persistence_config));
1055 if (node)
1056 {
1057 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
1058 node->backendpath = backendpath;
1059 node->backendnum = pathnum;
1060
1061 node->autosel = -1;
1062 if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
1063 {
1064 if (autosel >= 0 && autosel <= pathnum)
1065 {
1066 node->autosel = autosel;
1067 }
1068 }
1069
1070 if (g_persistence_head)
1071 {
1072 node->next = g_persistence_head;
1073 }
1074
1075 g_persistence_head = node;
1076 }
1077 }
1078 }
1079 }
1080
1081 return 0;
1082 }
1083
1084 static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
1085 {
1086 int type;
1087 const char *path = NULL;
1088 const char *alias = NULL;
1089 VTOY_JSON *pNode = NULL;
1090
1091 (void)isodisk;
1092
1093 if (json->enDataType != JSON_TYPE_ARRAY)
1094 {
1095 grub_printf("Not array %d\n", json->enDataType);
1096 return 1;
1097 }
1098
1099 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1100 {
1101 type = vtoy_alias_image_file;
1102 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1103 if (!path)
1104 {
1105 path = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1106 type = vtoy_alias_directory;
1107 }
1108
1109 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
1110 if (path && path[0] == '/' && alias)
1111 {
1112 if (vtoy_alias_image_file == type)
1113 {
1114 if (grub_strchr(path, '*'))
1115 {
1116 grub_printf("image: <%s> [ * ]\n", path);
1117 }
1118 else if (ventoy_is_file_exist("%s%s", isodisk, path))
1119 {
1120 grub_printf("image: <%s> [ OK ]\n", path);
1121 }
1122 else
1123 {
1124 grub_printf("image: <%s> [ NOT EXIST ]\n", path);
1125 }
1126 }
1127 else
1128 {
1129 if (ventoy_is_dir_exist("%s%s", isodisk, path))
1130 {
1131 grub_printf("dir: <%s> [ OK ]\n", path);
1132 }
1133 else
1134 {
1135 grub_printf("dir: <%s> [ NOT EXIST ]\n", path);
1136 }
1137 }
1138
1139 grub_printf("alias: <%s>\n\n", alias);
1140 }
1141 }
1142
1143 return 0;
1144 }
1145
1146 static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk)
1147 {
1148 int type;
1149 const char *path = NULL;
1150 const char *alias = NULL;
1151 VTOY_JSON *pNode = NULL;
1152 menu_alias *node = NULL;
1153 menu_alias *next = NULL;
1154
1155 (void)isodisk;
1156
1157 if (json->enDataType != JSON_TYPE_ARRAY)
1158 {
1159 debug("Not array %d\n", json->enDataType);
1160 return 0;
1161 }
1162
1163 if (g_menu_alias_head)
1164 {
1165 for (node = g_menu_alias_head; node; node = next)
1166 {
1167 next = node->next;
1168 grub_free(node);
1169 }
1170
1171 g_menu_alias_head = NULL;
1172 }
1173
1174 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1175 {
1176 type = vtoy_alias_image_file;
1177 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1178 if (!path)
1179 {
1180 path = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1181 type = vtoy_alias_directory;
1182 }
1183
1184 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
1185 if (path && path[0] == '/' && alias)
1186 {
1187 node = grub_zalloc(sizeof(menu_alias));
1188 if (node)
1189 {
1190 node->type = type;
1191 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path);
1192 grub_snprintf(node->alias, sizeof(node->alias), "%s", alias);
1193
1194 if (g_menu_alias_head)
1195 {
1196 node->next = g_menu_alias_head;
1197 }
1198
1199 g_menu_alias_head = node;
1200 }
1201 }
1202 }
1203
1204 return 0;
1205 }
1206
1207
1208 static int ventoy_plugin_injection_check(VTOY_JSON *json, const char *isodisk)
1209 {
1210 const char *path = NULL;
1211 const char *archive = NULL;
1212 VTOY_JSON *pNode = NULL;
1213
1214 (void)isodisk;
1215
1216 if (json->enDataType != JSON_TYPE_ARRAY)
1217 {
1218 grub_printf("Not array %d\n", json->enDataType);
1219 return 0;
1220 }
1221
1222 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1223 {
1224 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1225 if (!path)
1226 {
1227 grub_printf("image not found\n");
1228 continue;
1229 }
1230
1231 archive = vtoy_json_get_string_ex(pNode->pstChild, "archive");
1232 if (!archive)
1233 {
1234 grub_printf("archive not found\n");
1235 continue;
1236 }
1237
1238 if (grub_strchr(path, '*'))
1239 {
1240 grub_printf("image: <%s> [*]\n", path);
1241 }
1242 else
1243 {
1244 grub_printf("image: <%s> [%s]\n", path, ventoy_check_file_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST");
1245 }
1246
1247 grub_printf("archive: <%s> [%s]\n\n", archive, ventoy_check_file_exist("%s%s", isodisk, archive) ? "OK" : "NOT EXIST");
1248 }
1249
1250 return 0;
1251 }
1252
1253 static int ventoy_plugin_injection_entry(VTOY_JSON *json, const char *isodisk)
1254 {
1255 const char *path = NULL;
1256 const char *archive = NULL;
1257 VTOY_JSON *pNode = NULL;
1258 injection_config *node = NULL;
1259 injection_config *next = NULL;
1260
1261 (void)isodisk;
1262
1263 if (json->enDataType != JSON_TYPE_ARRAY)
1264 {
1265 debug("Not array %d\n", json->enDataType);
1266 return 0;
1267 }
1268
1269 if (g_injection_head)
1270 {
1271 for (node = g_injection_head; node; node = next)
1272 {
1273 next = node->next;
1274 grub_free(node);
1275 }
1276
1277 g_injection_head = NULL;
1278 }
1279
1280 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1281 {
1282 path = vtoy_json_get_string_ex(pNode->pstChild, "image");
1283 archive = vtoy_json_get_string_ex(pNode->pstChild, "archive");
1284 if (path && path[0] == '/' && archive && archive[0] == '/')
1285 {
1286 node = grub_zalloc(sizeof(injection_config));
1287 if (node)
1288 {
1289 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path);
1290 grub_snprintf(node->archive, sizeof(node->archive), "%s", archive);
1291
1292 if (g_injection_head)
1293 {
1294 node->next = g_injection_head;
1295 }
1296
1297 g_injection_head = node;
1298 }
1299 }
1300 }
1301
1302 return 0;
1303 }
1304
1305 static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk)
1306 {
1307 int type;
1308 const char *key = NULL;
1309 const char *class = NULL;
1310 VTOY_JSON *pNode = NULL;
1311 menu_class *tail = NULL;
1312 menu_class *node = NULL;
1313 menu_class *next = NULL;
1314
1315 (void)isodisk;
1316
1317 if (json->enDataType != JSON_TYPE_ARRAY)
1318 {
1319 debug("Not array %d\n", json->enDataType);
1320 return 0;
1321 }
1322
1323 if (g_menu_class_head)
1324 {
1325 for (node = g_menu_class_head; node; node = next)
1326 {
1327 next = node->next;
1328 grub_free(node);
1329 }
1330
1331 g_menu_class_head = NULL;
1332 }
1333
1334 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1335 {
1336 type = vtoy_class_image_file;
1337 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1338 if (!key)
1339 {
1340 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1341 type = vtoy_class_directory;
1342 }
1343
1344 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1345 if (key && class)
1346 {
1347 node = grub_zalloc(sizeof(menu_class));
1348 if (node)
1349 {
1350 node->type = type;
1351 node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key);
1352 grub_snprintf(node->class, sizeof(node->class), "%s", class);
1353
1354 if (g_menu_class_head)
1355 {
1356 tail->next = node;
1357 }
1358 else
1359 {
1360 g_menu_class_head = node;
1361 }
1362 tail = node;
1363 }
1364 }
1365 }
1366
1367 return 0;
1368 }
1369
1370 static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk)
1371 {
1372 int type;
1373 const char *key = NULL;
1374 const char *class = 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_class_image_file;
1388 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1389 if (!key)
1390 {
1391 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1392 type = vtoy_class_directory;
1393 }
1394
1395 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1396 if (key && class)
1397 {
1398 grub_printf("%s: <%s>\n", (type == vtoy_class_directory) ? "dir" : "key", key);
1399 grub_printf("class: <%s>\n\n", class);
1400 }
1401 }
1402
1403 return 0;
1404 }
1405
1406 static int ventoy_plugin_custom_boot_entry(VTOY_JSON *json, const char *isodisk)
1407 {
1408 int type;
1409 int len;
1410 const char *key = NULL;
1411 const char *cfg = NULL;
1412 VTOY_JSON *pNode = NULL;
1413 custom_boot *tail = NULL;
1414 custom_boot *node = NULL;
1415 custom_boot *next = NULL;
1416
1417 (void)isodisk;
1418
1419 if (json->enDataType != JSON_TYPE_ARRAY)
1420 {
1421 debug("Not array %d\n", json->enDataType);
1422 return 0;
1423 }
1424
1425 if (g_custom_boot_head)
1426 {
1427 for (node = g_custom_boot_head; node; node = next)
1428 {
1429 next = node->next;
1430 grub_free(node);
1431 }
1432
1433 g_custom_boot_head = NULL;
1434 }
1435
1436 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1437 {
1438 type = vtoy_custom_boot_image_file;
1439 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1440 if (!key)
1441 {
1442 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1443 type = vtoy_custom_boot_directory;
1444 }
1445
1446 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1447 if (key && cfg)
1448 {
1449 node = grub_zalloc(sizeof(custom_boot));
1450 if (node)
1451 {
1452 node->type = type;
1453 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", key);
1454 len = (int)grub_snprintf(node->cfg, sizeof(node->cfg), "%s", cfg);
1455
1456 if (len >= 5 && grub_strncmp(node->cfg + len - 5, ".vcfg", 5) == 0)
1457 {
1458 if (g_custom_boot_head)
1459 {
1460 tail->next = node;
1461 }
1462 else
1463 {
1464 g_custom_boot_head = node;
1465 }
1466 tail = node;
1467 }
1468 else
1469 {
1470 grub_free(node);
1471 }
1472 }
1473 }
1474 }
1475
1476 return 0;
1477 }
1478
1479 static int ventoy_plugin_custom_boot_check(VTOY_JSON *json, const char *isodisk)
1480 {
1481 int type;
1482 int len;
1483 const char *key = NULL;
1484 const char *cfg = NULL;
1485 VTOY_JSON *pNode = NULL;
1486
1487 (void)isodisk;
1488
1489 if (json->enDataType != JSON_TYPE_ARRAY)
1490 {
1491 grub_printf("Not array %d\n", json->enDataType);
1492 return 1;
1493 }
1494
1495 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1496 {
1497 type = vtoy_custom_boot_image_file;
1498 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1499 if (!key)
1500 {
1501 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1502 type = vtoy_custom_boot_directory;
1503 }
1504
1505 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1506 len = (int)grub_strlen(cfg);
1507 if (key && cfg)
1508 {
1509 if (len < 5 || grub_strncmp(cfg + len - 5, ".vcfg", 5))
1510 {
1511 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg);
1512 }
1513 else
1514 {
1515 grub_printf("%s: <%s>\n", (type == vtoy_custom_boot_directory) ? "dir" : "file", key);
1516 grub_printf("vcfg: <%s>\n\n", cfg);
1517 }
1518 }
1519 }
1520
1521 return 0;
1522 }
1523
1524 static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk)
1525 {
1526 const char *isof = NULL;
1527 const char *orgf = NULL;
1528 const char *newf = NULL;
1529 VTOY_JSON *pNode = NULL;
1530 conf_replace *tail = NULL;
1531 conf_replace *node = NULL;
1532 conf_replace *next = NULL;
1533
1534 (void)isodisk;
1535
1536 if (json->enDataType != JSON_TYPE_ARRAY)
1537 {
1538 debug("Not array %d\n", json->enDataType);
1539 return 0;
1540 }
1541
1542 if (g_conf_replace_head)
1543 {
1544 for (node = g_conf_replace_head; node; node = next)
1545 {
1546 next = node->next;
1547 grub_free(node);
1548 }
1549
1550 g_conf_replace_head = NULL;
1551 }
1552
1553 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1554 {
1555 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
1556 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
1557 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
1558 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
1559 {
1560 node = grub_zalloc(sizeof(conf_replace));
1561 if (node)
1562 {
1563 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof);
1564 grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf);
1565 grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf);
1566
1567 if (g_conf_replace_head)
1568 {
1569 tail->next = node;
1570 }
1571 else
1572 {
1573 g_conf_replace_head = node;
1574 }
1575 tail = node;
1576 }
1577 }
1578 }
1579
1580 return 0;
1581 }
1582
1583 static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk)
1584 {
1585 const char *isof = NULL;
1586 const char *orgf = NULL;
1587 const char *newf = NULL;
1588 VTOY_JSON *pNode = NULL;
1589 grub_file_t file = NULL;
1590 char cmd[256];
1591
1592 (void)isodisk;
1593
1594 if (json->enDataType != JSON_TYPE_ARRAY)
1595 {
1596 grub_printf("Not array %d\n", json->enDataType);
1597 return 1;
1598 }
1599
1600 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1601 {
1602 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
1603 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
1604 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
1605 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
1606 {
1607 if (ventoy_check_file_exist("%s%s", isodisk, isof))
1608 {
1609 grub_printf("iso:<%s> [OK]\n", isof);
1610
1611 grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof);
1612 grub_script_execute_sourcecode(cmd);
1613
1614 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
1615 if (file)
1616 {
1617 if (grub_strcmp(file->fs->name, "iso9660") == 0)
1618 {
1619 grub_printf("org:<%s> [OK]\n", orgf);
1620 }
1621 else
1622 {
1623 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf);
1624 }
1625 grub_file_close(file);
1626 }
1627 else
1628 {
1629 grub_printf("org:<%s> [NOT Exist]\n", orgf);
1630 }
1631
1632 grub_script_execute_sourcecode("loopback -d vtisocheck");
1633 }
1634 else if (grub_strchr(isof, '*'))
1635 {
1636 grub_printf("iso:<%s> [*]\n", isof);
1637 grub_printf("org:<%s>\n", orgf);
1638 }
1639 else
1640 {
1641 grub_printf("iso:<%s> [NOT Exist]\n", isof);
1642 grub_printf("org:<%s>\n", orgf);
1643 }
1644
1645 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf);
1646 if (file)
1647 {
1648 if (file->size > vtoy_max_replace_file_size)
1649 {
1650 grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size);
1651 }
1652 else
1653 {
1654 grub_printf("new:<%s> [OK]\n", newf);
1655 }
1656 grub_file_close(file);
1657 }
1658 else
1659 {
1660 grub_printf("new:<%s> [NOT Exist]\n", newf);
1661 }
1662 grub_printf("\n");
1663 }
1664 }
1665
1666 return 0;
1667 }
1668
1669 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
1670 {
1671 VTOY_JSON *pNode = NULL;
1672 auto_memdisk *node = NULL;
1673 auto_memdisk *next = NULL;
1674
1675 (void)isodisk;
1676
1677 if (json->enDataType != JSON_TYPE_ARRAY)
1678 {
1679 debug("Not array %d\n", json->enDataType);
1680 return 0;
1681 }
1682
1683 if (g_auto_memdisk_head)
1684 {
1685 for (node = g_auto_memdisk_head; node; node = next)
1686 {
1687 next = node->next;
1688 grub_free(node);
1689 }
1690
1691 g_auto_memdisk_head = NULL;
1692 }
1693
1694 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1695 {
1696 if (pNode->enDataType == JSON_TYPE_STRING)
1697 {
1698 node = grub_zalloc(sizeof(auto_memdisk));
1699 if (node)
1700 {
1701 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
1702
1703 if (g_auto_memdisk_head)
1704 {
1705 node->next = g_auto_memdisk_head;
1706 }
1707
1708 g_auto_memdisk_head = node;
1709 }
1710 }
1711 }
1712
1713 return 0;
1714 }
1715
1716 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk)
1717 {
1718 VTOY_JSON *pNode = NULL;
1719
1720 if (json->enDataType != JSON_TYPE_ARRAY)
1721 {
1722 grub_printf("Not array %d\n", json->enDataType);
1723 return 1;
1724 }
1725
1726 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1727 {
1728 if (pNode->enDataType == JSON_TYPE_STRING)
1729 {
1730 grub_printf("<%s> ", pNode->unData.pcStrVal);
1731
1732 if (grub_strchr(pNode->unData.pcStrVal, '*'))
1733 {
1734 grub_printf(" [*]\n");
1735 }
1736 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
1737 {
1738 grub_printf(" [OK]\n");
1739 }
1740 else
1741 {
1742 grub_printf(" [NOT EXIST]\n");
1743 }
1744 }
1745 }
1746
1747 return 0;
1748 }
1749
1750 static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk)
1751 {
1752 VTOY_JSON *pNode = NULL;
1753 image_list *node = NULL;
1754 image_list *next = NULL;
1755 image_list *tail = NULL;
1756
1757 (void)isodisk;
1758
1759 if (json->enDataType != JSON_TYPE_ARRAY)
1760 {
1761 debug("Not array %d\n", json->enDataType);
1762 return 0;
1763 }
1764
1765 if (g_image_list_head)
1766 {
1767 for (node = g_image_list_head; node; node = next)
1768 {
1769 next = node->next;
1770 grub_free(node);
1771 }
1772
1773 g_image_list_head = NULL;
1774 }
1775
1776 if (grub_strncmp(json->pcName, "image_blacklist", 15) == 0)
1777 {
1778 g_plugin_image_list = VENTOY_IMG_BLACK_LIST;
1779 }
1780 else
1781 {
1782 g_plugin_image_list = VENTOY_IMG_WHITE_LIST;
1783 }
1784
1785 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1786 {
1787 if (pNode->enDataType == JSON_TYPE_STRING)
1788 {
1789 node = grub_zalloc(sizeof(image_list));
1790 if (node)
1791 {
1792 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
1793
1794 if (g_image_list_head)
1795 {
1796 tail->next = node;
1797 }
1798 else
1799 {
1800 g_image_list_head = node;
1801 }
1802 tail = node;
1803 }
1804 }
1805 }
1806
1807 return 0;
1808 }
1809
1810 static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk)
1811 {
1812 VTOY_JSON *pNode = NULL;
1813
1814 if (json->enDataType != JSON_TYPE_ARRAY)
1815 {
1816 grub_printf("Not array %d\n", json->enDataType);
1817 return 1;
1818 }
1819
1820 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1821 {
1822 if (pNode->enDataType == JSON_TYPE_STRING)
1823 {
1824 grub_printf("<%s> ", pNode->unData.pcStrVal);
1825
1826 if (grub_strchr(pNode->unData.pcStrVal, '*'))
1827 {
1828 grub_printf(" [*]\n");
1829 }
1830 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
1831 {
1832 grub_printf(" [OK]\n");
1833 }
1834 else
1835 {
1836 grub_printf(" [NOT EXIST]\n");
1837 }
1838 }
1839 }
1840
1841 return 0;
1842 }
1843
1844 static plugin_entry g_plugin_entries[] =
1845 {
1846 { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
1847 { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
1848 { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
1849 { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check },
1850 { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
1851 { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check },
1852 { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
1853 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check },
1854 { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check },
1855 { "image_blacklist", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check },
1856 { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check },
1857 { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check },
1858 { "password", ventoy_plugin_pwd_entry, ventoy_plugin_pwd_check },
1859 { "custom_boot", ventoy_plugin_custom_boot_entry, ventoy_plugin_custom_boot_check },
1860 };
1861
1862 static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
1863 {
1864 int i;
1865 char key[128];
1866 VTOY_JSON *cur = json;
1867
1868 grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
1869
1870 while (cur)
1871 {
1872 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
1873 {
1874 grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, g_arch_mode_suffix);
1875 if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0 || grub_strcmp(key, cur->pcName) == 0)
1876 {
1877 debug("Plugin entry for %s\n", g_plugin_entries[i].key);
1878 g_plugin_entries[i].entryfunc(cur, isodisk);
1879 break;
1880 }
1881 }
1882
1883 cur = cur->pstNext;
1884 }
1885
1886 return 0;
1887 }
1888
1889 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args)
1890 {
1891 int ret = 0;
1892 char *buf = NULL;
1893 grub_file_t file;
1894 VTOY_JSON *json = NULL;
1895
1896 (void)ctxt;
1897 (void)argc;
1898
1899 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
1900 if (!file)
1901 {
1902 return GRUB_ERR_NONE;
1903 }
1904
1905 debug("json configuration file size %d\n", (int)file->size);
1906
1907 buf = grub_malloc(file->size + 1);
1908 if (!buf)
1909 {
1910 grub_file_close(file);
1911 return 1;
1912 }
1913
1914 buf[file->size] = 0;
1915 grub_file_read(file, buf, file->size);
1916 grub_file_close(file);
1917
1918 json = vtoy_json_create();
1919 if (!json)
1920 {
1921 return 1;
1922 }
1923
1924
1925
1926 ret = vtoy_json_parse(json, buf);
1927 if (ret)
1928 {
1929 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
1930 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
1931
1932 debug("Failed to parse json string %d\n", ret);
1933 grub_free(buf);
1934 return 1;
1935 }
1936
1937 ventoy_parse_plugin_config(json->pstChild, args[0]);
1938
1939 vtoy_json_destroy(json);
1940
1941 grub_free(buf);
1942
1943 if (g_boot_pwd.type)
1944 {
1945 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
1946 if (ventoy_check_password(&g_boot_pwd, 3))
1947 {
1948 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
1949 grub_refresh();
1950 grub_sleep(5);
1951 grub_exit();
1952 }
1953 }
1954
1955 VENTOY_CMD_RETURN(GRUB_ERR_NONE);
1956 }
1957
1958 void ventoy_plugin_dump_injection(void)
1959 {
1960 injection_config *node = NULL;
1961
1962 for (node = g_injection_head; node; node = node->next)
1963 {
1964 grub_printf("\nIMAGE:<%s>\n", node->isopath);
1965 grub_printf("ARCHIVE:<%s>\n", node->archive);
1966 }
1967
1968 return;
1969 }
1970
1971
1972 void ventoy_plugin_dump_auto_install(void)
1973 {
1974 int i;
1975 install_template *node = NULL;
1976
1977 for (node = g_install_template_head; node; node = node->next)
1978 {
1979 grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->templatenum);
1980 for (i = 0; i < node->templatenum; i++)
1981 {
1982 grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path);
1983 }
1984 }
1985
1986 return;
1987 }
1988
1989 void ventoy_plugin_dump_persistence(void)
1990 {
1991 int rc;
1992 int i = 0;
1993 persistence_config *node = NULL;
1994 ventoy_img_chunk_list chunk_list;
1995
1996 for (node = g_persistence_head; node; node = node->next)
1997 {
1998 grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum);
1999
2000 for (i = 0; i < node->backendnum; i++)
2001 {
2002 grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path);
2003 rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list);
2004 if (rc == 0)
2005 {
2006 grub_printf(" [ SUCCESS ]\n");
2007 grub_free(chunk_list.chunk);
2008 }
2009 else
2010 {
2011 grub_printf(" [ FAILED ]\n");
2012 }
2013 }
2014 }
2015
2016 return;
2017 }
2018
2019 install_template * ventoy_plugin_find_install_template(const char *isopath)
2020 {
2021 int len;
2022 install_template *node = NULL;
2023
2024 if (!g_install_template_head)
2025 {
2026 return NULL;
2027 }
2028
2029 len = (int)grub_strlen(isopath);
2030 for (node = g_install_template_head; node; node = node->next)
2031 {
2032 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2033 {
2034 return node;
2035 }
2036 }
2037
2038 return NULL;
2039 }
2040
2041 char * ventoy_plugin_get_cur_install_template(const char *isopath)
2042 {
2043 install_template *node = NULL;
2044
2045 node = ventoy_plugin_find_install_template(isopath);
2046 if ((!node) || (!node->templatepath))
2047 {
2048 return NULL;
2049 }
2050
2051 if (node->cursel < 0 || node->cursel >= node->templatenum)
2052 {
2053 return NULL;
2054 }
2055
2056 return node->templatepath[node->cursel].path;
2057 }
2058
2059 persistence_config * ventoy_plugin_find_persistent(const char *isopath)
2060 {
2061 int len;
2062 persistence_config *node = NULL;
2063
2064 if (!g_persistence_head)
2065 {
2066 return NULL;
2067 }
2068
2069 len = (int)grub_strlen(isopath);
2070 for (node = g_persistence_head; node; node = node->next)
2071 {
2072 if ((len == node->pathlen) && (ventoy_strcmp(node->isopath, isopath) == 0))
2073 {
2074 return node;
2075 }
2076 }
2077
2078 return NULL;
2079 }
2080
2081 int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
2082 {
2083 int rc = 1;
2084 grub_uint64_t start = 0;
2085 grub_file_t file = NULL;
2086 persistence_config *node = NULL;
2087
2088 node = ventoy_plugin_find_persistent(isopath);
2089 if ((!node) || (!node->backendpath))
2090 {
2091 return 1;
2092 }
2093
2094 if (index < 0)
2095 {
2096 index = node->cursel;
2097 }
2098
2099 if (index < 0 || index >= node->backendnum)
2100 {
2101 return 1;
2102 }
2103
2104 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path);
2105 if (!file)
2106 {
2107 debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path);
2108 goto end;
2109 }
2110
2111 grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list));
2112 chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
2113 if (NULL == chunk_list->chunk)
2114 {
2115 goto end;
2116 }
2117
2118 chunk_list->max_chunk = DEFAULT_CHUNK_NUM;
2119 chunk_list->cur_chunk = 0;
2120
2121 start = file->device->disk->partition->start;
2122 ventoy_get_block_list(file, chunk_list, start);
2123
2124 if (0 != ventoy_check_block_list(file, chunk_list, start))
2125 {
2126 grub_free(chunk_list->chunk);
2127 chunk_list->chunk = NULL;
2128 goto end;
2129 }
2130
2131 rc = 0;
2132
2133 end:
2134 if (file)
2135 grub_file_close(file);
2136
2137 return rc;
2138 }
2139
2140 const char * ventoy_plugin_get_injection(const char *isopath)
2141 {
2142 int len;
2143 injection_config *node = NULL;
2144
2145 if (!g_injection_head)
2146 {
2147 return NULL;
2148 }
2149
2150 len = (int)grub_strlen(isopath);
2151 for (node = g_injection_head; node; node = node->next)
2152 {
2153 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2154 {
2155 return node->archive;
2156 }
2157 }
2158
2159 return NULL;
2160 }
2161
2162 const char * ventoy_plugin_get_menu_alias(int type, const char *isopath)
2163 {
2164 int len;
2165 menu_alias *node = NULL;
2166
2167 if (!g_menu_alias_head)
2168 {
2169 return NULL;
2170 }
2171
2172 len = (int)grub_strlen(isopath);
2173 for (node = g_menu_alias_head; node; node = node->next)
2174 {
2175 if (node->type == type && node->pathlen &&
2176 node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2177 {
2178 return node->alias;
2179 }
2180 }
2181
2182 return NULL;
2183 }
2184
2185 const char * ventoy_plugin_get_menu_class(int type, const char *name)
2186 {
2187 int len;
2188 menu_class *node = NULL;
2189
2190 if (!g_menu_class_head)
2191 {
2192 return NULL;
2193 }
2194
2195 len = (int)grub_strlen(name);
2196
2197 if (vtoy_class_image_file == type)
2198 {
2199 for (node = g_menu_class_head; node; node = node->next)
2200 {
2201 if (node->type == type && node->patlen <= len && grub_strstr(name, node->pattern))
2202 {
2203 return node->class;
2204 }
2205 }
2206 }
2207 else
2208 {
2209 for (node = g_menu_class_head; node; node = node->next)
2210 {
2211 if (node->type == type && node->patlen == len && grub_strncmp(name, node->pattern, len) == 0)
2212 {
2213 return node->class;
2214 }
2215 }
2216 }
2217
2218 return NULL;
2219 }
2220
2221 int ventoy_plugin_add_custom_boot(const char *vcfgpath)
2222 {
2223 int len;
2224 custom_boot *node = NULL;
2225
2226 node = grub_zalloc(sizeof(custom_boot));
2227 if (node)
2228 {
2229 node->type = vtoy_custom_boot_image_file;
2230 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", vcfgpath);
2231 grub_snprintf(node->cfg, sizeof(node->cfg), "%s", vcfgpath);
2232
2233 /* .vcfg */
2234 len = node->pathlen - 5;
2235 node->path[len] = 0;
2236 node->pathlen = len;
2237
2238 if (g_custom_boot_head)
2239 {
2240 node->next = g_custom_boot_head;
2241 }
2242 g_custom_boot_head = node;
2243 }
2244
2245 return 0;
2246 }
2247
2248 const char * ventoy_plugin_get_custom_boot(const char *isopath)
2249 {
2250 int i;
2251 int len;
2252 custom_boot *node = NULL;
2253
2254 if (!g_custom_boot_head)
2255 {
2256 return NULL;
2257 }
2258
2259 len = (int)grub_strlen(isopath);
2260
2261 for (node = g_custom_boot_head; node; node = node->next)
2262 {
2263 if (node->type == vtoy_custom_boot_image_file)
2264 {
2265 if (node->pathlen == len && grub_strncmp(isopath, node->path, len) == 0)
2266 {
2267 return node->cfg;
2268 }
2269 }
2270 else
2271 {
2272 if (node->pathlen < len && isopath[node->pathlen] == '/' &&
2273 grub_strncmp(isopath, node->path, node->pathlen) == 0)
2274 {
2275 for (i = node->pathlen + 1; i < len; i++)
2276 {
2277 if (isopath[i] == '/')
2278 {
2279 break;
2280 }
2281 }
2282
2283 if (i >= len)
2284 {
2285 return node->cfg;
2286 }
2287 }
2288 }
2289 }
2290
2291 return NULL;
2292 }
2293
2294 grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args)
2295 {
2296 custom_boot *node = NULL;
2297
2298 (void)argc;
2299 (void)ctxt;
2300 (void)args;
2301
2302 for (node = g_custom_boot_head; node; node = node->next)
2303 {
2304 grub_printf("[%s] <%s>:<%s>\n", (node->type == vtoy_custom_boot_directory) ? "dir" : "file",
2305 node->path, node->cfg);
2306 }
2307
2308 return 0;
2309 }
2310
2311 int ventoy_plugin_check_memdisk(const char *isopath)
2312 {
2313 int len;
2314 auto_memdisk *node = NULL;
2315
2316 if (!g_auto_memdisk_head)
2317 {
2318 return 0;
2319 }
2320
2321 len = (int)grub_strlen(isopath);
2322 for (node = g_auto_memdisk_head; node; node = node->next)
2323 {
2324 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
2325 {
2326 return 1;
2327 }
2328 }
2329
2330 return 0;
2331 }
2332
2333 int ventoy_plugin_get_image_list_index(int type, const char *name)
2334 {
2335 int len;
2336 int index = 1;
2337 image_list *node = NULL;
2338
2339 if (!g_image_list_head)
2340 {
2341 return 0;
2342 }
2343
2344 len = (int)grub_strlen(name);
2345
2346 for (node = g_image_list_head; node; node = node->next, index++)
2347 {
2348 if (vtoy_class_directory == type)
2349 {
2350 if (len < node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2351 {
2352 return index;
2353 }
2354 }
2355 else
2356 {
2357 if (len == node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2358 {
2359 return index;
2360 }
2361 }
2362 }
2363
2364 return 0;
2365 }
2366
2367 conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
2368 {
2369 int len;
2370 conf_replace *node;
2371
2372 if (!g_conf_replace_head)
2373 {
2374 return NULL;
2375 }
2376
2377 len = (int)grub_strlen(iso);
2378
2379 for (node = g_conf_replace_head; node; node = node->next)
2380 {
2381 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
2382 {
2383 return node;
2384 }
2385 }
2386
2387 return NULL;
2388 }
2389
2390 dud * ventoy_plugin_find_dud(const char *iso)
2391 {
2392 int len;
2393 dud *node;
2394
2395 if (!g_dud_head)
2396 {
2397 return NULL;
2398 }
2399
2400 len = (int)grub_strlen(iso);
2401 for (node = g_dud_head; node; node = node->next)
2402 {
2403 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
2404 {
2405 return node;
2406 }
2407 }
2408
2409 return NULL;
2410 }
2411
2412 int ventoy_plugin_load_dud(dud *node, const char *isopart)
2413 {
2414 int i;
2415 char *buf;
2416 grub_file_t file;
2417
2418 for (i = 0; i < node->dudnum; i++)
2419 {
2420 if (node->files[i].size > 0)
2421 {
2422 debug("file %d has been loaded\n", i);
2423 continue;
2424 }
2425
2426 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path);
2427 if (file)
2428 {
2429 buf = grub_malloc(file->size);
2430 if (buf)
2431 {
2432 grub_file_read(file, buf, file->size);
2433 node->files[i].size = (int)file->size;
2434 node->files[i].buf = buf;
2435 }
2436 grub_file_close(file);
2437 }
2438 }
2439
2440 return 0;
2441 }
2442
2443 static const vtoy_password * ventoy_plugin_get_password(const char *isopath)
2444 {
2445 int len;
2446 menu_password *node = NULL;
2447
2448 if ((!g_pwd_head) || (!isopath))
2449 {
2450 return NULL;
2451 }
2452
2453 len = (int)grub_strlen(isopath);
2454 for (node = g_pwd_head; node; node = node->next)
2455 {
2456 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
2457 {
2458 return &(node->password);
2459 }
2460 }
2461
2462 return NULL;
2463 }
2464
2465 grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args)
2466 {
2467 int ret;
2468 const vtoy_password *pwd = NULL;
2469
2470 (void)ctxt;
2471 (void)argc;
2472
2473 pwd = ventoy_plugin_get_password(args[0]);
2474 if (pwd)
2475 {
2476 if (0 == ventoy_check_password(pwd, 1))
2477 {
2478 ret = 1;
2479 }
2480 else
2481 {
2482 ret = 0;
2483 }
2484 }
2485 else
2486 {
2487 ret = 1;
2488 }
2489
2490 grub_errno = 0;
2491 return ret;
2492 }
2493
2494 grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
2495 {
2496 int i = 0;
2497 int ret = 0;
2498 char *buf = NULL;
2499 char key[128];
2500 grub_file_t file;
2501 VTOY_JSON *node = NULL;
2502 VTOY_JSON *json = NULL;
2503
2504 (void)ctxt;
2505
2506 if (argc != 3)
2507 {
2508 return 0;
2509 }
2510
2511 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
2512 if (!file)
2513 {
2514 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2515 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2516 goto end;
2517 }
2518
2519 buf = grub_malloc(file->size + 1);
2520 if (!buf)
2521 {
2522 grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
2523 goto end;
2524 }
2525
2526 buf[file->size] = 0;
2527 grub_file_read(file, buf, file->size);
2528
2529 json = vtoy_json_create();
2530 if (!json)
2531 {
2532 grub_printf("Failed to create json\n");
2533 goto end;
2534 }
2535
2536 ret = vtoy_json_parse(json, buf);
2537 if (ret)
2538 {
2539 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2540 goto end;
2541 }
2542
2543 grub_snprintf(key, sizeof(key), "%s_%s", args[1], g_arch_mode_suffix);
2544 for (node = json->pstChild; node; node = node->pstNext)
2545 {
2546 if (grub_strcmp(node->pcName, args[1]) == 0 || grub_strcmp(node->pcName, key) == 0)
2547 {
2548 break;
2549 }
2550 }
2551
2552 if (!node)
2553 {
2554 grub_printf("%s is NOT found in ventoy.json\n", args[1]);
2555 goto end;
2556 }
2557
2558 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
2559 {
2560 if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
2561 {
2562 if (g_plugin_entries[i].checkfunc)
2563 {
2564 ret = g_plugin_entries[i].checkfunc(node, args[2]);
2565 }
2566 break;
2567 }
2568 }
2569
2570 end:
2571 check_free(file, grub_file_close);
2572 check_free(json, vtoy_json_destroy);
2573 grub_check_free(buf);
2574
2575 return 0;
2576 }
2577