Support Large Profile Values Try2

Robert Shearman rob at codeweavers.com
Tue Jul 13 13:53:15 CDT 2004


Robert Shearman wrote:

> Hi,
>
> As per Alexandre's comments, don't use snprintfW for just 
> concatenating strings.
>
> Rob
>
> Changelog:
> Support large profile values. 

This time with the right patch.

-------------- next part --------------
Index: wine/dlls/kernel/profile.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/profile.c,v
retrieving revision 1.12
diff -u -r1.12 profile.c
--- wine/dlls/kernel/profile.c	14 Jun 2004 17:04:35 -0000	1.12
+++ wine/dlls/kernel/profile.c	13 Jul 2004 18:25:23 -0000
@@ -81,8 +81,6 @@
 
 #define CurProfile (MRUProfile[0])
 
-#define PROFILE_MAX_LINE_LEN   1024
-
 /* Check for comments in profile */
 #define IS_ENTRY_COMMENT(str)  ((str)[0] == ';')
 
@@ -156,7 +154,8 @@
 
 static void PROFILE_WriteLine( HANDLE hFile, WCHAR * szLine, int len, ENCODING encoding)
 {
-    char write_buffer[PROFILE_MAX_LINE_LEN];
+    char * write_buffer;
+    int write_buffer_len;
     DWORD dwBytesWritten;
 
     TRACE("writing: %s\n", debugstr_wn(szLine, len));
@@ -164,12 +163,20 @@
     switch (encoding)
     {
     case ENCODING_ANSI:
-        len = WideCharToMultiByte(CP_ACP, 0, szLine, len, write_buffer, sizeof(write_buffer), NULL, NULL);
-        WriteFile(hFile, write_buffer, len * sizeof(char), &dwBytesWritten, NULL);
+        write_buffer_len = WideCharToMultiByte(CP_ACP, 0, szLine, len, NULL, 0, NULL, NULL);
+        write_buffer = HeapAlloc(GetProcessHeap(), 0, write_buffer_len);
+        if (!write_buffer) return;
+        len = WideCharToMultiByte(CP_ACP, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
+        WriteFile(hFile, write_buffer, len, &dwBytesWritten, NULL);
+        HeapFree(GetProcessHeap(), 0, write_buffer);
         break;
     case ENCODING_UTF8:
-        len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, write_buffer, sizeof(write_buffer), NULL, NULL);
-        WriteFile(hFile, write_buffer, len * sizeof(char), &dwBytesWritten, NULL);
+        write_buffer_len = WideCharToMultiByte(CP_ACP, 0, szLine, len, NULL, 0, NULL, NULL);
+        write_buffer = HeapAlloc(GetProcessHeap(), 0, write_buffer_len);
+        if (!write_buffer) return;
+        len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
+        WriteFile(hFile, write_buffer, len, &dwBytesWritten, NULL);
+        HeapFree(GetProcessHeap(), 0, write_buffer);
         break;
     case ENCODING_UTF16LE:
         WriteFile(hFile, szLine, len * sizeof(WCHAR), &dwBytesWritten, NULL);
@@ -183,40 +190,95 @@
     }
 }
 
+static inline int multistrcatW_len2(const WCHAR * str1, const WCHAR * str2)
+{
+    return strlenW(str1)+strlenW(str2);
+}
+
+static inline void multistrcatW2(WCHAR * buffer, const WCHAR * str1, const WCHAR * str2)
+{
+    memcpy(buffer, str1, (strlenW(str1)+1)*sizeof(WCHAR));
+    buffer += strlenW(str1);
+    memcpy(buffer, str2, (strlenW(str2)+1)*sizeof(WCHAR));
+}
+
+static inline int multistrcatW_len4(const WCHAR * str1, const WCHAR * str2, const WCHAR * str3, const WCHAR * str4)
+{
+    return strlenW(str1)+strlenW(str2)+strlenW(str3)+strlenW(str4);
+}
+
+static inline void multistrcatW4(WCHAR * buffer, const WCHAR * str1, const WCHAR * str2, const WCHAR * str3, const WCHAR * str4)
+{
+    memcpy(buffer, str1, (strlenW(str1)+1)*sizeof(WCHAR));
+    buffer += strlenW(str1);
+    memcpy(buffer, str2, (strlenW(str2)+1)*sizeof(WCHAR));
+    buffer += strlenW(str2);
+    memcpy(buffer, str3, (strlenW(str3)+1)*sizeof(WCHAR));
+    buffer += strlenW(str3);
+    memcpy(buffer, str4, (strlenW(str4)+1)*sizeof(WCHAR));
+}
+
+static inline int multistrcatW_len5(const WCHAR * str1, const WCHAR * str2, const WCHAR * str3, const WCHAR * str4, const WCHAR * str5)
+{
+    return strlenW(str1)+strlenW(str2)+strlenW(str3)+strlenW(str4)+strlenW(str5);
+}
+
+static inline void multistrcatW5(WCHAR * buffer, const WCHAR * str1, const WCHAR * str2, const WCHAR * str3, const WCHAR * str4, const WCHAR * str5)
+{
+    memcpy(buffer, str1, (strlenW(str1)+1)*sizeof(WCHAR));
+    buffer += strlenW(str1);
+    memcpy(buffer, str2, (strlenW(str2)+1)*sizeof(WCHAR));
+    buffer += strlenW(str2);
+    memcpy(buffer, str3, (strlenW(str3)+1)*sizeof(WCHAR));
+    buffer += strlenW(str3);
+    memcpy(buffer, str4, (strlenW(str4)+1)*sizeof(WCHAR));
+    buffer += strlenW(str4);
+    memcpy(buffer, str5, (strlenW(str5)+1)*sizeof(WCHAR));
+}
+
 /***********************************************************************
  *           PROFILE_Save
  *
  * Save a profile tree to a file.
  */
-static void PROFILE_Save( HANDLE hFile, PROFILESECTION *section, ENCODING encoding )
+static void PROFILE_Save( HANDLE hFile, const PROFILESECTION *section, ENCODING encoding )
 {
-    static const WCHAR wSectionFormat[] = {'\r','\n','[','%','s',']','\r','\n',0};
-    static const WCHAR wNameFormat[] = {'%','s',0};
-    static const WCHAR wValueFormat[] = {'=','%','s',0};
+    static const WCHAR wEquals[] = {'=',0};
     static const WCHAR wNewLine[] = {'\r','\n',0};
+    static const WCHAR wLSquareBracket[] = {'[',0};
+    static const WCHAR wRSquareBracket[] = {']',0};
     PROFILEKEY *key;
-    WCHAR szLine[PROFILE_MAX_LINE_LEN];
+    WCHAR * szLine;
     int len = 0;
-    
+
     PROFILE_WriteMarker(hFile, encoding);
 
     for ( ; section; section = section->next)
     {
         if (section->name[0])
         {
-            len += snprintfW( szLine + len, PROFILE_MAX_LINE_LEN - len, wSectionFormat, section->name );
+            len = multistrcatW_len5(wNewLine, wLSquareBracket, section->name, wRSquareBracket, wNewLine);
+            szLine = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+            if (!szLine) return;
+            multistrcatW5(szLine, wNewLine, wLSquareBracket, section->name, wRSquareBracket, wNewLine);
             PROFILE_WriteLine( hFile, szLine, len, encoding );
-            len = 0;
+            HeapFree(GetProcessHeap(), 0, szLine);
        }
 
         for (key = section->key; key; key = key->next)
         {
-            len += snprintfW( szLine + len, PROFILE_MAX_LINE_LEN - len, wNameFormat, key->name );
             if (key->value)
-                 len += snprintfW( szLine + len, PROFILE_MAX_LINE_LEN - len, wValueFormat, key->value );
-            len += snprintfW( szLine + len, PROFILE_MAX_LINE_LEN - len, wNewLine );
+                len = multistrcatW_len4(key->name, wEquals, key->value, wNewLine);
+            else
+                len = multistrcatW_len2(key->name, wNewLine);
+            szLine = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+            if (!szLine) return;
+            if (key->value)
+                multistrcatW4(szLine, key->name, wEquals, key->value, wNewLine);
+            else
+                multistrcatW2(szLine, key->name, wNewLine);
             PROFILE_WriteLine( hFile, szLine, len, encoding );
-            len = 0;
+            HeapFree(GetProcessHeap(), 0, szLine);
         }
     }
 }
@@ -703,6 +765,7 @@
     FILETIME LastWriteTime;
     int i,j;
     PROFILE *tempProfile;
+    LPWSTR dummy;
     
     ZeroMemory(&LastWriteTime, sizeof(LastWriteTime));
 
@@ -722,24 +785,25 @@
 
     GetWindowsDirectoryW( windirW, MAX_PATH );
 
-    if ((RtlDetermineDosPathNameType_U(filename) == RELATIVE_PATH) &&
+    /* try to find file as specified by caller */
+    GetFullPathNameW(filename, sizeof(buffer)/sizeof(buffer[0]), buffer, &dummy);
+    hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+    /* if it doesn't exist and the caller didn't specify a path then
+     * open from / create in Windows directory */
+    if ((hFile == INVALID_HANDLE_VALUE) &&
+        (RtlDetermineDosPathNameType_U(filename) == RELATIVE_PATH) &&
         !strchrW(filename, '\\') && !strchrW(filename, '/'))
     {
-        static const WCHAR wszSeparator[] = {'\\', 0};
-        strcpyW(buffer, windirW);
-        strcatW(buffer, wszSeparator);
-        strcatW(buffer, filename);
+        static const WCHAR wszFormat[] = {'%','s','\\','%','s', 0};
+        snprintfW(buffer, sizeof(buffer)/sizeof(buffer[0]), wszFormat, windirW, filename);
+        hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     }
-    else
-    {
-        LPWSTR dummy;
-        GetFullPathNameW(filename, sizeof(buffer)/sizeof(buffer[0]), buffer, &dummy);
-    }
-        
+
     TRACE("path: %s\n", debugstr_w(buffer));
-    
-    hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    
+
+    /* it's ok if the file doesn't exist as we will create it later if data is
+     * added to the file, but we fail on any other error */
     if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_FILE_NOT_FOUND))
     {
         WARN("Error %ld opening file %s\n", GetLastError(), debugstr_w(buffer));


More information about the wine-patches mailing list