[PATCH] kernel32: Fix failure reporting in WritePrivateProfile* and add tests
Paul Graham
development at omega-software.com
Sat Jan 27 14:11:10 CST 2018
Fixes https://bugs.winehq.org/show_bug.cgi?id=44310
The following functions have been fixed to correctly report failure
when they're unable to create the requested file:
WritePrivateProfileStringA
WritePrivateProfileStringW
WritePrivateProfileSectionA
WritePrivateProfileSectionW
WritePrivateProfileStructA
WritePrivateProfileStructW
Tested on Ubuntu 16.04. Conformance tests based on work by Fabian
Maurer, with some adaptations.
Signed-off-by: Paul Graham <development at omega-software.com>
---
dlls/kernel32/profile.c | 15 ++++++++++-----
dlls/kernel32/tests/profile.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c
index aad3ba3..4d6c016 100644
--- a/dlls/kernel32/profile.c
+++ b/dlls/kernel32/profile.c
@@ -1391,7 +1391,8 @@ BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
SetLastError(ERROR_FILE_NOT_FOUND);
} else {
ret = PROFILE_SetString( section, entry, string, FALSE);
- PROFILE_FlushFile();
+ if (ret)
+ ret = PROFILE_FlushFile();
}
}
@@ -1447,7 +1448,8 @@ BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
else if (PROFILE_Open( filename, TRUE )) {
if (!string) {/* delete the named section*/
ret = PROFILE_SetString(section,NULL,NULL, FALSE);
- PROFILE_FlushFile();
+ if (ret)
+ ret = PROFILE_FlushFile();
} else {
PROFILE_DeleteAllKeys(section);
ret = TRUE;
@@ -1456,12 +1458,14 @@ BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
strcpyW( buf, string );
if((p = strchrW( buf, '='))) {
*p='\0';
- ret = PROFILE_SetString( section, buf, p+1, TRUE);
+ if (ret)
+ ret = PROFILE_SetString( section, buf, p+1, TRUE);
}
HeapFree( GetProcessHeap(), 0, buf );
string += strlenW(string)+1;
}
- PROFILE_FlushFile();
+ if (ret)
+ ret = PROFILE_FlushFile();
}
}
@@ -1744,7 +1748,8 @@ BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
if (PROFILE_Open( filename, TRUE )) {
ret = PROFILE_SetString( section, key, outstring, FALSE);
- PROFILE_FlushFile();
+ if (ret)
+ ret = PROFILE_FlushFile();
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c
index 2eb90a8..17ba124 100644
--- a/dlls/kernel32/tests/profile.c
+++ b/dlls/kernel32/tests/profile.c
@@ -25,6 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "windows.h"
+#include "sddl.h"
#define KEY "ProfileInt"
#define SECTION "Test"
@@ -534,6 +535,41 @@ static BOOL emptystr_ok(CHAR emptystr[MAX_PATH])
return TRUE;
}
+static void test_profile_directory_readonly(void)
+{
+ BOOL ret;
+ CHAR path_folder[MAX_PATH];
+ CHAR path_file[MAX_PATH];
+ const char *sddl_string_everyone_readonly = "D:PAI(A;;0x1200a9;;;WD)";
+ SECURITY_ATTRIBUTES attributes = {0};
+ char lpStruct[] = { 's', 't', 'r', 'i', 'n', 'g' };
+
+ attributes.nLength = sizeof(attributes);
+ ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(sddl_string_everyone_readonly, SDDL_REVISION_1, &attributes.lpSecurityDescriptor, NULL);
+ ok(ret == TRUE, "ConvertStringSecurityDescriptorToSecurityDescriptor failed: %d\n", GetLastError());
+
+ GetTempPathA(MAX_PATH, path_folder);
+ lstrcatA(path_folder, "wine-test");
+
+ strcpy(path_file, path_folder);
+ lstrcatA(path_file, "\\tmp.ini");
+
+ ret = CreateDirectoryA(path_folder, &attributes);
+ ok(ret == TRUE, "CreateDirectoryA failed: %d\n", GetLastError());
+
+ ret = WritePrivateProfileStringA("App", "key", "string", path_file);
+ ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
+
+ ret = WritePrivateProfileSectionA("App", "key=string", path_file);
+ ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
+
+ ret = WritePrivateProfileStructA("App", "key", lpStruct, sizeof(lpStruct), path_file);
+ ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
+
+ ret = RemoveDirectoryA(path_folder);
+ ok(ret == TRUE, "RemoveDirectoryA failed: %d\n", GetLastError());
+}
+
static void test_GetPrivateProfileString(const char *content, const char *descript)
{
DWORD ret, len;
@@ -1132,6 +1168,7 @@ START_TEST(profile)
test_profile_existing();
test_profile_delete_on_close();
test_profile_refresh();
+ test_profile_directory_readonly();
test_GetPrivateProfileString(
"[section1]\r\n"
"name1=val1\r\n"
--
2.7.4
More information about the wine-devel
mailing list