From 34372dcbf0706dd67fc9e40823b952240ede1610 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Fri, 29 Mar 2002 18:17:35 +0000 Subject: [PATCH] Fix SetFileAttributes to honor the umask (rather than making files world-writable). --- dlls/kernel/kernel_main.c | 6 ++ files/file.c | 97 ++++++++++++++++++++++++++ include/file.h | 2 + win32/Makefile.in | 1 - win32/file.c | 143 -------------------------------------- 5 files changed, 105 insertions(+), 144 deletions(-) delete mode 100644 win32/file.c diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c index d04290a3a4d..aef6d0c8744 100644 --- a/dlls/kernel/kernel_main.c +++ b/dlls/kernel/kernel_main.c @@ -23,10 +23,12 @@ #include #include #include +#include #include "winbase.h" #include "wine/winbase16.h" +#include "file.h" #include "global.h" #include "miscemu.h" #include "module.h" @@ -43,6 +45,10 @@ static BOOL process_attach(void) { HMODULE16 hModule; + /* Get the umask */ + FILE_umask = umask(0777); + umask( FILE_umask ); + /* Setup codepage info */ CODEPAGE_Init(); diff --git a/files/file.c b/files/file.c index 87953dc246f..7d23c6c6c6f 100644 --- a/files/file.c +++ b/files/file.c @@ -76,6 +76,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); static HANDLE dos_handles[DOS_TABLE_SIZE]; +mode_t FILE_umask; + extern WINAPI HANDLE FILE_SmbOpen(LPCSTR name); /*********************************************************************** @@ -674,6 +676,101 @@ DWORD WINAPI GetFileAttributesW( LPCWSTR name ) } +/************************************************************************** + * SetFileAttributes (KERNEL.421) + */ +BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes ) +{ + return SetFileAttributesA( lpFileName, attributes ); +} + + +/************************************************************************** + * SetFileAttributesA (KERNEL32.@) + */ +BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD attributes) +{ + struct stat buf; + DOS_FULL_NAME full_name; + + if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) + return FALSE; + + TRACE("(%s,%lx)\n",lpFileName,attributes); + if (attributes & FILE_ATTRIBUTE_NORMAL) { + attributes &= ~FILE_ATTRIBUTE_NORMAL; + if (attributes) + FIXME("(%s):%lx illegal combination with FILE_ATTRIBUTE_NORMAL.\n", lpFileName,attributes); + } + if(stat(full_name.long_name,&buf)==-1) + { + FILE_SetDosError(); + return FALSE; + } + if (attributes & FILE_ATTRIBUTE_READONLY) + { + if(S_ISDIR(buf.st_mode)) + /* FIXME */ + WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n"); + else + buf.st_mode &= ~0222; /* octal!, clear write permission bits */ + attributes &= ~FILE_ATTRIBUTE_READONLY; + } + else + { + /* add write permission */ + buf.st_mode |= (0600 | ((buf.st_mode & 044) >> 1)) & (~FILE_umask); + } + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!S_ISDIR(buf.st_mode)) + FIXME("SetFileAttributes expected the file '%s' to be a directory", + lpFileName); + attributes &= ~FILE_ATTRIBUTE_DIRECTORY; + } + attributes &= ~(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); + if (attributes) + FIXME("(%s):%lx attribute(s) not implemented.\n", lpFileName,attributes); + if (-1==chmod(full_name.long_name,buf.st_mode)) + { + if(GetDriveTypeA(lpFileName) == DRIVE_CDROM) { + SetLastError( ERROR_ACCESS_DENIED ); + return FALSE; + } + + /* + * FIXME: We don't return FALSE here because of differences between + * Linux and Windows privileges. Under Linux only the owner of + * the file is allowed to change file attributes. Under Windows, + * applications expect that if you can write to a file, you can also + * change its attributes (see GENERIC_WRITE). We could try to be + * clever here but that would break multi-user installations where + * users share read-only DLLs. This is because some installers like + * to change attributes of already installed DLLs. + */ + FIXME("Couldn't set file attributes for existing file \"%s\".\n" + "Check permissions or set VFAT \"quiet\" mount flag\n", full_name.long_name); + } + return TRUE; +} + + +/************************************************************************** + * SetFileAttributesW (KERNEL32.@) + */ +BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD attributes) +{ + BOOL res; + DWORD len = WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, NULL, 0, NULL, NULL ); + LPSTR afn = HeapAlloc( GetProcessHeap(), 0, len ); + + WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, afn, len, NULL, NULL ); + res = SetFileAttributesA( afn, attributes ); + HeapFree( GetProcessHeap(), 0, afn ); + return res; +} + + /*********************************************************************** * GetFileSize (KERNEL32.@) */ diff --git a/include/file.h b/include/file.h index b7c7e599d44..e061f4c2766 100644 --- a/include/file.h +++ b/include/file.h @@ -23,6 +23,7 @@ #include /* time_t */ #include +#include #include "winbase.h" #include "wine/windef16.h" /* HFILE16 */ @@ -85,6 +86,7 @@ inline static int FILE_contains_path (LPCSTR name) } /* files/file.c */ +extern mode_t FILE_umask; extern int FILE_strcasecmp( const char *str1, const char *str2 ); extern int FILE_strncasecmp( const char *str1, const char *str2, int len ); extern void FILE_SetDosError(void); diff --git a/win32/Makefile.in b/win32/Makefile.in index 890c2e745af..a14de171828 100644 --- a/win32/Makefile.in +++ b/win32/Makefile.in @@ -10,7 +10,6 @@ C_SRCS = \ device.c \ editline.c \ except.c \ - file.c \ init.c \ kernel32.c \ newfns.c \ diff --git a/win32/file.c b/win32/file.c deleted file mode 100644 index b37f032f1d9..00000000000 --- a/win32/file.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Win32 kernel functions - * - * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#ifdef HAVE_SYS_ERRNO_H -#include -#endif -#include -#include -#include -#include -#ifdef HAVE_SYS_MMAN_H -#include -#endif -#include -#include -#include - -#include "winbase.h" -#include "winerror.h" - -#include "wine/winbase16.h" -#include "file.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(file); - -/************************************************************************** - * SetFileAttributes (KERNEL.421) - */ -BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes ) -{ - return SetFileAttributesA( lpFileName, attributes ); -} - - -/************************************************************************** - * SetFileAttributesA (KERNEL32.@) - */ -BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD attributes) -{ - struct stat buf; - DOS_FULL_NAME full_name; - - if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) - return FALSE; - - TRACE("(%s,%lx)\n",lpFileName,attributes); - if (attributes & FILE_ATTRIBUTE_NORMAL) { - attributes &= ~FILE_ATTRIBUTE_NORMAL; - if (attributes) - FIXME("(%s):%lx illegal combination with FILE_ATTRIBUTE_NORMAL.\n", - lpFileName,attributes); - } - if(stat(full_name.long_name,&buf)==-1) - { - FILE_SetDosError(); - return FALSE; - } - if (attributes & FILE_ATTRIBUTE_READONLY) - { - if(S_ISDIR(buf.st_mode)) - /* FIXME */ - WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n"); - else - buf.st_mode &= ~0222; /* octal!, clear write permission bits */ - attributes &= ~FILE_ATTRIBUTE_READONLY; - } - else - { - /* add write permission */ - buf.st_mode |= 0600 | ((buf.st_mode & 044) >> 1); - } - if (attributes & FILE_ATTRIBUTE_DIRECTORY) - { - if (!S_ISDIR(buf.st_mode)) - FIXME("SetFileAttributes expected the file '%s' to be a directory", - lpFileName); - attributes &= ~FILE_ATTRIBUTE_DIRECTORY; - } - attributes &= ~(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); - if (attributes) - FIXME("(%s):%lx attribute(s) not implemented.\n", - lpFileName,attributes); - if (-1==chmod(full_name.long_name,buf.st_mode)) - { - if(GetDriveTypeA(lpFileName) == DRIVE_CDROM) { - SetLastError( ERROR_ACCESS_DENIED ); - return FALSE; - } - - /* - * FIXME: We don't return FALSE here because of differences between - * Linux and Windows privileges. Under Linux only the owner of - * the file is allowed to change file attributes. Under Windows, - * applications expect that if you can write to a file, you can also - * change its attributes (see GENERIC_WRITE). We could try to be - * clever here but that would break multi-user installations where - * users share read-only DLLs. This is because some installers like - * to change attributes of already installed DLLs. - */ - FIXME("Couldn't set file attributes for existing file \"%s\".\n" - "Check permissions or set VFAT \"quiet\" mount flag\n", full_name.long_name); - } - return TRUE; -} - - -/************************************************************************** - * SetFileAttributesW (KERNEL32.@) - */ -BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD attributes) -{ - BOOL res; - DWORD len = WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, NULL, 0, NULL, NULL ); - LPSTR afn = HeapAlloc( GetProcessHeap(), 0, len ); - - WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, afn, len, NULL, NULL ); - res = SetFileAttributesA( afn, attributes ); - HeapFree( GetProcessHeap(), 0, afn ); - return res; -}