]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Plugson/src/Web/ventoy_http.c
Add prompt and wait for key when Ventoy check device failed. (#2094)
[Ventoy.git] / Plugson / src / Web / ventoy_http.c
1 /******************************************************************************
2 * ventoy_http.c ---- ventoy http
3 * Copyright (c) 2021, longpanda <admin@ventoy.net>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <stddef.h>
25 #include <errno.h>
26 #include <time.h>
27
28 #if defined(_MSC_VER) || defined(WIN32)
29 #else
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/mount.h>
37 #include <linux/fs.h>
38 #include <linux/limits.h>
39 #include <dirent.h>
40 #include <pthread.h>
41 #endif
42
43 #include <ventoy_define.h>
44 #include <ventoy_json.h>
45 #include <ventoy_util.h>
46 #include <ventoy_disk.h>
47 #include <ventoy_http.h>
48 #include "fat_filelib.h"
49
50 static const char *g_json_title_postfix[bios_max + 1] =
51 {
52 "", "_legacy", "_uefi", "_ia32", "_aa64", "_mips", ""
53 };
54
55 static const char *g_ventoy_kbd_layout[] =
56 {
57 "QWERTY_USA", "AZERTY", "CZECH_QWERTY", "CZECH_QWERTZ", "DANISH",
58 "DVORAK_USA", "FRENCH", "GERMAN", "ITALIANO", "JAPAN_106", "LATIN_USA",
59 "PORTU_BRAZIL", "QWERTY_UK", "QWERTZ", "QWERTZ_HUN", "QWERTZ_SLOV_CROAT",
60 "SPANISH", "SWEDISH", "TURKISH_Q", "VIETNAMESE",
61 NULL
62 };
63
64 #define VTOY_DEL_ALL_PATH "4119ae33-98ea-448e-b9c0-569aafcf1fb4"
65
66 static int g_json_exist[plugin_type_max][bios_max];
67 static const char *g_plugin_name[plugin_type_max] =
68 {
69 "control", "theme", "menu_alias", "menu_tip",
70 "menu_class", "auto_install", "persistence", "injection",
71 "conf_replace", "password", "image_list",
72 "auto_memdisk", "dud"
73 };
74
75 static char g_ventoy_menu_lang[MAX_LANGUAGE][8];
76
77 static char g_pub_path[2 * MAX_PATH];
78 static data_control g_data_control[bios_max + 1];
79 static data_theme g_data_theme[bios_max + 1];
80 static data_alias g_data_menu_alias[bios_max + 1];
81 static data_tip g_data_menu_tip[bios_max + 1];
82 static data_class g_data_menu_class[bios_max + 1];
83 static data_image_list g_data_image_list[bios_max + 1];
84 static data_image_list *g_data_image_blacklist = g_data_image_list;
85 static data_auto_memdisk g_data_auto_memdisk[bios_max + 1];
86 static data_password g_data_password[bios_max + 1];
87 static data_conf_replace g_data_conf_replace[bios_max + 1];
88 static data_injection g_data_injection[bios_max + 1];
89 static data_auto_install g_data_auto_install[bios_max + 1];
90 static data_persistence g_data_persistence[bios_max + 1];
91 static data_dud g_data_dud[bios_max + 1];
92
93 static char *g_pub_json_buffer = NULL;
94 static char *g_pub_save_buffer = NULL;
95 #define JSON_BUFFER g_pub_json_buffer
96 #define JSON_SAVE_BUFFER g_pub_save_buffer
97
98 static pthread_mutex_t g_api_mutex;
99 static struct mg_context *g_ventoy_http_ctx = NULL;
100
101 #define ventoy_is_real_exist_common(xpath, xnode, xtype) \
102 ventoy_path_is_real_exist(xpath, xnode, offsetof(xtype, path), offsetof(xtype, next))
103
104 static int ventoy_is_kbd_valid(const char *key)
105 {
106 int i = 0;
107
108 for (i = 0; g_ventoy_kbd_layout[i]; i++)
109 {
110 if (strcmp(g_ventoy_kbd_layout[i], key) == 0)
111 {
112 return 1;
113 }
114 }
115
116 return 0;
117 }
118
119 static const char * ventoy_real_path(const char *org)
120 {
121 int count = 0;
122
123 if (g_sysinfo.pathcase)
124 {
125 scnprintf(g_pub_path, MAX_PATH, "%s", org);
126 count = ventoy_path_case(g_pub_path + 1, 1);
127 if (count > 0)
128 {
129 return g_pub_path;
130 }
131 return org;
132 }
133 else
134 {
135 return org;
136 }
137 }
138
139
140 static int ventoy_json_result(struct mg_connection *conn, const char *err)
141 {
142 mg_printf(conn,
143 "HTTP/1.1 200 OK \r\n"
144 "Content-Type: application/json\r\n"
145 "Content-Length: %d\r\n"
146 "\r\n%s",
147 (int)strlen(err), err);
148
149 return 0;
150 }
151
152 static int ventoy_json_buffer(struct mg_connection *conn, const char *json_buf, int json_len)
153 {
154 mg_printf(conn,
155 "HTTP/1.1 200 OK \r\n"
156 "Content-Type: application/json\r\n"
157 "Content-Length: %d\r\n"
158 "\r\n%s",
159 json_len, json_buf);
160
161 return 0;
162 }
163
164 static void ventoy_free_path_node_list(path_node *list)
165 {
166 path_node *next = NULL;
167 path_node *node = list;
168
169 while (node)
170 {
171 next = node->next;
172 free(node);
173 node = next;
174 }
175 }
176
177 static int ventoy_path_is_real_exist(const char *path, void *head, size_t pathoff, size_t nextoff)
178 {
179 char *node = NULL;
180 const char *nodepath = NULL;
181 const char *realpath = NULL;
182 char pathbuf[MAX_PATH];
183
184 if (strchr(path, '*'))
185 {
186 return 0;
187 }
188
189 realpath = ventoy_real_path(path);
190 scnprintf(pathbuf, sizeof(pathbuf), "%s", realpath);
191
192 node = (char *)head;
193 while (node)
194 {
195 nodepath = node + pathoff;
196 if (NULL == strchr(nodepath, '*'))
197 {
198 realpath = ventoy_real_path(nodepath);
199 if (strcmp(pathbuf, realpath) == 0)
200 {
201 return 1;
202 }
203 }
204
205 memcpy(&node, node + nextoff, sizeof(node));
206 }
207
208 return 0;
209 }
210
211 static path_node * ventoy_path_node_add_array(VTOY_JSON *array)
212 {
213 path_node *head = NULL;
214 path_node *node = NULL;
215 path_node *cur = NULL;
216 VTOY_JSON *item = NULL;
217
218 for (item = array->pstChild; item; item = item->pstNext)
219 {
220 node = zalloc(sizeof(path_node));
221 if (node)
222 {
223 scnprintf(node->path, sizeof(node->path), "%s", item->unData.pcStrVal);
224 vtoy_list_add(head, cur, node);
225 }
226 }
227
228 return head;
229 }
230
231 static int ventoy_check_fuzzy_path(char *path, int prefix)
232 {
233 int rc;
234 char c;
235 char *cur = NULL;
236 char *pos = NULL;
237
238 if (!path)
239 {
240 return 0;
241 }
242
243 pos = strchr(path, '*');
244 if (pos)
245 {
246 for (cur = pos; *cur; cur++)
247 {
248 if (*cur == '/')
249 {
250 return 0;
251 }
252 }
253
254 while (pos != path)
255 {
256 if (*pos == '/')
257 {
258 break;
259 }
260 pos--;
261 }
262
263 if (*pos == '/')
264 {
265 if (pos != path)
266 {
267 c = *pos;
268 *pos = 0;
269 if (prefix)
270 {
271 rc = ventoy_is_directory_exist("%s%s", g_cur_dir, path);
272 }
273 else
274 {
275 rc = ventoy_is_directory_exist("%s", path);
276 }
277 *pos = c;
278
279 if (rc == 0)
280 {
281 return 0;
282 }
283 }
284
285 return -1;
286 }
287 else
288 {
289 return 0;
290 }
291 }
292 else
293 {
294 if (prefix)
295 {
296 return ventoy_is_file_exist("%s%s", g_cur_dir, path);
297 }
298 else
299 {
300 return ventoy_is_file_exist("%s", path);
301 }
302 }
303 }
304
305 static int ventoy_path_list_cmp(path_node *list1, path_node *list2)
306 {
307 if (NULL == list1 && NULL == list2)
308 {
309 return 0;
310 }
311 else if (list1 && list2)
312 {
313 while (list1 && list2)
314 {
315 if (strcmp(list1->path, list2->path))
316 {
317 return 1;
318 }
319
320 list1 = list1->next;
321 list2 = list2->next;
322 }
323
324 if (list1 == NULL && list2 == NULL)
325 {
326 return 0;
327 }
328 return 1;
329 }
330 else
331 {
332 return 1;
333 }
334 }
335
336
337 static int ventoy_api_device_info(struct mg_connection *conn, VTOY_JSON *json)
338 {
339 int pos = 0;
340
341 (void)json;
342
343 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
344 VTOY_JSON_FMT_OBJ_BEGIN();
345
346 VTOY_JSON_FMT_STRN("dev_name", g_sysinfo.cur_model);
347 VTOY_JSON_FMT_STRN("dev_capacity", g_sysinfo.cur_capacity);
348 VTOY_JSON_FMT_STRN("dev_fs", g_sysinfo.cur_fsname);
349 VTOY_JSON_FMT_STRN("ventoy_ver", g_sysinfo.cur_ventoy_ver);
350 VTOY_JSON_FMT_SINT("part_style", g_sysinfo.cur_part_style);
351 VTOY_JSON_FMT_SINT("secure_boot", g_sysinfo.cur_secureboot);
352
353 VTOY_JSON_FMT_OBJ_END();
354 VTOY_JSON_FMT_END(pos);
355
356 ventoy_json_buffer(conn, JSON_BUFFER, pos);
357 return 0;
358 }
359
360 static int ventoy_api_sysinfo(struct mg_connection *conn, VTOY_JSON *json)
361 {
362 int pos = 0;
363
364 (void)json;
365
366 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
367 VTOY_JSON_FMT_OBJ_BEGIN();
368 VTOY_JSON_FMT_STRN("language", ventoy_get_os_language());
369 VTOY_JSON_FMT_STRN("curdir", g_cur_dir);
370
371 //read clear
372 VTOY_JSON_FMT_SINT("syntax_error", g_sysinfo.syntax_error);
373 g_sysinfo.syntax_error = 0;
374
375 VTOY_JSON_FMT_SINT("invalid_config", g_sysinfo.invalid_config);
376 g_sysinfo.invalid_config = 0;
377
378 #if defined(_MSC_VER) || defined(WIN32)
379 VTOY_JSON_FMT_STRN("os", "windows");
380 #else
381 VTOY_JSON_FMT_STRN("os", "linux");
382 #endif
383
384 VTOY_JSON_FMT_OBJ_END();
385 VTOY_JSON_FMT_END(pos);
386
387 ventoy_json_buffer(conn, JSON_BUFFER, pos);
388 return 0;
389 }
390
391 static int ventoy_api_handshake(struct mg_connection *conn, VTOY_JSON *json)
392 {
393 int i = 0;
394 int j = 0;
395 int pos = 0;
396 char key[128];
397
398 (void)json;
399
400 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
401 VTOY_JSON_FMT_OBJ_BEGIN();
402 VTOY_JSON_FMT_SINT("status", 0);
403 VTOY_JSON_FMT_SINT("save_error", g_sysinfo.config_save_error);
404 g_sysinfo.config_save_error = 0;
405
406 for (i = 0; i < plugin_type_max; i++)
407 {
408 scnprintf(key, sizeof(key), "exist_%s", g_plugin_name[i]);
409 VTOY_JSON_FMT_KEY(key);
410 VTOY_JSON_FMT_ARY_BEGIN();
411 for (j = 0; j < bios_max; j++)
412 {
413 VTOY_JSON_FMT_ITEM_INT(g_json_exist[i][j]);
414 }
415 VTOY_JSON_FMT_ARY_ENDEX();
416 }
417
418 VTOY_JSON_FMT_OBJ_END();
419 VTOY_JSON_FMT_END(pos);
420
421 ventoy_json_buffer(conn, JSON_BUFFER, pos);
422 return 0;
423 }
424
425 static int ventoy_api_check_exist(struct mg_connection *conn, VTOY_JSON *json)
426 {
427 int dir = 0;
428 int pos = 0;
429 int exist = 0;
430 const char *path = NULL;
431
432 path = vtoy_json_get_string_ex(json, "path");
433 vtoy_json_get_int(json, "dir", &dir);
434
435 if (path)
436 {
437 if (dir)
438 {
439 exist = ventoy_is_directory_exist("%s", path);
440 }
441 else
442 {
443 exist = ventoy_is_file_exist("%s", path);
444 }
445 }
446
447 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
448 VTOY_JSON_FMT_OBJ_BEGIN();
449 VTOY_JSON_FMT_SINT("exist", exist);
450 VTOY_JSON_FMT_OBJ_END();
451 VTOY_JSON_FMT_END(pos);
452
453 ventoy_json_buffer(conn, JSON_BUFFER, pos);
454 return 0;
455 }
456
457 static int ventoy_api_check_exist2(struct mg_connection *conn, VTOY_JSON *json)
458 {
459 int dir1 = 0;
460 int dir2 = 0;
461 int fuzzy1 = 0;
462 int fuzzy2 = 0;
463 int pos = 0;
464 int exist1 = 0;
465 int exist2 = 0;
466 const char *path1 = NULL;
467 const char *path2 = NULL;
468
469 path1 = vtoy_json_get_string_ex(json, "path1");
470 path2 = vtoy_json_get_string_ex(json, "path2");
471 vtoy_json_get_int(json, "dir1", &dir1);
472 vtoy_json_get_int(json, "dir2", &dir2);
473 vtoy_json_get_int(json, "fuzzy1", &fuzzy1);
474 vtoy_json_get_int(json, "fuzzy2", &fuzzy2);
475
476 if (path1)
477 {
478 if (dir1)
479 {
480 exist1 = ventoy_is_directory_exist("%s", path1);
481 }
482 else
483 {
484 if (fuzzy1)
485 {
486 exist1 = ventoy_check_fuzzy_path((char *)path1, 0);
487 }
488 else
489 {
490 exist1 = ventoy_is_file_exist("%s", path1);
491 }
492 }
493 }
494
495 if (path2)
496 {
497 if (dir2)
498 {
499 exist2 = ventoy_is_directory_exist("%s", path2);
500 }
501 else
502 {
503 if (fuzzy2)
504 {
505 exist2 = ventoy_check_fuzzy_path((char *)path2, 0);
506 }
507 else
508 {
509 exist2 = ventoy_is_file_exist("%s", path2);
510 }
511 }
512 }
513
514 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
515 VTOY_JSON_FMT_OBJ_BEGIN();
516 VTOY_JSON_FMT_SINT("exist1", exist1);
517 VTOY_JSON_FMT_SINT("exist2", exist2);
518 VTOY_JSON_FMT_OBJ_END();
519 VTOY_JSON_FMT_END(pos);
520
521 ventoy_json_buffer(conn, JSON_BUFFER, pos);
522 return 0;
523 }
524
525 static int ventoy_api_check_fuzzy(struct mg_connection *conn, VTOY_JSON *json)
526 {
527 int pos = 0;
528 int exist = 0;
529 const char *path = NULL;
530
531 path = vtoy_json_get_string_ex(json, "path");
532 if (path)
533 {
534 exist = ventoy_check_fuzzy_path((char *)path, 0);
535 }
536
537 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
538 VTOY_JSON_FMT_OBJ_BEGIN();
539 VTOY_JSON_FMT_SINT("exist", exist);
540 VTOY_JSON_FMT_OBJ_END();
541 VTOY_JSON_FMT_END(pos);
542
543 ventoy_json_buffer(conn, JSON_BUFFER, pos);
544 return 0;
545 }
546
547
548 #if 0
549 #endif
550 void ventoy_data_default_control(data_control *data)
551 {
552 memset(data, 0, sizeof(data_control));
553
554 data->password_asterisk = 1;
555 data->secondary_menu = 1;
556 data->filter_dot_underscore = 1;
557 data->max_search_level = -1;
558 data->menu_timeout = 0;
559 data->secondary_menu_timeout = 0;
560
561 strlcpy(data->default_kbd_layout, "QWERTY_USA");
562 strlcpy(data->menu_language, "en_US");
563 }
564
565 int ventoy_data_cmp_control(data_control *data1, data_control *data2)
566 {
567 if (data1->default_menu_mode != data2->default_menu_mode ||
568 data1->treeview_style != data2->treeview_style ||
569 data1->filter_dot_underscore != data2->filter_dot_underscore ||
570 data1->sort_casesensitive != data2->sort_casesensitive ||
571 data1->max_search_level != data2->max_search_level ||
572 data1->vhd_no_warning != data2->vhd_no_warning ||
573 data1->filter_iso != data2->filter_iso ||
574 data1->filter_wim != data2->filter_wim ||
575 data1->filter_efi != data2->filter_efi ||
576 data1->filter_img != data2->filter_img ||
577 data1->filter_vhd != data2->filter_vhd ||
578 data1->filter_vtoy != data2->filter_vtoy ||
579 data1->win11_bypass_check != data2->win11_bypass_check ||
580 data1->linux_remount != data2->linux_remount ||
581 data1->password_asterisk != data2->password_asterisk ||
582 data1->secondary_menu != data2->secondary_menu ||
583 data1->menu_timeout != data2->menu_timeout ||
584 data1->secondary_menu_timeout != data2->secondary_menu_timeout)
585 {
586 return 1;
587 }
588
589 if (strcmp(data1->default_search_root, data2->default_search_root) ||
590 strcmp(data1->default_image, data2->default_image) ||
591 strcmp(data1->default_kbd_layout, data2->default_kbd_layout) ||
592 strcmp(data1->menu_language, data2->menu_language))
593 {
594 return 1;
595 }
596
597 return 0;
598 }
599
600 int ventoy_data_save_control(data_control *data, const char *title, char *buf, int buflen)
601 {
602 int pos = 0;
603 data_control *def = g_data_control + bios_max;
604
605 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
606
607 VTOY_JSON_FMT_KEY_L(L1, title);
608 VTOY_JSON_FMT_ARY_BEGIN_N();
609
610 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_DEFAULT_MENU_MODE", default_menu_mode);
611 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_TREE_VIEW_MENU_STYLE", treeview_style);
612 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILT_DOT_UNDERSCORE_FILE", filter_dot_underscore);
613 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_SORT_CASE_SENSITIVE", sort_casesensitive);
614
615 if (data->max_search_level >= 0)
616 {
617 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_MAX_SEARCH_LEVEL", max_search_level);
618 }
619
620 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_VHD_NO_WARNING", vhd_no_warning);
621 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_ISO", filter_iso);
622 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_WIM", filter_wim);
623 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_EFI", filter_efi);
624 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_IMG", filter_img);
625 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VHD", filter_vhd);
626 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_FILE_FLT_VTOY", filter_vtoy);
627 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_WIN11_BYPASS_CHECK", win11_bypass_check);
628 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_LINUX_REMOUNT", linux_remount);
629 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_SECONDARY_BOOT_MENU", secondary_menu);
630 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_SHOW_PASSWORD_ASTERISK", password_asterisk);
631 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_MENU_TIMEOUT", menu_timeout);
632 VTOY_JSON_FMT_CTRL_INT(L2, "VTOY_SECONDARY_TIMEOUT", secondary_menu_timeout);
633
634 VTOY_JSON_FMT_CTRL_STRN(L2, "VTOY_DEFAULT_KBD_LAYOUT", default_kbd_layout);
635 VTOY_JSON_FMT_CTRL_STRN(L2, "VTOY_MENU_LANGUAGE", menu_language);
636
637 if (strcmp(def->default_search_root, data->default_search_root))
638 {
639 VTOY_JSON_FMT_CTRL_STRN_STR(L2, "VTOY_DEFAULT_SEARCH_ROOT", ventoy_real_path(data->default_search_root));
640 }
641
642 if (strcmp(def->default_image, data->default_image))
643 {
644 VTOY_JSON_FMT_CTRL_STRN_STR(L2, "VTOY_DEFAULT_IMAGE", ventoy_real_path(data->default_image));
645 }
646
647 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
648 VTOY_JSON_FMT_END(pos);
649
650 return pos;
651 }
652
653 int ventoy_data_json_control(data_control *ctrl, char *buf, int buflen)
654 {
655 int i = 0;
656 int pos = 0;
657 int valid = 0;
658
659 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
660 VTOY_JSON_FMT_OBJ_BEGIN();
661
662 VTOY_JSON_FMT_SINT("default_menu_mode", ctrl->default_menu_mode);
663 VTOY_JSON_FMT_SINT("treeview_style", ctrl->treeview_style);
664 VTOY_JSON_FMT_SINT("filter_dot_underscore", ctrl->filter_dot_underscore);
665 VTOY_JSON_FMT_SINT("sort_casesensitive", ctrl->sort_casesensitive);
666 VTOY_JSON_FMT_SINT("max_search_level", ctrl->max_search_level);
667 VTOY_JSON_FMT_SINT("vhd_no_warning", ctrl->vhd_no_warning);
668
669 VTOY_JSON_FMT_SINT("filter_iso", ctrl->filter_iso);
670 VTOY_JSON_FMT_SINT("filter_wim", ctrl->filter_wim);
671 VTOY_JSON_FMT_SINT("filter_efi", ctrl->filter_efi);
672 VTOY_JSON_FMT_SINT("filter_img", ctrl->filter_img);
673 VTOY_JSON_FMT_SINT("filter_vhd", ctrl->filter_vhd);
674 VTOY_JSON_FMT_SINT("filter_vtoy", ctrl->filter_vtoy);
675 VTOY_JSON_FMT_SINT("win11_bypass_check", ctrl->win11_bypass_check);
676 VTOY_JSON_FMT_SINT("linux_remount", ctrl->linux_remount);
677 VTOY_JSON_FMT_SINT("secondary_menu", ctrl->secondary_menu);
678 VTOY_JSON_FMT_SINT("password_asterisk", ctrl->password_asterisk);
679 VTOY_JSON_FMT_SINT("menu_timeout", ctrl->menu_timeout);
680 VTOY_JSON_FMT_SINT("secondary_menu_timeout", ctrl->secondary_menu_timeout);
681 VTOY_JSON_FMT_STRN("default_kbd_layout", ctrl->default_kbd_layout);
682 VTOY_JSON_FMT_STRN("menu_language", ctrl->menu_language);
683
684 valid = 0;
685 if (ctrl->default_search_root[0] && ventoy_is_directory_exist("%s%s", g_cur_dir, ctrl->default_search_root))
686 {
687 valid = 1;
688 }
689 VTOY_JSON_FMT_STRN("default_search_root", ctrl->default_search_root);
690 VTOY_JSON_FMT_SINT("default_search_root_valid", valid);
691
692
693 valid = 0;
694 if (ctrl->default_image[0] && ventoy_is_file_exist("%s%s", g_cur_dir, ctrl->default_image))
695 {
696 valid = 1;
697 }
698 VTOY_JSON_FMT_STRN("default_image", ctrl->default_image);
699 VTOY_JSON_FMT_SINT("default_image_valid", valid);
700
701 VTOY_JSON_FMT_KEY("menu_list");
702 VTOY_JSON_FMT_ARY_BEGIN();
703
704 for (i = 0; g_ventoy_menu_lang[i][0]; i++)
705 {
706 VTOY_JSON_FMT_ITEM(g_ventoy_menu_lang[i]);
707 }
708 VTOY_JSON_FMT_ARY_ENDEX();
709
710 VTOY_JSON_FMT_OBJ_END();
711 VTOY_JSON_FMT_END(pos);
712
713 return pos;
714 }
715
716 static int ventoy_api_get_control(struct mg_connection *conn, VTOY_JSON *json)
717 {
718 api_get_func(conn, json, control);
719 return 0;
720 }
721
722 static int ventoy_api_save_control(struct mg_connection *conn, VTOY_JSON *json)
723 {
724 int ret;
725 int index = 0;
726 data_control *ctrl = NULL;
727
728 vtoy_json_get_int(json, "index", &index);
729 ctrl = g_data_control + index;
730
731 VTOY_JSON_INT("default_menu_mode", ctrl->default_menu_mode);
732 VTOY_JSON_INT("treeview_style", ctrl->treeview_style);
733 VTOY_JSON_INT("filter_dot_underscore", ctrl->filter_dot_underscore);
734 VTOY_JSON_INT("sort_casesensitive", ctrl->sort_casesensitive);
735 VTOY_JSON_INT("max_search_level", ctrl->max_search_level);
736 VTOY_JSON_INT("vhd_no_warning", ctrl->vhd_no_warning);
737 VTOY_JSON_INT("filter_iso", ctrl->filter_iso);
738 VTOY_JSON_INT("filter_wim", ctrl->filter_wim);
739 VTOY_JSON_INT("filter_efi", ctrl->filter_efi);
740 VTOY_JSON_INT("filter_img", ctrl->filter_img);
741 VTOY_JSON_INT("filter_vhd", ctrl->filter_vhd);
742 VTOY_JSON_INT("filter_vtoy", ctrl->filter_vtoy);
743 VTOY_JSON_INT("win11_bypass_check", ctrl->win11_bypass_check);
744 VTOY_JSON_INT("linux_remount", ctrl->linux_remount);
745 VTOY_JSON_INT("secondary_menu", ctrl->secondary_menu);
746 VTOY_JSON_INT("password_asterisk", ctrl->password_asterisk);
747 VTOY_JSON_INT("menu_timeout", ctrl->menu_timeout);
748 VTOY_JSON_INT("secondary_menu_timeout", ctrl->secondary_menu_timeout);
749
750 VTOY_JSON_STR("default_image", ctrl->default_image);
751 VTOY_JSON_STR("default_search_root", ctrl->default_search_root);
752 VTOY_JSON_STR("menu_language", ctrl->menu_language);
753 VTOY_JSON_STR("default_kbd_layout", ctrl->default_kbd_layout);
754
755 ret = ventoy_data_save_all();
756
757 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
758 return 0;
759 }
760
761
762 #if 0
763 #endif
764
765 void ventoy_data_default_theme(data_theme *data)
766 {
767 memset(data, 0, sizeof(data_theme));
768 strlcpy(data->gfxmode, "1024x768");
769 scnprintf(data->ventoy_left, sizeof(data->ventoy_left), "5%%");
770 scnprintf(data->ventoy_top, sizeof(data->ventoy_top), "95%%");
771 scnprintf(data->ventoy_color, sizeof(data->ventoy_color), "%s", "#0000ff");
772 }
773
774 int ventoy_data_cmp_theme(data_theme *data1, data_theme *data2)
775 {
776 if (data1->display_mode != data2->display_mode ||
777 strcmp(data1->ventoy_left, data2->ventoy_left) ||
778 strcmp(data1->ventoy_top, data2->ventoy_top) ||
779 strcmp(data1->gfxmode, data2->gfxmode) ||
780 strcmp(data1->ventoy_color, data2->ventoy_color)
781 )
782 {
783 return 1;
784 }
785
786 if (ventoy_path_list_cmp(data1->filelist, data2->filelist))
787 {
788 return 1;
789 }
790
791 if (ventoy_path_list_cmp(data1->fontslist, data2->fontslist))
792 {
793 return 1;
794 }
795
796 return 0;
797 }
798
799
800 int ventoy_data_save_theme(data_theme *data, const char *title, char *buf, int buflen)
801 {
802 int pos = 0;
803 path_node *node = NULL;
804 data_theme *def = g_data_theme + bios_max;
805
806 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
807
808 VTOY_JSON_FMT_KEY_L(L1, title);
809 VTOY_JSON_FMT_OBJ_BEGIN_N();
810
811 if (data->filelist)
812 {
813 if (data->filelist->next)
814 {
815 VTOY_JSON_FMT_KEY_L(L2, "file");
816 VTOY_JSON_FMT_ARY_BEGIN_N();
817
818 for (node = data->filelist; node; node = node->next)
819 {
820 VTOY_JSON_FMT_ITEM_PATH_LN(L3, node->path);
821 }
822
823 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
824
825 if (def->default_file != data->default_file)
826 {
827 VTOY_JSON_FMT_SINT_LN(L2, "default_file", data->default_file);
828 }
829
830 if (def->resolution_fit != data->resolution_fit)
831 {
832 VTOY_JSON_FMT_SINT_LN(L2, "resolution_fit", data->resolution_fit);
833 }
834 }
835 else
836 {
837 VTOY_JSON_FMT_STRN_PATH_LN(L2, "file", data->filelist->path);
838 }
839 }
840
841 if (data->display_mode != def->display_mode)
842 {
843 if (display_mode_cli == data->display_mode)
844 {
845 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "CLI");
846 }
847 else if (display_mode_serial == data->display_mode)
848 {
849 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "serial");
850 }
851 else if (display_mode_ser_console == data->display_mode)
852 {
853 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "serial_console");
854 }
855 else
856 {
857 VTOY_JSON_FMT_STRN_LN(L2, "display_mode", "GUI");
858 }
859 }
860
861 VTOY_JSON_FMT_DIFF_STRN(L2, "gfxmode", gfxmode);
862
863 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_left", ventoy_left);
864 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_top", ventoy_top);
865 VTOY_JSON_FMT_DIFF_STRN(L2, "ventoy_color", ventoy_color);
866
867 if (data->fontslist)
868 {
869 VTOY_JSON_FMT_KEY_L(L2, "fonts");
870 VTOY_JSON_FMT_ARY_BEGIN_N();
871
872 for (node = data->fontslist; node; node = node->next)
873 {
874 VTOY_JSON_FMT_ITEM_PATH_LN(L3, node->path);
875 }
876
877 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
878 }
879
880 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
881 VTOY_JSON_FMT_END(pos);
882
883 return pos;
884 }
885
886
887 int ventoy_data_json_theme(data_theme *data, char *buf, int buflen)
888 {
889 int pos = 0;
890 path_node *node = NULL;
891
892 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
893 VTOY_JSON_FMT_OBJ_BEGIN();
894
895 VTOY_JSON_FMT_SINT("default_file", data->default_file);
896 VTOY_JSON_FMT_SINT("resolution_fit", data->resolution_fit);
897 VTOY_JSON_FMT_SINT("display_mode", data->display_mode);
898 VTOY_JSON_FMT_STRN("gfxmode", data->gfxmode);
899
900 VTOY_JSON_FMT_STRN("ventoy_color", data->ventoy_color);
901 VTOY_JSON_FMT_STRN("ventoy_left", data->ventoy_left);
902 VTOY_JSON_FMT_STRN("ventoy_top", data->ventoy_top);
903
904 VTOY_JSON_FMT_KEY("filelist");
905 VTOY_JSON_FMT_ARY_BEGIN();
906 for (node = data->filelist; node; node = node->next)
907 {
908 VTOY_JSON_FMT_OBJ_BEGIN();
909 VTOY_JSON_FMT_STRN("path", node->path);
910 VTOY_JSON_FMT_SINT("valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->path));
911 VTOY_JSON_FMT_OBJ_ENDEX();
912 }
913 VTOY_JSON_FMT_ARY_ENDEX();
914
915 VTOY_JSON_FMT_KEY("fontslist");
916 VTOY_JSON_FMT_ARY_BEGIN();
917 for (node = data->fontslist; node; node = node->next)
918 {
919 VTOY_JSON_FMT_OBJ_BEGIN();
920 VTOY_JSON_FMT_STRN("path", node->path);
921 VTOY_JSON_FMT_SINT("valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->path));
922 VTOY_JSON_FMT_OBJ_ENDEX();
923 }
924 VTOY_JSON_FMT_ARY_ENDEX();
925
926 VTOY_JSON_FMT_OBJ_END();
927 VTOY_JSON_FMT_END(pos);
928
929 return pos;
930 }
931
932 static int ventoy_api_get_theme(struct mg_connection *conn, VTOY_JSON *json)
933 {
934 api_get_func(conn, json, theme);
935 return 0;
936 }
937
938 static int ventoy_api_save_theme(struct mg_connection *conn, VTOY_JSON *json)
939 {
940 int ret;
941 int index = 0;
942 data_theme *data = NULL;
943
944 vtoy_json_get_int(json, "index", &index);
945 data = g_data_theme + index;
946
947 VTOY_JSON_INT("default_file", data->default_file);
948 VTOY_JSON_INT("resolution_fit", data->resolution_fit);
949 VTOY_JSON_INT("display_mode", data->display_mode);
950 VTOY_JSON_STR("gfxmode", data->gfxmode);
951 VTOY_JSON_STR("ventoy_left", data->ventoy_left);
952 VTOY_JSON_STR("ventoy_top", data->ventoy_top);
953 VTOY_JSON_STR("ventoy_color", data->ventoy_color);
954
955 ret = ventoy_data_save_all();
956
957 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
958 return 0;
959 }
960
961
962 static int ventoy_api_theme_add_file(struct mg_connection *conn, VTOY_JSON *json)
963 {
964 int ret;
965 int index = 0;
966 const char *path = NULL;
967 path_node *node = NULL;
968 path_node *cur = NULL;
969 data_theme *data = NULL;
970
971 vtoy_json_get_int(json, "index", &index);
972 data = g_data_theme + index;
973
974 path = VTOY_JSON_STR_EX("path");
975 if (path)
976 {
977 if (ventoy_is_real_exist_common(path, data->filelist, path_node))
978 {
979 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
980 return 0;
981 }
982
983 node = zalloc(sizeof(path_node));
984 if (node)
985 {
986 scnprintf(node->path, sizeof(node->path), "%s", path);
987
988 vtoy_list_add(data->filelist, cur, node);
989 }
990 }
991
992 ret = ventoy_data_save_all();
993
994 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
995 return 0;
996 }
997
998 static int ventoy_api_theme_del_file(struct mg_connection *conn, VTOY_JSON *json)
999 {
1000 int ret;
1001 int index = 0;
1002 const char *path = NULL;
1003 path_node *node = NULL;
1004 path_node *last = NULL;
1005 data_theme *data = NULL;
1006
1007 vtoy_json_get_int(json, "index", &index);
1008 data = g_data_theme + index;
1009
1010 path = VTOY_JSON_STR_EX("path");
1011 if (path)
1012 {
1013 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1014 {
1015 vtoy_list_free(path_node, data->filelist);
1016 }
1017 else
1018 {
1019 vtoy_list_del(last, node, data->filelist, path);
1020 }
1021 }
1022
1023 ret = ventoy_data_save_all();
1024
1025 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1026 return 0;
1027 }
1028
1029 static int ventoy_api_theme_add_font(struct mg_connection *conn, VTOY_JSON *json)
1030 {
1031 int ret;
1032 int index = 0;
1033 const char *path = NULL;
1034 path_node *node = NULL;
1035 path_node *cur = NULL;
1036 data_theme *data = NULL;
1037
1038 vtoy_json_get_int(json, "index", &index);
1039 data = g_data_theme + index;
1040
1041 path = VTOY_JSON_STR_EX("path");
1042 if (path)
1043 {
1044 if (ventoy_is_real_exist_common(path, data->fontslist, path_node))
1045 {
1046 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
1047 return 0;
1048 }
1049
1050 node = zalloc(sizeof(path_node));
1051 if (node)
1052 {
1053 scnprintf(node->path, sizeof(node->path), "%s", path);
1054 vtoy_list_add(data->fontslist, cur, node);
1055 }
1056 }
1057
1058 ret = ventoy_data_save_all();
1059
1060 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1061 return 0;
1062 }
1063
1064
1065 static int ventoy_api_theme_del_font(struct mg_connection *conn, VTOY_JSON *json)
1066 {
1067 int ret;
1068 int index = 0;
1069 const char *path = NULL;
1070 path_node *node = NULL;
1071 path_node *last = NULL;
1072 data_theme *data = NULL;
1073
1074 vtoy_json_get_int(json, "index", &index);
1075 data = g_data_theme + index;
1076
1077 path = VTOY_JSON_STR_EX("path");
1078 if (path)
1079 {
1080 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1081 {
1082 vtoy_list_free(path_node, data->fontslist);
1083 }
1084 else
1085 {
1086 vtoy_list_del(last, node, data->fontslist, path);
1087 }
1088 }
1089
1090 ret = ventoy_data_save_all();
1091
1092 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1093 return 0;
1094 }
1095
1096 #if 0
1097 #endif
1098
1099 void ventoy_data_default_menu_alias(data_alias *data)
1100 {
1101 memset(data, 0, sizeof(data_alias));
1102 }
1103
1104 int ventoy_data_cmp_menu_alias(data_alias *data1, data_alias *data2)
1105 {
1106 data_alias_node *list1 = NULL;
1107 data_alias_node *list2 = NULL;
1108
1109 if (NULL == data1->list && NULL == data2->list)
1110 {
1111 return 0;
1112 }
1113 else if (data1->list && data2->list)
1114 {
1115 list1 = data1->list;
1116 list2 = data2->list;
1117
1118 while (list1 && list2)
1119 {
1120 if ((list1->type != list2->type) ||
1121 strcmp(list1->path, list2->path) ||
1122 strcmp(list1->alias, list2->alias))
1123 {
1124 return 1;
1125 }
1126
1127 list1 = list1->next;
1128 list2 = list2->next;
1129 }
1130
1131 if (list1 == NULL && list2 == NULL)
1132 {
1133 return 0;
1134 }
1135 return 1;
1136 }
1137 else
1138 {
1139 return 1;
1140 }
1141
1142 return 0;
1143 }
1144
1145
1146 int ventoy_data_save_menu_alias(data_alias *data, const char *title, char *buf, int buflen)
1147 {
1148 int pos = 0;
1149 data_alias_node *node = NULL;
1150
1151 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1152
1153 VTOY_JSON_FMT_KEY_L(L1, title);
1154 VTOY_JSON_FMT_ARY_BEGIN_N();
1155
1156 for (node = data->list; node; node = node->next)
1157 {
1158 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
1159
1160 if (node->type == path_type_file)
1161 {
1162 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
1163 }
1164 else
1165 {
1166 VTOY_JSON_FMT_STRN_PATH_LN(L3, "dir", node->path);
1167 }
1168
1169 VTOY_JSON_FMT_STRN_EX_LN(L3, "alias", node->alias);
1170
1171 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
1172 }
1173
1174 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1175 VTOY_JSON_FMT_END(pos);
1176
1177 return pos;
1178 }
1179
1180
1181 int ventoy_data_json_menu_alias(data_alias *data, char *buf, int buflen)
1182 {
1183 int pos = 0;
1184 int valid = 0;
1185 data_alias_node *node = NULL;
1186
1187 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1188 VTOY_JSON_FMT_ARY_BEGIN();
1189
1190 for (node = data->list; node; node = node->next)
1191 {
1192 VTOY_JSON_FMT_OBJ_BEGIN();
1193
1194 VTOY_JSON_FMT_UINT("type", node->type);
1195 VTOY_JSON_FMT_STRN("path", node->path);
1196 if (node->type == path_type_file)
1197 {
1198 valid = ventoy_check_fuzzy_path(node->path, 1);
1199 }
1200 else
1201 {
1202 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1203 }
1204
1205 VTOY_JSON_FMT_SINT("valid", valid);
1206 VTOY_JSON_FMT_STRN("alias", node->alias);
1207
1208 VTOY_JSON_FMT_OBJ_ENDEX();
1209 }
1210
1211 VTOY_JSON_FMT_ARY_END();
1212 VTOY_JSON_FMT_END(pos);
1213
1214 return pos;
1215 }
1216
1217 static int ventoy_api_get_alias(struct mg_connection *conn, VTOY_JSON *json)
1218 {
1219 api_get_func(conn, json, menu_alias);
1220 return 0;
1221 }
1222
1223 static int ventoy_api_save_alias(struct mg_connection *conn, VTOY_JSON *json)
1224 {
1225 int ret;
1226 ret = ventoy_data_save_all();
1227
1228 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1229 return 0;
1230 }
1231
1232 static int ventoy_api_alias_add(struct mg_connection *conn, VTOY_JSON *json)
1233 {
1234 int ret;
1235 int index = 0;
1236 int type = path_type_file;
1237 const char *path = NULL;
1238 const char *alias = NULL;
1239 data_alias_node *node = NULL;
1240 data_alias_node *cur = NULL;
1241 data_alias *data = NULL;
1242
1243 vtoy_json_get_int(json, "index", &index);
1244 data = g_data_menu_alias + index;
1245
1246 vtoy_json_get_int(json, "type", &type);
1247
1248 path = VTOY_JSON_STR_EX("path");
1249 alias = VTOY_JSON_STR_EX("alias");
1250 if (path && alias)
1251 {
1252 if (ventoy_is_real_exist_common(path, data->list, data_alias_node))
1253 {
1254 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
1255 return 0;
1256 }
1257
1258 node = zalloc(sizeof(data_alias_node));
1259 if (node)
1260 {
1261 node->type = type;
1262 scnprintf(node->path, sizeof(node->path), "%s", path);
1263 scnprintf(node->alias, sizeof(node->alias), "%s", alias);
1264
1265 vtoy_list_add(data->list, cur, node);
1266 }
1267 }
1268
1269 ret = ventoy_data_save_all();
1270
1271 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1272 return 0;
1273 }
1274
1275 static int ventoy_api_alias_del(struct mg_connection *conn, VTOY_JSON *json)
1276 {
1277 int ret;
1278 int index = 0;
1279 const char *path = NULL;
1280 data_alias_node *last = NULL;
1281 data_alias_node *node = NULL;
1282 data_alias *data = NULL;
1283
1284 vtoy_json_get_int(json, "index", &index);
1285 data = g_data_menu_alias + index;
1286
1287 path = VTOY_JSON_STR_EX("path");
1288 if (path)
1289 {
1290 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1291 {
1292 vtoy_list_free(data_alias_node, data->list);
1293 }
1294 else
1295 {
1296 vtoy_list_del(last, node, data->list, path);
1297 }
1298 }
1299
1300 ret = ventoy_data_save_all();
1301
1302 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1303 return 0;
1304 }
1305
1306 #if 0
1307 #endif
1308
1309 void ventoy_data_default_menu_tip(data_tip *data)
1310 {
1311 memset(data, 0, sizeof(data_tip));
1312
1313 scnprintf(data->left, sizeof(data->left), "10%%");
1314 scnprintf(data->top, sizeof(data->top), "81%%");
1315 scnprintf(data->color, sizeof(data->color), "%s", "blue");
1316 }
1317
1318 int ventoy_data_cmp_menu_tip(data_tip *data1, data_tip *data2)
1319 {
1320 data_tip_node *list1 = NULL;
1321 data_tip_node *list2 = NULL;
1322
1323 if (strcmp(data1->left, data2->left) || strcmp(data1->top, data2->top) || strcmp(data1->color, data2->color))
1324 {
1325 return 1;
1326 }
1327
1328 if (NULL == data1->list && NULL == data2->list)
1329 {
1330 return 0;
1331 }
1332 else if (data1->list && data2->list)
1333 {
1334 list1 = data1->list;
1335 list2 = data2->list;
1336
1337 while (list1 && list2)
1338 {
1339 if ((list1->type != list2->type) ||
1340 strcmp(list1->path, list2->path) ||
1341 strcmp(list1->tip, list2->tip))
1342 {
1343 return 1;
1344 }
1345
1346 list1 = list1->next;
1347 list2 = list2->next;
1348 }
1349
1350 if (list1 == NULL && list2 == NULL)
1351 {
1352 return 0;
1353 }
1354 return 1;
1355 }
1356 else
1357 {
1358 return 1;
1359 }
1360
1361 return 0;
1362 }
1363
1364
1365 int ventoy_data_save_menu_tip(data_tip *data, const char *title, char *buf, int buflen)
1366 {
1367 int pos = 0;
1368 data_tip_node *node = NULL;
1369 data_tip *def = g_data_menu_tip + bios_max;
1370
1371 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1372 VTOY_JSON_FMT_KEY_L(L1, title);
1373 VTOY_JSON_FMT_OBJ_BEGIN_N();
1374
1375 VTOY_JSON_FMT_DIFF_STRN(L2, "left", left);
1376 VTOY_JSON_FMT_DIFF_STRN(L2, "top", top);
1377 VTOY_JSON_FMT_DIFF_STRN(L2, "color", color);
1378
1379 if (data->list)
1380 {
1381 VTOY_JSON_FMT_KEY_L(L2, "tips");
1382 VTOY_JSON_FMT_ARY_BEGIN_N();
1383
1384 for (node = data->list; node; node = node->next)
1385 {
1386 VTOY_JSON_FMT_OBJ_BEGIN_LN(L3);
1387
1388 if (node->type == path_type_file)
1389 {
1390 VTOY_JSON_FMT_STRN_PATH_LN(L4, "image", node->path);
1391 }
1392 else
1393 {
1394 VTOY_JSON_FMT_STRN_PATH_LN(L4, "dir", node->path);
1395 }
1396 VTOY_JSON_FMT_STRN_EX_LN(L4, "tip", node->tip);
1397
1398 VTOY_JSON_FMT_OBJ_ENDEX_LN(L3);
1399 }
1400
1401 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
1402 }
1403
1404 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
1405
1406 VTOY_JSON_FMT_END(pos);
1407
1408 return pos;
1409 }
1410
1411
1412 int ventoy_data_json_menu_tip(data_tip *data, char *buf, int buflen)
1413 {
1414 int pos = 0;
1415 int valid = 0;
1416 data_tip_node *node = NULL;
1417
1418 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1419
1420 VTOY_JSON_FMT_OBJ_BEGIN();
1421
1422 VTOY_JSON_FMT_STRN("left", data->left);
1423 VTOY_JSON_FMT_STRN("top", data->top);
1424 VTOY_JSON_FMT_STRN("color", data->color);
1425
1426 VTOY_JSON_FMT_KEY("tips");
1427 VTOY_JSON_FMT_ARY_BEGIN();
1428
1429 for (node = data->list; node; node = node->next)
1430 {
1431 VTOY_JSON_FMT_OBJ_BEGIN();
1432
1433 VTOY_JSON_FMT_UINT("type", node->type);
1434 VTOY_JSON_FMT_STRN("path", node->path);
1435 if (node->type == path_type_file)
1436 {
1437 valid = ventoy_check_fuzzy_path(node->path, 1);
1438 }
1439 else
1440 {
1441 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1442 }
1443
1444 VTOY_JSON_FMT_SINT("valid", valid);
1445 VTOY_JSON_FMT_STRN("tip", node->tip);
1446
1447 VTOY_JSON_FMT_OBJ_ENDEX();
1448 }
1449
1450 VTOY_JSON_FMT_ARY_ENDEX();
1451
1452 VTOY_JSON_FMT_OBJ_END();
1453 VTOY_JSON_FMT_END(pos);
1454
1455 return pos;
1456 }
1457
1458 static int ventoy_api_get_tip(struct mg_connection *conn, VTOY_JSON *json)
1459 {
1460 api_get_func(conn, json, menu_tip);
1461 return 0;
1462 }
1463
1464 static int ventoy_api_save_tip(struct mg_connection *conn, VTOY_JSON *json)
1465 {
1466 int ret;
1467 int index = 0;
1468 data_tip *data = NULL;
1469
1470 vtoy_json_get_int(json, "index", &index);
1471 data = g_data_menu_tip + index;
1472
1473 VTOY_JSON_STR("left", data->left);
1474 VTOY_JSON_STR("top", data->top);
1475 VTOY_JSON_STR("color", data->color);
1476
1477 ret = ventoy_data_save_all();
1478
1479 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1480 return 0;
1481 }
1482
1483 static int ventoy_api_tip_add(struct mg_connection *conn, VTOY_JSON *json)
1484 {
1485 int ret;
1486 int index = 0;
1487 int type = path_type_file;
1488 const char *path = NULL;
1489 const char *tip = NULL;
1490 data_tip_node *node = NULL;
1491 data_tip_node *cur = NULL;
1492 data_tip *data = NULL;
1493
1494 vtoy_json_get_int(json, "index", &index);
1495 data = g_data_menu_tip + index;
1496
1497 vtoy_json_get_int(json, "type", &type);
1498
1499 path = VTOY_JSON_STR_EX("path");
1500 tip = VTOY_JSON_STR_EX("tip");
1501 if (path && tip)
1502 {
1503 if (ventoy_is_real_exist_common(path, data->list, data_tip_node))
1504 {
1505 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
1506 return 0;
1507 }
1508
1509 node = zalloc(sizeof(data_tip_node));
1510 if (node)
1511 {
1512 node->type = type;
1513 scnprintf(node->path, sizeof(node->path), "%s", path);
1514 scnprintf(node->tip, sizeof(node->tip), "%s", tip);
1515
1516 vtoy_list_add(data->list, cur, node);
1517 }
1518 }
1519
1520 ret = ventoy_data_save_all();
1521
1522 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1523 return 0;
1524 }
1525
1526 static int ventoy_api_tip_del(struct mg_connection *conn, VTOY_JSON *json)
1527 {
1528 int ret;
1529 int index = 0;
1530 const char *path = NULL;
1531 data_tip_node *last = NULL;
1532 data_tip_node *node = NULL;
1533 data_tip *data = NULL;
1534
1535 vtoy_json_get_int(json, "index", &index);
1536 data = g_data_menu_tip + index;
1537
1538 path = VTOY_JSON_STR_EX("path");
1539 if (path)
1540 {
1541 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1542 {
1543 vtoy_list_free(data_tip_node, data->list);
1544 }
1545 else
1546 {
1547 vtoy_list_del(last, node, data->list, path);
1548 }
1549 }
1550
1551 ret = ventoy_data_save_all();
1552
1553 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1554 return 0;
1555 }
1556
1557 #if 0
1558 #endif
1559
1560 void ventoy_data_default_menu_class(data_class *data)
1561 {
1562 memset(data, 0, sizeof(data_class));
1563 }
1564
1565 int ventoy_data_cmp_menu_class(data_class *data1, data_class *data2)
1566 {
1567 data_class_node *list1 = NULL;
1568 data_class_node *list2 = NULL;
1569
1570 if (NULL == data1->list && NULL == data2->list)
1571 {
1572 return 0;
1573 }
1574 else if (data1->list && data2->list)
1575 {
1576 list1 = data1->list;
1577 list2 = data2->list;
1578
1579 while (list1 && list2)
1580 {
1581 if ((list1->type != list2->type) ||
1582 strcmp(list1->path, list2->path) ||
1583 strcmp(list1->class, list2->class))
1584 {
1585 return 1;
1586 }
1587
1588 list1 = list1->next;
1589 list2 = list2->next;
1590 }
1591
1592 if (list1 == NULL && list2 == NULL)
1593 {
1594 return 0;
1595 }
1596 return 1;
1597 }
1598 else
1599 {
1600 return 1;
1601 }
1602
1603 return 0;
1604 }
1605
1606
1607 int ventoy_data_save_menu_class(data_class *data, const char *title, char *buf, int buflen)
1608 {
1609 int pos = 0;
1610 data_class_node *node = NULL;
1611
1612 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1613
1614 VTOY_JSON_FMT_KEY_L(L1, title);
1615 VTOY_JSON_FMT_ARY_BEGIN_N();
1616
1617 for (node = data->list; node; node = node->next)
1618 {
1619 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
1620
1621 if (node->type == class_type_key)
1622 {
1623 VTOY_JSON_FMT_STRN_LN(L3, "key", node->path);
1624 }
1625 else if (node->type == class_type_dir)
1626 {
1627 VTOY_JSON_FMT_STRN_PATH_LN(L3, "dir", node->path);
1628 }
1629 else
1630 {
1631 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
1632 }
1633 VTOY_JSON_FMT_STRN_LN(L3, "class", node->class);
1634
1635 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
1636 }
1637
1638 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1639 VTOY_JSON_FMT_END(pos);
1640
1641 return pos;
1642 }
1643
1644
1645 int ventoy_data_json_menu_class(data_class *data, char *buf, int buflen)
1646 {
1647 int pos = 0;
1648 int valid = 0;
1649 data_class_node *node = NULL;
1650
1651 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1652 VTOY_JSON_FMT_ARY_BEGIN();
1653
1654 for (node = data->list; node; node = node->next)
1655 {
1656 VTOY_JSON_FMT_OBJ_BEGIN();
1657
1658 VTOY_JSON_FMT_UINT("type", node->type);
1659 VTOY_JSON_FMT_STRN("path", node->path);
1660
1661 if (node->type == class_type_key)
1662 {
1663 valid = 1;
1664 }
1665 else
1666 {
1667 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
1668 }
1669 VTOY_JSON_FMT_SINT("valid", valid);
1670
1671 VTOY_JSON_FMT_STRN("class", node->class);
1672
1673 VTOY_JSON_FMT_OBJ_ENDEX();
1674 }
1675
1676 VTOY_JSON_FMT_ARY_END();
1677 VTOY_JSON_FMT_END(pos);
1678
1679 return pos;
1680 }
1681
1682
1683 static int ventoy_api_get_class(struct mg_connection *conn, VTOY_JSON *json)
1684 {
1685 api_get_func(conn, json, menu_class);
1686 return 0;
1687 }
1688
1689 static int ventoy_api_save_class(struct mg_connection *conn, VTOY_JSON *json)
1690 {
1691 int ret;
1692 ret = ventoy_data_save_all();
1693
1694 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1695 return 0;
1696 }
1697
1698 static int ventoy_api_class_add(struct mg_connection *conn, VTOY_JSON *json)
1699 {
1700 int ret;
1701 int index = 0;
1702 int type = class_type_key;
1703 const char *path = NULL;
1704 const char *class = NULL;
1705 data_class_node *node = NULL;
1706 data_class_node *cur = NULL;
1707 data_class *data = NULL;
1708
1709 vtoy_json_get_int(json, "index", &index);
1710 data = g_data_menu_class + index;
1711
1712 vtoy_json_get_int(json, "type", &type);
1713
1714 path = VTOY_JSON_STR_EX("path");
1715 class = VTOY_JSON_STR_EX("class");
1716 if (path && class)
1717 {
1718 node = zalloc(sizeof(data_class_node));
1719 if (node)
1720 {
1721 node->type = type;
1722
1723 scnprintf(node->path, sizeof(node->path), "%s", path);
1724 scnprintf(node->class, sizeof(node->class), "%s", class);
1725
1726 vtoy_list_add(data->list, cur, node);
1727 }
1728 }
1729
1730 ret = ventoy_data_save_all();
1731
1732 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1733 return 0;
1734 }
1735
1736 static int ventoy_api_class_del(struct mg_connection *conn, VTOY_JSON *json)
1737 {
1738 int ret;
1739 int index = 0;
1740 const char *path = NULL;
1741 data_class_node *last = NULL;
1742 data_class_node *node = NULL;
1743 data_class *data = NULL;
1744
1745 vtoy_json_get_int(json, "index", &index);
1746 data = g_data_menu_class + index;
1747
1748 path = VTOY_JSON_STR_EX("path");
1749 if (path)
1750 {
1751 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1752 {
1753 vtoy_list_free(data_class_node, data->list);
1754 }
1755 else
1756 {
1757 vtoy_list_del(last, node, data->list, path);
1758 }
1759 }
1760
1761 ret = ventoy_data_save_all();
1762
1763 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1764 return 0;
1765 }
1766
1767 #if 0
1768 #endif
1769
1770 void ventoy_data_default_auto_memdisk(data_auto_memdisk *data)
1771 {
1772 memset(data, 0, sizeof(data_auto_memdisk));
1773 }
1774
1775 int ventoy_data_cmp_auto_memdisk(data_auto_memdisk *data1, data_auto_memdisk *data2)
1776 {
1777 return ventoy_path_list_cmp(data1->list, data2->list);
1778 }
1779
1780 int ventoy_data_save_auto_memdisk(data_auto_memdisk *data, const char *title, char *buf, int buflen)
1781 {
1782 int pos = 0;
1783 path_node *node = NULL;
1784
1785 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1786
1787 VTOY_JSON_FMT_KEY_L(L1, title);
1788 VTOY_JSON_FMT_ARY_BEGIN_N();
1789
1790 for (node = data->list; node; node = node->next)
1791 {
1792 VTOY_JSON_FMT_ITEM_PATH_LN(L2, node->path);
1793 }
1794
1795 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1796 VTOY_JSON_FMT_END(pos);
1797
1798 return pos;
1799 }
1800
1801 int ventoy_data_json_auto_memdisk(data_auto_memdisk *data, char *buf, int buflen)
1802 {
1803 int pos = 0;
1804 int valid = 0;
1805 path_node *node = NULL;
1806
1807 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1808 VTOY_JSON_FMT_ARY_BEGIN();
1809
1810 for (node = data->list; node; node = node->next)
1811 {
1812 VTOY_JSON_FMT_OBJ_BEGIN();
1813
1814 VTOY_JSON_FMT_STRN("path", node->path);
1815 valid = ventoy_check_fuzzy_path(node->path, 1);
1816 VTOY_JSON_FMT_SINT("valid", valid);
1817
1818 VTOY_JSON_FMT_OBJ_ENDEX();
1819 }
1820
1821 VTOY_JSON_FMT_ARY_END();
1822 VTOY_JSON_FMT_END(pos);
1823
1824 return pos;
1825 }
1826
1827 static int ventoy_api_get_auto_memdisk(struct mg_connection *conn, VTOY_JSON *json)
1828 {
1829 api_get_func(conn, json, auto_memdisk);
1830 return 0;
1831 }
1832
1833 static int ventoy_api_save_auto_memdisk(struct mg_connection *conn, VTOY_JSON *json)
1834 {
1835 int ret;
1836
1837 ret = ventoy_data_save_all();
1838
1839 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1840 return 0;
1841 }
1842
1843 static int ventoy_api_auto_memdisk_add(struct mg_connection *conn, VTOY_JSON *json)
1844 {
1845 int ret;
1846 int index = 0;
1847 const char *path = NULL;
1848 path_node *node = NULL;
1849 path_node *cur = NULL;
1850 data_auto_memdisk *data = NULL;
1851
1852 vtoy_json_get_int(json, "index", &index);
1853 data = g_data_auto_memdisk + index;
1854
1855 path = VTOY_JSON_STR_EX("path");
1856 if (path)
1857 {
1858 if (ventoy_is_real_exist_common(path, data->list, path_node))
1859 {
1860 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
1861 return 0;
1862 }
1863
1864 node = zalloc(sizeof(path_node));
1865 if (node)
1866 {
1867 scnprintf(node->path, sizeof(node->path), "%s", path);
1868 vtoy_list_add(data->list, cur, node);
1869 }
1870 }
1871
1872 ret = ventoy_data_save_all();
1873
1874 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1875 return 0;
1876 }
1877
1878 static int ventoy_api_auto_memdisk_del(struct mg_connection *conn, VTOY_JSON *json)
1879 {
1880 int ret;
1881 int index = 0;
1882 const char *path = NULL;
1883 path_node *last = NULL;
1884 path_node *node = NULL;
1885 data_auto_memdisk *data = NULL;
1886
1887 vtoy_json_get_int(json, "index", &index);
1888 data = g_data_auto_memdisk + index;
1889
1890 path = VTOY_JSON_STR_EX("path");
1891 if (path)
1892 {
1893 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
1894 {
1895 vtoy_list_free(path_node, data->list);
1896 }
1897 else
1898 {
1899 vtoy_list_del(last, node, data->list, path);
1900 }
1901 }
1902
1903 ret = ventoy_data_save_all();
1904
1905 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
1906 return 0;
1907 }
1908
1909 #if 0
1910 #endif
1911
1912 void ventoy_data_default_image_list(data_image_list *data)
1913 {
1914 memset(data, 0, sizeof(data_image_list));
1915 }
1916
1917 int ventoy_data_cmp_image_list(data_image_list *data1, data_image_list *data2)
1918 {
1919 if (data1->type != data2->type)
1920 {
1921 if (data1->list || data2->list)
1922 {
1923 return 1;
1924 }
1925 else
1926 {
1927 return 0;
1928 }
1929 }
1930
1931 return ventoy_path_list_cmp(data1->list, data2->list);
1932 }
1933
1934 int ventoy_data_save_image_list(data_image_list *data, const char *title, char *buf, int buflen)
1935 {
1936 int pos = 0;
1937 int prelen;
1938 path_node *node = NULL;
1939 char newtitle[64];
1940
1941 (void)title;
1942
1943 if (!(data->list))
1944 {
1945 return 0;
1946 }
1947
1948 prelen = (int)strlen("image_list");
1949
1950 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1951
1952 if (data->type == 0)
1953 {
1954 scnprintf(newtitle, sizeof(newtitle), "image_list%s", title + prelen);
1955 }
1956 else
1957 {
1958 scnprintf(newtitle, sizeof(newtitle), "image_blacklist%s", title + prelen);
1959 }
1960 VTOY_JSON_FMT_KEY_L(L1, newtitle);
1961
1962 VTOY_JSON_FMT_ARY_BEGIN_N();
1963
1964 for (node = data->list; node; node = node->next)
1965 {
1966 VTOY_JSON_FMT_ITEM_PATH_LN(L2, node->path);
1967 }
1968
1969 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
1970 VTOY_JSON_FMT_END(pos);
1971
1972 return pos;
1973 }
1974
1975 int ventoy_data_json_image_list(data_image_list *data, char *buf, int buflen)
1976 {
1977 int pos = 0;
1978 int valid = 0;
1979 path_node *node = NULL;
1980
1981 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
1982
1983 VTOY_JSON_FMT_OBJ_BEGIN();
1984 VTOY_JSON_FMT_SINT("type", data->type);
1985
1986 VTOY_JSON_FMT_KEY("list");
1987 VTOY_JSON_FMT_ARY_BEGIN();
1988
1989 for (node = data->list; node; node = node->next)
1990 {
1991 VTOY_JSON_FMT_OBJ_BEGIN();
1992
1993 VTOY_JSON_FMT_STRN("path", node->path);
1994 valid = ventoy_check_fuzzy_path(node->path, 1);
1995 VTOY_JSON_FMT_SINT("valid", valid);
1996
1997 VTOY_JSON_FMT_OBJ_ENDEX();
1998 }
1999
2000 VTOY_JSON_FMT_ARY_ENDEX();
2001 VTOY_JSON_FMT_OBJ_END();
2002
2003 VTOY_JSON_FMT_END(pos);
2004
2005 return pos;
2006 }
2007
2008 static int ventoy_api_get_image_list(struct mg_connection *conn, VTOY_JSON *json)
2009 {
2010 api_get_func(conn, json, image_list);
2011 return 0;
2012 }
2013
2014 static int ventoy_api_save_image_list(struct mg_connection *conn, VTOY_JSON *json)
2015 {
2016 int ret;
2017 int index = 0;
2018 data_image_list *data = NULL;
2019
2020 vtoy_json_get_int(json, "index", &index);
2021 data = g_data_image_list + index;
2022
2023 VTOY_JSON_INT("type", data->type);
2024
2025 ret = ventoy_data_save_all();
2026
2027 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2028 return 0;
2029 }
2030
2031 static int ventoy_api_image_list_add(struct mg_connection *conn, VTOY_JSON *json)
2032 {
2033 int ret;
2034 int index = 0;
2035 const char *path = NULL;
2036 path_node *node = NULL;
2037 path_node *cur = NULL;
2038 data_image_list *data = NULL;
2039
2040 vtoy_json_get_int(json, "index", &index);
2041 data = g_data_image_list + index;
2042
2043 path = VTOY_JSON_STR_EX("path");
2044 if (path)
2045 {
2046 if (ventoy_is_real_exist_common(path, data->list, path_node))
2047 {
2048 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
2049 return 0;
2050 }
2051
2052 node = zalloc(sizeof(path_node));
2053 if (node)
2054 {
2055 scnprintf(node->path, sizeof(node->path), "%s", path);
2056 vtoy_list_add(data->list, cur, node);
2057 }
2058 }
2059
2060 ret = ventoy_data_save_all();
2061
2062 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2063 return 0;
2064 }
2065
2066 static int ventoy_api_image_list_del(struct mg_connection *conn, VTOY_JSON *json)
2067 {
2068 int ret;
2069 int index = 0;
2070 const char *path = NULL;
2071 path_node *last = NULL;
2072 path_node *node = NULL;
2073 data_image_list *data = NULL;
2074
2075 vtoy_json_get_int(json, "index", &index);
2076 data = g_data_image_list + index;
2077
2078 path = VTOY_JSON_STR_EX("path");
2079 if (path)
2080 {
2081 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
2082 {
2083 vtoy_list_free(path_node, data->list);
2084 }
2085 else
2086 {
2087 vtoy_list_del(last, node, data->list, path);
2088 }
2089 }
2090
2091 ret = ventoy_data_save_all();
2092
2093 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2094 return 0;
2095 }
2096
2097 #if 0
2098 #endif
2099
2100 void ventoy_data_default_password(data_password *data)
2101 {
2102 memset(data, 0, sizeof(data_password));
2103 }
2104
2105 int ventoy_data_cmp_password(data_password *data1, data_password *data2)
2106 {
2107 menu_password *list1 = NULL;
2108 menu_password *list2 = NULL;
2109
2110 if (strcmp(data1->bootpwd, data2->bootpwd) ||
2111 strcmp(data1->isopwd, data2->isopwd) ||
2112 strcmp(data1->wimpwd, data2->wimpwd) ||
2113 strcmp(data1->vhdpwd, data2->vhdpwd) ||
2114 strcmp(data1->imgpwd, data2->imgpwd) ||
2115 strcmp(data1->efipwd, data2->efipwd) ||
2116 strcmp(data1->vtoypwd, data2->vtoypwd)
2117 )
2118 {
2119 return 1;
2120 }
2121
2122 if (NULL == data1->list && NULL == data2->list)
2123 {
2124 return 0;
2125 }
2126 else if (data1->list && data2->list)
2127 {
2128 list1 = data1->list;
2129 list2 = data2->list;
2130
2131 while (list1 && list2)
2132 {
2133 if ((list1->type != list2->type) || strcmp(list1->path, list2->path))
2134 {
2135 return 1;
2136 }
2137
2138 list1 = list1->next;
2139 list2 = list2->next;
2140 }
2141
2142 if (list1 == NULL && list2 == NULL)
2143 {
2144 return 0;
2145 }
2146 return 1;
2147 }
2148 else
2149 {
2150 return 1;
2151 }
2152
2153 return 0;
2154 }
2155
2156
2157 int ventoy_data_save_password(data_password *data, const char *title, char *buf, int buflen)
2158 {
2159 int pos = 0;
2160 menu_password *node = NULL;
2161 data_password *def = g_data_password + bios_max;
2162
2163 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2164 VTOY_JSON_FMT_KEY_L(L1, title);
2165 VTOY_JSON_FMT_OBJ_BEGIN_N();
2166
2167 VTOY_JSON_FMT_DIFF_STRN(L2, "bootpwd", bootpwd);
2168 VTOY_JSON_FMT_DIFF_STRN(L2, "isopwd", isopwd);
2169 VTOY_JSON_FMT_DIFF_STRN(L2, "wimpwd", wimpwd);
2170 VTOY_JSON_FMT_DIFF_STRN(L2, "vhdpwd", vhdpwd);
2171 VTOY_JSON_FMT_DIFF_STRN(L2, "imgpwd", imgpwd);
2172 VTOY_JSON_FMT_DIFF_STRN(L2, "efipwd", efipwd);
2173 VTOY_JSON_FMT_DIFF_STRN(L2, "vtoypwd", vtoypwd);
2174
2175 if (data->list)
2176 {
2177 VTOY_JSON_FMT_KEY_L(L2, "menupwd");
2178 VTOY_JSON_FMT_ARY_BEGIN_N();
2179
2180 for (node = data->list; node; node = node->next)
2181 {
2182 VTOY_JSON_FMT_OBJ_BEGIN_LN(L3);
2183
2184 if (node->type == 0)
2185 {
2186 VTOY_JSON_FMT_STRN_PATH_LN(L4, "file", node->path);
2187 }
2188 else
2189 {
2190 VTOY_JSON_FMT_STRN_PATH_LN(L4, "parent", node->path);
2191 }
2192 VTOY_JSON_FMT_STRN_LN(L4, "pwd", node->pwd);
2193
2194 VTOY_JSON_FMT_OBJ_ENDEX_LN(L3);
2195 }
2196
2197 VTOY_JSON_FMT_ARY_ENDEX_LN(L2);
2198 }
2199
2200 VTOY_JSON_FMT_OBJ_ENDEX_LN(L1);
2201
2202 VTOY_JSON_FMT_END(pos);
2203
2204 return pos;
2205 }
2206
2207
2208 int ventoy_data_json_password(data_password *data, char *buf, int buflen)
2209 {
2210 int pos = 0;
2211 int valid = 0;
2212 menu_password *node = NULL;
2213
2214 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2215
2216 VTOY_JSON_FMT_OBJ_BEGIN();
2217
2218 VTOY_JSON_FMT_STRN("bootpwd", data->bootpwd);
2219 VTOY_JSON_FMT_STRN("isopwd", data->isopwd);
2220 VTOY_JSON_FMT_STRN("wimpwd", data->wimpwd);
2221 VTOY_JSON_FMT_STRN("vhdpwd", data->vhdpwd);
2222 VTOY_JSON_FMT_STRN("imgpwd", data->imgpwd);
2223 VTOY_JSON_FMT_STRN("efipwd", data->efipwd);
2224 VTOY_JSON_FMT_STRN("vtoypwd", data->vtoypwd);
2225
2226 VTOY_JSON_FMT_KEY("list");
2227 VTOY_JSON_FMT_ARY_BEGIN();
2228
2229 for (node = data->list; node; node = node->next)
2230 {
2231 VTOY_JSON_FMT_OBJ_BEGIN();
2232
2233 VTOY_JSON_FMT_SINT("type", node->type);
2234 VTOY_JSON_FMT_STRN("path", node->path);
2235 if (node->type == path_type_file)
2236 {
2237 valid = ventoy_check_fuzzy_path(node->path, 1);
2238 }
2239 else
2240 {
2241 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
2242 }
2243
2244 VTOY_JSON_FMT_SINT("valid", valid);
2245 VTOY_JSON_FMT_STRN("pwd", node->pwd);
2246
2247 VTOY_JSON_FMT_OBJ_ENDEX();
2248 }
2249
2250 VTOY_JSON_FMT_ARY_ENDEX();
2251
2252 VTOY_JSON_FMT_OBJ_END();
2253 VTOY_JSON_FMT_END(pos);
2254
2255 return pos;
2256 }
2257
2258 static int ventoy_api_get_password(struct mg_connection *conn, VTOY_JSON *json)
2259 {
2260 api_get_func(conn, json, password);
2261 return 0;
2262 }
2263
2264 static int ventoy_api_save_password(struct mg_connection *conn, VTOY_JSON *json)
2265 {
2266 int ret;
2267 int index = 0;
2268 data_password *data = NULL;
2269
2270 vtoy_json_get_int(json, "index", &index);
2271 data = g_data_password + index;
2272
2273 VTOY_JSON_STR("bootpwd", data->bootpwd);
2274 VTOY_JSON_STR("isopwd", data->isopwd);
2275 VTOY_JSON_STR("wimpwd", data->wimpwd);
2276 VTOY_JSON_STR("vhdpwd", data->vhdpwd);
2277 VTOY_JSON_STR("imgpwd", data->imgpwd);
2278 VTOY_JSON_STR("efipwd", data->efipwd);
2279 VTOY_JSON_STR("vtoypwd", data->vtoypwd);
2280
2281 ret = ventoy_data_save_all();
2282
2283 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2284 return 0;
2285 }
2286
2287 static int ventoy_api_password_add(struct mg_connection *conn, VTOY_JSON *json)
2288 {
2289 int ret;
2290 int index = 0;
2291 int type = 0;
2292 const char *path = NULL;
2293 const char *pwd = NULL;
2294 menu_password *node = NULL;
2295 menu_password *cur = NULL;
2296 data_password *data = NULL;
2297
2298 vtoy_json_get_int(json, "index", &index);
2299 data = g_data_password + index;
2300
2301 vtoy_json_get_int(json, "type", &type);
2302
2303 path = VTOY_JSON_STR_EX("path");
2304 pwd = VTOY_JSON_STR_EX("pwd");
2305 if (path && pwd)
2306 {
2307 if (ventoy_is_real_exist_common(path, data->list, menu_password))
2308 {
2309 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
2310 return 0;
2311 }
2312
2313 node = zalloc(sizeof(menu_password));
2314 if (node)
2315 {
2316 node->type = type;
2317 scnprintf(node->path, sizeof(node->path), "%s", path);
2318 scnprintf(node->pwd, sizeof(node->pwd), "%s", pwd);
2319
2320 vtoy_list_add(data->list, cur, node);
2321 }
2322 }
2323
2324 ret = ventoy_data_save_all();
2325
2326 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2327 return 0;
2328 }
2329
2330 static int ventoy_api_password_del(struct mg_connection *conn, VTOY_JSON *json)
2331 {
2332 int ret;
2333 int index = 0;
2334 const char *path = NULL;
2335 menu_password *last = NULL;
2336 menu_password *node = NULL;
2337 data_password *data = NULL;
2338
2339 vtoy_json_get_int(json, "index", &index);
2340 data = g_data_password + index;
2341
2342 path = VTOY_JSON_STR_EX("path");
2343 if (path)
2344 {
2345 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
2346 {
2347 vtoy_list_free(menu_password, data->list);
2348 }
2349 else
2350 {
2351 vtoy_list_del(last, node, data->list, path);
2352 }
2353 }
2354
2355 ret = ventoy_data_save_all();
2356
2357 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2358 return 0;
2359 }
2360
2361 #if 0
2362 #endif
2363
2364 void ventoy_data_default_conf_replace(data_conf_replace *data)
2365 {
2366 memset(data, 0, sizeof(data_conf_replace));
2367 }
2368
2369 int ventoy_data_cmp_conf_replace(data_conf_replace *data1, data_conf_replace *data2)
2370 {
2371 conf_replace_node *list1 = NULL;
2372 conf_replace_node *list2 = NULL;
2373
2374 if (NULL == data1->list && NULL == data2->list)
2375 {
2376 return 0;
2377 }
2378 else if (data1->list && data2->list)
2379 {
2380 list1 = data1->list;
2381 list2 = data2->list;
2382
2383 while (list1 && list2)
2384 {
2385 if (list1->image != list2->image ||
2386 strcmp(list1->path, list2->path) ||
2387 strcmp(list1->org, list2->org) ||
2388 strcmp(list1->new, list2->new)
2389 )
2390 {
2391 return 1;
2392 }
2393
2394 list1 = list1->next;
2395 list2 = list2->next;
2396 }
2397
2398 if (list1 == NULL && list2 == NULL)
2399 {
2400 return 0;
2401 }
2402 return 1;
2403 }
2404 else
2405 {
2406 return 1;
2407 }
2408
2409 return 0;
2410 }
2411
2412
2413 int ventoy_data_save_conf_replace(data_conf_replace *data, const char *title, char *buf, int buflen)
2414 {
2415 int pos = 0;
2416 conf_replace_node *node = NULL;
2417
2418 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2419
2420 VTOY_JSON_FMT_KEY_L(L1, title);
2421 VTOY_JSON_FMT_ARY_BEGIN_N();
2422
2423 for (node = data->list; node; node = node->next)
2424 {
2425 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2426
2427 VTOY_JSON_FMT_STRN_PATH_LN(L3, "iso", node->path);
2428 VTOY_JSON_FMT_STRN_LN(L3, "org", node->org);
2429 VTOY_JSON_FMT_STRN_PATH_LN(L3, "new", node->new);
2430 if (node->image)
2431 {
2432 VTOY_JSON_FMT_SINT_LN(L3, "img", node->image);
2433 }
2434
2435 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2436 }
2437
2438 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2439 VTOY_JSON_FMT_END(pos);
2440
2441 return pos;
2442 }
2443
2444
2445 int ventoy_data_json_conf_replace(data_conf_replace *data, char *buf, int buflen)
2446 {
2447 int pos = 0;
2448 conf_replace_node *node = NULL;
2449
2450 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2451 VTOY_JSON_FMT_ARY_BEGIN();
2452
2453 for (node = data->list; node; node = node->next)
2454 {
2455 VTOY_JSON_FMT_OBJ_BEGIN();
2456
2457 VTOY_JSON_FMT_STRN("path", node->path);
2458 VTOY_JSON_FMT_SINT("valid", ventoy_check_fuzzy_path(node->path, 1));
2459 VTOY_JSON_FMT_STRN("org", node->org);
2460 VTOY_JSON_FMT_STRN("new", node->new);
2461 VTOY_JSON_FMT_SINT("new_valid", ventoy_is_file_exist("%s%s", g_cur_dir, node->new));
2462 VTOY_JSON_FMT_SINT("img", node->image);
2463
2464 VTOY_JSON_FMT_OBJ_ENDEX();
2465 }
2466
2467 VTOY_JSON_FMT_ARY_END();
2468 VTOY_JSON_FMT_END(pos);
2469
2470 return pos;
2471 }
2472
2473 static int ventoy_api_get_conf_replace(struct mg_connection *conn, VTOY_JSON *json)
2474 {
2475 api_get_func(conn, json, conf_replace);
2476 return 0;
2477 }
2478
2479 static int ventoy_api_save_conf_replace(struct mg_connection *conn, VTOY_JSON *json)
2480 {
2481 int ret;
2482 ret = ventoy_data_save_all();
2483
2484 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2485 return 0;
2486 }
2487
2488 static int ventoy_api_conf_replace_add(struct mg_connection *conn, VTOY_JSON *json)
2489 {
2490 int ret;
2491 int image = 0;
2492 int index = 0;
2493 const char *path = NULL;
2494 const char *org = NULL;
2495 const char *new = NULL;
2496 conf_replace_node *node = NULL;
2497 conf_replace_node *cur = NULL;
2498 data_conf_replace *data = NULL;
2499
2500 vtoy_json_get_int(json, "img", &image);
2501
2502 vtoy_json_get_int(json, "index", &index);
2503 data = g_data_conf_replace + index;
2504
2505 path = VTOY_JSON_STR_EX("path");
2506 org = VTOY_JSON_STR_EX("org");
2507 new = VTOY_JSON_STR_EX("new");
2508 if (path && org && new)
2509 {
2510 node = zalloc(sizeof(conf_replace_node));
2511 if (node)
2512 {
2513 node->image = image;
2514 scnprintf(node->path, sizeof(node->path), "%s", path);
2515 scnprintf(node->org, sizeof(node->org), "%s", org);
2516 scnprintf(node->new, sizeof(node->new), "%s", new);
2517
2518 vtoy_list_add(data->list, cur, node);
2519 }
2520 }
2521
2522 ret = ventoy_data_save_all();
2523
2524 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2525 return 0;
2526 }
2527
2528 static int ventoy_api_conf_replace_del(struct mg_connection *conn, VTOY_JSON *json)
2529 {
2530 int ret;
2531 int index = 0;
2532 const char *path = NULL;
2533 conf_replace_node *last = NULL;
2534 conf_replace_node *node = NULL;
2535 data_conf_replace *data = NULL;
2536
2537 vtoy_json_get_int(json, "index", &index);
2538 data = g_data_conf_replace + index;
2539
2540 path = VTOY_JSON_STR_EX("path");
2541 if (path)
2542 {
2543 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
2544 {
2545 vtoy_list_free(conf_replace_node, data->list);
2546 }
2547 else
2548 {
2549 vtoy_list_del(last, node, data->list, path);
2550 }
2551 }
2552
2553 ret = ventoy_data_save_all();
2554
2555 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2556 return 0;
2557 }
2558
2559
2560 #if 0
2561 #endif
2562
2563 void ventoy_data_default_dud(data_dud *data)
2564 {
2565 memset(data, 0, sizeof(data_dud));
2566 }
2567
2568 int ventoy_data_cmp_dud(data_dud *data1, data_dud *data2)
2569 {
2570 dud_node *list1 = NULL;
2571 dud_node *list2 = NULL;
2572
2573 if (NULL == data1->list && NULL == data2->list)
2574 {
2575 return 0;
2576 }
2577 else if (data1->list && data2->list)
2578 {
2579 list1 = data1->list;
2580 list2 = data2->list;
2581
2582 while (list1 && list2)
2583 {
2584 if (strcmp(list1->path, list2->path))
2585 {
2586 return 1;
2587 }
2588
2589 /* no need to compare dud list with default */
2590 list1 = list1->next;
2591 list2 = list2->next;
2592 }
2593
2594 if (list1 == NULL && list2 == NULL)
2595 {
2596 return 0;
2597 }
2598 return 1;
2599 }
2600 else
2601 {
2602 return 1;
2603 }
2604
2605 return 0;
2606 }
2607
2608
2609 int ventoy_data_save_dud(data_dud *data, const char *title, char *buf, int buflen)
2610 {
2611 int pos = 0;
2612 dud_node *node = NULL;
2613 path_node *pathnode = NULL;
2614
2615 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2616
2617 VTOY_JSON_FMT_KEY_L(L1, title);
2618 VTOY_JSON_FMT_ARY_BEGIN_N();
2619
2620 for (node = data->list; node; node = node->next)
2621 {
2622 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2623 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
2624
2625 VTOY_JSON_FMT_KEY_L(L3, "dud");
2626 VTOY_JSON_FMT_ARY_BEGIN_N();
2627 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2628 {
2629 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
2630 }
2631 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
2632
2633 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2634 }
2635
2636 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2637 VTOY_JSON_FMT_END(pos);
2638
2639 return pos;
2640 }
2641
2642
2643 int ventoy_data_json_dud(data_dud *data, char *buf, int buflen)
2644 {
2645 int pos = 0;
2646 int valid = 0;
2647 dud_node *node = NULL;
2648 path_node *pathnode = NULL;
2649
2650 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2651 VTOY_JSON_FMT_ARY_BEGIN();
2652
2653 for (node = data->list; node; node = node->next)
2654 {
2655 VTOY_JSON_FMT_OBJ_BEGIN();
2656
2657 VTOY_JSON_FMT_STRN("path", node->path);
2658 valid = ventoy_check_fuzzy_path(node->path, 1);
2659 VTOY_JSON_FMT_SINT("valid", valid);
2660
2661
2662 VTOY_JSON_FMT_KEY("list");
2663 VTOY_JSON_FMT_ARY_BEGIN();
2664 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2665 {
2666 VTOY_JSON_FMT_OBJ_BEGIN();
2667 VTOY_JSON_FMT_STRN("path", pathnode->path);
2668
2669 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
2670 VTOY_JSON_FMT_SINT("valid", valid);
2671 VTOY_JSON_FMT_OBJ_ENDEX();
2672 }
2673 VTOY_JSON_FMT_ARY_ENDEX();
2674
2675
2676 VTOY_JSON_FMT_OBJ_ENDEX();
2677 }
2678
2679 VTOY_JSON_FMT_ARY_END();
2680 VTOY_JSON_FMT_END(pos);
2681
2682 return pos;
2683 }
2684
2685 static int ventoy_api_get_dud(struct mg_connection *conn, VTOY_JSON *json)
2686 {
2687 api_get_func(conn, json, dud);
2688 return 0;
2689 }
2690
2691 static int ventoy_api_save_dud(struct mg_connection *conn, VTOY_JSON *json)
2692 {
2693 int ret;
2694 ret = ventoy_data_save_all();
2695
2696 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2697 return 0;
2698 }
2699
2700
2701 static int ventoy_api_dud_add(struct mg_connection *conn, VTOY_JSON *json)
2702 {
2703 int ret;
2704 int index = 0;
2705 const char *path = NULL;
2706 dud_node *node = NULL;
2707 dud_node *cur = NULL;
2708 data_dud *data = NULL;
2709 VTOY_JSON *array = NULL;
2710
2711 vtoy_json_get_int(json, "index", &index);
2712 data = g_data_dud + index;
2713
2714 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "dud");
2715 path = VTOY_JSON_STR_EX("path");
2716 if (path && array)
2717 {
2718 if (ventoy_is_real_exist_common(path, data->list, dud_node))
2719 {
2720 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
2721 return 0;
2722 }
2723
2724 node = zalloc(sizeof(dud_node));
2725 if (node)
2726 {
2727 scnprintf(node->path, sizeof(node->path), "%s", path);
2728 node->list = ventoy_path_node_add_array(array);
2729
2730 vtoy_list_add(data->list, cur, node);
2731 }
2732 }
2733
2734 ret = ventoy_data_save_all();
2735
2736 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2737 return 0;
2738 }
2739
2740 static int ventoy_api_dud_del(struct mg_connection *conn, VTOY_JSON *json)
2741 {
2742 int ret;
2743 int index = 0;
2744 const char *path = NULL;
2745 dud_node *next = NULL;
2746 dud_node *last = NULL;
2747 dud_node *node = NULL;
2748 data_dud *data = NULL;
2749
2750 vtoy_json_get_int(json, "index", &index);
2751 data = g_data_dud + index;
2752
2753 path = VTOY_JSON_STR_EX("path");
2754 if (path)
2755 {
2756 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
2757 {
2758 for (node = data->list; node; node = next)
2759 {
2760 next = node->next;
2761 ventoy_free_path_node_list(node->list);
2762 free(node);
2763 }
2764 data->list = NULL;
2765 }
2766 else
2767 {
2768 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
2769 }
2770 }
2771
2772 ret = ventoy_data_save_all();
2773
2774 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2775 return 0;
2776 }
2777
2778
2779 static int ventoy_api_dud_add_inner(struct mg_connection *conn, VTOY_JSON *json)
2780 {
2781 int ret;
2782 int index = 0;
2783 const char *path = NULL;
2784 const char *outpath = NULL;
2785 path_node *pcur = NULL;
2786 path_node *pnode = NULL;
2787 dud_node *node = NULL;
2788 data_dud *data = NULL;
2789
2790 vtoy_json_get_int(json, "index", &index);
2791 data = g_data_dud + index;
2792
2793 path = VTOY_JSON_STR_EX("path");
2794 outpath = VTOY_JSON_STR_EX("outpath");
2795 if (path && outpath)
2796 {
2797 for (node = data->list; node; node = node->next)
2798 {
2799 if (strcmp(outpath, node->path) == 0)
2800 {
2801 pnode = zalloc(sizeof(path_node));
2802 if (pnode)
2803 {
2804 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
2805 vtoy_list_add(node->list, pcur, pnode);
2806 }
2807
2808 break;
2809 }
2810 }
2811 }
2812
2813 ret = ventoy_data_save_all();
2814
2815 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2816 return 0;
2817 }
2818
2819 static int ventoy_api_dud_del_inner(struct mg_connection *conn, VTOY_JSON *json)
2820 {
2821 int ret;
2822 int index = 0;
2823 const char *path = NULL;
2824 const char *outpath = NULL;
2825 path_node *plast = NULL;
2826 path_node *pnode = NULL;
2827 dud_node *node = NULL;
2828 data_dud *data = NULL;
2829
2830 vtoy_json_get_int(json, "index", &index);
2831 data = g_data_dud + index;
2832
2833 path = VTOY_JSON_STR_EX("path");
2834 outpath = VTOY_JSON_STR_EX("outpath");
2835 if (path && outpath)
2836 {
2837 for (node = data->list; node; node = node->next)
2838 {
2839 if (strcmp(outpath, node->path) == 0)
2840 {
2841 vtoy_list_del(plast, pnode, node->list, path);
2842 break;
2843 }
2844 }
2845 }
2846
2847 ret = ventoy_data_save_all();
2848
2849 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
2850 return 0;
2851 }
2852
2853
2854 #if 0
2855 #endif
2856
2857 void ventoy_data_default_auto_install(data_auto_install *data)
2858 {
2859 memset(data, 0, sizeof(data_auto_install));
2860 }
2861
2862 int ventoy_data_cmp_auto_install(data_auto_install *data1, data_auto_install *data2)
2863 {
2864 auto_install_node *list1 = NULL;
2865 auto_install_node *list2 = NULL;
2866
2867 if (NULL == data1->list && NULL == data2->list)
2868 {
2869 return 0;
2870 }
2871 else if (data1->list && data2->list)
2872 {
2873 list1 = data1->list;
2874 list2 = data2->list;
2875
2876 while (list1 && list2)
2877 {
2878 if (list1->timeout != list2->timeout ||
2879 list1->autosel != list2->autosel ||
2880 strcmp(list1->path, list2->path))
2881 {
2882 return 1;
2883 }
2884
2885 /* no need to compare auto install list with default */
2886 list1 = list1->next;
2887 list2 = list2->next;
2888 }
2889
2890 if (list1 == NULL && list2 == NULL)
2891 {
2892 return 0;
2893 }
2894 return 1;
2895 }
2896 else
2897 {
2898 return 1;
2899 }
2900
2901 return 0;
2902 }
2903
2904
2905 int ventoy_data_save_auto_install(data_auto_install *data, const char *title, char *buf, int buflen)
2906 {
2907 int pos = 0;
2908 auto_install_node *node = NULL;
2909 path_node *pathnode = NULL;
2910
2911 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2912
2913 VTOY_JSON_FMT_KEY_L(L1, title);
2914 VTOY_JSON_FMT_ARY_BEGIN_N();
2915
2916 for (node = data->list; node; node = node->next)
2917 {
2918 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
2919 if (node->type == 0)
2920 {
2921 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
2922 }
2923 else
2924 {
2925 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
2926 }
2927
2928
2929 VTOY_JSON_FMT_KEY_L(L3, "template");
2930 VTOY_JSON_FMT_ARY_BEGIN_N();
2931 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2932 {
2933 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
2934 }
2935 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
2936
2937 if (node->timeouten)
2938 {
2939 VTOY_JSON_FMT_SINT_LN(L3, "timeout", node->timeout);
2940 }
2941
2942 if (node->autoselen)
2943 {
2944 VTOY_JSON_FMT_SINT_LN(L3, "autosel", node->autosel);
2945 }
2946
2947 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
2948 }
2949
2950 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
2951 VTOY_JSON_FMT_END(pos);
2952
2953 return pos;
2954 }
2955
2956
2957 int ventoy_data_json_auto_install(data_auto_install *data, char *buf, int buflen)
2958 {
2959 int pos = 0;
2960 int valid = 0;
2961 auto_install_node *node = NULL;
2962 path_node *pathnode = NULL;
2963
2964 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
2965 VTOY_JSON_FMT_ARY_BEGIN();
2966
2967 for (node = data->list; node; node = node->next)
2968 {
2969 VTOY_JSON_FMT_OBJ_BEGIN();
2970
2971 VTOY_JSON_FMT_STRN("path", node->path);
2972
2973 if (node->type == 0)
2974 {
2975 valid = ventoy_check_fuzzy_path(node->path, 1);
2976 }
2977 else
2978 {
2979 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
2980 }
2981 VTOY_JSON_FMT_SINT("valid", valid);
2982 VTOY_JSON_FMT_SINT("type", node->type);
2983
2984 VTOY_JSON_FMT_BOOL("timeouten", node->timeouten);
2985 VTOY_JSON_FMT_BOOL("autoselen", node->autoselen);
2986
2987 VTOY_JSON_FMT_SINT("autosel", node->autosel);
2988 VTOY_JSON_FMT_SINT("timeout", node->timeout);
2989
2990 VTOY_JSON_FMT_KEY("list");
2991 VTOY_JSON_FMT_ARY_BEGIN();
2992 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
2993 {
2994 VTOY_JSON_FMT_OBJ_BEGIN();
2995 VTOY_JSON_FMT_STRN("path", pathnode->path);
2996
2997 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
2998 VTOY_JSON_FMT_SINT("valid", valid);
2999 VTOY_JSON_FMT_OBJ_ENDEX();
3000 }
3001 VTOY_JSON_FMT_ARY_ENDEX();
3002
3003
3004 VTOY_JSON_FMT_OBJ_ENDEX();
3005 }
3006
3007 VTOY_JSON_FMT_ARY_END();
3008 VTOY_JSON_FMT_END(pos);
3009
3010 return pos;
3011 }
3012
3013 static int ventoy_api_get_auto_install(struct mg_connection *conn, VTOY_JSON *json)
3014 {
3015 api_get_func(conn, json, auto_install);
3016 return 0;
3017 }
3018
3019 static int ventoy_api_save_auto_install(struct mg_connection *conn, VTOY_JSON *json)
3020 {
3021 int ret;
3022 int id = -1;
3023 int cnt = 0;
3024 int index = 0;
3025 uint8_t timeouten = 0;
3026 uint8_t autoselen = 0;
3027 auto_install_node *node = NULL;
3028 data_auto_install *data = NULL;
3029
3030 vtoy_json_get_int(json, "index", &index);
3031 vtoy_json_get_int(json, "id", &id);
3032
3033 vtoy_json_get_bool(json, "timeouten", &timeouten);
3034 vtoy_json_get_bool(json, "autoselen", &autoselen);
3035
3036 data = g_data_auto_install + index;
3037
3038 if (id >= 0)
3039 {
3040 for (node = data->list; node; node = node->next)
3041 {
3042 if (cnt == id)
3043 {
3044 node->timeouten = (int)timeouten;
3045 node->autoselen = (int)autoselen;
3046 VTOY_JSON_INT("timeout", node->timeout);
3047 VTOY_JSON_INT("autosel", node->autosel);
3048 break;
3049 }
3050 }
3051 }
3052
3053 ret = ventoy_data_save_all();
3054
3055 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3056 return 0;
3057 }
3058
3059
3060 static int ventoy_api_auto_install_add(struct mg_connection *conn, VTOY_JSON *json)
3061 {
3062 int ret;
3063 int index = 0;
3064 int type = 0;
3065 const char *path = NULL;
3066 auto_install_node *node = NULL;
3067 auto_install_node *cur = NULL;
3068 data_auto_install *data = NULL;
3069 VTOY_JSON *array = NULL;
3070
3071 vtoy_json_get_int(json, "type", &type);
3072 vtoy_json_get_int(json, "index", &index);
3073 data = g_data_auto_install + index;
3074
3075 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "template");
3076 path = VTOY_JSON_STR_EX("path");
3077 if (path && array)
3078 {
3079 if (ventoy_is_real_exist_common(path, data->list, auto_install_node))
3080 {
3081 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
3082 return 0;
3083 }
3084
3085 node = zalloc(sizeof(auto_install_node));
3086 if (node)
3087 {
3088 node->type = type;
3089 node->timeouten = 0;
3090 node->autoselen = 0;
3091 node->autosel = 1;
3092 node->timeout = 0;
3093 scnprintf(node->path, sizeof(node->path), "%s", path);
3094 node->list = ventoy_path_node_add_array(array);
3095
3096 vtoy_list_add(data->list, cur, node);
3097 }
3098 }
3099
3100 ret = ventoy_data_save_all();
3101
3102 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3103 return 0;
3104 }
3105
3106 static int ventoy_api_auto_install_del(struct mg_connection *conn, VTOY_JSON *json)
3107 {
3108 int ret;
3109 int index = 0;
3110 const char *path = NULL;
3111 auto_install_node *last = NULL;
3112 auto_install_node *next = NULL;
3113 auto_install_node *node = NULL;
3114 data_auto_install *data = NULL;
3115
3116 vtoy_json_get_int(json, "index", &index);
3117 data = g_data_auto_install + index;
3118
3119 path = VTOY_JSON_STR_EX("path");
3120 if (path)
3121 {
3122 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
3123 {
3124 for (node = data->list; node; node = next)
3125 {
3126 next = node->next;
3127 ventoy_free_path_node_list(node->list);
3128 free(node);
3129 }
3130 data->list = NULL;
3131 }
3132 else
3133 {
3134 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
3135 }
3136 }
3137
3138 ret = ventoy_data_save_all();
3139
3140 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3141 return 0;
3142 }
3143
3144 static int ventoy_api_auto_install_add_inner(struct mg_connection *conn, VTOY_JSON *json)
3145 {
3146 int ret;
3147 int index = 0;
3148 const char *path = NULL;
3149 const char *outpath = NULL;
3150 path_node *pcur = NULL;
3151 path_node *pnode = NULL;
3152 auto_install_node *node = NULL;
3153 data_auto_install *data = NULL;
3154
3155 vtoy_json_get_int(json, "index", &index);
3156 data = g_data_auto_install + index;
3157
3158 path = VTOY_JSON_STR_EX("path");
3159 outpath = VTOY_JSON_STR_EX("outpath");
3160 if (path && outpath)
3161 {
3162 for (node = data->list; node; node = node->next)
3163 {
3164 if (strcmp(outpath, node->path) == 0)
3165 {
3166 pnode = zalloc(sizeof(path_node));
3167 if (pnode)
3168 {
3169 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
3170 vtoy_list_add(node->list, pcur, pnode);
3171 }
3172
3173 break;
3174 }
3175 }
3176 }
3177
3178 ret = ventoy_data_save_all();
3179
3180 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3181 return 0;
3182 }
3183
3184 static int ventoy_api_auto_install_del_inner(struct mg_connection *conn, VTOY_JSON *json)
3185 {
3186 int ret;
3187 int index = 0;
3188 const char *path = NULL;
3189 const char *outpath = NULL;
3190 path_node *plast = NULL;
3191 path_node *pnode = NULL;
3192 auto_install_node *node = NULL;
3193 data_auto_install *data = NULL;
3194
3195 vtoy_json_get_int(json, "index", &index);
3196 data = g_data_auto_install + index;
3197
3198 path = VTOY_JSON_STR_EX("path");
3199 outpath = VTOY_JSON_STR_EX("outpath");
3200 if (path && outpath)
3201 {
3202 for (node = data->list; node; node = node->next)
3203 {
3204 if (strcmp(outpath, node->path) == 0)
3205 {
3206 vtoy_list_del(plast, pnode, node->list, path);
3207 break;
3208 }
3209 }
3210 }
3211
3212 ret = ventoy_data_save_all();
3213
3214 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3215 return 0;
3216 }
3217
3218
3219 #if 0
3220 #endif
3221
3222
3223 void ventoy_data_default_persistence(data_persistence *data)
3224 {
3225 memset(data, 0, sizeof(data_persistence));
3226 }
3227
3228 int ventoy_data_cmp_persistence(data_persistence *data1, data_persistence *data2)
3229 {
3230 persistence_node *list1 = NULL;
3231 persistence_node *list2 = NULL;
3232
3233 if (NULL == data1->list && NULL == data2->list)
3234 {
3235 return 0;
3236 }
3237 else if (data1->list && data2->list)
3238 {
3239 list1 = data1->list;
3240 list2 = data2->list;
3241
3242 while (list1 && list2)
3243 {
3244 if (list1->timeout != list2->timeout ||
3245 list1->autosel != list2->autosel ||
3246 strcmp(list1->path, list2->path))
3247 {
3248 return 1;
3249 }
3250
3251 /* no need to compare auto install list with default */
3252 list1 = list1->next;
3253 list2 = list2->next;
3254 }
3255
3256 if (list1 == NULL && list2 == NULL)
3257 {
3258 return 0;
3259 }
3260 return 1;
3261 }
3262 else
3263 {
3264 return 1;
3265 }
3266
3267 return 0;
3268 }
3269
3270
3271 int ventoy_data_save_persistence(data_persistence *data, const char *title, char *buf, int buflen)
3272 {
3273 int pos = 0;
3274 persistence_node *node = NULL;
3275 path_node *pathnode = NULL;
3276
3277 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3278
3279 VTOY_JSON_FMT_KEY_L(L1, title);
3280 VTOY_JSON_FMT_ARY_BEGIN_N();
3281
3282 for (node = data->list; node; node = node->next)
3283 {
3284 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
3285 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
3286 VTOY_JSON_FMT_KEY_L(L3, "backend");
3287 VTOY_JSON_FMT_ARY_BEGIN_N();
3288 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
3289 {
3290 VTOY_JSON_FMT_ITEM_PATH_LN(L4, pathnode->path);
3291 }
3292 VTOY_JSON_FMT_ARY_ENDEX_LN(L3);
3293
3294 if (node->timeouten)
3295 {
3296 VTOY_JSON_FMT_SINT_LN(L3, "timeout", node->timeout);
3297 }
3298
3299 if (node->autoselen)
3300 {
3301 VTOY_JSON_FMT_SINT_LN(L3, "autosel", node->autosel);
3302 }
3303
3304 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
3305 }
3306
3307 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
3308 VTOY_JSON_FMT_END(pos);
3309
3310 return pos;
3311 }
3312
3313
3314 int ventoy_data_json_persistence(data_persistence *data, char *buf, int buflen)
3315 {
3316 int pos = 0;
3317 int valid = 0;
3318 persistence_node *node = NULL;
3319 path_node *pathnode = NULL;
3320
3321 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3322 VTOY_JSON_FMT_ARY_BEGIN();
3323
3324 for (node = data->list; node; node = node->next)
3325 {
3326 VTOY_JSON_FMT_OBJ_BEGIN();
3327
3328 VTOY_JSON_FMT_STRN("path", node->path);
3329
3330 valid = ventoy_check_fuzzy_path(node->path, 1);
3331 VTOY_JSON_FMT_SINT("valid", valid);
3332 VTOY_JSON_FMT_SINT("type", node->type);
3333
3334 VTOY_JSON_FMT_BOOL("timeouten", node->timeouten);
3335 VTOY_JSON_FMT_BOOL("autoselen", node->autoselen);
3336
3337 VTOY_JSON_FMT_SINT("autosel", node->autosel);
3338 VTOY_JSON_FMT_SINT("timeout", node->timeout);
3339
3340 VTOY_JSON_FMT_KEY("list");
3341 VTOY_JSON_FMT_ARY_BEGIN();
3342 for (pathnode = node->list; pathnode; pathnode = pathnode->next)
3343 {
3344 VTOY_JSON_FMT_OBJ_BEGIN();
3345 VTOY_JSON_FMT_STRN("path", pathnode->path);
3346
3347 valid = ventoy_is_file_exist("%s%s", g_cur_dir, pathnode->path);
3348 VTOY_JSON_FMT_SINT("valid", valid);
3349 VTOY_JSON_FMT_OBJ_ENDEX();
3350 }
3351 VTOY_JSON_FMT_ARY_ENDEX();
3352
3353
3354 VTOY_JSON_FMT_OBJ_ENDEX();
3355 }
3356
3357 VTOY_JSON_FMT_ARY_END();
3358 VTOY_JSON_FMT_END(pos);
3359
3360 return pos;
3361 }
3362
3363 static int ventoy_api_get_persistence(struct mg_connection *conn, VTOY_JSON *json)
3364 {
3365 api_get_func(conn, json, persistence);
3366 return 0;
3367 }
3368
3369 static int ventoy_api_save_persistence(struct mg_connection *conn, VTOY_JSON *json)
3370 {
3371 int ret;
3372 int id = -1;
3373 int cnt = 0;
3374 int index = 0;
3375 uint8_t timeouten = 0;
3376 uint8_t autoselen = 0;
3377 persistence_node *node = NULL;
3378 data_persistence *data = NULL;
3379
3380 vtoy_json_get_int(json, "index", &index);
3381 vtoy_json_get_int(json, "id", &id);
3382
3383 vtoy_json_get_bool(json, "timeouten", &timeouten);
3384 vtoy_json_get_bool(json, "autoselen", &autoselen);
3385
3386 data = g_data_persistence + index;
3387
3388 if (id >= 0)
3389 {
3390 for (node = data->list; node; node = node->next)
3391 {
3392 if (cnt == id)
3393 {
3394 node->timeouten = (int)timeouten;
3395 node->autoselen = (int)autoselen;
3396 VTOY_JSON_INT("timeout", node->timeout);
3397 VTOY_JSON_INT("autosel", node->autosel);
3398 break;
3399 }
3400 }
3401 }
3402
3403 ret = ventoy_data_save_all();
3404
3405 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3406 return 0;
3407 }
3408
3409
3410 static int ventoy_api_persistence_add(struct mg_connection *conn, VTOY_JSON *json)
3411 {
3412 int ret;
3413 int index = 0;
3414 const char *path = NULL;
3415 persistence_node *node = NULL;
3416 persistence_node *cur = NULL;
3417 data_persistence *data = NULL;
3418 VTOY_JSON *array = NULL;
3419
3420 vtoy_json_get_int(json, "index", &index);
3421 data = g_data_persistence + index;
3422
3423 array = vtoy_json_find_item(json, JSON_TYPE_ARRAY, "backend");
3424 path = VTOY_JSON_STR_EX("path");
3425 if (path && array)
3426 {
3427 if (ventoy_is_real_exist_common(path, data->list, persistence_node))
3428 {
3429 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
3430 return 0;
3431 }
3432
3433 node = zalloc(sizeof(persistence_node));
3434 if (node)
3435 {
3436 node->timeouten = 0;
3437 node->autoselen = 0;
3438 node->autosel = 1;
3439 node->timeout = 0;
3440 scnprintf(node->path, sizeof(node->path), "%s", path);
3441 node->list = ventoy_path_node_add_array(array);
3442
3443 vtoy_list_add(data->list, cur, node);
3444 }
3445 }
3446
3447 ret = ventoy_data_save_all();
3448
3449 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3450 return 0;
3451 }
3452
3453 static int ventoy_api_persistence_del(struct mg_connection *conn, VTOY_JSON *json)
3454 {
3455 int ret;
3456 int index = 0;
3457 const char *path = NULL;
3458 persistence_node *last = NULL;
3459 persistence_node *next = NULL;
3460 persistence_node *node = NULL;
3461 data_persistence *data = NULL;
3462
3463 vtoy_json_get_int(json, "index", &index);
3464 data = g_data_persistence + index;
3465
3466 path = VTOY_JSON_STR_EX("path");
3467 if (path)
3468 {
3469 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
3470 {
3471 for (node = data->list; node; node = next)
3472 {
3473 next = node->next;
3474 ventoy_free_path_node_list(node->list);
3475 free(node);
3476 }
3477 data->list = NULL;
3478 }
3479 else
3480 {
3481 vtoy_list_del_ex(last, node, data->list, path, ventoy_free_path_node_list);
3482 }
3483 }
3484
3485 ret = ventoy_data_save_all();
3486
3487 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3488 return 0;
3489 }
3490
3491 static int ventoy_api_persistence_add_inner(struct mg_connection *conn, VTOY_JSON *json)
3492 {
3493 int ret;
3494 int index = 0;
3495 const char *path = NULL;
3496 const char *outpath = NULL;
3497 path_node *pcur = NULL;
3498 path_node *pnode = NULL;
3499 persistence_node *node = NULL;
3500 data_persistence *data = NULL;
3501
3502 vtoy_json_get_int(json, "index", &index);
3503 data = g_data_persistence + index;
3504
3505 path = VTOY_JSON_STR_EX("path");
3506 outpath = VTOY_JSON_STR_EX("outpath");
3507 if (path && outpath)
3508 {
3509 for (node = data->list; node; node = node->next)
3510 {
3511 if (strcmp(outpath, node->path) == 0)
3512 {
3513 pnode = zalloc(sizeof(path_node));
3514 if (pnode)
3515 {
3516 scnprintf(pnode->path, sizeof(pnode->path), "%s", path);
3517 vtoy_list_add(node->list, pcur, pnode);
3518 }
3519
3520 break;
3521 }
3522 }
3523 }
3524
3525 ret = ventoy_data_save_all();
3526
3527 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3528 return 0;
3529 }
3530
3531 static int ventoy_api_persistence_del_inner(struct mg_connection *conn, VTOY_JSON *json)
3532 {
3533 int ret;
3534 int index = 0;
3535 const char *path = NULL;
3536 const char *outpath = NULL;
3537 path_node *plast = NULL;
3538 path_node *pnode = NULL;
3539 persistence_node *node = NULL;
3540 data_persistence *data = NULL;
3541
3542 vtoy_json_get_int(json, "index", &index);
3543 data = g_data_persistence + index;
3544
3545 path = VTOY_JSON_STR_EX("path");
3546 outpath = VTOY_JSON_STR_EX("outpath");
3547 if (path && outpath)
3548 {
3549 for (node = data->list; node; node = node->next)
3550 {
3551 if (strcmp(outpath, node->path) == 0)
3552 {
3553 vtoy_list_del(plast, pnode, node->list, path);
3554 break;
3555 }
3556 }
3557 }
3558
3559 ret = ventoy_data_save_all();
3560
3561 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3562 return 0;
3563 }
3564
3565
3566 #if 0
3567 #endif
3568
3569 void ventoy_data_default_injection(data_injection *data)
3570 {
3571 memset(data, 0, sizeof(data_injection));
3572 }
3573
3574 int ventoy_data_cmp_injection(data_injection *data1, data_injection *data2)
3575 {
3576 injection_node *list1 = NULL;
3577 injection_node *list2 = NULL;
3578
3579 if (NULL == data1->list && NULL == data2->list)
3580 {
3581 return 0;
3582 }
3583 else if (data1->list && data2->list)
3584 {
3585 list1 = data1->list;
3586 list2 = data2->list;
3587
3588 while (list1 && list2)
3589 {
3590 if ((list1->type != list2->type) ||
3591 strcmp(list1->path, list2->path) ||
3592 strcmp(list1->archive, list2->archive))
3593 {
3594 return 1;
3595 }
3596
3597 list1 = list1->next;
3598 list2 = list2->next;
3599 }
3600
3601 if (list1 == NULL && list2 == NULL)
3602 {
3603 return 0;
3604 }
3605 return 1;
3606 }
3607 else
3608 {
3609 return 1;
3610 }
3611
3612 return 0;
3613 }
3614
3615
3616 int ventoy_data_save_injection(data_injection *data, const char *title, char *buf, int buflen)
3617 {
3618 int pos = 0;
3619 injection_node *node = NULL;
3620
3621 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3622
3623 VTOY_JSON_FMT_KEY_L(L1, title);
3624 VTOY_JSON_FMT_ARY_BEGIN_N();
3625
3626 for (node = data->list; node; node = node->next)
3627 {
3628 VTOY_JSON_FMT_OBJ_BEGIN_LN(L2);
3629
3630 if (node->type == 0)
3631 {
3632 VTOY_JSON_FMT_STRN_PATH_LN(L3, "image", node->path);
3633 }
3634 else
3635 {
3636 VTOY_JSON_FMT_STRN_PATH_LN(L3, "parent", node->path);
3637 }
3638 VTOY_JSON_FMT_STRN_PATH_LN(L3, "archive", node->archive);
3639
3640 VTOY_JSON_FMT_OBJ_ENDEX_LN(L2);
3641 }
3642
3643 VTOY_JSON_FMT_ARY_ENDEX_LN(L1);
3644 VTOY_JSON_FMT_END(pos);
3645
3646 return pos;
3647 }
3648
3649
3650 int ventoy_data_json_injection(data_injection *data, char *buf, int buflen)
3651 {
3652 int pos = 0;
3653 int valid = 0;
3654 injection_node *node = NULL;
3655
3656 VTOY_JSON_FMT_BEGIN(pos, buf, buflen);
3657 VTOY_JSON_FMT_ARY_BEGIN();
3658
3659 for (node = data->list; node; node = node->next)
3660 {
3661 VTOY_JSON_FMT_OBJ_BEGIN();
3662
3663 VTOY_JSON_FMT_UINT("type", node->type);
3664 VTOY_JSON_FMT_STRN("path", node->path);
3665
3666 if (node->type == 0)
3667 {
3668 valid = ventoy_check_fuzzy_path(node->path, 1);
3669 }
3670 else
3671 {
3672 valid = ventoy_is_directory_exist("%s%s", g_cur_dir, node->path);
3673 }
3674 VTOY_JSON_FMT_SINT("valid", valid);
3675
3676 VTOY_JSON_FMT_STRN("archive", node->archive);
3677
3678 valid = ventoy_is_file_exist("%s%s", g_cur_dir, node->archive);
3679 VTOY_JSON_FMT_SINT("archive_valid", valid);
3680
3681 VTOY_JSON_FMT_OBJ_ENDEX();
3682 }
3683
3684 VTOY_JSON_FMT_ARY_END();
3685 VTOY_JSON_FMT_END(pos);
3686
3687 return pos;
3688 }
3689
3690
3691 static int ventoy_api_get_injection(struct mg_connection *conn, VTOY_JSON *json)
3692 {
3693 api_get_func(conn, json, injection);
3694 return 0;
3695 }
3696
3697 static int ventoy_api_save_injection(struct mg_connection *conn, VTOY_JSON *json)
3698 {
3699 int ret;
3700 ret = ventoy_data_save_all();
3701
3702 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3703 return 0;
3704 }
3705
3706 static int ventoy_api_injection_add(struct mg_connection *conn, VTOY_JSON *json)
3707 {
3708 int ret;
3709 int index = 0;
3710 int type = 0;
3711 const char *path = NULL;
3712 const char *archive = NULL;
3713 injection_node *node = NULL;
3714 injection_node *cur = NULL;
3715 data_injection *data = NULL;
3716
3717 vtoy_json_get_int(json, "index", &index);
3718 data = g_data_injection + index;
3719
3720 vtoy_json_get_int(json, "type", &type);
3721
3722 path = VTOY_JSON_STR_EX("path");
3723 archive = VTOY_JSON_STR_EX("archive");
3724 if (path && archive)
3725 {
3726 if (ventoy_is_real_exist_common(path, data->list, injection_node))
3727 {
3728 ventoy_json_result(conn, VTOY_JSON_DUPLICATE);
3729 return 0;
3730 }
3731
3732 node = zalloc(sizeof(injection_node));
3733 if (node)
3734 {
3735 node->type = type;
3736
3737 scnprintf(node->path, sizeof(node->path), "%s", path);
3738 scnprintf(node->archive, sizeof(node->archive), "%s", archive);
3739
3740 vtoy_list_add(data->list, cur, node);
3741 }
3742 }
3743
3744 ret = ventoy_data_save_all();
3745
3746 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3747 return 0;
3748 }
3749
3750 static int ventoy_api_injection_del(struct mg_connection *conn, VTOY_JSON *json)
3751 {
3752 int ret;
3753 int index = 0;
3754 const char *path = NULL;
3755 injection_node *last = NULL;
3756 injection_node *node = NULL;
3757 data_injection *data = NULL;
3758
3759 vtoy_json_get_int(json, "index", &index);
3760 data = g_data_injection + index;
3761
3762 path = VTOY_JSON_STR_EX("path");
3763 if (path)
3764 {
3765 if (strcmp(path, VTOY_DEL_ALL_PATH) == 0)
3766 {
3767 vtoy_list_free(injection_node, data->list);
3768 }
3769 else
3770 {
3771 vtoy_list_del(last, node, data->list, path);
3772 }
3773 }
3774
3775 ret = ventoy_data_save_all();
3776
3777 ventoy_json_result(conn, ret == 0 ? VTOY_JSON_SUCCESS_RET : VTOY_JSON_FAILED_RET);
3778 return 0;
3779 }
3780
3781 #if 0
3782 #endif
3783
3784 static int ventoy_api_preview_json(struct mg_connection *conn, VTOY_JSON *json)
3785 {
3786 int i = 0;
3787 int pos = 0;
3788 int len = 0;
3789 int utf16enclen = 0;
3790 char *encodebuf = NULL;
3791 unsigned short *utf16buf = NULL;
3792
3793 (void)json;
3794
3795 /* We can not use json directly, because it will be formated in the JS. */
3796
3797 len = ventoy_data_real_save_all(0);
3798
3799 utf16buf = (unsigned short *)malloc(2 * len + 16);
3800 if (!utf16buf)
3801 {
3802 goto json;
3803 }
3804
3805 utf16enclen = (int)utf8_to_utf16((unsigned char *)JSON_SAVE_BUFFER, len, utf16buf, len + 2);
3806
3807 encodebuf = (char *)malloc(utf16enclen * 4 + 16);
3808 if (!encodebuf)
3809 {
3810 goto json;
3811 }
3812
3813 for (i = 0; i < utf16enclen; i++)
3814 {
3815 scnprintf(encodebuf + i * 4, 5, "%04X", utf16buf[i]);
3816 }
3817
3818 json:
3819 VTOY_JSON_FMT_BEGIN(pos, JSON_BUFFER, JSON_BUF_MAX);
3820 VTOY_JSON_FMT_OBJ_BEGIN();
3821 VTOY_JSON_FMT_STRN("json", (encodebuf ? encodebuf : ""));
3822 VTOY_JSON_FMT_OBJ_END();
3823 VTOY_JSON_FMT_END(pos);
3824
3825 CHECK_FREE(encodebuf);
3826 CHECK_FREE(utf16buf);
3827
3828 ventoy_json_buffer(conn, JSON_BUFFER, pos);
3829 return 0;
3830 }
3831
3832
3833 #if 0
3834 #endif
3835
3836 int ventoy_data_save_all(void)
3837 {
3838 ventoy_set_writeback_event();
3839 return 0;
3840 }
3841
3842 int ventoy_data_real_save_all(int apilock)
3843 {
3844 int i = 0;
3845 int pos = 0;
3846 char title[64];
3847
3848 if (apilock)
3849 {
3850 pthread_mutex_lock(&g_api_mutex);
3851 }
3852
3853 ssprintf(pos, JSON_SAVE_BUFFER, JSON_BUF_MAX, "{\n");
3854
3855 ventoy_save_plug(control);
3856 ventoy_save_plug(theme);
3857 ventoy_save_plug(menu_alias);
3858 ventoy_save_plug(menu_tip);
3859 ventoy_save_plug(menu_class);
3860 ventoy_save_plug(auto_install);
3861 ventoy_save_plug(persistence);
3862 ventoy_save_plug(injection);
3863 ventoy_save_plug(conf_replace);
3864 ventoy_save_plug(password);
3865 ventoy_save_plug(image_list);
3866 ventoy_save_plug(auto_memdisk);
3867 ventoy_save_plug(dud);
3868
3869 if (JSON_SAVE_BUFFER[pos - 1] == '\n' && JSON_SAVE_BUFFER[pos - 2] == ',')
3870 {
3871 JSON_SAVE_BUFFER[pos - 2] = '\n';
3872 pos--;
3873 }
3874 ssprintf(pos, JSON_SAVE_BUFFER, JSON_BUF_MAX, "}\n");
3875
3876 if (apilock)
3877 {
3878 pthread_mutex_unlock(&g_api_mutex);
3879 }
3880
3881 return pos;
3882 }
3883
3884 int ventoy_http_writeback(void)
3885 {
3886 int ret;
3887 int pos;
3888 char filename[128];
3889
3890 ventoy_get_json_path(filename, NULL);
3891
3892 pos = ventoy_data_real_save_all(1);
3893
3894 #ifdef VENTOY_SIM
3895 printf("%s", JSON_SAVE_BUFFER);
3896 #endif
3897
3898 ret = ventoy_write_buf_to_file(filename, JSON_SAVE_BUFFER, pos);
3899 if (ret)
3900 {
3901 vlog("Failed to write ventoy.json file.\n");
3902 g_sysinfo.config_save_error = 1;
3903 }
3904
3905 return 0;
3906 }
3907
3908
3909 static JSON_CB g_ventoy_json_cb[] =
3910 {
3911 { "sysinfo", ventoy_api_sysinfo },
3912 { "handshake", ventoy_api_handshake },
3913 { "check_path", ventoy_api_check_exist },
3914 { "check_path2", ventoy_api_check_exist2 },
3915 { "check_fuzzy", ventoy_api_check_fuzzy },
3916
3917 { "device_info", ventoy_api_device_info },
3918
3919 { "get_control", ventoy_api_get_control },
3920 { "save_control", ventoy_api_save_control },
3921
3922 { "get_theme", ventoy_api_get_theme },
3923 { "save_theme", ventoy_api_save_theme },
3924 { "theme_add_file", ventoy_api_theme_add_file },
3925 { "theme_del_file", ventoy_api_theme_del_file },
3926 { "theme_add_font", ventoy_api_theme_add_font },
3927 { "theme_del_font", ventoy_api_theme_del_font },
3928
3929 { "get_alias", ventoy_api_get_alias },
3930 { "save_alias", ventoy_api_save_alias },
3931 { "alias_add", ventoy_api_alias_add },
3932 { "alias_del", ventoy_api_alias_del },
3933
3934 { "get_tip", ventoy_api_get_tip },
3935 { "save_tip", ventoy_api_save_tip },
3936 { "tip_add", ventoy_api_tip_add },
3937 { "tip_del", ventoy_api_tip_del },
3938
3939 { "get_class", ventoy_api_get_class },
3940 { "save_class", ventoy_api_save_class },
3941 { "class_add", ventoy_api_class_add },
3942 { "class_del", ventoy_api_class_del },
3943
3944 { "get_auto_memdisk", ventoy_api_get_auto_memdisk },
3945 { "save_auto_memdisk", ventoy_api_save_auto_memdisk },
3946 { "auto_memdisk_add", ventoy_api_auto_memdisk_add },
3947 { "auto_memdisk_del", ventoy_api_auto_memdisk_del },
3948
3949 { "get_image_list", ventoy_api_get_image_list },
3950 { "save_image_list", ventoy_api_save_image_list },
3951 { "image_list_add", ventoy_api_image_list_add },
3952 { "image_list_del", ventoy_api_image_list_del },
3953
3954 { "get_conf_replace", ventoy_api_get_conf_replace },
3955 { "save_conf_replace", ventoy_api_save_conf_replace },
3956 { "conf_replace_add", ventoy_api_conf_replace_add },
3957 { "conf_replace_del", ventoy_api_conf_replace_del },
3958
3959 { "get_dud", ventoy_api_get_dud },
3960 { "save_dud", ventoy_api_save_dud },
3961 { "dud_add", ventoy_api_dud_add },
3962 { "dud_del", ventoy_api_dud_del },
3963 { "dud_add_inner", ventoy_api_dud_add_inner },
3964 { "dud_del_inner", ventoy_api_dud_del_inner },
3965
3966 { "get_auto_install", ventoy_api_get_auto_install },
3967 { "save_auto_install", ventoy_api_save_auto_install },
3968 { "auto_install_add", ventoy_api_auto_install_add },
3969 { "auto_install_del", ventoy_api_auto_install_del },
3970 { "auto_install_add_inner", ventoy_api_auto_install_add_inner },
3971 { "auto_install_del_inner", ventoy_api_auto_install_del_inner },
3972
3973 { "get_persistence", ventoy_api_get_persistence },
3974 { "save_persistence", ventoy_api_save_persistence },
3975 { "persistence_add", ventoy_api_persistence_add },
3976 { "persistence_del", ventoy_api_persistence_del },
3977 { "persistence_add_inner", ventoy_api_persistence_add_inner },
3978 { "persistence_del_inner", ventoy_api_persistence_del_inner },
3979
3980 { "get_password", ventoy_api_get_password },
3981 { "save_password", ventoy_api_save_password },
3982 { "password_add", ventoy_api_password_add },
3983 { "password_del", ventoy_api_password_del },
3984
3985 { "get_injection", ventoy_api_get_injection },
3986 { "save_injection", ventoy_api_save_injection },
3987 { "injection_add", ventoy_api_injection_add },
3988 { "injection_del", ventoy_api_injection_del },
3989 { "preview_json", ventoy_api_preview_json },
3990
3991 };
3992
3993 static int ventoy_json_handler(struct mg_connection *conn, VTOY_JSON *json, char *jsonstr)
3994 {
3995 int i;
3996 const char *method = NULL;
3997
3998 method = vtoy_json_get_string_ex(json, "method");
3999 if (!method)
4000 {
4001 ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET);
4002 return 0;
4003 }
4004
4005 if (strcmp(method, "handshake") == 0)
4006 {
4007 ventoy_api_handshake(conn, json);
4008 return 0;
4009 }
4010
4011 for (i = 0; i < (int)(sizeof(g_ventoy_json_cb) / sizeof(g_ventoy_json_cb[0])); i++)
4012 {
4013 if (strcmp(method, g_ventoy_json_cb[i].method) == 0)
4014 {
4015 g_ventoy_json_cb[i].callback(conn, json);
4016 break;
4017 }
4018 }
4019
4020 return 0;
4021 }
4022
4023 static int ventoy_request_handler(struct mg_connection *conn)
4024 {
4025 int post_data_len;
4026 int post_buf_len;
4027 VTOY_JSON *json = NULL;
4028 char *post_data_buf = NULL;
4029 const struct mg_request_info *ri = NULL;
4030 char stack_buf[512];
4031
4032 ri = mg_get_request_info(conn);
4033
4034 if (strcmp(ri->uri, "/vtoy/json") == 0)
4035 {
4036 if (ri->content_length > 500)
4037 {
4038 post_data_buf = malloc((int)(ri->content_length + 4));
4039 post_buf_len = (int)(ri->content_length + 1);
4040 }
4041 else
4042 {
4043 post_data_buf = stack_buf;
4044 post_buf_len = sizeof(stack_buf);
4045 }
4046
4047 post_data_len = mg_read(conn, post_data_buf, post_buf_len);
4048 post_data_buf[post_data_len] = 0;
4049
4050 json = vtoy_json_create();
4051 if (JSON_SUCCESS == vtoy_json_parse(json, post_data_buf))
4052 {
4053 pthread_mutex_lock(&g_api_mutex);
4054 ventoy_json_handler(conn, json->pstChild, post_data_buf);
4055 pthread_mutex_unlock(&g_api_mutex);
4056 }
4057 else
4058 {
4059 ventoy_json_result(conn, VTOY_JSON_INVALID_RET);
4060 }
4061
4062 vtoy_json_destroy(json);
4063
4064 if (post_data_buf != stack_buf)
4065 {
4066 free(post_data_buf);
4067 }
4068 return 1;
4069 }
4070 else
4071 {
4072 return 0;
4073 }
4074 }
4075
4076 const char *ventoy_web_openfile(const struct mg_connection *conn, const char *path, size_t *data_len)
4077 {
4078 ventoy_file *node = NULL;
4079
4080 (void)conn;
4081
4082 if (!path)
4083 {
4084 return NULL;
4085 }
4086
4087 node = ventoy_tar_find_file(path);
4088 if (node)
4089 {
4090 *data_len = node->size;
4091 return node->addr;
4092 }
4093 else
4094 {
4095 return NULL;
4096 }
4097 }
4098
4099 #if 0
4100 #endif
4101
4102 static int ventoy_parse_control(VTOY_JSON *json, void *p)
4103 {
4104 int i;
4105 VTOY_JSON *node = NULL;
4106 VTOY_JSON *child = NULL;
4107 data_control *data = (data_control *)p;
4108
4109 if (json->enDataType != JSON_TYPE_ARRAY)
4110 {
4111 return 0;
4112 }
4113
4114 for (node = json->pstChild; node; node = node->pstNext)
4115 {
4116 if (node->enDataType == JSON_TYPE_OBJECT)
4117 {
4118 child = node->pstChild;
4119
4120 if (child->enDataType != JSON_TYPE_STRING)
4121 {
4122 continue;
4123 }
4124
4125 if (strcmp(child->pcName, "VTOY_DEFAULT_MENU_MODE") == 0)
4126 {
4127 CONTROL_PARSE_INT_DEF_0(child, data->default_menu_mode);
4128 }
4129 else if (strcmp(child->pcName, "VTOY_WIN11_BYPASS_CHECK") == 0)
4130 {
4131 CONTROL_PARSE_INT_DEF_0(child, data->win11_bypass_check);
4132 }
4133 else if (strcmp(child->pcName, "VTOY_LINUX_REMOUNT") == 0)
4134 {
4135 CONTROL_PARSE_INT_DEF_0(child, data->linux_remount);
4136 }
4137 else if (strcmp(child->pcName, "VTOY_SECONDARY_BOOT_MENU") == 0)
4138 {
4139 CONTROL_PARSE_INT_DEF_1(child, data->secondary_menu);
4140 }
4141 else if (strcmp(child->pcName, "VTOY_SHOW_PASSWORD_ASTERISK") == 0)
4142 {
4143 CONTROL_PARSE_INT_DEF_1(child, data->password_asterisk);
4144 }
4145 else if (strcmp(child->pcName, "VTOY_TREE_VIEW_MENU_STYLE") == 0)
4146 {
4147 CONTROL_PARSE_INT_DEF_0(child, data->treeview_style);
4148 }
4149 else if (strcmp(child->pcName, "VTOY_FILT_DOT_UNDERSCORE_FILE") == 0)
4150 {
4151 CONTROL_PARSE_INT_DEF_1(child, data->filter_dot_underscore);
4152 }
4153 else if (strcmp(child->pcName, "VTOY_SORT_CASE_SENSITIVE") == 0)
4154 {
4155 CONTROL_PARSE_INT_DEF_0(child, data->sort_casesensitive);
4156 }
4157 else if (strcmp(child->pcName, "VTOY_MAX_SEARCH_LEVEL") == 0)
4158 {
4159 if (strcmp(child->unData.pcStrVal, "max") == 0)
4160 {
4161 data->max_search_level = -1;
4162 }
4163 else
4164 {
4165 data->max_search_level = (int)strtol(child->unData.pcStrVal, NULL, 10);
4166 }
4167 }
4168 else if (strcmp(child->pcName, "VTOY_DEFAULT_SEARCH_ROOT") == 0)
4169 {
4170 strlcpy(data->default_search_root, child->unData.pcStrVal);
4171 }
4172 else if (strcmp(child->pcName, "VTOY_DEFAULT_IMAGE") == 0)
4173 {
4174 strlcpy(data->default_image, child->unData.pcStrVal);
4175 }
4176 else if (strcmp(child->pcName, "VTOY_DEFAULT_KBD_LAYOUT") == 0)
4177 {
4178 for (i = 0; g_ventoy_kbd_layout[i]; i++)
4179 {
4180 if (strcmp(child->unData.pcStrVal, g_ventoy_kbd_layout[i]) == 0)
4181 {
4182 strlcpy(data->default_kbd_layout, child->unData.pcStrVal);
4183 break;
4184 }
4185 }
4186 }
4187 else if (strcmp(child->pcName, "VTOY_MENU_LANGUAGE") == 0)
4188 {
4189 for (i = 0; g_ventoy_menu_lang[i][0]; i++)
4190 {
4191 if (strcmp(child->unData.pcStrVal, g_ventoy_menu_lang[i]) == 0)
4192 {
4193 strlcpy(data->menu_language, child->unData.pcStrVal);
4194 break;
4195 }
4196 }
4197 }
4198 else if (strcmp(child->pcName, "VTOY_MENU_TIMEOUT") == 0)
4199 {
4200 data->menu_timeout = (int)strtol(child->unData.pcStrVal, NULL, 10);
4201 }
4202 else if (strcmp(child->pcName, "VTOY_SECONDARY_TIMEOUT") == 0)
4203 {
4204 data->secondary_menu_timeout = (int)strtol(child->unData.pcStrVal, NULL, 10);
4205 }
4206 else if (strcmp(child->pcName, "VTOY_VHD_NO_WARNING") == 0)
4207 {
4208 CONTROL_PARSE_INT_DEF_0(child, data->vhd_no_warning);
4209 }
4210 else if (strcmp(child->pcName, "VTOY_FILE_FLT_ISO") == 0)
4211 {
4212 CONTROL_PARSE_INT_DEF_0(child, data->filter_iso);
4213 }
4214 else if (strcmp(child->pcName, "VTOY_FILE_FLT_IMG") == 0)
4215 {
4216 CONTROL_PARSE_INT_DEF_0(child, data->filter_img);
4217 }
4218 else if (strcmp(child->pcName, "VTOY_FILE_FLT_EFI") == 0)
4219 {
4220 CONTROL_PARSE_INT_DEF_0(child, data->filter_efi);
4221 }
4222 else if (strcmp(child->pcName, "VTOY_FILE_FLT_WIM") == 0)
4223 {
4224 CONTROL_PARSE_INT_DEF_0(child, data->filter_wim);
4225 }
4226 else if (strcmp(child->pcName, "VTOY_FILE_FLT_VHD") == 0)
4227 {
4228 CONTROL_PARSE_INT_DEF_0(child, data->filter_vhd);
4229 }
4230 else if (strcmp(child->pcName, "VTOY_FILE_FLT_VTOY") == 0)
4231 {
4232 CONTROL_PARSE_INT_DEF_0(child, data->filter_vtoy);
4233 }
4234
4235 }
4236 }
4237
4238 return 0;
4239 }
4240 static int ventoy_parse_theme(VTOY_JSON *json, void *p)
4241 {
4242 const char *dismode = NULL;
4243 VTOY_JSON *child = NULL;
4244 VTOY_JSON *node = NULL;
4245 path_node *tail = NULL;
4246 path_node *pnode = NULL;
4247 data_theme *data = (data_theme *)p;
4248
4249 if (json->enDataType != JSON_TYPE_OBJECT)
4250 {
4251 return 0;
4252 }
4253
4254 child = json->pstChild;
4255
4256 dismode = vtoy_json_get_string_ex(child, "display_mode");
4257 vtoy_json_get_string(child, "ventoy_left", sizeof(data->ventoy_left), data->ventoy_left);
4258 vtoy_json_get_string(child, "ventoy_top", sizeof(data->ventoy_top), data->ventoy_top);
4259 vtoy_json_get_string(child, "ventoy_color", sizeof(data->ventoy_color), data->ventoy_color);
4260
4261 vtoy_json_get_int(child, "default_file", &(data->default_file));
4262 vtoy_json_get_int(child, "resolution_fit", &(data->resolution_fit));
4263 vtoy_json_get_string(child, "gfxmode", sizeof(data->gfxmode), data->gfxmode);
4264 vtoy_json_get_string(child, "serial_param", sizeof(data->serial_param), data->serial_param);
4265
4266 if (dismode)
4267 {
4268 if (strcmp(dismode, "CLI") == 0)
4269 {
4270 data->display_mode = display_mode_cli;
4271 }
4272 else if (strcmp(dismode, "serial") == 0)
4273 {
4274 data->display_mode = display_mode_serial;
4275 }
4276 else if (strcmp(dismode, "serial_console") == 0)
4277 {
4278 data->display_mode = display_mode_ser_console;
4279 }
4280 else
4281 {
4282 data->display_mode = display_mode_gui;
4283 }
4284 }
4285
4286 node = vtoy_json_find_item(child, JSON_TYPE_STRING, "file");
4287 if (node)
4288 {
4289 data->default_file = 0;
4290 data->resolution_fit = 0;
4291
4292 pnode = zalloc(sizeof(path_node));
4293 if (pnode)
4294 {
4295 strlcpy(pnode->path, node->unData.pcStrVal);
4296 data->filelist = pnode;
4297 }
4298 }
4299 else
4300 {
4301 node = vtoy_json_find_item(child, JSON_TYPE_ARRAY, "file");
4302 if (node)
4303 {
4304 for (node = node->pstChild; node; node = node->pstNext)
4305 {
4306 if (node->enDataType == JSON_TYPE_STRING)
4307 {
4308 pnode = zalloc(sizeof(path_node));
4309 if (pnode)
4310 {
4311 strlcpy(pnode->path, node->unData.pcStrVal);
4312 if (data->filelist)
4313 {
4314 tail->next = pnode;
4315 tail = pnode;
4316 }
4317 else
4318 {
4319 data->filelist = tail = pnode;
4320 }
4321 }
4322 }
4323 }
4324 }
4325 }
4326
4327
4328 node = vtoy_json_find_item(child, JSON_TYPE_ARRAY, "fonts");
4329 if (node)
4330 {
4331 for (node = node->pstChild; node; node = node->pstNext)
4332 {
4333 if (node->enDataType == JSON_TYPE_STRING)
4334 {
4335 pnode = zalloc(sizeof(path_node));
4336 if (pnode)
4337 {
4338 strlcpy(pnode->path, node->unData.pcStrVal);
4339 if (data->fontslist)
4340 {
4341 tail->next = pnode;
4342 tail = pnode;
4343 }
4344 else
4345 {
4346 data->fontslist = tail = pnode;
4347 }
4348 }
4349 }
4350 }
4351 }
4352
4353 return 0;
4354 }
4355 static int ventoy_parse_menu_alias(VTOY_JSON *json, void *p)
4356 {
4357 int type;
4358 const char *path = NULL;
4359 const char *alias = NULL;
4360 data_alias *data = (data_alias *)p;
4361 data_alias_node *tail = NULL;
4362 data_alias_node *pnode = NULL;
4363 VTOY_JSON *node = NULL;
4364
4365 if (json->enDataType != JSON_TYPE_ARRAY)
4366 {
4367 return 0;
4368 }
4369
4370 for (node = json->pstChild; node; node = node->pstNext)
4371 {
4372 if (node->enDataType != JSON_TYPE_OBJECT)
4373 {
4374 continue;
4375 }
4376
4377 type = path_type_file;
4378 path = vtoy_json_get_string_ex(node->pstChild, "image");
4379 if (!path)
4380 {
4381 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4382 type = path_type_dir;
4383 }
4384 alias = vtoy_json_get_string_ex(node->pstChild, "alias");
4385
4386 if (path && alias)
4387 {
4388 pnode = zalloc(sizeof(data_alias_node));
4389 if (pnode)
4390 {
4391 pnode->type = type;
4392 strlcpy(pnode->path, path);
4393 strlcpy(pnode->alias, alias);
4394
4395 if (data->list)
4396 {
4397 tail->next = pnode;
4398 tail = pnode;
4399 }
4400 else
4401 {
4402 data->list = tail = pnode;
4403 }
4404 }
4405 }
4406 }
4407
4408 return 0;
4409 }
4410
4411 static int ventoy_parse_menu_tip(VTOY_JSON *json, void *p)
4412 {
4413 int type;
4414 const char *path = NULL;
4415 const char *tip = NULL;
4416 data_tip *data = (data_tip *)p;
4417 data_tip_node *tail = NULL;
4418 data_tip_node *pnode = NULL;
4419 VTOY_JSON *node = NULL;
4420 VTOY_JSON *tips = NULL;
4421
4422 if (json->enDataType != JSON_TYPE_OBJECT)
4423 {
4424 return 0;
4425 }
4426
4427 vtoy_json_get_string(json->pstChild, "left", sizeof(data->left), data->left);
4428 vtoy_json_get_string(json->pstChild, "top", sizeof(data->top), data->top);
4429 vtoy_json_get_string(json->pstChild, "color", sizeof(data->color), data->color);
4430
4431 tips = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips");
4432 if (!tips)
4433 {
4434 return 0;
4435 }
4436
4437 for (node = tips->pstChild; node; node = node->pstNext)
4438 {
4439 if (node->enDataType != JSON_TYPE_OBJECT)
4440 {
4441 continue;
4442 }
4443
4444 type = path_type_file;
4445 path = vtoy_json_get_string_ex(node->pstChild, "image");
4446 if (!path)
4447 {
4448 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4449 type = path_type_dir;
4450 }
4451 tip = vtoy_json_get_string_ex(node->pstChild, "tip");
4452
4453 if (path && tip)
4454 {
4455 pnode = zalloc(sizeof(data_tip_node));
4456 if (pnode)
4457 {
4458 pnode->type = type;
4459 strlcpy(pnode->path, path);
4460 strlcpy(pnode->tip, tip);
4461
4462 if (data->list)
4463 {
4464 tail->next = pnode;
4465 tail = pnode;
4466 }
4467 else
4468 {
4469 data->list = tail = pnode;
4470 }
4471 }
4472 }
4473 }
4474
4475 return 0;
4476 }
4477 static int ventoy_parse_menu_class(VTOY_JSON *json, void *p)
4478 {
4479 int type;
4480 const char *path = NULL;
4481 const char *class = NULL;
4482 data_class *data = (data_class *)p;
4483 data_class_node *tail = NULL;
4484 data_class_node *pnode = NULL;
4485 VTOY_JSON *node = NULL;
4486
4487 if (json->enDataType != JSON_TYPE_ARRAY)
4488 {
4489 return 0;
4490 }
4491
4492 for (node = json->pstChild; node; node = node->pstNext)
4493 {
4494 if (node->enDataType != JSON_TYPE_OBJECT)
4495 {
4496 continue;
4497 }
4498
4499 type = class_type_key;
4500 path = vtoy_json_get_string_ex(node->pstChild, "key");
4501 if (!path)
4502 {
4503 type = class_type_dir;
4504 path = vtoy_json_get_string_ex(node->pstChild, "dir");
4505 if (!path)
4506 {
4507 type = class_type_parent;
4508 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4509 }
4510 }
4511 class = vtoy_json_get_string_ex(node->pstChild, "class");
4512
4513 if (path && class)
4514 {
4515 pnode = zalloc(sizeof(data_class_node));
4516 if (pnode)
4517 {
4518 pnode->type = type;
4519 strlcpy(pnode->path, path);
4520 strlcpy(pnode->class, class);
4521
4522 if (data->list)
4523 {
4524 tail->next = pnode;
4525 tail = pnode;
4526 }
4527 else
4528 {
4529 data->list = tail = pnode;
4530 }
4531 }
4532 }
4533 }
4534
4535 return 0;
4536 }
4537 static int ventoy_parse_auto_install(VTOY_JSON *json, void *p)
4538 {
4539 int type;
4540 int count;
4541 int timeout;
4542 int timeouten;
4543 int autosel;
4544 int autoselen;
4545 const char *path = NULL;
4546 const char *file = NULL;
4547 data_auto_install *data = (data_auto_install *)p;
4548 auto_install_node *tail = NULL;
4549 auto_install_node *pnode = NULL;
4550 path_node *pathnode = NULL;
4551 path_node *pathtail = NULL;
4552 VTOY_JSON *node = NULL;
4553 VTOY_JSON *filelist = NULL;
4554 VTOY_JSON *filenode = NULL;
4555
4556 if (json->enDataType != JSON_TYPE_ARRAY)
4557 {
4558 return 0;
4559 }
4560
4561 for (node = json->pstChild; node; node = node->pstNext)
4562 {
4563 if (node->enDataType != JSON_TYPE_OBJECT)
4564 {
4565 continue;
4566 }
4567
4568 type = 0;
4569 path = vtoy_json_get_string_ex(node->pstChild, "image");
4570 if (!path)
4571 {
4572 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4573 type = 1;
4574 }
4575 if (!path)
4576 {
4577 continue;
4578 }
4579
4580 file = vtoy_json_get_string_ex(node->pstChild, "template");
4581 if (file)
4582 {
4583 pnode = zalloc(sizeof(auto_install_node));
4584 if (pnode)
4585 {
4586 pnode->type = type;
4587 pnode->autosel = 1;
4588 strlcpy(pnode->path, path);
4589
4590 pathnode = zalloc(sizeof(path_node));
4591 if (pathnode)
4592 {
4593 strlcpy(pathnode->path, file);
4594 pnode->list = pathnode;
4595 }
4596 else
4597 {
4598 free(pnode);
4599 }
4600
4601 if (data->list)
4602 {
4603 tail->next = pnode;
4604 tail = pnode;
4605 }
4606 else
4607 {
4608 data->list = tail = pnode;
4609 }
4610 }
4611
4612 continue;
4613 }
4614
4615
4616 timeouten = autoselen = 0;
4617 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "timeout", &timeout))
4618 {
4619 timeouten = 1;
4620 }
4621 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "autosel", &autosel))
4622 {
4623 autoselen = 1;
4624 }
4625
4626 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "template");
4627 if (!filelist)
4628 {
4629 continue;
4630 }
4631
4632 pnode = zalloc(sizeof(auto_install_node));
4633 if (!pnode)
4634 {
4635 continue;
4636 }
4637
4638 pnode->type = type;
4639 pnode->autoselen = autoselen;
4640 pnode->timeouten = timeouten;
4641 pnode->timeout = timeout;
4642 pnode->autosel = autosel;
4643 strlcpy(pnode->path, path);
4644
4645 count = 0;
4646 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
4647 {
4648 if (filenode->enDataType != JSON_TYPE_STRING)
4649 {
4650 continue;
4651 }
4652
4653 pathnode = zalloc(sizeof(path_node));
4654 if (pathnode)
4655 {
4656 count++;
4657 strlcpy(pathnode->path, filenode->unData.pcStrVal);
4658
4659 if (pnode->list)
4660 {
4661 pathtail->next = pathnode;
4662 pathtail = pathnode;
4663 }
4664 else
4665 {
4666 pnode->list = pathtail = pathnode;
4667 }
4668 }
4669 }
4670
4671 if (count == 0)
4672 {
4673 free(pnode);
4674 }
4675 else
4676 {
4677 if (pnode->autoselen && pnode->autosel > count)
4678 {
4679 pnode->autosel = 1;
4680 }
4681
4682 if (data->list)
4683 {
4684 tail->next = pnode;
4685 tail = pnode;
4686 }
4687 else
4688 {
4689 data->list = tail = pnode;
4690 }
4691 }
4692 }
4693
4694 return 0;
4695 }
4696 static int ventoy_parse_persistence(VTOY_JSON *json, void *p)
4697 {
4698 int count;
4699 int timeout;
4700 int timeouten;
4701 int autosel;
4702 int autoselen;
4703 const char *path = NULL;
4704 const char *file = NULL;
4705 data_persistence *data = (data_persistence *)p;
4706 persistence_node *tail = NULL;
4707 persistence_node *pnode = NULL;
4708 path_node *pathnode = NULL;
4709 path_node *pathtail = NULL;
4710 VTOY_JSON *node = NULL;
4711 VTOY_JSON *filelist = NULL;
4712 VTOY_JSON *filenode = NULL;
4713
4714 if (json->enDataType != JSON_TYPE_ARRAY)
4715 {
4716 return 0;
4717 }
4718
4719 for (node = json->pstChild; node; node = node->pstNext)
4720 {
4721 if (node->enDataType != JSON_TYPE_OBJECT)
4722 {
4723 continue;
4724 }
4725
4726 path = vtoy_json_get_string_ex(node->pstChild, "image");
4727 if (!path)
4728 {
4729 continue;
4730 }
4731
4732 file = vtoy_json_get_string_ex(node->pstChild, "backend");
4733 if (file)
4734 {
4735 pnode = zalloc(sizeof(persistence_node));
4736 if (pnode)
4737 {
4738 pnode->type = 0;
4739 pnode->autosel = 1;
4740 strlcpy(pnode->path, path);
4741
4742 pathnode = zalloc(sizeof(path_node));
4743 if (pathnode)
4744 {
4745 strlcpy(pathnode->path, file);
4746 pnode->list = pathnode;
4747 }
4748 else
4749 {
4750 free(pnode);
4751 }
4752
4753 if (data->list)
4754 {
4755 tail->next = pnode;
4756 tail = pnode;
4757 }
4758 else
4759 {
4760 data->list = tail = pnode;
4761 }
4762 }
4763
4764 continue;
4765 }
4766
4767
4768 timeouten = autoselen = 0;
4769 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "timeout", &timeout))
4770 {
4771 timeouten = 1;
4772 }
4773 if (JSON_SUCCESS == vtoy_json_get_int(node->pstChild, "autosel", &autosel))
4774 {
4775 autoselen = 1;
4776 }
4777
4778 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "backend");
4779 if (!filelist)
4780 {
4781 continue;
4782 }
4783
4784 pnode = zalloc(sizeof(persistence_node));
4785 if (!pnode)
4786 {
4787 continue;
4788 }
4789
4790 pnode->type = 0;
4791 pnode->autoselen = autoselen;
4792 pnode->timeouten = timeouten;
4793 pnode->timeout = timeout;
4794 pnode->autosel = autosel;
4795 strlcpy(pnode->path, path);
4796
4797 count = 0;
4798 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
4799 {
4800 if (filenode->enDataType != JSON_TYPE_STRING)
4801 {
4802 continue;
4803 }
4804
4805 pathnode = zalloc(sizeof(path_node));
4806 if (pathnode)
4807 {
4808 count++;
4809 strlcpy(pathnode->path, filenode->unData.pcStrVal);
4810
4811 if (pnode->list)
4812 {
4813 pathtail->next = pathnode;
4814 pathtail = pathnode;
4815 }
4816 else
4817 {
4818 pnode->list = pathtail = pathnode;
4819 }
4820 }
4821 }
4822
4823 if (count == 0)
4824 {
4825 free(pnode);
4826 }
4827 else
4828 {
4829 if (pnode->autoselen && pnode->autosel > count)
4830 {
4831 pnode->autosel = 1;
4832 }
4833
4834 if (data->list)
4835 {
4836 tail->next = pnode;
4837 tail = pnode;
4838 }
4839 else
4840 {
4841 data->list = tail = pnode;
4842 }
4843 }
4844 }
4845
4846 return 0;
4847 }
4848 static int ventoy_parse_injection(VTOY_JSON *json, void *p)
4849 {
4850 int type;
4851 const char *path = NULL;
4852 const char *archive = NULL;
4853 data_injection *data = (data_injection *)p;
4854 injection_node *tail = NULL;
4855 injection_node *pnode = NULL;
4856 VTOY_JSON *node = NULL;
4857
4858 if (json->enDataType != JSON_TYPE_ARRAY)
4859 {
4860 return 0;
4861 }
4862
4863 for (node = json->pstChild; node; node = node->pstNext)
4864 {
4865 if (node->enDataType != JSON_TYPE_OBJECT)
4866 {
4867 continue;
4868 }
4869
4870 type = 0;
4871 path = vtoy_json_get_string_ex(node->pstChild, "image");
4872 if (!path)
4873 {
4874 path = vtoy_json_get_string_ex(node->pstChild, "parent");
4875 type = 1;
4876 }
4877 archive = vtoy_json_get_string_ex(node->pstChild, "archive");
4878
4879 if (path && archive)
4880 {
4881 pnode = zalloc(sizeof(injection_node));
4882 if (pnode)
4883 {
4884 pnode->type = type;
4885 strlcpy(pnode->path, path);
4886 strlcpy(pnode->archive, archive);
4887
4888 if (data->list)
4889 {
4890 tail->next = pnode;
4891 tail = pnode;
4892 }
4893 else
4894 {
4895 data->list = tail = pnode;
4896 }
4897 }
4898 }
4899 }
4900
4901 return 0;
4902 }
4903 static int ventoy_parse_conf_replace(VTOY_JSON *json, void *p)
4904 {
4905 int img = 0;
4906 const char *path = NULL;
4907 const char *org = NULL;
4908 const char *new = NULL;
4909 data_conf_replace *data = (data_conf_replace *)p;
4910 conf_replace_node *tail = NULL;
4911 conf_replace_node *pnode = NULL;
4912 VTOY_JSON *node = NULL;
4913
4914 if (json->enDataType != JSON_TYPE_ARRAY)
4915 {
4916 return 0;
4917 }
4918
4919 for (node = json->pstChild; node; node = node->pstNext)
4920 {
4921 if (node->enDataType != JSON_TYPE_OBJECT)
4922 {
4923 continue;
4924 }
4925
4926 path = vtoy_json_get_string_ex(node->pstChild, "iso");
4927 org = vtoy_json_get_string_ex(node->pstChild, "org");
4928 new = vtoy_json_get_string_ex(node->pstChild, "new");
4929
4930 img = 0;
4931 vtoy_json_get_int(node->pstChild, "img", &img);
4932
4933 if (path && org && new)
4934 {
4935 pnode = zalloc(sizeof(conf_replace_node));
4936 if (pnode)
4937 {
4938 strlcpy(pnode->path, path);
4939 strlcpy(pnode->org, org);
4940 strlcpy(pnode->new, new);
4941 if (img == 1)
4942 {
4943 pnode->image = img;
4944 }
4945
4946 if (data->list)
4947 {
4948 tail->next = pnode;
4949 tail = pnode;
4950 }
4951 else
4952 {
4953 data->list = tail = pnode;
4954 }
4955 }
4956 }
4957 }
4958
4959 return 0;
4960 }
4961 static int ventoy_parse_password(VTOY_JSON *json, void *p)
4962 {
4963 int type;
4964 const char *bootpwd = NULL;
4965 const char *isopwd= NULL;
4966 const char *wimpwd= NULL;
4967 const char *imgpwd= NULL;
4968 const char *efipwd= NULL;
4969 const char *vhdpwd= NULL;
4970 const char *vtoypwd= NULL;
4971 const char *path = NULL;
4972 const char *pwd = NULL;
4973 data_password *data = (data_password *)p;
4974 menu_password *tail = NULL;
4975 menu_password *pnode = NULL;
4976 VTOY_JSON *node = NULL;
4977 VTOY_JSON *menupwd = NULL;
4978
4979 if (json->enDataType != JSON_TYPE_OBJECT)
4980 {
4981 return 0;
4982 }
4983
4984 bootpwd = vtoy_json_get_string_ex(json->pstChild, "bootpwd");
4985 isopwd = vtoy_json_get_string_ex(json->pstChild, "isopwd");
4986 wimpwd = vtoy_json_get_string_ex(json->pstChild, "wimpwd");
4987 imgpwd = vtoy_json_get_string_ex(json->pstChild, "imgpwd");
4988 efipwd = vtoy_json_get_string_ex(json->pstChild, "efipwd");
4989 vhdpwd = vtoy_json_get_string_ex(json->pstChild, "vhdpwd");
4990 vtoypwd = vtoy_json_get_string_ex(json->pstChild, "vtoypwd");
4991
4992
4993 if (bootpwd) strlcpy(data->bootpwd, bootpwd);
4994 if (isopwd) strlcpy(data->isopwd, isopwd);
4995 if (wimpwd) strlcpy(data->wimpwd, wimpwd);
4996 if (imgpwd) strlcpy(data->imgpwd, imgpwd);
4997 if (efipwd) strlcpy(data->efipwd, efipwd);
4998 if (vhdpwd) strlcpy(data->vhdpwd, vhdpwd);
4999 if (vtoypwd) strlcpy(data->vtoypwd, vtoypwd);
5000
5001
5002 menupwd = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "menupwd");
5003 if (!menupwd)
5004 {
5005 return 0;
5006 }
5007
5008 for (node = menupwd->pstChild; node; node = node->pstNext)
5009 {
5010 if (node->enDataType != JSON_TYPE_OBJECT)
5011 {
5012 continue;
5013 }
5014
5015 type = 0;
5016 path = vtoy_json_get_string_ex(node->pstChild, "file");
5017 if (!path)
5018 {
5019 path = vtoy_json_get_string_ex(node->pstChild, "parent");
5020 type = 1;
5021 }
5022 pwd = vtoy_json_get_string_ex(node->pstChild, "pwd");
5023
5024 if (path && pwd)
5025 {
5026 pnode = zalloc(sizeof(menu_password));
5027 if (pnode)
5028 {
5029 pnode->type = type;
5030 strlcpy(pnode->path, path);
5031 strlcpy(pnode->pwd, pwd);
5032
5033 if (data->list)
5034 {
5035 tail->next = pnode;
5036 tail = pnode;
5037 }
5038 else
5039 {
5040 data->list = tail = pnode;
5041 }
5042 }
5043 }
5044 }
5045
5046 return 0;
5047 }
5048
5049 static int ventoy_parse_image_list_real(VTOY_JSON *json, int type, void *p)
5050 {
5051 VTOY_JSON *node = NULL;
5052 data_image_list *data = (data_image_list *)p;
5053 path_node *tail = NULL;
5054 path_node *pnode = NULL;
5055
5056 if (json->enDataType != JSON_TYPE_ARRAY)
5057 {
5058 return 0;
5059 }
5060
5061 data->type = type;
5062
5063 for (node = json->pstChild; node; node = node->pstNext)
5064 {
5065 if (node->enDataType == JSON_TYPE_STRING)
5066 {
5067 pnode = zalloc(sizeof(path_node));
5068 if (pnode)
5069 {
5070 strlcpy(pnode->path, node->unData.pcStrVal);
5071 if (data->list)
5072 {
5073 tail->next = pnode;
5074 tail = pnode;
5075 }
5076 else
5077 {
5078 data->list = tail = pnode;
5079 }
5080 }
5081 }
5082 }
5083
5084 return 0;
5085 }
5086 static int ventoy_parse_image_blacklist(VTOY_JSON *json, void *p)
5087 {
5088 return ventoy_parse_image_list_real(json, 1, p);
5089 }
5090 static int ventoy_parse_image_list(VTOY_JSON *json, void *p)
5091 {
5092 return ventoy_parse_image_list_real(json, 0, p);
5093 }
5094
5095 static int ventoy_parse_auto_memdisk(VTOY_JSON *json, void *p)
5096 {
5097 VTOY_JSON *node = NULL;
5098 data_auto_memdisk *data = (data_auto_memdisk *)p;
5099 path_node *tail = NULL;
5100 path_node *pnode = NULL;
5101
5102 if (json->enDataType != JSON_TYPE_ARRAY)
5103 {
5104 return 0;
5105 }
5106
5107 for (node = json->pstChild; node; node = node->pstNext)
5108 {
5109 if (node->enDataType == JSON_TYPE_STRING)
5110 {
5111 pnode = zalloc(sizeof(path_node));
5112 if (pnode)
5113 {
5114 strlcpy(pnode->path, node->unData.pcStrVal);
5115 if (data->list)
5116 {
5117 tail->next = pnode;
5118 tail = pnode;
5119 }
5120 else
5121 {
5122 data->list = tail = pnode;
5123 }
5124 }
5125 }
5126 }
5127
5128 return 0;
5129 }
5130 static int ventoy_parse_dud(VTOY_JSON *json, void *p)
5131 {
5132 int count = 0;
5133 const char *path = NULL;
5134 const char *file = NULL;
5135 data_dud *data = (data_dud *)p;
5136 dud_node *tail = NULL;
5137 dud_node *pnode = NULL;
5138 path_node *pathnode = NULL;
5139 path_node *pathtail = NULL;
5140 VTOY_JSON *node = NULL;
5141 VTOY_JSON *filelist = NULL;
5142 VTOY_JSON *filenode = NULL;
5143
5144 if (json->enDataType != JSON_TYPE_ARRAY)
5145 {
5146 return 0;
5147 }
5148
5149 for (node = json->pstChild; node; node = node->pstNext)
5150 {
5151 if (node->enDataType != JSON_TYPE_OBJECT)
5152 {
5153 continue;
5154 }
5155
5156 path = vtoy_json_get_string_ex(node->pstChild, "image");
5157 if (!path)
5158 {
5159 continue;
5160 }
5161
5162 file = vtoy_json_get_string_ex(node->pstChild, "dud");
5163 if (file)
5164 {
5165 pnode = zalloc(sizeof(dud_node));
5166 if (pnode)
5167 {
5168 strlcpy(pnode->path, path);
5169
5170 pathnode = zalloc(sizeof(path_node));
5171 if (pathnode)
5172 {
5173 strlcpy(pathnode->path, file);
5174 pnode->list = pathnode;
5175 }
5176 else
5177 {
5178 free(pnode);
5179 }
5180
5181 if (data->list)
5182 {
5183 tail->next = pnode;
5184 tail = pnode;
5185 }
5186 else
5187 {
5188 data->list = tail = pnode;
5189 }
5190 }
5191
5192 continue;
5193 }
5194
5195 filelist = vtoy_json_find_item(node->pstChild, JSON_TYPE_ARRAY, "dud");
5196 if (!filelist)
5197 {
5198 continue;
5199 }
5200
5201 pnode = zalloc(sizeof(dud_node));
5202 if (!pnode)
5203 {
5204 continue;
5205 }
5206
5207 strlcpy(pnode->path, path);
5208
5209 for (filenode = filelist->pstChild; filenode; filenode = filenode->pstNext)
5210 {
5211 if (filenode->enDataType != JSON_TYPE_STRING)
5212 {
5213 continue;
5214 }
5215
5216 pathnode = zalloc(sizeof(path_node));
5217 if (pathnode)
5218 {
5219 strlcpy(pathnode->path, filenode->unData.pcStrVal);
5220 count++;
5221
5222 if (pnode->list)
5223 {
5224 pathtail->next = pathnode;
5225 pathtail = pathnode;
5226 }
5227 else
5228 {
5229 pnode->list = pathtail = pathnode;
5230 }
5231 }
5232 }
5233
5234 if (count == 0)
5235 {
5236 free(pnode);
5237 }
5238 else
5239 {
5240 if (data->list)
5241 {
5242 tail->next = pnode;
5243 tail = pnode;
5244 }
5245 else
5246 {
5247 data->list = tail = pnode;
5248 }
5249 }
5250 }
5251
5252 return 0;
5253 }
5254
5255
5256
5257 #if 0
5258 #endif
5259
5260
5261 static int ventoy_load_old_json(const char *filename)
5262 {
5263 int ret = 0;
5264 int offset = 0;
5265 int buflen = 0;
5266 char *buffer = NULL;
5267 unsigned char *start = NULL;
5268 VTOY_JSON *json = NULL;
5269 VTOY_JSON *node = NULL;
5270 VTOY_JSON *next = NULL;
5271
5272 ret = ventoy_read_file_to_buf(filename, 4, (void **)&buffer, &buflen);
5273 if (ret)
5274 {
5275 vlog("Failed to read old ventoy.json file.\n");
5276 return 1;
5277 }
5278 buffer[buflen] = 0;
5279
5280 start = (unsigned char *)buffer;
5281
5282 if (start[0] == 0xef && start[1] == 0xbb && start[2] == 0xbf)
5283 {
5284 offset = 3;
5285 }
5286 else if ((start[0] == 0xff && start[1] == 0xfe) || (start[0] == 0xfe && start[1] == 0xff))
5287 {
5288 vlog("ventoy.json is in UCS-2 encoding, ignore it.\n");
5289 free(buffer);
5290 return 1;
5291 }
5292
5293 json = vtoy_json_create();
5294 if (!json)
5295 {
5296 free(buffer);
5297 return 1;
5298 }
5299
5300 if (vtoy_json_parse_ex(json, buffer + offset, buflen - offset) == JSON_SUCCESS)
5301 {
5302 vlog("parse ventoy.json success\n");
5303
5304 for (node = json->pstChild; node; node = node->pstNext)
5305 for (next = node->pstNext; next; next = next->pstNext)
5306 {
5307 if (node->pcName && next->pcName && strcmp(node->pcName, next->pcName) == 0)
5308 {
5309 vlog("ventoy.json contains duplicate key <%s>.\n", node->pcName);
5310 g_sysinfo.invalid_config = 1;
5311 ret = 1;
5312 goto end;
5313 }
5314 }
5315
5316 for (node = json->pstChild; node; node = node->pstNext)
5317 {
5318 ventoy_parse_json(control);
5319 ventoy_parse_json(theme);
5320 ventoy_parse_json(menu_alias);
5321 ventoy_parse_json(menu_tip);
5322 ventoy_parse_json(menu_class);
5323 ventoy_parse_json(auto_install);
5324 ventoy_parse_json(persistence);
5325 ventoy_parse_json(injection);
5326 ventoy_parse_json(conf_replace);
5327 ventoy_parse_json(password);
5328 ventoy_parse_json(image_list);
5329 ventoy_parse_json(image_blacklist);
5330 ventoy_parse_json(auto_memdisk);
5331 ventoy_parse_json(dud);
5332 }
5333 }
5334 else
5335 {
5336 vlog("ventoy.json has syntax error.\n");
5337 g_sysinfo.syntax_error = 1;
5338 ret = 1;
5339 }
5340
5341 end:
5342 vtoy_json_destroy(json);
5343
5344 free(buffer);
5345 return ret;
5346 }
5347
5348
5349 int ventoy_http_start(const char *ip, const char *port)
5350 {
5351 int i = 0;
5352 int ret = 0;
5353 char addr[128];
5354 char filename[128];
5355 char backupname[128];
5356 struct mg_callbacks callbacks;
5357 const char *options[] =
5358 {
5359 "listening_ports", "24681",
5360 "document_root", "www",
5361 "index_files", "index.html",
5362 "num_threads", "16",
5363 "error_log_file", LOG_FILE,
5364 "request_timeout_ms", "10000",
5365 NULL
5366 };
5367
5368 for (i = 0; i <= bios_max; i++)
5369 {
5370 ventoy_data_default_control(g_data_control + i);
5371 ventoy_data_default_theme(g_data_theme + i);
5372 ventoy_data_default_menu_alias(g_data_menu_alias + i);
5373 ventoy_data_default_menu_class(g_data_menu_class + i);
5374 ventoy_data_default_menu_tip(g_data_menu_tip + i);
5375 ventoy_data_default_auto_install(g_data_auto_install + i);
5376 ventoy_data_default_persistence(g_data_persistence + i);
5377 ventoy_data_default_injection(g_data_injection + i);
5378 ventoy_data_default_conf_replace(g_data_conf_replace + i);
5379 ventoy_data_default_password(g_data_password + i);
5380 ventoy_data_default_image_list(g_data_image_list + i);
5381 ventoy_data_default_auto_memdisk(g_data_auto_memdisk + i);
5382 ventoy_data_default_dud(g_data_dud + i);
5383 }
5384
5385 ventoy_get_json_path(filename, backupname);
5386 if (ventoy_is_file_exist("%s", filename))
5387 {
5388 ventoy_copy_file(filename, backupname);
5389 ret = ventoy_load_old_json(filename);
5390 if (ret == 0)
5391 {
5392 ventoy_data_real_save_all(0);
5393 }
5394 }
5395
5396 /* option */
5397 scnprintf(addr, sizeof(addr), "%s:%s", ip, port);
5398 options[1] = addr;
5399
5400 memset(&callbacks, 0, sizeof(callbacks));
5401 callbacks.begin_request = ventoy_request_handler;
5402 #ifndef VENTOY_SIM
5403 callbacks.open_file = ventoy_web_openfile;
5404 #endif
5405 g_ventoy_http_ctx = mg_start(&callbacks, NULL, options);
5406
5407 ventoy_start_writeback_thread(ventoy_http_writeback);
5408
5409 return g_ventoy_http_ctx ? 0 : 1;
5410 }
5411
5412 int ventoy_http_stop(void)
5413 {
5414 if (g_ventoy_http_ctx)
5415 {
5416 mg_stop(g_ventoy_http_ctx);
5417 }
5418
5419 ventoy_stop_writeback_thread();
5420 return 0;
5421 }
5422
5423 int ventoy_http_init(void)
5424 {
5425 int i = 0;
5426
5427 #ifdef VENTOY_SIM
5428 char *Buffer = NULL;
5429 int BufLen = 0;
5430
5431 ventoy_read_file_to_buf("www/menulist", 4, (void **)&Buffer, &BufLen);
5432 if (Buffer)
5433 {
5434 for (i = 0; i < BufLen / 5; i++)
5435 {
5436 memcpy(g_ventoy_menu_lang[i], Buffer + i * 5, 5);
5437 g_ventoy_menu_lang[i][5] = 0;
5438 }
5439 free(Buffer);
5440 }
5441 #else
5442 ventoy_file *file;
5443
5444 file = ventoy_tar_find_file("www/menulist");
5445 if (file)
5446 {
5447 for (i = 0; i < file->size / 5; i++)
5448 {
5449 memcpy(g_ventoy_menu_lang[i], (char *)(file->addr) + i * 5, 5);
5450 g_ventoy_menu_lang[i][5] = 0;
5451 }
5452 }
5453 #endif
5454
5455 if (!g_pub_json_buffer)
5456 {
5457 g_pub_json_buffer = malloc(JSON_BUF_MAX * 2);
5458 g_pub_save_buffer = g_pub_json_buffer + JSON_BUF_MAX;
5459 }
5460
5461
5462 pthread_mutex_init(&g_api_mutex, NULL);
5463 return 0;
5464 }
5465
5466 void ventoy_http_exit(void)
5467 {
5468 check_free(g_pub_json_buffer);
5469 g_pub_json_buffer = NULL;
5470 g_pub_save_buffer = NULL;
5471
5472 pthread_mutex_destroy(&g_api_mutex);
5473 }
5474
5475