Alexandre Julliard : kernel32: Don' t require write access on profile file when only reading.

Alexandre Julliard julliard at winehq.org
Thu May 22 06:27:40 CDT 2008


Module: wine
Branch: master
Commit: 284335229aff3e694b042cbfe549d5c7190ceb23
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=284335229aff3e694b042cbfe549d5c7190ceb23

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu May 22 12:15:37 2008 +0200

kernel32: Don't require write access on profile file when only reading.

---

 dlls/kernel32/profile.c       |   25 ++++++++-------
 dlls/kernel32/tests/profile.c |   65 +++++++++++++++++++++++++++++-----------
 2 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c
index a412e1e..9b6b1a1 100644
--- a/dlls/kernel32/profile.c
+++ b/dlls/kernel32/profile.c
@@ -708,7 +708,7 @@ static void PROFILE_ReleaseFile(void)
  *
  * Open a profile file, checking the cached file first.
  */
-static BOOL PROFILE_Open( LPCWSTR filename )
+static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
 {
     WCHAR windirW[MAX_PATH];
     WCHAR buffer[MAX_PATH];
@@ -754,8 +754,9 @@ static BOOL PROFILE_Open( LPCWSTR filename )
         
     TRACE("path: %s\n", debugstr_w(buffer));
 
-    hFile = CreateFileW(buffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    hFile = CreateFileW(buffer, GENERIC_READ | (write_access ? GENERIC_WRITE : 0),
+                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
     if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_FILE_NOT_FOUND))
     {
@@ -1104,7 +1105,7 @@ static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename )) {
+    if (PROFILE_Open( filename, FALSE )) {
 	if (win32 && (section == NULL))
             ret = PROFILE_GetSectionNames(buffer, len);
 	else 
@@ -1336,7 +1337,7 @@ INT WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, FALSE ))
         ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, TRUE, FALSE);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1419,12 +1420,12 @@ BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
 
     if (!section && !entry && !string) /* documented "file flush" case */
     {
-        if (!filename || PROFILE_Open( filename ))
+        if (!filename || PROFILE_Open( filename, TRUE ))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
     }
-    else if (PROFILE_Open( filename ))
+    else if (PROFILE_Open( filename, TRUE ))
     {
         if (!section) {
             FIXME("(NULL?,%s,%s,%s)?\n",
@@ -1479,12 +1480,12 @@ BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
 
     if (!section && !string)
     {
-        if (!filename || PROFILE_Open( filename ))
+        if (!filename || PROFILE_Open( filename, TRUE ))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
     }
-    else if (PROFILE_Open( filename )) {
+    else if (PROFILE_Open( filename, TRUE )) {
         if (!string) {/* delete the named section*/
 	    ret = PROFILE_SetString(section,NULL,NULL, FALSE);
 	    PROFILE_FlushFile();
@@ -1607,7 +1608,7 @@ DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename ))
+    if (PROFILE_Open( filename, FALSE ))
         ret = PROFILE_GetSectionNames(buffer, size);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1662,7 +1663,7 @@ BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename )) {
+    if (PROFILE_Open( filename, FALSE )) {
         PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE);
 	if (k) {
 	    TRACE("value (at %p): %s\n", k->value, debugstr_w(k->value));
@@ -1782,7 +1783,7 @@ BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename )) {
+    if (PROFILE_Open( filename, TRUE )) {
         ret = PROFILE_SetString( section, key, outstring, FALSE);
         PROFILE_FlushFile();
     }
diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c
index 54ad6da..cddc9a0 100644
--- a/dlls/kernel32/tests/profile.c
+++ b/dlls/kernel32/tests/profile.c
@@ -19,6 +19,7 @@
  */
 
 #include <stdarg.h>
+#include <stdio.h>
 
 #include "wine/test.h"
 #include "windef.h"
@@ -29,7 +30,6 @@
 #define SECTION  "Test"
 #define TESTFILE ".\\testwine.ini"
 #define TESTFILE2 ".\\testwine2.ini"
-#define TESTFILE3 ".\\testwine3.ini"
 
 struct _profileInt { 
     LPCSTR section;
@@ -270,21 +270,25 @@ static void test_profile_sections_names(void)
 /* If the ini-file has already been opened with CreateFile, WritePrivateProfileString failed in wine with an error ERROR_SHARING_VIOLATION,  some testing here */
 static void test_profile_existing(void)
 {
+    static const char *testfile1 = ".\\winesharing1.ini";
+    static const char *testfile2 = ".\\winesharing2.ini";
+
     static const struct {
         DWORD dwDesiredAccess;
         DWORD dwShareMode;
-        DWORD error;
+        DWORD write_error;
+        BOOL read_error;
     } pe[] = {
-        {GENERIC_READ,  FILE_SHARE_READ,  ERROR_SHARING_VIOLATION},
-        {GENERIC_READ,  FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION},
-        {GENERIC_WRITE, FILE_SHARE_READ,  ERROR_SHARING_VIOLATION},
-        {GENERIC_WRITE, FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION},
-        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,  ERROR_SHARING_VIOLATION},
-        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION},
-        {GENERIC_READ,  FILE_SHARE_READ|FILE_SHARE_WRITE, 0},
-        {GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0},
+        {GENERIC_READ,  FILE_SHARE_READ,  ERROR_SHARING_VIOLATION, FALSE },
+        {GENERIC_READ,  FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION, TRUE },
+        {GENERIC_WRITE, FILE_SHARE_READ,  ERROR_SHARING_VIOLATION, FALSE },
+        {GENERIC_WRITE, FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION, TRUE },
+        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,  ERROR_SHARING_VIOLATION, FALSE },
+        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, ERROR_SHARING_VIOLATION, TRUE },
+        {GENERIC_READ,  FILE_SHARE_READ|FILE_SHARE_WRITE, 0, FALSE },
+        {GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, FALSE },
         /*Thief demo (bug 5024) opens .ini file like this*/
-        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0},
+        {GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, FALSE }
     };
 
     int i;
@@ -295,28 +299,53 @@ static void test_profile_existing(void)
 
     for (i=0; i < sizeof(pe)/sizeof(pe[0]); i++)
     {
-        h = CreateFile(TESTFILE3, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+        h = CreateFile(testfile1, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL,
+                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
         ok(INVALID_HANDLE_VALUE != h, "%d: CreateFile failed\n",i);
         SetLastError(0xdeadbeef);
-        ret = WritePrivateProfileString(SECTION, KEY, "12345", TESTFILE3);
-        if (!pe[i].error)
+
+        ret = WritePrivateProfileString(SECTION, KEY, "12345", testfile1);
+        if (!pe[i].write_error)
         {
             ok( ret, "%d: WritePrivateProfileString failed with error %u\n", i, GetLastError() );
             CloseHandle(h);
-            size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, TESTFILE3);
+            size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, testfile1);
             ok( size == 5, "%d: test failed, number of characters copied: %d instead of 5\n", i, size );
         }
         else
         {
             DWORD err = GetLastError();
             ok( !ret, "%d: WritePrivateProfileString succeeded\n", i );
-            if (!ret) ok( err == pe[i].error, "%d: WritePrivateProfileString failed with error %u/%u\n", i, err, pe[i].error );
+            if (!ret)
+                ok( err == pe[i].write_error, "%d: WritePrivateProfileString failed with error %u/%u\n",
+                    i, err, pe[i].write_error );
             CloseHandle(h);
-            size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, TESTFILE3);
+            size = GetPrivateProfileString(SECTION, KEY, 0, buffer, MAX_PATH, testfile1);
             ok( !size, "%d: test failed, number of characters copied: %d instead of 0\n", i, size );
         }
-        ok( DeleteFile(TESTFILE3), "delete failed\n" );
+
+        ok( DeleteFile(testfile1), "delete failed\n" );
+    }
+
+    h = CreateFile(testfile2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    sprintf( buffer, "[%s]\r\n%s=123\r\n", SECTION, KEY );
+    ok( WriteFile( h, buffer, strlen(buffer), &size, NULL ), "failed to write\n" );
+    CloseHandle( h );
+
+    for (i=0; i < sizeof(pe)/sizeof(pe[0]); i++)
+    {
+        h = CreateFile(testfile2, pe[i].dwDesiredAccess, pe[i].dwShareMode, NULL,
+                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        ok(INVALID_HANDLE_VALUE != h, "%d: CreateFile failed\n",i);
+        SetLastError(0xdeadbeef);
+        ret = GetPrivateProfileStringA(SECTION, KEY, NULL, buffer, MAX_PATH, testfile2);
+        if (!pe[i].read_error)
+            ok( ret, "%d: GetPrivateProfileString failed with error %u\n", i, GetLastError() );
+        else
+            ok( !ret, "%d: GetPrivateProfileString succeeded\n", i );
+        CloseHandle(h);
     }
+    ok( DeleteFile(testfile2), "delete failed\n" );
 }
 
 START_TEST(profile)




More information about the wine-cvs mailing list