Commit 6f2e3e1b authored by Alexander Nicolaysen Sørnes's avatar Alexander Nicolaysen Sørnes Committed by Alexandre Julliard

regedit: Add support for importing Unicode files.

parent 9d608490
......@@ -311,6 +311,16 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME *pofn)
return TRUE;
}
static BOOL import_registry_filename(LPTSTR filename)
{
FILE* reg_file = fopen(filename, "r");
if(!reg_file)
return FALSE;
return import_registry_file(reg_file);
}
static BOOL ImportRegistryFile(HWND hWnd)
{
OPENFILENAME ofn;
......@@ -320,7 +330,7 @@ static BOOL ImportRegistryFile(HWND hWnd)
LoadString(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
ofn.lpstrTitle = title;
if (GetOpenFileName(&ofn)) {
if (!import_registry_file(ofn.lpstrFile)) {
if (!import_registry_filename(ofn.lpstrFile)) {
/*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
return FALSE;
}
......
......@@ -167,7 +167,7 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
exit(1);
}
}
processRegLines(reg_file);
import_registry_file(reg_file);
if (realname)
{
HeapFree(GetProcessHeap(),0,realname);
......
......@@ -594,11 +594,10 @@ static void processRegEntry(WCHAR* stdInput)
* Parameters:
* in - input stream to read from
*/
void processRegLines(FILE *in)
void processRegLinesA(FILE *in)
{
LPSTR line = NULL; /* line read from input stream */
ULONG lineSize = REG_VAL_BUF_SIZE;
BOOL unicode_check = TRUE;
line = HeapAlloc(GetProcessHeap(), 0, lineSize);
CHECK_ENOUGH_MEMORY(line);
......@@ -636,31 +635,7 @@ void processRegLines(FILE *in)
*/
size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining);
if (unicode_check)
{
if (fread( s, 2, 1, in) == 1)
{
if ((BYTE)s[0] == 0xff && (BYTE)s[1] == 0xfe)
{
printf("Trying to import from a unicode file: this isn't supported yet.\n"
"Please use export as Win 9x/NT4 files from native regedit\n");
HeapFree(GetProcessHeap(), 0, line);
return;
}
else
{
unicode_check = FALSE;
check = fgets (&s[2], size_to_get-2, in);
}
}
else
{
unicode_check = FALSE;
check = NULL;
}
}
else
check = fgets (s, size_to_get, in);
check = fgets (s, size_to_get, in);
if (check == NULL) {
if (ferror(in)) {
......@@ -725,6 +700,119 @@ void processRegLines(FILE *in)
HeapFree(GetProcessHeap(), 0, line);
}
void processRegLinesW(FILE *in)
{
WCHAR* buf = NULL; /* line read from input stream */
ULONG lineSize = REG_VAL_BUF_SIZE;
size_t check = -1;
WCHAR* s; /* The pointer into line for where the current fgets should read */
int i;
buf = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(WCHAR));
CHECK_ENOUGH_MEMORY(buf);
s = buf;
while(!feof(in)) {
size_t size_remaining;
int size_to_get;
WCHAR *s_eol = NULL; /* various local uses */
/* Do we need to expand the buffer ? */
assert (s >= buf && s <= buf + lineSize);
size_remaining = lineSize - (s-buf);
if (size_remaining < 2) /* room for 1 character and the \0 */
{
WCHAR *new_buffer;
size_t new_size = lineSize + (REG_VAL_BUF_SIZE / sizeof(WCHAR));
if (new_size > lineSize) /* no arithmetic overflow */
new_buffer = HeapReAlloc (GetProcessHeap(), 0, buf, new_size * sizeof(WCHAR));
else
new_buffer = NULL;
CHECK_ENOUGH_MEMORY(new_buffer);
buf = new_buffer;
s = buf + lineSize - size_remaining;
lineSize = new_size;
size_remaining = lineSize - (s-buf);
}
/* Get as much as possible into the buffer, terminated either by
* eof, error, eol or getting the maximum amount. Abort on error.
*/
size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining);
check = fread(s, sizeof(WCHAR), size_to_get, in);
if (check == 0) {
if (ferror(in)) {
perror ("While reading input");
exit (IO_ERROR);
} else {
assert (feof(in));
*s = '\0';
/* It is not clear to me from the definition that the
* contents of the buffer are well defined on detecting
* an eof without managing to read anything.
*/
}
}
/* If we didn't read the eol nor the eof go around for the rest */
while(1)
{
for(i = 0; s[i] != 0; i++)
{
if(s[i] == '\n')
{
s_eol = &s[i];
break;
}
}
/* If it is a comment line then discard it and go around again */
if (buf[0] == '#') {
s = buf;
continue;
}
/* Remove any line feed. Leave s_eol on the \0 */
if (s_eol) {
*s_eol = '\0';
if (s_eol > buf && *(s_eol-1) == '\r')
*(s_eol-1) = '\0';
}
/* If there is a concatenating \\ then go around again */
if (s_eol > buf && *(s_eol-1) == '\\') {
WCHAR c[2];
s = s_eol+1;
/* The following error protection could be made more self-
* correcting but I thought it not worth trying.
*/
if(!fread(&c, sizeof(WCHAR), 2, in))
break;
if (feof(in) || c[0] != ' ' || c[1] != ' ')
fprintf(stderr,"%s: ERROR - invalid continuation.\n",
getAppName());
continue;
}
if(!s_eol)
break;
processRegEntry(s);
s = s_eol + 1;
s_eol = 0;
continue; /* That is the full virtual line */
}
}
processRegEntry(NULL);
HeapFree(GetProcessHeap(), 0, buf);
}
/****************************************************************************
* REGPROC_print_error
*
......@@ -1080,12 +1168,24 @@ BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name)
/******************************************************************************
* Reads contents of the specified file into the registry.
*/
BOOL import_registry_file(LPTSTR filename)
BOOL import_registry_file(FILE* reg_file)
{
FILE* reg_file = fopen(filename, "r");
if (reg_file) {
processRegLines(reg_file);
if (reg_file)
{
BYTE s[2];
if (fread( s, 2, 1, reg_file) == 1)
{
if (s[0] == 0xff && s[1] == 0xfe)
{
printf("Trying to open unicode file\n");
processRegLinesW(reg_file);
} else
{
printf("ansi file\n");
rewind(reg_file);
processRegLinesA(reg_file);
}
}
return TRUE;
}
return FALSE;
......
......@@ -22,7 +22,6 @@
const CHAR *getAppName(void);
BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name);
BOOL import_registry_file(LPTSTR filename);
BOOL import_registry_file(FILE *in);
void delete_registry_key(WCHAR *reg_key_name);
WCHAR* GetWideString(const char* strA);
void processRegLines(FILE *in);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment