ReactOS 0.4.16-dev-2206-gc56950d
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 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
9 */
10
11#ifdef __REACTOS__
12#include <fcntl.h>
13#include <io.h>
14#include "regedit.h"
15#else
16#include <errno.h>
17#include <fcntl.h>
18#include <io.h>
19#include <windows.h>
20#include <commctrl.h>
21
22#include "main.h"
23#endif
24
25#define REG_VAL_BUF_SIZE 4096
26
27static HKEY reg_class_keys[] = {
30 };
31
32/******************************************************************************
33 * Allocates memory and converts input from multibyte to wide chars
34 * Returned string must be freed by the caller
35 */
36static WCHAR* GetWideString(const char* strA)
37{
38 if(strA)
39 {
40 WCHAR* strW;
41 int len = MultiByteToWideChar(CP_ACP, 0, strA, -1, NULL, 0);
42
43 strW = malloc(len * sizeof(WCHAR));
45 return strW;
46 }
47 return NULL;
48}
49
50/******************************************************************************
51 * Allocates memory and converts input from multibyte to wide chars
52 * Returned string must be freed by the caller
53 */
54static WCHAR* GetWideStringN(const char* strA, int chars, DWORD *len)
55{
56 if(strA)
57 {
58 WCHAR* strW;
59 *len = MultiByteToWideChar(CP_ACP, 0, strA, chars, NULL, 0);
60
61 strW = malloc(*len * sizeof(WCHAR));
62 MultiByteToWideChar(CP_ACP, 0, strA, chars, strW, *len);
63 return strW;
64 }
65 *len = 0;
66 return NULL;
67}
68
69/******************************************************************************
70 * Allocates memory and converts input from wide chars to multibyte
71 * Returned string must be freed by the caller
72 */
74{
75 if(strW)
76 {
77 char* strA;
78 int len = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL);
79
80 strA = malloc(len);
82 return strA;
83 }
84 return NULL;
85}
86
87/******************************************************************************
88 * Allocates memory and converts input from wide chars to multibyte
89 * Returned string must be freed by the caller
90 */
91static char* GetMultiByteStringN(const WCHAR* strW, int chars, DWORD* len)
92{
93 if(strW)
94 {
95 char* strA;
96 *len = WideCharToMultiByte(CP_ACP, 0, strW, chars, NULL, 0, NULL, NULL);
97
98 strA = malloc(*len);
100 return strA;
101 }
102 *len = 0;
103 return NULL;
104}
105
106static WCHAR *(*get_line)(FILE *);
107
108/* parser definitions */
110{
111 HEADER, /* parsing the registry file version header */
112 PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */
113 LINE_START, /* at the beginning of a registry line */
114 KEY_NAME, /* parsing a key name */
115 DELETE_KEY, /* deleting a registry key */
116 DEFAULT_VALUE_NAME, /* parsing a default value name */
117 QUOTED_VALUE_NAME, /* parsing a double-quoted value name */
118 DATA_START, /* preparing for data parsing operations */
119 DELETE_VALUE, /* deleting a registry value */
120 DATA_TYPE, /* parsing the registry data type */
121 STRING_DATA, /* parsing REG_SZ data */
122 DWORD_DATA, /* parsing DWORD data */
123 HEX_DATA, /* parsing REG_BINARY, REG_NONE, REG_EXPAND_SZ or REG_MULTI_SZ data */
124 EOL_BACKSLASH, /* preparing to parse multiple lines of hex data */
125 HEX_MULTILINE, /* parsing multiple lines of hex data */
126 UNKNOWN_DATA, /* parsing an unhandled or invalid data type */
127 SET_VALUE, /* adding a value to the registry */
130
131struct parser
132{
133 FILE *file; /* pointer to a registry file */
134 WCHAR two_wchars[2]; /* first two characters from the encoding check */
135 BOOL is_unicode; /* parsing Unicode or ASCII data */
136 short int reg_version; /* registry file version */
137 HKEY hkey; /* current registry key */
138 WCHAR *key_name; /* current key name */
139 WCHAR *value_name; /* value name */
140 DWORD parse_type; /* generic data type for parsing */
141 DWORD data_type; /* data type */
142 void *data; /* value data */
143 DWORD data_size; /* size of the data (in bytes) */
144 BOOL backslash; /* TRUE if the current line contains a backslash */
145#ifdef __REACTOS__
146 BOOL unicode_in_asc; /* TRUE if ASCII file contains Unicode entry */
147#endif
148 enum parser_state state; /* current parser state */
149};
150
151typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
152
153/* parser state machine functions */
154static WCHAR *header_state(struct parser *parser, WCHAR *pos);
156static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
157static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
158static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
161static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
162static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
163static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
164static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
165static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
166static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
169static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
170static WCHAR *set_value_state(struct parser *parser, WCHAR *pos);
171
173{
174 header_state, /* HEADER */
175 parse_win31_line_state, /* PARSE_WIN31_LINE */
176 line_start_state, /* LINE_START */
177 key_name_state, /* KEY_NAME */
178 delete_key_state, /* DELETE_KEY */
179 default_value_name_state, /* DEFAULT_VALUE_NAME */
180 quoted_value_name_state, /* QUOTED_VALUE_NAME */
181 data_start_state, /* DATA_START */
182 delete_value_state, /* DELETE_VALUE */
183 data_type_state, /* DATA_TYPE */
184 string_data_state, /* STRING_DATA */
185 dword_data_state, /* DWORD_DATA */
186 hex_data_state, /* HEX_DATA */
187 eol_backslash_state, /* EOL_BACKSLASH */
188 hex_multiline_state, /* HEX_MULTILINE */
189 unknown_data_state, /* UNKNOWN_DATA */
190 set_value_state, /* SET_VALUE */
191};
192
193/* set the new parser state and return the previous one */
194static inline enum parser_state set_state(struct parser *parser, enum parser_state state)
195{
197 parser->state = state;
198 return ret;
199}
200
201/******************************************************************************
202 * Converts a hex representation of a DWORD into a DWORD.
203 */
205{
206 WCHAR *p, *end;
207 int count = 0;
208
209 while (*str == ' ' || *str == '\t') str++;
210 if (!*str) goto error;
211
212 p = str;
213 while (iswxdigit(*p))
214 {
215 count++;
216 p++;
217 }
218 if (count > 8) goto error;
219
220 end = p;
221 while (*p == ' ' || *p == '\t') p++;
222 if (*p && *p != ';') goto error;
223
224 *end = 0;
225 *dw = wcstoul(str, &end, 16);
226 return TRUE;
227
228error:
229 return FALSE;
230}
231
232/******************************************************************************
233 * Converts comma-separated hex data into a binary string and modifies
234 * the input parameter to skip the concatenating backslash, if found.
235 *
236 * Returns TRUE or FALSE to indicate whether parsing was successful.
237 */
239{
240 size_t size;
241 BYTE *d;
242 WCHAR *s;
243
245
246 /* The worst case is 1 digit + 1 comma per byte */
247 size = ((lstrlenW(*str) + 1) / 2) + parser->data_size;
249
250 s = *str;
251 d = (BYTE *)parser->data + parser->data_size;
252
253 while (*s)
254 {
255 WCHAR *end;
256 unsigned long wc;
257
258 wc = wcstoul(s, &end, 16);
259 if (wc > 0xff) return FALSE;
260
261 if (s == end && wc == 0)
262 {
263 while (*end == ' ' || *end == '\t') end++;
264 if (*end == '\\')
265 {
267 *str = end + 1;
268 return TRUE;
269 }
270 else if (*end == ';')
271 return TRUE;
272 return FALSE;
273 }
274
275 *d++ = wc;
276 parser->data_size++;
277
278 if (*end && *end != ',')
279 {
280 while (*end == ' ' || *end == '\t') end++;
281 if (*end && *end != ';') return FALSE;
282 return TRUE;
283 }
284
285 if (*end) end++;
286 s = end;
287 }
288
289 return TRUE;
290}
291
292/******************************************************************************
293 * Parses the data type of the registry value being imported and modifies
294 * the input parameter to skip the string representation of the data type.
295 *
296 * Returns TRUE or FALSE to indicate whether a data type was found.
297 */
299{
300 struct data_type { const WCHAR *tag; int len; int type; int parse_type; };
301
302 static const struct data_type data_types[] = {
303 /* tag len type parse type */
304 { L"\"", 1, REG_SZ, REG_SZ },
305 { L"hex:", 4, REG_BINARY, REG_BINARY },
306 { L"dword:", 6, REG_DWORD, REG_DWORD },
307 { L"hex(", 4, -1, REG_BINARY }, /* REG_NONE, REG_EXPAND_SZ, REG_MULTI_SZ */
308 { NULL, 0, 0, 0 }
309 };
310
311 const struct data_type *ptr;
312
313#ifdef __REACTOS__
314 DWORD len = wcslen(*line);
315
316 parser->unicode_in_asc = FALSE;
317
318 if (!parser->is_unicode && len >= 15)
319 {
320 WCHAR Buffer[16] = { 0 };
321 WCHAR* ret;
322
323 memcpy(Buffer, *line, 30);
325
326 ret = wcsstr(Buffer, L"00,"); // Any UNICODE characters?
327 parser->unicode_in_asc = (ret != NULL);
328 }
329
330#endif
331 for (ptr = data_types; ptr->tag; ptr++)
332 {
333 if (wcsncmp(ptr->tag, *line, ptr->len))
334 continue;
335
336 parser->parse_type = ptr->parse_type;
337 parser->data_type = ptr->parse_type;
338 *line += ptr->len;
339
340 if (ptr->type == -1)
341 {
342 WCHAR *end;
343 DWORD val;
344
345 if (!**line || towlower((*line)[1]) == 'x')
346 return FALSE;
347
348 /* "hex(xx):" is special */
349 val = wcstoul(*line, &end, 16);
350#ifdef __REACTOS__
351 /* Up to 8 hex digits, "hex(000000002)" is invalid */
352 if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE) || end - *line > 8)
353#else
354 if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE))
355#endif
356 return FALSE;
357
359 *line = end + 2;
360 }
361 return TRUE;
362 }
363 return FALSE;
364}
365
366/******************************************************************************
367 * Replaces escape sequences with their character equivalents and
368 * null-terminates the string on the first non-escaped double quote.
369 *
370 * Assigns a pointer to the remaining unparsed data in the line.
371 * Returns TRUE or FALSE to indicate whether a closing double quote was found.
372 */
374{
375 int str_idx = 0; /* current character under analysis */
376 int val_idx = 0; /* the last character of the unescaped string */
377 int len = lstrlenW(str);
378 BOOL ret;
379
380 for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
381 if (str[str_idx] == '\\') {
382 str_idx++;
383 switch (str[str_idx]) {
384 case 'n':
385 str[val_idx] = '\n';
386 break;
387 case 'r':
388 str[val_idx] = '\r';
389 break;
390 case '0':
391 return FALSE;
392 case '\\':
393 case '"':
394 str[val_idx] = str[str_idx];
395 break;
396 default:
397 if (!str[str_idx]) return FALSE;
399 str[val_idx] = str[str_idx];
400 break;
401 }
402 } else if (str[str_idx] == '"') {
403 break;
404 } else {
405 str[val_idx] = str[str_idx];
406 }
407 }
408
409 ret = (str[str_idx] == '"');
410 *unparsed = str + str_idx + 1;
411 str[val_idx] = '\0';
412 return ret;
413}
414
416{
417 unsigned int i;
418
419 if (!key_name) return 0;
420
421 *key_path = wcschr(key_name, '\\');
422 if (*key_path) (*key_path)++;
423
424 for (i = 0; i < ARRAY_SIZE(reg_class_keys); i++)
425 {
427#ifdef __REACTOS__
429#else
431#endif
432 (key_name[len] == 0 || key_name[len] == '\\'))
433 {
434 return reg_class_keys[i];
435 }
436 }
437
438 return 0;
439}
440
441static void close_key(struct parser *parser)
442{
443 if (parser->hkey)
444 {
447
449 parser->hkey = NULL;
450 }
451}
452
453/******************************************************************************
454 * Opens the registry key given by the input path.
455 * This key must be closed by calling close_key().
456 */
458{
459 HKEY key_class;
460 WCHAR *key_path;
461 LONG res;
462
464
465 /* Get the registry class */
466 if (!path || !(key_class = parse_key_name(path, &key_path)))
468
469 res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
471
472 if (res == ERROR_SUCCESS)
473 {
474 parser->key_name = malloc((lstrlenW(path) + 1) * sizeof(WCHAR));
476 }
477 else
478 parser->hkey = NULL;
479
480 return res;
481}
482
483static void free_parser_data(struct parser *parser)
484{
486 free(parser->data);
487
488 parser->data = NULL;
489 parser->data_size = 0;
490}
491
493{
496 {
497#ifdef __REACTOS__
498 if (parser->is_unicode || (!parser->is_unicode && parser->unicode_in_asc))
499#else
500 if (parser->is_unicode)
501#endif
502 {
503 WCHAR *data = parser->data;
504 DWORD len = parser->data_size / sizeof(WCHAR);
505
506 if (data[len - 1] != 0)
507 {
508 data[len] = 0;
509 parser->data_size += sizeof(WCHAR);
510 }
511 }
512 else
513 {
514 BYTE *data = parser->data;
515
516 if (data[parser->data_size - 1] != 0)
517 {
518 data[parser->data_size] = 0;
519 parser->data_size++;
520 }
521
523 parser->data_size *= sizeof(WCHAR);
524 free(data);
525 }
526 }
527}
528
536
538{
539 static const WCHAR header_31[] = L"REGEDIT";
540
541 while (*s == ' ' || *s == '\t') s++;
542
543 if (!lstrcmpW(s, header_31))
544 return REG_VERSION_31;
545
546 if (!lstrcmpW(s, L"REGEDIT4"))
547 return REG_VERSION_40;
548
549 if (!lstrcmpW(s, L"Windows Registry Editor Version 5.00"))
550 return REG_VERSION_50;
551
552 /* The Windows version accepts registry file headers beginning with "REGEDIT" and ending
553 * with other characters, as long as "REGEDIT" appears at the start of the line. For example,
554 * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all treated as valid file headers.
555 * In all such cases, however, the contents of the registry file are not imported.
556 */
557 if (!wcsncmp(s, header_31, 7)) /* "REGEDIT" without NUL */
558 return REG_VERSION_FUZZY;
559
560 return REG_VERSION_INVALID;
561}
562
563/* handler for parser HEADER state */
565{
566 WCHAR *line, *header;
567
568 if (!(line = get_line(parser->file)))
569 return NULL;
570
571 if (!parser->is_unicode)
572 {
573 header = malloc((lstrlenW(line) + 3) * sizeof(WCHAR));
574 header[0] = parser->two_wchars[0];
575 header[1] = parser->two_wchars[1];
576 lstrcpyW(header + 2, line);
578 free(header);
579 }
581
582 switch (parser->reg_version)
583 {
584 case REG_VERSION_31:
586 break;
587 case REG_VERSION_40:
588 case REG_VERSION_50:
590 break;
591 default:
592 get_line(NULL); /* Reset static variables */
593 return NULL;
594 }
595
596 return line;
597}
598
599/* handler for parser PARSE_WIN31_LINE state */
601{
602 WCHAR *line, *value;
603 static WCHAR hkcr[] = L"HKEY_CLASSES_ROOT";
604 unsigned int key_end = 0;
605
606 if (!(line = get_line(parser->file)))
607 return NULL;
608
609 if (wcsncmp(line, hkcr, lstrlenW(hkcr)))
610 return line;
611
612 /* get key name */
613 while (line[key_end] && !iswspace(line[key_end])) key_end++;
614
615 value = line + key_end;
616 while (*value == ' ' || *value == '\t') value++;
617
618 if (*value == '=') value++;
619 if (*value == ' ') value++; /* at most one space is skipped */
620
621 line[key_end] = 0;
622
624 {
626 return line;
627 }
628
631 parser->data = value;
632 parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
633
635 return value;
636}
637
638/* handler for parser LINE_START state */
640{
641 WCHAR *line, *p;
642
643 if (!(line = get_line(parser->file)))
644 return NULL;
645
646 for (p = line; *p; p++)
647 {
648 switch (*p)
649 {
650 case '[':
652 return p + 1;
653 case '@':
655 return p;
656 case '"':
658 return p + 1;
659 case ' ':
660 case '\t':
661 break;
662 default:
663 return p;
664 }
665 }
666
667 return p;
668}
669
670/* handler for parser KEY_NAME state */
672{
673 WCHAR *p = pos, *key_end;
674
675 if (*p == ' ' || *p == '\t' || !(key_end = wcsrchr(p, ']')))
676 goto done;
677
678 *key_end = 0;
679
680 if (*p == '-')
681 {
683 return p + 1;
684 }
685 else if (open_key(parser, p) != ERROR_SUCCESS)
687
688done:
690 return p;
691}
692
693/* handler for parser DELETE_KEY state */
695{
696 WCHAR *p = pos;
697
699
700 if (*p == 'H' || *p == 'h')
702
704 return p;
705}
706
707/* handler for parser DEFAULT_VALUE_NAME state */
709{
712
714 return pos + 1;
715}
716
717/* handler for parser QUOTED_VALUE_NAME state */
719{
720 WCHAR *val_name = pos, *p;
721
724
725 if (!REGPROC_unescape_string(val_name, &p))
726 goto invalid;
727
728 /* copy the value name in case we need to parse multiple lines and the buffer is overwritten */
729 parser->value_name = malloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
730 lstrcpyW(parser->value_name, val_name);
731
733 return p;
734
735invalid:
737 return val_name;
738}
739
740/* handler for parser DATA_START state */
742{
743 WCHAR *p = pos;
744 unsigned int len;
745
746 while (*p == ' ' || *p == '\t') p++;
747 if (*p != '=') goto done;
748 p++;
749 while (*p == ' ' || *p == '\t') p++;
750
751 /* trim trailing whitespace */
752 len = lstrlenW(p);
753 while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t')) len--;
754 p[len] = 0;
755
756 if (*p == '-')
758 else
760 return p;
761
762done:
764 return p;
765}
766
767/* handler for parser DELETE_VALUE state */
769{
770 WCHAR *p = pos + 1;
771
772 while (*p == ' ' || *p == '\t') p++;
773 if (*p && *p != ';') goto done;
774
776
777done:
779 return p;
780}
781
782/* handler for parser DATA_TYPE state */
784{
785 WCHAR *line = pos;
786
788 {
790 return line;
791 }
792
793 switch (parser->parse_type)
794 {
795 case REG_SZ:
797 break;
798 case REG_DWORD:
800 break;
801 case REG_BINARY: /* all hex data types, including undefined */
803 break;
804 default:
806 }
807
808 return line;
809}
810
811/* handler for parser STRING_DATA state */
813{
814 WCHAR *line;
815
816 parser->data = pos;
817
819 goto invalid;
820
821 while (*line == ' ' || *line == '\t') line++;
822 if (*line && *line != ';') goto invalid;
823
824 parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
825
827 return line;
828
829invalid:
832 return line;
833}
834
835/* handler for parser DWORD_DATA state */
837{
838 WCHAR *line = pos;
839
840 parser->data = malloc(sizeof(DWORD));
841
843 goto invalid;
844
845 parser->data_size = sizeof(DWORD);
846
848 return line;
849
850invalid:
853 return line;
854}
855
856/* handler for parser HEX_DATA state */
858{
859 WCHAR *line = pos;
860
861 if (!*line)
862 goto set_value;
863
865 goto invalid;
866
867 if (parser->backslash)
868 {
870 return line;
871 }
872
874
877 return line;
878
879invalid:
882 return line;
883}
884
885/* handler for parser EOL_BACKSLASH state */
887{
888 WCHAR *p = pos;
889
890 while (*p == ' ' || *p == '\t') p++;
891 if (*p && *p != ';') goto invalid;
892
894 return pos;
895
896invalid:
899 return p;
900}
901
902/* handler for parser HEX_MULTILINE state */
904{
905 WCHAR *line;
906
907 if (!(line = get_line(parser->file)))
908 {
911 return pos;
912 }
913
914 while (*line == ' ' || *line == '\t') line++;
915 if (!*line || *line == ';') return line;
916
917 if (!iswxdigit(*line)) goto invalid;
918
920 return line;
921
922invalid:
925 return line;
926}
927
928/* handler for parser UNKNOWN_DATA state */
930{
932
934 return pos;
935}
936
937/* handler for parser SET_VALUE state */
939{
942
944
947 else
949
950 return pos;
951}
952
953static WCHAR *get_lineA(FILE *fp)
954{
955 static WCHAR *lineW;
956 static size_t size;
957 static char *buf, *next;
958 char *line;
959
960 free(lineW);
961
962 if (!fp) goto cleanup;
963
964 if (!size)
965 {
967 buf = malloc(size);
968 *buf = 0;
969 next = buf;
970 }
971 line = next;
972
973 while (next)
974 {
975 char *p = strpbrk(line, "\r\n");
976 if (!p)
977 {
978 size_t len, count;
979 len = strlen(next);
980 memmove(buf, next, len + 1);
981 if (size - len < 3)
982 {
983 size *= 2;
984 buf = realloc(buf, size);
985 }
986 if (!(count = fread(buf + len, 1, size - len - 1, fp)))
987 {
988 next = NULL;
989 lineW = GetWideString(buf);
990 return lineW;
991 }
992 buf[len + count] = 0;
993 next = buf;
994 line = buf;
995 continue;
996 }
997 next = p + 1;
998 if (*p == '\r' && *(p + 1) == '\n') next++;
999 *p = 0;
1000 lineW = GetWideString(line);
1001 return lineW;
1002 }
1003
1004cleanup:
1005 lineW = NULL;
1006 if (size) free(buf);
1007 size = 0;
1008 return NULL;
1009}
1010
1012{
1013 static size_t size;
1014 static WCHAR *buf, *next;
1015 WCHAR *line;
1016
1017 if (!fp) goto cleanup;
1018
1019 if (!size)
1020 {
1022 buf = malloc(size * sizeof(WCHAR));
1023 *buf = 0;
1024 next = buf;
1025 }
1026 line = next;
1027
1028 while (next)
1029 {
1030 WCHAR *p = wcspbrk(line, L"\r\n");
1031 if (!p)
1032 {
1033 size_t len, count;
1034 len = lstrlenW(next);
1035 memmove(buf, next, (len + 1) * sizeof(WCHAR));
1036 if (size - len < 3)
1037 {
1038 size *= 2;
1039 buf = realloc(buf, size * sizeof(WCHAR));
1040 }
1041 if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
1042 {
1043 next = NULL;
1044 return buf;
1045 }
1046 buf[len + count] = 0;
1047 next = buf;
1048 line = buf;
1049 continue;
1050 }
1051 next = p + 1;
1052 if (*p == '\r' && *(p + 1) == '\n') next++;
1053 *p = 0;
1054 return line;
1055 }
1056
1057cleanup:
1058 if (size) free(buf);
1059 size = 0;
1060 return NULL;
1061}
1062
1063/******************************************************************************
1064 * Reads contents of the specified file into the registry.
1065 */
1067{
1068 BYTE s[2];
1069 struct parser parser;
1070 WCHAR *pos;
1071
1072 if (!reg_file || (fread(s, 2, 1, reg_file) != 1))
1073 return FALSE;
1074
1075 parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
1077
1078 parser.file = reg_file;
1079 parser.two_wchars[0] = s[0];
1080 parser.two_wchars[1] = s[1];
1081 parser.reg_version = -1;
1082 parser.hkey = NULL;
1085 parser.parse_type = 0;
1086 parser.data_type = 0;
1087 parser.data = NULL;
1088 parser.data_size = 0;
1091
1093
1094 /* parser main loop */
1095 while (pos)
1097
1100
1102 close_key(&parser);
1103
1104 return TRUE;
1105}
1106
1107/******************************************************************************
1108 * Removes the registry key with all subkeys. Parses full key name.
1109 *
1110 * Parameters:
1111 * reg_key_name - full name of registry branch to delete. Ignored if is NULL,
1112 * empty, points to register key class, does not exist.
1113 */
1114void delete_registry_key(WCHAR *reg_key_name)
1115{
1116 WCHAR *key_name = NULL;
1117 HKEY key_class;
1118
1119 if (!reg_key_name || !reg_key_name[0])
1120 return;
1121
1122 if (!(key_class = parse_key_name(reg_key_name, &key_name)))
1123 {
1124 if (key_name) *(key_name - 1) = 0;
1125#ifdef __REACTOS__
1127 return;
1128#else
1130#endif
1131 }
1132
1133 if (!key_name || !*key_name)
1134#ifdef __REACTOS__
1135 {
1136 output_message(STRING_DELETE_FAILED, reg_key_name);
1137 return;
1138 }
1139#else
1140 error_exit(STRING_DELETE_FAILED, reg_key_name);
1141#endif
1142
1143#ifdef __REACTOS__
1144 SHDeleteKey(key_class, key_name);
1145#else
1146 RegDeleteTreeW(key_class, key_name);
1147#endif
1148}
1149
1150static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
1151{
1152 if (unicode)
1153 fwrite(str, sizeof(WCHAR), lstrlenW(str), fp);
1154 else
1155 {
1156 char *strA = GetMultiByteString(str);
1157 fputs(strA, fp);
1158 free(strA);
1159 }
1160}
1161
1162static WCHAR *REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
1163{
1164 size_t i, escape_count, pos;
1165 WCHAR *buf;
1166
1167 for (i = 0, escape_count = 0; i < str_len; i++)
1168 {
1169 WCHAR c = str[i];
1170
1171 if (!c) break;
1172
1173 if (c == '\r' || c == '\n' || c == '\\' || c == '"')
1174 escape_count++;
1175 }
1176
1177 buf = malloc((str_len + escape_count + 1) * sizeof(WCHAR));
1178
1179 for (i = 0, pos = 0; i < str_len; i++, pos++)
1180 {
1181 WCHAR c = str[i];
1182
1183 if (!c) break;
1184
1185 switch (c)
1186 {
1187 case '\r':
1188 buf[pos++] = '\\';
1189 buf[pos] = 'r';
1190 break;
1191 case '\n':
1192 buf[pos++] = '\\';
1193 buf[pos] = 'n';
1194 break;
1195 case '\\':
1196 buf[pos++] = '\\';
1197 buf[pos] = '\\';
1198 break;
1199 case '"':
1200 buf[pos++] = '\\';
1201 buf[pos] = '"';
1202 break;
1203 default:
1204 buf[pos] = c;
1205 }
1206 }
1207
1208 buf[pos] = 0;
1209 *line_len = pos;
1210 return buf;
1211}
1212
1213static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
1214{
1215 static const WCHAR default_name[] = L"@=";
1216 size_t line_len;
1217
1218 if (name && *name)
1219 {
1220 WCHAR *str = REGPROC_escape_string(name, len, &line_len);
1221 WCHAR *buf = malloc((line_len + 4) * sizeof(WCHAR));
1222#ifdef __REACTOS__
1223 StringCchPrintfW(buf, line_len + 4, L"\"%s\"=", str);
1224 line_len = wcslen(buf);
1225#else
1226 line_len = swprintf(buf, line_len + 4, L"\"%s\"=", str);
1227#endif
1228 REGPROC_write_line(fp, buf, unicode);
1229 free(buf);
1230 free(str);
1231 }
1232 else
1233 {
1234 line_len = lstrlenW(default_name);
1235 REGPROC_write_line(fp, default_name, unicode);
1236 }
1237
1238 return line_len;
1239}
1240
1241static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
1242{
1243 size_t len = 0, line_len;
1244 WCHAR *str;
1245
1246 if (size)
1247 len = size / sizeof(WCHAR) - 1;
1248 str = REGPROC_escape_string(data, len, &line_len);
1249 *buf = malloc((line_len + 3) * sizeof(WCHAR));
1250#ifdef __REACTOS__
1251 StringCchPrintfW(*buf, line_len + 3, L"\"%s\"", str);
1252#else
1253 swprintf(*buf, line_len + 3, L"\"%s\"", str);
1254#endif
1255 free(str);
1256}
1257
1259{
1260 *buf = malloc(15 * sizeof(WCHAR));
1261#ifdef __REACTOS__
1262 StringCchPrintfW(*buf, 15, L"dword:%08x", *data);
1263#else
1264 swprintf(*buf, 15, L"dword:%08x", *data);
1265#endif
1266}
1267
1268static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
1269{
1270 static const WCHAR hex[] = L"hex:";
1271 size_t line_len;
1272
1273 if (type == REG_BINARY)
1274 {
1275 line_len = lstrlenW(hex);
1276 REGPROC_write_line(fp, hex, unicode);
1277 }
1278 else
1279 {
1280 WCHAR *buf = malloc(15 * sizeof(WCHAR));
1281#ifdef __REACTOS__
1282 StringCchPrintfW(buf, 15, L"hex(%x):", type);
1283 line_len = wcslen(buf);
1284#else
1285 line_len = swprintf(buf, 15, L"hex(%x):", type);
1286#endif
1287 REGPROC_write_line(fp, buf, unicode);
1288 free(buf);
1289 }
1290
1291 return line_len;
1292}
1293
1294#define MAX_HEX_CHARS 77
1295
1296static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len,
1297 void *data, DWORD size, BOOL unicode)
1298{
1299 size_t num_commas, i, pos;
1300
1301 line_len += export_hex_data_type(fp, type, unicode);
1302
1303 if (!size) return;
1304
1305 if (!unicode && (type == REG_EXPAND_SZ || type == REG_MULTI_SZ))
1306 data = GetMultiByteStringN(data, size / sizeof(WCHAR), &size);
1307
1308 num_commas = size - 1;
1309 *buf = malloc(size * 3 * sizeof(WCHAR));
1310
1311 for (i = 0, pos = 0; i < size; i++)
1312 {
1313#ifdef __REACTOS__
1314 StringCchPrintfW(*buf + pos, 3, L"%02x", ((BYTE *)data)[i]);
1315 pos += wcslen(*buf + pos);
1316#else
1317 pos += swprintf(*buf + pos, 3, L"%02x", ((BYTE *)data)[i]);
1318#endif
1319 if (i == num_commas) break;
1320 (*buf)[pos++] = ',';
1321 (*buf)[pos] = 0;
1322 line_len += 3;
1323
1324 if (line_len >= MAX_HEX_CHARS)
1325 {
1326 REGPROC_write_line(fp, *buf, unicode);
1327 REGPROC_write_line(fp, L"\\\r\n ", unicode);
1328 line_len = 2;
1329 pos = 0;
1330 }
1331 }
1332}
1333
1334static void export_newline(FILE *fp, BOOL unicode)
1335{
1336 REGPROC_write_line(fp, L"\r\n", unicode);
1337}
1338
1339static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type,
1340 void *data, size_t size, BOOL unicode)
1341{
1342 WCHAR *buf = NULL;
1343 size_t line_len = export_value_name(fp, value_name, value_len, unicode);
1344
1345 switch (type)
1346 {
1347 case REG_SZ:
1349 break;
1350 case REG_DWORD:
1351 if (size)
1352 {
1354 break;
1355 }
1356 /* fall through */
1357 case REG_NONE:
1358 case REG_EXPAND_SZ:
1359 case REG_BINARY:
1360 case REG_MULTI_SZ:
1361 default:
1362 export_hex_data(fp, &buf, type, line_len, data, size, unicode);
1363 break;
1364 }
1365
1366 if (size || type == REG_SZ)
1367 {
1368 REGPROC_write_line(fp, buf, unicode);
1369 free(buf);
1370 }
1371
1372 export_newline(fp, unicode);
1373}
1374
1375static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
1376{
1377 WCHAR *subkey_path;
1378
1379 subkey_path = malloc((path_len + subkey_len + 2) * sizeof(WCHAR));
1380#ifdef __REACTOS__
1381 StringCchPrintfW(subkey_path, path_len + subkey_len + 2, L"%s\\%s", path, subkey_name);
1382#else
1383 swprintf(subkey_path, path_len + subkey_len + 2, L"%s\\%s", path, subkey_name);
1384#endif
1385
1386 return subkey_path;
1387}
1388
1389static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
1390{
1391 WCHAR *buf;
1392
1393 buf = malloc((lstrlenW(name) + 7) * sizeof(WCHAR));
1394#ifdef __REACTOS__
1395 StringCchPrintfW(buf, lstrlenW(name) + 7, L"\r\n[%s]\r\n", name);
1396#else
1397 swprintf(buf, lstrlenW(name) + 7, L"\r\n[%s]\r\n", name);
1398#endif
1399 REGPROC_write_line(fp, buf, unicode);
1400 free(buf);
1401}
1402
1403#define MAX_SUBKEY_LEN 257
1404
1405static void export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
1406{
1407 LONG rc;
1408 DWORD max_value_len = 256, value_len;
1409 DWORD max_data_bytes = 2048, data_size;
1410 DWORD subkey_len;
1411 DWORD i, type, path_len;
1412 WCHAR *value_name, *subkey_name, *subkey_path;
1413 BYTE *data;
1414 HKEY subkey;
1415
1416 export_key_name(fp, path, unicode);
1417
1418 value_name = malloc(max_value_len * sizeof(WCHAR));
1419 data = malloc(max_data_bytes);
1420
1421 i = 0;
1422 for (;;)
1423 {
1424 value_len = max_value_len;
1425 data_size = max_data_bytes;
1426 rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
1427 if (rc == ERROR_SUCCESS)
1428 {
1429 export_data(fp, value_name, value_len, type, data, data_size, unicode);
1430 i++;
1431 }
1432 else if (rc == ERROR_MORE_DATA)
1433 {
1434 if (data_size > max_data_bytes)
1435 {
1436 max_data_bytes = data_size;
1437 data = realloc(data, max_data_bytes);
1438 }
1439 else
1440 {
1441 max_value_len *= 2;
1442 value_name = realloc(value_name, max_value_len * sizeof(WCHAR));
1443 }
1444 }
1445 else break;
1446 }
1447
1448 free(data);
1450
1451 subkey_name = malloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
1452
1454
1455 i = 0;
1456 for (;;)
1457 {
1458 subkey_len = MAX_SUBKEY_LEN;
1459 rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
1460 if (rc == ERROR_SUCCESS)
1461 {
1462 subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
1463 if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
1464 {
1465 export_registry_data(fp, subkey, subkey_path, unicode);
1466 RegCloseKey(subkey);
1467 }
1468 free(subkey_path);
1469 i++;
1470 }
1471 else break;
1472 }
1473
1474 free(subkey_name);
1475}
1476
1478{
1479 FILE *file;
1480
1481 if (!lstrcmpW(file_name, L"-"))
1482 {
1483 file = stdout;
1485 }
1486 else
1487 {
1488 file = _wfopen(file_name, L"wb");
1489 if (!file)
1490 {
1491 _wperror(L"regedit");
1492#ifdef __REACTOS__
1494 return NULL;
1495#else
1497#endif
1498 }
1499 }
1500
1501 if (unicode)
1502 {
1503 static const BYTE bom[] = {0xff,0xfe};
1504 static const WCHAR header[] = L"Windows Registry Editor Version 5.00\r\n";
1505
1506 fwrite(bom, sizeof(BYTE), ARRAY_SIZE(bom), file);
1507 fwrite(header, sizeof(WCHAR), lstrlenW(header), file);
1508 }
1509 else
1510 fputs("REGEDIT4\r\n", file);
1511
1512 return file;
1513}
1514
1515static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
1516{
1517 HKEY key;
1518
1519 if (!RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key))
1520 return key;
1521
1523 return NULL;
1524}
1525
1527{
1528 HKEY key_class, key;
1529 WCHAR *subkey;
1530 FILE *fp;
1531
1532 if (!(key_class = parse_key_name(path, &subkey)))
1533 {
1534 if (subkey) *(subkey - 1) = 0;
1536 return FALSE;
1537 }
1538
1539 if (!(key = open_export_key(key_class, subkey, path)))
1540 return FALSE;
1541
1542 fp = REGPROC_open_export_file(file_name, unicode);
1543#ifdef __REACTOS__
1544 if (!fp)
1545 return TRUE; /* Error message is already displayed */
1546#endif
1547 export_registry_data(fp, key, path, unicode);
1548 export_newline(fp, unicode);
1549 fclose(fp);
1550
1552 return TRUE;
1553}
1554
1556{
1557 FILE *fp;
1558 int i;
1559 HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
1560 WCHAR *class_name;
1561
1562 fp = REGPROC_open_export_file(file_name, unicode);
1563#ifdef __REACTOS__
1564 if (!fp)
1565 return TRUE; /* Error message is already displayed */
1566#endif
1567
1568 for (i = 0; i < ARRAY_SIZE(classes); i++)
1569 {
1570 if (!(key = open_export_key(classes[i], NULL, path)))
1571 {
1572 fclose(fp);
1573 return FALSE;
1574 }
1575
1576 class_name = malloc((lstrlenW(reg_class_namesW[i]) + 1) * sizeof(WCHAR));
1577 lstrcpyW(class_name, reg_class_namesW[i]);
1578
1579 export_registry_data(fp, classes[i], class_name, unicode);
1580
1581 free(class_name);
1583 }
1584
1585 export_newline(fp, unicode);
1586 fclose(fp);
1587
1588 return TRUE;
1589}
1590
1592{
1593 BOOL unicode = (format == REG_FORMAT_5);
1594
1595 if (path && *path)
1596 return export_key(file_name, path, unicode);
1597 else
1598 return export_all(file_name, path, unicode);
1599}
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:12
#define ARRAY_SIZE(A)
Definition: main.h:20
#define REG_FORMAT_5
Definition: main.h:31
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:88
static WCHAR * default_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:708
static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
Definition: regproc.c:1389
#define REG_VAL_BUF_SIZE
Definition: regproc.c:25
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1066
static WCHAR * REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
Definition: regproc.c:1162
static void export_newline(FILE *fp, BOOL unicode)
Definition: regproc.c:1334
static WCHAR * hex_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:857
static WCHAR * dword_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:836
static WCHAR * string_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:812
static WCHAR * key_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:671
static void prepare_hex_string_data(struct parser *parser)
Definition: regproc.c:492
static void export_dword_data(WCHAR **buf, DWORD *data)
Definition: regproc.c:1258
static WCHAR * delete_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:768
static WCHAR * eol_backslash_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:886
#define MAX_HEX_CHARS
Definition: regproc.c:1294
static WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: regproc.c:1375
static WCHAR * data_type_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:783
static BOOL export_all(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1555
static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
Definition: regproc.c:204
static WCHAR * GetWideString(const char *strA)
Definition: regproc.c:36
static HKEY reg_class_keys[]
Definition: regproc.c:27
static enum reg_versions parse_file_header(const WCHAR *s)
Definition: regproc.c:537
static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
Definition: regproc.c:238
static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
Definition: regproc.c:1241
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: regproc.c:194
static void free_parser_data(struct parser *parser)
Definition: regproc.c:483
static void export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
Definition: regproc.c:1405
static WCHAR * set_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:938
static WCHAR * data_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:741
WCHAR *(* parser_state_func)(struct parser *parser, WCHAR *pos)
Definition: regproc.c:151
static WCHAR * GetWideStringN(const char *strA, int chars, DWORD *len)
Definition: regproc.c:54
static WCHAR * get_lineA(FILE *fp)
Definition: regproc.c:953
static BOOL REGPROC_unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: regproc.c:373
static WCHAR * unknown_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:929
static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len, void *data, DWORD size, BOOL unicode)
Definition: regproc.c:1296
static BOOL parse_data_type(struct parser *parser, WCHAR **line)
Definition: regproc.c:298
static char * GetMultiByteStringN(const WCHAR *strW, int chars, DWORD *len)
Definition: regproc.c:91
static FILE * REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
Definition: regproc.c:1477
@ PARSE_WIN31_LINE
Definition: regproc.c:112
@ HEX_DATA
Definition: regproc.c:123
@ DEFAULT_VALUE_NAME
Definition: regproc.c:116
@ HEADER
Definition: regproc.c:111
@ NB_PARSER_STATES
Definition: regproc.c:128
@ STRING_DATA
Definition: regproc.c:121
@ QUOTED_VALUE_NAME
Definition: regproc.c:117
@ DATA_TYPE
Definition: regproc.c:120
@ HEX_MULTILINE
Definition: regproc.c:125
@ UNKNOWN_DATA
Definition: regproc.c:126
@ LINE_START
Definition: regproc.c:113
@ EOL_BACKSLASH
Definition: regproc.c:124
@ SET_VALUE
Definition: regproc.c:127
@ DELETE_VALUE
Definition: regproc.c:119
@ DWORD_DATA
Definition: regproc.c:122
@ KEY_NAME
Definition: regproc.c:114
@ DATA_START
Definition: regproc.c:118
@ DELETE_KEY
Definition: regproc.c:115
@ REG_VERSION_50
Definition: regproc.c:532
@ REG_VERSION_INVALID
Definition: regproc.c:534
@ REG_VERSION_40
Definition: regproc.c:531
@ REG_VERSION_FUZZY
Definition: regproc.c:533
@ REG_VERSION_31
Definition: regproc.c:530
static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
Definition: regproc.c:1213
static WCHAR * get_lineW(FILE *fp)
Definition: regproc.c:1011
static WCHAR * quoted_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:718
static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
Definition: regproc.c:415
static WCHAR *(* get_line)(FILE *)
Definition: regproc.c:106
char * GetMultiByteString(const WCHAR *strW)
Definition: regproc.c:73
static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
Definition: regproc.c:1150
static WCHAR * parse_win31_line_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:600
static WCHAR * delete_key_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:694
static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
Definition: regproc.c:1515
static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
Definition: regproc.c:1268
static BOOL export_key(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1526
static WCHAR * hex_multiline_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:903
#define MAX_SUBKEY_LEN
Definition: regproc.c:1403
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1591
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1114
static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type, void *data, size_t size, BOOL unicode)
Definition: regproc.c:1339
static WCHAR * header_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:564
static WCHAR * line_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:639
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: regproc.c:172
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:330
#define STRING_OPEN_KEY_FAILED
Definition: resource.h:340
#define STRING_UNKNOWN_DATA_FORMAT
Definition: resource.h:336
#define STRING_DELETE_FAILED
Definition: resource.h:345
#define RegCloseKey(hKey)
Definition: registry.h:49
#define _setmode(fd, mode)
Definition: cat.c:21
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: bufpool.h:45
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:3333
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:2504
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:4882
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
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:2830
#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
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4246
void CDECL _wperror(const wchar_t *str)
Definition: errno.c:354
int CDECL fclose(FILE *file)
Definition: file.c:3757
size_t CDECL fread(void *ptr, size_t size, size_t nmemb, FILE *file)
Definition: file.c:4406
FILE *CDECL _wfopen(const wchar_t *path, const wchar_t *mode)
Definition: file.c:4335
int CDECL fputs(const char *s, FILE *file)
Definition: file.c:4769
int CDECL _fileno(FILE *file)
Definition: file.c:1925
size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE *file)
Definition: file.c:4129
#define stdout
_ACRTIMP __msvcrt_ulong __cdecl wcstoul(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2912
_ACRTIMP wchar_t *__cdecl wcspbrk(const wchar_t *, const wchar_t *)
Definition: wcs.c:2016
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2993
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:195
#define ERANGE
Definition: errno.h:55
#define errno
Definition: errno.h:120
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strpbrk(const char *, const char *)
Definition: string.c:3525
#define swprintf
Definition: precomp.h:40
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
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)
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
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#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 LPCWSTR file_name
Definition: protocol.c:147
WCHAR strW[12]
Definition: clipboard.c:2025
char strA[12]
Definition: clipboard.c:2024
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1495
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
#define SHDeleteKey
Definition: shlwapi.h:831
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:615
#define iswspace(_c)
Definition: ctype.h:669
#define iswxdigit(_c)
Definition: ctype.h:668
#define towlower(c)
Definition: wctype.h:97
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
Definition: fci.c:127
Definition: format.c:58
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 str_len
Definition: treelist.c:89
Definition: pdh_main.c:96
#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