Commit 743997fa authored by Alexandre Julliard's avatar Alexandre Julliard

Replace the get_file_info request by an fstat() on the client side.

parent be009383
......@@ -1059,6 +1059,22 @@ static void test_MapFile()
ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
}
static void test_GetFileType(void)
{
DWORD type;
HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
type = GetFileType(h);
ok( type == FILE_TYPE_DISK, "expected type disk got %ld\n", type );
CloseHandle( h );
h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
type = GetFileType(h);
ok( type == FILE_TYPE_CHAR, "expected type char for nul got %ld\n", type );
CloseHandle( h );
DeleteFileA( filename );
}
START_TEST(file)
{
test__hread( );
......@@ -1084,4 +1100,5 @@ START_TEST(file)
test_file_sharing();
test_offset_in_overlapped_structure();
test_MapFile();
test_GetFileType();
}
......@@ -763,129 +763,110 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
* Get 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 [O] Destination for file information
* Length [I] Size of FileInformation
* FileInformationClass [I] Type of file information to get
* hFile [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* io [O] Receives information about the operation on return
* ptr [O] Destination for file information
* len [I] Size of FileInformation
* class [I] Type of file information to get
*
* RETURNS
* Success: 0. IoStatusBlock and FileInformation are updated.
* Failure: An NTSTATUS error code describing the error.
*/
NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
PVOID ptr, LONG len,
FILE_INFORMATION_CLASS class)
NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
PVOID ptr, LONG len, FILE_INFORMATION_CLASS class )
{
NTSTATUS status;
LONG used = 0;
BYTE answer[256];
time_t ct = 0, wt = 0, at = 0;
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", hFile, io, ptr, len, class);
io->Information = 0;
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
return io->u.Status;
switch (class)
{
case FileBasicInformation:
{
FILE_BASIC_INFORMATION* fbi = (FILE_BASIC_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fbi)) goto too_small;
FILE_BASIC_INFORMATION *info = ptr;
SERVER_START_REQ( get_file_info )
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
req->handle = hFile;
if (!(status = wine_server_call( req )))
struct stat st;
if (fstat( fd, &st ) == -1)
io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else
{
/* FIXME: which file types are supported ?
* Serial ports (FILE_TYPE_CHAR) are not,
* and MSDN also says that pipes are not supported.
* FILE_TYPE_REMOTE seems to be supported according to
* MSDN q234741.txt */
if ((reply->type == FILE_TYPE_DISK) ||
(reply->type == FILE_TYPE_REMOTE))
{
at = reply->access_time;
wt = reply->write_time;
ct = reply->change_time;
fbi->FileAttributes = reply->attr;
used = sizeof(*fbi);
}
else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
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);
}
}
SERVER_END_REQ;
if (used)
{
RtlSecondsSince1970ToTime(wt, &fbi->CreationTime);
RtlSecondsSince1970ToTime(wt, &fbi->LastWriteTime);
RtlSecondsSince1970ToTime(ct, &fbi->ChangeTime);
RtlSecondsSince1970ToTime(at, &fbi->LastAccessTime);
}
}
break;
case FileStandardInformation:
{
FILE_STANDARD_INFORMATION* fsi = (FILE_STANDARD_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fsi)) goto too_small;
FILE_STANDARD_INFORMATION *info = ptr;
SERVER_START_REQ( get_file_info )
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
req->handle = hFile;
if (!(status = wine_server_call( req )))
struct stat st;
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
else
{
/* FIXME: which file types are supported ?
* Serial ports (FILE_TYPE_CHAR) are not,
* and MSDN also says that pipes are not supported.
* FILE_TYPE_REMOTE seems to be supported according to
* MSDN q234741.txt */
if ((reply->type == FILE_TYPE_DISK) ||
(reply->type == FILE_TYPE_REMOTE))
if ((info->Directory = S_ISDIR(st.st_mode)))
{
fsi->AllocationSize.u.HighPart = reply->alloc_high;
fsi->AllocationSize.u.LowPart = reply->alloc_low;
fsi->EndOfFile.u.HighPart = reply->size_high;
fsi->EndOfFile.u.LowPart = reply->size_low;
fsi->NumberOfLinks = reply->links;
fsi->DeletePending = FALSE; /* FIXME */
fsi->Directory = (reply->attr & FILE_ATTRIBUTE_DIRECTORY);
used = sizeof(*fsi);
info->AllocationSize.QuadPart = 0;
info->EndOfFile.QuadPart = 0;
info->NumberOfLinks = 1;
info->DeletePending = FALSE;
}
else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
else
{
info->AllocationSize.QuadPart = (ULONGLONG)st.st_blocks * 512;
info->EndOfFile.QuadPart = st.st_size;
info->NumberOfLinks = st.st_nlink;
info->DeletePending = FALSE; /* FIXME */
}
io->Information = sizeof(*info);
}
}
SERVER_END_REQ;
}
break;
case FilePositionInformation:
{
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
FILE_POSITION_INFORMATION *info = ptr;
if (sizeof(answer) < sizeof(*fpi)) goto too_small;
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
off_t res = lseek( fd, 0, SEEK_CUR );
if (res == (off_t)-1) status = FILE_GetNtStatus();
if (res == (off_t)-1) io->u.Status = FILE_GetNtStatus();
else
{
fpi->CurrentByteOffset.QuadPart = res;
used = sizeof(*fpi);
info->CurrentByteOffset.QuadPart = res;
io->Information = sizeof(*info);
}
wine_server_release_fd( hFile, fd );
}
}
break;
default:
FIXME("Unsupported class (%d)\n", class);
return io_status->u.Status = STATUS_NOT_IMPLEMENTED;
io->u.Status = STATUS_NOT_IMPLEMENTED;
break;
}
if (used) memcpy(ptr, answer, min(used, len));
io_status->u.Status = status;
io_status->Information = len;
return status;
too_small:
io_status->Information = 0;
return io_status->u.Status = STATUS_BUFFER_TOO_SMALL;
wine_server_release_fd( hFile, fd );
return io->u.Status;
}
/******************************************************************************
......
......@@ -497,15 +497,20 @@ static void FILE_FillInfo( struct stat *st, BY_HANDLE_FILE_INFORMATION *info )
RtlSecondsSince1970ToTime( st->st_atime, (LARGE_INTEGER *)&info->ftLastAccessTime );
info->dwVolumeSerialNumber = 0; /* FIXME */
info->nFileSizeHigh = 0;
info->nFileSizeLow = 0;
if (!S_ISDIR(st->st_mode)) {
info->nFileSizeHigh = st->st_size >> 32;
info->nFileSizeLow = st->st_size & 0xffffffff;
}
info->nNumberOfLinks = st->st_nlink;
info->nFileIndexHigh = 0;
info->nFileIndexLow = st->st_ino;
if (S_ISDIR(st->st_mode))
{
info->nFileSizeHigh = 0;
info->nFileSizeLow = 0;
info->nNumberOfLinks = 1;
}
else
{
info->nFileSizeHigh = st->st_size >> 32;
info->nFileSizeLow = (DWORD)st->st_size;
info->nNumberOfLinks = st->st_nlink;
}
info->nFileIndexHigh = st->st_ino >> 32;
info->nFileIndexLow = (DWORD)st->st_ino;
}
......@@ -599,45 +604,33 @@ BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info, BOOL *is_syml
/***********************************************************************
* GetFileInformationByHandle (KERNEL32.@)
*/
DWORD WINAPI GetFileInformationByHandle( HANDLE hFile,
BY_HANDLE_FILE_INFORMATION *info )
BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION *info )
{
DWORD ret;
if (!info) return 0;
NTSTATUS status;
int fd;
BOOL ret = FALSE;
TRACE("%p,%p\n", hFile, info);
TRACE("%p\n", hFile);
if (!info) return 0;
SERVER_START_REQ( get_file_info )
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
req->handle = hFile;
if ((ret = !wine_server_call_err( req )))
struct stat st;
if (fstat( fd, &st ) == -1)
FILE_SetDosError();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
SetLastError( ERROR_INVALID_FUNCTION );
else
{
/* FIXME: which file types are supported ?
* Serial ports (FILE_TYPE_CHAR) are not,
* and MSDN also says that pipes are not supported.
* FILE_TYPE_REMOTE seems to be supported according to
* MSDN q234741.txt */
if ((reply->type == FILE_TYPE_DISK) || (reply->type == FILE_TYPE_REMOTE))
{
RtlSecondsSince1970ToTime( reply->write_time, (LARGE_INTEGER *)&info->ftCreationTime );
RtlSecondsSince1970ToTime( reply->write_time, (LARGE_INTEGER *)&info->ftLastWriteTime );
RtlSecondsSince1970ToTime( reply->access_time, (LARGE_INTEGER *)&info->ftLastAccessTime );
info->dwFileAttributes = reply->attr;
info->dwVolumeSerialNumber = reply->serial;
info->nFileSizeHigh = reply->size_high;
info->nFileSizeLow = reply->size_low;
info->nNumberOfLinks = reply->links;
info->nFileIndexHigh = reply->index_high;
info->nFileIndexLow = reply->index_low;
}
else
{
SetLastError(ERROR_NOT_SUPPORTED);
ret = 0;
}
FILE_FillInfo( &st, info );
ret = TRUE;
}
wine_server_release_fd( hFile, fd );
}
SERVER_END_REQ;
else SetLastError( RtlNtStatusToDosError(status) );
return ret;
}
......@@ -1217,17 +1210,29 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile )
*/
DWORD WINAPI GetFileType( HANDLE hFile )
{
NTSTATUS status;
int fd;
DWORD ret = FILE_TYPE_UNKNOWN;
if (is_console_handle( hFile ))
return FILE_TYPE_CHAR;
SERVER_START_REQ( get_file_info )
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
req->handle = hFile;
if (!wine_server_call_err( req )) ret = reply->type;
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 );
}
SERVER_END_REQ;
else SetLastError( RtlNtStatusToDosError(status) );
return ret;
}
......
......@@ -1416,7 +1416,7 @@ DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD);
BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
#define GetFileAttributesEx WINELIB_NAME_AW(GetFileAttributesEx)
DWORD WINAPI GetFileInformationByHandle(HANDLE,BY_HANDLE_FILE_INFORMATION*);
BOOL WINAPI GetFileInformationByHandle(HANDLE,BY_HANDLE_FILE_INFORMATION*);
BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
#define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment