Skip to content
Snippets Groups Projects
Commit b592cbbc authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

Reimplemented GetFileType and SetEndOfFile using ntdll functions.

parent 25dd29c8
Branches
Tags
No related merge requests found
......@@ -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" );
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;
}
......
......@@ -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.@)
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment