Alexander Nicolaysen Sørnes : regedit: Add support for importing Unicode files.
Alexandre Julliard
julliard at winehq.org
Thu Jul 10 14:07:24 CDT 2008
Module: wine
Branch: master
Commit: 6f2e3e1b1ecce90f98d6e84170a3185a28661d1d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6f2e3e1b1ecce90f98d6e84170a3185a28661d1d
Author: Alexander Nicolaysen Sørnes <alex at thehandofagony.com>
Date: Wed Jul 9 23:39:08 2008 +0200
regedit: Add support for importing Unicode files.
---
programs/regedit/framewnd.c | 12 +++-
programs/regedit/regedit.c | 2 +-
programs/regedit/regproc.c | 164 ++++++++++++++++++++++++++++++++++--------
programs/regedit/regproc.h | 3 +-
4 files changed, 145 insertions(+), 36 deletions(-)
diff --git a/programs/regedit/framewnd.c b/programs/regedit/framewnd.c
index fd20a62..4bf78af 100644
--- a/programs/regedit/framewnd.c
+++ b/programs/regedit/framewnd.c
@@ -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;
}
diff --git a/programs/regedit/regedit.c b/programs/regedit/regedit.c
index 8c473e6..8e7136b 100644
--- a/programs/regedit/regedit.c
+++ b/programs/regedit/regedit.c
@@ -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);
diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index a42ee5c..2f8b826 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -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;
diff --git a/programs/regedit/regproc.h b/programs/regedit/regproc.h
index d1725b1..0621d8b 100644
--- a/programs/regedit/regproc.h
+++ b/programs/regedit/regproc.h
@@ -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);
More information about the wine-cvs
mailing list