regedit: Gather a full string before exporting it.

This commit is contained in:
Alexander Nicolaysen Sørnes 2008-09-12 00:54:02 +02:00 committed by Alexandre Julliard
parent 16d2a46bc5
commit 60cd910797

View File

@ -878,30 +878,62 @@ static void REGPROC_resize_char_buffer(WCHAR **buffer, DWORD *len, DWORD require
/****************************************************************************** /******************************************************************************
* Prints string str to file * Prints string str to file
*/ */
static void REGPROC_export_string(FILE *file, WCHAR *str) static void REGPROC_export_string(WCHAR **line_buf, DWORD *line_buf_size, DWORD *line_size, WCHAR *str)
{ {
CHAR* strA = GetMultiByteString(str); DWORD len = lstrlenW(str);
size_t len = strlen(strA); DWORD i;
size_t i; DWORD extra = 0;
REGPROC_resize_char_buffer(line_buf, line_buf_size, len + 10);
/* escaping characters */ /* escaping characters */
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
CHAR c = str[i]; WCHAR c = str[i];
switch (c) { switch (c) {
case '\\': case '\\':
fputs("\\\\", file); {
break; const WCHAR escape[] = {'\\','\\'};
case '\"':
fputs("\\\"", file); extra++;
break; REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra);
case '\n': memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR));
fputs("\\\n", file);
break;
default:
fputc(c, file);
break; break;
} }
case '\"':
{
const WCHAR escape[] = {'\\','"'};
extra++;
REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra);
memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR));
break;
}
case '\n':
{
const WCHAR escape[] = {'\\','\n'};
extra++;
REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra);
memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR));
break;
}
default:
memcpy(*line_buf + *line_size - 1, &c, sizeof(WCHAR));
break;
}
*line_size += 1;
} }
*(*line_buf + *line_size - 1) = 0;
*line_size += extra;
}
/******************************************************************************
* Writes the given line to a file, in multi-byte or wide characters
*/
static void REGPROC_write_line(FILE *file, const WCHAR* str)
{
char* strA = GetMultiByteString(str);
fprintf(file, strA);
HeapFree(GetProcessHeap(), 0, strA); HeapFree(GetProcessHeap(), 0, strA);
} }
@ -924,7 +956,8 @@ static void REGPROC_export_string(FILE *file, WCHAR *str)
static void export_hkey(FILE *file, HKEY key, static void export_hkey(FILE *file, HKEY key,
WCHAR **reg_key_name_buf, DWORD *reg_key_name_len, WCHAR **reg_key_name_buf, DWORD *reg_key_name_len,
WCHAR **val_name_buf, DWORD *val_name_len, WCHAR **val_name_buf, DWORD *val_name_len,
BYTE **val_buf, DWORD *val_size) BYTE **val_buf, DWORD *val_size,
WCHAR **line_buf, DWORD *line_buf_size)
{ {
DWORD max_sub_key_len; DWORD max_sub_key_len;
DWORD max_val_name_len; DWORD max_val_name_len;
@ -933,7 +966,8 @@ static void export_hkey(FILE *file, HKEY key,
DWORD i; DWORD i;
BOOL more_data; BOOL more_data;
LONG ret; LONG ret;
CHAR* bufA; WCHAR key_format[] = {'\n','[','%','s',']','\n',0};
DWORD line_pos;
/* get size information and resize the buffers if necessary */ /* get size information and resize the buffers if necessary */
if (RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, if (RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL,
@ -954,12 +988,11 @@ static void export_hkey(FILE *file, HKEY key,
CHECK_ENOUGH_MEMORY(val_buf); CHECK_ENOUGH_MEMORY(val_buf);
} }
REGPROC_resize_char_buffer(line_buf, line_buf_size, lstrlenW(*reg_key_name_buf) + 4);
/* output data for the current key */ /* output data for the current key */
fputs("\n[", file); wsprintfW(*line_buf, key_format, *reg_key_name_buf);
bufA = GetMultiByteString(*reg_key_name_buf); REGPROC_write_line(file, *line_buf);
fputs(bufA, file);
HeapFree(GetProcessHeap(), 0, bufA);
fputs("]\n", file);
/* print all the values */ /* print all the values */
i = 0; i = 0;
more_data = TRUE; more_data = TRUE;
@ -967,6 +1000,7 @@ static void export_hkey(FILE *file, HKEY key,
DWORD value_type; DWORD value_type;
DWORD val_name_len1 = *val_name_len; DWORD val_name_len1 = *val_name_len;
DWORD val_size1 = *val_size; DWORD val_size1 = *val_size;
DWORD line_size = 0;
ret = RegEnumValueW(key, i, *val_name_buf, &val_name_len1, NULL, ret = RegEnumValueW(key, i, *val_name_buf, &val_name_len1, NULL,
&value_type, *val_buf, &val_size1); &value_type, *val_buf, &val_size1);
if (ret != ERROR_SUCCESS) { if (ret != ERROR_SUCCESS) {
@ -978,24 +1012,48 @@ static void export_hkey(FILE *file, HKEY key,
i++; i++;
if ((*val_name_buf)[0]) { if ((*val_name_buf)[0]) {
fputs("\"", file); const WCHAR val_start[] = {'"','%','s','"','=',0};
REGPROC_export_string(file, *val_name_buf);
fputs("\"=", file); line_size = 4 + lstrlenW(*val_name_buf);
REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
wsprintfW(*line_buf, val_start, *val_name_buf);
line_pos = lstrlenW(*line_buf);
} else { } else {
fputs("@=", file); const WCHAR std_val[] = {'@','=',0};
line_size = 3;
REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
lstrcpyW(*line_buf, std_val);
line_pos = lstrlenW(*line_buf);
} }
switch (value_type) { switch (value_type) {
case REG_SZ: case REG_SZ:
case REG_EXPAND_SZ: case REG_EXPAND_SZ:
fputs("\"", file); {
if (val_size1) REGPROC_export_string(file, (WCHAR*) *val_buf); const WCHAR start[] = {'"',0};
fputs("\"\n", file); const WCHAR end[] = {'"','\n',0};
line_size += lstrlenW(start);
REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
lstrcatW(*line_buf, start);
if (val_size1) REGPROC_export_string(line_buf, line_buf_size, &line_size, (WCHAR*) *val_buf);
line_size += lstrlenW(end);
REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
lstrcatW(*line_buf, end);
break; break;
}
case REG_DWORD: case REG_DWORD:
fprintf(file, "dword:%08x\n", *((DWORD *)*val_buf)); {
WCHAR format[] = {'d','w','o','r','d',':','%','0','8','x','\n',0};
line_size += 20;
REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
wsprintfW(*line_buf + line_pos, format, *((DWORD *)*val_buf));
break; break;
}
default: default:
fprintf(stderr,"%s: warning - unsupported registry format '%d', " fprintf(stderr,"%s: warning - unsupported registry format '%d', "
@ -1013,7 +1071,10 @@ static void export_hkey(FILE *file, HKEY key,
int cur_pos; int cur_pos;
const WCHAR hex[] = {'h','e','x',':',0}; const WCHAR hex[] = {'h','e','x',':',0};
const WCHAR delim[] = {'"','"','=',0}; const WCHAR delim[] = {'"','"','=',0};
CHAR* hex_prefixA; const WCHAR format[] = {'%','0','2','x',0};
const WCHAR comma[] = {',',0};
const WCHAR concat[] = {'\\','\n',' ',' ',0};
const WCHAR newline[] = {'\n',0};
BYTE* val_buf1 = *val_buf; BYTE* val_buf1 = *val_buf;
DWORD val_buf1_size = val_size1; DWORD val_buf1_size = val_size1;
@ -1032,28 +1093,34 @@ static void export_hkey(FILE *file, HKEY key,
cur_pos = lstrlenW(delim) + lstrlenW(hex) + cur_pos = lstrlenW(delim) + lstrlenW(hex) +
lstrlenW(*val_name_buf); lstrlenW(*val_name_buf);
hex_prefixA = GetMultiByteString(hex_prefix); line_size += lstrlenW(hex_prefix);
fputs(hex_prefixA, file); line_size += val_buf1_size * 3 + lstrlenW(concat) * ((int)((float)val_buf1_size * 3.0 / (float)REG_FILE_HEX_LINE_LEN) + 1 ) + 1;
HeapFree(GetProcessHeap(), 0, hex_prefixA); REGPROC_resize_char_buffer(line_buf, line_buf_size, line_size);
lstrcatW(*line_buf, hex_prefix);
line_pos += lstrlenW(hex_prefix);
for (i1 = 0; i1 < val_buf1_size; i1++) { for (i1 = 0; i1 < val_buf1_size; i1++) {
fprintf(file, "%02x", (unsigned int)(val_buf1)[i1]); wsprintfW(*line_buf + line_pos, format, (unsigned int)(val_buf1)[i1]);
line_pos += 2;
if (i1 + 1 < val_buf1_size) { if (i1 + 1 < val_buf1_size) {
fputs(",", file); lstrcpyW(*line_buf + line_pos, comma);
line_pos++;
} }
cur_pos += 3; cur_pos += 3;
/* wrap the line */ /* wrap the line */
if (cur_pos > REG_FILE_HEX_LINE_LEN) { if (cur_pos > REG_FILE_HEX_LINE_LEN) {
fputs("\\\n ", file); lstrcpyW(*line_buf + line_pos, concat);
line_pos += lstrlenW(concat);
cur_pos = 2; cur_pos = 2;
} }
} }
if(value_type == REG_MULTI_SZ) if(value_type == REG_MULTI_SZ)
HeapFree(GetProcessHeap(), 0, val_buf1); HeapFree(GetProcessHeap(), 0, val_buf1);
fputs("\n", file); lstrcpyW(*line_buf + line_pos, newline);
break; break;
} }
} }
REGPROC_write_line(file, *line_buf);
} }
} }
@ -1077,7 +1144,8 @@ static void export_hkey(FILE *file, HKEY key,
if (RegOpenKeyW(key, *reg_key_name_buf + curr_len + 1, if (RegOpenKeyW(key, *reg_key_name_buf + curr_len + 1,
&subkey) == ERROR_SUCCESS) { &subkey) == ERROR_SUCCESS) {
export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len, export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len,
val_name_buf, val_name_len, val_buf, val_size); val_name_buf, val_name_len, val_buf, val_size,
line_buf, line_buf_size);
RegCloseKey(subkey); RegCloseKey(subkey);
} else { } else {
REGPROC_print_error(); REGPROC_print_error();
@ -1126,9 +1194,11 @@ BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name)
WCHAR *reg_key_name_buf; WCHAR *reg_key_name_buf;
WCHAR *val_name_buf; WCHAR *val_name_buf;
BYTE *val_buf; BYTE *val_buf;
WCHAR *line_buf;
DWORD reg_key_name_len = KEY_MAX_LEN; DWORD reg_key_name_len = KEY_MAX_LEN;
DWORD val_name_len = KEY_MAX_LEN; DWORD val_name_len = KEY_MAX_LEN;
DWORD val_size = REG_VAL_BUF_SIZE; DWORD val_size = REG_VAL_BUF_SIZE;
DWORD line_buf_size = KEY_MAX_LEN + REG_VAL_BUF_SIZE;
FILE *file = NULL; FILE *file = NULL;
reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0,
@ -1136,6 +1206,7 @@ BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name)
val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_buf = HeapAlloc(GetProcessHeap(), 0,
val_name_len * sizeof(*val_name_buf)); val_name_len * sizeof(*val_name_buf));
val_buf = HeapAlloc(GetProcessHeap(), 0, val_size); val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
line_buf = HeapAlloc(GetProcessHeap(), 0, line_buf_size);
CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf); CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf);
if (reg_key_name && reg_key_name[0]) { if (reg_key_name && reg_key_name[0]) {
@ -1161,13 +1232,13 @@ BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name)
export_hkey(file, reg_key_class, export_hkey(file, reg_key_class,
&reg_key_name_buf, &reg_key_name_len, &reg_key_name_buf, &reg_key_name_len,
&val_name_buf, &val_name_len, &val_name_buf, &val_name_len,
&val_buf, &val_size); &val_buf, &val_size, &line_buf, &line_buf_size);
} else if (RegOpenKeyW(reg_key_class, branch_name, &key) == ERROR_SUCCESS) { } else if (RegOpenKeyW(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
file = REGPROC_open_export_file(file_name); file = REGPROC_open_export_file(file_name);
export_hkey(file, key, export_hkey(file, key,
&reg_key_name_buf, &reg_key_name_len, &reg_key_name_buf, &reg_key_name_len,
&val_name_buf, &val_name_len, &val_name_buf, &val_name_len,
&val_buf, &val_size); &val_buf, &val_size, &line_buf, &line_buf_size);
RegCloseKey(key); RegCloseKey(key);
} else { } else {
CHAR* key_nameA = GetMultiByteString(reg_key_name); CHAR* key_nameA = GetMultiByteString(reg_key_name);
@ -1191,7 +1262,7 @@ BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name)
export_hkey(file, reg_class_keys[i], export_hkey(file, reg_class_keys[i],
&reg_key_name_buf, &reg_key_name_len, &reg_key_name_buf, &reg_key_name_len,
&val_name_buf, &val_name_len, &val_name_buf, &val_name_len,
&val_buf, &val_size); &val_buf, &val_size, &line_buf, &line_buf_size);
} }
} }
} }
@ -1202,6 +1273,7 @@ BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name)
HeapFree(GetProcessHeap(), 0, reg_key_name); HeapFree(GetProcessHeap(), 0, reg_key_name);
HeapFree(GetProcessHeap(), 0, val_name_buf); HeapFree(GetProcessHeap(), 0, val_name_buf);
HeapFree(GetProcessHeap(), 0, val_buf); HeapFree(GetProcessHeap(), 0, val_buf);
HeapFree(GetProcessHeap(), 0, line_buf);
return TRUE; return TRUE;
} }