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