ReactOS  0.4.14-dev-98-gb0d4763
regproc.c
Go to the documentation of this file.
1 /*
2  * Registry processing routines. Routines, common for registry
3  * processing frontends.
4  *
5  * Copyright 1999 Sylvain St-Germain
6  * Copyright 2002 Andriy Palamarchuk
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 
23 #ifdef WIN32_REGDBG
24 #include <windows.h>
25 #include <tchar.h>
26 #ifndef __GNUC__
27 #include <ntsecapi.h>
28 #else
29 #include <ctype.h>
30 #endif
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <assert.h>
35 //#include <winreg.h>
36 #include "regdump.h"
37 #else
38 
39 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
40 #include <windows.h>
41 #include <commctrl.h>
42 #include <stdlib.h>
43 #include <tchar.h>
44 #include <process.h>
45 #include <stdio.h>
46 #include <wchar.h>
47 
48 #include <ctype.h>
49 #include <limits.h>
50 #include <winnt.h>
51 #include <winreg.h>
52 #include <assert.h>
53 
54 #endif
55 
56 #include "regproc.h"
57 
58 
59 #define REG_VAL_BUF_SIZE 4096
60 
61 /* Delimiters used to parse the "value" to query queryValue*/
62 #define QUERY_VALUE_MAX_ARGS 1
63 
64 /* maximal number of characters in hexadecimal data line,
65  not including '\' character */
66 #define REG_FILE_HEX_LINE_LEN 76
67 
68 /* Globals used by the api setValue, queryValue */
70 static HKEY currentKeyClass = 0;
73 
74 static TCHAR *reg_class_names[] = {
75  _T("HKEY_LOCAL_MACHINE"),
76  _T("HKEY_USERS"),
77  _T("HKEY_CLASSES_ROOT"),
78  _T("HKEY_CURRENT_CONFIG"),
79  _T("HKEY_CURRENT_USER")
80 };
81 
82 #define REG_CLASS_NUMBER (sizeof(reg_class_names) / sizeof(reg_class_names[0]))
83 
87 };
88 
89 /* return values */
90 #define NOT_ENOUGH_MEMORY 1
91 #define IO_ERROR 2
92 
93 /* processing macros */
94 
95 /* common check of memory allocation results */
96 #ifdef UNICODE
97 #define CHECK_ENOUGH_MEMORY(p) \
98  if (!(p)) \
99  { \
100  _tprintf(_T("file %S, line %d: Not enough memory"), __FILE__, __LINE__); \
101  assert(0);\
102  exit(NOT_ENOUGH_MEMORY); \
103  }
104 #else
105 #define CHECK_ENOUGH_MEMORY(p) \
106  if (!(p)) \
107  { \
108  _tprintf(_T("file %s, line %d: Not enough memory"), __FILE__, __LINE__); \
109  assert(0);\
110  exit(NOT_ENOUGH_MEMORY); \
111  }
112 #endif
113 
114 #ifdef UNICODE
115 #define _TEOF WEOF
116 #else
117 #define _TEOF EOF
118 #endif
119 
120 /******************************************************************************
121  * This is a replacement for strsep which is not portable (missing on Solaris).
122  */
123 #if 0
124 /* DISABLED */
125 char* getToken(char** str, const char* delims)
126 {
127  char* token;
128 
129  if (*str==NULL) {
130  /* No more tokens */
131  return NULL;
132  }
133 
134  token=*str;
135  while (**str!='\0') {
136  if (strchr(delims,**str)!=NULL) {
137  **str='\0';
138  (*str)++;
139  return token;
140  }
141  (*str)++;
142  }
143  /* There is no other token */
144  *str=NULL;
145  return token;
146 }
147 #endif
148 
149 /******************************************************************************
150  * Copies file name from command line string to the buffer.
151  * Rewinds the command line string pointer to the next non-spece character
152  * after the file name.
153  * Buffer contains an empty string if no filename was found;
154  *
155  * params:
156  * command_line - command line current position pointer
157  * where *s[0] is the first symbol of the file name.
158  * file_name - buffer to write the file name to.
159  */
160 void get_file_nameA(CHAR **command_line, CHAR *file_name, int max_filename)
161 {
162  CHAR *s = *command_line;
163  int pos = 0; /* position of pointer "s" in *command_line */
164  file_name[0] = 0;
165 
166  if (!s[0]) {
167  return;
168  }
169  if (s[0] == '"') {
170  s++;
171  (*command_line)++;
172  while (s[0] != '"') {
173  if (!s[0]) {
174  _tprintf(_T("Unexpected end of file name!\n"));
175  assert(0);
176  //exit(1);
177  }
178  s++;
179  pos++;
180  }
181  } else {
182  while (s[0] && !isspace(s[0])) {
183  s++;
184  pos++;
185  }
186  }
187  memcpy(file_name, *command_line, pos * sizeof((*command_line)[0]));
188  /* remove the last backslash */
189  if (file_name[pos - 1] == '\\') {
190  file_name[pos - 1] = '\0';
191  } else {
192  file_name[pos] = '\0';
193  }
194  if (s[0]) {
195  s++;
196  pos++;
197  }
198  while (s[0] && isspace(s[0])) {
199  s++;
200  pos++;
201  }
202  (*command_line) += pos;
203 }
204 
205 void get_file_nameW(CHAR** command_line, WCHAR* filename, int max_filename)
206 {
208  int len;
209 
210  get_file_nameA(command_line, filenameA, _MAX_PATH);
211  len = strlen(filenameA);
212  OemToCharBuffW(filenameA, filename, max_filename);
213  filename[len] = _T('\0');
214 /*
215  UNICODE_STRING UnicodeString;
216  ANSI_STRING AnsiString;
217  CHAR filenameA[_MAX_PATH];
218 
219  get_file_nameA(command_line, filenameA, _MAX_PATH);
220 
221  //RtlInitAnsiString(&AnsiString, filenameA);
222  UnicodeString.Buffer = filename;
223  UnicodeString.MaximumLength = max_filename;//MAX_PATH;
224  RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
225  */
226 }
227 
228 /******************************************************************************
229  * Converts a hex representation of a DWORD into a DWORD.
230  */
232 {
233  DWORD dw;
234  TCHAR xbuf[9];
235 
236  memcpy(xbuf, str, 8 * sizeof(TCHAR));
237  xbuf[88 * sizeof(TCHAR)] = '\0';
238  _stscanf(xbuf, _T("%08lx"), &dw);
239  memcpy(buf, &dw, sizeof(DWORD));
240  return sizeof(DWORD);
241 }
242 
243 /******************************************************************************
244  * Converts a hex buffer into a hex comma separated values
245  */
247 {
248  TCHAR* str;
249  TCHAR* ptrStr;
250  BYTE* ptrBuf;
251 
252  ULONG current = 0;
253  str = HeapAlloc(GetProcessHeap(), 0, (bufLen+1)*2*sizeof(TCHAR));
254  memset(str, 0, (bufLen+1)*2);
255  ptrStr = str; /* Pointer to result */
256  ptrBuf = buf; /* Pointer to current */
257  while (current < bufLen) {
258  BYTE bCur = ptrBuf[current++];
259  TCHAR res[3];
260  _stprintf(res, _T("%02x"), (unsigned int)*&bCur);
261  _tcscat(str, res);
262  _tcscat(str, _T(","));
263  }
264  /* Get rid of the last comma */
265  str[_tcslen(str)-1] = _T('\0');
266  return str;
267 }
268 
269 /******************************************************************************
270  * Converts a hex buffer into a DWORD string
271  */
273 {
274  TCHAR* str;
275  DWORD dw;
276 
277  if (bufLen != sizeof(DWORD)) return NULL;
278  str = HeapAlloc(GetProcessHeap(), 0, ((bufLen*2)+1)*sizeof(TCHAR));
279  memcpy(&dw, buf, sizeof(DWORD));
280  _stprintf(str, _T("%08lx"), dw);
281  /* Get rid of the last comma */
282  return str;
283 }
284 
285 /******************************************************************************
286  * Converts a hex comma separated values list into a hex list.
287  * The Hex input string must be in exactly the correct form.
288  */
290 {
291  TCHAR* s = str; /* Pointer to current */
292  CHAR* b = buf; /* Pointer to result */
293  ULONG strLen = _tcslen(str);
294  ULONG strPos = 0;
295  DWORD byteCount = 0;
296 
297  memset(buf, 0, bufLen);
298  /*
299  * warn the user if we are here with a string longer than 2 bytes that does
300  * not contains ",". It is more likely because the data is invalid.
301  */
302  if ((strLen > 2) && (_tcschr(str, _T(',')) == NULL)) {
303  _tprintf(_T("WARNING converting CSV hex stream with no comma, ") \
304  _T("input data seems invalid.\n"));
305  }
306  if (strLen > 3*bufLen) {
307  _tprintf(_T("ERROR converting CSV hex stream. Too long\n"));
308  }
309  while (strPos < strLen) {
310  TCHAR xbuf[3];
311  TCHAR wc;
312  memcpy(xbuf, s, 2);
313  xbuf[2] = _T('\0');
314  _stscanf(xbuf, _T("%02x"), (UINT*)&wc);
315  if (byteCount < bufLen)
316  *b++ = (unsigned char)wc;
317  s += 3;
318  strPos += 3;
319  ++byteCount;
320  }
321  return byteCount;
322 }
323 
324 /******************************************************************************
325  * This function returns the HKEY associated with the data type encoded in the
326  * value. It modifies the input parameter (key value) in order to skip this
327  * "now useless" data type information.
328  *
329  * Note: Updated based on the algorithm used in 'server/registry.c'
330  */
332 {
333  struct data_type { const TCHAR *tag; int len; int type; int parse_type; };
334 
335  static const struct data_type data_types[] =
336  { /* actual type */ /* type to assume for parsing */
337  { _T("\""), 1, REG_SZ, REG_SZ },
338  { _T("str:\""), 5, REG_SZ, REG_SZ },
339 // { _T("str(2):\""), 8, REG_EXPAND_SZ, REG_SZ },
340  { _T("expand:\""), 8, REG_EXPAND_SZ, REG_EXPAND_SZ },
341  { _T("hex:"), 4, REG_BINARY, REG_BINARY },
342  { _T("dword:"), 6, REG_DWORD, REG_DWORD },
343  { _T("hex("), 4, -1, REG_BINARY },
344  { NULL, 0, 0, 0 }
345  };
346 
347  const struct data_type *ptr;
348  int type;
349 
350  for (ptr = data_types; ptr->tag; ptr++) {
351  if (memcmp(ptr->tag, *lpValue, ptr->len))
352  continue;
353 
354  /* Found! */
355  *parse_type = ptr->parse_type;
356  type = ptr->type;
357  *lpValue += ptr->len;
358  if (type == -1) {
359  TCHAR* end;
360  /* "hex(xx):" is special */
361  type = (int)_tcstoul(*lpValue , &end, 16);
362  if (**lpValue == _T('\0') || *end != _T(')') || *(end+1) != _T(':')) {
363  type = REG_NONE;
364  } else {
365  *lpValue = end + 2;
366  }
367  }
368  return type;
369  }
370  return (**lpValue == _T('\0') ? REG_SZ : REG_NONE);
371 }
372 
373 /******************************************************************************
374  * Returns an allocated buffer with a cleaned copy (removed the surrounding
375  * dbl quotes) of the passed value.
376  */
378 {
379  LPTSTR tmp = NULL;
380  ULONG len;
381 
382  if (arg == NULL) return NULL;
383 
384  // Get rid of surrounding quotes
385  len = _tcslen(arg);
386  if (arg[len-1] == _T('\"')) arg[len-1] = _T('\0');
387  if (arg[0] == _T('\"')) arg++;
388  tmp = HeapAlloc(GetProcessHeap(), 0, (_tcslen(arg)+1) * sizeof(TCHAR));
389  _tcscpy(tmp, arg);
390  return tmp;
391 }
392 
393 /******************************************************************************
394  * Replaces escape sequences with the characters.
395  */
397 {
398  int str_idx = 0; /* current character under analysis */
399  int val_idx = 0; /* the last character of the unescaped string */
400  int len = _tcslen(str);
401  for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
402  if (str[str_idx] == _T('\\')) {
403  str_idx++;
404  switch (str[str_idx]) {
405  case _T('n'):
406  str[val_idx] = _T('\n');
407  break;
408  case _T('\\'):
409  case _T('"'):
410  str[val_idx] = str[str_idx];
411  break;
412  default:
413  _tprintf(_T("Warning! Unrecognized escape sequence: \\%c'\n"), str[str_idx]);
414  str[val_idx] = str[str_idx];
415  break;
416  }
417  } else {
418  str[val_idx] = str[str_idx];
419  }
420  }
421  str[val_idx] = _T('\0');
422 }
423 
424 /******************************************************************************
425  * Sets the value with name val_name to the data in val_data for the currently
426  * opened key.
427  *
428  * Parameters:
429  * val_name - name of the registry value
430  * val_data - registry value data
431  */
432 HRESULT setValue(LPTSTR val_name, LPTSTR val_data)
433 {
434  HRESULT hRes;
435  DWORD dwDataType, dwParseType;
436  LPBYTE lpbData;
438  BYTE *bBigBuffer = 0;
439  DWORD dwLen;
440 
441  if ((val_name == NULL) || (val_data == NULL))
443 
444  /* Get the data type stored into the value field */
445  dwDataType = getDataType(&val_data, &dwParseType);
446 
447 // if (dwParseType == REG_EXPAND_SZ) {
448 // }
449 // if (dwParseType == REG_SZ || dwParseType == REG_EXPAND_SZ) { /* no conversion for string */
450 
451  if (dwParseType == REG_SZ) { /* no conversion for string */
452  dwLen = _tcslen(val_data);
453  if (dwLen > 0 && val_data[dwLen-1] == _T('"')) {
454  dwLen--;
455  val_data[dwLen] = _T('\0');
456  }
457  dwLen++;
458  dwLen *= sizeof(TCHAR);
459  REGPROC_unescape_string(val_data);
460  lpbData = val_data;
461  } else if (dwParseType == REG_DWORD) { /* Convert the dword types */
462  dwLen = convertHexToDWord(val_data, convert);
463  lpbData = convert;
464  } else { /* Convert the hexadecimal types */
465  int b_len = _tcslen(val_data)+2/3;
466  if (b_len > KEY_MAX_LEN) {
467  bBigBuffer = HeapAlloc (GetProcessHeap(), 0, b_len * sizeof(TCHAR));
468  if (bBigBuffer == NULL) {
470  }
471  CHECK_ENOUGH_MEMORY(bBigBuffer);
472  dwLen = convertHexCSVToHex(val_data, bBigBuffer, b_len);
473  lpbData = bBigBuffer;
474  } else {
475  dwLen = convertHexCSVToHex(val_data, convert, KEY_MAX_LEN);
476  lpbData = convert;
477  }
478  }
479  hRes = RegSetValueEx(currentKeyHandle, val_name,
480  0, /* Reserved */dwDataType, lpbData, dwLen);
481 
482  _tprintf(_T(" Value: %s, Data: %s\n"), val_name, lpbData);
483 
484 
485  if (bBigBuffer)
486  HeapFree(GetProcessHeap(), 0, bBigBuffer);
487  return hRes;
488 }
489 
490 
491 /******************************************************************************
492  * Open the key
493  */
495 {
496  DWORD dwDisp;
497  HRESULT hRes;
498 
499  /* Sanity checks */
500  if (stdInput == NULL)
502 
503  /* Get the registry class */
504  currentKeyClass = getRegClass(stdInput); /* Sets global variable */
507 
508  /* Get the key name */
509  currentKeyName = getRegKeyName(stdInput); /* Sets global variable */
510  if (currentKeyName == NULL)
512 
513  hRes = RegCreateKeyEx(
514  currentKeyClass, /* Class */
515  currentKeyName, /* Sub Key */
516  0, /* MUST BE 0 */
517  NULL, /* object type */
518  REG_OPTION_NON_VOLATILE, /* option, REG_OPTION_NON_VOLATILE ... */
519  KEY_ALL_ACCESS, /* access mask, KEY_ALL_ACCESS */
520  NULL, /* security attribute */
521  &currentKeyHandle, /* result */
522  &dwDisp); /* disposition, REG_CREATED_NEW_KEY or
523  REG_OPENED_EXISTING_KEY */
524 
525  if (hRes == ERROR_SUCCESS)
527 
528  return hRes;
529 
530 }
531 
532 /******************************************************************************
533  * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
534  * the key name (what starts after the first '\')
535  */
537 {
538  LPTSTR keyNameBeg;
539  TCHAR lpLineCopy[KEY_MAX_LEN];
540 
541  if (lpLine == NULL)
542  return NULL;
543 
544  _tcscpy(lpLineCopy, lpLine);
545  keyNameBeg = _tcschr(lpLineCopy, _T('\\')); /* The key name start by '\' */
546  if (keyNameBeg) {
547  LPTSTR keyNameEnd;
548 
549  keyNameBeg++; /* is not part of the name */
550  keyNameEnd = _tcschr(lpLineCopy, _T(']'));
551  if (keyNameEnd) {
552  *keyNameEnd = _T('\0'); /* remove ']' from the key name */
553  }
554  } else {
555  keyNameBeg = lpLineCopy + _tcslen(lpLineCopy); /* branch - empty string */
556  }
557  currentKeyName = HeapAlloc(GetProcessHeap(), 0, (_tcslen(keyNameBeg)+1)*sizeof(TCHAR));
559  _tcscpy(currentKeyName, keyNameBeg);
560  return currentKeyName;
561 }
562 
563 /******************************************************************************
564  * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
565  * the key class (what ends before the first '\')
566  */
568 {
569  LPTSTR classNameEnd;
570  LPTSTR classNameBeg;
571  int i;
572 
573  TCHAR lpClassCopy[KEY_MAX_LEN];
574 
575  if (lpClass == NULL)
577 
578  _tcsncpy(lpClassCopy, lpClass, KEY_MAX_LEN);
579 
580  classNameEnd = _tcschr(lpClassCopy, _T('\\')); /* The class name ends by '\' */
581  if (!classNameEnd) { /* or the whole string */
582  classNameEnd = lpClassCopy + _tcslen(lpClassCopy);
583  if (classNameEnd[-1] == _T(']')) {
584  classNameEnd--;
585  }
586  }
587  *classNameEnd = _T('\0'); /* Isolate the class name */
588  if (lpClassCopy[0] == _T('[')) {
589  classNameBeg = lpClassCopy + 1;
590  } else {
591  classNameBeg = lpClassCopy;
592  }
593  for (i = 0; i < REG_CLASS_NUMBER; i++) {
594  if (!_tcscmp(classNameBeg, reg_class_names[i])) {
595  return reg_class_keys[i];
596  }
597  }
599 }
600 
601 /******************************************************************************
602  * Close the currently opened key.
603  */
605 {
607  HeapFree(GetProcessHeap(), 0, currentKeyName); /* Allocated by getKeyName */
610  currentKeyClass = 0;
611  currentKeyHandle = 0;
612 }
613 
614 /******************************************************************************
615  * This function is the main entry point to the setValue type of action. It
616  * receives the currently read line and dispatch the work depending on the
617  * context.
618  */
619 void doSetValue(LPTSTR stdInput)
620 {
621  /*
622  * We encountered the end of the file, make sure we
623  * close the opened key and exit
624  */
625  if (stdInput == NULL) {
626  if (bTheKeyIsOpen != FALSE)
627  closeKey();
628  return;
629  }
630 
631  if (stdInput[0] == _T('[')) { /* We are reading a new key */
632  if (bTheKeyIsOpen != FALSE) {
633  closeKey(); /* Close the previous key before */
634  }
635  if (openKey(stdInput) != ERROR_SUCCESS) {
636  _tprintf(_T("doSetValue failed to open key %s\n"), stdInput);
637  }
638  } else if ((bTheKeyIsOpen) &&
639  ((stdInput[0] == _T('@')) || /* reading a default @=data pair */
640  (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */
641  processSetValue(stdInput);
642  } else { /* since we are assuming that the file format is */
643  if (bTheKeyIsOpen) /* valid we must be reading a blank line which */
644  closeKey(); /* indicate end of this key processing */
645  }
646 }
647 
648 /******************************************************************************
649  * This funtion is the main entry point to the queryValue type of action. It
650  * receives the currently read line and dispatch the work depending on the
651  * context.
652  */
653 void doQueryValue(LPTSTR stdInput) {
654  /*
655  * We encoutered the end of the file, make sure we
656  * close the opened key and exit
657  */
658  if (stdInput == NULL) {
659  if (bTheKeyIsOpen != FALSE)
660  closeKey();
661  return;
662  }
663 
664  if (stdInput[0] == _T('[')) { /* We are reading a new key */
665  if (bTheKeyIsOpen != FALSE)
666  closeKey(); /* Close the previous key before */
667  if (openKey(stdInput) != ERROR_SUCCESS ) {
668  _tprintf(_T("doQueryValue failed to open key %s\n"), stdInput);
669  }
670  }
671  else if( (bTheKeyIsOpen) &&
672  ((stdInput[0] == _T('@')) || /* reading a default @=data pair */
673  (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */
674  processQueryValue(stdInput);
675  } else { /* since we are assuming that the file format is */
676  if (bTheKeyIsOpen) /* valid we must be reading a blank line which */
677  closeKey(); /* indicate end of this key processing */
678  }
679 }
680 
681 /******************************************************************************
682  * This funtion is the main entry point to the deletetValue type of action. It
683  * receives the currently read line and dispatch the work depending on the
684  * context.
685  */
687  _tprintf(_T("deleteValue not yet implemented\n"));
688 }
689 
690 /******************************************************************************
691  * This funtion is the main entry point to the deleteKey type of action. It
692  * receives the currently read line and dispatch the work depending on the
693  * context.
694  */
696  _tprintf(_T("deleteKey not yet implemented\n"));
697 }
698 
699 /******************************************************************************
700  * This funtion is the main entry point to the createKey type of action. It
701  * receives the currently read line and dispatch the work depending on the
702  * context.
703  */
705  _tprintf(_T("createKey not yet implemented\n"));
706 }
707 
708 /******************************************************************************
709  * This function is a wrapper for the setValue function. It prepares the
710  * land and clean the area once completed.
711  * Note: this function modifies the line parameter.
712  *
713  * line - registry file unwrapped line. Should have the registry value name and
714  * complete registry value data.
715  */
717 {
718  LPTSTR val_name; /* registry value name */
719  LPTSTR val_data; /* registry value data */
720 
721  int line_idx = 0; /* current character under analysis */
722  HRESULT hRes = 0;
723 
724  /* get value name */
725  if (line[line_idx] == _T('@') && line[line_idx + 1] == _T('=')) {
726  line[line_idx] = _T('\0');
727  val_name = line;
728  line_idx++;
729  } else if (line[line_idx] == _T('\"')) {
730  line_idx++;
731  val_name = line + line_idx;
732  while (TRUE) {
733  if (line[line_idx] == _T('\\')) { /* skip escaped character */
734  line_idx += 2;
735  } else {
736  if (line[line_idx] == _T('\"')) {
737  line[line_idx] = _T('\0');
738  line_idx++;
739  break;
740  } else {
741  line_idx++;
742  }
743  }
744  }
745  if (line[line_idx] != _T('=')) {
746  line[line_idx] = _T('\"');
747  _tprintf(_T("Warning! uncrecognized line:\n%s\n"), line);
748  return;
749  }
750  } else {
751  _tprintf(_T("Warning! unrecognized line:\n%s\n"), line);
752  return;
753  }
754  line_idx++; /* skip the '=' character */
755  val_data = line + line_idx;
756  REGPROC_unescape_string(val_name);
757 
758  _tprintf(_T("Key: %s, Value: %s, Data: %s\n"), currentKeyName, val_name, val_data);
759 
760  hRes = setValue(val_name, val_data);
761  if (hRes != ERROR_SUCCESS) {
762  _tprintf(_T("ERROR Key %s not created. Value: %s, Data: %s\n"), currentKeyName, val_name, val_data);
763  }
764 }
765 
766 /******************************************************************************
767  * This function is a wrapper for the queryValue function. It prepares the
768  * land and clean the area once completed.
769  */
771 {
772  _tprintf(_T("ERROR!!! - temporary disabled"));
773  //exit(1);
774  return;
775 #if 0
776  LPSTR argv[QUERY_VALUE_MAX_ARGS];/* args storage */
777  LPSTR token = NULL; /* current token analized */
778  ULONG argCounter = 0; /* counter of args */
779  INT counter;
780  HRESULT hRes = 0;
781  LPSTR keyValue = NULL;
782  LPSTR lpsRes = NULL;
783 
784  /*
785  * Init storage and parse the line
786  */
788  argv[counter] = NULL;
789 
790  while ((token = getToken(&cmdline, queryValueDelim[argCounter])) != NULL) {
791  argv[argCounter++] = getArg(token);
792  if (argCounter == QUERY_VALUE_MAX_ARGS)
793  break; /* Stop processing args no matter what */
794  }
795 
796  /* The value we look for is the first token on the line */
797  if (argv[0] == NULL)
798  return; /* SHOULD NOT HAPPEN */
799  else
800  keyValue = argv[0];
801 
802  if ((keyValue[0] == '@') && (_tcslen(keyValue) == 1)) {
803  LONG lLen = KEY_MAX_LEN;
805  /*
806  * We need to query the key default value
807  */
808  hRes = RegQueryValue(currentKeyHandle, currentKeyName, (LPBYTE)lpsData, &lLen);
809  if (hRes == ERROR_MORE_DATA) {
810  lpsData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpsData, lLen);
811  hRes = RegQueryValue(currentKeyHandle, currentKeyName, (LPBYTE)lpsData, &lLen);
812  }
813  if (hRes == ERROR_SUCCESS) {
814  lpsRes = HeapAlloc(GetProcessHeap(), 0, lLen);
815  strncpy(lpsRes, lpsData, lLen);
816  lpsRes[lLen-1]='\0';
817  }
818  } else {
819  DWORD dwLen = KEY_MAX_LEN;
821  DWORD dwType;
822  /*
823  * We need to query a specific value for the key
824  */
825  hRes = RegQueryValueEx(
827  keyValue,
828  0,
829  &dwType,
830  (LPBYTE)lpbData,
831  &dwLen);
832 
833  if (hRes == ERROR_MORE_DATA) {
834  lpbData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpbData, dwLen * sizeof(TCHAR));
835  hRes = RegQueryValueEx(currentKeyHandle, keyValue, NULL, &dwType, (LPBYTE)lpbData, &dwLen);
836  }
837 
838  if (hRes == ERROR_SUCCESS) {
839  /*
840  * Convert the returned data to a displayable format
841  */
842  switch (dwType) {
843  case REG_SZ:
844  case REG_EXPAND_SZ:
845  lpsRes = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(TCHAR));
846  strncpy(lpsRes, lpbData, dwLen);
847  lpsRes[dwLen-1] = '\0';
848  break;
849  case REG_DWORD:
850  lpsRes = convertHexToDWORDStr(lpbData, dwLen);
851  break;
852  default:
853  lpsRes = convertHexToHexCSV(lpbData, dwLen);
854  break;
855  }
856  }
857 
858  HeapFree(GetProcessHeap(), 0, lpbData);
859  }
860  if (hRes == ERROR_SUCCESS) {
861  _tprintf(_T("Value \"%s\" = \"%s\" in key [%s]\n"), keyValue, lpsRes, currentKeyName);
862 
863  } else {
864  _tprintf(_T("ERROR Value \"%s\" not found. for key \"%s\"\n"), keyValue, currentKeyName);
865  }
866 
867  /*
868  * Do some cleanup
869  */
870  for (counter=0; counter<argCounter; counter++)
871  if (argv[counter] != NULL)
873 
874  if (lpsRes != NULL)
875  HeapFree(GetProcessHeap(), 0, lpsRes);
876 #endif
877 }
878 
879 /******************************************************************************
880  * Calls command for each line of a registry file.
881  * Correctly processes comments (in # form), line continuation.
882  *
883  * Parameters:
884  * in - input stream to read from
885  * command - command to be called for each line
886  */
888 {
889  LPTSTR line = NULL; /* line read from input stream */
890  ULONG lineSize = REG_VAL_BUF_SIZE;
891 
892  line = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(TCHAR));
894 
895  while (!feof(in)) {
896  LPTSTR s; /* The pointer into line for where the current fgets should read */
897  s = line;
898  for (;;) {
899  size_t size_remaining;
900  int size_to_get;
901  TCHAR *s_eol; /* various local uses */
902 
903  /* Do we need to expand the buffer ? */
904  assert (s >= line && s <= line + lineSize);
905  size_remaining = lineSize - (s-line);
906  if (size_remaining < 2) { /* room for 1 character and the \0 */
907  TCHAR *new_buffer;
908  size_t new_size = lineSize + REG_VAL_BUF_SIZE;
909  if (new_size > lineSize) /* no arithmetic overflow */
910  new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size * sizeof(TCHAR));
911  else
912  new_buffer = NULL;
913  CHECK_ENOUGH_MEMORY(new_buffer);
914  line = new_buffer;
915  s = line + lineSize - size_remaining;
916  lineSize = new_size;
917  size_remaining = lineSize - (s-line);
918  }
919 
920  /* Get as much as possible into the buffer, terminated either by
921  * eof, error, eol or getting the maximum amount. Abort on error.
922  */
923 //
924 // This line is surely foobar, don't want to read INT_MAX in buffer at s, it's never going to be that big...
925 // size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining);
926 //
927 // Looks as if 'lineSize' contains the number of characters of buffer size
928 //
929  size_to_get = (size_remaining > lineSize ? lineSize : size_remaining);
930 
931  if (NULL == _fgetts(s, size_to_get, in)) {
932  if (ferror(in)) {
933  //_tperror(_T("While reading input"));
934  perror ("While reading input");
935  //exit(IO_ERROR);
936  return;
937  } else {
938  assert (feof(in));
939  *s = _T('\0');
940  /* It is not clear to me from the definition that the
941  * contents of the buffer are well defined on detecting
942  * an eof without managing to read anything.
943  */
944  }
945  }
946 
947  /* If we didn't read the eol nor the eof go around for the rest */
948  s_eol = _tcschr (s, _T('\n'));
949  if (!feof (in) && !s_eol) {
950  s = _tcschr (s, _T('\0'));
951  /* It should be s + size_to_get - 1 but this is safer */
952  continue;
953  }
954 
955  /* If it is a comment line then discard it and go around again */
956  if (line [0] == _T('#')) {
957  s = line;
958  continue;
959  }
960 
961  /* Remove any line feed. Leave s_eol on the \0 */
962  if (s_eol) {
963  *s_eol = _T('\0');
964  if (s_eol > line && *(s_eol-1) == _T('\r'))
965  *--s_eol = _T('\0');
966  } else {
967  s_eol = _tcschr (s, _T('\0'));
968  }
969  /* If there is a concatenating \\ then go around again */
970  if (s_eol > line && *(s_eol-1) == _T('\\')) {
971  int c;
972  s = s_eol-1;
973  /* The following error protection could be made more self-
974  * correcting but I thought it not worth trying.
975  */
976 
977  if ((c = _fgettc(in)) == _TEOF || c != _T(' ') ||
978  (c = _fgettc(in)) == _TEOF || c != _T(' '))
979  _tprintf(_T("ERROR - invalid continuation.\n"));
980  continue;
981  }
982  break; /* That is the full virtual line */
983  }
984  command(line);
985  }
986  command(NULL);
988 }
989 
990 /******************************************************************************
991  * This funtion is the main entry point to the registerDLL action. It
992  * receives the currently read line, then loads and registers the requested DLLs
993  */
994 void doRegisterDLL(LPTSTR stdInput)
995 {
996  HMODULE theLib = 0;
997  UINT retVal = 0;
998 
999  /* Check for valid input */
1000  if (stdInput == NULL) return;
1001 
1002  /* Load and register the library, then free it */
1003  theLib = LoadLibrary(stdInput);
1004  if (theLib) {
1005  FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllRegisterServer");
1006  if (lpfnDLLRegProc) {
1007  retVal = (*lpfnDLLRegProc)();
1008  } else {
1009  _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput);
1010  }
1011  if (retVal != S_OK) {
1012  _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput);
1013  }
1014  FreeLibrary(theLib);
1015  } else {
1016  _tprintf(_T("Could not load DLL '%s'.\n"), stdInput);
1017  }
1018 }
1019 
1020 /******************************************************************************
1021  * This funtion is the main entry point to the unregisterDLL action. It
1022  * receives the currently read line, then loads and unregisters the requested DLLs
1023  */
1024 void doUnregisterDLL(LPTSTR stdInput)
1025 {
1026  HMODULE theLib = 0;
1027  UINT retVal = 0;
1028 
1029  /* Check for valid input */
1030  if (stdInput == NULL) return;
1031 
1032  /* Load and unregister the library, then free it */
1033  theLib = LoadLibrary(stdInput);
1034  if (theLib) {
1035  FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllUnregisterServer");
1036  if (lpfnDLLRegProc) {
1037  retVal = (*lpfnDLLRegProc)();
1038  } else {
1039  _tprintf(_T("Couldn't find DllUnregisterServer proc in '%s'.\n"), stdInput);
1040  }
1041  if (retVal != S_OK) {
1042  _tprintf(_T("DLLUnregisterServer error 0x%x in '%s'.\n"), retVal, stdInput);
1043  }
1044  FreeLibrary(theLib);
1045  } else {
1046  _tprintf(_T("Could not load DLL '%s'.\n"), stdInput);
1047  }
1048 }
1049 
1050 /****************************************************************************
1051  * REGPROC_print_error
1052  *
1053  * Print the message for GetLastError
1054  */
1055 
1057 {
1058  LPVOID lpMsgBuf;
1059  DWORD error_code;
1060  int status;
1061 
1062  error_code = GetLastError ();
1064  NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
1065  if (!status) {
1066  _tprintf(_T("Cannot display message for error %ld, status %ld\n"), error_code, GetLastError());
1067  } else {
1068  _tprintf(_T("REGPROC_print_error() - "));
1069  puts(lpMsgBuf);
1070  LocalFree((HLOCAL)lpMsgBuf);
1071  }
1072  //exit(1);
1073 }
1074 
1075 /******************************************************************************
1076  * Checks whether the buffer has enough room for the string or required size.
1077  * Resizes the buffer if necessary.
1078  *
1079  * Parameters:
1080  * buffer - pointer to a buffer for string
1081  * len - current length of the buffer in characters.
1082  * required_len - length of the string to place to the buffer in characters.
1083  * The length does not include the terminating null character.
1084  */
1086 {
1087  required_len++;
1088  if (required_len > *len) {
1089  *len = required_len;
1090  *buffer = HeapReAlloc(GetProcessHeap(), 0, *buffer, *len * sizeof(**buffer));
1092  }
1093 }
1094 
1095 /******************************************************************************
1096  * Prints string str to file
1097  */
1099 {
1100  size_t len = _tcslen(str);
1101  size_t i;
1102 
1103  /* escaping characters */
1104  for (i = 0; i < len; i++) {
1105  TCHAR c = str[i];
1106  switch (c) {
1107  //case _T('\\'): _fputts(_T("\\\\"), file); break;
1108  case _T('\"'): _fputts(_T("\\\""), file); break;
1109  case _T('\n'): _fputts(_T("\\\n"), file); break;
1110  default: _fputtc(c, file); break;
1111  }
1112  }
1113 }
1114 
1115 /******************************************************************************
1116  * Writes contents of the registry key to the specified file stream.
1117  *
1118  * Parameters:
1119  * file - writable file stream to export registry branch to.
1120  * key - registry branch to export.
1121  * reg_key_name_buf - name of the key with registry class.
1122  * Is resized if necessary.
1123  * reg_key_name_len - length of the buffer for the registry class in characters.
1124  * val_name_buf - buffer for storing value name.
1125  * Is resized if necessary.
1126  * val_name_len - length of the buffer for storing value names in characters.
1127  * val_buf - buffer for storing values while extracting.
1128  * Is resized if necessary.
1129  * val_size - size of the buffer for storing values in bytes.
1130  */
1132  TCHAR **reg_key_name_buf, DWORD *reg_key_name_len,
1133  TCHAR **val_name_buf, DWORD *val_name_len,
1134  BYTE **val_buf, DWORD *val_size)
1135 {
1136  DWORD max_sub_key_len;
1137  DWORD max_val_name_len;
1138  DWORD max_val_size;
1139  DWORD curr_len;
1140  DWORD i;
1141  BOOL more_data;
1142  LONG ret;
1143 
1144  /* get size information and resize the buffers if necessary */
1145  if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, &max_sub_key_len, NULL,
1146  NULL, &max_val_name_len, &max_val_size, NULL, NULL) != ERROR_SUCCESS) {
1148  }
1149  curr_len = _tcslen(*reg_key_name_buf);
1150  REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1);
1151  REGPROC_resize_char_buffer(val_name_buf, val_name_len, max_val_name_len);
1152  if (max_val_size > *val_size) {
1153  *val_size = max_val_size;
1154  *val_buf = HeapReAlloc(GetProcessHeap(), 0, *val_buf, *val_size * sizeof(TCHAR));
1155  CHECK_ENOUGH_MEMORY(val_buf);
1156  }
1157  /* output data for the current key */
1158  _fputts(_T("\n["), file);
1159  _fputts(*reg_key_name_buf, file);
1160  _fputts(_T("]\n"), file);
1161  /* print all the values */
1162  i = 0;
1163  more_data = TRUE;
1164  while (more_data) {
1165  DWORD value_type;
1166  DWORD val_name_len1 = *val_name_len;
1167  DWORD val_size1 = *val_size;
1168  ret = RegEnumValue(key, i, *val_name_buf, &val_name_len1, NULL, &value_type, *val_buf, &val_size1);
1169  if (ret != ERROR_SUCCESS) {
1170  more_data = FALSE;
1171  if (ret != ERROR_NO_MORE_ITEMS) {
1173  }
1174  } else {
1175  i++;
1176  if ((*val_name_buf)[0]) {
1177  _fputts(_T("\""), file);
1178  REGPROC_export_string(file, *val_name_buf);
1179  _fputts(_T("\"="), file);
1180  } else {
1181  _fputts(_T("@="), file);
1182  }
1183  switch (value_type) {
1184  case REG_EXPAND_SZ:
1185  _fputts(_T("expand:"), file);
1186  case REG_SZ:
1187  _fputts(_T("\""), file);
1188  REGPROC_export_string(file, *val_buf);
1189  _fputts(_T("\"\n"), file);
1190  break;
1191  case REG_DWORD:
1192  _ftprintf(file, _T("dword:%08lx\n"), *((DWORD *)*val_buf));
1193  break;
1194  default:
1195 /*
1196  _tprintf(_T("warning - unsupported registry format '%ld', ") \
1197  _T("treating as binary\n"), value_type);
1198  _tprintf(_T("key name: \"%s\"\n"), *reg_key_name_buf);
1199  _tprintf(_T("value name:\"%s\"\n\n"), *val_name_buf);
1200  */
1201  /* falls through */
1202  case REG_MULTI_SZ:
1203  /* falls through */
1204  case REG_BINARY:
1205  {
1206  DWORD i1;
1207  TCHAR *hex_prefix;
1208  TCHAR buf[20];
1209  int cur_pos;
1210 
1211  if (value_type == REG_BINARY) {
1212  hex_prefix = _T("hex:");
1213  } else {
1214  hex_prefix = buf;
1215  _stprintf(buf, _T("hex(%ld):"), value_type);
1216  }
1217  /* position of where the next character will be printed */
1218  /* NOTE: yes, _tcslen("hex:") is used even for hex(x): */
1219  cur_pos = _tcslen(_T("\"\"=")) + _tcslen(_T("hex:")) +
1220  _tcslen(*val_name_buf);
1221  _fputts(hex_prefix, file);
1222  for (i1 = 0; i1 < val_size1; i1++) {
1223  _ftprintf(file, _T("%02x"), (unsigned int)(*val_buf)[i1]);
1224  if (i1 + 1 < val_size1) {
1225  _fputts(_T(","), file);
1226  }
1227  cur_pos += 3;
1228  /* wrap the line */
1229  if (cur_pos > REG_FILE_HEX_LINE_LEN) {
1230  _fputts(_T("\\\n "), file);
1231  cur_pos = 2;
1232  }
1233  }
1234  _fputts(_T("\n"), file);
1235  break;
1236  }
1237  }
1238  }
1239  }
1240  i = 0;
1241  more_data = TRUE;
1242  (*reg_key_name_buf)[curr_len] = _T('\\');
1243  while (more_data) {
1244  DWORD buf_len = *reg_key_name_len - curr_len;
1245  ret = RegEnumKeyEx(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
1246  if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) {
1247  more_data = FALSE;
1248  if (ret != ERROR_NO_MORE_ITEMS) {
1250  }
1251  } else {
1252  HKEY subkey;
1253 
1254  i++;
1255  if (RegOpenKey(key, *reg_key_name_buf + curr_len + 1, &subkey) == ERROR_SUCCESS) {
1256  export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len, val_name_buf, val_name_len, val_buf, val_size);
1257  RegCloseKey(subkey);
1258  } else {
1260  }
1261  }
1262  }
1263  (*reg_key_name_buf)[curr_len] = _T('\0');
1264 }
1265 /*
1266 #define REG_NONE ( 0 ) // No value type
1267 #define REG_SZ ( 1 ) // Unicode nul terminated string
1268 #define REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string
1269  // (with environment variable references)
1270 #define REG_BINARY ( 3 ) // Free form binary
1271 #define REG_DWORD ( 4 ) // 32-bit number
1272 #define REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD)
1273 #define REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number
1274 #define REG_LINK ( 6 ) // Symbolic Link (unicode)
1275 #define REG_MULTI_SZ ( 7 ) // Multiple Unicode strings
1276 #define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map
1277 #define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description
1278 #define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )
1279 
1280  */
1281 /******************************************************************************
1282  * Open file for export.
1283  */
1285 {
1286 //_CRTIMP FILE * __cdecl _wfopen(const wchar_t *, const wchar_t *);
1287 
1288 //FILE* fopen (const char* szFileName, const char* szMode);
1289 //FILE* _wfopen(const wchar_t *file, const wchar_t *mode);
1290 
1291  FILE *file = _tfopen(file_name, _T("w"));
1292  if (!file) {
1293  perror("");
1294  _tprintf(_T("REGPROC_open_export_file(%s) - Can't open file.\n"), file_name);
1295  //exit(1);
1296  return NULL;
1297  }
1298  _fputts(_T("REGEDIT4\n"), file);
1299  return file;
1300 }
1301 
1302 /******************************************************************************
1303  * Writes contents of the registry key to the specified file stream.
1304  *
1305  * Parameters:
1306  * file_name - name of a file to export registry branch to.
1307  * reg_key_name - registry branch to export. The whole registry is exported if
1308  * reg_key_name is NULL or contains an empty string.
1309  */
1311 {
1312  HKEY reg_key_class;
1313 
1314  TCHAR *reg_key_name_buf;
1315  TCHAR *val_name_buf;
1316  BYTE *val_buf;
1317  DWORD reg_key_name_len = KEY_MAX_LEN;
1318  DWORD val_name_len = KEY_MAX_LEN;
1319  DWORD val_size = REG_VAL_BUF_SIZE;
1320  FILE *file = NULL;
1321 
1322  //_tprintf(_T("export_registry_key(%s, %s)\n"), reg_key_name, file_name);
1323 
1324  reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_len * sizeof(*reg_key_name_buf));
1325  val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_len * sizeof(*val_name_buf));
1326  val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
1327  CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf);
1328 
1329  if (reg_key_name && reg_key_name[0]) {
1330  TCHAR *branch_name;
1331  HKEY key;
1332 
1333  REGPROC_resize_char_buffer(&reg_key_name_buf, &reg_key_name_len,
1334  _tcslen(reg_key_name));
1335  _tcscpy(reg_key_name_buf, reg_key_name);
1336 
1337  /* open the specified key */
1338  reg_key_class = getRegClass(reg_key_name);
1339  if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) {
1340  _tprintf(_T("Incorrect registry class specification in '%s\n"), reg_key_name);
1341  //exit(1);
1342  return FALSE;
1343  }
1344  branch_name = getRegKeyName(reg_key_name);
1345  CHECK_ENOUGH_MEMORY(branch_name);
1346  if (!branch_name[0]) {
1347  /* no branch - registry class is specified */
1349  export_hkey(file, reg_key_class,
1350  &reg_key_name_buf, &reg_key_name_len,
1351  &val_name_buf, &val_name_len,
1352  &val_buf, &val_size);
1353  } else if (RegOpenKey(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
1355  export_hkey(file, key,
1356  &reg_key_name_buf, &reg_key_name_len,
1357  &val_name_buf, &val_name_len,
1358  &val_buf, &val_size);
1359  RegCloseKey(key);
1360  } else {
1361  _tprintf(_T("Can't export. Registry key '%s does not exist!\n"), reg_key_name);
1363  }
1364  HeapFree(GetProcessHeap(), 0, branch_name);
1365  } else {
1366  int i;
1367 
1368  /* export all registry classes */
1370  for (i = 0; i < REG_CLASS_NUMBER; i++) {
1371  /* do not export HKEY_CLASSES_ROOT */
1375  _tcscpy(reg_key_name_buf, reg_class_names[i]);
1377  &reg_key_name_buf, &reg_key_name_len,
1378  &val_name_buf, &val_name_len,
1379  &val_buf, &val_size);
1380  }
1381  }
1382  }
1383  if (file) {
1384  fclose(file);
1385  }
1386 // HeapFree(GetProcessHeap(), 0, reg_key_name);
1387  HeapFree(GetProcessHeap(), 0, val_buf);
1388  HeapFree(GetProcessHeap(), 0, val_name_buf);
1389  HeapFree(GetProcessHeap(), 0, reg_key_name_buf);
1390  return TRUE;
1391 }
1392 
1393 /******************************************************************************
1394  * Reads contents of the specified file into the registry.
1395  */
1397 {
1398  FILE* reg_file = _tfopen(filename, _T("r"));
1399 
1400  if (reg_file) {
1401  processRegLines(reg_file, doSetValue);
1402  return TRUE;
1403  }
1404  return FALSE;
1405 }
1406 
1407 /******************************************************************************
1408  * Recursive function which removes the registry key with all subkeys.
1409  */
1410 BOOL delete_branch(HKEY key, TCHAR** reg_key_name_buf, DWORD* reg_key_name_len)
1411 {
1412  HKEY branch_key;
1413  DWORD max_sub_key_len;
1414  DWORD subkeys;
1415  DWORD curr_len;
1416  LONG ret;
1417  long int i;
1418 
1419  if (RegOpenKey(key, *reg_key_name_buf, &branch_key) != ERROR_SUCCESS) {
1421  return FALSE;
1422  }
1423 
1424  /* get size information and resize the buffers if necessary */
1425  if (RegQueryInfoKey(branch_key, NULL, NULL, NULL, &subkeys, &max_sub_key_len,
1426  NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
1428  RegCloseKey(branch_key);
1429  return FALSE;
1430  }
1431  curr_len = _tcslen(*reg_key_name_buf);
1432  REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1);
1433 
1434  (*reg_key_name_buf)[curr_len] = '\\';
1435  for (i = subkeys - 1; i >= 0; i--) {
1436  DWORD buf_len = *reg_key_name_len - curr_len;
1437  ret = RegEnumKeyEx(branch_key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
1440  RegCloseKey(branch_key);
1441  return FALSE;
1442  } else {
1443  delete_branch(key, reg_key_name_buf, reg_key_name_len);
1444  }
1445  }
1446  (*reg_key_name_buf)[curr_len] = '\0';
1447  RegCloseKey(branch_key);
1448  RegDeleteKey(key, *reg_key_name_buf);
1449  return TRUE;
1450 }
1451 
1452 /******************************************************************************
1453  * Removes the registry key with all subkeys. Parses full key name.
1454  *
1455  * Parameters:
1456  * reg_key_name - full name of registry branch to delete. Ignored if is NULL,
1457  * empty, points to register key class, does not exist.
1458  */
1459 void delete_registry_key(TCHAR* reg_key_name)
1460 {
1461  TCHAR* branch_name;
1462  DWORD branch_name_len;
1463  HKEY reg_key_class;
1464  HKEY branch_key;
1465 
1466  if (!reg_key_name || !reg_key_name[0]) {
1467  return;
1468  }
1469  /* open the specified key */
1470  reg_key_class = getRegClass(reg_key_name);
1471  if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) {
1472  _tprintf(_T("Incorrect registry class specification in '%s'\n"), reg_key_name);
1473  //exit(1);
1474  return;
1475  }
1476  branch_name = getRegKeyName(reg_key_name);
1477  CHECK_ENOUGH_MEMORY(branch_name);
1478  branch_name_len = _tcslen(branch_name);
1479  if (!branch_name[0]) {
1480  _tprintf(_T("Can't delete registry class '%s'\n"), reg_key_name);
1481  //exit(1);
1482  return;
1483  }
1484  if (RegOpenKey(reg_key_class, branch_name, &branch_key) == ERROR_SUCCESS) {
1485  /* check whether the key exists */
1486  RegCloseKey(branch_key);
1487  delete_branch(reg_key_class, &branch_name, &branch_name_len);
1488  }
1489  HeapFree(GetProcessHeap(), 0, branch_name);
1490 }
1491 
#define HKEY_USERS
Definition: winreg.h:13
void processRegLines(FILE *in, CommandAPI command)
Definition: regproc.c:887
#define RegQueryValueEx
Definition: winreg.h:524
static HKEY currentKeyHandle
Definition: regproc.c:71
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define isspace(c)
Definition: acclib.h:69
#define _tprintf
Definition: tchar.h:506
_Check_return_ _CRTIMP int __cdecl ferror(_In_ FILE *_File)
BOOL WINAPI OemToCharBuffW(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPWSTR lpszDst, _In_ DWORD cchDstLength)
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define RegQueryInfoKey
Definition: winreg.h:521
#define ERROR_SUCCESS
Definition: deptool.c:10
#define LoadLibrary
Definition: winbase.h:3686
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
void processSetValue(LPTSTR line)
Definition: regproc.c:716
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_BINARY
Definition: nt_native.h:1496
#define _fgettc
Definition: tchar.h:562
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char CHAR
Definition: xmlstorage.h:175
_TCHAR * _tcsncpy(_TCHAR *dst, const _TCHAR *src, size_t n)
Definition: tcsncpy.h:9
DWORD getDataType(LPTSTR *lpValue, DWORD *parse_type)
Definition: regproc.c:331
#define _fgetts
Definition: tchar.h:565
#define _stscanf
Definition: tchar.h:557
static LPTSTR currentKeyName
Definition: regproc.c:69
#define _fputts
Definition: tchar.h:569
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
void doSetValue(LPTSTR stdInput)
Definition: regproc.c:619
FILE * REGPROC_open_export_file(TCHAR *file_name)
Definition: regproc.c:1284
void processQueryValue(LPTSTR cmdline)
Definition: regproc.c:770
#define REG_FILE_HEX_LINE_LEN
Definition: regproc.c:66
GLuint GLuint end
Definition: gl.h:1545
TCHAR * cmdline
Definition: stretchblt.cpp:32
void export_hkey(FILE *file, HKEY key, TCHAR **reg_key_name_buf, DWORD *reg_key_name_len, TCHAR **val_name_buf, DWORD *val_name_len, BYTE **val_buf, DWORD *val_size)
Definition: regproc.c:1131
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
const char * filename
Definition: ioapi.h:135
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
CHAR * LPTSTR
Definition: xmlstorage.h:192
static HKEY reg_class_keys[REG_CLASS_NUMBER]
Definition: regproc.c:84
BOOL delete_branch(HKEY key, TCHAR **reg_key_name_buf, DWORD *reg_key_name_len)
Definition: regproc.c:1410
char * getToken(char **str, const char *delims)
void REGPROC_resize_char_buffer(TCHAR **buffer, DWORD *len, DWORD required_len)
Definition: regproc.c:1085
DWORD convertHexCSVToHex(TCHAR *str, BYTE *buf, ULONG bufLen)
Definition: regproc.c:289
void REGPROC_print_error(VOID)
Definition: regproc.c:1056
#define KEY_MAX_LEN
Definition: regproc.h:22
void doDeleteValue(LPTSTR line)
Definition: regproc.c:686
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
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 token
Definition: glfuncs.h:210
#define REG_VAL_BUF_SIZE
Definition: regproc.c:59
#define _MAX_PATH
Definition: utility.h:77
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static PVOID ptr
Definition: dispmode.c:27
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
static int error_code[8]
Definition: odbccp32.c:62
void doRegisterDLL(LPTSTR stdInput)
Definition: regproc.c:994
const WCHAR * str
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
Definition: parser.c:48
void doCreateKey(LPTSTR line)
Definition: regproc.c:704
void(* CommandAPI)(LPTSTR lpsLine)
Definition: regproc.h:29
GLuint counter
Definition: glext.h:11116
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
#define _ftprintf
Definition: tchar.h:518
#define QUERY_VALUE_MAX_ARGS
Definition: regproc.c:62
void doUnregisterDLL(LPTSTR stdInput)
Definition: regproc.c:1024
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static TCHAR * reg_class_names[]
Definition: regproc.c:74
char TCHAR
Definition: xmlstorage.h:189
#define CHECK_ENOUGH_MEMORY(p)
Definition: regproc.c:105
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
void doQueryValue(LPTSTR stdInput)
Definition: regproc.c:653
#define _tfopen
Definition: xmlstorage.h:196
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define _T(x)
Definition: vfdio.h:22
#define FreeLibrary(x)
Definition: compat.h:405
void get_file_nameW(CHAR **command_line, WCHAR *filename, int max_filename)
Definition: regproc.c:205
LPTSTR getRegKeyName(LPTSTR lpLine)
Definition: regproc.c:536
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
int convert
Definition: msacm.c:1362
TCHAR * convertHexToHexCSV(BYTE *buf, ULONG bufLen)
Definition: regproc.c:246
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _fputtc
Definition: tchar.h:566
LONG HRESULT
Definition: typedefs.h:77
const char file[]
Definition: icontest.c:11
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
static CHAR filenameA[MAX_PATH]
Definition: storage32.c:42
HRESULT openKey(LPTSTR stdInput)
Definition: regproc.c:494
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
#define FormatMessage
Definition: winbase.h:3619
int ret
static BOOL bTheKeyIsOpen
Definition: regproc.c:72
char line[200]
Definition: main.c:97
#define _tcstoul
Definition: tchar.h:595
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
HKEY key
Definition: reg.c:42
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
GLdouble s
Definition: gl.h:2039
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
void doDeleteKey(LPTSTR line)
Definition: regproc.c:695
#define RegEnumKeyEx
Definition: winreg.h:510
#define ERROR_MORE_DATA
Definition: dderror.h:13
int puts(const char *string)
Definition: crtsupp.c:23
LPTSTR getArg(LPTSTR arg)
Definition: regproc.c:377
void get_file_nameA(CHAR **command_line, CHAR *file_name, int max_filename)
Definition: regproc.c:160
#define _stprintf
Definition: utility.h:124
#define S_OK
Definition: intsafe.h:59
GLuint in
Definition: glext.h:9616
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define HeapReAlloc
Definition: compat.h:393
TCHAR * convertHexToDWORDStr(BYTE *buf, ULONG bufLen)
Definition: regproc.c:272
unsigned int UINT
Definition: ndis.h:50
#define _TEOF
Definition: regproc.c:117
BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name, DWORD format)
Definition: regproc.c:1310
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define RegDeleteKey
Definition: winreg.h:502
#define ERROR_REGISTRY_IO_FAILED
Definition: winerror.h:595
void REGPROC_export_string(FILE *file, TCHAR *str)
Definition: regproc.c:1098
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static LPCWSTR file_name
Definition: protocol.c:146
HKEY getRegClass(LPTSTR lpClass)
Definition: regproc.c:567
int command(const char *fmt,...)
Definition: ftp.c:266
_TCHAR * _tcscat(_TCHAR *s, const _TCHAR *append)
Definition: tcscat.h:8
GLuint res
Definition: glext.h:9613
#define RegQueryValue
Definition: winreg.h:523
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1405
#define GetProcAddress(x, y)
Definition: compat.h:410
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define REG_CLASS_NUMBER
Definition: regproc.c:82
#define REG_NONE
Definition: nt_native.h:1492
#define RegOpenKey
Definition: winreg.h:519
static HKEY currentKeyClass
Definition: regproc.c:70
#define memset(x, y, z)
Definition: compat.h:39
void closeKey(VOID)
Definition: regproc.c:604
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
#define HeapFree(x, y, z)
Definition: compat.h:394
#define RegEnumValue
Definition: winreg.h:511
#define RegSetValueEx
Definition: winreg.h:533
#define RegCreateKeyEx
Definition: winreg.h:501
int(* FARPROC)()
Definition: compat.h:28
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1432
struct task_struct * current
Definition: linux.c:32
HRESULT setValue(LPTSTR val_name, LPTSTR val_data)
Definition: regproc.c:432
DWORD convertHexToDWord(TCHAR *str, BYTE *buf)
Definition: regproc.c:231
Definition: path.c:42
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
Definition: fci.c:126
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97
char * tag
Definition: main.c:59
void REGPROC_unescape_string(LPTSTR str)
Definition: regproc.c:396