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