diff --git a/dlls/kernel/file.c b/dlls/kernel/file.c index 35372a995d0..5dd744f9c31 100644 --- a/dlls/kernel/file.c +++ b/dlls/kernel/file.c @@ -2,7 +2,7 @@ * File handling functions * * Copyright 1993 John Burton - * Copyright 1996 Alexandre Julliard + * Copyright 1996, 2004 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,10 +17,6 @@ * 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 - * - * TODO: - * Fix the CopyFileEx methods to implement the "extended" functionality. - * Right now, they simply call the CopyFile method. */ #include "config.h" @@ -36,6 +32,7 @@ #include "winbase.h" #include "winreg.h" #include "winternl.h" +#include "winioctl.h" #include "wincon.h" #include "wine/winbase16.h" #include "kernel_private.h" @@ -330,6 +327,39 @@ BOOL WINAPI FlushFileBuffers( HANDLE hFile ) } +/*********************************************************************** + * GetFileType (KERNEL32.@) + */ +DWORD WINAPI GetFileType( HANDLE hFile ) +{ + FILE_FS_DEVICE_INFORMATION info; + IO_STATUS_BLOCK io; + NTSTATUS status; + + if (is_console_handle( hFile )) return FILE_TYPE_CHAR; + + status = NtQueryVolumeInformationFile( hFile, &io, &info, sizeof(info), FileFsDeviceInformation ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FILE_TYPE_UNKNOWN; + } + + switch(info.DeviceType) + { + case FILE_DEVICE_NULL: + case FILE_DEVICE_SERIAL_PORT: + case FILE_DEVICE_PARALLEL_PORT: + case FILE_DEVICE_UNKNOWN: + return FILE_TYPE_CHAR; + case FILE_DEVICE_NAMED_PIPE: + return FILE_TYPE_PIPE; + default: + return FILE_TYPE_DISK; + } +} + + /*********************************************************************** * GetFileInformationByHandle (KERNEL32.@) */ @@ -395,6 +425,28 @@ BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize ) } +/************************************************************************** + * SetEndOfFile (KERNEL32.@) + */ +BOOL WINAPI SetEndOfFile( HANDLE hFile ) +{ + FILE_POSITION_INFORMATION pos; + FILE_END_OF_FILE_INFORMATION eof; + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtQueryInformationFile( hFile, &io, &pos, sizeof(pos), FilePositionInformation ); + if (status == STATUS_SUCCESS) + { + eof.EndOfFile = pos.CurrentByteOffset; + status = NtSetInformationFile( hFile, &io, &eof, sizeof(eof), FileEndOfFileInformation ); + } + if (status == STATUS_SUCCESS) return TRUE; + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; +} + + /*********************************************************************** * GetFileTime (KERNEL32.@) */ diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 4d3d50e19cf..457b20fb36d 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1124,6 +1124,29 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, else io->u.Status = STATUS_INVALID_PARAMETER_3; break; + case FileEndOfFileInformation: + if (len >= sizeof(FILE_END_OF_FILE_INFORMATION)) + { + const FILE_END_OF_FILE_INFORMATION *info = ptr; + + if (info->EndOfFile.QuadPart > lseek( fd, 0, SEEK_END )) + { + static const char zero; + + /* extend the file one byte beyond the requested size and then truncate it */ + /* this should work around ftruncate implementations that can't extend files */ + if (pwrite( fd, &zero, 1, (off_t)info->EndOfFile.QuadPart ) == -1) + { + io->u.Status = FILE_GetNtStatus(); + break; + } + } + if (ftruncate( fd, (off_t)info->EndOfFile.QuadPart ) == -1) + io->u.Status = FILE_GetNtStatus(); + } + else io->u.Status = STATUS_INVALID_PARAMETER_3; + break; + default: FIXME("Unsupported class (%d)\n", class); io->u.Status = STATUS_NOT_IMPLEMENTED; @@ -1278,11 +1301,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io { FILE_FS_DEVICE_INFORMATION *info = buffer; -#if defined(linux) && defined(HAVE_FSTATFS) - struct statfs stfs; - info->Characteristics = 0; - if (fstat( fd, &st ) < 0) { io->u.Status = FILE_GetNtStatus(); @@ -1290,6 +1309,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io } if (S_ISCHR( st.st_mode )) { + info->DeviceType = FILE_DEVICE_UNKNOWN; +#ifdef linux switch(major(st.st_rdev)) { case MEM_MAJOR: @@ -1301,10 +1322,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io case LP_MAJOR: info->DeviceType = FILE_DEVICE_PARALLEL_PORT; break; - default: - info->DeviceType = FILE_DEVICE_UNKNOWN; - break; } +#endif } else if (S_ISBLK( st.st_mode )) { @@ -1316,7 +1335,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io } else /* regular file or directory */ { - info->Characteristics |= FILE_DEVICE_IS_MOUNTED; +#if defined(linux) && defined(HAVE_FSTATFS) + struct statfs stfs; /* check for floppy disk */ if (major(st.st_dev) == FLOPPY_MAJOR) @@ -1346,13 +1366,13 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM; break; } - } #else - static int warned; - if (!warned++) FIXME( "device info not supported on this platform\n" ); - info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM; - info->Characteristics = 0; + static int warned; + if (!warned++) FIXME( "device info not properly supported on this platform\n" ); + info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM; #endif + info->Characteristics |= FILE_DEVICE_IS_MOUNTED; + } io->Information = sizeof(*info); io->u.Status = STATUS_SUCCESS; } diff --git a/files/file.c b/files/file.c index 4964b22e4ff..ae5859da2b2 100644 --- a/files/file.c +++ b/files/file.c @@ -718,54 +718,6 @@ UINT WINAPI SetHandleCount( UINT count ) } -/************************************************************************** - * SetEndOfFile (KERNEL32.@) - */ -BOOL WINAPI SetEndOfFile( HANDLE hFile ) -{ - BOOL ret; - SERVER_START_REQ( truncate_file ) - { - req->handle = hFile; - ret = !wine_server_call_err( req ); - } - SERVER_END_REQ; - return ret; -} - - -/*********************************************************************** - * GetFileType (KERNEL32.@) - */ -DWORD WINAPI GetFileType( HANDLE hFile ) -{ - NTSTATUS status; - int fd; - DWORD ret = FILE_TYPE_UNKNOWN; - - if (is_console_handle( hFile )) - return FILE_TYPE_CHAR; - - if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL ))) - { - struct stat st; - - if (fstat( fd, &st ) == -1) - FILE_SetDosError(); - else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) - ret = FILE_TYPE_PIPE; - else if (S_ISCHR(st.st_mode)) - ret = FILE_TYPE_CHAR; - else - ret = FILE_TYPE_DISK; - wine_server_release_fd( hFile, fd ); - } - else SetLastError( RtlNtStatusToDosError(status) ); - - return ret; -} - - /************************************************************************** * CopyFileW (KERNEL32.@) */