]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c
7069b599be4072353550f4d30b19c3e48419f241
[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 int parent = 0;
1309 const char *key = NULL;
1310 const char *class = NULL;
1311 VTOY_JSON *pNode = NULL;
1312 menu_class *tail = NULL;
1313 menu_class *node = NULL;
1314 menu_class *next = NULL;
1315
1316 (void)isodisk;
1317
1318 if (json->enDataType != JSON_TYPE_ARRAY)
1319 {
1320 debug("Not array %d\n", json->enDataType);
1321 return 0;
1322 }
1323
1324 if (g_menu_class_head)
1325 {
1326 for (node = g_menu_class_head; node; node = next)
1327 {
1328 next = node->next;
1329 grub_free(node);
1330 }
1331
1332 g_menu_class_head = NULL;
1333 }
1334
1335 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1336 {
1337 parent = 0;
1338 type = vtoy_class_image_file;
1339 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1340 if (!key)
1341 {
1342 key = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1343 if (key)
1344 {
1345 parent = 1;
1346 }
1347 else
1348 {
1349 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1350 type = vtoy_class_directory;
1351 }
1352 }
1353
1354 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1355 if (key && class)
1356 {
1357 node = grub_zalloc(sizeof(menu_class));
1358 if (node)
1359 {
1360 node->type = type;
1361 node->parent = parent;
1362 node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key);
1363 grub_snprintf(node->class, sizeof(node->class), "%s", class);
1364
1365 if (g_menu_class_head)
1366 {
1367 tail->next = node;
1368 }
1369 else
1370 {
1371 g_menu_class_head = node;
1372 }
1373 tail = node;
1374 }
1375 }
1376 }
1377
1378 return 0;
1379 }
1380
1381 static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk)
1382 {
1383 const char *name = NULL;
1384 const char *key = NULL;
1385 const char *class = NULL;
1386 VTOY_JSON *pNode = NULL;
1387
1388 (void)isodisk;
1389
1390 if (json->enDataType != JSON_TYPE_ARRAY)
1391 {
1392 grub_printf("Not array %d\n", json->enDataType);
1393 return 1;
1394 }
1395
1396 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1397 {
1398 name = "key";
1399 key = vtoy_json_get_string_ex(pNode->pstChild, "key");
1400 if (!key)
1401 {
1402 name = "parent";
1403 key = vtoy_json_get_string_ex(pNode->pstChild, "parent");
1404 if (!key)
1405 {
1406 name = "dir";
1407 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1408 }
1409 }
1410
1411 class = vtoy_json_get_string_ex(pNode->pstChild, "class");
1412 if (key && class)
1413 {
1414 grub_printf("%s: <%s>\n", name, key);
1415 grub_printf("class: <%s>\n\n", class);
1416 }
1417 }
1418
1419 return 0;
1420 }
1421
1422 static int ventoy_plugin_custom_boot_entry(VTOY_JSON *json, const char *isodisk)
1423 {
1424 int type;
1425 int len;
1426 const char *key = NULL;
1427 const char *cfg = NULL;
1428 VTOY_JSON *pNode = NULL;
1429 custom_boot *tail = NULL;
1430 custom_boot *node = NULL;
1431 custom_boot *next = NULL;
1432
1433 (void)isodisk;
1434
1435 if (json->enDataType != JSON_TYPE_ARRAY)
1436 {
1437 debug("Not array %d\n", json->enDataType);
1438 return 0;
1439 }
1440
1441 if (g_custom_boot_head)
1442 {
1443 for (node = g_custom_boot_head; node; node = next)
1444 {
1445 next = node->next;
1446 grub_free(node);
1447 }
1448
1449 g_custom_boot_head = NULL;
1450 }
1451
1452 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1453 {
1454 type = vtoy_custom_boot_image_file;
1455 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1456 if (!key)
1457 {
1458 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1459 type = vtoy_custom_boot_directory;
1460 }
1461
1462 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1463 if (key && cfg)
1464 {
1465 node = grub_zalloc(sizeof(custom_boot));
1466 if (node)
1467 {
1468 node->type = type;
1469 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", key);
1470 len = (int)grub_snprintf(node->cfg, sizeof(node->cfg), "%s", cfg);
1471
1472 if (len >= 5 && grub_strncmp(node->cfg + len - 5, ".vcfg", 5) == 0)
1473 {
1474 if (g_custom_boot_head)
1475 {
1476 tail->next = node;
1477 }
1478 else
1479 {
1480 g_custom_boot_head = node;
1481 }
1482 tail = node;
1483 }
1484 else
1485 {
1486 grub_free(node);
1487 }
1488 }
1489 }
1490 }
1491
1492 return 0;
1493 }
1494
1495 static int ventoy_plugin_custom_boot_check(VTOY_JSON *json, const char *isodisk)
1496 {
1497 int type;
1498 int len;
1499 const char *key = NULL;
1500 const char *cfg = NULL;
1501 VTOY_JSON *pNode = NULL;
1502
1503 (void)isodisk;
1504
1505 if (json->enDataType != JSON_TYPE_ARRAY)
1506 {
1507 grub_printf("Not array %d\n", json->enDataType);
1508 return 1;
1509 }
1510
1511 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1512 {
1513 type = vtoy_custom_boot_image_file;
1514 key = vtoy_json_get_string_ex(pNode->pstChild, "file");
1515 if (!key)
1516 {
1517 key = vtoy_json_get_string_ex(pNode->pstChild, "dir");
1518 type = vtoy_custom_boot_directory;
1519 }
1520
1521 cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg");
1522 len = (int)grub_strlen(cfg);
1523 if (key && cfg)
1524 {
1525 if (len < 5 || grub_strncmp(cfg + len - 5, ".vcfg", 5))
1526 {
1527 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg);
1528 }
1529 else
1530 {
1531 grub_printf("%s: <%s>\n", (type == vtoy_custom_boot_directory) ? "dir" : "file", key);
1532 grub_printf("vcfg: <%s>\n\n", cfg);
1533 }
1534 }
1535 }
1536
1537 return 0;
1538 }
1539
1540 static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk)
1541 {
1542 const char *isof = NULL;
1543 const char *orgf = NULL;
1544 const char *newf = NULL;
1545 VTOY_JSON *pNode = NULL;
1546 conf_replace *tail = NULL;
1547 conf_replace *node = NULL;
1548 conf_replace *next = NULL;
1549
1550 (void)isodisk;
1551
1552 if (json->enDataType != JSON_TYPE_ARRAY)
1553 {
1554 debug("Not array %d\n", json->enDataType);
1555 return 0;
1556 }
1557
1558 if (g_conf_replace_head)
1559 {
1560 for (node = g_conf_replace_head; node; node = next)
1561 {
1562 next = node->next;
1563 grub_free(node);
1564 }
1565
1566 g_conf_replace_head = NULL;
1567 }
1568
1569 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1570 {
1571 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
1572 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
1573 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
1574 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
1575 {
1576 node = grub_zalloc(sizeof(conf_replace));
1577 if (node)
1578 {
1579 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof);
1580 grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf);
1581 grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf);
1582
1583 if (g_conf_replace_head)
1584 {
1585 tail->next = node;
1586 }
1587 else
1588 {
1589 g_conf_replace_head = node;
1590 }
1591 tail = node;
1592 }
1593 }
1594 }
1595
1596 return 0;
1597 }
1598
1599 static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk)
1600 {
1601 const char *isof = NULL;
1602 const char *orgf = NULL;
1603 const char *newf = NULL;
1604 VTOY_JSON *pNode = NULL;
1605 grub_file_t file = NULL;
1606 char cmd[256];
1607
1608 (void)isodisk;
1609
1610 if (json->enDataType != JSON_TYPE_ARRAY)
1611 {
1612 grub_printf("Not array %d\n", json->enDataType);
1613 return 1;
1614 }
1615
1616 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1617 {
1618 isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
1619 orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
1620 newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
1621 if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
1622 {
1623 if (ventoy_check_file_exist("%s%s", isodisk, isof))
1624 {
1625 grub_printf("iso:<%s> [OK]\n", isof);
1626
1627 grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof);
1628 grub_script_execute_sourcecode(cmd);
1629
1630 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
1631 if (file)
1632 {
1633 if (grub_strcmp(file->fs->name, "iso9660") == 0)
1634 {
1635 grub_printf("org:<%s> [OK]\n", orgf);
1636 }
1637 else
1638 {
1639 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf);
1640 }
1641 grub_file_close(file);
1642 }
1643 else
1644 {
1645 grub_printf("org:<%s> [NOT Exist]\n", orgf);
1646 }
1647
1648 grub_script_execute_sourcecode("loopback -d vtisocheck");
1649 }
1650 else if (grub_strchr(isof, '*'))
1651 {
1652 grub_printf("iso:<%s> [*]\n", isof);
1653 grub_printf("org:<%s>\n", orgf);
1654 }
1655 else
1656 {
1657 grub_printf("iso:<%s> [NOT Exist]\n", isof);
1658 grub_printf("org:<%s>\n", orgf);
1659 }
1660
1661 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf);
1662 if (file)
1663 {
1664 if (file->size > vtoy_max_replace_file_size)
1665 {
1666 grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size);
1667 }
1668 else
1669 {
1670 grub_printf("new:<%s> [OK]\n", newf);
1671 }
1672 grub_file_close(file);
1673 }
1674 else
1675 {
1676 grub_printf("new:<%s> [NOT Exist]\n", newf);
1677 }
1678 grub_printf("\n");
1679 }
1680 }
1681
1682 return 0;
1683 }
1684
1685 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
1686 {
1687 VTOY_JSON *pNode = NULL;
1688 auto_memdisk *node = NULL;
1689 auto_memdisk *next = NULL;
1690
1691 (void)isodisk;
1692
1693 if (json->enDataType != JSON_TYPE_ARRAY)
1694 {
1695 debug("Not array %d\n", json->enDataType);
1696 return 0;
1697 }
1698
1699 if (g_auto_memdisk_head)
1700 {
1701 for (node = g_auto_memdisk_head; node; node = next)
1702 {
1703 next = node->next;
1704 grub_free(node);
1705 }
1706
1707 g_auto_memdisk_head = NULL;
1708 }
1709
1710 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1711 {
1712 if (pNode->enDataType == JSON_TYPE_STRING)
1713 {
1714 node = grub_zalloc(sizeof(auto_memdisk));
1715 if (node)
1716 {
1717 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
1718
1719 if (g_auto_memdisk_head)
1720 {
1721 node->next = g_auto_memdisk_head;
1722 }
1723
1724 g_auto_memdisk_head = node;
1725 }
1726 }
1727 }
1728
1729 return 0;
1730 }
1731
1732 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk)
1733 {
1734 VTOY_JSON *pNode = NULL;
1735
1736 if (json->enDataType != JSON_TYPE_ARRAY)
1737 {
1738 grub_printf("Not array %d\n", json->enDataType);
1739 return 1;
1740 }
1741
1742 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1743 {
1744 if (pNode->enDataType == JSON_TYPE_STRING)
1745 {
1746 grub_printf("<%s> ", pNode->unData.pcStrVal);
1747
1748 if (grub_strchr(pNode->unData.pcStrVal, '*'))
1749 {
1750 grub_printf(" [*]\n");
1751 }
1752 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
1753 {
1754 grub_printf(" [OK]\n");
1755 }
1756 else
1757 {
1758 grub_printf(" [NOT EXIST]\n");
1759 }
1760 }
1761 }
1762
1763 return 0;
1764 }
1765
1766 static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk)
1767 {
1768 VTOY_JSON *pNode = NULL;
1769 image_list *node = NULL;
1770 image_list *next = NULL;
1771 image_list *tail = NULL;
1772
1773 (void)isodisk;
1774
1775 if (json->enDataType != JSON_TYPE_ARRAY)
1776 {
1777 debug("Not array %d\n", json->enDataType);
1778 return 0;
1779 }
1780
1781 if (g_image_list_head)
1782 {
1783 for (node = g_image_list_head; node; node = next)
1784 {
1785 next = node->next;
1786 grub_free(node);
1787 }
1788
1789 g_image_list_head = NULL;
1790 }
1791
1792 if (grub_strncmp(json->pcName, "image_blacklist", 15) == 0)
1793 {
1794 g_plugin_image_list = VENTOY_IMG_BLACK_LIST;
1795 }
1796 else
1797 {
1798 g_plugin_image_list = VENTOY_IMG_WHITE_LIST;
1799 }
1800
1801 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1802 {
1803 if (pNode->enDataType == JSON_TYPE_STRING)
1804 {
1805 node = grub_zalloc(sizeof(image_list));
1806 if (node)
1807 {
1808 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
1809
1810 if (g_image_list_head)
1811 {
1812 tail->next = node;
1813 }
1814 else
1815 {
1816 g_image_list_head = node;
1817 }
1818 tail = node;
1819 }
1820 }
1821 }
1822
1823 return 0;
1824 }
1825
1826 static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk)
1827 {
1828 VTOY_JSON *pNode = NULL;
1829
1830 if (json->enDataType != JSON_TYPE_ARRAY)
1831 {
1832 grub_printf("Not array %d\n", json->enDataType);
1833 return 1;
1834 }
1835
1836 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
1837 {
1838 if (pNode->enDataType == JSON_TYPE_STRING)
1839 {
1840 grub_printf("<%s> ", pNode->unData.pcStrVal);
1841
1842 if (grub_strchr(pNode->unData.pcStrVal, '*'))
1843 {
1844 grub_printf(" [*]\n");
1845 }
1846 else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
1847 {
1848 grub_printf(" [OK]\n");
1849 }
1850 else
1851 {
1852 grub_printf(" [NOT EXIST]\n");
1853 }
1854 }
1855 }
1856
1857 return 0;
1858 }
1859
1860 static plugin_entry g_plugin_entries[] =
1861 {
1862 { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
1863 { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
1864 { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
1865 { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check },
1866 { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
1867 { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check },
1868 { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
1869 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check },
1870 { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check },
1871 { "image_blacklist", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check },
1872 { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check },
1873 { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check },
1874 { "password", ventoy_plugin_pwd_entry, ventoy_plugin_pwd_check },
1875 { "custom_boot", ventoy_plugin_custom_boot_entry, ventoy_plugin_custom_boot_check },
1876 };
1877
1878 static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
1879 {
1880 int i;
1881 char key[128];
1882 VTOY_JSON *cur = json;
1883
1884 grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
1885
1886 while (cur)
1887 {
1888 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
1889 {
1890 grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, g_arch_mode_suffix);
1891 if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0 || grub_strcmp(key, cur->pcName) == 0)
1892 {
1893 debug("Plugin entry for %s\n", g_plugin_entries[i].key);
1894 g_plugin_entries[i].entryfunc(cur, isodisk);
1895 break;
1896 }
1897 }
1898
1899 cur = cur->pstNext;
1900 }
1901
1902 return 0;
1903 }
1904
1905 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args)
1906 {
1907 int ret = 0;
1908 char *buf = NULL;
1909 grub_file_t file;
1910 VTOY_JSON *json = NULL;
1911
1912 (void)ctxt;
1913 (void)argc;
1914
1915 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
1916 if (!file)
1917 {
1918 return GRUB_ERR_NONE;
1919 }
1920
1921 debug("json configuration file size %d\n", (int)file->size);
1922
1923 buf = grub_malloc(file->size + 1);
1924 if (!buf)
1925 {
1926 grub_file_close(file);
1927 return 1;
1928 }
1929
1930 buf[file->size] = 0;
1931 grub_file_read(file, buf, file->size);
1932 grub_file_close(file);
1933
1934 json = vtoy_json_create();
1935 if (!json)
1936 {
1937 return 1;
1938 }
1939
1940
1941
1942 ret = vtoy_json_parse(json, buf);
1943 if (ret)
1944 {
1945 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
1946 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
1947
1948 debug("Failed to parse json string %d\n", ret);
1949 grub_free(buf);
1950 return 1;
1951 }
1952
1953 ventoy_parse_plugin_config(json->pstChild, args[0]);
1954
1955 vtoy_json_destroy(json);
1956
1957 grub_free(buf);
1958
1959 if (g_boot_pwd.type)
1960 {
1961 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
1962 if (ventoy_check_password(&g_boot_pwd, 3))
1963 {
1964 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
1965 grub_refresh();
1966 grub_sleep(5);
1967 grub_exit();
1968 }
1969 }
1970
1971 VENTOY_CMD_RETURN(GRUB_ERR_NONE);
1972 }
1973
1974 void ventoy_plugin_dump_injection(void)
1975 {
1976 injection_config *node = NULL;
1977
1978 for (node = g_injection_head; node; node = node->next)
1979 {
1980 grub_printf("\nIMAGE:<%s>\n", node->isopath);
1981 grub_printf("ARCHIVE:<%s>\n", node->archive);
1982 }
1983
1984 return;
1985 }
1986
1987
1988 void ventoy_plugin_dump_auto_install(void)
1989 {
1990 int i;
1991 install_template *node = NULL;
1992
1993 for (node = g_install_template_head; node; node = node->next)
1994 {
1995 grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->templatenum);
1996 for (i = 0; i < node->templatenum; i++)
1997 {
1998 grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path);
1999 }
2000 }
2001
2002 return;
2003 }
2004
2005 void ventoy_plugin_dump_persistence(void)
2006 {
2007 int rc;
2008 int i = 0;
2009 persistence_config *node = NULL;
2010 ventoy_img_chunk_list chunk_list;
2011
2012 for (node = g_persistence_head; node; node = node->next)
2013 {
2014 grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum);
2015
2016 for (i = 0; i < node->backendnum; i++)
2017 {
2018 grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path);
2019 rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list);
2020 if (rc == 0)
2021 {
2022 grub_printf(" [ SUCCESS ]\n");
2023 grub_free(chunk_list.chunk);
2024 }
2025 else
2026 {
2027 grub_printf(" [ FAILED ]\n");
2028 }
2029 }
2030 }
2031
2032 return;
2033 }
2034
2035 install_template * ventoy_plugin_find_install_template(const char *isopath)
2036 {
2037 int len;
2038 install_template *node = NULL;
2039
2040 if (!g_install_template_head)
2041 {
2042 return NULL;
2043 }
2044
2045 len = (int)grub_strlen(isopath);
2046 for (node = g_install_template_head; node; node = node->next)
2047 {
2048 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2049 {
2050 return node;
2051 }
2052 }
2053
2054 return NULL;
2055 }
2056
2057 char * ventoy_plugin_get_cur_install_template(const char *isopath)
2058 {
2059 install_template *node = NULL;
2060
2061 node = ventoy_plugin_find_install_template(isopath);
2062 if ((!node) || (!node->templatepath))
2063 {
2064 return NULL;
2065 }
2066
2067 if (node->cursel < 0 || node->cursel >= node->templatenum)
2068 {
2069 return NULL;
2070 }
2071
2072 return node->templatepath[node->cursel].path;
2073 }
2074
2075 persistence_config * ventoy_plugin_find_persistent(const char *isopath)
2076 {
2077 int len;
2078 persistence_config *node = NULL;
2079
2080 if (!g_persistence_head)
2081 {
2082 return NULL;
2083 }
2084
2085 len = (int)grub_strlen(isopath);
2086 for (node = g_persistence_head; node; node = node->next)
2087 {
2088 if ((len == node->pathlen) && (ventoy_strcmp(node->isopath, isopath) == 0))
2089 {
2090 return node;
2091 }
2092 }
2093
2094 return NULL;
2095 }
2096
2097 int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
2098 {
2099 int rc = 1;
2100 grub_uint64_t start = 0;
2101 grub_file_t file = NULL;
2102 persistence_config *node = NULL;
2103
2104 node = ventoy_plugin_find_persistent(isopath);
2105 if ((!node) || (!node->backendpath))
2106 {
2107 return 1;
2108 }
2109
2110 if (index < 0)
2111 {
2112 index = node->cursel;
2113 }
2114
2115 if (index < 0 || index >= node->backendnum)
2116 {
2117 return 1;
2118 }
2119
2120 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path);
2121 if (!file)
2122 {
2123 debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path);
2124 goto end;
2125 }
2126
2127 grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list));
2128 chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
2129 if (NULL == chunk_list->chunk)
2130 {
2131 goto end;
2132 }
2133
2134 chunk_list->max_chunk = DEFAULT_CHUNK_NUM;
2135 chunk_list->cur_chunk = 0;
2136
2137 start = file->device->disk->partition->start;
2138 ventoy_get_block_list(file, chunk_list, start);
2139
2140 if (0 != ventoy_check_block_list(file, chunk_list, start))
2141 {
2142 grub_free(chunk_list->chunk);
2143 chunk_list->chunk = NULL;
2144 goto end;
2145 }
2146
2147 rc = 0;
2148
2149 end:
2150 if (file)
2151 grub_file_close(file);
2152
2153 return rc;
2154 }
2155
2156 const char * ventoy_plugin_get_injection(const char *isopath)
2157 {
2158 int len;
2159 injection_config *node = NULL;
2160
2161 if (!g_injection_head)
2162 {
2163 return NULL;
2164 }
2165
2166 len = (int)grub_strlen(isopath);
2167 for (node = g_injection_head; node; node = node->next)
2168 {
2169 if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2170 {
2171 return node->archive;
2172 }
2173 }
2174
2175 return NULL;
2176 }
2177
2178 const char * ventoy_plugin_get_menu_alias(int type, const char *isopath)
2179 {
2180 int len;
2181 menu_alias *node = NULL;
2182
2183 if (!g_menu_alias_head)
2184 {
2185 return NULL;
2186 }
2187
2188 len = (int)grub_strlen(isopath);
2189 for (node = g_menu_alias_head; node; node = node->next)
2190 {
2191 if (node->type == type && node->pathlen &&
2192 node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0)
2193 {
2194 return node->alias;
2195 }
2196 }
2197
2198 return NULL;
2199 }
2200
2201 const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path)
2202 {
2203 int len;
2204 menu_class *node = NULL;
2205
2206 if (!g_menu_class_head)
2207 {
2208 return NULL;
2209 }
2210
2211 if (vtoy_class_image_file == type)
2212 {
2213 for (node = g_menu_class_head; node; node = node->next)
2214 {
2215 if (node->type != type)
2216 {
2217 continue;
2218 }
2219
2220 if (node->parent)
2221 {
2222 len = (int)grub_strlen(path);
2223 if ((node->patlen < len) && (path[node->patlen] == '/') &&
2224 (grub_strncmp(path, node->pattern, node->patlen) == 0))
2225 {
2226 return node->class;
2227 }
2228 }
2229 else
2230 {
2231 len = (int)grub_strlen(name);
2232 if ((node->patlen < len) && grub_strstr(name, node->pattern))
2233 {
2234 return node->class;
2235 }
2236 }
2237 }
2238 }
2239 else
2240 {
2241 len = (int)grub_strlen(name);
2242 for (node = g_menu_class_head; node; node = node->next)
2243 {
2244 if (node->type == type && node->patlen == len && grub_strncmp(name, node->pattern, len) == 0)
2245 {
2246 return node->class;
2247 }
2248 }
2249 }
2250
2251 return NULL;
2252 }
2253
2254 int ventoy_plugin_add_custom_boot(const char *vcfgpath)
2255 {
2256 int len;
2257 custom_boot *node = NULL;
2258
2259 node = grub_zalloc(sizeof(custom_boot));
2260 if (node)
2261 {
2262 node->type = vtoy_custom_boot_image_file;
2263 node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", vcfgpath);
2264 grub_snprintf(node->cfg, sizeof(node->cfg), "%s", vcfgpath);
2265
2266 /* .vcfg */
2267 len = node->pathlen - 5;
2268 node->path[len] = 0;
2269 node->pathlen = len;
2270
2271 if (g_custom_boot_head)
2272 {
2273 node->next = g_custom_boot_head;
2274 }
2275 g_custom_boot_head = node;
2276 }
2277
2278 return 0;
2279 }
2280
2281 const char * ventoy_plugin_get_custom_boot(const char *isopath)
2282 {
2283 int i;
2284 int len;
2285 custom_boot *node = NULL;
2286
2287 if (!g_custom_boot_head)
2288 {
2289 return NULL;
2290 }
2291
2292 len = (int)grub_strlen(isopath);
2293
2294 for (node = g_custom_boot_head; node; node = node->next)
2295 {
2296 if (node->type == vtoy_custom_boot_image_file)
2297 {
2298 if (node->pathlen == len && grub_strncmp(isopath, node->path, len) == 0)
2299 {
2300 return node->cfg;
2301 }
2302 }
2303 else
2304 {
2305 if (node->pathlen < len && isopath[node->pathlen] == '/' &&
2306 grub_strncmp(isopath, node->path, node->pathlen) == 0)
2307 {
2308 for (i = node->pathlen + 1; i < len; i++)
2309 {
2310 if (isopath[i] == '/')
2311 {
2312 break;
2313 }
2314 }
2315
2316 if (i >= len)
2317 {
2318 return node->cfg;
2319 }
2320 }
2321 }
2322 }
2323
2324 return NULL;
2325 }
2326
2327 grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args)
2328 {
2329 custom_boot *node = NULL;
2330
2331 (void)argc;
2332 (void)ctxt;
2333 (void)args;
2334
2335 for (node = g_custom_boot_head; node; node = node->next)
2336 {
2337 grub_printf("[%s] <%s>:<%s>\n", (node->type == vtoy_custom_boot_directory) ? "dir" : "file",
2338 node->path, node->cfg);
2339 }
2340
2341 return 0;
2342 }
2343
2344 int ventoy_plugin_check_memdisk(const char *isopath)
2345 {
2346 int len;
2347 auto_memdisk *node = NULL;
2348
2349 if (!g_auto_memdisk_head)
2350 {
2351 return 0;
2352 }
2353
2354 len = (int)grub_strlen(isopath);
2355 for (node = g_auto_memdisk_head; node; node = node->next)
2356 {
2357 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
2358 {
2359 return 1;
2360 }
2361 }
2362
2363 return 0;
2364 }
2365
2366 int ventoy_plugin_get_image_list_index(int type, const char *name)
2367 {
2368 int len;
2369 int index = 1;
2370 image_list *node = NULL;
2371
2372 if (!g_image_list_head)
2373 {
2374 return 0;
2375 }
2376
2377 len = (int)grub_strlen(name);
2378
2379 for (node = g_image_list_head; node; node = node->next, index++)
2380 {
2381 if (vtoy_class_directory == type)
2382 {
2383 if (len < node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2384 {
2385 return index;
2386 }
2387 }
2388 else
2389 {
2390 if (len == node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0)
2391 {
2392 return index;
2393 }
2394 }
2395 }
2396
2397 return 0;
2398 }
2399
2400 conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
2401 {
2402 int len;
2403 conf_replace *node;
2404
2405 if (!g_conf_replace_head)
2406 {
2407 return NULL;
2408 }
2409
2410 len = (int)grub_strlen(iso);
2411
2412 for (node = g_conf_replace_head; node; node = node->next)
2413 {
2414 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
2415 {
2416 return node;
2417 }
2418 }
2419
2420 return NULL;
2421 }
2422
2423 dud * ventoy_plugin_find_dud(const char *iso)
2424 {
2425 int len;
2426 dud *node;
2427
2428 if (!g_dud_head)
2429 {
2430 return NULL;
2431 }
2432
2433 len = (int)grub_strlen(iso);
2434 for (node = g_dud_head; node; node = node->next)
2435 {
2436 if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
2437 {
2438 return node;
2439 }
2440 }
2441
2442 return NULL;
2443 }
2444
2445 int ventoy_plugin_load_dud(dud *node, const char *isopart)
2446 {
2447 int i;
2448 char *buf;
2449 grub_file_t file;
2450
2451 for (i = 0; i < node->dudnum; i++)
2452 {
2453 if (node->files[i].size > 0)
2454 {
2455 debug("file %d has been loaded\n", i);
2456 continue;
2457 }
2458
2459 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path);
2460 if (file)
2461 {
2462 buf = grub_malloc(file->size);
2463 if (buf)
2464 {
2465 grub_file_read(file, buf, file->size);
2466 node->files[i].size = (int)file->size;
2467 node->files[i].buf = buf;
2468 }
2469 grub_file_close(file);
2470 }
2471 }
2472
2473 return 0;
2474 }
2475
2476 static const vtoy_password * ventoy_plugin_get_password(const char *isopath)
2477 {
2478 int len;
2479 menu_password *node = NULL;
2480
2481 if ((!g_pwd_head) || (!isopath))
2482 {
2483 return NULL;
2484 }
2485
2486 len = (int)grub_strlen(isopath);
2487 for (node = g_pwd_head; node; node = node->next)
2488 {
2489 if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0)
2490 {
2491 return &(node->password);
2492 }
2493 }
2494
2495 return NULL;
2496 }
2497
2498 grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args)
2499 {
2500 int ret;
2501 const vtoy_password *pwd = NULL;
2502
2503 (void)ctxt;
2504 (void)argc;
2505
2506 pwd = ventoy_plugin_get_password(args[0]);
2507 if (pwd)
2508 {
2509 if (0 == ventoy_check_password(pwd, 1))
2510 {
2511 ret = 1;
2512 }
2513 else
2514 {
2515 ret = 0;
2516 }
2517 }
2518 else
2519 {
2520 ret = 1;
2521 }
2522
2523 grub_errno = 0;
2524 return ret;
2525 }
2526
2527 grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
2528 {
2529 int i = 0;
2530 int ret = 0;
2531 char *buf = NULL;
2532 char key[128];
2533 grub_file_t file;
2534 VTOY_JSON *node = NULL;
2535 VTOY_JSON *json = NULL;
2536
2537 (void)ctxt;
2538
2539 if (argc != 3)
2540 {
2541 return 0;
2542 }
2543
2544 file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]);
2545 if (!file)
2546 {
2547 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2548 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2549 goto end;
2550 }
2551
2552 buf = grub_malloc(file->size + 1);
2553 if (!buf)
2554 {
2555 grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
2556 goto end;
2557 }
2558
2559 buf[file->size] = 0;
2560 grub_file_read(file, buf, file->size);
2561
2562 json = vtoy_json_create();
2563 if (!json)
2564 {
2565 grub_printf("Failed to create json\n");
2566 goto end;
2567 }
2568
2569 ret = vtoy_json_parse(json, buf);
2570 if (ret)
2571 {
2572 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2573 goto end;
2574 }
2575
2576 grub_snprintf(key, sizeof(key), "%s_%s", args[1], g_arch_mode_suffix);
2577 for (node = json->pstChild; node; node = node->pstNext)
2578 {
2579 if (grub_strcmp(node->pcName, args[1]) == 0 || grub_strcmp(node->pcName, key) == 0)
2580 {
2581 break;
2582 }
2583 }
2584
2585 if (!node)
2586 {
2587 grub_printf("%s is NOT found in ventoy.json\n", args[1]);
2588 goto end;
2589 }
2590
2591 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
2592 {
2593 if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
2594 {
2595 if (g_plugin_entries[i].checkfunc)
2596 {
2597 ret = g_plugin_entries[i].checkfunc(node, args[2]);
2598 }
2599 break;
2600 }
2601 }
2602
2603 end:
2604 check_free(file, grub_file_close);
2605 check_free(json, vtoy_json_destroy);
2606 grub_check_free(buf);
2607
2608 return 0;
2609 }
2610