Reimplemented GetFileType and SetEndOfFile using ntdll functions.
This commit is contained in:
parent
25dd29c80b
commit
b592cbbc18
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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" );
|
||||
if (!warned++) FIXME( "device info not properly supported on this platform\n" );
|
||||
info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
|
||||
info->Characteristics = 0;
|
||||
#endif
|
||||
info->Characteristics |= FILE_DEVICE_IS_MOUNTED;
|
||||
}
|
||||
io->Information = sizeof(*info);
|
||||
io->u.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
|
48
files/file.c
48
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.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue