Replace the get_file_info request by an fstat() on the client side.
This commit is contained in:
parent
be00938306
commit
743997fa38
|
@ -1059,6 +1059,22 @@ static void test_MapFile()
|
||||||
ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
|
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)
|
START_TEST(file)
|
||||||
{
|
{
|
||||||
test__hread( );
|
test__hread( );
|
||||||
|
@ -1084,4 +1100,5 @@ START_TEST(file)
|
||||||
test_file_sharing();
|
test_file_sharing();
|
||||||
test_offset_in_overlapped_structure();
|
test_offset_in_overlapped_structure();
|
||||||
test_MapFile();
|
test_MapFile();
|
||||||
|
test_GetFileType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -763,129 +763,110 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
|
||||||
* Get information about an open file handle.
|
* Get information about an open file handle.
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
|
* hFile [I] Handle returned from ZwOpenFile() or ZwCreateFile()
|
||||||
* IoStatusBlock [O] Receives information about the operation on return
|
* io [O] Receives information about the operation on return
|
||||||
* FileInformation [O] Destination for file information
|
* ptr [O] Destination for file information
|
||||||
* Length [I] Size of FileInformation
|
* len [I] Size of FileInformation
|
||||||
* FileInformationClass [I] Type of file information to get
|
* class [I] Type of file information to get
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Success: 0. IoStatusBlock and FileInformation are updated.
|
* Success: 0. IoStatusBlock and FileInformation are updated.
|
||||||
* Failure: An NTSTATUS error code describing the error.
|
* Failure: An NTSTATUS error code describing the error.
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
|
NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
PVOID ptr, LONG len,
|
PVOID ptr, LONG len, FILE_INFORMATION_CLASS class )
|
||||||
FILE_INFORMATION_CLASS class)
|
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
int fd;
|
||||||
LONG used = 0;
|
|
||||||
BYTE answer[256];
|
|
||||||
time_t ct = 0, wt = 0, at = 0;
|
|
||||||
|
|
||||||
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)
|
switch (class)
|
||||||
{
|
{
|
||||||
case FileBasicInformation:
|
case FileBasicInformation:
|
||||||
{
|
{
|
||||||
FILE_BASIC_INFORMATION* fbi = (FILE_BASIC_INFORMATION*)answer;
|
FILE_BASIC_INFORMATION *info = ptr;
|
||||||
if (sizeof(answer) < sizeof(*fbi)) goto too_small;
|
|
||||||
|
|
||||||
SERVER_START_REQ( get_file_info )
|
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
req->handle = hFile;
|
struct stat st;
|
||||||
if (!(status = wine_server_call( req )))
|
|
||||||
|
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 ?
|
if (S_ISDIR(st.st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
* Serial ports (FILE_TYPE_CHAR) are not,
|
else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||||
* and MSDN also says that pipes are not supported.
|
if (!(st.st_mode & S_IWUSR)) info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||||
* FILE_TYPE_REMOTE seems to be supported according to
|
RtlSecondsSince1970ToTime( st.st_mtime, &info->CreationTime);
|
||||||
* MSDN q234741.txt */
|
RtlSecondsSince1970ToTime( st.st_mtime, &info->LastWriteTime);
|
||||||
if ((reply->type == FILE_TYPE_DISK) ||
|
RtlSecondsSince1970ToTime( st.st_ctime, &info->ChangeTime);
|
||||||
(reply->type == FILE_TYPE_REMOTE))
|
RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime);
|
||||||
{
|
|
||||||
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 ??? */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
|
||||||
if (used)
|
|
||||||
{
|
|
||||||
RtlSecondsSince1970ToTime(wt, &fbi->CreationTime);
|
|
||||||
RtlSecondsSince1970ToTime(wt, &fbi->LastWriteTime);
|
|
||||||
RtlSecondsSince1970ToTime(ct, &fbi->ChangeTime);
|
|
||||||
RtlSecondsSince1970ToTime(at, &fbi->LastAccessTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
{
|
{
|
||||||
FILE_STANDARD_INFORMATION* fsi = (FILE_STANDARD_INFORMATION*)answer;
|
FILE_STANDARD_INFORMATION *info = ptr;
|
||||||
if (sizeof(answer) < sizeof(*fsi)) goto too_small;
|
|
||||||
|
|
||||||
SERVER_START_REQ( get_file_info )
|
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
req->handle = hFile;
|
struct stat st;
|
||||||
if (!(status = wine_server_call( req )))
|
|
||||||
|
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: which file types are supported ?
|
if ((info->Directory = S_ISDIR(st.st_mode)))
|
||||||
* 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))
|
|
||||||
{
|
{
|
||||||
fsi->AllocationSize.u.HighPart = reply->alloc_high;
|
info->AllocationSize.QuadPart = 0;
|
||||||
fsi->AllocationSize.u.LowPart = reply->alloc_low;
|
info->EndOfFile.QuadPart = 0;
|
||||||
fsi->EndOfFile.u.HighPart = reply->size_high;
|
info->NumberOfLinks = 1;
|
||||||
fsi->EndOfFile.u.LowPart = reply->size_low;
|
info->DeletePending = FALSE;
|
||||||
fsi->NumberOfLinks = reply->links;
|
|
||||||
fsi->DeletePending = FALSE; /* FIXME */
|
|
||||||
fsi->Directory = (reply->attr & FILE_ATTRIBUTE_DIRECTORY);
|
|
||||||
used = sizeof(*fsi);
|
|
||||||
}
|
}
|
||||||
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;
|
break;
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
{
|
{
|
||||||
int fd;
|
FILE_POSITION_INFORMATION *info = ptr;
|
||||||
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
|
|
||||||
|
|
||||||
if (sizeof(answer) < sizeof(*fpi)) goto too_small;
|
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
|
else
|
||||||
{
|
{
|
||||||
off_t res = lseek( fd, 0, SEEK_CUR );
|
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
|
else
|
||||||
{
|
{
|
||||||
fpi->CurrentByteOffset.QuadPart = res;
|
info->CurrentByteOffset.QuadPart = res;
|
||||||
used = sizeof(*fpi);
|
io->Information = sizeof(*info);
|
||||||
}
|
}
|
||||||
wine_server_release_fd( hFile, fd );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unsupported class (%d)\n", class);
|
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));
|
wine_server_release_fd( hFile, fd );
|
||||||
io_status->u.Status = status;
|
return io->u.Status;
|
||||||
io_status->Information = len;
|
|
||||||
return status;
|
|
||||||
too_small:
|
|
||||||
io_status->Information = 0;
|
|
||||||
return io_status->u.Status = STATUS_BUFFER_TOO_SMALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
93
files/file.c
93
files/file.c
|
@ -497,15 +497,20 @@ static void FILE_FillInfo( struct stat *st, BY_HANDLE_FILE_INFORMATION *info )
|
||||||
RtlSecondsSince1970ToTime( st->st_atime, (LARGE_INTEGER *)&info->ftLastAccessTime );
|
RtlSecondsSince1970ToTime( st->st_atime, (LARGE_INTEGER *)&info->ftLastAccessTime );
|
||||||
|
|
||||||
info->dwVolumeSerialNumber = 0; /* FIXME */
|
info->dwVolumeSerialNumber = 0; /* FIXME */
|
||||||
info->nFileSizeHigh = 0;
|
if (S_ISDIR(st->st_mode))
|
||||||
info->nFileSizeLow = 0;
|
{
|
||||||
if (!S_ISDIR(st->st_mode)) {
|
info->nFileSizeHigh = 0;
|
||||||
info->nFileSizeHigh = st->st_size >> 32;
|
info->nFileSizeLow = 0;
|
||||||
info->nFileSizeLow = st->st_size & 0xffffffff;
|
info->nNumberOfLinks = 1;
|
||||||
}
|
}
|
||||||
info->nNumberOfLinks = st->st_nlink;
|
else
|
||||||
info->nFileIndexHigh = 0;
|
{
|
||||||
info->nFileIndexLow = st->st_ino;
|
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.@)
|
* GetFileInformationByHandle (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetFileInformationByHandle( HANDLE hFile,
|
BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION *info )
|
||||||
BY_HANDLE_FILE_INFORMATION *info )
|
|
||||||
{
|
{
|
||||||
DWORD ret;
|
NTSTATUS status;
|
||||||
|
int fd;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
TRACE("%p,%p\n", hFile, info);
|
||||||
|
|
||||||
if (!info) return 0;
|
if (!info) return 0;
|
||||||
|
|
||||||
TRACE("%p\n", hFile);
|
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
|
||||||
|
|
||||||
SERVER_START_REQ( get_file_info )
|
|
||||||
{
|
{
|
||||||
req->handle = hFile;
|
struct stat st;
|
||||||
if ((ret = !wine_server_call_err( req )))
|
|
||||||
|
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 ?
|
FILE_FillInfo( &st, info );
|
||||||
* Serial ports (FILE_TYPE_CHAR) are not,
|
ret = TRUE;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
wine_server_release_fd( hFile, fd );
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
else SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,17 +1210,29 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile )
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetFileType( HANDLE hFile )
|
DWORD WINAPI GetFileType( HANDLE hFile )
|
||||||
{
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
int fd;
|
||||||
DWORD ret = FILE_TYPE_UNKNOWN;
|
DWORD ret = FILE_TYPE_UNKNOWN;
|
||||||
|
|
||||||
if (is_console_handle( hFile ))
|
if (is_console_handle( hFile ))
|
||||||
return FILE_TYPE_CHAR;
|
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;
|
struct stat st;
|
||||||
if (!wine_server_call_err( req )) ret = reply->type;
|
|
||||||
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1416,7 +1416,7 @@ DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD);
|
||||||
BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
|
BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
|
||||||
BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
|
BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
|
||||||
#define GetFileAttributesEx WINELIB_NAME_AW(GetFileAttributesEx)
|
#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 GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
|
||||||
BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
|
BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
|
||||||
#define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity)
|
#define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity)
|
||||||
|
|
Loading…
Reference in New Issue