ReactOS  0.4.15-dev-1039-gb9754fa
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 <windows.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include <wine/debug.h>
25 #include <wine/heap.h>
26 
27 #include "reg.h"
28 
30 
31 static WCHAR *GetWideString(const char *strA)
32 {
33  if (strA)
34  {
35  WCHAR *strW;
36  int len = MultiByteToWideChar(CP_ACP, 0, strA, -1, NULL, 0);
37 
38  strW = heap_xalloc(len * sizeof(WCHAR));
40  return strW;
41  }
42  return NULL;
43 }
44 
45 static WCHAR *GetWideStringN(const char *strA, int size, DWORD *len)
46 {
47  if (strA)
48  {
49  WCHAR *strW;
51 
52  strW = heap_xalloc(*len * sizeof(WCHAR));
54  return strW;
55  }
56  *len = 0;
57  return NULL;
58 }
59 
60 static WCHAR *(*get_line)(FILE *);
61 
62 /* parser definitions */
64 {
65  HEADER, /* parsing the registry file version header */
66  PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */
67  LINE_START, /* at the beginning of a registry line */
68  KEY_NAME, /* parsing a key name */
69  DELETE_KEY, /* deleting a registry key */
70  DEFAULT_VALUE_NAME, /* parsing a default value name */
71  QUOTED_VALUE_NAME, /* parsing a double-quoted value name */
72  DATA_START, /* preparing for data parsing operations */
73  DELETE_VALUE, /* deleting a registry value */
74  DATA_TYPE, /* parsing the registry data type */
75  STRING_DATA, /* parsing REG_SZ data */
76  DWORD_DATA, /* parsing DWORD data */
77  HEX_DATA, /* parsing REG_BINARY, REG_NONE, REG_EXPAND_SZ or REG_MULTI_SZ data */
78  EOL_BACKSLASH, /* preparing to parse multiple lines of hex data */
79  HEX_MULTILINE, /* parsing multiple lines of hex data */
80  UNKNOWN_DATA, /* parsing an unhandled or invalid data type */
81  SET_VALUE, /* adding a value to the registry */
83 };
84 
85 struct parser
86 {
87  FILE *file; /* pointer to a registry file */
88  WCHAR two_wchars[2]; /* first two characters from the encoding check */
89  BOOL is_unicode; /* parsing Unicode or ASCII data */
90  short int reg_version; /* registry file version */
91  HKEY hkey; /* current registry key */
92  WCHAR *key_name; /* current key name */
93  WCHAR *value_name; /* value name */
94  DWORD parse_type; /* generic data type for parsing */
95  DWORD data_type; /* data type */
96  void *data; /* value data */
97  DWORD data_size; /* size of the data (in bytes) */
98  BOOL backslash; /* TRUE if the current line contains a backslash */
99  enum parser_state state; /* current parser state */
100 };
101 
102 typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
103 
104 /* parser state machine functions */
105 static WCHAR *header_state(struct parser *parser, WCHAR *pos);
107 static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
108 static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
109 static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
112 static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
113 static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
114 static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
115 static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
116 static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
117 static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
118 static WCHAR *eol_backslash_state(struct parser *parser, WCHAR *pos);
119 static WCHAR *hex_multiline_state(struct parser *parser, WCHAR *pos);
120 static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
121 static WCHAR *set_value_state(struct parser *parser, WCHAR *pos);
122 
124 {
125  header_state, /* HEADER */
126  parse_win31_line_state, /* PARSE_WIN31_LINE */
127  line_start_state, /* LINE_START */
128  key_name_state, /* KEY_NAME */
129  delete_key_state, /* DELETE_KEY */
130  default_value_name_state, /* DEFAULT_VALUE_NAME */
131  quoted_value_name_state, /* QUOTED_VALUE_NAME */
132  data_start_state, /* DATA_START */
133  delete_value_state, /* DELETE_VALUE */
134  data_type_state, /* DATA_TYPE */
135  string_data_state, /* STRING_DATA */
136  dword_data_state, /* DWORD_DATA */
137  hex_data_state, /* HEX_DATA */
138  eol_backslash_state, /* EOL_BACKSLASH */
139  hex_multiline_state, /* HEX_MULTILINE */
140  unknown_data_state, /* UNKNOWN_DATA */
141  set_value_state, /* SET_VALUE */
142 };
143 
144 /* set the new parser state and return the previous one */
145 static inline enum parser_state set_state(struct parser *parser, enum parser_state state)
146 {
147  enum parser_state ret = parser->state;
148  parser->state = state;
149  return ret;
150 }
151 
152 /******************************************************************************
153  * Converts a hex representation of a DWORD into a DWORD.
154  */
156 {
157  WCHAR *p, *end;
158  int count = 0;
159 
160  while (*str == ' ' || *str == '\t') str++;
161  if (!*str) goto error;
162 
163  p = str;
164  while (iswxdigit(*p))
165  {
166  count++;
167  p++;
168  }
169  if (count > 8) goto error;
170 
171  end = p;
172  while (*p == ' ' || *p == '\t') p++;
173  if (*p && *p != ';') goto error;
174 
175  *end = 0;
176  *dw = wcstoul(str, &end, 16);
177  return TRUE;
178 
179 error:
180  return FALSE;
181 }
182 
183 /******************************************************************************
184  * Converts comma-separated hex data into a binary string and modifies
185  * the input parameter to skip the concatenating backslash, if found.
186  *
187  * Returns TRUE or FALSE to indicate whether parsing was successful.
188  */
190 {
191  size_t size;
192  BYTE *d;
193  WCHAR *s;
194 
196 
197  /* The worst case is 1 digit + 1 comma per byte */
198  size = ((lstrlenW(*str) + 1) / 2) + parser->data_size;
200 
201  s = *str;
202  d = (BYTE *)parser->data + parser->data_size;
203 
204  while (*s)
205  {
206  WCHAR *end;
207  unsigned long wc;
208 
209  wc = wcstoul(s, &end, 16);
210  if (wc > 0xff) return FALSE;
211 
212  if (s == end && wc == 0)
213  {
214  while (*end == ' ' || *end == '\t') end++;
215  if (*end == '\\')
216  {
217  parser->backslash = TRUE;
218  *str = end + 1;
219  return TRUE;
220  }
221  else if (*end == ';')
222  return TRUE;
223  return FALSE;
224  }
225 
226  *d++ = wc;
227  parser->data_size++;
228 
229  if (*end && *end != ',')
230  {
231  while (*end == ' ' || *end == '\t') end++;
232  if (*end && *end != ';') return FALSE;
233  return TRUE;
234  }
235 
236  if (*end) end++;
237  s = end;
238  }
239 
240  return TRUE;
241 }
242 
243 /******************************************************************************
244  * Parses the data type of the registry value being imported and modifies
245  * the input parameter to skip the string representation of the data type.
246  *
247  * Returns TRUE or FALSE to indicate whether a data type was found.
248  */
250 {
251  struct data_type { const WCHAR *tag; int len; int type; int parse_type; };
252 
253  static const WCHAR quote[] = {'"'};
254  static const WCHAR hex[] = {'h','e','x',':'};
255  static const WCHAR dword[] = {'d','w','o','r','d',':'};
256  static const WCHAR hexp[] = {'h','e','x','('};
257 
258  static const struct data_type data_types[] = {
259  /* tag len type parse type */
260  { quote, 1, REG_SZ, REG_SZ },
261  { hex, 4, REG_BINARY, REG_BINARY },
262  { dword, 6, REG_DWORD, REG_DWORD },
263  { hexp, 4, -1, REG_BINARY }, /* REG_NONE, REG_EXPAND_SZ, REG_MULTI_SZ */
264  { NULL, 0, 0, 0 }
265  };
266 
267  const struct data_type *ptr;
268 
269  for (ptr = data_types; ptr->tag; ptr++)
270  {
271  if (wcsncmp(ptr->tag, *line, ptr->len))
272  continue;
273 
274  parser->parse_type = ptr->parse_type;
275  parser->data_type = ptr->parse_type;
276  *line += ptr->len;
277 
278  if (ptr->type == -1)
279  {
280  WCHAR *end;
281  DWORD val;
282 
283  if (!**line || towlower((*line)[1]) == 'x')
284  return FALSE;
285 
286  /* "hex(xx):" is special */
287  val = wcstoul(*line, &end, 16);
288  if (*end != ')' || *(end + 1) != ':' || (val == ~0u && errno == ERANGE))
289  return FALSE;
290 
291  parser->data_type = val;
292  *line = end + 2;
293  }
294  return TRUE;
295  }
296  return FALSE;
297 }
298 
299 /******************************************************************************
300  * Replaces escape sequences with their character equivalents and
301  * null-terminates the string on the first non-escaped double quote.
302  *
303  * Assigns a pointer to the remaining unparsed data in the line.
304  * Returns TRUE or FALSE to indicate whether a closing double quote was found.
305  */
306 static BOOL unescape_string(WCHAR *str, WCHAR **unparsed)
307 {
308  int str_idx = 0; /* current character under analysis */
309  int val_idx = 0; /* the last character of the unescaped string */
310  int len = lstrlenW(str);
311  BOOL ret;
312 
313  for (str_idx = 0; str_idx < len; str_idx++, val_idx++)
314  {
315  if (str[str_idx] == '\\')
316  {
317  str_idx++;
318  switch (str[str_idx])
319  {
320  case 'n':
321  str[val_idx] = '\n';
322  break;
323  case 'r':
324  str[val_idx] = '\r';
325  break;
326  case '0':
327  str[val_idx] = '\0';
328  break;
329  case '\\':
330  case '"':
331  str[val_idx] = str[str_idx];
332  break;
333  default:
334  if (!str[str_idx]) return FALSE;
336  str[val_idx] = str[str_idx];
337  break;
338  }
339  }
340  else if (str[str_idx] == '"')
341  break;
342  else
343  str[val_idx] = str[str_idx];
344  }
345 
346  ret = (str[str_idx] == '"');
347  *unparsed = str + str_idx + 1;
348  str[val_idx] = '\0';
349  return ret;
350 }
351 
352 static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
353 {
354  if (!key_name) return 0;
355 
356  *key_path = wcschr(key_name, '\\');
357  if (*key_path) (*key_path)++;
358 
359  return path_get_rootkey(key_name);
360 }
361 
362 static void close_key(struct parser *parser)
363 {
364  if (parser->hkey)
365  {
367  parser->key_name = NULL;
368 
370  parser->hkey = NULL;
371  }
372 }
373 
374 static LONG open_key(struct parser *parser, WCHAR *path)
375 {
376  HKEY key_class;
377  WCHAR *key_path;
378  LONG res;
379 
380  close_key(parser);
381 
382  /* Get the registry class */
383  if (!path || !(key_class = parse_key_name(path, &key_path)))
385 
386  res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
388 
389  if (res == ERROR_SUCCESS)
390  {
391  parser->key_name = heap_xalloc((lstrlenW(path) + 1) * sizeof(WCHAR));
393  }
394  else
395  parser->hkey = NULL;
396 
397  return res;
398 }
399 
400 static void free_parser_data(struct parser *parser)
401 {
404 
405  parser->data = NULL;
406  parser->data_size = 0;
407 }
408 
410 {
412  parser->data_type == REG_SZ)
413  {
414  if (parser->is_unicode)
415  {
416  WCHAR *data = parser->data;
417  DWORD len = parser->data_size / sizeof(WCHAR);
418 
419  if (data[len - 1] != 0)
420  {
421  data[len] = 0;
422  parser->data_size += sizeof(WCHAR);
423  }
424  }
425  else
426  {
427  BYTE *data = parser->data;
428 
429  if (data[parser->data_size - 1] != 0)
430  {
431  data[parser->data_size] = 0;
432  parser->data_size++;
433  }
434 
436  parser->data_size *= sizeof(WCHAR);
437  heap_free(data);
438  }
439  }
440 }
441 
448 };
449 
451 {
452  static const WCHAR header_31[] = {'R','E','G','E','D','I','T',0};
453  static const WCHAR header_40[] = {'R','E','G','E','D','I','T','4',0};
454  static const WCHAR header_50[] = {'W','i','n','d','o','w','s',' ',
455  'R','e','g','i','s','t','r','y',' ','E','d','i','t','o','r',' ',
456  'V','e','r','s','i','o','n',' ','5','.','0','0',0};
457 
458  while (*s == ' ' || *s == '\t') s++;
459 
460  if (!lstrcmpW(s, header_31))
461  return REG_VERSION_31;
462 
463  if (!lstrcmpW(s, header_40))
464  return REG_VERSION_40;
465 
466  if (!lstrcmpW(s, header_50))
467  return REG_VERSION_50;
468 
469  /* The Windows version accepts registry file headers beginning with "REGEDIT" and ending
470  * with other characters, as long as "REGEDIT" appears at the start of the line. For example,
471  * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all treated as valid file headers.
472  * In all such cases, however, the contents of the registry file are not imported.
473  */
474  if (!wcsncmp(s, header_31, 7)) /* "REGEDIT" without NUL */
475  return REG_VERSION_FUZZY;
476 
477  return REG_VERSION_INVALID;
478 }
479 
480 /* handler for parser HEADER state */
482 {
483  WCHAR *line, *header;
484 
485  if (!(line = get_line(parser->file)))
486  return NULL;
487 
488  if (!parser->is_unicode)
489  {
490  header = heap_xalloc((lstrlenW(line) + 3) * sizeof(WCHAR));
491  header[0] = parser->two_wchars[0];
492  header[1] = parser->two_wchars[1];
493  lstrcpyW(header + 2, line);
495  heap_free(header);
496  }
498 
499  switch (parser->reg_version)
500  {
501  case REG_VERSION_31:
503  break;
504  case REG_VERSION_40:
505  case REG_VERSION_50:
507  break;
508  default:
509  get_line(NULL); /* Reset static variables */
510  return NULL;
511  }
512 
513  return line;
514 }
515 
516 /* handler for parser PARSE_WIN31_LINE state */
518 {
519  WCHAR *line, *value;
520  static WCHAR hkcr[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T'};
521  unsigned int key_end = 0;
522 
523  if (!(line = get_line(parser->file)))
524  return NULL;
525 
526  if (wcsncmp(line, hkcr, ARRAY_SIZE(hkcr)))
527  return line;
528 
529  /* get key name */
530  while (line[key_end] && !iswspace(line[key_end])) key_end++;
531 
532  value = line + key_end;
533  while (*value == ' ' || *value == '\t') value++;
534 
535  if (*value == '=') value++;
536  if (*value == ' ') value++; /* at most one space is skipped */
537 
538  line[key_end] = 0;
539 
541  {
543  return line;
544  }
545 
548  parser->data = value;
549  parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
550 
552  return value;
553 }
554 
555 /* handler for parser LINE_START state */
557 {
558  WCHAR *line, *p;
559 
560  if (!(line = get_line(parser->file)))
561  return NULL;
562 
563  for (p = line; *p; p++)
564  {
565  switch (*p)
566  {
567  case '[':
569  return p + 1;
570  case '@':
572  return p;
573  case '"':
575  return p + 1;
576  case ' ':
577  case '\t':
578  break;
579  default:
580  return p;
581  }
582  }
583 
584  return p;
585 }
586 
587 /* handler for parser KEY_NAME state */
589 {
590  WCHAR *p = pos, *key_end;
591 
592  if (*p == ' ' || *p == '\t' || !(key_end = wcsrchr(p, ']')))
593  goto done;
594 
595  *key_end = 0;
596 
597  if (*p == '-')
598  {
600  return p + 1;
601  }
602  else if (open_key(parser, p) != ERROR_SUCCESS)
604 
605 done:
607  return p;
608 }
609 
610 /* handler for parser DELETE_KEY state */
612 {
613  WCHAR *p = pos;
614 
615  close_key(parser);
616 
617  if (*p == 'H' || *p == 'h')
618  {
619  HKEY root;
620  WCHAR *path;
621 
622  root = parse_key_name(p, &path);
623 
624  if (root && path && *path)
626  }
627 
629  return p;
630 }
631 
632 /* handler for parser DEFAULT_VALUE_NAME state */
634 {
637 
639  return pos + 1;
640 }
641 
642 /* handler for parser QUOTED_VALUE_NAME state */
644 {
645  WCHAR *val_name = pos, *p;
646 
649 
650  if (!unescape_string(val_name, &p))
651  goto invalid;
652 
653  /* copy the value name in case we need to parse multiple lines and the buffer is overwritten */
654  parser->value_name = heap_xalloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
655  lstrcpyW(parser->value_name, val_name);
656 
658  return p;
659 
660 invalid:
662  return val_name;
663 }
664 
665 /* handler for parser DATA_START state */
667 {
668  WCHAR *p = pos;
669  unsigned int len;
670 
671  while (*p == ' ' || *p == '\t') p++;
672  if (*p != '=') goto invalid;
673  p++;
674  while (*p == ' ' || *p == '\t') p++;
675 
676  /* trim trailing whitespace */
677  len = lstrlenW(p);
678  while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t')) len--;
679  p[len] = 0;
680 
681  if (*p == '-')
683  else
685  return p;
686 
687 invalid:
689  return p;
690 }
691 
692 /* handler for parser DELETE_VALUE state */
694 {
695  WCHAR *p = pos + 1;
696 
697  while (*p == ' ' || *p == '\t') p++;
698  if (*p && *p != ';') goto done;
699 
701 
702 done:
704  return p;
705 }
706 
707 /* handler for parser DATA_TYPE state */
709 {
710  WCHAR *line = pos;
711 
712  if (!parse_data_type(parser, &line))
713  {
715  return line;
716  }
717 
718  switch (parser->parse_type)
719  {
720  case REG_SZ:
722  break;
723  case REG_DWORD:
725  break;
726  case REG_BINARY: /* all hex data types, including undefined */
728  break;
729  default:
731  }
732 
733  return line;
734 }
735 
736 /* handler for parser STRING_DATA state */
738 {
739  WCHAR *line;
740 
741  parser->data = pos;
742 
743  if (!unescape_string(parser->data, &line))
744  goto invalid;
745 
746  while (*line == ' ' || *line == '\t') line++;
747  if (*line && *line != ';') goto invalid;
748 
749  parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
750 
752  return line;
753 
754 invalid:
757  return line;
758 }
759 
760 /* handler for parser DWORD_DATA state */
762 {
763  WCHAR *line = pos;
764 
765  parser->data = heap_xalloc(sizeof(DWORD));
766 
768  goto invalid;
769 
770  parser->data_size = sizeof(DWORD);
771 
773  return line;
774 
775 invalid:
778  return line;
779 }
780 
781 /* handler for parser HEX_DATA state */
783 {
784  WCHAR *line = pos;
785 
786  if (!*line)
787  goto set_value;
788 
790  goto invalid;
791 
792  if (parser->backslash)
793  {
795  return line;
796  }
797 
799 
800 set_value:
802  return line;
803 
804 invalid:
807  return line;
808 }
809 
810 /* handler for parser EOL_BACKSLASH state */
812 {
813  WCHAR *p = pos;
814 
815  while (*p == ' ' || *p == '\t') p++;
816  if (*p && *p != ';') goto invalid;
817 
819  return pos;
820 
821 invalid:
824  return p;
825 }
826 
827 /* handler for parser HEX_MULTILINE state */
829 {
830  WCHAR *line;
831 
832  if (!(line = get_line(parser->file)))
833  {
836  return pos;
837  }
838 
839  while (*line == ' ' || *line == '\t') line++;
840  if (!*line || *line == ';') return line;
841 
842  if (!iswxdigit(*line)) goto invalid;
843 
845  return line;
846 
847 invalid:
850  return line;
851 }
852 
853 /* handler for parser UNKNOWN_DATA state */
855 {
856  FIXME("Unknown registry data type [0x%x]\n", parser->data_type);
857 
859  return pos;
860 }
861 
862 /* handler for parser SET_VALUE state */
864 {
867 
869 
872  else
874 
875  return pos;
876 }
877 
878 #define REG_VAL_BUF_SIZE 4096
879 
880 static WCHAR *get_lineA(FILE *fp)
881 {
882  static WCHAR *lineW;
883  static size_t size;
884  static char *buf, *next;
885  char *line;
886 
887  heap_free(lineW);
888 
889  if (!fp) goto cleanup;
890 
891  if (!size)
892  {
894  buf = heap_xalloc(size);
895  *buf = 0;
896  next = buf;
897  }
898  line = next;
899 
900  while (next)
901  {
902  char *p = strpbrk(line, "\r\n");
903  if (!p)
904  {
905  size_t len, count;
906  len = strlen(next);
907  memmove(buf, next, len + 1);
908  if (size - len < 3)
909  {
910  size *= 2;
912  }
913  if (!(count = fread(buf + len, 1, size - len - 1, fp)))
914  {
915  next = NULL;
916  lineW = GetWideString(buf);
917  return lineW;
918  }
919  buf[len + count] = 0;
920  next = buf;
921  line = buf;
922  continue;
923  }
924  next = p + 1;
925  if (*p == '\r' && *(p + 1) == '\n') next++;
926  *p = 0;
927  lineW = GetWideString(line);
928  return lineW;
929  }
930 
931 cleanup:
932  lineW = NULL;
933  if (size) heap_free(buf);
934  size = 0;
935  return NULL;
936 }
937 
938 static WCHAR *get_lineW(FILE *fp)
939 {
940  static size_t size;
941  static WCHAR *buf, *next;
942  WCHAR *line;
943 
944  if (!fp) goto cleanup;
945 
946  if (!size)
947  {
949  buf = heap_xalloc(size * sizeof(WCHAR));
950  *buf = 0;
951  next = buf;
952  }
953  line = next;
954 
955  while (next)
956  {
957  static const WCHAR line_endings[] = {'\r','\n',0};
958  WCHAR *p = wcspbrk(line, line_endings);
959  if (!p)
960  {
961  size_t len, count;
962  len = lstrlenW(next);
963  memmove(buf, next, (len + 1) * sizeof(WCHAR));
964  if (size - len < 3)
965  {
966  size *= 2;
967  buf = heap_xrealloc(buf, size * sizeof(WCHAR));
968  }
969  if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
970  {
971  next = NULL;
972  return buf;
973  }
974  buf[len + count] = 0;
975  next = buf;
976  line = buf;
977  continue;
978  }
979  next = p + 1;
980  if (*p == '\r' && *(p + 1) == '\n') next++;
981  *p = 0;
982  return line;
983  }
984 
985 cleanup:
986  if (size) heap_free(buf);
987  size = 0;
988  return NULL;
989 }
990 
992 {
993  FILE *fp;
994  static const WCHAR rb_mode[] = {'r','b',0};
995  BYTE s[2];
996  struct parser parser;
997  WCHAR *pos;
998 
999  fp = _wfopen(filename, rb_mode);
1000  if (!fp)
1001  {
1003  return 1;
1004  }
1005 
1006  if (fread(s, sizeof(WCHAR), 1, fp) != 1)
1007  goto error;
1008 
1009  parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
1011 
1012  parser.file = fp;
1013  parser.two_wchars[0] = s[0];
1014  parser.two_wchars[1] = s[1];
1015  parser.reg_version = -1;
1016  parser.hkey = NULL;
1017  parser.key_name = NULL;
1019  parser.parse_type = 0;
1020  parser.data_type = 0;
1021  parser.data = NULL;
1022  parser.data_size = 0;
1024  parser.state = HEADER;
1025 
1026  pos = parser.two_wchars;
1027 
1028  /* parser main loop */
1029  while (pos)
1031 
1033  goto error;
1034 
1036  close_key(&parser);
1037 
1038  fclose(fp);
1039  return 0;
1040 
1041 error:
1042  fclose(fp);
1043  return 1;
1044 }
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 WCHAR * quoted_value_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:643
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static WCHAR * parse_win31_line_state(struct parser *parser, WCHAR *pos)
Definition: import.c:517
static const WCHAR invalid[]
Definition: assoc.c:39
WCHAR * value_name
Definition: import.c:93
char strA[12]
Definition: clipboard.c:2028
static WCHAR * eol_backslash_state(struct parser *parser, WCHAR *pos)
Definition: import.c:811
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static WCHAR * get_lineA(FILE *fp)
Definition: import.c:880
static WCHAR * set_value_state(struct parser *parser, WCHAR *pos)
Definition: import.c:863
static void close_key(struct parser *parser)
Definition: import.c:362
static WCHAR * GetWideStringN(const char *strA, int size, DWORD *len)
Definition: import.c:45
#define ERROR_SUCCESS
Definition: deptool.c:10
#define error(str)
Definition: mkdosfs.c:1605
BOOL is_unicode
Definition: import.c:89
reg_versions
Definition: import.c:442
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#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)
static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
Definition: import.c:352
#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
struct _root root
enum parser_state state
Definition: import.c:99
static WCHAR * header_state(struct parser *parser, WCHAR *pos)
Definition: import.c:481
WINE_DEFAULT_DEBUG_CHANNEL(reg)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:147
GLuint GLuint end
Definition: gl.h:1545
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:88
static WCHAR * GetWideString(const char *strA)
Definition: import.c:31
const char * filename
Definition: ioapi.h:135
static const char hex[16]
Definition: profile.c:123
#define lstrlenW
Definition: compat.h:498
#define DWORD
Definition: nt_native.h:44
BOOL backslash
Definition: import.c:98
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 void prepare_hex_string_data(struct parser *parser)
Definition: import.c:409
void * data
Definition: import.c:96
DWORD parse_type
Definition: import.c:94
while(1)
Definition: macro.lex.yy.c:740
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
_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
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
#define FIXME(fmt,...)
Definition: debug.h:111
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: import.c:145
static PVOID ptr
Definition: dispmode.c:27
#define quote
Definition: macro.lex.yy.c:531
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
const WCHAR * str
short int reg_version
Definition: import.c:90
smooth NULL
Definition: ftsmooth.c:416
static WCHAR * unknown_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:854
Definition: parser.c:48
HRESULT set_value(const struct table *table, UINT row, UINT column, LONGLONG val, CIMTYPE type)
Definition: table.c:219
GLuint GLfloat * val
Definition: glext.h:7180
static WCHAR * key_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:588
Definition: import.c:65
#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:4895
GLsizeiptr size
Definition: glext.h:5919
#define d
Definition: ke_i.h:81
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static WCHAR * line_start_state(struct parser *parser, WCHAR *pos)
Definition: import.c:556
unsigned long DWORD
Definition: ntddk_ex.h:95
static WCHAR * data_type_state(struct parser *parser, WCHAR *pos)
Definition: import.c:708
FILE * file
Definition: import.c:87
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)
#define iswspace(_c)
Definition: ctype.h:669
#define ERANGE
Definition: acclib.h:92
int ret
char line[200]
Definition: main.c:97
static WCHAR * delete_value_state(struct parser *parser, WCHAR *pos)
Definition: import.c:693
#define STRING_FILE_NOT_FOUND
Definition: resource.h:8
HKEY hkey
Definition: import.c:91
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
static WCHAR * get_lineW(FILE *fp)
Definition: import.c:938
static int state
Definition: maze.c:121
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
int reg_import(const WCHAR *filename)
Definition: import.c:991
void * heap_xrealloc(void *buf, size_t size)
Definition: reg.c:94
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define STRING_OPEN_KEY_FAILED
Definition: resource.h:59
static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
Definition: import.c:155
#define wcsrchr
Definition: compat.h:16
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned char BYTE
Definition: xxhash.c:193
static BOOL parse_data_type(struct parser *parser, WCHAR **line)
Definition: import.c:249
#define STRING_ESCAPE_SEQUENCE
Definition: resource.h:60
static WCHAR *(* get_line)(FILE *)
Definition: import.c:60
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
static BOOL unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: import.c:306
static unsigned __int64 next
Definition: rand_nt.c:6
static WCHAR * string_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:737
#define lstrcpyW
Definition: compat.h:497
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
parser_state
Definition: import.c:63
#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
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
static int reg
Definition: i386-dis.c:1275
#define MultiByteToWideChar
Definition: compat.h:110
static WCHAR * dword_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:761
WCHAR * key_name
Definition: import.c:92
HKEY path_get_rootkey(const WCHAR *path)
Definition: reg.c:210
Definition: import.c:85
DWORD data_type
Definition: import.c:95
static LONG open_key(struct parser *parser, WCHAR *path)
Definition: import.c:374
static WCHAR * delete_key_state(struct parser *parser, WCHAR *pos)
Definition: import.c:611
static WCHAR * data_start_state(struct parser *parser, WCHAR *pos)
Definition: import.c:666
GLuint res
Definition: glext.h:9613
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: import.c:123
static enum reg_versions parse_file_header(const WCHAR *s)
Definition: import.c:450
#define towlower(c)
Definition: wctype.h:97
char * cleanup(char *str)
Definition: wpickclick.c:99
void * heap_xalloc(size_t size)
Definition: reg.c:83
static WCHAR * hex_multiline_state(struct parser *parser, WCHAR *pos)
Definition: import.c:828
static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
Definition: import.c:189
static WCHAR * hex_data_state(struct parser *parser, WCHAR *pos)
Definition: import.c:782
GLfloat GLfloat p
Definition: glext.h:8902
static WCHAR * default_value_name_state(struct parser *parser, WCHAR *pos)
Definition: import.c:633
#define REG_VAL_BUF_SIZE
Definition: import.c:878
#define REG_DWORD
Definition: sdbapi.c:596
static void free_parser_data(struct parser *parser)
Definition: import.c:400
WCHAR *(* parser_state_func)(struct parser *parser, WCHAR *pos)
Definition: import.c:102
struct CFHEADER header
Definition: fdi.c:101
DWORD data_size
Definition: import.c:97
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define REG_SZ
Definition: layer.c:22
char * tag
Definition: main.c:59