ReactOS  0.4.12-dev-14-gd0c8636
reg.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Andrew Riedi
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 <stdlib.h>
22 #include <wine/unicode.h>
23 #include <wine/debug.h>
24 #include <wine/heap.h>
25 #include "reg.h"
26 
28 
29 static const WCHAR short_hklm[] = {'H','K','L','M',0};
30 static const WCHAR short_hkcu[] = {'H','K','C','U',0};
31 static const WCHAR short_hkcr[] = {'H','K','C','R',0};
32 static const WCHAR short_hku[] = {'H','K','U',0};
33 static const WCHAR short_hkcc[] = {'H','K','C','C',0};
34 static const WCHAR long_hklm[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0};
35 static const WCHAR long_hkcu[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0};
36 static const WCHAR long_hkcr[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0};
37 static const WCHAR long_hku[] = {'H','K','E','Y','_','U','S','E','R','S',0};
38 static const WCHAR long_hkcc[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0};
39 
40 static const struct
41 {
43  const WCHAR *short_name;
44  const WCHAR *long_name;
45 }
46 root_rels[] =
47 {
53 };
54 
55 static const WCHAR type_none[] = {'R','E','G','_','N','O','N','E',0};
56 static const WCHAR type_sz[] = {'R','E','G','_','S','Z',0};
57 static const WCHAR type_expand_sz[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
58 static const WCHAR type_binary[] = {'R','E','G','_','B','I','N','A','R','Y',0};
59 static const WCHAR type_dword[] = {'R','E','G','_','D','W','O','R','D',0};
60 static const WCHAR type_dword_le[] = {'R','E','G','_','D','W','O','R','D','_','L','I','T','T','L','E','_','E','N','D','I','A','N',0};
61 static const WCHAR type_dword_be[] = {'R','E','G','_','D','W','O','R','D','_','B','I','G','_','E','N','D','I','A','N',0};
62 static const WCHAR type_multi_sz[] = {'R','E','G','_','M','U','L','T','I','_','S','Z',0};
63 
64 static const struct
65 {
67  const WCHAR *name;
68 }
69 type_rels[] =
70 {
72  {REG_SZ, type_sz},
79 };
80 
81 static const WCHAR newlineW[] = {'\n',0};
82 
83 void *heap_xalloc(size_t size)
84 {
85  void *buf = heap_alloc(size);
86  if (!buf)
87  {
88  ERR("Out of memory!\n");
89  exit(1);
90  }
91  return buf;
92 }
93 
94 void *heap_xrealloc(void *buf, size_t size)
95 {
96  void *new_buf = heap_realloc(buf, size);
97 
98  if (!new_buf)
99  {
100  ERR("Out of memory!\n");
101  exit(1);
102  }
103 
104  return new_buf;
105 }
106 
107 void output_writeconsole(const WCHAR *str, DWORD wlen)
108 {
109  DWORD count, ret;
110 
111  ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
112  if (!ret)
113  {
114  DWORD len;
115  char *msgA;
116 
117  /* On Windows WriteConsoleW() fails if the output is redirected. So fall
118  * back to WriteFile(), assuming the console encoding is still the right
119  * one in that case.
120  */
121  len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
122  msgA = heap_xalloc(len);
123 
124  WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
125  WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
126  heap_free(msgA);
127  }
128 }
129 
130 static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
131 {
132  WCHAR *str;
133  DWORD len;
134 
137  fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
138  if (len == 0 && GetLastError() != NO_ERROR)
139  {
140  WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
141  return;
142  }
143  output_writeconsole(str, len);
144  LocalFree(str);
145 }
146 
147 void WINAPIV output_message(unsigned int id, ...)
148 {
149  WCHAR fmt[1024];
150  __ms_va_list va_args;
151 
152  if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, ARRAY_SIZE(fmt)))
153  {
154  WINE_FIXME("LoadString failed with %d\n", GetLastError());
155  return;
156  }
157  __ms_va_start(va_args, id);
158  output_formatstring(fmt, va_args);
159  __ms_va_end(va_args);
160 }
161 
162 static void WINAPIV output_string(const WCHAR *fmt, ...)
163 {
164  __ms_va_list va_args;
165 
166  __ms_va_start(va_args, fmt);
167  output_formatstring(fmt, va_args);
168  __ms_va_end(va_args);
169 }
170 
171 /* ask_confirm() adapted from programs/cmd/builtins.c */
172 BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
173 {
174  HMODULE hmod;
175  WCHAR Ybuffer[4];
176  WCHAR Nbuffer[4];
177  WCHAR defval[32];
178  WCHAR answer[MAX_PATH];
179  WCHAR *str;
180  DWORD count;
181 
182  hmod = GetModuleHandleW(NULL);
183  LoadStringW(hmod, STRING_YES, Ybuffer, ARRAY_SIZE(Ybuffer));
184  LoadStringW(hmod, STRING_NO, Nbuffer, ARRAY_SIZE(Nbuffer));
185  LoadStringW(hmod, STRING_DEFAULT_VALUE, defval, ARRAY_SIZE(defval));
186 
187  str = (reg_info && *reg_info) ? reg_info : defval;
188 
189  while (1)
190  {
191  output_message(msgid, str);
193  ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), answer, ARRAY_SIZE(answer), &count, NULL);
194  answer[0] = toupperW(answer[0]);
195  if (answer[0] == Ybuffer[0])
196  return TRUE;
197  if (answer[0] == Nbuffer[0])
198  return FALSE;
199  }
200 }
201 
202 static inline BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name)
203 {
204  DWORD length = strlenW(rootkey_name);
205 
206  return (!strncmpiW(input_path, rootkey_name, length) &&
207  (input_path[length] == 0 || input_path[length] == '\\'));
208 }
209 
211 {
212  DWORD i;
213 
214  for (i = 0; i < ARRAY_SIZE(root_rels); i++)
215  {
216  if (path_rootname_cmp(path, root_rels[i].short_name) ||
218  return root_rels[i].key;
219  }
220 
221  return NULL;
222 }
223 
224 static DWORD wchar_get_type(const WCHAR *type_name)
225 {
226  DWORD i;
227 
228  if (!type_name)
229  return REG_SZ;
230 
231  for (i = 0; i < ARRAY_SIZE(type_rels); i++)
232  {
233  if (!strcmpiW(type_rels[i].name, type_name))
234  return type_rels[i].type;
235  }
236 
237  return ~0u;
238 }
239 
240 /* hexchar_to_byte from programs/regedit/hexedit.c */
241 static inline BYTE hexchar_to_byte(WCHAR ch)
242 {
243  if (ch >= '0' && ch <= '9')
244  return ch - '0';
245  else if (ch >= 'a' && ch <= 'f')
246  return ch - 'a' + 10;
247  else if (ch >= 'A' && ch <= 'F')
248  return ch - 'A' + 10;
249  else
250  return -1;
251 }
252 
254 {
255  static const WCHAR empty;
256  LPBYTE out_data = NULL;
257  *reg_count = 0;
258 
259  if (!data) data = &empty;
260 
261  switch (reg_type)
262  {
263  case REG_NONE:
264  case REG_SZ:
265  case REG_EXPAND_SZ:
266  {
267  *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
268  out_data = heap_xalloc(*reg_count);
269  lstrcpyW((LPWSTR)out_data,data);
270  break;
271  }
272  case REG_DWORD:
273  /* case REG_DWORD_LITTLE_ENDIAN: */
274  case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */
275  {
276  LPWSTR rest;
277  unsigned long val;
278  val = wcstoul(data, &rest, (tolowerW(data[1]) == 'x') ? 16 : 10);
279  if (*rest || data[0] == '-' || (val == ~0u && errno == ERANGE)) {
281  break;
282  }
283  *reg_count = sizeof(DWORD);
284  out_data = heap_xalloc(*reg_count);
285  ((LPDWORD)out_data)[0] = val;
286  break;
287  }
288  case REG_BINARY:
289  {
290  BYTE hex0, hex1;
291  int i = 0, destByteIndex = 0, datalen = lstrlenW(data);
292  *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE);
293  out_data = heap_xalloc(*reg_count);
294  if(datalen % 2)
295  {
296  hex1 = hexchar_to_byte(data[i++]);
297  if(hex1 == 0xFF)
298  goto no_hex_data;
299  out_data[destByteIndex++] = hex1;
300  }
301  for(;i + 1 < datalen;i += 2)
302  {
303  hex0 = hexchar_to_byte(data[i]);
304  hex1 = hexchar_to_byte(data[i + 1]);
305  if(hex0 == 0xFF || hex1 == 0xFF)
306  goto no_hex_data;
307  out_data[destByteIndex++] = (hex0 << 4) | hex1;
308  }
309  break;
310  no_hex_data:
311  /* cleanup, print error */
312  heap_free(out_data);
314  out_data = NULL;
315  break;
316  }
317  case REG_MULTI_SZ:
318  {
319  int i, destindex, len = strlenW(data);
320  WCHAR *buffer = heap_xalloc((len + 2) * sizeof(WCHAR));
321 
322  for (i = 0, destindex = 0; i < len; i++, destindex++)
323  {
324  if (!separator && data[i] == '\\' && data[i + 1] == '0')
325  {
326  buffer[destindex] = 0;
327  i++;
328  }
329  else if (data[i] == separator)
330  buffer[destindex] = 0;
331  else
332  buffer[destindex] = data[i];
333 
334  if (destindex && !buffer[destindex - 1] && (!buffer[destindex] || destindex == 1))
335  {
336  heap_free(buffer);
338  return NULL;
339  }
340  }
341  buffer[destindex] = 0;
342  if (destindex && buffer[destindex - 1])
343  buffer[++destindex] = 0;
344  *reg_count = (destindex + 1) * sizeof(WCHAR);
345  return (BYTE *)buffer;
346  }
347  default:
348  output_message(STRING_UNHANDLED_TYPE, reg_type, data);
349  }
350 
351  return out_data;
352 }
353 
354 static BOOL sane_path(const WCHAR *key)
355 {
356  unsigned int i = strlenW(key);
357 
358  if (i < 3 || (key[i - 1] == '\\' && key[i - 2] == '\\'))
359  {
361  return FALSE;
362  }
363 
364  if (key[0] == '\\' && key[1] == '\\' && key[2] != '\\')
365  {
367  return FALSE;
368  }
369 
370  return TRUE;
371 }
372 
373 static int reg_add(HKEY root, WCHAR *path, WCHAR *value_name, BOOL value_empty,
374  WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
375 {
376  HKEY key;
377 
378  if (RegCreateKeyW(root, path, &key) != ERROR_SUCCESS)
379  {
381  return 1;
382  }
383 
384  if (value_name || value_empty || data)
385  {
386  DWORD reg_type;
387  DWORD reg_count = 0;
388  BYTE* reg_data = NULL;
389 
390  if (!force)
391  {
392  if (RegQueryValueExW(key, value_name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
393  {
394  if (!ask_confirm(STRING_OVERWRITE_VALUE, value_name))
395  {
396  RegCloseKey(key);
398  return 0;
399  }
400  }
401  }
402 
403  reg_type = wchar_get_type(type);
404  if (reg_type == ~0u)
405  {
406  RegCloseKey(key);
408  return 1;
409  }
410  if ((reg_type == REG_DWORD || reg_type == REG_DWORD_BIG_ENDIAN) && !data)
411  {
412  RegCloseKey(key);
414  return 1;
415  }
416 
417  if (!(reg_data = get_regdata(data, reg_type, separator, &reg_count)))
418  {
419  RegCloseKey(key);
420  return 1;
421  }
422 
423  RegSetValueExW(key, value_name, 0, reg_type, reg_data, reg_count);
424  heap_free(reg_data);
425  }
426 
427  RegCloseKey(key);
429 
430  return 0;
431 }
432 
434  BOOL value_empty, BOOL value_all, BOOL force)
435 {
436  HKEY key;
437 
438  if (!force)
439  {
440  BOOL ret;
441 
442  if (value_name || value_empty)
443  ret = ask_confirm(STRING_DELETE_VALUE, value_name);
444  else if (value_all)
445  ret = ask_confirm(STRING_DELETE_VALUEALL, key_name);
446  else
447  ret = ask_confirm(STRING_DELETE_SUBKEY, key_name);
448 
449  if (!ret)
450  {
452  return 0;
453  }
454  }
455 
456  /* Delete subtree only if no /v* option is given */
457  if (!value_name && !value_empty && !value_all)
458  {
459  if (RegDeleteTreeW(root, path) != ERROR_SUCCESS)
460  {
462  return 1;
463  }
465  return 0;
466  }
467 
468  if (RegOpenKeyW(root, path, &key) != ERROR_SUCCESS)
469  {
471  return 1;
472  }
473 
474  if (value_all)
475  {
476  DWORD max_value_len = 256, value_len;
477  WCHAR *value_name;
478  LONG rc;
479 
480  value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
481 
482  while (1)
483  {
484  value_len = max_value_len;
485  rc = RegEnumValueW(key, 0, value_name, &value_len, NULL, NULL, NULL, NULL);
486  if (rc == ERROR_SUCCESS)
487  {
488  rc = RegDeleteValueW(key, value_name);
489  if (rc != ERROR_SUCCESS)
490  {
491  heap_free(value_name);
492  RegCloseKey(key);
494  return 1;
495  }
496  }
497  else if (rc == ERROR_MORE_DATA)
498  {
499  max_value_len *= 2;
500  value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
501  }
502  else break;
503  }
504  heap_free(value_name);
505  }
506  else if (value_name || value_empty)
507  {
508  if (RegDeleteValueW(key, value_empty ? NULL : value_name) != ERROR_SUCCESS)
509  {
510  RegCloseKey(key);
512  return 1;
513  }
514  }
515 
516  RegCloseKey(key);
518  return 0;
519 }
520 
521 static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
522 {
523  WCHAR *buffer = NULL;
524  int i;
525 
526  switch (type)
527  {
528  case REG_SZ:
529  case REG_EXPAND_SZ:
530  buffer = heap_xalloc(size_bytes);
531  strcpyW(buffer, (WCHAR *)src);
532  break;
533  case REG_NONE:
534  case REG_BINARY:
535  {
536  WCHAR *ptr;
537  static const WCHAR fmt[] = {'%','0','2','X',0};
538 
539  buffer = heap_xalloc((size_bytes * 2 + 1) * sizeof(WCHAR));
540  ptr = buffer;
541  for (i = 0; i < size_bytes; i++)
542  ptr += sprintfW(ptr, fmt, src[i]);
543  break;
544  }
545  case REG_DWORD:
546  /* case REG_DWORD_LITTLE_ENDIAN: */
548  {
549  const int zero_x_dword = 10;
550  static const WCHAR fmt[] = {'0','x','%','x',0};
551 
552  buffer = heap_xalloc((zero_x_dword + 1) * sizeof(WCHAR));
553  sprintfW(buffer, fmt, *(DWORD *)src);
554  break;
555  }
556  case REG_MULTI_SZ:
557  {
558  const int two_wchars = 2 * sizeof(WCHAR);
559  DWORD tmp_size;
560  const WCHAR *tmp = (const WCHAR *)src;
561  int len, destindex;
562 
563  if (size_bytes <= two_wchars)
564  {
565  buffer = heap_xalloc(sizeof(WCHAR));
566  *buffer = 0;
567  return buffer;
568  }
569 
570  tmp_size = size_bytes - two_wchars; /* exclude both null terminators */
571  buffer = heap_xalloc(tmp_size * 2 + sizeof(WCHAR));
572  len = tmp_size / sizeof(WCHAR);
573 
574  for (i = 0, destindex = 0; i < len; i++, destindex++)
575  {
576  if (tmp[i])
577  buffer[destindex] = tmp[i];
578  else
579  {
580  buffer[destindex++] = '\\';
581  buffer[destindex] = '0';
582  }
583  }
584  buffer[destindex] = 0;
585  break;
586  }
587  }
588  return buffer;
589 }
590 
592 {
594 
595  for (i = 0; i < array_size; i++)
596  {
597  if (type == type_rels[i].type)
598  return type_rels[i].name;
599  }
600  return NULL;
601 }
602 
604 {
605  static const WCHAR fmt[] = {' ',' ',' ',' ','%','1',0};
606  WCHAR defval[32];
607  WCHAR *reg_data;
608 
609  if (value_name && value_name[0])
610  output_string(fmt, value_name);
611  else
612  {
614  output_string(fmt, defval);
615  }
616  output_string(fmt, reg_type_to_wchar(type));
617 
618  if (data)
619  {
620  reg_data = reg_data_to_wchar(type, data, data_size);
621  output_string(fmt, reg_data);
622  heap_free(reg_data);
623  }
624  else
625  {
627  output_string(fmt, defval);
628  }
630 }
631 
632 WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
633 {
634  WCHAR *subkey_path;
635  static const WCHAR fmt[] = {'%','s','\\','%','s',0};
636 
637  subkey_path = heap_xalloc((path_len + subkey_len + 2) * sizeof(WCHAR));
638  sprintfW(subkey_path, fmt, path, subkey_name);
639 
640  return subkey_path;
641 }
642 
643 static unsigned int num_values_found = 0;
644 
645 static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
646 {
647  LONG rc;
648  DWORD max_data_bytes = 2048, data_size;
649  DWORD subkey_len;
650  DWORD type, path_len, i;
651  BYTE *data;
652  WCHAR fmt[] = {'%','1','\n',0};
653  WCHAR *subkey_name, *subkey_path;
654  HKEY subkey;
655 
656  data = heap_xalloc(max_data_bytes);
657 
658  for (;;)
659  {
660  data_size = max_data_bytes;
661  rc = RegQueryValueExW(key, value_name, NULL, &type, data, &data_size);
662  if (rc == ERROR_MORE_DATA)
663  {
664  max_data_bytes = data_size;
665  data = heap_xrealloc(data, max_data_bytes);
666  }
667  else break;
668  }
669 
670  if (rc == ERROR_SUCCESS)
671  {
672  output_string(fmt, path);
673  output_value(value_name, type, data, data_size);
676  }
677 
678  heap_free(data);
679 
680  if (!recurse)
681  {
682  if (rc == ERROR_FILE_NOT_FOUND)
683  {
684  if (value_name && *value_name)
685  {
687  return 1;
688  }
689  output_string(fmt, path);
691  }
692  return 0;
693  }
694 
695  subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
696 
697  path_len = strlenW(path);
698 
699  i = 0;
700  for (;;)
701  {
702  subkey_len = MAX_SUBKEY_LEN;
703  rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
704  if (rc == ERROR_SUCCESS)
705  {
706  subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
707  if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
708  {
709  query_value(subkey, value_name, subkey_path, recurse);
710  RegCloseKey(subkey);
711  }
712  heap_free(subkey_path);
713  i++;
714  }
715  else break;
716  }
717 
718  heap_free(subkey_name);
719  return 0;
720 }
721 
722 static int query_all(HKEY key, WCHAR *path, BOOL recurse)
723 {
724  LONG rc;
725  DWORD max_value_len = 256, value_len;
726  DWORD max_data_bytes = 2048, data_size;
727  DWORD subkey_len;
728  DWORD i, type, path_len;
729  WCHAR fmt[] = {'%','1','\n',0};
730  WCHAR fmt_path[] = {'%','1','\\','%','2','\n',0};
731  WCHAR *value_name, *subkey_name, *subkey_path;
732  BYTE *data;
733  HKEY subkey;
734 
735  output_string(fmt, path);
736 
737  value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
738  data = heap_xalloc(max_data_bytes);
739 
740  i = 0;
741  for (;;)
742  {
743  value_len = max_value_len;
744  data_size = max_data_bytes;
745  rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
746  if (rc == ERROR_SUCCESS)
747  {
748  output_value(value_name, type, data, data_size);
749  i++;
750  }
751  else if (rc == ERROR_MORE_DATA)
752  {
753  if (data_size > max_data_bytes)
754  {
755  max_data_bytes = data_size;
756  data = heap_xrealloc(data, max_data_bytes);
757  }
758  else
759  {
760  max_value_len *= 2;
761  value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
762  }
763  }
764  else break;
765  }
766 
767  heap_free(data);
768  heap_free(value_name);
769 
770  if (i || recurse)
772 
773  subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
774 
775  path_len = strlenW(path);
776 
777  i = 0;
778  for (;;)
779  {
780  subkey_len = MAX_SUBKEY_LEN;
781  rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
782  if (rc == ERROR_SUCCESS)
783  {
784  if (recurse)
785  {
786  subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
787  if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
788  {
789  query_all(subkey, subkey_path, recurse);
790  RegCloseKey(subkey);
791  }
792  heap_free(subkey_path);
793  }
794  else output_string(fmt_path, path, subkey_name);
795  i++;
796  }
797  else break;
798  }
799 
800  heap_free(subkey_name);
801 
802  if (i && !recurse)
804 
805  return 0;
806 }
807 
809  BOOL value_empty, BOOL recurse)
810 {
811  HKEY key;
812  int ret;
813 
814  if (RegOpenKeyExW(root, path, 0, KEY_READ, &key) != ERROR_SUCCESS)
815  {
817  return 1;
818  }
819 
821 
822  if (value_name || value_empty)
823  {
824  ret = query_value(key, value_name, key_name, recurse);
825  if (recurse)
827  }
828  else
829  ret = query_all(key, key_name, recurse);
830 
831  RegCloseKey(key);
832 
833  return ret;
834 }
835 
837 {
839  WCHAR *long_key;
840  WCHAR fmt[] = {'%','s','\\','%','s',0};
841 
842  for (i = 0; i < array_size; i++)
843  {
844  if (root == root_rels[i].key)
845  break;
846  }
847 
849 
850  if (!path)
851  {
852  long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
853  strcpyW(long_key, root_rels[i].long_name);
854  return long_key;
855  }
856 
857  len += strlenW(path) + 1; /* add one for the backslash */
858  long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
859  sprintfW(long_key, fmt, root_rels[i].long_name, path);
860  return long_key;
861 }
862 
864 {
865  if (!sane_path(key))
866  return FALSE;
867 
868  *path = strchrW(key, '\\');
869  if (*path) (*path)++;
870 
871  *root = path_get_rootkey(key);
872  if (!*root)
873  {
874  if (*path) *(*path - 1) = 0;
876  return FALSE;
877  }
878 
879  *long_key = get_long_key(*root, *path);
880 
881  return TRUE;
882 }
883 
884 static BOOL is_switch(const WCHAR *s, const WCHAR c)
885 {
886  if (strlenW(s) > 2)
887  return FALSE;
888 
889  if ((s[0] == '/' || s[0] == '-') && (s[1] == c || s[1] == toupperW(c)))
890  return TRUE;
891 
892  return FALSE;
893 }
894 
895 static BOOL is_help_switch(const WCHAR *s)
896 {
897  if (is_switch(s, '?') || is_switch(s, 'h'))
898  return TRUE;
899 
900  return FALSE;
901 }
902 
910 };
911 
912 static enum operations get_operation(const WCHAR *str, int *op_help)
913 {
914  struct op_info { const WCHAR *op; int id; int help_id; };
915 
916  static const WCHAR add[] = {'a','d','d',0};
917  static const WCHAR delete[] = {'d','e','l','e','t','e',0};
918  static const WCHAR import[] = {'i','m','p','o','r','t',0};
919  static const WCHAR export[] = {'e','x','p','o','r','t',0};
920  static const WCHAR query[] = {'q','u','e','r','y',0};
921 
922  static const struct op_info op_array[] =
923  {
925  { delete, REG_DELETE, STRING_DELETE_USAGE },
926  { import, REG_IMPORT, STRING_IMPORT_USAGE },
927  { export, REG_EXPORT, STRING_EXPORT_USAGE },
929  { NULL, -1, 0 }
930  };
931 
932  const struct op_info *ptr;
933 
934  for (ptr = op_array; ptr->op; ptr++)
935  {
936  if (!lstrcmpiW(str, ptr->op))
937  {
938  *op_help = ptr->help_id;
939  return ptr->id;
940  }
941  }
942 
943  return REG_INVALID;
944 }
945 
946 int wmain(int argc, WCHAR *argvW[])
947 {
948  int i, op, op_help, ret;
949  BOOL show_op_help = FALSE;
950  static const WCHAR switchVAW[] = {'v','a',0};
951  static const WCHAR switchVEW[] = {'v','e',0};
952  WCHAR *key_name, *path, *value_name = NULL, *type = NULL, *data = NULL, separator = '\0';
953  BOOL value_empty = FALSE, value_all = FALSE, recurse = FALSE, force = FALSE;
954  HKEY root;
955 
956  if (argc == 1)
957  {
960  return 1;
961  }
962 
963  if (is_help_switch(argvW[1]))
964  {
966  return 0;
967  }
968 
969  op = get_operation(argvW[1], &op_help);
970 
971  if (op == REG_INVALID)
972  {
975  return 1;
976  }
977 
978  if (argc > 2)
979  show_op_help = is_help_switch(argvW[2]);
980 
981  if (argc == 2 || ((show_op_help || op == REG_IMPORT) && argc > 3))
982  {
985  return 1;
986  }
987  else if (show_op_help)
988  {
989  output_message(op_help);
990  return 0;
991  }
992 
993  if (op == REG_IMPORT)
994  return reg_import(argvW[2]);
995 
996  if (op == REG_EXPORT)
997  return reg_export(argc, argvW);
998 
999  if (!parse_registry_key(argvW[2], &root, &path, &key_name))
1000  return 1;
1001 
1002  for (i = 3; i < argc; i++)
1003  {
1004  if (argvW[i][0] == '/' || argvW[i][0] == '-')
1005  {
1006  WCHAR *ptr = &argvW[i][1];
1007 
1008  if (!lstrcmpiW(ptr, switchVEW))
1009  {
1010  value_empty = TRUE;
1011  continue;
1012  }
1013  else if (!lstrcmpiW(ptr, switchVAW))
1014  {
1015  value_all = TRUE;
1016  continue;
1017  }
1018  else if (!ptr[0] || ptr[1])
1019  {
1021  return 1;
1022  }
1023 
1024  switch(tolowerW(argvW[i][1]))
1025  {
1026  case 'v':
1027  if (value_name || !(value_name = argvW[++i]))
1028  {
1030  return 1;
1031  }
1032  break;
1033  case 't':
1034  if (type || !(type = argvW[++i]))
1035  {
1037  return 1;
1038  }
1039  break;
1040  case 'd':
1041  if (data || !(data = argvW[++i]))
1042  {
1044  return 1;
1045  }
1046  break;
1047  case 's':
1048  if (op == REG_QUERY)
1049  {
1050  recurse = TRUE;
1051  break;
1052  }
1053 
1054  ptr = argvW[++i];
1055  if (!ptr || strlenW(ptr) != 1)
1056  {
1058  return 1;
1059  }
1060  separator = ptr[0];
1061  break;
1062  case 'f':
1063  force = TRUE;
1064  break;
1065  default:
1067  return 1;
1068  }
1069  }
1070  }
1071 
1072  if ((value_name && value_empty) || (value_name && value_all) || (value_empty && value_all))
1073  {
1075  return 1;
1076  }
1077 
1078  if (op == REG_ADD)
1079  ret = reg_add(root, path, value_name, value_empty, type, separator, data, force);
1080  else if (op == REG_DELETE)
1081  ret = reg_delete(root, path, key_name, value_name, value_empty, value_all, force);
1082  else
1083  ret = reg_query(root, path, key_name, value_name, value_empty, recurse);
1084  return ret;
1085 }
#define HKEY_USERS
Definition: winreg.h:13
#define STRING_VALUE_NOT_SET
Definition: resource.h:56
int add
Definition: i386-dis.c:3122
static const WCHAR newlineW[]
Definition: reg.c:81
WCHAR * value_name
Definition: import.c:94
static int argc
Definition: ServiceArgs.c:12
static const struct @3 type_rels[]
#define STRING_OVERWRITE_VALUE
Definition: resource.h:39
#define STRING_USAGE
Definition: resource.h:26
static const char __ms_va_list
Definition: printf.c:70
static int reg_delete(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL value_all, BOOL force)
Definition: reg.c:433
#define TRUE
Definition: types.h:120
Definition: reg.c:908
static const WCHAR long_hklm[]
Definition: reg.c:34
#define MAX_SUBKEY_LEN
Definition: reg.h:24
static const WCHAR separator[]
Definition: asmname.c:63
#define STRING_MISSING_HEXDATA
Definition: resource.h:37
static void WINAPIV output_string(const WCHAR *fmt,...)
Definition: reg.c:162
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
int wmain(int argc, WCHAR *argvW[])
Definition: reg.c:946
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:101
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_BINARY
Definition: nt_native.h:1496
static const WCHAR long_hku[]
Definition: reg.c:37
#define STRING_NO
Definition: resource.h:42
#define KEY_READ
Definition: nt_native.h:1023
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLsizei const GLchar ** path
Definition: glext.h:7234
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define STRING_DELETE_VALUE
Definition: resource.h:45
static DWORD wchar_get_type(const WCHAR *type_name)
Definition: reg.c:224
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1449
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:402
struct _root root
static int reg_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse)
Definition: reg.c:808
#define STRING_QUERY_USAGE
Definition: resource.h:29
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static const WCHAR type_sz[]
Definition: reg.c:56
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
GLuint buffer
Definition: glext.h:5915
static WCHAR * get_long_key(HKEY root, WCHAR *path)
Definition: reg.c:836
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:147
static BOOL is_help_switch(const WCHAR *s)
Definition: reg.c:895
#define STRING_INVALID_STRING
Definition: resource.h:48
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)
#define STRING_VALUEALL_FAILED
Definition: resource.h:49
WCHAR two_wchars[2]
Definition: import.c:89
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key)
Definition: reg.c:863
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define WCHAR
Definition: msvc.h:43
#define NO_ERROR
Definition: dderror.h:5
#define lstrlenW
Definition: compat.h:407
static BYTE hexchar_to_byte(WCHAR ch)
Definition: reg.c:241
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
#define STRING_DELETE_VALUEALL
Definition: resource.h:46
static const WCHAR type_none[]
Definition: reg.c:55
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static const WCHAR short_hklm[]
Definition: reg.c:29
static const WCHAR long_hkcr[]
Definition: reg.c:36
static UINT array_size
Definition: msctf.c:69
static const WCHAR empty[]
Definition: task.c:29
#define STRING_CANNOT_FIND
Definition: resource.h:34
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static const WCHAR type_dword_be[]
Definition: reg.c:61
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
GLenum GLclampf GLint i
Definition: glfuncs.h:14
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
UINT op
Definition: effect.c:223
long LONG
Definition: pedump.c:60
#define STRING_EXPORT_USAGE
Definition: resource.h:61
static BOOL is_switch(const WCHAR *s, const WCHAR c)
Definition: reg.c:884
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define STRING_SUCCESS
Definition: resource.h:30
#define STRING_INVALID_CMDLINE
Definition: resource.h:32
static PVOID ptr
Definition: dispmode.c:27
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
static enum operations get_operation(const WCHAR *str, int *op_help)
Definition: reg.c:912
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
#define STRING_INVALID_KEY
Definition: resource.h:31
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2453
static const WCHAR short_hku[]
Definition: reg.c:32
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:2867
#define STRING_FUNC_HELP
Definition: resource.h:55
static int reg_add(HKEY root, WCHAR *path, WCHAR *value_name, BOOL value_empty, WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
Definition: reg.c:373
smooth NULL
Definition: ftsmooth.c:416
#define STRING_INVALID_SYSTEM_KEY
Definition: resource.h:62
#define STRING_MISSING_INTEGER
Definition: resource.h:36
#define STRING_YES
Definition: resource.h:41
#define STRING_IMPORT_USAGE
Definition: resource.h:57
#define STD_INPUT_HANDLE
Definition: winbase.h:264
operations
Definition: reg.c:903
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const WCHAR long_hkcu[]
Definition: reg.c:35
GLuint GLfloat * val
Definition: glext.h:7180
WINE_UNICODE_INLINE WCHAR toupperW(WCHAR ch)
Definition: unicode.h:141
static const WCHAR long_hkcc[]
Definition: reg.c:38
static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
Definition: reg.c:130
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
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:4917
WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: reg.c:632
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleW(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1176
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
static const WCHAR type_multi_sz[]
Definition: reg.c:62
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
static const WCHAR short_hkcc[]
Definition: reg.c:33
static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DWORD *reg_count)
Definition: reg.c:253
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define STRING_INVALID_SYNTAX
Definition: resource.h:52
#define MAX_PATH
Definition: compat.h:26
const GLubyte * c
Definition: glext.h:8905
#define STRING_REG_HELP
Definition: resource.h:54
WINE_UNICODE_INLINE WCHAR tolowerW(WCHAR ch)
Definition: unicode.h:135
static BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name)
Definition: reg.c:202
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR type_binary[]
Definition: reg.c:58
#define SetLastError(x)
Definition: compat.h:409
const WCHAR * short_name
Definition: reg.c:43
static WCHAR * reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
Definition: reg.c:521
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ERANGE
Definition: acclib.h:92
static const WCHAR short_hkcu[]
Definition: reg.c:30
int ret
#define REG_DWORD_LITTLE_ENDIAN
Definition: nt_native.h:1498
WINE_DEFAULT_DEBUG_CHANNEL(reg)
#define LPDWORD
Definition: nt_native.h:46
static const WCHAR type_dword[]
Definition: reg.c:59
#define STRING_DELETE_SUBKEY
Definition: resource.h:47
HKEY key
Definition: reg.c:42
#define STRING_MATCHES_FOUND
Definition: resource.h:51
GLenum GLsizei len
Definition: glext.h:6722
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1202
GLdouble s
Definition: gl.h:2039
const WCHAR * long_name
Definition: reg.c:44
int reg_import(const WCHAR *filename)
Definition: import.c:995
static BOOL sane_path(const WCHAR *key)
Definition: reg.c:354
void * heap_xrealloc(void *buf, size_t size)
Definition: reg.c:94
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD data_size)
Definition: reg.c:603
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define WINAPIV
Definition: sdbpapi.h:64
unsigned char BYTE
Definition: ntddk_ex.h:96
#define REG_DWORD_BIG_ENDIAN
Definition: nt_native.h:1499
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
#define strcmpiW(s1, s2)
Definition: unicode.h:39
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1755
#define ERR(fmt,...)
Definition: debug.h:109
#define STRING_UNHANDLED_TYPE
Definition: resource.h:38
static const WCHAR type_expand_sz[]
Definition: reg.c:57
#define STRING_DEFAULT_VALUE
Definition: resource.h:44
BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
Definition: reg.c:172
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
static DWORD path_len
Definition: batch.c:31
#define lstrcpyW
Definition: compat.h:406
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
#define ARRAY_SIZE(a)
Definition: main.h:24
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define STRING_DELETE_USAGE
Definition: resource.h:28
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
static const WCHAR short_hkcr[]
Definition: reg.c:31
Definition: services.c:325
#define sprintfW
Definition: unicode.h:58
#define __ms_va_end(list)
Definition: windef.h:448
static int reg
Definition: i386-dis.c:1275
HKEY path_get_rootkey(const WCHAR *path)
Definition: reg.c:210
#define STRING_UNSUPPORTED_TYPE
Definition: resource.h:35
#define STRING_YESNO
Definition: resource.h:40
#define __ms_va_start(list, arg)
Definition: windef.h:447
Definition: name.c:36
static unsigned int num_values_found
Definition: reg.c:643
#define STRING_NO_REMOTE
Definition: resource.h:33
GLenum GLuint id
Definition: glext.h:5579
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
int reg_export(int argc, WCHAR *argv[])
Definition: export.c:373
void * heap_xalloc(size_t size)
Definition: reg.c:83
Definition: reg.c:904
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:2541
const WCHAR * name
Definition: reg.c:67
#define STRING_INVALID_OPTION
Definition: resource.h:53
#define REG_NONE
Definition: nt_native.h:1492
static const WCHAR type_dword_le[]
Definition: reg.c:60
void exit(int exitcode)
Definition: _exit.c:33
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static int query_all(HKEY key, WCHAR *path, BOOL recurse)
Definition: reg.c:722
void output_writeconsole(const WCHAR *str, DWORD wlen)
Definition: reg.c:107
static ULONG ULONG *static const UNICODE_STRING void DWORD
Definition: reg.c:135
#define STRING_ADD_USAGE
Definition: resource.h:27
static const struct @2 root_rels[]
#define REG_DWORD
Definition: sdbapi.c:539
type_t * reg_type(type_t *type, const char *name, struct namespace *namespace, int t)
Definition: parser.tab.c:5874
GLenum query
Definition: glext.h:7781
Definition: dsound.c:943
DWORD data_size
Definition: import.c:98
#define STRING_CANCELLED
Definition: resource.h:43
Definition: path.c:42
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
DWORD type
Definition: reg.c:66
static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
Definition: reg.c:645
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define WINE_FIXME
Definition: debug.h:370
static const WCHAR * reg_type_to_wchar(DWORD type)
Definition: reg.c:591
#define REG_SZ
Definition: layer.c:22
WINE_UNICODE_INLINE WCHAR * struprW(WCHAR *str)
Definition: unicode.h:288