ReactOS 0.4.15-dev-7924-g5949c20
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 */
73
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 */
125char* 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 */
160void 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
205void 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);
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 */
432HRESULT 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;
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 */
619void 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 */
653void 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 */
994void 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 */
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;
1060 int status;
1061
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) {
1356 &reg_key_name_buf, &reg_key_name_len,
1357 &val_name_buf, &val_name_len,
1358 &val_buf, &val_size);
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 */
1410BOOL 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,
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 */
1459void 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 isspace(c)
Definition: acclib.h:69
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define KEY_MAX_LEN
Definition: main.h:42
#define REG_VAL_BUF_SIZE
Definition: regproc.c:38
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1054
static HKEY reg_class_keys[]
Definition: regproc.c:40
static BOOL REGPROC_unescape_string(WCHAR *str, WCHAR **unparsed)
Definition: regproc.c:365
static FILE * REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
Definition: regproc.c:1465
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1579
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1102
#define RegCloseKey(hKey)
Definition: registry.h:49
int puts(const char *string)
Definition: crtsupp.c:23
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
int(* FARPROC)()
Definition: compat.h:36
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLenum GLsizei len
Definition: glext.h:6722
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
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_Check_return_ _CRTIMP int __cdecl ferror(_In_ FILE *_File)
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define _stscanf
Definition: tchar.h:557
#define _fputts
Definition: tchar.h:569
#define _tcscmp
Definition: tchar.h:1424
#define _tcscat
Definition: tchar.h:622
#define _tcscpy
Definition: tchar.h:623
#define _tcsncpy
Definition: tchar.h:1410
#define _tcstoul
Definition: tchar.h:595
#define _fgettc
Definition: tchar.h:562
#define _fgetts
Definition: tchar.h:565
#define _fputtc
Definition: tchar.h:566
#define _ftprintf
Definition: tchar.h:518
#define _tprintf
Definition: tchar.h:506
#define _tcschr
Definition: tchar.h:1406
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define S_OK
Definition: intsafe.h:52
const char * filename
Definition: ioapi.h:137
#define c
Definition: ke_i.h:80
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
#define _stprintf
Definition: utility.h:124
#define _MAX_PATH
Definition: utility.h:77
static PVOID ptr
Definition: dispmode.c:27
void doRegisterDLL(LPTSTR stdInput)
Definition: regproc.c:994
void closeKey(VOID)
Definition: regproc.c:604
static TCHAR * reg_class_names[]
Definition: regproc.c:74
LPTSTR getRegKeyName(LPTSTR lpLine)
Definition: regproc.c:536
TCHAR * convertHexToDWORDStr(BYTE *buf, ULONG bufLen)
Definition: regproc.c:272
void processQueryValue(LPTSTR cmdline)
Definition: regproc.c:770
void doSetValue(LPTSTR stdInput)
Definition: regproc.c:619
static HKEY currentKeyHandle
Definition: regproc.c:71
void processSetValue(LPTSTR line)
Definition: regproc.c:716
void REGPROC_export_string(FILE *file, TCHAR *str)
Definition: regproc.c:1098
HRESULT openKey(LPTSTR stdInput)
Definition: regproc.c:494
BOOL delete_branch(HKEY key, TCHAR **reg_key_name_buf, DWORD *reg_key_name_len)
Definition: regproc.c:1410
#define REG_FILE_HEX_LINE_LEN
Definition: regproc.c:66
static HKEY currentKeyClass
Definition: regproc.c:70
static BOOL bTheKeyIsOpen
Definition: regproc.c:72
HRESULT setValue(LPTSTR val_name, LPTSTR val_data)
Definition: regproc.c:432
DWORD getDataType(LPTSTR *lpValue, DWORD *parse_type)
Definition: regproc.c:331
#define QUERY_VALUE_MAX_ARGS
Definition: regproc.c:62
void REGPROC_resize_char_buffer(TCHAR **buffer, DWORD *len, DWORD required_len)
Definition: regproc.c:1085
static LPTSTR currentKeyName
Definition: regproc.c:69
void REGPROC_print_error(VOID)
Definition: regproc.c:1056
void doDeleteValue(LPTSTR line)
Definition: regproc.c:686
void doQueryValue(LPTSTR stdInput)
Definition: regproc.c:653
TCHAR * convertHexToHexCSV(BYTE *buf, ULONG bufLen)
Definition: regproc.c:246
DWORD convertHexToDWord(TCHAR *str, BYTE *buf)
Definition: regproc.c:231
void doDeleteKey(LPTSTR line)
Definition: regproc.c:695
void doUnregisterDLL(LPTSTR stdInput)
Definition: regproc.c:1024
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 _TEOF
Definition: regproc.c:117
DWORD convertHexCSVToHex(TCHAR *str, BYTE *buf, ULONG bufLen)
Definition: regproc.c:289
HKEY getRegClass(LPTSTR lpClass)
Definition: regproc.c:567
void get_file_nameA(CHAR **command_line, CHAR *file_name, int max_filename)
Definition: regproc.c:160
#define CHECK_ENOUGH_MEMORY(p)
Definition: regproc.c:105
LPTSTR getArg(LPTSTR arg)
Definition: regproc.c:377
void processRegLines(FILE *in, CommandAPI command)
Definition: regproc.c:887
#define REG_CLASS_NUMBER
Definition: regproc.c:82
void doCreateKey(LPTSTR line)
Definition: regproc.c:704
void get_file_nameW(CHAR **command_line, WCHAR *filename, int max_filename)
Definition: regproc.c:205
static CHAR filenameA[MAX_PATH]
Definition: storage32.c:42
static LPCWSTR file_name
Definition: protocol.c:147
#define argv
Definition: mplay32.c:18
int convert
Definition: msacm.c:1374
unsigned int UINT
Definition: ndis.h:50
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
long LONG
Definition: pedump.c:60
void(* CommandAPI)(LPTSTR lpsLine)
Definition: regproc.h:29
char * getToken(char **str, const char *delims)
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
UCHAR byteCount
Definition: scsi.h:3709
#define memset(x, y, z)
Definition: compat.h:39
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: fci.c:127
Definition: copy.c:22
Definition: parser.c:49
Definition: ps.c:97
Definition: ecma_167.h:138
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define _T(x)
Definition: vfdio.h:22
int ret
static int error_code[8]
Definition: odbccp32.c:61
#define FormatMessage
Definition: winbase.h:3795
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LoadLibrary
Definition: winbase.h:3862
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define ERROR_REGISTRY_IO_FAILED
Definition: winerror.h:595
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RegSetValueEx
Definition: winreg.h:533
#define RegCreateKeyEx
Definition: winreg.h:501
#define RegQueryValueEx
Definition: winreg.h:524
#define RegDeleteKey
Definition: winreg.h:502
#define RegOpenKey
Definition: winreg.h:519
#define RegEnumValue
Definition: winreg.h:511
#define RegQueryValue
Definition: winreg.h:523
#define RegEnumKeyEx
Definition: winreg.h:510
#define RegQueryInfoKey
Definition: winreg.h:521
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
BOOL WINAPI OemToCharBuffW(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPWSTR lpszDst, _In_ DWORD cchDstLength)
char TCHAR
Definition: xmlstorage.h:189
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _tfopen
Definition: xmlstorage.h:196
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193