]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c
1948d0af4c4a859899bf443aafaa3d64fcc07798
[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/time.h>
36 #include <grub/ventoy.h>
37 #include "ventoy_def.h"
38
39 GRUB_MOD_LICENSE ("GPLv3+");
40
41 static char g_iso_disk_name[128];
42 static install_template *g_install_template_head = NULL;
43 static persistence_config *g_persistence_head = NULL;
44 static menu_alias *g_menu_alias_head = NULL;
45
46 static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
47 {
48 int rc = 0;
49 VTOY_JSON *pNode = NULL;
50 VTOY_JSON *pChild = NULL;
51
52 (void)isodisk;
53
54 if (json->enDataType != JSON_TYPE_ARRAY)
55 {
56 grub_printf("Not array type %d\n", json->enDataType);
57 return 1;
58 }
59
60 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
61 {
62 if (pNode->enDataType == JSON_TYPE_OBJECT)
63 {
64 pChild = pNode->pstChild;
65 if (pChild->enDataType == JSON_TYPE_STRING)
66 {
67 grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
68 }
69 else
70 {
71 grub_printf("%s is NOT string type\n", pChild->pcName);
72 rc = 1;
73 }
74 }
75 else
76 {
77 grub_printf("%s is not an object\n", pNode->pcName);
78 rc = 1;
79 }
80 }
81
82 return rc;
83 }
84
85 static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
86 {
87 VTOY_JSON *pNode = NULL;
88 VTOY_JSON *pChild = NULL;
89
90 (void)isodisk;
91
92 if (json->enDataType != JSON_TYPE_ARRAY)
93 {
94 debug("Not array %d\n", json->enDataType);
95 return 0;
96 }
97
98 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
99 {
100 if (pNode->enDataType == JSON_TYPE_OBJECT)
101 {
102 pChild = pNode->pstChild;
103 if (pChild->enDataType == JSON_TYPE_STRING && pChild->pcName && pChild->unData.pcStrVal)
104 {
105 ventoy_set_env(pChild->pcName, pChild->unData.pcStrVal);
106 }
107 }
108 }
109
110 return 0;
111 }
112
113 static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
114 {
115 int exist = 0;
116 const char *value;
117
118 value = vtoy_json_get_string_ex(json->pstChild, "file");
119 if (value)
120 {
121 grub_printf("file: %s\n", value);
122 if (value[0] == '/')
123 {
124 exist = ventoy_is_file_exist("%s%s", isodisk, value);
125 }
126 else
127 {
128 exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
129 }
130
131 if (exist == 0)
132 {
133 grub_printf("Theme file %s does NOT exist\n", value);
134 return 1;
135 }
136 }
137
138 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
139 if (value)
140 {
141 grub_printf("gfxmode: %s\n", value);
142 }
143
144 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
145 if (value)
146 {
147 grub_printf("display_mode: %s\n", value);
148 }
149
150 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
151 if (value)
152 {
153 grub_printf("ventoy_left: %s\n", value);
154 }
155
156 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
157 if (value)
158 {
159 grub_printf("ventoy_top: %s\n", value);
160 }
161
162 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
163 if (value)
164 {
165 grub_printf("ventoy_color: %s\n", value);
166 }
167
168 return 0;
169 }
170
171 static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
172 {
173 const char *value;
174 char filepath[256];
175
176 value = vtoy_json_get_string_ex(json->pstChild, "file");
177 if (value)
178 {
179 if (value[0] == '/')
180 {
181 grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value);
182 }
183 else
184 {
185 grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value);
186 }
187
188 if (ventoy_is_file_exist(filepath) == 0)
189 {
190 debug("Theme file %s does not exist\n", filepath);
191 return 0;
192 }
193
194 debug("vtoy_theme %s\n", filepath);
195 grub_env_set("vtoy_theme", filepath);
196 }
197
198 value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
199 if (value)
200 {
201 debug("vtoy_gfxmode %s\n", value);
202 grub_env_set("vtoy_gfxmode", value);
203 }
204
205 value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
206 if (value)
207 {
208 debug("display_mode %s\n", value);
209 grub_env_set("vtoy_display_mode", value);
210 }
211
212 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
213 if (value)
214 {
215 grub_env_set("VTLE_LFT", value);
216 }
217
218 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
219 if (value)
220 {
221 grub_env_set("VTLE_TOP", value);
222 }
223
224 value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
225 if (value)
226 {
227 grub_env_set("VTLE_CLR", value);
228 }
229
230 return 0;
231 }
232
233 static int ventoy_plugin_check_path(const char *path, const char *file)
234 {
235 if (file[0] != '/')
236 {
237 grub_printf("%s is NOT begin with '/' \n", file);
238 return 1;
239 }
240
241 if (grub_strchr(file, '\\'))
242 {
243 grub_printf("%s contains invalid '\\' \n", file);
244 return 1;
245 }
246
247 if (grub_strstr(file, "//"))
248 {
249 grub_printf("%s contains invalid double slash\n", file);
250 return 1;
251 }
252
253 if (grub_strstr(file, "../"))
254 {
255 grub_printf("%s contains invalid '../' \n", file);
256 return 1;
257 }
258
259 if (!ventoy_is_file_exist("%s%s", path, file))
260 {
261 grub_printf("%s%s does NOT exist\n", path, file);
262 return 1;
263 }
264
265 return 0;
266 }
267
268 static int ventoy_plugin_check_fullpath
269 (
270 VTOY_JSON *json,
271 const char *isodisk,
272 const char *key
273 )
274 {
275 int rc = 0;
276 int ret = 0;
277 VTOY_JSON *node = json;
278 VTOY_JSON *child = NULL;
279
280 while (node)
281 {
282 if (0 == grub_strcmp(key, node->pcName))
283 {
284 break;
285 }
286 node = node->pstNext;
287 }
288
289 if (!node)
290 {
291 return 1;
292 }
293
294 if (JSON_TYPE_STRING == node->enDataType)
295 {
296 ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
297 grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
298 }
299 else if (JSON_TYPE_ARRAY == node->enDataType)
300 {
301 for (child = node->pstChild; child; child = child->pstNext)
302 {
303 if (JSON_TYPE_STRING != child->enDataType)
304 {
305 grub_printf("Non string json type\n");
306 }
307 else
308 {
309 rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
310 grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
311 ret += rc;
312 }
313 }
314 }
315
316 return ret;
317 }
318
319 static int ventoy_plugin_parse_fullpath
320 (
321 VTOY_JSON *json,
322 const char *isodisk,
323 const char *key,
324 file_fullpath **fullpath,
325 int *pathnum
326 )
327 {
328 int rc = 1;
329 int count = 0;
330 VTOY_JSON *node = json;
331 VTOY_JSON *child = NULL;
332 file_fullpath *path = NULL;
333
334 while (node)
335 {
336 if (0 == grub_strcmp(key, node->pcName))
337 {
338 break;
339 }
340 node = node->pstNext;
341 }
342
343 if (!node)
344 {
345 return 1;
346 }
347
348 if (JSON_TYPE_STRING == node->enDataType)
349 {
350 debug("%s is string type data\n", node->pcName);
351
352 if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal)))
353 {
354 debug("%s%s file not found\n", isodisk, node->unData.pcStrVal);
355 return 1;
356 }
357
358 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath));
359 if (path)
360 {
361 grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal);
362 *fullpath = path;
363 *pathnum = 1;
364 rc = 0;
365 }
366 }
367 else if (JSON_TYPE_ARRAY == node->enDataType)
368 {
369 for (child = node->pstChild; child; child = child->pstNext)
370 {
371 if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/'))
372 {
373 debug("Invalid data type:%d\n", child->enDataType);
374 return 1;
375 }
376 count++;
377 }
378 debug("%s is array type data, count=%d\n", node->pcName, count);
379
380 path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count);
381 if (path)
382 {
383 *fullpath = path;
384
385 for (count = 0, child = node->pstChild; child; child = child->pstNext)
386 {
387 if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal))
388 {
389 grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal);
390 path++;
391 count++;
392 }
393 }
394
395 *pathnum = count;
396 rc = 0;
397 }
398 }
399
400 return rc;
401 }
402
403 static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk)
404 {
405 const char *iso = NULL;
406 VTOY_JSON *pNode = NULL;
407
408 if (json->enDataType != JSON_TYPE_ARRAY)
409 {
410 grub_printf("Not array type %d\n", json->enDataType);
411 return 1;
412 }
413
414 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
415 {
416 if (pNode->enDataType != JSON_TYPE_OBJECT)
417 {
418 grub_printf("NOT object type\n");
419 }
420
421 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
422 if (iso)
423 {
424 if (0 == ventoy_plugin_check_path(isodisk, iso))
425 {
426 grub_printf("image: %s [OK]\n", iso);
427 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template");
428 }
429 else
430 {
431 grub_printf("image: %s [FAIL]\n", iso);
432 }
433 }
434 else
435 {
436 grub_printf("image not found\n");
437 }
438 }
439
440 return 0;
441 }
442
443 static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk)
444 {
445 int pathnum = 0;
446 const char *iso = NULL;
447 VTOY_JSON *pNode = NULL;
448 install_template *node = NULL;
449 install_template *next = NULL;
450 file_fullpath *templatepath = NULL;
451
452 if (json->enDataType != JSON_TYPE_ARRAY)
453 {
454 debug("Not array %d\n", json->enDataType);
455 return 0;
456 }
457
458 if (g_install_template_head)
459 {
460 for (node = g_install_template_head; node; node = next)
461 {
462 next = node->next;
463 grub_check_free(node->templatepath);
464 grub_free(node);
465 }
466
467 g_install_template_head = NULL;
468 }
469
470 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
471 {
472 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
473 if (iso && iso[0] == '/')
474 {
475 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum))
476 {
477 node = grub_zalloc(sizeof(install_template));
478 if (node)
479 {
480 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
481 node->templatepath = templatepath;
482 node->templatenum = pathnum;
483
484 if (g_install_template_head)
485 {
486 node->next = g_install_template_head;
487 }
488
489 g_install_template_head = node;
490 }
491 }
492 }
493 }
494
495 return 0;
496 }
497
498 static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
499 {
500 const char *iso = NULL;
501 VTOY_JSON *pNode = NULL;
502
503 if (json->enDataType != JSON_TYPE_ARRAY)
504 {
505 grub_printf("Not array type %d\n", json->enDataType);
506 return 1;
507 }
508
509 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
510 {
511 if (pNode->enDataType != JSON_TYPE_OBJECT)
512 {
513 grub_printf("NOT object type\n");
514 }
515
516 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
517 if (iso)
518 {
519 if (0 == ventoy_plugin_check_path(isodisk, iso))
520 {
521 grub_printf("image: %s [OK]\n", iso);
522 ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend");
523 }
524 else
525 {
526 grub_printf("image: %s [FAIL]\n", iso);
527 }
528 }
529 else
530 {
531 grub_printf("image not found\n");
532 }
533 }
534
535 return 0;
536 }
537
538 static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
539 {
540 int pathnum = 0;
541 const char *iso = NULL;
542 VTOY_JSON *pNode = NULL;
543 persistence_config *node = NULL;
544 persistence_config *next = NULL;
545 file_fullpath *backendpath = NULL;
546
547 (void)isodisk;
548
549 if (json->enDataType != JSON_TYPE_ARRAY)
550 {
551 debug("Not array %d\n", json->enDataType);
552 return 0;
553 }
554
555 if (g_persistence_head)
556 {
557 for (node = g_persistence_head; node; node = next)
558 {
559 next = node->next;
560 grub_check_free(node->backendpath);
561 grub_free(node);
562 }
563
564 g_persistence_head = NULL;
565 }
566
567 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
568 {
569 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
570 if (iso && iso[0] == '/')
571 {
572 if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum))
573 {
574 node = grub_zalloc(sizeof(persistence_config));
575 if (node)
576 {
577 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
578 node->backendpath = backendpath;
579 node->backendnum = pathnum;
580
581 if (g_persistence_head)
582 {
583 node->next = g_persistence_head;
584 }
585
586 g_persistence_head = node;
587 }
588 }
589 }
590 }
591
592 return 0;
593 }
594
595 static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
596 {
597 const char *iso = NULL;
598 const char *alias = NULL;
599 VTOY_JSON *pNode = NULL;
600
601 (void)isodisk;
602
603 if (json->enDataType != JSON_TYPE_ARRAY)
604 {
605 grub_printf("Not array %d\n", json->enDataType);
606 return 1;
607 }
608
609 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
610 {
611 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
612 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
613 if (iso && iso[0] == '/' && alias)
614 {
615 grub_printf("image: <%s>\n", iso);
616 grub_printf("alias: <%s>\n\n", alias);
617 }
618 }
619
620 return 0;
621 }
622
623 static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk)
624 {
625 const char *iso = NULL;
626 const char *alias = NULL;
627 VTOY_JSON *pNode = NULL;
628 menu_alias *node = NULL;
629 menu_alias *next = NULL;
630
631 (void)isodisk;
632
633 if (json->enDataType != JSON_TYPE_ARRAY)
634 {
635 debug("Not array %d\n", json->enDataType);
636 return 0;
637 }
638
639 if (g_menu_alias_head)
640 {
641 for (node = g_menu_alias_head; node; node = next)
642 {
643 next = node->next;
644 grub_free(node);
645 }
646
647 g_menu_alias_head = NULL;
648 }
649
650 for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
651 {
652 iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
653 alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
654 if (iso && iso[0] == '/' && alias)
655 {
656 node = grub_zalloc(sizeof(menu_alias));
657 if (node)
658 {
659 node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
660 grub_snprintf(node->alias, sizeof(node->alias), "%s", alias);
661
662 if (g_menu_alias_head)
663 {
664 node->next = g_menu_alias_head;
665 }
666
667 g_menu_alias_head = node;
668 }
669 }
670 }
671
672 return 0;
673 }
674
675 static plugin_entry g_plugin_entries[] =
676 {
677 { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
678 { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
679 { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
680 { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check },
681 { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
682 };
683
684 static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
685 {
686 int i;
687 VTOY_JSON *cur = json;
688
689 grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
690
691 while (cur)
692 {
693 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
694 {
695 if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0)
696 {
697 debug("Plugin entry for %s\n", g_plugin_entries[i].key);
698 g_plugin_entries[i].entryfunc(cur, isodisk);
699 break;
700 }
701 }
702
703 cur = cur->pstNext;
704 }
705
706 return 0;
707 }
708
709 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args)
710 {
711 int ret = 0;
712 char *buf = NULL;
713 grub_file_t file;
714 VTOY_JSON *json = NULL;
715
716 (void)ctxt;
717 (void)argc;
718
719 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]);
720 if (!file)
721 {
722 return GRUB_ERR_NONE;
723 }
724
725 debug("json configuration file size %d\n", (int)file->size);
726
727 buf = grub_malloc(file->size + 1);
728 if (!buf)
729 {
730 grub_file_close(file);
731 return 1;
732 }
733
734 buf[file->size] = 0;
735 grub_file_read(file, buf, file->size);
736 grub_file_close(file);
737
738 json = vtoy_json_create();
739 if (!json)
740 {
741 return 1;
742 }
743
744
745
746 ret = vtoy_json_parse(json, buf);
747 if (ret)
748 {
749 debug("Failed to parse json string %d\n", ret);
750 grub_free(buf);
751 return 1;
752 }
753
754 ventoy_parse_plugin_config(json->pstChild, args[0]);
755
756 vtoy_json_destroy(json);
757
758 grub_free(buf);
759
760 VENTOY_CMD_RETURN(GRUB_ERR_NONE);
761 }
762
763 void ventoy_plugin_dump_auto_install(void)
764 {
765 int i;
766 install_template *node = NULL;
767
768 for (node = g_install_template_head; node; node = node->next)
769 {
770 grub_printf("\nIMAGE:<%s>\n", node->isopath);
771 for (i = 0; i < node->templatenum; i++)
772 {
773 grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path);
774 }
775 }
776
777 return;
778 }
779
780 void ventoy_plugin_dump_persistence(void)
781 {
782 int rc;
783 int i = 0;
784 persistence_config *node = NULL;
785 ventoy_img_chunk_list chunk_list;
786
787 for (node = g_persistence_head; node; node = node->next)
788 {
789 grub_printf("\nIMAGE:<%s>\n", node->isopath);
790
791 for (i = 0; i < node->backendnum; i++)
792 {
793 grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path);
794 rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list);
795 if (rc == 0)
796 {
797 grub_printf(" [ SUCCESS ]\n");
798 grub_free(chunk_list.chunk);
799 }
800 else
801 {
802 grub_printf(" [ FAILED ]\n");
803 }
804 }
805 }
806
807 return;
808 }
809
810 install_template * ventoy_plugin_find_install_template(const char *isopath)
811 {
812 install_template *node = NULL;
813 int len = (int)grub_strlen(isopath);
814
815 for (node = g_install_template_head; node; node = node->next)
816 {
817 if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
818 {
819 return node;
820 }
821 }
822
823 return NULL;
824 }
825
826 char * ventoy_plugin_get_cur_install_template(const char *isopath)
827 {
828 install_template *node = NULL;
829
830 node = ventoy_plugin_find_install_template(isopath);
831 if ((!node) || (!node->templatepath))
832 {
833 return NULL;
834 }
835
836 if (node->cursel < 0 || node->cursel >= node->templatenum)
837 {
838 return NULL;
839 }
840
841 return node->templatepath[node->cursel].path;
842 }
843
844 persistence_config * ventoy_plugin_find_persistent(const char *isopath)
845 {
846 persistence_config *node = NULL;
847 int len = (int)grub_strlen(isopath);
848
849 for (node = g_persistence_head; node; node = node->next)
850 {
851 if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0))
852 {
853 return node;
854 }
855 }
856
857 return NULL;
858 }
859
860 int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
861 {
862 int rc = 1;
863 grub_uint64_t start = 0;
864 grub_file_t file = NULL;
865 persistence_config *node = NULL;
866
867 node = ventoy_plugin_find_persistent(isopath);
868 if ((!node) || (!node->backendpath))
869 {
870 return 1;
871 }
872
873 if (index < 0)
874 {
875 index = node->cursel;
876 }
877
878 if (index < 0 || index >= node->backendnum)
879 {
880 return 1;
881 }
882
883 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path);
884 if (!file)
885 {
886 debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path);
887 goto end;
888 }
889
890 grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list));
891 chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
892 if (NULL == chunk_list->chunk)
893 {
894 goto end;
895 }
896
897 chunk_list->max_chunk = DEFAULT_CHUNK_NUM;
898 chunk_list->cur_chunk = 0;
899
900 start = file->device->disk->partition->start;
901 ventoy_get_block_list(file, chunk_list, start);
902
903 if (0 != ventoy_check_block_list(file, chunk_list, start))
904 {
905 grub_free(chunk_list->chunk);
906 chunk_list->chunk = NULL;
907 goto end;
908 }
909
910 rc = 0;
911
912 end:
913 if (file)
914 grub_file_close(file);
915
916 return rc;
917 }
918
919 const char * ventoy_plugin_get_menu_alias(const char *isopath)
920 {
921 menu_alias *node = NULL;
922 int len = (int)grub_strlen(isopath);
923
924 for (node = g_menu_alias_head; node; node = node->next)
925 {
926 if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
927 {
928 return node->alias;
929 }
930 }
931
932 return NULL;
933 }
934
935 grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
936 {
937 int i = 0;
938 int ret = 0;
939 char *buf = NULL;
940 grub_file_t file;
941 VTOY_JSON *node = NULL;
942 VTOY_JSON *json = NULL;
943
944 (void)ctxt;
945
946 if (argc != 3)
947 {
948 return 0;
949 }
950
951 file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]);
952 if (!file)
953 {
954 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
955 goto end;
956 }
957
958 buf = grub_malloc(file->size + 1);
959 if (!buf)
960 {
961 grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
962 goto end;
963 }
964
965 buf[file->size] = 0;
966 grub_file_read(file, buf, file->size);
967
968 json = vtoy_json_create();
969 if (!json)
970 {
971 grub_printf("Failed to create json\n");
972 goto end;
973 }
974
975 ret = vtoy_json_parse(json, buf);
976 if (ret)
977 {
978 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
979 goto end;
980 }
981
982 for (node = json->pstChild; node; node = node->pstNext)
983 {
984 if (grub_strcmp(node->pcName, args[1]) == 0)
985 {
986 break;
987 }
988 }
989
990 if (!node)
991 {
992 grub_printf("%s is NOT found in ventoy.json\n", args[1]);
993 goto end;
994 }
995
996 for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
997 {
998 if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
999 {
1000 if (g_plugin_entries[i].checkfunc)
1001 {
1002 ret = g_plugin_entries[i].checkfunc(node, args[2]);
1003 }
1004 break;
1005 }
1006 }
1007
1008 end:
1009 check_free(file, grub_file_close);
1010 check_free(json, vtoy_json_destroy);
1011 grub_check_free(buf);
1012
1013 return 0;
1014 }
1015