ReactOS  0.4.15-dev-4934-gfd1e799
import.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Hugh McMaster
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include <errno.h>
20 #include <stdio.h>
21 #include "reg.h"
22 #include <wine/debug.h>
23 
25 
26 static WCHAR *GetWideString(const char *strA)
27 {
28  if (strA)
29  {
30  WCHAR *strW;
31  int len = MultiByteToWideChar(CP_ACP, 0, strA, -1, NULL, 0);
32 
33  strW = malloc(len * sizeof(WCHAR));
35  return strW;
36  }
37  return NULL;
38 }
39 
40 static WCHAR *GetWideStringN(const char *strA, int size, DWORD *len)
41 {
42  if (strA)
43  {
44  WCHAR *strW;
46 
47  strW = malloc(*len * sizeof(WCHAR));
49  return strW;
50  }
51  *len = 0;
52  return NULL;
53 }
54 
55 static WCHAR *(*get_line)(FILE *);
56 
57 /* parser definitions */
59 {
60  HEADER, /* parsing the registry file version header */
61  PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */
62  LINE_START, /* at the beginning of a registry line */
63  KEY_NAME, /* parsing a key name */
64  DELETE_KEY, /* deleting a registry key */
65  DEFAULT_VALUE_NAME, /* parsing a default value name */
66  QUOTED_VALUE_NAME, /* parsing a double-quoted value name */
67  DATA_START, /* preparing for data parsing operations */
68  DELETE_VALUE, /* deleting a registry value */
69  DATA_TYPE, /* parsing the registry data type */
70  STRING_DATA, /* parsing REG_SZ data */
71  DWORD_DATA, /* parsing DWORD data */
72  HEX_DATA, /* parsing REG_BINARY, REG_NONE, REG_EXPAND_SZ or REG_MULTI_SZ data */
73  EOL_BACKSLASH, /* preparing to parse multiple lines of hex data */
74  HEX_MULTILINE, /* parsing multiple lines of hex data */
75  UNKNOWN_DATA, /* parsing an unhandled or invalid data type */
76  SET_VALUE, /* adding a value to the registry */
78 };
79 
80 struct parser
81 {
82  FILE *file; /* pointer to a registry file */
83  WCHAR two_wchars[2]; /* first two characters from the encoding check */
84  BOOL is_unicode; /* parsing Unicode or ASCII data */
85  short int reg_version; /* registry file version */
86  REGSAM sam; /* 32-bit or 64-bit registry view (if set) */
87  HKEY hkey; /* current registry key */
88  WCHAR *key_name; /* current key name */
89  WCHAR *value_name; /* value name */
90  DWORD parse_type; /* generic data type for parsing */
91  DWORD data_type; /* data type */
92  void *data; /* value data */
93  DWORD data_size; /* size of the data (in bytes) */
94  BOOL backslash; /* TRUE if the current line contains a backslash */
95  enum parser_state state; /* current parser state */
96 };
97 
98 typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
99 
100 /* parser state machine functions */
101 static WCHAR *header_state(struct parser *parser, WCHAR *pos);
103 static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
104 static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
105 static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
108 static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
109 static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
110 static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
111 static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
112 static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
113 static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
114 static WCHAR *eol_backslash_state(struct parser *parser, WCHAR *pos);
115 static WCHAR *hex_multiline_state(struct parser *parser, WCHAR *pos);
116 static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
117 static WCHAR *set_value_state(struct parser *parser, WCHAR *pos);
118 
120 {
121  header_state, /* HEADER */
122  parse_win31_line_state, /* PARSE_WIN31_LINE */
123  line_start_state, /* LINE_START */
124  key_name_state, /* KEY_NAME */
125  delete_key_state, /* DELETE_KEY */
126  default_value_name_state, /* DEFAULT_VALUE_NAME */
127  quoted_value_name_state, /* QUOTED_VALUE_NAME */
128  data_start_state, /* DATA_START */
129  delete_value_state, /* DELETE_VALUE */
130  data_type_state, /* DATA_TYPE */
131  string_data_state, /* STRING_DATA */
132  dword_data_state, /* DWORD_DATA */
133  hex_data_state, /* HEX_DATA */
134  eol_backslash_state, /* EOL_BACKSLASH */
135  hex_multiline_state, /* HEX_MULTILINE */
136  unknown_data_state, /* UNKNOWN_DATA */
137  set_value_state, /* SET_VALUE */
138 };
139 
140 /* set the new parser state and return the previous one */
141 static inline enum parser_state set_state(struct parser *parser, enum parser_state state)
142 {
143  enum parser_state ret = parser->state;
144  parser->state = state;
145  return ret;
146 }
147 
148 /******************************************************************************
149  * Converts a hex representation of a DWORD into a DWORD.
150  */
152 {
153  WCHAR *p, *end;
154  int count = 0;
155 
156  while (*str == ' ' || *str == '\t') str++;
157  if (!*str) goto error;
158 
159  p = str;
160  while (iswxdigit(*p))
161  {
162  count++;
163  p++;
164  }
165  if (count > 8) goto error;
166 
167  end = p;
168  while (*p == ' ' || *p == '\t') p++;
169  if (*p && *p != ';') goto error;
170 
171  *end = 0;
172  *dw = wcstoul(str, &end, 16);
173  return TRUE;
174 
175 error:
176  return FALSE;
177 }
178 
179 /******************************************************************************
180  * Converts comma-separated hex data into a binary string and modifies
181  * the input parameter to skip the concatenating backslash, if found.
182  *
183  * Returns TRUE or FALSE to indicate whether parsing was successful.
184  */
186 {
187  size_t size;
188  BYTE *d;
189  WCHAR *s;
190 
192 
193  /* The worst case is 1 digit + 1 comma per byte */
194  size = ((lstrlenW(*str) + 1) / 2) + parser->data_size;
196 
197  s = *str;
198  d = (BYTE *)parser->data + parser->data_size;
199 
200  while (*s)
201  {
202  WCHAR *end;
203  unsigned long wc;
204 
205  wc = wcstoul(s, &end, 16);
206  if (wc > 0xff) return FALSE;
207 
208  if (s == end && wc == 0)
209  {
210  while (*end == ' ' || *end == '\t') end++;
211  if (*end == '\\')
212  {
213  parser->backslash = TRUE;
214  *str = end + 1;
215  return TRUE;
216  }
217  else if (*end == ';')
218  return TRUE;
219  return FALSE;
220  }
221 
222  *d++ = wc;
223  parser->data_size++;
224 
225  if (*end && *end != ',')
226  {
227  while (*end == ' ' || *end == '\t') end++;
228  if (*end && *end != ';') return FALSE;
229  return TRUE;
230  }
231 
232  if (*end) end++;
233  s = end;
234  }
235 
236  return TRUE;
237 }
238 
239 /******************************************************************************
240  * Parses the data type of the registry value being imported and modifies
241  * the input parameter to skip the string representation of the data type.
242  *
243  * Returns TRUE or FALSE to indicate whether a data type was found.
244  */
246 {
247  struct data_type { const WCHAR *tag; int len; int type; int parse_type; };
248 
249  static const struct data_type data_types[] = {
250  /* tag len type parse type */
251  { L"\"", 1, REG_SZ, REG_SZ },
252  { L"hex:", 4, REG_BINARY, REG_BINARY },
253  { L"dword:", 6, REG_DWORD, REG_DWORD },
254  { L"hex(", 4, -1, REG_BINARY }, /* REG_NONE, REG_EXPAND_SZ, REG_MULTI_SZ */
255  { NULL, 0, 0, 0 }
256  };
257 
258  const struct data_type *ptr;
259 
260  for (ptr = data_types; ptr->tag; ptr++)
261  {
262  if (wcsncmp(ptr->tag, *line, ptr->len))
263  continue;
264 
265  parser->parse_type = ptr->parse_type;
266  parser->data_type = ptr->parse_type;
267  *line += ptr->len;
268 
269  if (ptr->type == -1)
270  {
271  WCHAR *end;
272  DWORD val;
273 
274  if (!**line || towlower((*line)[1]) == 'x')
275  return FALSE;
276 
277  /* "hex(xx):" is special */
278  val = wcstoul(*line, &end, 16);
279  if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE))
280  return FALSE;
281 
282  parser->data_type = val;
283  *line = end + 2;
284  }
285  return TRUE;
286  }
287  return FALSE;
288 }
289 
290 /******************************************************************************
291  * Replaces escape sequences with their character equivalents and
292  * null-terminates the string on the first non-escaped double quote.
293  *
294  * Assigns a pointer to the remaining unparsed data in the line.
295  * Returns TRUE or FALSE to indicate whether a closing double quote was found.
296  */
297 static BOOL unescape_string(WCHAR *str, WCHAR **unparsed)
298 {
299  int str_idx = 0; /* current character under analysis */
300  int val_idx = 0; /* the last character of the unescaped string */
301  int len = lstrlenW(str);
302  BOOL ret;
303 
304  for (str_idx = 0; str_idx < len; str_idx++, val_idx++)
305  {
306  if (str[str_idx] == '\\')
307  {
308  str_idx++;
309  switch (str[str_idx])
310  {
311  case 'n':
312  str[val_idx] = '\n';
313  break;
314  case 'r':
315  str[val_idx] = '\r';
316  break;
317  case '0':
318  return FALSE;
319  case '\\':
320  case '"':
321  str[val_idx] = str[str_idx];
322  break;
323  default:
324  if (!str[str_idx]) return FALSE;
326  str[val_idx] = str[str_idx];
327  break;
328  }
329  }
330  else if (str[str_idx] == '"')
331  break;
332  else
333  str[val_idx] = str[str_idx];
334  }
335 
336  ret = (str[str_idx] == '"');
337  *unparsed = str + str_idx + 1;
338  str[val_idx] = '\0';
339  return ret;
340 }
341 
342 static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
343 {
344  if (!key_name) return 0;
345 
346  *key_path = wcschr(key_name, '\\');
347  if (*key_path) (*key_path)++;
348 
349  return path_get_rootkey(key_name);
350 }
351 
352 static void close_key(struct parser *parser)
353 {
354  if (parser->hkey)
355  {
356  free(parser->key_name);
357  parser->key_name = NULL;
358 
360  parser->hkey = NULL;
361  }
362 }
363 
364 static LONG open_key(struct parser *parser, WCHAR *path)
365 {
366  HKEY key_class;
367  WCHAR *key_path;
368  LONG res;
369 
370  close_key(parser);
371 
372  /* Get the registry class */
373  if (!path || !(key_class = parse_key_name(path, &key_path)))
375 
376  res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
378 
379  if (res == ERROR_SUCCESS)
380  {
381  parser->key_name = malloc((lstrlenW(path) + 1) * sizeof(WCHAR));
383  }
384  else
385  parser->hkey = NULL;
386 
387  return res;
388 }
389 
390 static void free_parser_data(struct parser *parser)
391 {
393  free(parser->data);
394 
395  parser->data = NULL;
396  parser->data_size = 0;
397 }
398 
400 {
402  parser->data_type == REG_SZ)
403  {
404  if (parser->is_unicode)
405  {
406  WCHAR *data = parser->data;
407  DWORD len = parser->data_size / sizeof(WCHAR);
408 
409  if (data[len - 1] != 0)
410  {
411  data[len] = 0;
412  parser->data_size += sizeof(WCHAR);
413  }
414  }
415  else
416  {
417  BYTE *data = parser->data;
418 
419  if (data[parser->data_size - 1] != 0)
420  {
421  data[parser->data_size] = 0;
422  parser->data_size++;
423  }
424 
426  parser->data_size *= sizeof(WCHAR);
427  free(data);
428  }
429  }
430 }
431 
438 };
439 
441 {
442  static const WCHAR *header_31 = L"REGEDIT";
443 
444  while (*s == ' ' || *s == '\t') s++;
445 
446  if (!lstrcmpW(s, header_31))
447  return REG_VERSION_31;
448 
449  if (!lstrcmpW(s, L"REGEDIT4"))
450  return REG_VERSION_40;
451 
452  if (!lstrcmpW(s, L"Windows Registry Editor Version 5.00"))
453  return REG_VERSION_50;
454 
455  /* The Windows version accepts registry file headers beginning with "REGEDIT" and ending
456  * with other characters, as long as "REGEDIT" appears at the start of the line. For example,
457  * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all treated as valid file headers.
458  * In all such cases, however, the contents of the registry file are not imported.
459  */
460  if (!wcsncmp(s, header_31, 7)) /* "REGEDIT" without NUL */
461  return REG_VERSION_FUZZY;
462 
463  return REG_VERSION_INVALID;
464 }
465 
466 /* handler for parser HEADER state */
468 {
469  WCHAR *line, *header;
470 
471  if (!(line = get_line(parser->file)))
472  return NULL;
473 
474  if (!parser->is_unicode)
475  {
476  header = malloc((lstrlenW(line) + 3) * sizeof(WCHAR));
477  header[0] = parser->two_wchars[0];
478  header[1] = parser->two_wchars[1];
479  lstrcpyW(header + 2, line);
481  free(header);
482  }
484 
485  switch (parser->reg_version)
486  {
487  case REG_VERSION_31:
489  break;
490  case REG_VERSION_40:
491  case REG_VERSION_50:
493  break;
494  default:
495  get_line(NULL); /* Reset static variables */
496  return NULL;
497  }
498 
499  return line;
500 }
501 
502 /* handler for parser PARSE_WIN31_LINE state */
504 {
505  WCHAR *line, *value;
506  unsigned int key_end = 0;
507 
508  if (!(line = get_line(parser->file)))
509  return NULL;
510 
511  if (wcsncmp(line, L"HKEY_CLASSES_ROOT", 17)) /* "HKEY_CLASSES_ROOT" without NUL */
512  return line;
513 
514  /* get key name */
515  while (line[key_end] && !iswspace(line[key_end])) key_end++;
516 
517  value = line + key_end;
518  while (*value == ' ' || *value == '\t') value++;
519 
520  if (*value == '=') value++;
521  if (*value == ' ') value++; /* at most one space is skipped */
522 
523  line[key_end] = 0;
524 
526  {
528  return line;
529  }
530 
533  parser->data = value;
534  parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
535 
537  return value;
538 }
539 
540 /* handler for parser LINE_START state */
542 {
543  WCHAR *line, *p;
544 
545  if (!(line = get_line(parser->file)))
546  return NULL;
547 
548  for (p = line; *p; p++)
549  {
550  switch (*p)
551  {
552  case '[':
554  return p + 1;
555  case '@':
557  return p;
558  case '"':
560  return p + 1;
561  case ' ':
562  case '\t':
563  break;
564  default:
565  return p;
566  }
567  }
568 
569  return p;
570 }
571 
572 /* handler for parser KEY_NAME state */
574 {
575  WCHAR *p = pos, *key_end;
576 
577  if (*p == ' ' || *p == '\t' || !(key_end = wcsrchr(p, ']')))
578  goto done;
579 
580  *key_end = 0;
581 
582  if (*p == '-')
583  {
585  return p + 1;
586  }
587  else if (open_key(parser, p) != ERROR_SUCCESS)
589 
590 done:
592  return p;
593 }
594 
595 /* handler for parser DELETE_KEY state */
597 {
598  WCHAR *p = pos;
599 
600  close_key(parser);
601 
602  if (*p == 'H' || *p == 'h')
603  {
604  HKEY root;
605  WCHAR *path;
606 
607  root = parse_key_name(p, &path);
608 
609  if (root && path && *path)
611  }
612 
614  return p;
615 }
616 
617 /* handler for parser DEFAULT_VALUE_NAME state */
619 {
622 
624  return pos + 1;
625 }
626 
627 /* handler for parser QUOTED_VALUE_NAME state */
629 {
630  WCHAR *val_name = pos, *p;
631 
634 
635  if (!unescape_string(val_name, &p))
636  goto invalid;
637 
638  /* copy the value name in case we need to parse multiple lines and the buffer is overwritten */
639  parser->value_name = malloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
640  lstrcpyW(parser->value_name, val_name);
641 
643  return p;
644 
645 invalid:
647  return val_name;
648 }
649 
650 /* handler for parser DATA_START state */
652 {
653  WCHAR *p = pos;
654  unsigned int len;
655 
656  while (*p == ' ' || *p == '\t') p++;
657  if (*p != '=') goto invalid;
658  p++;
659  while (*p == ' ' || *p == '\t') p++;
660 
661  /* trim trailing whitespace */
662  len = lstrlenW(p);
663  while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t')) len--;
664  p[len] = 0;
665 
666  if (*p == '-')
668  else
670  return p;
671 
672 invalid:
674  return p;
675 }
676 
677 /* handler for parser DELETE_VALUE state */
679 {
680  WCHAR *p = pos + 1;
681 
682  while (*p == ' ' || *p == '\t') p++;
683  if (*p && *p != ';') goto done;
684 
686 
687 done:
689  return p;
690 }
691 
692 /* handler for parser DATA_TYPE state */
694 {
695  WCHAR *line = pos;
696 
697  if (!parse_data_type(parser, &line))
698  {
700  return line;
701  }
702 
703  switch (parser->parse_type)
704  {
705  case REG_SZ:
707  break;
708  case REG_DWORD:
710  break;
711  case REG_BINARY: /* all hex data types, including undefined */
713  break;
714  default:
716  }
717 
718  return line;
719 }
720 
721 /* handler for parser STRING_DATA state */
723 {
724  WCHAR *line;
725 
726  parser->data = pos;
727 
728  if (!unescape_string(parser->data, &line))
729  goto invalid;
730 
731  while (*line == ' ' || *line == '\t') line++;
732  if (*line && *line != ';') goto invalid;
733 
734  parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
735 
737  return line;
738 
739 invalid:
742  return line;
743 }
744 
745 /* handler for parser DWORD_DATA state */
747 {
748  WCHAR *line = pos;
749 
750  parser->data = malloc(sizeof(DWORD));
751 
753  goto invalid;
754 
755  parser->data_size = sizeof(DWORD);
756 
758  return line;
759 
760 invalid:
763  return line;
764 }
765 
766 /* handler for parser HEX_DATA state */
768 {
769  WCHAR *line = pos;
770 
771  if (!*line)
772  goto set_value;
773 
775  goto invalid;
776 
777  if (parser->backslash)
778  {
780  return line;
781  }
782 
784 
785 set_value:
787  return line;
788 
789 invalid:
792  return line;
793 }
794 
795 /* handler for parser EOL_BACKSLASH state */
797 {
798  WCHAR *p = pos;
799 
800  while (*p == ' ' || *p == '\t') p++;
801  if (*p && *p != ';') goto invalid;
802 
804  return pos;
805 
806 invalid:
809  return p;
810 }
811 
812 /* handler for parser HEX_MULTILINE state */
814 {
815  WCHAR *line;
816 
817  if (!(line = get_line(parser->file)))
818  {
821  return pos;
822  }
823 
824  while (*line == ' ' || *line == '\t') line++;
825  if (!*line || *line == ';') return line;
826 
827  if (!iswxdigit(*line)) goto invalid;
828 
830  return line;
831 
832 invalid:
835  return line;
836 }
837 
838 /* handler for parser UNKNOWN_DATA state */
840 {
841  FIXME("Unknown registry data type [0x%x]\n", parser->data_type);
842 
844  return pos;
845 }
846 
847 /* handler for parser SET_VALUE state */
849 {
852 
854 
857  else
859 
860  return pos;
861 }
862 
863 #define REG_VAL_BUF_SIZE 4096
864 
865 static WCHAR *get_lineA(FILE *fp)
866 {
867  static WCHAR *lineW;
868  static size_t size;
869  static char *buf, *next;
870  char *line;
871 
872  free(lineW);
873 
874  if (!fp) goto cleanup;
875 
876  if (!size)
877  {
879  buf = malloc(size);
880  *buf = 0;
881  next = buf;
882  }
883  line = next;
884 
885  while (next)
886  {
887  char *p = strpbrk(line, "\r\n");
888  if (!p)
889  {
890  size_t len, count;
891  len = strlen(next);
892  memmove(buf, next, len + 1);
893  if (size - len < 3)
894  {
895  size *= 2;
896  buf = realloc(buf, size);
897  }
898  if (!(count = fread(buf + len, 1, size - len - 1, fp)))
899  {
900  next = NULL;
901  lineW = GetWideString(buf);
902  return lineW;
903  }
904  buf[len + count] = 0;
905  next = buf;
906  line = buf;
907  continue;
908  }
909  next = p + 1;
910  if (*p == '\r' && *(p + 1) == '\n') next++;
911  *p = 0;
912  lineW = GetWideString(line);
913  return lineW;
914  }
915 
916 cleanup:
917  lineW = NULL;
918  free(buf);
919  size = 0;
920  return NULL;
921 }
922 
923 static WCHAR *get_lineW(FILE *fp)
924 {
925  static size_t size;
926  static WCHAR *buf, *next;
927  WCHAR *line;
928 
929  if (!fp) goto cleanup;
930 
931  if (!size)
932  {
934  buf = malloc(size * sizeof(WCHAR));
935  *buf = 0;
936  next = buf;
937  }
938  line = next;
939 
940  while (next)
941  {
942  WCHAR *p = wcspbrk(line, L"\r\n");
943  if (!p)
944  {
945  size_t len, count;
946  len = lstrlenW(next);
947  memmove(buf, next, (len + 1) * sizeof(WCHAR));
948  if (size - len < 3)
949  {
950  size *= 2;
951  buf = realloc(buf, size * sizeof(WCHAR));
952  }
953  if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
954  {
955  next = NULL;
956  return buf;
957  }
958  buf[len + count] = 0;
959  next = buf;
960  line = buf;
961  continue;
962  }
963  next = p + 1;
964  if (*p == '\r' && *(p + 1) == '\n') next++;
965  *p = 0;
966  return line;
967  }
968 
969 cleanup:
970  free(buf);
971  size = 0;
972  return NULL;
973 }
974 
975 int reg_import(int argc, WCHAR *argvW[])
976 {
977  WCHAR *filename, *pos;
978  FILE *fp;
979  BYTE s[2];
980  struct parser parser;
981 
982  if (argc > 4) goto invalid;
983 
984  parser.sam = 0;
985 
986  if (argc == 4)
987  {
988  WCHAR *str = argvW[3];
989 
990  if (*str != '/' && *str != '-')
991  goto invalid;
992 
993  str++;
994 
995  if (!lstrcmpiW(str, L"reg:32"))
997  else if (!lstrcmpiW(str, L"reg:64"))
999  else
1000  goto invalid;
1001  }
1002 
1003  filename = argvW[2];
1004 
1005  fp = _wfopen(filename, L"rb");
1006  if (!fp)
1007  {
1009  return 1;
1010  }
1011 
1012  if (fread(s, sizeof(WCHAR), 1, fp) != 1)
1013  goto error;
1014 
1015  parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
1017 
1018  parser.file = fp;
1019  parser.two_wchars[0] = s[0];
1020  parser.two_wchars[1] = s[1];
1021  parser.reg_version = -1;
1022  parser.hkey = NULL;
1023  parser.key_name = NULL;
1025  parser.parse_type = 0;
1026  parser.data_type = 0;
1027  parser.data = NULL;
1028  parser.data_size = 0;
1030  parser.state = HEADER;
1031 
1032  pos = parser.two_wchars;
1033 
1034  /* parser main loop */
1035  while (pos)
1037 
1039  goto error;
1040 
1042  close_key(&parser);
1043 
1044  fclose(fp);
1045  return 0;
1046 
1047 error:
1048  fclose(fp);
1049  return 1;
1050 
1051 invalid:
1054  return 1;
1055 }
#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
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: import.c:119
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
static WCHAR * quoted_value_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:628
static const WCHAR invalid[]
Definition: assoc.c:39
WCHAR * value_name
Definition: import.c:89
static int argc
Definition: ServiceArgs.c:12
char strA[12]
Definition: clipboard.c:2028
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
Definition: pdh_main.c:93
static WCHAR * data_start_state(struct parser *parser, WCHAR *pos)
Definition: import.c:651
static WCHAR * hex_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:767
#define ERROR_SUCCESS
Definition: deptool.c:10
#define error(str)
Definition: mkdosfs.c:1605
BOOL is_unicode
Definition: import.c:84
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 TRUE
Definition: types.h:120
GLsizei const GLchar ** path
Definition: glext.h:7234
#define iswxdigit(_c)
Definition: ctype.h:668
#define CP_ACP
Definition: compat.h:109
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
struct _root root
static WCHAR * get_lineA(FILE *fp)
Definition: import.c:865
enum parser_state state
Definition: import.c:95
static WCHAR * string_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:722
static WCHAR * get_lineW(FILE *fp)
Definition: import.c:923
static void prepare_hex_string_data(struct parser *parser)
Definition: import.c:399
static WCHAR * set_value_state(struct parser *parser, WCHAR *pos)
Definition: import.c:848
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:92
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)
WCHAR two_wchars[2]
Definition: import.c:83
const char * filename
Definition: ioapi.h:135
static WCHAR * header_state(struct parser *parser, WCHAR *pos)
Definition: import.c:467
static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
Definition: import.c:342
#define lstrlenW
Definition: compat.h:609
#define DWORD
Definition: nt_native.h:44
BOOL backslash
Definition: import.c:94
static WCHAR * unknown_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:839
#define REG_VAL_BUF_SIZE
Definition: import.c:863
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 * eol_backslash_state(struct parser *parser, WCHAR *pos)
Definition: import.c:796
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
void * data
Definition: import.c:92
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)
#define FALSE
Definition: types.h:117
static void close_key(struct parser *parser)
Definition: import.c:352
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
long LONG
Definition: pedump.c:60
WCHAR *(* parser_state_func)(struct parser *parser, WCHAR *pos)
Definition: import.c:98
REGSAM sam
Definition: import.c:86
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define FIXME(fmt,...)
Definition: debug.h:111
static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
Definition: import.c:185
static PVOID ptr
Definition: dispmode.c:27
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
const WCHAR * str
#define STRING_FUNC_HELP
Definition: resource.h:34
short int reg_version
Definition: import.c:85
Definition: parser.c:48
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
static WCHAR *(* get_line)(FILE *)
Definition: import.c:55
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
int reg_import(int argc, WCHAR *argvW[])
Definition: import.c:975
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
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
static WCHAR * GetWideString(const char *strA)
Definition: import.c:26
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: import.c:141
GLsizeiptr size
Definition: glext.h:5919
static WCHAR * dword_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:746
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define STRING_KEY_IMPORT_FAILED
Definition: resource.h:81
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STRING_INVALID_SYNTAX
Definition: resource.h:33
static void free_parser_data(struct parser *parser)
Definition: import.c:390
unsigned long DWORD
Definition: ntddk_ex.h:95
static WCHAR * delete_value_state(struct parser *parser, WCHAR *pos)
Definition: import.c:678
FILE * file
Definition: import.c:82
static int reg
Definition: i386-dis.c:1291
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static WCHAR * default_value_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:618
_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)
Definition: import.c:60
static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
Definition: import.c:151
GLuint GLuint end
Definition: gl.h:1545
#define iswspace(_c)
Definition: ctype.h:669
#define ERANGE
Definition: acclib.h:92
int ret
static LONG open_key(struct parser *parser, WCHAR *path)
Definition: import.c:364
#define STRING_FILE_NOT_FOUND
Definition: resource.h:8
static WCHAR * key_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:573
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 int state
Definition: maze.c:121
static enum reg_versions parse_file_header(const WCHAR *s)
Definition: import.c:440
static WCHAR * delete_key_state(struct parser *parser, WCHAR *pos)
Definition: import.c:596
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
reg_versions
Definition: import.c:432
GLsizei const GLfloat * value
Definition: glext.h:6069
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define wcsrchr
Definition: compat.h:16
IN PCTCH line
Definition: pager.h:36
unsigned char BYTE
Definition: xxhash.c:193
#define STRING_ESCAPE_SEQUENCE
Definition: resource.h:80
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
static unsigned __int64 next
Definition: rand_nt.c:6
#define lstrcpyW
Definition: compat.h:608
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
ACCESS_MASK REGSAM
Definition: winreg.h:69
static WCHAR * hex_multiline_state(struct parser *parser, WCHAR *pos)
Definition: import.c:813
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
#define NULL
Definition: types.h:112
#define MultiByteToWideChar
Definition: compat.h:110
WCHAR * key_name
Definition: import.c:88
HKEY path_get_rootkey(const WCHAR *path)
Definition: reg.c:165
Definition: import.c:80
DWORD data_type
Definition: import.c:91
GLuint res
Definition: glext.h:9613
#define towlower(c)
Definition: wctype.h:97
static WCHAR * data_type_state(struct parser *parser, WCHAR *pos)
Definition: import.c:693
char * cleanup(char *str)
Definition: wpickclick.c:99
#define malloc
Definition: debug_ros.c:4
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
static BOOL parse_data_type(struct parser *parser, WCHAR **line)
Definition: import.c:245
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
WINE_DEFAULT_DEBUG_CHANNEL(reg)
static WCHAR * parse_win31_line_state(struct parser *parser, WCHAR *pos)
Definition: import.c:503
static BOOL unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: import.c:297
GLfloat GLfloat p
Definition: glext.h:8902
#define REG_DWORD
Definition: sdbapi.c:596
#define RegCloseKey(hKey)
Definition: registry.h:47
static WCHAR * GetWideStringN(const char *strA, int size, DWORD *len)
Definition: import.c:40
struct CFHEADER header
Definition: fdi.c:101
DWORD data_size
Definition: import.c:93
#define d
Definition: ke_i.h:81
static WCHAR * line_start_state(struct parser *parser, WCHAR *pos)
Definition: import.c:541
parser_state
Definition: import.c:58
#define REG_SZ
Definition: layer.c:22
char * tag
Definition: main.c:59