Reimplemented GetFileAttributesW, SetFileAttributesW and SetFileTime using the corresponding ntdll functionality.
diff --git a/dlls/kernel/file.c b/dlls/kernel/file.c index 8dfeb98..9c4d0ab 100644 --- a/dlls/kernel/file.c +++ b/dlls/kernel/file.c
@@ -367,6 +367,40 @@ } +/*********************************************************************** + * SetFileTime (KERNEL32.@) + */ +BOOL WINAPI SetFileTime( HANDLE hFile, const FILETIME *ctime, + const FILETIME *atime, const FILETIME *mtime ) +{ + FILE_BASIC_INFORMATION info; + IO_STATUS_BLOCK io; + NTSTATUS status; + + memset( &info, 0, sizeof(info) ); + if (ctime) + { + info.CreationTime.u.HighPart = ctime->dwHighDateTime; + info.CreationTime.u.LowPart = ctime->dwLowDateTime; + } + if (atime) + { + info.LastAccessTime.u.HighPart = atime->dwHighDateTime; + info.LastAccessTime.u.LowPart = atime->dwLowDateTime; + } + if (mtime) + { + info.LastWriteTime.u.HighPart = mtime->dwHighDateTime; + info.LastWriteTime.u.LowPart = mtime->dwLowDateTime; + } + + status = NtSetInformationFile( hFile, &io, &info, sizeof(info), FileBasicInformation ); + if (status == STATUS_SUCCESS) return TRUE; + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; +} + + /************************************************************************** * LockFile (KERNEL32.@) */ @@ -918,6 +952,135 @@ } +/************************************************************************** + * GetFileAttributesW (KERNEL32.@) + */ +DWORD WINAPI GetFileAttributesW( LPCWSTR name ) +{ + FILE_BASIC_INFORMATION info; + UNICODE_STRING nt_name; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL )) + { + SetLastError( ERROR_PATH_NOT_FOUND ); + return INVALID_FILE_ATTRIBUTES; + } + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &nt_name; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + status = NtQueryAttributesFile( &attr, &info ); + RtlFreeUnicodeString( &nt_name ); + + if (status == STATUS_SUCCESS) return info.FileAttributes; + + /* NtQueryAttributesFile fails on devices, but GetFileAttributesW succeeds */ + if (RtlIsDosDeviceName_U( name )) return FILE_ATTRIBUTE_ARCHIVE; + + SetLastError( RtlNtStatusToDosError(status) ); + return INVALID_FILE_ATTRIBUTES; +} + + +/************************************************************************** + * GetFileAttributesA (KERNEL32.@) + */ +DWORD WINAPI GetFileAttributesA( LPCSTR name ) +{ + UNICODE_STRING nameW; + DWORD ret = INVALID_FILE_ATTRIBUTES; + + if (!name) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return INVALID_FILE_ATTRIBUTES; + } + + if (RtlCreateUnicodeStringFromAsciiz(&nameW, name)) + { + ret = GetFileAttributesW(nameW.Buffer); + RtlFreeUnicodeString(&nameW); + } + else + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return ret; +} + + +/************************************************************************** + * SetFileAttributesW (KERNEL32.@) + */ +BOOL WINAPI SetFileAttributesW( LPCWSTR name, DWORD attributes ) +{ + UNICODE_STRING nt_name; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE handle; + + if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL )) + { + SetLastError( ERROR_PATH_NOT_FOUND ); + return FALSE; + } + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &nt_name; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + status = NtOpenFile( &handle, 0, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT ); + RtlFreeUnicodeString( &nt_name ); + + if (status == STATUS_SUCCESS) + { + FILE_BASIC_INFORMATION info; + + memset( &info, 0, sizeof(info) ); + info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL; /* make sure it's not zero */ + status = NtSetInformationFile( handle, &io, &info, sizeof(info), FileBasicInformation ); + NtClose( handle ); + } + + if (status == STATUS_SUCCESS) return TRUE; + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; +} + + +/************************************************************************** + * SetFileAttributesA (KERNEL32.@) + */ +BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes ) +{ + UNICODE_STRING filenameW; + BOOL ret = FALSE; + + if (!name) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name)) + { + ret = SetFileAttributesW(filenameW.Buffer, attributes); + RtlFreeUnicodeString(&filenameW); + } + else + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return ret; +} + + /*********************************************************************** * OpenFile (KERNEL32.@) */
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c index 20df164..36ba86c 100644 --- a/dlls/kernel/kernel_main.c +++ b/dlls/kernel/kernel_main.c
@@ -110,10 +110,6 @@ { HMODULE16 hModule; - /* Get the umask */ - FILE_umask = umask(0777); - umask( FILE_umask ); - /* Setup registry locale information */ LOCALE_InitRegistry();
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 09d3f21..f22f574 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c
@@ -189,6 +189,29 @@ /*********************************************************************** + * DIR_is_hidden_file + * + * Check if the specified file should be hidden based on its name and the show dot files option. + */ +BOOL DIR_is_hidden_file( const UNICODE_STRING *name ) +{ + WCHAR *p, *end; + + if (show_dir_symlinks == -1) init_options(); + if (show_dot_files) return FALSE; + + end = p = name->Buffer + name->Length/sizeof(WCHAR); + while (p > name->Buffer && IS_SEPARATOR(p[-1])) p--; + while (p > name->Buffer && !IS_SEPARATOR(p[-1])) p--; + if (p == end || *p != '.') return FALSE; + /* make sure it isn't '.' or '..' */ + if (p + 1 == end) return FALSE; + if (p[1] == '.' && p + 2 == end) return FALSE; + return TRUE; +} + + +/*********************************************************************** * hash_short_file_name * * Transform a Unix file name into a hashed DOS name. If the name is a valid
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 55c35cf..3fa7121 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c
@@ -39,6 +39,12 @@ #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> #endif +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef HAVE_UTIME_H +# include <utime.h> +#endif #ifdef STATFS_DEFINED_BY_SYS_VFS # include <sys/vfs.h> #else @@ -64,6 +70,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); +mode_t FILE_umask = 0; + +#define SECSPERDAY 86400 +#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) + /************************************************************************** * NtOpenFile [NTDLL.@] * ZwOpenFile [NTDLL.@] @@ -868,46 +879,143 @@ * Set information about an open file handle. * * PARAMS - * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() - * IoStatusBlock [O] Receives information about the operation on return - * FileInformation [I] Source for file information - * Length [I] Size of FileInformation - * FileInformationClass [I] Type of file information to set + * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile() + * io [O] Receives information about the operation on return + * ptr [I] Source for file information + * len [I] Size of FileInformation + * class [I] Type of file information to set * * RETURNS - * Success: 0. IoStatusBlock is updated. + * Success: 0. io is updated. * Failure: An NTSTATUS error code describing the error. */ -NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status, - PVOID ptr, ULONG len, - FILE_INFORMATION_CLASS class) +NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, + PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class) { - NTSTATUS status = STATUS_INVALID_PARAMETER_3; + int fd; - TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class); + TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", handle, io, ptr, len, class); + if ((io->u.Status = wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL ))) + return io->u.Status; + + io->u.Status = STATUS_SUCCESS; switch (class) { + case FileBasicInformation: + if (len >= sizeof(FILE_BASIC_INFORMATION)) + { + struct stat st; + const FILE_BASIC_INFORMATION *info = ptr; + +#ifdef HAVE_FUTIMES + if (info->LastAccessTime.QuadPart || info->LastWriteTime.QuadPart) + { + ULONGLONG sec, nsec; + struct timeval tv[2]; + + if (!info->LastAccessTime.QuadPart || !info->LastWriteTime.QuadPart) + { + + tv[0].tv_sec = tv[0].tv_usec = 0; + tv[1].tv_sec = tv[1].tv_usec = 0; + if (!fstat( fd, &st )) + { + tv[0].tv_sec = st.st_atime; + tv[1].tv_sec = st.st_mtime; + } + } + if (info->LastAccessTime.QuadPart) + { + sec = RtlLargeIntegerDivide( info->LastAccessTime.QuadPart, 10000000, &nsec ); + tv[0].tv_sec = sec - SECS_1601_TO_1970; + tv[0].tv_usec = (UINT)nsec / 10; + } + if (info->LastWriteTime.QuadPart) + { + sec = RtlLargeIntegerDivide( info->LastWriteTime.QuadPart, 10000000, &nsec ); + tv[1].tv_sec = sec - SECS_1601_TO_1970; + tv[1].tv_usec = (UINT)nsec / 10; + } + if (futimes( fd, tv ) == -1) io->u.Status = FILE_GetNtStatus(); + } +#endif /* HAVE_FUTIMES */ + if (io->u.Status == STATUS_SUCCESS && info->FileAttributes) + { + if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus(); + else + { + if (info->FileAttributes & FILE_ATTRIBUTE_READONLY) + { + st.st_mode &= ~0222; /* clear write permission bits */ + } + else + { + /* add write permission only where we already have read permission */ + st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~FILE_umask); + } + if (fchmod( fd, st.st_mode ) == -1) io->u.Status = FILE_GetNtStatus(); + } + } + } + else io->u.Status = STATUS_INVALID_PARAMETER_3; + break; + case FilePositionInformation: if (len >= sizeof(FILE_POSITION_INFORMATION)) { - int fd; - FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr; + const FILE_POSITION_INFORMATION *info = ptr; - if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL ))) - { - if (lseek( fd, fpi->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1) - status = FILE_GetNtStatus(); - wine_server_release_fd( hFile, fd ); - } + if (lseek( fd, info->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1) + io->u.Status = FILE_GetNtStatus(); } + else io->u.Status = STATUS_INVALID_PARAMETER_3; break; + default: FIXME("Unsupported class (%d)\n", class); - return STATUS_NOT_IMPLEMENTED; + io->u.Status = STATUS_NOT_IMPLEMENTED; + break; } - io_status->u.Status = status; - io_status->Information = 0; + wine_server_release_fd( handle, fd ); + io->Information = 0; + return io->u.Status; +} + + +/****************************************************************************** + * NtQueryAttributesFile (NTDLL.@) + * ZwQueryAttributesFile (NTDLL.@) + */ +NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info ) +{ + ANSI_STRING unix_name; + NTSTATUS status; + + if (!(status = DIR_nt_to_unix( attr->ObjectName, &unix_name, + TRUE, !(attr->Attributes & OBJ_CASE_INSENSITIVE) ))) + { + struct stat st; + + if (stat( unix_name.Buffer, &st ) == -1) + status = FILE_GetNtStatus(); + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + status = STATUS_INVALID_INFO_CLASS; + else + { + if (S_ISDIR(st.st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; + else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE; + if (!(st.st_mode & S_IWUSR)) info->FileAttributes |= FILE_ATTRIBUTE_READONLY; + RtlSecondsSince1970ToTime( st.st_mtime, &info->CreationTime ); + RtlSecondsSince1970ToTime( st.st_mtime, &info->LastWriteTime ); + RtlSecondsSince1970ToTime( st.st_ctime, &info->ChangeTime ); + RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime ); + if (DIR_is_hidden_file( attr->ObjectName )) + info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; + } + RtlFreeAnsiString( &unix_name ); + } + else WARN("%s not found (%lx)\n", debugstr_us(attr->ObjectName), status ); return status; }
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e136d52..c854a03 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c
@@ -2016,10 +2016,15 @@ ANSI_STRING func_name; void (* DECLSPEC_NORETURN init_func)(); extern void __wine_dbg_ntdll_init(void); + extern mode_t FILE_umask; thread_init(); __wine_dbg_ntdll_init(); /* hack: register debug channels early */ + /* retrieve current umask */ + FILE_umask = umask(0777); + umask( FILE_umask ); + /* setup the load callback and create ntdll modref */ wine_dll_set_callback( load_builtin_callback );
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5cced80..507953c 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec
@@ -159,7 +159,7 @@ @ stub NtPrivilegedServiceAuditAlarm @ stdcall NtProtectVirtualMemory(long ptr ptr long ptr) @ stdcall NtPulseEvent(long ptr) -@ stub NtQueryAttributesFile +@ stdcall NtQueryAttributesFile(ptr ptr) @ stdcall NtQueryDefaultLocale(long ptr) @ stdcall NtQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long) @ stdcall NtQueryDirectoryObject(long ptr long long long ptr ptr) @@ -736,7 +736,7 @@ @ stub ZwPrivilegedServiceAuditAlarm @ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) NtProtectVirtualMemory @ stdcall ZwPulseEvent(long ptr) NtPulseEvent -@ stub ZwQueryAttributesFile +@ stdcall ZwQueryAttributesFile(ptr ptr) NtQueryAttributesFile @ stdcall ZwQueryDefaultLocale(long ptr) NtQueryDefaultLocale @ stdcall ZwQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long)NtQueryDirectoryFile @ stdcall ZwQueryDirectoryObject(long ptr long long long ptr ptr) NtQueryDirectoryObject
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 66c854c..cb81dc4 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h
@@ -84,6 +84,7 @@ /* file I/O */ extern NTSTATUS FILE_GetNtStatus(void); +extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ); extern NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, int check_last, int check_case );
diff --git a/files/file.c b/files/file.c index 5c673de..daa6a0f 100644 --- a/files/file.c +++ b/files/file.c
@@ -86,8 +86,6 @@ #define SECSPERDAY 86400 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) -mode_t FILE_umask; - /*********************************************************************** * FILE_ConvertOFMode * @@ -637,151 +635,6 @@ } -/************************************************************************** - * GetFileAttributesW (KERNEL32.@) - */ -DWORD WINAPI GetFileAttributesW( LPCWSTR name ) -{ - DOS_FULL_NAME full_name; - BY_HANDLE_FILE_INFORMATION info; - - if (name == NULL) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return INVALID_FILE_ATTRIBUTES; - } - if (!DOSFS_GetFullName( name, TRUE, &full_name) ) - return INVALID_FILE_ATTRIBUTES; - if (!FILE_Stat( full_name.long_name, &info, NULL )) - return INVALID_FILE_ATTRIBUTES; - return info.dwFileAttributes; -} - - -/************************************************************************** - * GetFileAttributesA (KERNEL32.@) - */ -DWORD WINAPI GetFileAttributesA( LPCSTR name ) -{ - UNICODE_STRING nameW; - DWORD ret = INVALID_FILE_ATTRIBUTES; - - if (!name) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return INVALID_FILE_ATTRIBUTES; - } - - if (RtlCreateUnicodeStringFromAsciiz(&nameW, name)) - { - ret = GetFileAttributesW(nameW.Buffer); - RtlFreeUnicodeString(&nameW); - } - else - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return ret; -} - - -/************************************************************************** - * SetFileAttributesW (KERNEL32.@) - */ -BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD attributes) -{ - struct stat buf; - DOS_FULL_NAME full_name; - - if (!lpFileName) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - TRACE("(%s,%lx)\n", debugstr_w(lpFileName), attributes); - - if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) - return FALSE; - - 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\n", - debugstr_w(lpFileName)); - attributes &= ~FILE_ATTRIBUTE_DIRECTORY; - } - attributes &= ~(FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN| - FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY); - if (attributes) - FIXME("(%s):%lx attribute(s) not implemented.\n", debugstr_w(lpFileName), attributes); - if (-1==chmod(full_name.long_name,buf.st_mode)) - { - if (GetDriveTypeW(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; -} - - -/************************************************************************** - * SetFileAttributesA (KERNEL32.@) - */ -BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD attributes) -{ - UNICODE_STRING filenameW; - BOOL ret = FALSE; - - if (!lpFileName) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - if (RtlCreateUnicodeStringFromAsciiz(&filenameW, lpFileName)) - { - ret = SetFileAttributesW(filenameW.Buffer, attributes); - RtlFreeUnicodeString(&filenameW); - } - else - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return ret; -} - - /****************************************************************************** * GetCompressedFileSizeA [KERNEL32.@] */ @@ -1725,63 +1578,6 @@ } -/*********************************************************************** - * SetFileTime (KERNEL32.@) - */ -BOOL WINAPI SetFileTime( HANDLE hFile, - const FILETIME *ctime, - const FILETIME *atime, - const FILETIME *mtime ) -{ - BOOL ret = FALSE; - NTSTATUS status; - int fd; - - if (!(status = wine_server_handle_to_fd( hFile, GENERIC_WRITE, &fd, NULL, NULL ))) - { -#ifdef HAVE_FUTIMES - ULONGLONG sec, nsec; - struct timeval tv[2]; - - if (!atime || !mtime) - { - struct stat st; - - tv[0].tv_sec = tv[0].tv_usec = 0; - tv[1].tv_sec = tv[1].tv_usec = 0; - if (!fstat( fd, &st )) - { - tv[0].tv_sec = st.st_atime; - tv[1].tv_sec = st.st_mtime; - } - } - if (atime) - { - sec = ((ULONGLONG)atime->dwHighDateTime << 32) | atime->dwLowDateTime; - sec = RtlLargeIntegerDivide( sec, 10000000, &nsec ); - tv[0].tv_sec = sec - SECS_1601_TO_1970; - tv[0].tv_usec = (UINT)nsec / 10; - } - if (mtime) - { - sec = ((ULONGLONG)mtime->dwHighDateTime << 32) | mtime->dwLowDateTime; - sec = RtlLargeIntegerDivide( sec, 10000000, &nsec ); - tv[1].tv_sec = sec - SECS_1601_TO_1970; - tv[1].tv_usec = (UINT)nsec / 10; - } - - if (!futimes( fd, tv )) ret = TRUE; - else FILE_SetDosError(); -#else - ret = TRUE; /* pretend it succeeded */ -#endif - wine_server_release_fd( hFile, fd ); - } - else SetLastError( RtlNtStatusToDosError(status) ); - return ret; -} - - /************************************************************************** * GetFileAttributesExW (KERNEL32.@) */
diff --git a/include/file.h b/include/file.h index 28e621f..b4be155 100644 --- a/include/file.h +++ b/include/file.h
@@ -36,7 +36,6 @@ } DOS_FULL_NAME; /* files/file.c */ -extern mode_t FILE_umask; extern void FILE_SetDosError(void); extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info, BOOL *is_symlink ); extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
diff --git a/include/winternl.h b/include/winternl.h index 19e497d..86ae5a5 100644 --- a/include/winternl.h +++ b/include/winternl.h
@@ -1171,6 +1171,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*); NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG); NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR); +NTSTATUS WINAPI NtQueryAttributesFile(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*); NTSTATUS WINAPI NtQueryDefaultLocale(BOOLEAN,LCID*); NTSTATUS WINAPI NtQueryDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN); NTSTATUS WINAPI NtQueryInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS);