ReactOS  0.4.15-dev-5462-g4d0d22a
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 
40 static 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  */
49 static 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  */
67 static 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  */
104 static 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);
112  WideCharToMultiByte(CP_ACP, 0, strW, chars, strA, *len, NULL, NULL);
113  return strA;
114  }
115  *len = 0;
116  return NULL;
117 }
118 
119 static 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 */
142 };
143 
144 struct 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 
161 typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
162 
163 /* parser state machine functions */
164 static WCHAR *header_state(struct parser *parser, WCHAR *pos);
166 static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
167 static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
168 static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
171 static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
172 static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
173 static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
174 static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
175 static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
176 static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
177 static WCHAR *eol_backslash_state(struct parser *parser, WCHAR *pos);
178 static WCHAR *hex_multiline_state(struct parser *parser, WCHAR *pos);
179 static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
180 static 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 */
204 static inline enum parser_state set_state(struct parser *parser, enum parser_state state)
205 {
206  enum parser_state ret = parser->state;
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 
238 error:
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  {
276  parser->backslash = TRUE;
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  if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE))
343  return FALSE;
344 
345  parser->data_type = val;
346  *line = end + 2;
347  }
348  return TRUE;
349  }
350  return FALSE;
351 }
352 
353 /******************************************************************************
354  * Replaces escape sequences with their character equivalents and
355  * null-terminates the string on the first non-escaped double quote.
356  *
357  * Assigns a pointer to the remaining unparsed data in the line.
358  * Returns TRUE or FALSE to indicate whether a closing double quote was found.
359  */
361 {
362  int str_idx = 0; /* current character under analysis */
363  int val_idx = 0; /* the last character of the unescaped string */
364  int len = lstrlenW(str);
365  BOOL ret;
366 
367  for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
368  if (str[str_idx] == '\\') {
369  str_idx++;
370  switch (str[str_idx]) {
371  case 'n':
372  str[val_idx] = '\n';
373  break;
374  case 'r':
375  str[val_idx] = '\r';
376  break;
377  case '0':
378  return FALSE;
379  case '\\':
380  case '"':
381  str[val_idx] = str[str_idx];
382  break;
383  default:
384  if (!str[str_idx]) return FALSE;
386  str[val_idx] = str[str_idx];
387  break;
388  }
389  } else if (str[str_idx] == '"') {
390  break;
391  } else {
392  str[val_idx] = str[str_idx];
393  }
394  }
395 
396  ret = (str[str_idx] == '"');
397  *unparsed = str + str_idx + 1;
398  str[val_idx] = '\0';
399  return ret;
400 }
401 
402 static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
403 {
404  unsigned int i;
405 
406  if (!key_name) return 0;
407 
408  *key_path = wcschr(key_name, '\\');
409  if (*key_path) (*key_path)++;
410 
411  for (i = 0; i < ARRAY_SIZE(reg_class_keys); i++)
412  {
413  int len = lstrlenW(reg_class_namesW[i]);
414 #ifdef __REACTOS__
416 #else
418 #endif
419  (key_name[len] == 0 || key_name[len] == '\\'))
420  {
421  return reg_class_keys[i];
422  }
423  }
424 
425  return 0;
426 }
427 
428 static void close_key(struct parser *parser)
429 {
430  if (parser->hkey)
431  {
432  free(parser->key_name);
433  parser->key_name = NULL;
434 
436  parser->hkey = NULL;
437  }
438 }
439 
440 /******************************************************************************
441  * Opens the registry key given by the input path.
442  * This key must be closed by calling close_key().
443  */
444 static LONG open_key(struct parser *parser, WCHAR *path)
445 {
446  HKEY key_class;
447  WCHAR *key_path;
448  LONG res;
449 
450  close_key(parser);
451 
452  /* Get the registry class */
453  if (!path || !(key_class = parse_key_name(path, &key_path)))
455 
456  res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
458 
459  if (res == ERROR_SUCCESS)
460  {
461  parser->key_name = malloc((lstrlenW(path) + 1) * sizeof(WCHAR));
463  }
464  else
465  parser->hkey = NULL;
466 
467  return res;
468 }
469 
470 static void free_parser_data(struct parser *parser)
471 {
473  free(parser->data);
474 
475  parser->data = NULL;
476  parser->data_size = 0;
477 }
478 
480 {
482  parser->data_type == REG_SZ)
483  {
484  if (parser->is_unicode)
485  {
486  WCHAR *data = parser->data;
487  DWORD len = parser->data_size / sizeof(WCHAR);
488 
489  if (data[len - 1] != 0)
490  {
491  data[len] = 0;
492  parser->data_size += sizeof(WCHAR);
493  }
494  }
495  else
496  {
497  BYTE *data = parser->data;
498 
499  if (data[parser->data_size - 1] != 0)
500  {
501  data[parser->data_size] = 0;
502  parser->data_size++;
503  }
504 
506  parser->data_size *= sizeof(WCHAR);
507  free(data);
508  }
509  }
510 }
511 
518 };
519 
521 {
522  static const WCHAR header_31[] = L"REGEDIT";
523 
524  while (*s == ' ' || *s == '\t') s++;
525 
526  if (!lstrcmpW(s, header_31))
527  return REG_VERSION_31;
528 
529  if (!lstrcmpW(s, L"REGEDIT4"))
530  return REG_VERSION_40;
531 
532  if (!lstrcmpW(s, L"Windows Registry Editor Version 5.00"))
533  return REG_VERSION_50;
534 
535  /* The Windows version accepts registry file headers beginning with "REGEDIT" and ending
536  * with other characters, as long as "REGEDIT" appears at the start of the line. For example,
537  * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all treated as valid file headers.
538  * In all such cases, however, the contents of the registry file are not imported.
539  */
540  if (!wcsncmp(s, header_31, 7)) /* "REGEDIT" without NUL */
541  return REG_VERSION_FUZZY;
542 
543  return REG_VERSION_INVALID;
544 }
545 
546 /* handler for parser HEADER state */
548 {
549  WCHAR *line, *header;
550 
551  if (!(line = get_line(parser->file)))
552  return NULL;
553 
554  if (!parser->is_unicode)
555  {
556  header = malloc((lstrlenW(line) + 3) * sizeof(WCHAR));
557  header[0] = parser->two_wchars[0];
558  header[1] = parser->two_wchars[1];
559  lstrcpyW(header + 2, line);
561  free(header);
562  }
564 
565  switch (parser->reg_version)
566  {
567  case REG_VERSION_31:
569  break;
570  case REG_VERSION_40:
571  case REG_VERSION_50:
573  break;
574  default:
575  get_line(NULL); /* Reset static variables */
576  return NULL;
577  }
578 
579  return line;
580 }
581 
582 /* handler for parser PARSE_WIN31_LINE state */
584 {
585  WCHAR *line, *value;
586  static WCHAR hkcr[] = L"HKEY_CLASSES_ROOT";
587  unsigned int key_end = 0;
588 
589  if (!(line = get_line(parser->file)))
590  return NULL;
591 
592  if (wcsncmp(line, hkcr, lstrlenW(hkcr)))
593  return line;
594 
595  /* get key name */
596  while (line[key_end] && !iswspace(line[key_end])) key_end++;
597 
598  value = line + key_end;
599  while (*value == ' ' || *value == '\t') value++;
600 
601  if (*value == '=') value++;
602  if (*value == ' ') value++; /* at most one space is skipped */
603 
604  line[key_end] = 0;
605 
607  {
609  return line;
610  }
611 
614  parser->data = value;
615  parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
616 
618  return value;
619 }
620 
621 /* handler for parser LINE_START state */
623 {
624  WCHAR *line, *p;
625 
626  if (!(line = get_line(parser->file)))
627  return NULL;
628 
629  for (p = line; *p; p++)
630  {
631  switch (*p)
632  {
633  case '[':
635  return p + 1;
636  case '@':
638  return p;
639  case '"':
641  return p + 1;
642  case ' ':
643  case '\t':
644  break;
645  default:
646  return p;
647  }
648  }
649 
650  return p;
651 }
652 
653 /* handler for parser KEY_NAME state */
655 {
656  WCHAR *p = pos, *key_end;
657 
658  if (*p == ' ' || *p == '\t' || !(key_end = wcsrchr(p, ']')))
659  goto done;
660 
661  *key_end = 0;
662 
663  if (*p == '-')
664  {
666  return p + 1;
667  }
668  else if (open_key(parser, p) != ERROR_SUCCESS)
670 
671 done:
673  return p;
674 }
675 
676 /* handler for parser DELETE_KEY state */
678 {
679  WCHAR *p = pos;
680 
681  close_key(parser);
682 
683  if (*p == 'H' || *p == 'h')
685 
687  return p;
688 }
689 
690 /* handler for parser DEFAULT_VALUE_NAME state */
692 {
695 
697  return pos + 1;
698 }
699 
700 /* handler for parser QUOTED_VALUE_NAME state */
702 {
703  WCHAR *val_name = pos, *p;
704 
707 
708  if (!REGPROC_unescape_string(val_name, &p))
709  goto invalid;
710 
711  /* copy the value name in case we need to parse multiple lines and the buffer is overwritten */
712  parser->value_name = malloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
713  lstrcpyW(parser->value_name, val_name);
714 
716  return p;
717 
718 invalid:
720  return val_name;
721 }
722 
723 /* handler for parser DATA_START state */
725 {
726  WCHAR *p = pos;
727  unsigned int len;
728 
729  while (*p == ' ' || *p == '\t') p++;
730  if (*p != '=') goto done;
731  p++;
732  while (*p == ' ' || *p == '\t') p++;
733 
734  /* trim trailing whitespace */
735  len = lstrlenW(p);
736  while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t')) len--;
737  p[len] = 0;
738 
739  if (*p == '-')
741  else
743  return p;
744 
745 done:
747  return p;
748 }
749 
750 /* handler for parser DELETE_VALUE state */
752 {
753  WCHAR *p = pos + 1;
754 
755  while (*p == ' ' || *p == '\t') p++;
756  if (*p && *p != ';') goto done;
757 
759 
760 done:
762  return p;
763 }
764 
765 /* handler for parser DATA_TYPE state */
767 {
768  WCHAR *line = pos;
769 
770  if (!parse_data_type(parser, &line))
771  {
773  return line;
774  }
775 
776  switch (parser->parse_type)
777  {
778  case REG_SZ:
780  break;
781  case REG_DWORD:
783  break;
784  case REG_BINARY: /* all hex data types, including undefined */
786  break;
787  default:
789  }
790 
791  return line;
792 }
793 
794 /* handler for parser STRING_DATA state */
796 {
797  WCHAR *line;
798 
799  parser->data = pos;
800 
802  goto invalid;
803 
804  while (*line == ' ' || *line == '\t') line++;
805  if (*line && *line != ';') goto invalid;
806 
807  parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
808 
810  return line;
811 
812 invalid:
815  return line;
816 }
817 
818 /* handler for parser DWORD_DATA state */
820 {
821  WCHAR *line = pos;
822 
823  parser->data = malloc(sizeof(DWORD));
824 
826  goto invalid;
827 
828  parser->data_size = sizeof(DWORD);
829 
831  return line;
832 
833 invalid:
836  return line;
837 }
838 
839 /* handler for parser HEX_DATA state */
841 {
842  WCHAR *line = pos;
843 
844  if (!*line)
845  goto set_value;
846 
848  goto invalid;
849 
850  if (parser->backslash)
851  {
853  return line;
854  }
855 
857 
858 set_value:
860  return line;
861 
862 invalid:
865  return line;
866 }
867 
868 /* handler for parser EOL_BACKSLASH state */
870 {
871  WCHAR *p = pos;
872 
873  while (*p == ' ' || *p == '\t') p++;
874  if (*p && *p != ';') goto invalid;
875 
877  return pos;
878 
879 invalid:
882  return p;
883 }
884 
885 /* handler for parser HEX_MULTILINE state */
887 {
888  WCHAR *line;
889 
890  if (!(line = get_line(parser->file)))
891  {
894  return pos;
895  }
896 
897  while (*line == ' ' || *line == '\t') line++;
898  if (!*line || *line == ';') return line;
899 
900  if (!iswxdigit(*line)) goto invalid;
901 
903  return line;
904 
905 invalid:
908  return line;
909 }
910 
911 /* handler for parser UNKNOWN_DATA state */
913 {
915 
917  return pos;
918 }
919 
920 /* handler for parser SET_VALUE state */
922 {
925 
927 
930  else
932 
933  return pos;
934 }
935 
936 static WCHAR *get_lineA(FILE *fp)
937 {
938  static WCHAR *lineW;
939  static size_t size;
940  static char *buf, *next;
941  char *line;
942 
943  free(lineW);
944 
945  if (!fp) goto cleanup;
946 
947  if (!size)
948  {
950  buf = malloc(size);
951  *buf = 0;
952  next = buf;
953  }
954  line = next;
955 
956  while (next)
957  {
958  char *p = strpbrk(line, "\r\n");
959  if (!p)
960  {
961  size_t len, count;
962  len = strlen(next);
963  memmove(buf, next, len + 1);
964  if (size - len < 3)
965  {
966  size *= 2;
967  buf = realloc(buf, size);
968  }
969  if (!(count = fread(buf + len, 1, size - len - 1, fp)))
970  {
971  next = NULL;
972  lineW = GetWideString(buf);
973  return lineW;
974  }
975  buf[len + count] = 0;
976  next = buf;
977  line = buf;
978  continue;
979  }
980  next = p + 1;
981  if (*p == '\r' && *(p + 1) == '\n') next++;
982  *p = 0;
983  lineW = GetWideString(line);
984  return lineW;
985  }
986 
987 cleanup:
988  lineW = NULL;
989  if (size) free(buf);
990  size = 0;
991  return NULL;
992 }
993 
994 static WCHAR *get_lineW(FILE *fp)
995 {
996  static size_t size;
997  static WCHAR *buf, *next;
998  WCHAR *line;
999 
1000  if (!fp) goto cleanup;
1001 
1002  if (!size)
1003  {
1005  buf = malloc(size * sizeof(WCHAR));
1006  *buf = 0;
1007  next = buf;
1008  }
1009  line = next;
1010 
1011  while (next)
1012  {
1013  WCHAR *p = wcspbrk(line, L"\r\n");
1014  if (!p)
1015  {
1016  size_t len, count;
1017  len = lstrlenW(next);
1018  memmove(buf, next, (len + 1) * sizeof(WCHAR));
1019  if (size - len < 3)
1020  {
1021  size *= 2;
1022  buf = realloc(buf, size * sizeof(WCHAR));
1023  }
1024  if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
1025  {
1026  next = NULL;
1027  return buf;
1028  }
1029  buf[len + count] = 0;
1030  next = buf;
1031  line = buf;
1032  continue;
1033  }
1034  next = p + 1;
1035  if (*p == '\r' && *(p + 1) == '\n') next++;
1036  *p = 0;
1037  return line;
1038  }
1039 
1040 cleanup:
1041  if (size) free(buf);
1042  size = 0;
1043  return NULL;
1044 }
1045 
1046 /******************************************************************************
1047  * Reads contents of the specified file into the registry.
1048  */
1050 {
1051  BYTE s[2];
1052  struct parser parser;
1053  WCHAR *pos;
1054 
1055  if (!reg_file || (fread(s, 2, 1, reg_file) != 1))
1056  return FALSE;
1057 
1058  parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
1060 
1061  parser.file = reg_file;
1062  parser.two_wchars[0] = s[0];
1063  parser.two_wchars[1] = s[1];
1064  parser.reg_version = -1;
1065  parser.hkey = NULL;
1066  parser.key_name = NULL;
1068  parser.parse_type = 0;
1069  parser.data_type = 0;
1070  parser.data = NULL;
1071  parser.data_size = 0;
1073  parser.state = HEADER;
1074 
1075  pos = parser.two_wchars;
1076 
1077  /* parser main loop */
1078  while (pos)
1080 
1083 
1085  close_key(&parser);
1086 
1087  return TRUE;
1088 }
1089 
1090 /******************************************************************************
1091  * Removes the registry key with all subkeys. Parses full key name.
1092  *
1093  * Parameters:
1094  * reg_key_name - full name of registry branch to delete. Ignored if is NULL,
1095  * empty, points to register key class, does not exist.
1096  */
1097 void delete_registry_key(WCHAR *reg_key_name)
1098 {
1099  WCHAR *key_name = NULL;
1100  HKEY key_class;
1101 
1102  if (!reg_key_name || !reg_key_name[0])
1103  return;
1104 
1105  if (!(key_class = parse_key_name(reg_key_name, &key_name)))
1106  {
1107  if (key_name) *(key_name - 1) = 0;
1108  error_exit(STRING_INVALID_SYSTEM_KEY, reg_key_name);
1109  }
1110 
1111  if (!key_name || !*key_name)
1112  error_exit(STRING_DELETE_FAILED, reg_key_name);
1113 
1114 #ifdef __REACTOS__
1115  SHDeleteKey(key_class, key_name);
1116 #else
1117  RegDeleteTreeW(key_class, key_name);
1118 #endif
1119 }
1120 
1121 static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
1122 {
1123  if (unicode)
1124  fwrite(str, sizeof(WCHAR), lstrlenW(str), fp);
1125  else
1126  {
1127  char *strA = GetMultiByteString(str);
1128  fputs(strA, fp);
1129  free(strA);
1130  }
1131 }
1132 
1133 static WCHAR *REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
1134 {
1135  size_t i, escape_count, pos;
1136  WCHAR *buf;
1137 
1138  for (i = 0, escape_count = 0; i < str_len; i++)
1139  {
1140  WCHAR c = str[i];
1141 
1142  if (!c) break;
1143 
1144  if (c == '\r' || c == '\n' || c == '\\' || c == '"')
1145  escape_count++;
1146  }
1147 
1148  buf = malloc((str_len + escape_count + 1) * sizeof(WCHAR));
1149 
1150  for (i = 0, pos = 0; i < str_len; i++, pos++)
1151  {
1152  WCHAR c = str[i];
1153 
1154  if (!c) break;
1155 
1156  switch (c)
1157  {
1158  case '\r':
1159  buf[pos++] = '\\';
1160  buf[pos] = 'r';
1161  break;
1162  case '\n':
1163  buf[pos++] = '\\';
1164  buf[pos] = 'n';
1165  break;
1166  case '\\':
1167  buf[pos++] = '\\';
1168  buf[pos] = '\\';
1169  break;
1170  case '"':
1171  buf[pos++] = '\\';
1172  buf[pos] = '"';
1173  break;
1174  default:
1175  buf[pos] = c;
1176  }
1177  }
1178 
1179  buf[pos] = 0;
1180  *line_len = pos;
1181  return buf;
1182 }
1183 
1184 static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
1185 {
1186  static const WCHAR default_name[] = L"@=";
1187  size_t line_len;
1188 
1189  if (name && *name)
1190  {
1191  WCHAR *str = REGPROC_escape_string(name, len, &line_len);
1192  WCHAR *buf = malloc((line_len + 4) * sizeof(WCHAR));
1193 #ifdef __REACTOS__
1194  line_len = swprintf(buf, L"\"%s\"=", str);
1195 #else
1196  line_len = swprintf(buf, line_len + 4, L"\"%s\"=", str);
1197 #endif
1198  REGPROC_write_line(fp, buf, unicode);
1199  free(buf);
1200  free(str);
1201  }
1202  else
1203  {
1204  line_len = lstrlenW(default_name);
1205  REGPROC_write_line(fp, default_name, unicode);
1206  }
1207 
1208  return line_len;
1209 }
1210 
1211 static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
1212 {
1213  size_t len = 0, line_len;
1214  WCHAR *str;
1215 
1216  if (size)
1217  len = size / sizeof(WCHAR) - 1;
1218  str = REGPROC_escape_string(data, len, &line_len);
1219  *buf = malloc((line_len + 3) * sizeof(WCHAR));
1220 #ifdef __REACTOS__
1221  swprintf(*buf, L"\"%s\"", str);
1222 #else
1223  swprintf(*buf, line_len + 3, L"\"%s\"", str);
1224 #endif
1225  free(str);
1226 }
1227 
1229 {
1230  *buf = malloc(15 * sizeof(WCHAR));
1231 #ifdef __REACTOS__
1232  swprintf(*buf, L"dword:%08x", *data);
1233 #else
1234  swprintf(*buf, 15, L"dword:%08x", *data);
1235 #endif
1236 }
1237 
1238 static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
1239 {
1240  static const WCHAR hex[] = L"hex:";
1241  size_t line_len;
1242 
1243  if (type == REG_BINARY)
1244  {
1245  line_len = lstrlenW(hex);
1246  REGPROC_write_line(fp, hex, unicode);
1247  }
1248  else
1249  {
1250  WCHAR *buf = malloc(15 * sizeof(WCHAR));
1251 #ifdef __REACTOS__
1252  line_len = swprintf(buf, L"hex(%x):", type);
1253 #else
1254  line_len = swprintf(buf, 15, L"hex(%x):", type);
1255 #endif
1256  REGPROC_write_line(fp, buf, unicode);
1257  free(buf);
1258  }
1259 
1260  return line_len;
1261 }
1262 
1263 #define MAX_HEX_CHARS 77
1264 
1265 static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len,
1266  void *data, DWORD size, BOOL unicode)
1267 {
1268  size_t num_commas, i, pos;
1269 
1270  line_len += export_hex_data_type(fp, type, unicode);
1271 
1272  if (!size) return;
1273 
1274  if (!unicode && (type == REG_EXPAND_SZ || type == REG_MULTI_SZ))
1275  data = GetMultiByteStringN(data, size / sizeof(WCHAR), &size);
1276 
1277  num_commas = size - 1;
1278  *buf = malloc(size * 3 * sizeof(WCHAR));
1279 
1280  for (i = 0, pos = 0; i < size; i++)
1281  {
1282 #ifdef __REACTOS__
1283  pos += swprintf(*buf + pos, L"%02x", ((BYTE *)data)[i]);
1284 #else
1285  pos += swprintf(*buf + pos, 3, L"%02x", ((BYTE *)data)[i]);
1286 #endif
1287  if (i == num_commas) break;
1288  (*buf)[pos++] = ',';
1289  (*buf)[pos] = 0;
1290  line_len += 3;
1291 
1292  if (line_len >= MAX_HEX_CHARS)
1293  {
1294  REGPROC_write_line(fp, *buf, unicode);
1295  REGPROC_write_line(fp, L"\\\r\n ", unicode);
1296  line_len = 2;
1297  pos = 0;
1298  }
1299  }
1300 }
1301 
1302 static void export_newline(FILE *fp, BOOL unicode)
1303 {
1304  REGPROC_write_line(fp, L"\r\n", unicode);
1305 }
1306 
1307 static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type,
1308  void *data, size_t size, BOOL unicode)
1309 {
1310  WCHAR *buf = NULL;
1311  size_t line_len = export_value_name(fp, value_name, value_len, unicode);
1312 
1313  switch (type)
1314  {
1315  case REG_SZ:
1317  break;
1318  case REG_DWORD:
1319  if (size)
1320  {
1322  break;
1323  }
1324  /* fall through */
1325  case REG_NONE:
1326  case REG_EXPAND_SZ:
1327  case REG_BINARY:
1328  case REG_MULTI_SZ:
1329  default:
1330  export_hex_data(fp, &buf, type, line_len, data, size, unicode);
1331  break;
1332  }
1333 
1334  if (size || type == REG_SZ)
1335  {
1336  REGPROC_write_line(fp, buf, unicode);
1337  free(buf);
1338  }
1339 
1340  export_newline(fp, unicode);
1341 }
1342 
1343 static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
1344 {
1345  WCHAR *subkey_path;
1346 
1347  subkey_path = malloc((path_len + subkey_len + 2) * sizeof(WCHAR));
1348 #ifdef __REACTOS__
1349  swprintf(subkey_path, L"%s\\%s", path, subkey_name);
1350 #else
1351  swprintf(subkey_path, path_len + subkey_len + 2, L"%s\\%s", path, subkey_name);
1352 #endif
1353 
1354  return subkey_path;
1355 }
1356 
1357 static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
1358 {
1359  WCHAR *buf;
1360 
1361  buf = malloc((lstrlenW(name) + 7) * sizeof(WCHAR));
1362 #ifdef __REACTOS__
1363  swprintf(buf, L"\r\n[%s]\r\n", name);
1364 #else
1365  swprintf(buf, lstrlenW(name) + 7, L"\r\n[%s]\r\n", name);
1366 #endif
1367  REGPROC_write_line(fp, buf, unicode);
1368  free(buf);
1369 }
1370 
1371 #define MAX_SUBKEY_LEN 257
1372 
1373 static int export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
1374 {
1375  LONG rc;
1376  DWORD max_value_len = 256, value_len;
1377  DWORD max_data_bytes = 2048, data_size;
1378  DWORD subkey_len;
1379  DWORD i, type, path_len;
1380  WCHAR *value_name, *subkey_name, *subkey_path;
1381  BYTE *data;
1382  HKEY subkey;
1383 
1384  export_key_name(fp, path, unicode);
1385 
1386  value_name = malloc(max_value_len * sizeof(WCHAR));
1387  data = malloc(max_data_bytes);
1388 
1389  i = 0;
1390  for (;;)
1391  {
1392  value_len = max_value_len;
1393  data_size = max_data_bytes;
1394  rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
1395  if (rc == ERROR_SUCCESS)
1396  {
1397  export_data(fp, value_name, value_len, type, data, data_size, unicode);
1398  i++;
1399  }
1400  else if (rc == ERROR_MORE_DATA)
1401  {
1402  if (data_size > max_data_bytes)
1403  {
1404  max_data_bytes = data_size;
1405  data = realloc(data, max_data_bytes);
1406  }
1407  else
1408  {
1409  max_value_len *= 2;
1410  value_name = realloc(value_name, max_value_len * sizeof(WCHAR));
1411  }
1412  }
1413  else break;
1414  }
1415 
1416  free(data);
1417  free(value_name);
1418 
1419  subkey_name = malloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
1420 
1421  path_len = lstrlenW(path);
1422 
1423  i = 0;
1424  for (;;)
1425  {
1426  subkey_len = MAX_SUBKEY_LEN;
1427  rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
1428  if (rc == ERROR_SUCCESS)
1429  {
1430  subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
1431  if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
1432  {
1433  export_registry_data(fp, subkey, subkey_path, unicode);
1434  RegCloseKey(subkey);
1435  }
1436  free(subkey_path);
1437  i++;
1438  }
1439  else break;
1440  }
1441 
1442  free(subkey_name);
1443  return 0;
1444 }
1445 
1447 {
1448  FILE *file;
1449 
1450  if (!lstrcmpW(file_name, L"-"))
1451  {
1452  file = stdout;
1454  }
1455  else
1456  {
1457  file = _wfopen(file_name, L"wb");
1458  if (!file)
1459  {
1460  _wperror(L"regedit");
1462  }
1463  }
1464 
1465  if (unicode)
1466  {
1467  static const BYTE bom[] = {0xff,0xfe};
1468  static const WCHAR header[] = L"Windows Registry Editor Version 5.00\r\n";
1469 
1470  fwrite(bom, sizeof(BYTE), ARRAY_SIZE(bom), file);
1471  fwrite(header, sizeof(WCHAR), lstrlenW(header), file);
1472  }
1473  else
1474  fputs("REGEDIT4\r\n", file);
1475 
1476  return file;
1477 }
1478 
1479 static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
1480 {
1481  HKEY key;
1482 
1483  if (!RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key))
1484  return key;
1485 
1487  return NULL;
1488 }
1489 
1491 {
1492  HKEY key_class, key;
1493  WCHAR *subkey;
1494  FILE *fp;
1495  BOOL ret;
1496 
1497  if (!(key_class = parse_key_name(path, &subkey)))
1498  {
1499  if (subkey) *(subkey - 1) = 0;
1501  return FALSE;
1502  }
1503 
1504  if (!(key = open_export_key(key_class, subkey, path)))
1505  return FALSE;
1506 
1507  fp = REGPROC_open_export_file(file_name, unicode);
1508  ret = export_registry_data(fp, key, path, unicode);
1509  export_newline(fp, unicode);
1510  fclose(fp);
1511 
1512  RegCloseKey(key);
1513  return ret;
1514 }
1515 
1517 {
1518  FILE *fp;
1519  int i;
1520  HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
1521  WCHAR *class_name;
1522 
1523  fp = REGPROC_open_export_file(file_name, unicode);
1524 
1525  for (i = 0; i < ARRAY_SIZE(classes); i++)
1526  {
1527  if (!(key = open_export_key(classes[i], NULL, path)))
1528  {
1529  fclose(fp);
1530  return FALSE;
1531  }
1532 
1533  class_name = malloc((lstrlenW(reg_class_namesW[i]) + 1) * sizeof(WCHAR));
1534  lstrcpyW(class_name, reg_class_namesW[i]);
1535 
1536  export_registry_data(fp, classes[i], class_name, unicode);
1537 
1538  free(class_name);
1539  RegCloseKey(key);
1540  }
1541 
1542  export_newline(fp, unicode);
1543  fclose(fp);
1544 
1545  return TRUE;
1546 }
1547 
1549 {
1550  BOOL unicode = (format == REG_FORMAT_5);
1551 
1552  if (path && *path)
1553  return export_key(file_name, path, unicode);
1554  else
1555  return export_all(file_name, path, unicode);
1556 }
#define realloc
Definition: debug_ros.c:6
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
#define HKEY_USERS
Definition: winreg.h:13
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1548
static const WCHAR invalid[]
Definition: assoc.c:39
static WCHAR * GetWideStringN(const char *strA, int chars, DWORD *len)
Definition: regproc.c:67
static WCHAR * parse_win31_line_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:583
char strA[12]
Definition: clipboard.c:2028
static size_t export_hex_data_type(FILE *fp, DWORD type, BOOL unicode)
Definition: regproc.c:1238
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define _setmode(fd, mode)
Definition: cat.c:21
Definition: pdh_main.c:93
static void export_key_name(FILE *fp, WCHAR *name, BOOL unicode)
Definition: regproc.c:1357
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: regproc.c:182
#define ERROR_SUCCESS
Definition: deptool.c:10
static enum reg_versions parse_file_header(const WCHAR *s)
Definition: regproc.c:520
#define WideCharToMultiByte
Definition: compat.h:111
#define error(str)
Definition: mkdosfs.c:1605
BOOL is_unicode
Definition: import.c:84
static void close_key(struct parser *parser)
Definition: regproc.c:428
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
#define REG_BINARY
Definition: nt_native.h:1496
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define iswxdigit(_c)
Definition: ctype.h:668
const WCHAR * reg_class_namesW[]
Definition: main.c:25
#define CP_ACP
Definition: compat.h:109
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
enum parser_state state
Definition: import.c:95
static BOOL export_key(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1490
#define str_len
Definition: treelist.c:89
_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)
static BOOL export_all(WCHAR *file_name, WCHAR *path, BOOL unicode)
Definition: regproc.c:1516
static void export_newline(FILE *fp, BOOL unicode)
Definition: regproc.c:1302
static WCHAR * default_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:691
static void export_dword_data(WCHAR **buf, DWORD *data)
Definition: regproc.c:1228
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:92
#define HKEY_DYN_DATA
Definition: winreg.h:16
int errno
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
static WCHAR *(* get_line)(FILE *)
Definition: regproc.c:119
_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)
static WCHAR * hex_multiline_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:886
static WCHAR * set_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:921
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
static const char hex[16]
Definition: profile.c:123
static WCHAR * line_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:622
#define lstrlenW
Definition: compat.h:750
static void export_hex_data(FILE *fp, WCHAR **buf, DWORD type, DWORD line_len, void *data, DWORD size, BOOL unicode)
Definition: regproc.c:1265
#define DWORD
Definition: nt_native.h:44
BOOL backslash
Definition: import.c:94
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
FILE * stdout
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:1091
static WCHAR * dword_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:819
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD parse_type
Definition: import.c:90
#define L(x)
Definition: ntvdm.h:50
_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)
static FILE * REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
Definition: regproc.c:1446
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
long LONG
Definition: pedump.c:60
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static PVOID ptr
Definition: dispmode.c:27
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
const WCHAR * str
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:2853
short int reg_version
Definition: import.c:85
#define STRING_INVALID_SYSTEM_KEY
Definition: resource.h:54
Definition: parser.c:48
static void REGPROC_write_line(FILE *fp, const WCHAR *str, BOOL unicode)
Definition: regproc.c:1121
#define STRING_DELETE_FAILED
Definition: resource.h:323
WCHAR *(* parser_state_func)(struct parser *parser, WCHAR *pos)
Definition: regproc.c:161
char * GetMultiByteString(const WCHAR *strW)
Definition: regproc.c:86
static char * GetMultiByteStringN(const WCHAR *strW, int chars, DWORD *len)
Definition: regproc.c:104
static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
Definition: regproc.c:402
GLuint GLfloat * val
Definition: glext.h:7180
static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes, void *dst_data)
Definition: effect.c:889
WCHAR * key_name
Definition: import.c:88
static BOOL REGPROC_unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: regproc.c:360
#define STRING_OPEN_KEY_FAILED
Definition: resource.h:318
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
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:4899
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STRING_UNKNOWN_DATA_FORMAT
Definition: resource.h:314
const char file[]
Definition: icontest.c:11
const GLubyte * c
Definition: glext.h:8905
static BOOL parse_data_type(struct parser *parser, WCHAR **line)
Definition: regproc.c:308
unsigned long DWORD
Definition: ntddk_ex.h:95
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:103
FILE * file
Definition: import.c:82
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
_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)
static WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: regproc.c:1343
GLuint GLuint end
Definition: gl.h:1545
#define MAX_HEX_CHARS
Definition: regproc.c:1263
#define iswspace(_c)
Definition: ctype.h:669
#define ERANGE
Definition: acclib.h:92
static WCHAR * delete_key_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:677
int ret
#define wcsnicmp
Definition: compat.h:14
#define _O_BINARY
Definition: cabinet.h:51
static WCHAR * quoted_value_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:701
HKEY hkey
Definition: import.c:87
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
Definition: regproc.c:214
HKEY key
Definition: reg.c:28
static int state
Definition: maze.c:121
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
static void free_parser_data(struct parser *parser)
Definition: regproc.c:470
reg_versions
Definition: import.c:432
static WCHAR * data_type_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:766
GLsizei const GLfloat * value
Definition: glext.h:6069
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_CRTIMP void __cdecl _wperror(_In_opt_z_ const wchar_t *_ErrMsg)
#define wcsrchr
Definition: compat.h:16
IN PCTCH line
Definition: pager.h:36
static WCHAR * REGPROC_escape_string(WCHAR *str, size_t str_len, size_t *line_len)
Definition: regproc.c:1133
int _cdecl swprintf(const WCHAR *,...)
static LONG open_key(struct parser *parser, WCHAR *path)
Definition: regproc.c:444
#define ERROR_MORE_DATA
Definition: dderror.h:13
static WCHAR * hex_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:840
unsigned char BYTE
Definition: xxhash.c:193
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:308
static void export_data(FILE *fp, WCHAR *value_name, DWORD value_len, DWORD type, void *data, size_t size, BOOL unicode)
Definition: regproc.c:1307
static WCHAR * header_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:547
#define STRING_ESCAPE_SEQUENCE
Definition: resource.h:80
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
#define MAX_SUBKEY_LEN
Definition: regproc.c:1371
static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
Definition: regproc.c:248
static unsigned __int64 next
Definition: rand_nt.c:6
static DWORD path_len
Definition: batch.c:31
#define lstrcpyW
Definition: compat.h:749
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
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
WCHAR * value_name
Definition: import.c:89
static WCHAR * unknown_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:912
#define ARRAY_SIZE(a)
Definition: main.h:24
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
static void prepare_hex_string_data(struct parser *parser)
Definition: regproc.c:479
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: regproc.c:204
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
Definition: regproc.c:1479
#define NULL
Definition: types.h:112
static int export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
Definition: regproc.c:1373
void * data
Definition: import.c:92
static WCHAR * eol_backslash_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:869
static WCHAR * GetWideString(const char *strA)
Definition: regproc.c:49
WCHAR two_wchars[2]
Definition: import.c:83
#define MultiByteToWideChar
Definition: compat.h:110
#define SHDeleteKey
Definition: shlwapi.h:44
static LPCWSTR file_name
Definition: protocol.c:147
static HKEY reg_class_keys[]
Definition: regproc.c:40
static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
Definition: regproc.c:1211
static WCHAR * delete_value_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:751
Definition: import.c:80
DWORD data_type
Definition: import.c:91
Definition: name.c:38
static WCHAR * key_name_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:654
GLuint res
Definition: glext.h:9613
#define c
Definition: ke_i.h:80
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1049
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define towlower(c)
Definition: wctype.h:97
char * cleanup(char *str)
Definition: wpickclick.c:99
#define malloc
Definition: debug_ros.c:4
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
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:2527
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define REG_NONE
Definition: nt_native.h:1492
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
GLfloat GLfloat p
Definition: glext.h:8902
static WCHAR * get_lineA(FILE *fp)
Definition: regproc.c:936
#define REG_DWORD
Definition: sdbapi.c:596
static size_t export_value_name(FILE *fp, WCHAR *name, size_t len, BOOL unicode)
Definition: regproc.c:1184
static WCHAR * string_data_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:795
#define REG_VAL_BUF_SIZE
Definition: regproc.c:38
#define RegCloseKey(hKey)
Definition: registry.h:47
static WCHAR * get_lineW(FILE *fp)
Definition: regproc.c:994
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
struct CFHEADER header
Definition: fdi.c:101
DWORD data_size
Definition: import.c:93
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1097
#define d
Definition: ke_i.h:81
#define REG_FORMAT_5
Definition: main.h:44
Definition: copy.c:22
static WCHAR * data_start_state(struct parser *parser, WCHAR *pos)
Definition: regproc.c:724
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
parser_state
Definition: import.c:58
Definition: fci.c:126
#define REG_SZ
Definition: layer.c:22
char * tag
Definition: main.c:59