ReactOS 0.4.15-dev-7788-g1ad9096
regproc.c
Go to the documentation of this file.
1/*
2 * Registry processing routines. Routines, common for registry
3 * processing frontends.
4 *
5 * Copyright 1999 Sylvain St-Germain
6 * Copyright 2002 Andriy Palamarchuk
7 * Copyright 2008 Alexander N. Sørnes <alex@thehandofagony.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#ifdef __REACTOS__
25#include <fcntl.h>
26#include <io.h>
27#include "regedit.h"
28#else
29#include <errno.h>
30#include <fcntl.h>
31#include <io.h>
32#include <windows.h>
33#include <commctrl.h>
34
35#include "main.h"
36#endif
37
38#define REG_VAL_BUF_SIZE 4096
39
40static HKEY reg_class_keys[] = {
43 };
44
45/******************************************************************************
46 * Allocates memory and converts input from multibyte to wide chars
47 * Returned string must be freed by the caller
48 */
49static WCHAR* GetWideString(const char* strA)
50{
51 if(strA)
52 {
53 WCHAR* strW;
54 int len = MultiByteToWideChar(CP_ACP, 0, strA, -1, NULL, 0);
55
56 strW = malloc(len * sizeof(WCHAR));
58 return strW;
59 }
60 return NULL;
61}
62
63/******************************************************************************
64 * Allocates memory and converts input from multibyte to wide chars
65 * Returned string must be freed by the caller
66 */
67static WCHAR* GetWideStringN(const char* strA, int chars, DWORD *len)
68{
69 if(strA)
70 {
71 WCHAR* strW;
72 *len = MultiByteToWideChar(CP_ACP, 0, strA, chars, NULL, 0);
73
74 strW = malloc(*len * sizeof(WCHAR));
75 MultiByteToWideChar(CP_ACP, 0, strA, chars, strW, *len);
76 return strW;
77 }
78 *len = 0;
79 return NULL;
80}
81
82/******************************************************************************
83 * Allocates memory and converts input from wide chars to multibyte
84 * Returned string must be freed by the caller
85 */
87{
88 if(strW)
89 {
90 char* strA;
91 int len = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL);
92
93 strA = malloc(len);
95 return strA;
96 }
97 return NULL;
98}
99
100/******************************************************************************
101 * Allocates memory and converts input from wide chars to multibyte
102 * Returned string must be freed by the caller
103 */
104static char* GetMultiByteStringN(const WCHAR* strW, int chars, DWORD* len)
105{
106 if(strW)
107 {
108 char* strA;
109 *len = WideCharToMultiByte(CP_ACP, 0, strW, chars, NULL, 0, NULL, NULL);
110
111 strA = malloc(*len);
113 return strA;
114 }
115 *len = 0;
116 return NULL;
117}
118
119static WCHAR *(*get_line)(FILE *);
120
121/* parser definitions */
123{
124 HEADER, /* parsing the registry file version header */
125 PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */
126 LINE_START, /* at the beginning of a registry line */
127 KEY_NAME, /* parsing a key name */
128 DELETE_KEY, /* deleting a registry key */
129 DEFAULT_VALUE_NAME, /* parsing a default value name */
130 QUOTED_VALUE_NAME, /* parsing a double-quoted value name */
131 DATA_START, /* preparing for data parsing operations */
132 DELETE_VALUE, /* deleting a registry value */
133 DATA_TYPE, /* parsing the registry data type */
134 STRING_DATA, /* parsing REG_SZ data */
135 DWORD_DATA, /* parsing DWORD data */
136 HEX_DATA, /* parsing REG_BINARY, REG_NONE, REG_EXPAND_SZ or REG_MULTI_SZ data */
137 EOL_BACKSLASH, /* preparing to parse multiple lines of hex data */
138 HEX_MULTILINE, /* parsing multiple lines of hex data */
139 UNKNOWN_DATA, /* parsing an unhandled or invalid data type */
140 SET_VALUE, /* adding a value to the registry */
143
144struct parser
145{
146 FILE *file; /* pointer to a registry file */
147 WCHAR two_wchars[2]; /* first two characters from the encoding check */
148 BOOL is_unicode; /* parsing Unicode or ASCII data */
149 short int reg_version; /* registry file version */
150 HKEY hkey; /* current registry key */
151 WCHAR *key_name; /* current key name */
152 WCHAR *value_name; /* value name */
153 DWORD parse_type; /* generic data type for parsing */
154 DWORD data_type; /* data type */
155 void *data; /* value data */
156 DWORD data_size; /* size of the data (in bytes) */
157 BOOL backslash; /* TRUE if the current line contains a backslash */
158 enum parser_state state; /* current parser state */
159};
160
161typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
162
163/* parser state machine functions */
164static WCHAR *header_state(struct parser *parser, WCHAR *pos);
166static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
167static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
168static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
171static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
172static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
173static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
174static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
175static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
176static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
179static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
180static WCHAR *set_value_state(struct parser *parser, WCHAR *pos);
181
183{
184 header_state, /* HEADER */
185 parse_win31_line_state, /* PARSE_WIN31_LINE */
186 line_start_state, /* LINE_START */
187 key_name_state, /* KEY_NAME */
188 delete_key_state, /* DELETE_KEY */
189 default_value_name_state, /* DEFAULT_VALUE_NAME */
190 quoted_value_name_state, /* QUOTED_VALUE_NAME */
191 data_start_state, /* DATA_START */
192 delete_value_state, /* DELETE_VALUE */
193 data_type_state, /* DATA_TYPE */
194 string_data_state, /* STRING_DATA */
195 dword_data_state, /* DWORD_DATA */
196 hex_data_state, /* HEX_DATA */
197 eol_backslash_state, /* EOL_BACKSLASH */
198 hex_multiline_state, /* HEX_MULTILINE */
199 unknown_data_state, /* UNKNOWN_DATA */
200 set_value_state, /* SET_VALUE */
201};
202
203/* set the new parser state and return the previous one */
204static inline enum parser_state set_state(struct parser *parser, enum parser_state state)
205{
207 parser->state = state;
208 return ret;
209}
210
211/******************************************************************************
212 * Converts a hex representation of a DWORD into a DWORD.
213 */
215{
216 WCHAR *p, *end;
217 int count = 0;
218
219 while (*str == ' ' || *str == '\t') str++;
220 if (!*str) goto error;
221
222 p = str;
223 while (iswxdigit(*p))
224 {
225 count++;
226 p++;
227 }
228 if (count > 8) goto error;
229
230 end = p;
231 while (*p == ' ' || *p == '\t') p++;
232 if (*p && *p != ';') goto error;
233
234 *end = 0;
235 *dw = wcstoul(str, &end, 16);
236 return TRUE;
237
238error:
239 return FALSE;
240}
241
242/******************************************************************************
243 * Converts comma-separated hex data into a binary string and modifies
244 * the input parameter to skip the concatenating backslash, if found.
245 *
246 * Returns TRUE or FALSE to indicate whether parsing was successful.
247 */
249{
250 size_t size;
251 BYTE *d;
252 WCHAR *s;
253
255
256 /* The worst case is 1 digit + 1 comma per byte */
257 size = ((lstrlenW(*str) + 1) / 2) + parser->data_size;
259
260 s = *str;
261 d = (BYTE *)parser->data + parser->data_size;
262
263 while (*s)
264 {
265 WCHAR *end;
266 unsigned long wc;
267
268 wc = wcstoul(s, &end, 16);
269 if (wc > 0xff) return FALSE;
270
271 if (s == end && wc == 0)
272 {
273 while (*end == ' ' || *end == '\t') end++;
274 if (*end == '\\')
275 {
277 *str = end + 1;
278 return TRUE;
279 }
280 else if (*end == ';')
281 return TRUE;
282 return FALSE;
283 }
284
285 *d++ = wc;
286 parser->data_size++;
287
288 if (*end && *end != ',')
289 {
290 while (*end == ' ' || *end == '\t') end++;
291 if (*end && *end != ';') return FALSE;
292 return TRUE;
293 }
294
295 if (*end) end++;
296 s = end;
297 }
298
299 return TRUE;
300}
301
302/******************************************************************************
303 * Parses the data type of the registry value being imported and modifies
304 * the input parameter to skip the string representation of the data type.
305 *
306 * Returns TRUE or FALSE to indicate whether a data type was found.
307 */
309{
310 struct data_type { const WCHAR *tag; int len; int type; int parse_type; };
311
312 static const struct data_type data_types[] = {
313 /* tag len type parse type */
314 { L"\"", 1, REG_SZ, REG_SZ },
315 { L"hex:", 4, REG_BINARY, REG_BINARY },
316 { L"dword:", 6, REG_DWORD, REG_DWORD },
317 { L"hex(", 4, -1, REG_BINARY }, /* REG_NONE, REG_EXPAND_SZ, REG_MULTI_SZ */
318 { NULL, 0, 0, 0 }
319 };
320
321 const struct data_type *ptr;
322
323 for (ptr = data_types; ptr->tag; ptr++)
324 {
325 if (wcsncmp(ptr->tag, *line, ptr->len))
326 continue;
327
328 parser->parse_type = ptr->parse_type;
329 parser->data_type = ptr->parse_type;
330 *line += ptr->len;
331
332 if (ptr->type == -1)
333 {
334 WCHAR *end;
335 DWORD val;
336
337 if (!**line || towlower((*line)[1]) == 'x')
338 return FALSE;
339
340 /* "hex(xx):" is special */
341 val = wcstoul(*line, &end, 16);
342#ifdef __REACTOS__
343 /* Up to 8 hex digits, "hex(000000002)" is invalid */
344 if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE) || end - *line > 8)
345#else
346 if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE))
347#endif
348 return FALSE;
349
351 *line = end + 2;
352 }
353 return TRUE;
354 }
355 return FALSE;
356}
357
358/******************************************************************************
359 * Replaces escape sequences with their character equivalents and
360 * null-terminates the string on the first non-escaped double quote.
361 *
362 * Assigns a pointer to the remaining unparsed data in the line.
363 * Returns TRUE or FALSE to indicate whether a closing double quote was found.
364 */
366{
367 int str_idx = 0; /* current character under analysis */
368 int val_idx = 0; /* the last character of the unescaped string */
369 int len = lstrlenW(str);
370 BOOL ret;
371
372 for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
373 if (str[str_idx] == '\\') {
374 str_idx++;
375 switch (str[str_idx]) {
376 case 'n':
377 str[val_idx] = '\n';
378 break;
379 case 'r':
380 str[val_idx] = '\r';
381 break;
382 case '0':
383 return FALSE;
384 case '\\':
385 case '"':
386 str[val_idx] = str[str_idx];
387 break;
388 default:
389 if (!str[str_idx]) return FALSE;
391 str[val_idx] = str[str_idx];
392 break;
393 }
394 } else if (str[str_idx] == '"') {
395 break;
396 } else {
397 str[val_idx] = str[str_idx];
398 }
399 }
400
401 ret = (str[str_idx] == '"');
402 *unparsed = str + str_idx + 1;
403 str[val_idx] = '\0';
404 return ret;
405}
406
408{
409 unsigned int i;
410
411 if (!key_name) return 0;
412
413 *key_path = wcschr(key_name, '\\');
414 if (*key_path) (*key_path)++;
415
416 for (i = 0; i < ARRAY_SIZE(reg_class_keys); i++)
417 {
419#ifdef __REACTOS__
421#else
423#endif
424 (key_name[len] == 0 || key_name[len] == '\\'))
425 {
426 return reg_class_keys[i];
427 }
428 }
429
430 return 0;
431}
432
433static void close_key(struct parser *parser)
434{
435 if (parser->hkey)
436 {
439
441 parser->hkey = NULL;
442 }
443}
444
445/******************************************************************************
446 * Opens the registry key given by the input path.
447 * This key must be closed by calling close_key().
448 */
450{
451 HKEY key_class;
452 WCHAR *key_path;
453 LONG res;
454
456
457 /* Get the registry class */
458 if (!path || !(key_class = parse_key_name(path, &key_path)))
460
461 res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
463
464 if (res == ERROR_SUCCESS)
465 {
466 parser->key_name = malloc((lstrlenW(path) + 1) * sizeof(WCHAR));
468 }
469 else
470 parser->hkey = NULL;
471
472 return res;
473}
474
475static void free_parser_data(struct parser *parser)
476{
478 free(parser->data);
479
480 parser->data = NULL;
481 parser->data_size = 0;
482}
483
485{
488 {
489 if (parser->is_unicode)
490 {
491 WCHAR *data = parser->data;
492 DWORD len = parser->data_size / sizeof(WCHAR);
493
494 if (data[len - 1] != 0)
495 {
496 data[len] = 0;
497 parser->data_size += sizeof(WCHAR);
498 }
499 }
500 else
501 {
502 BYTE *data = parser->data;
503
504 if (data[parser->data_size - 1] != 0)
505 {
506 data[parser->data_size] = 0;
507 parser->data_size++;
508 }
509
511 parser->data_size *= sizeof(WCHAR);
512 free(data);
513 }
514 }
515}
516
524
526{
527 static const WCHAR header_31[] = L"REGEDIT";
528
529 while (*s == ' ' || *s == '\t') s++;
530
531 if (!lstrcmpW(s, header_31))
532 return REG_VERSION_31;
533
534 if (!lstrcmpW(s, L"REGEDIT4"))
535 return REG_VERSION_40;
536
537 if (!lstrcmpW(s, L"Windows Registry Editor Version 5.00"))
538 return REG_VERSION_50;
539
540 /* The Windows version accepts registry file headers beginning with "REGEDIT" and ending
541 * with other characters, as long as "REGEDIT" appears at the start of the line. For example,
542 * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all treated as valid file headers.
543 * In all such cases, however, the contents of the registry file are not imported.
544 */
545 if (!wcsncmp(s, header_31, 7)) /* "REGEDIT" without NUL */
546 return REG_VERSION_FUZZY;
547
548 return REG_VERSION_INVALID;
549}
550
551/* handler for parser HEADER state */
553{
554 WCHAR *line, *header;
555
556 if (!(line = get_line(parser->file)))
557 return NULL;
558
559 if (!parser->is_unicode)
560 {
561 header = malloc((lstrlenW(line) + 3) * sizeof(WCHAR));
562 header[0] = parser->two_wchars[0];
563 header[1] = parser->two_wchars[1];
564 lstrcpyW(header + 2, line);
566 free(header);
567 }
569
570 switch (parser->reg_version)
571 {
572 case REG_VERSION_31:
574 break;
575 case REG_VERSION_40:
576 case REG_VERSION_50:
578 break;
579 default:
580 get_line(NULL); /* Reset static variables */
581 return NULL;
582 }
583
584 return line;
585}
586
587/* handler for parser PARSE_WIN31_LINE state */
589{
590 WCHAR *line, *value;
591 static WCHAR hkcr[] = L"HKEY_CLASSES_ROOT";
592 unsigned int key_end = 0;
593
594 if (!(line = get_line(parser->file)))
595 return NULL;
596
597 if (wcsncmp(line, hkcr, lstrlenW(hkcr)))
598 return line;
599
600 /* get key name */
601 while (line[key_end] && !iswspace(line[key_end])) key_end++;
602
603 value = line + key_end;
604 while (*value == ' ' || *value == '\t') value++;
605
606 if (*value == '=') value++;
607 if (*value == ' ') value++; /* at most one space is skipped */
608
609 line[key_end] = 0;
610
612 {
614 return line;
615 }
616
619 parser->data = value;
620 parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
621
623 return value;
624}
625
626/* handler for parser LINE_START state */
628{
629 WCHAR *line, *p;
630
631 if (!(line = get_line(parser->file)))
632 return NULL;
633
634 for (p = line; *p; p++)
635 {
636 switch (*p)
637 {
638 case '[':
640 return p + 1;
641 case '@':
643 return p;
644 case '"':
646 return p + 1;
647 case ' ':
648 case '\t':
649 break;
650 default:
651 return p;
652 }
653 }
654
655 return p;
656}
657
658/* handler for parser KEY_NAME state */
660{
661 WCHAR *p = pos, *key_end;
662
663 if (*p == ' ' || *p == '\t' || !(key_end = wcsrchr(p, ']')))
664 goto done;
665
666 *key_end = 0;
667
668 if (*p == '-')
669 {
671 return p + 1;
672 }
673 else if (open_key(parser, p) != ERROR_SUCCESS)
675
676done:
678 return p;
679}
680
681/* handler for parser DELETE_KEY state */
683{
684 WCHAR *p = pos;
685
687
688 if (*p == 'H' || *p == 'h')
690
692 return p;
693}
694
695/* handler for parser DEFAULT_VALUE_NAME state */
697{
700
702 return pos + 1;
703}
704
705/* handler for parser QUOTED_VALUE_NAME state */
707{
708 WCHAR *val_name = pos, *p;
709
712
713 if (!REGPROC_unescape_string(val_name, &p))
714 goto invalid;
715
716 /* copy the value name in case we need to parse multiple lines and the buffer is overwritten */
717 parser->value_name = malloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
718 lstrcpyW(parser->value_name, val_name);
719
721 return p;
722
723invalid:
725 return val_name;
726}
727
728/* handler for parser DATA_START state */
730{
731 WCHAR *p = pos;
732 unsigned int len;
733
734 while (*p == ' ' || *p == '\t') p++;
735 if (*p != '=') goto done;
736 p++;
737 while (*p == ' ' || *p == '\t') p++;
738
739 /* trim trailing whitespace */
740 len = lstrlenW(p);
741 while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t')) len--;
742 p[len] = 0;
743
744 if (*p == '-')
746 else
748 return p;
749
750done:
752 return p;
753}
754
755/* handler for parser DELETE_VALUE state */
757{
758 WCHAR *p = pos + 1;
759
760 while (*p == ' ' || *p == '\t') p++;
761 if (*p && *p != ';') goto done;
762
764
765done:
767 return p;
768}
769
770/* handler for parser DATA_TYPE state */
772{
773 WCHAR *line = pos;
774
776 {
778 return line;
779 }
780
781 switch (parser->parse_type)
782 {
783 case REG_SZ:
785 break;
786 case REG_DWORD:
788 break;
789 case REG_BINARY: /* all hex data types, including undefined */
791 break;
792 default:
794 }
795
796 return line;
797}
798
799/* handler for parser STRING_DATA state */
801{
802 WCHAR *line;
803
804 parser->data = pos;
805
807 goto invalid;
808
809 while (*line == ' ' || *line == '\t') line++;
810 if (*line && *line != ';') goto invalid;
811
812 parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
813
815 return line;
816
817invalid:
820 return line;
821}
822
823/* handler for parser DWORD_DATA state */
825{
826 WCHAR *line = pos;
827
828 parser->data = malloc(sizeof(DWORD));
829
831 goto invalid;
832
833 parser->data_size = sizeof(DWORD);
834
836 return line;
837
838invalid:
841 return line;
842}
843
844/* handler for parser HEX_DATA state */
846{
847 WCHAR *line = pos;
848
849 if (!*line)
850 goto set_value;
851
853 goto invalid;
854
855 if (parser->backslash)
856 {
858 return line;
859 }
860
862
865 return line;
866
867invalid:
870 return line;
871}
872
873/* handler for parser EOL_BACKSLASH state */
875{
876 WCHAR *p = pos;
877
878 while (*p == ' ' || *p == '\t') p++;
879 if (*p && *p != ';') goto invalid;
880
882 return pos;
883
884invalid:
887 return p;
888}
889
890/* handler for parser HEX_MULTILINE state */
892{
893 WCHAR *line;
894
895 if (!(line = get_line(parser->file)))
896 {
899 return pos;
900 }
901
902 while (*line == ' ' || *line == '\t') line++;
903 if (!*line || *line == ';') return line;
904
905 if (!iswxdigit(*line)) goto invalid;
906
908 return line;
909
910invalid:
913 return line;
914}
915
916/* handler for parser UNKNOWN_DATA state */
918{
920
922 return pos;
923}
924
925/* handler for parser SET_VALUE state */
927{
930
932
935 else
937
938 return pos;
939}
940
941static WCHAR *get_lineA(FILE *fp)
942{
943 static WCHAR *lineW;
944 static size_t size;
945 static char *buf, *next;
946 char *line;
947
948 free(lineW);
949
950 if (!fp) goto cleanup;
951
952 if (!size)
953 {
955 buf = malloc(size);
956 *buf = 0;
957 next = buf;
958 }
959 line = next;
960
961 while (next)
962 {
963 char *p = strpbrk(line, "\r\n");
964 if (!p)
965 {
966 size_t len, count;
967 len = strlen(next);
968 memmove(buf, next, len + 1);
969 if (size - len < 3)
970 {
971 size *= 2;
972 buf = realloc(buf, size);
973 }
974 if (!(count = fread(buf + len, 1, size - len - 1, fp)))
975 {
976 next = NULL;
977 lineW = GetWideString(buf);
978 return lineW;
979 }
980 buf[len + count] = 0;
981 next = buf;
982 line = buf;
983 continue;
984 }
985 next = p + 1;
986 if (*p == '\r' && *(p + 1) == '\n') next++;
987 *p = 0;
988 lineW = GetWideString(line);
989 return lineW;
990 }
991
992cleanup:
993 lineW = NULL;
994 if (size) free(buf);
995 size = 0;
996 return NULL;
997}
998
999static WCHAR *get_lineW(FILE *fp)
1000{
1001 static size_t size;
1002 static WCHAR *buf, *next;
1003 WCHAR *line;
1004
1005 if (!fp) goto cleanup;
1006
1007 if (!size)
1008 {
1010 buf = malloc(size * sizeof(WCHAR));
1011 *buf = 0;
1012 next = buf;
1013 }
1014 line = next;
1015
1016 while (next)
1017 {
1018 WCHAR *p = wcspbrk(line, L"\r\n");
1019 if (!p)
1020 {
1021 size_t len, count;
1022 len = lstrlenW(next);
1023 memmove(buf, next, (len + 1) * sizeof(WCHAR));
1024 if (size - len < 3)
1025 {
1026 size *= 2;
1027 buf = realloc(buf, size * sizeof(WCHAR));
1028 }
1029 if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
1030 {
1031 next = NULL;
1032 return buf;
1033 }
1034 buf[len + count] = 0;
1035 next = buf;
1036 line = buf;
1037 continue;
1038 }
1039 next = p + 1;
1040 if (*p == '\r' && *(p + 1) == '\n') next++;
1041 *p = 0;
1042 return line;
1043 }
1044
1045cleanup:
1046 if (size) free(buf);
1047 size = 0;
1048 return NULL;
1049}
1050
1051/******************************************************************************
1052 * Reads contents of the specified file into the registry.
1053 */
1055{
1056 BYTE s[2];
1057 struct parser parser;
1058 WCHAR *pos;
1059
1060 if (!reg_file || (fread(s, 2, 1, reg_file) != 1))
1061 return FALSE;
1062
1063 parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
1065
1066 parser.file = reg_file;
1067 parser.two_wchars[0] = s[0];
1068 parser.two_wchars[1] = s[1];
1069 parser.reg_version = -1;
1070 parser.hkey = NULL;
1073 parser.parse_type = 0;
1074 parser.data_type = 0;
1075 parser.data = NULL;
1076 parser.data_size = 0;
1079
1081
1082 /* parser main loop */
1083 while (pos)
1085
1088
1090 close_key(&parser);
1091
1092 return TRUE;
1093}
1094
1095/******************************************************************************
1096 * Removes the registry key with all subkeys. Parses full key name.
1097 *
1098 * Parameters:
1099 * reg_key_name - full name of registry branch to delete. Ignored if is NULL,
1100 * empty, points to register key class, does not exist.
1101 */
1102void delete_registry_key(WCHAR *reg_key_name)
1103{
1104 WCHAR *key_name = NULL;
1105 HKEY key_class;
1106
1107 if (!reg_key_name || !reg_key_name[0])
1108 return;
1109
1110 if (!(key_class = parse_key_name(reg_key_name, &key_name)))
1111 {
1112 if (key_name) *(key_name - 1) = 0;
1113#ifdef __REACTOS__
1115 return;
1116#else
1118#endif
1119 }
1120
1121 if (!key_name || !*key_name)
1122#ifdef __REACTOS__
1123 {
1124 output_message(STRING_DELETE_FAILED, reg_key_name);
1125 return;
1126 }
1127#else
1128 error_exit(STRING_DELETE_FAILED, reg_key_name);
1129#endif
1130
1131#ifdef __REACTOS__
1132 SHDeleteKey(key_class, key_name);
1133#else
1134 RegDeleteTreeW(key_class, key_name);
1135#endif
1136}
1137
1138static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
1139{
1140 if (unicode)
1141 fwrite(str, sizeof(WCHAR), lstrlenW(str), fp);
1142 else
1143 {
1144 char *strA = GetMultiByteString(str);
1145 fputs(strA, fp);
1146 free(strA);
1147 }
1148}
1149
1150static WCHAR *REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
1151{
1152 size_t i, escape_count, pos;
1153 WCHAR *buf;
1154
1155 for (i = 0, escape_count = 0; i < str_len; i++)
1156 {
1157 WCHAR c = str[i];
1158
1159 if (!c) break;
1160
1161 if (c == '\r' || c == '\n' || c == '\\' || c == '"')
1162 escape_count++;
1163 }
1164
1165 buf = malloc((str_len + escape_count + 1) * sizeof(WCHAR));
1166
1167 for (i = 0, pos = 0; i < str_len; i++, pos++)
1168 {
1169 WCHAR c = str[i];
1170
1171 if (!c) break;
1172
1173 switch (c)
1174 {
1175 case '\r':
1176 buf[pos++] = '\\';
1177 buf[pos] = 'r';
1178 break;
1179 case '\n':
1180 buf[pos++] = '\\';
1181 buf[pos] = 'n';
1182 break;
1183 case '\\':
1184 buf[pos++] = '\\';
1185 buf[pos] = '\\';
1186 break;
1187 case '"':
1188 buf[pos++] = '\\';
1189 buf[pos] = '"';
1190 break;
1191 default:
1192 buf[pos] = c;
1193 }
1194 }
1195
1196 buf[pos] = 0;
1197 *line_len = pos;
1198 return buf;
1199}
1200
1201static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
1202{
1203 static const WCHAR default_name[] = L"@=";
1204 size_t line_len;
1205
1206 if (name && *name)
1207 {
1208 WCHAR *str = REGPROC_escape_string(name, len, &line_len);
1209 WCHAR *buf = malloc((line_len + 4) * sizeof(WCHAR));
1210#ifdef __REACTOS__
1211 StringCchPrintfW(buf, line_len + 4, L"\"%s\"=", str);
1212 line_len = wcslen(buf);
1213#else
1214 line_len = swprintf(buf, line_len + 4, L"\"%s\"=", str);
1215#endif
1216 REGPROC_write_line(fp, buf, unicode);
1217 free(buf);
1218 free(str);
1219 }
1220 else
1221 {
1222 line_len = lstrlenW(default_name);
1223 REGPROC_write_line(fp, default_name, unicode);
1224 }
1225
1226 return line_len;
1227}
1228
1229static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
1230{
1231 size_t len = 0, line_len;
1232 WCHAR *str;
1233
1234 if (size)
1235 len = size / sizeof(WCHAR) - 1;
1236 str = REGPROC_escape_string(data, len, &line_len);
1237 *buf = malloc((line_len + 3) * sizeof(WCHAR));
1238#ifdef __REACTOS__
1239 StringCchPrintfW(*buf, line_len + 3, L"\"%s\"", str);
1240#else
1241 swprintf(*buf, line_len + 3, L"\"%s\"", str);
1242#endif
1243 free(str);
1244}
1245
1247{
1248 *buf = malloc(15 * sizeof(WCHAR));
1249#ifdef __REACTOS__
1250 StringCchPrintfW(*buf, 15, L"dword:%08x", *data);
1251#else
1252 swprintf(*buf, 15, L"dword:%08x", *data);
1253#endif
1254}
1255
1256static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
1257{
1258 static const WCHAR hex[] = L"hex:";
1259 size_t line_len;
1260
1261 if (type == REG_BINARY)
1262 {
1263 line_len = lstrlenW(hex);
1264 REGPROC_write_line(fp, hex, unicode);
1265 }
1266 else
1267 {
1268 WCHAR *buf = malloc(15 * sizeof(WCHAR));
1269#ifdef __REACTOS__
1270 StringCchPrintfW(buf, 15, L"hex(%x):", type);
1271 line_len = wcslen(buf);
1272#else
1273 line_len = swprintf(buf, 15, L"hex(%x):", type);
1274#endif
1275 REGPROC_write_line(fp, buf, unicode);
1276 free(buf);
1277 }
1278
1279 return line_len;
1280}
1281
1282#define MAX_HEX_CHARS 77
1283
1284static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len,
1285 void *data, DWORD size, BOOL unicode)
1286{
1287 size_t num_commas, i, pos;
1288
1289 line_len += export_hex_data_type(fp, type, unicode);
1290
1291 if (!size) return;
1292
1293 if (!unicode && (type == REG_EXPAND_SZ || type == REG_MULTI_SZ))
1294 data = GetMultiByteStringN(data, size / sizeof(WCHAR), &size);
1295
1296 num_commas = size - 1;
1297 *buf = malloc(size * 3 * sizeof(WCHAR));
1298
1299 for (i = 0, pos = 0; i < size; i++)
1300 {
1301#ifdef __REACTOS__
1302 StringCchPrintfW(*buf + pos, 3, L"%02x", ((BYTE *)data)[i]);
1303 pos += wcslen(*buf + pos);
1304#else
1305 pos += swprintf(*buf + pos, 3, L"%02x", ((BYTE *)data)[i]);
1306#endif
1307 if (i == num_commas) break;
1308 (*buf)[pos++] = ',';
1309 (*buf)[pos] = 0;
1310 line_len += 3;
1311
1312 if (line_len >= MAX_HEX_CHARS)
1313 {
1314 REGPROC_write_line(fp, *buf, unicode);
1315 REGPROC_write_line(fp, L"\\\r\n ", unicode);
1316 line_len = 2;
1317 pos = 0;
1318 }
1319 }
1320}
1321
1322static void export_newline(FILE *fp, BOOL unicode)
1323{
1324 REGPROC_write_line(fp, L"\r\n", unicode);
1325}
1326
1327static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type,
1328 void *data, size_t size, BOOL unicode)
1329{
1330 WCHAR *buf = NULL;
1331 size_t line_len = export_value_name(fp, value_name, value_len, unicode);
1332
1333 switch (type)
1334 {
1335 case REG_SZ:
1337 break;
1338 case REG_DWORD:
1339 if (size)
1340 {
1342 break;
1343 }
1344 /* fall through */
1345 case REG_NONE:
1346 case REG_EXPAND_SZ:
1347 case REG_BINARY:
1348 case REG_MULTI_SZ:
1349 default:
1350 export_hex_data(fp, &buf, type, line_len, data, size, unicode);
1351 break;
1352 }
1353
1354 if (size || type == REG_SZ)
1355 {
1356 REGPROC_write_line(fp, buf, unicode);
1357 free(buf);
1358 }
1359
1360 export_newline(fp, unicode);
1361}
1362
1363static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
1364{
1365 WCHAR *subkey_path;
1366
1367 subkey_path = malloc((path_len + subkey_len + 2) * sizeof(WCHAR));
1368#ifdef __REACTOS__
1369 StringCchPrintfW(subkey_path, path_len + subkey_len + 2, L"%s\\%s", path, subkey_name);
1370#else
1371 swprintf(subkey_path, path_len + subkey_len + 2, L"%s\\%s", path, subkey_name);
1372#endif
1373
1374 return subkey_path;
1375}
1376
1377static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
1378{
1379 WCHAR *buf;
1380
1381 buf = malloc((lstrlenW(name) + 7) * sizeof(WCHAR));
1382#ifdef __REACTOS__
1383 StringCchPrintfW(buf, lstrlenW(name) + 7, L"\r\n[%s]\r\n", name);
1384#else
1385 swprintf(buf, lstrlenW(name) + 7, L"\r\n[%s]\r\n", name);
1386#endif
1387 REGPROC_write_line(fp, buf, unicode);
1388 free(buf);
1389}
1390
1391#define MAX_SUBKEY_LEN 257
1392
1393static void export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
1394{
1395 LONG rc;
1396 DWORD max_value_len = 256, value_len;
1397 DWORD max_data_bytes = 2048, data_size;
1398 DWORD subkey_len;
1399 DWORD i, type, path_len;
1400 WCHAR *value_name, *subkey_name, *subkey_path;
1401 BYTE *data;
1402 HKEY subkey;
1403
1404 export_key_name(fp, path, unicode);
1405
1406 value_name = malloc(max_value_len * sizeof(WCHAR));
1407 data = malloc(max_data_bytes);
1408
1409 i = 0;
1410 for (;;)
1411 {
1412 value_len = max_value_len;
1413 data_size = max_data_bytes;
1414 rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
1415 if (rc == ERROR_SUCCESS)
1416 {
1417 export_data(fp, value_name, value_len, type, data, data_size, unicode);
1418 i++;
1419 }
1420 else if (rc == ERROR_MORE_DATA)
1421 {
1422 if (data_size > max_data_bytes)
1423 {
1424 max_data_bytes = data_size;
1425 data = realloc(data, max_data_bytes);
1426 }
1427 else
1428 {
1429 max_value_len *= 2;
1430 value_name = realloc(value_name, max_value_len * sizeof(WCHAR));
1431 }
1432 }
1433 else break;
1434 }
1435
1436 free(data);
1438
1439 subkey_name = malloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
1440
1442
1443 i = 0;
1444 for (;;)
1445 {
1446 subkey_len = MAX_SUBKEY_LEN;
1447 rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
1448 if (rc == ERROR_SUCCESS)
1449 {
1450 subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
1451 if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
1452 {
1453 export_registry_data(fp, subkey, subkey_path, unicode);
1454 RegCloseKey(subkey);
1455 }
1456 free(subkey_path);
1457 i++;
1458 }
1459 else break;
1460 }
1461
1462 free(subkey_name);
1463}
1464
1466{
1467 FILE *file;
1468
1469 if (!lstrcmpW(file_name, L"-"))
1470 {
1471 file = stdout;
1473 }
1474 else
1475 {
1476 file = _wfopen(file_name, L"wb");
1477 if (!file)
1478 {
1479 _wperror(L"regedit");
1480#ifdef __REACTOS__
1482 return NULL;
1483#else
1485#endif
1486 }
1487 }
1488
1489 if (unicode)
1490 {
1491 static const BYTE bom[] = {0xff,0xfe};
1492 static const WCHAR header[] = L"Windows Registry Editor Version 5.00\r\n";
1493
1494 fwrite(bom, sizeof(BYTE), ARRAY_SIZE(bom), file);
1495 fwrite(header, sizeof(WCHAR), lstrlenW(header), file);
1496 }
1497 else
1498 fputs("REGEDIT4\r\n", file);
1499
1500 return file;
1501}
1502
1503static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
1504{
1505 HKEY key;
1506
1507 if (!RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key))
1508 return key;
1509
1511 return NULL;
1512}
1513
1515{
1516 HKEY key_class, key;
1517 WCHAR *subkey;
1518 FILE *fp;
1519
1520 if (!(key_class = parse_key_name(path, &subkey)))
1521 {
1522 if (subkey) *(subkey - 1) = 0;
1524 return FALSE;
1525 }
1526
1527 if (!(key = open_export_key(key_class, subkey, path)))
1528 return FALSE;
1529
1530 fp = REGPROC_open_export_file(file_name, unicode);
1531#ifdef __REACTOS__
1532 if (!fp)
1533 return TRUE; /* Error message is already displayed */
1534#endif
1535 export_registry_data(fp, key, path, unicode);
1536 export_newline(fp, unicode);
1537 fclose(fp);
1538
1540 return TRUE;
1541}
1542
1544{
1545 FILE *fp;
1546 int i;
1547 HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
1548 WCHAR *class_name;
1549
1550 fp = REGPROC_open_export_file(file_name, unicode);
1551#ifdef __REACTOS__
1552 if (!fp)
1553 return TRUE; /* Error message is already displayed */
1554#endif
1555
1556 for (i = 0; i < ARRAY_SIZE(classes); i++)
1557 {
1558 if (!(key = open_export_key(classes[i], NULL, path)))
1559 {
1560 fclose(fp);
1561 return FALSE;
1562 }
1563
1564 class_name = malloc((lstrlenW(reg_class_namesW[i]) + 1) * sizeof(WCHAR));
1565 lstrcpyW(class_name, reg_class_namesW[i]);
1566
1567 export_registry_data(fp, classes[i], class_name, unicode);
1568
1569 free(class_name);
1571 }
1572
1573 export_newline(fp, unicode);
1574 fclose(fp);
1575
1576 return TRUE;
1577}
1578
1580{
1581 BOOL unicode = (format == REG_FORMAT_5);
1582
1583 if (path && *path)
1584 return export_key(file_name, path, unicode);
1585 else
1586 return export_all(file_name, path, unicode);
1587}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERANGE
Definition: acclib.h:92
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
static int state
Definition: maze.c:121
parser_state
Definition: import.c:59
reg_versions
Definition: import.c:437
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:92
#define STRING_INVALID_SYSTEM_KEY
Definition: resource.h:54
#define STRING_ESCAPE_SEQUENCE
Definition: resource.h:80
const WCHAR * reg_class_namesW[]
Definition: main.c:25
#define ARRAY_SIZE(A)
Definition: main.h:33
#define REG_FORMAT_5
Definition: main.h:44
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:101
static WCHAR * default_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:696
static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
Definition: regproc.c:1377
#define REG_VAL_BUF_SIZE
Definition: regproc.c:38
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1054
static WCHAR * REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
Definition: regproc.c:1150
static void export_newline(FILE *fp, BOOL unicode)
Definition: regproc.c:1322
static WCHAR * hex_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:845
static WCHAR * dword_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:824
static WCHAR * string_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:800
static WCHAR * key_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:659
static void prepare_hex_string_data(struct parser *parser)
Definition: regproc.c:484
static void export_dword_data(WCHAR **buf, DWORD *data)
Definition: regproc.c:1246
static WCHAR * delete_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:756
static WCHAR * eol_backslash_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:874
#define MAX_HEX_CHARS
Definition: regproc.c:1282
static WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: regproc.c:1363
static WCHAR * data_type_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:771
static BOOL export_all(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1543
static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
Definition: regproc.c:214
static WCHAR * GetWideString(const char *strA)
Definition: regproc.c:49
static HKEY reg_class_keys[]
Definition: regproc.c:40
static enum reg_versions parse_file_header(const WCHAR *s)
Definition: regproc.c:525
static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
Definition: regproc.c:248
static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
Definition: regproc.c:1229
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: regproc.c:204
static void free_parser_data(struct parser *parser)
Definition: regproc.c:475
static void export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
Definition: regproc.c:1393
static WCHAR * set_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:926
static WCHAR * data_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:729
WCHAR *(* parser_state_func)(struct parser *parser, WCHAR *pos)
Definition: regproc.c:161
static WCHAR * GetWideStringN(const char *strA, int chars, DWORD *len)
Definition: regproc.c:67
static WCHAR * get_lineA(FILE *fp)
Definition: regproc.c:941
static BOOL REGPROC_unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: regproc.c:365
static WCHAR * unknown_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:917
static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len, void *data, DWORD size, BOOL unicode)
Definition: regproc.c:1284
static BOOL parse_data_type(struct parser *parser, WCHAR **line)
Definition: regproc.c:308
static char * GetMultiByteStringN(const WCHAR *strW, int chars, DWORD *len)
Definition: regproc.c:104
static FILE * REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
Definition: regproc.c:1465
@ PARSE_WIN31_LINE
Definition: regproc.c:125
@ HEX_DATA
Definition: regproc.c:136
@ DEFAULT_VALUE_NAME
Definition: regproc.c:129
@ HEADER
Definition: regproc.c:124
@ NB_PARSER_STATES
Definition: regproc.c:141
@ STRING_DATA
Definition: regproc.c:134
@ QUOTED_VALUE_NAME
Definition: regproc.c:130
@ DATA_TYPE
Definition: regproc.c:133
@ HEX_MULTILINE
Definition: regproc.c:138
@ UNKNOWN_DATA
Definition: regproc.c:139
@ LINE_START
Definition: regproc.c:126
@ EOL_BACKSLASH
Definition: regproc.c:137
@ SET_VALUE
Definition: regproc.c:140
@ DELETE_VALUE
Definition: regproc.c:132
@ DWORD_DATA
Definition: regproc.c:135
@ KEY_NAME
Definition: regproc.c:127
@ DATA_START
Definition: regproc.c:131
@ DELETE_KEY
Definition: regproc.c:128
@ REG_VERSION_50
Definition: regproc.c:520
@ REG_VERSION_INVALID
Definition: regproc.c:522
@ REG_VERSION_40
Definition: regproc.c:519
@ REG_VERSION_FUZZY
Definition: regproc.c:521
@ REG_VERSION_31
Definition: regproc.c:518
static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
Definition: regproc.c:1201
static WCHAR * get_lineW(FILE *fp)
Definition: regproc.c:999
static WCHAR * quoted_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:706
static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
Definition: regproc.c:407
static WCHAR *(* get_line)(FILE *)
Definition: regproc.c:119
char * GetMultiByteString(const WCHAR *strW)
Definition: regproc.c:86
static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
Definition: regproc.c:1138
static WCHAR * parse_win31_line_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:588
static WCHAR * delete_key_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:682
static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
Definition: regproc.c:1503
static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
Definition: regproc.c:1256
static BOOL export_key(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1514
static WCHAR * hex_multiline_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:891
#define MAX_SUBKEY_LEN
Definition: regproc.c:1391
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1579
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1102
static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type, void *data, size_t size, BOOL unicode)
Definition: regproc.c:1327
static WCHAR * header_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:552
static WCHAR * line_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:627
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: regproc.c:182
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:378
#define STRING_OPEN_KEY_FAILED
Definition: resource.h:388
#define STRING_UNKNOWN_DATA_FORMAT
Definition: resource.h:384
#define STRING_DELETE_FAILED
Definition: resource.h:393
#define RegCloseKey(hKey)
Definition: registry.h:49
#define _setmode(fd, mode)
Definition: cat.c:21
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes, void *dst_data)
Definition: effect.c:889
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2533
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4911
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2361
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2859
#define _O_BINARY
Definition: cabinet.h:51
#define wcschr
Definition: compat.h:17
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsnicmp
Definition: compat.h:14
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
int hex(char ch)
#define iswspace(_c)
Definition: ctype.h:669
#define iswxdigit(_c)
Definition: ctype.h:668
#define stdout
Definition: stdio.h:99
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_CRTIMP void __cdecl _wperror(_In_opt_z_ const wchar_t *_ErrMsg)
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define REG_SZ
Definition: layer.c:22
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define error(str)
Definition: mkdosfs.c:1605
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
static DWORD path_len
Definition: batch.c:31
static const WCHAR invalid[]
Definition: assoc.c:39
static LPCWSTR file_name
Definition: protocol.c:147
WCHAR strW[12]
Definition: clipboard.c:2029
char strA[12]
Definition: clipboard.c:2028
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
#define open_key(r, p, s, k)
Definition: reg_test.h:49
#define close_key(k)
Definition: reg_test.h:52
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
#define SHDeleteKey
Definition: shlwapi.h:44
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
Definition: fci.c:127
Definition: copy.c:22
Definition: parser.c:49
Definition: name.c:39
Definition: import.c:81
BOOL is_unicode
Definition: import.c:84
BOOL backslash
Definition: import.c:94
enum parser_state state
Definition: import.c:95
WCHAR * value_name
Definition: import.c:89
WCHAR two_wchars[2]
Definition: import.c:83
short int reg_version
Definition: import.c:85
DWORD data_size
Definition: import.c:93
void * data
Definition: import.c:92
HKEY hkey
Definition: import.c:87
DWORD data_type
Definition: import.c:91
DWORD parse_type
Definition: import.c:90
WCHAR * key_name
Definition: import.c:88
FILE * file
Definition: import.c:82
Definition: ecma_167.h:138
#define towlower(c)
Definition: wctype.h:97
#define str_len
Definition: treelist.c:89
Definition: pdh_main.c:94
int ret
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_DYN_DATA
Definition: winreg.h:16
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193