mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
kernel32: Don't require write access on profile file when only reading.
This commit is contained in:
parent
5026c25e05
commit
284335229a
2 changed files with 60 additions and 30 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue