ntdll: Move the get/set file information functions to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
07248fc500
commit
c3e2013b61
|
@ -112,82 +112,9 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
|
||||
mode_t FILE_umask = 0;
|
||||
|
||||
#define SECSPERDAY 86400
|
||||
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
|
||||
|
||||
#define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1)
|
||||
#define FILE_USE_FILE_POINTER_POSITION ((LONGLONG)-2)
|
||||
|
||||
/* fetch the attributes of a file */
|
||||
static inline ULONG get_file_attributes( const struct stat *st )
|
||||
{
|
||||
ULONG attr;
|
||||
|
||||
if (S_ISDIR(st->st_mode))
|
||||
attr = FILE_ATTRIBUTE_DIRECTORY;
|
||||
else
|
||||
attr = FILE_ATTRIBUTE_ARCHIVE;
|
||||
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
attr |= FILE_ATTRIBUTE_READONLY;
|
||||
return attr;
|
||||
}
|
||||
|
||||
static BOOL fd_is_mount_point( int fd, const struct stat *st )
|
||||
{
|
||||
struct stat parent;
|
||||
return S_ISDIR( st->st_mode ) && !fstatat( fd, "..", &parent, 0 )
|
||||
&& (parent.st_dev != st->st_dev || parent.st_ino == st->st_ino);
|
||||
}
|
||||
|
||||
/* get the stat info and file attributes for a file (by file descriptor) */
|
||||
int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULONG *attr )
|
||||
{
|
||||
int ret;
|
||||
|
||||
*attr = 0;
|
||||
ret = fstat( fd, st );
|
||||
if (ret == -1) return ret;
|
||||
*attr |= get_file_attributes( st );
|
||||
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
|
||||
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
|
||||
{
|
||||
char *parent_path;
|
||||
int ret;
|
||||
|
||||
*attr = 0;
|
||||
ret = lstat( path, st );
|
||||
if (ret == -1) return ret;
|
||||
if (S_ISLNK( st->st_mode ))
|
||||
{
|
||||
ret = stat( path, st );
|
||||
if (ret == -1) return ret;
|
||||
/* is a symbolic link and a directory, consider these "reparse points" */
|
||||
if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
}
|
||||
else if (S_ISDIR( st->st_mode ) && (parent_path = RtlAllocateHeap( GetProcessHeap(), 0, strlen(path) + 4 )))
|
||||
{
|
||||
struct stat parent_st;
|
||||
|
||||
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
|
||||
strcpy( parent_path, path );
|
||||
strcat( parent_path, "/.." );
|
||||
if (!stat( parent_path, &parent_st )
|
||||
&& (st->st_dev != parent_st.st_dev || st->st_ino == parent_st.st_ino))
|
||||
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
|
||||
RtlFreeHeap( GetProcessHeap(), 0, parent_path );
|
||||
}
|
||||
*attr |= get_file_attributes( st );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* NtOpenFile [NTDLL.@]
|
||||
|
@ -1802,244 +1729,6 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) && !defined(HAVE_FUTIMENS)
|
||||
static int futimens( int fd, const struct timespec spec[2] )
|
||||
{
|
||||
return syscall( __NR_utimensat, fd, NULL, spec, 0 );
|
||||
}
|
||||
#define HAVE_FUTIMENS
|
||||
#endif /* __ANDROID__ */
|
||||
|
||||
#ifndef UTIME_OMIT
|
||||
#define UTIME_OMIT ((1 << 30) - 2)
|
||||
#endif
|
||||
|
||||
static BOOL set_file_times_precise( int fd, const LARGE_INTEGER *mtime,
|
||||
const LARGE_INTEGER *atime, NTSTATUS *status )
|
||||
{
|
||||
#ifdef HAVE_FUTIMENS
|
||||
struct timespec tv[2];
|
||||
|
||||
tv[0].tv_sec = tv[1].tv_sec = 0;
|
||||
tv[0].tv_nsec = tv[1].tv_nsec = UTIME_OMIT;
|
||||
if (atime->QuadPart)
|
||||
{
|
||||
tv[0].tv_sec = atime->QuadPart / 10000000 - SECS_1601_TO_1970;
|
||||
tv[0].tv_nsec = (atime->QuadPart % 10000000) * 100;
|
||||
}
|
||||
if (mtime->QuadPart)
|
||||
{
|
||||
tv[1].tv_sec = mtime->QuadPart / 10000000 - SECS_1601_TO_1970;
|
||||
tv[1].tv_nsec = (mtime->QuadPart % 10000000) * 100;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
if (!&futimens) return FALSE;
|
||||
#endif
|
||||
if (futimens( fd, tv ) == -1) *status = FILE_GetNtStatus();
|
||||
else *status = STATUS_SUCCESS;
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static NTSTATUS set_file_times( int fd, const LARGE_INTEGER *mtime, const LARGE_INTEGER *atime )
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT)
|
||||
struct timeval tv[2];
|
||||
struct stat st;
|
||||
#endif
|
||||
|
||||
if (set_file_times_precise( fd, mtime, atime, &status ))
|
||||
return status;
|
||||
|
||||
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT)
|
||||
if (!atime->QuadPart || !mtime->QuadPart)
|
||||
{
|
||||
|
||||
tv[0].tv_sec = tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = tv[1].tv_usec = 0;
|
||||
if (!fstat( fd, &st ))
|
||||
{
|
||||
tv[0].tv_sec = st.st_atime;
|
||||
tv[1].tv_sec = st.st_mtime;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_ATIM
|
||||
tv[0].tv_usec = st.st_atim.tv_nsec / 1000;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
|
||||
tv[0].tv_usec = st.st_atimespec.tv_nsec / 1000;
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
tv[1].tv_usec = st.st_mtim.tv_nsec / 1000;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
||||
tv[1].tv_usec = st.st_mtimespec.tv_nsec / 1000;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (atime->QuadPart)
|
||||
{
|
||||
tv[0].tv_sec = atime->QuadPart / 10000000 - SECS_1601_TO_1970;
|
||||
tv[0].tv_usec = (atime->QuadPart % 10000000) / 10;
|
||||
}
|
||||
if (mtime->QuadPart)
|
||||
{
|
||||
tv[1].tv_sec = mtime->QuadPart / 10000000 - SECS_1601_TO_1970;
|
||||
tv[1].tv_usec = (mtime->QuadPart % 10000000) / 10;
|
||||
}
|
||||
#ifdef HAVE_FUTIMES
|
||||
if (futimes( fd, tv ) == -1) status = FILE_GetNtStatus();
|
||||
#elif defined(HAVE_FUTIMESAT)
|
||||
if (futimesat( fd, NULL, tv ) == -1) status = FILE_GetNtStatus();
|
||||
#endif
|
||||
|
||||
#else /* HAVE_FUTIMES || HAVE_FUTIMESAT */
|
||||
FIXME( "setting file times not supported\n" );
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime, LARGE_INTEGER *ctime,
|
||||
LARGE_INTEGER *atime, LARGE_INTEGER *creation )
|
||||
{
|
||||
RtlSecondsSince1970ToTime( st->st_mtime, mtime );
|
||||
RtlSecondsSince1970ToTime( st->st_ctime, ctime );
|
||||
RtlSecondsSince1970ToTime( st->st_atime, atime );
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
mtime->QuadPart += st->st_mtim.tv_nsec / 100;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
||||
mtime->QuadPart += st->st_mtimespec.tv_nsec / 100;
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_CTIM
|
||||
ctime->QuadPart += st->st_ctim.tv_nsec / 100;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
|
||||
ctime->QuadPart += st->st_ctimespec.tv_nsec / 100;
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_ATIM
|
||||
atime->QuadPart += st->st_atim.tv_nsec / 100;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
|
||||
atime->QuadPart += st->st_atimespec.tv_nsec / 100;
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
RtlSecondsSince1970ToTime( st->st_birthtime, creation );
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIM
|
||||
creation->QuadPart += st->st_birthtim.tv_nsec / 100;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
|
||||
creation->QuadPart += st->st_birthtimespec.tv_nsec / 100;
|
||||
#endif
|
||||
#elif defined(HAVE_STRUCT_STAT___ST_BIRTHTIME)
|
||||
RtlSecondsSince1970ToTime( st->__st_birthtime, creation );
|
||||
#ifdef HAVE_STRUCT_STAT___ST_BIRTHTIM
|
||||
creation->QuadPart += st->__st_birthtim.tv_nsec / 100;
|
||||
#endif
|
||||
#else
|
||||
*creation = *mtime;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* fill in the file information that depends on the stat and attribute info */
|
||||
NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
|
||||
FILE_INFORMATION_CLASS class )
|
||||
{
|
||||
switch (class)
|
||||
{
|
||||
case FileBasicInformation:
|
||||
{
|
||||
FILE_BASIC_INFORMATION *info = ptr;
|
||||
|
||||
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
|
||||
&info->LastAccessTime, &info->CreationTime );
|
||||
info->FileAttributes = attr;
|
||||
}
|
||||
break;
|
||||
case FileStandardInformation:
|
||||
{
|
||||
FILE_STANDARD_INFORMATION *info = ptr;
|
||||
|
||||
if ((info->Directory = S_ISDIR(st->st_mode)))
|
||||
{
|
||||
info->AllocationSize.QuadPart = 0;
|
||||
info->EndOfFile.QuadPart = 0;
|
||||
info->NumberOfLinks = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512;
|
||||
info->EndOfFile.QuadPart = st->st_size;
|
||||
info->NumberOfLinks = st->st_nlink;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileInternalInformation:
|
||||
{
|
||||
FILE_INTERNAL_INFORMATION *info = ptr;
|
||||
info->IndexNumber.QuadPart = st->st_ino;
|
||||
}
|
||||
break;
|
||||
case FileEndOfFileInformation:
|
||||
{
|
||||
FILE_END_OF_FILE_INFORMATION *info = ptr;
|
||||
info->EndOfFile.QuadPart = S_ISDIR(st->st_mode) ? 0 : st->st_size;
|
||||
}
|
||||
break;
|
||||
case FileAllInformation:
|
||||
{
|
||||
FILE_ALL_INFORMATION *info = ptr;
|
||||
fill_file_info( st, attr, &info->BasicInformation, FileBasicInformation );
|
||||
fill_file_info( st, attr, &info->StandardInformation, FileStandardInformation );
|
||||
fill_file_info( st, attr, &info->InternalInformation, FileInternalInformation );
|
||||
}
|
||||
break;
|
||||
/* all directory structures start with the FileDirectoryInformation layout */
|
||||
case FileBothDirectoryInformation:
|
||||
case FileFullDirectoryInformation:
|
||||
case FileDirectoryInformation:
|
||||
{
|
||||
FILE_DIRECTORY_INFORMATION *info = ptr;
|
||||
|
||||
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
|
||||
&info->LastAccessTime, &info->CreationTime );
|
||||
if (S_ISDIR(st->st_mode))
|
||||
{
|
||||
info->AllocationSize.QuadPart = 0;
|
||||
info->EndOfFile.QuadPart = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512;
|
||||
info->EndOfFile.QuadPart = st->st_size;
|
||||
}
|
||||
info->FileAttributes = attr;
|
||||
}
|
||||
break;
|
||||
case FileIdFullDirectoryInformation:
|
||||
{
|
||||
FILE_ID_FULL_DIRECTORY_INFORMATION *info = ptr;
|
||||
info->FileId.QuadPart = st->st_ino;
|
||||
fill_file_info( st, attr, info, FileDirectoryInformation );
|
||||
}
|
||||
break;
|
||||
case FileIdBothDirectoryInformation:
|
||||
{
|
||||
FILE_ID_BOTH_DIRECTORY_INFORMATION *info = ptr;
|
||||
info->FileId.QuadPart = st->st_ino;
|
||||
fill_file_info( st, attr, info, FileDirectoryInformation );
|
||||
}
|
||||
break;
|
||||
case FileIdGlobalTxDirectoryInformation:
|
||||
{
|
||||
FILE_ID_GLOBAL_TX_DIR_INFORMATION *info = ptr;
|
||||
info->FileId.QuadPart = st->st_ino;
|
||||
fill_file_info( st, attr, info, FileDirectoryInformation );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
|
||||
{
|
||||
data_size_t size = 1024;
|
||||
|
@ -2074,51 +1763,6 @@ NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(status = wine_unix_to_nt_file_name( unix_name, &nt_name )))
|
||||
{
|
||||
const WCHAR *ptr = nt_name.Buffer;
|
||||
const WCHAR *end = ptr + (nt_name.Length / sizeof(WCHAR));
|
||||
|
||||
/* Skip the volume mount point. */
|
||||
while (ptr != end && *ptr == '\\') ++ptr;
|
||||
while (ptr != end && *ptr != '\\') ++ptr;
|
||||
while (ptr != end && *ptr == '\\') ++ptr;
|
||||
while (ptr != end && *ptr != '\\') ++ptr;
|
||||
|
||||
info->FileNameLength = (end - ptr) * sizeof(WCHAR);
|
||||
if (*name_len < info->FileNameLength) status = STATUS_BUFFER_OVERFLOW;
|
||||
else *name_len = info->FileNameLength;
|
||||
|
||||
memcpy( info->FileName, ptr, *name_len );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS server_get_file_info( HANDLE handle, IO_STATUS_BLOCK *io, void *buffer,
|
||||
ULONG length, FILE_INFORMATION_CLASS info_class )
|
||||
{
|
||||
SERVER_START_REQ( get_file_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->info_class = info_class;
|
||||
wine_server_set_reply( req, buffer, length );
|
||||
io->u.Status = wine_server_call( req );
|
||||
io->Information = wine_server_reply_size( reply );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (io->u.Status == STATUS_NOT_IMPLEMENTED)
|
||||
FIXME( "Unsupported info class %x\n", info_class );
|
||||
return io->u.Status;
|
||||
|
||||
}
|
||||
|
||||
/* Find a DOS device which can act as the root of "path".
|
||||
* Similar to find_drive_root(), but returns -1 instead of crossing volumes. */
|
||||
static int find_dos_device( const char *path )
|
||||
|
@ -2260,288 +1904,7 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
|
|||
NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
PVOID ptr, LONG len, FILE_INFORMATION_CLASS class )
|
||||
{
|
||||
static const size_t info_sizes[] =
|
||||
{
|
||||
0,
|
||||
sizeof(FILE_DIRECTORY_INFORMATION), /* FileDirectoryInformation */
|
||||
sizeof(FILE_FULL_DIRECTORY_INFORMATION), /* FileFullDirectoryInformation */
|
||||
sizeof(FILE_BOTH_DIRECTORY_INFORMATION), /* FileBothDirectoryInformation */
|
||||
sizeof(FILE_BASIC_INFORMATION), /* FileBasicInformation */
|
||||
sizeof(FILE_STANDARD_INFORMATION), /* FileStandardInformation */
|
||||
sizeof(FILE_INTERNAL_INFORMATION), /* FileInternalInformation */
|
||||
sizeof(FILE_EA_INFORMATION), /* FileEaInformation */
|
||||
0, /* FileAccessInformation */
|
||||
sizeof(FILE_NAME_INFORMATION), /* FileNameInformation */
|
||||
sizeof(FILE_RENAME_INFORMATION)-sizeof(WCHAR), /* FileRenameInformation */
|
||||
0, /* FileLinkInformation */
|
||||
sizeof(FILE_NAMES_INFORMATION)-sizeof(WCHAR), /* FileNamesInformation */
|
||||
sizeof(FILE_DISPOSITION_INFORMATION), /* FileDispositionInformation */
|
||||
sizeof(FILE_POSITION_INFORMATION), /* FilePositionInformation */
|
||||
sizeof(FILE_FULL_EA_INFORMATION), /* FileFullEaInformation */
|
||||
0, /* FileModeInformation */
|
||||
sizeof(FILE_ALIGNMENT_INFORMATION), /* FileAlignmentInformation */
|
||||
sizeof(FILE_ALL_INFORMATION), /* FileAllInformation */
|
||||
sizeof(FILE_ALLOCATION_INFORMATION), /* FileAllocationInformation */
|
||||
sizeof(FILE_END_OF_FILE_INFORMATION), /* FileEndOfFileInformation */
|
||||
0, /* FileAlternateNameInformation */
|
||||
sizeof(FILE_STREAM_INFORMATION)-sizeof(WCHAR), /* FileStreamInformation */
|
||||
sizeof(FILE_PIPE_INFORMATION), /* FilePipeInformation */
|
||||
sizeof(FILE_PIPE_LOCAL_INFORMATION), /* FilePipeLocalInformation */
|
||||
0, /* FilePipeRemoteInformation */
|
||||
sizeof(FILE_MAILSLOT_QUERY_INFORMATION), /* FileMailslotQueryInformation */
|
||||
0, /* FileMailslotSetInformation */
|
||||
0, /* FileCompressionInformation */
|
||||
0, /* FileObjectIdInformation */
|
||||
0, /* FileCompletionInformation */
|
||||
0, /* FileMoveClusterInformation */
|
||||
0, /* FileQuotaInformation */
|
||||
0, /* FileReparsePointInformation */
|
||||
sizeof(FILE_NETWORK_OPEN_INFORMATION), /* FileNetworkOpenInformation */
|
||||
sizeof(FILE_ATTRIBUTE_TAG_INFORMATION), /* FileAttributeTagInformation */
|
||||
0, /* FileTrackingInformation */
|
||||
0, /* FileIdBothDirectoryInformation */
|
||||
0, /* FileIdFullDirectoryInformation */
|
||||
0, /* FileValidDataLengthInformation */
|
||||
0, /* FileShortNameInformation */
|
||||
0, /* FileIoCompletionNotificationInformation, */
|
||||
0, /* FileIoStatusBlockRangeInformation */
|
||||
0, /* FileIoPriorityHintInformation */
|
||||
0, /* FileSfioReserveInformation */
|
||||
0, /* FileSfioVolumeInformation */
|
||||
0, /* FileHardLinkInformation */
|
||||
0, /* FileProcessIdsUsingFileInformation */
|
||||
0, /* FileNormalizedNameInformation */
|
||||
0, /* FileNetworkPhysicalNameInformation */
|
||||
0, /* FileIdGlobalTxDirectoryInformation */
|
||||
0, /* FileIsRemoteDeviceInformation */
|
||||
0, /* FileAttributeCacheInformation */
|
||||
0, /* FileNumaNodeInformation */
|
||||
0, /* FileStandardLinkInformation */
|
||||
0, /* FileRemoteProtocolInformation */
|
||||
0, /* FileRenameInformationBypassAccessCheck */
|
||||
0, /* FileLinkInformationBypassAccessCheck */
|
||||
0, /* FileVolumeNameInformation */
|
||||
sizeof(FILE_ID_INFORMATION), /* FileIdInformation */
|
||||
0, /* FileIdExtdDirectoryInformation */
|
||||
0, /* FileReplaceCompletionInformation */
|
||||
0, /* FileHardLinkFullIdInformation */
|
||||
0, /* FileIdExtdBothDirectoryInformation */
|
||||
};
|
||||
|
||||
struct stat st;
|
||||
int fd, needs_close = FALSE;
|
||||
ULONG attr;
|
||||
unsigned int options;
|
||||
|
||||
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
|
||||
|
||||
io->Information = 0;
|
||||
|
||||
if (class <= 0 || class >= FileMaximumInformation)
|
||||
return io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
if (!info_sizes[class])
|
||||
return server_get_file_info( hFile, io, ptr, len, class );
|
||||
if (len < info_sizes[class])
|
||||
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
if ((io->u.Status = unix_funcs->server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, &options )))
|
||||
{
|
||||
if (io->u.Status != STATUS_BAD_DEVICE_TYPE) return io->u.Status;
|
||||
return server_get_file_info( hFile, io, ptr, len, class );
|
||||
}
|
||||
|
||||
switch (class)
|
||||
{
|
||||
case FileBasicInformation:
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -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
|
||||
fill_file_info( &st, attr, ptr, class );
|
||||
break;
|
||||
case FileStandardInformation:
|
||||
{
|
||||
FILE_STANDARD_INFORMATION *info = ptr;
|
||||
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
fill_file_info( &st, attr, info, class );
|
||||
info->DeletePending = FALSE; /* FIXME */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FilePositionInformation:
|
||||
{
|
||||
FILE_POSITION_INFORMATION *info = ptr;
|
||||
off_t res = lseek( fd, 0, SEEK_CUR );
|
||||
if (res == (off_t)-1) io->u.Status = FILE_GetNtStatus();
|
||||
else info->CurrentByteOffset.QuadPart = res;
|
||||
}
|
||||
break;
|
||||
case FileInternalInformation:
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else fill_file_info( &st, attr, ptr, class );
|
||||
break;
|
||||
case FileEaInformation:
|
||||
{
|
||||
FILE_EA_INFORMATION *info = ptr;
|
||||
info->EaSize = 0;
|
||||
}
|
||||
break;
|
||||
case FileEndOfFileInformation:
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else fill_file_info( &st, attr, ptr, class );
|
||||
break;
|
||||
case FileAllInformation:
|
||||
{
|
||||
FILE_ALL_INFORMATION *info = ptr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -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 if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
|
||||
{
|
||||
LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
|
||||
|
||||
fill_file_info( &st, attr, info, FileAllInformation );
|
||||
info->StandardInformation.DeletePending = FALSE; /* FIXME */
|
||||
info->EaInformation.EaSize = 0;
|
||||
info->AccessInformation.AccessFlags = 0; /* FIXME */
|
||||
info->PositionInformation.CurrentByteOffset.QuadPart = lseek( fd, 0, SEEK_CUR );
|
||||
info->ModeInformation.Mode = 0; /* FIXME */
|
||||
info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */
|
||||
|
||||
io->u.Status = fill_name_info( &unix_name, &info->NameInformation, &name_len );
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileMailslotQueryInformation:
|
||||
{
|
||||
FILE_MAILSLOT_QUERY_INFORMATION *info = ptr;
|
||||
|
||||
SERVER_START_REQ( set_mailslot_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( hFile );
|
||||
req->flags = 0;
|
||||
io->u.Status = wine_server_call( req );
|
||||
if( io->u.Status == STATUS_SUCCESS )
|
||||
{
|
||||
info->MaximumMessageSize = reply->max_msgsize;
|
||||
info->MailslotQuota = 0;
|
||||
info->NextMessageSize = 0;
|
||||
info->MessagesAvailable = 0;
|
||||
info->ReadTimeout.QuadPart = reply->read_timeout;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!io->u.Status)
|
||||
{
|
||||
char *tmpbuf;
|
||||
ULONG size = info->MaximumMessageSize ? info->MaximumMessageSize : 0x10000;
|
||||
if (size > 0x10000) size = 0x10000;
|
||||
if ((tmpbuf = RtlAllocateHeap( GetProcessHeap(), 0, size )))
|
||||
{
|
||||
if (!unix_funcs->server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))
|
||||
{
|
||||
int res = recv( fd, tmpbuf, size, MSG_PEEK );
|
||||
info->MessagesAvailable = (res > 0);
|
||||
info->NextMessageSize = (res >= 0) ? res : MAILSLOT_NO_MESSAGE;
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, tmpbuf );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileNameInformation:
|
||||
{
|
||||
FILE_NAME_INFORMATION *info = ptr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
|
||||
{
|
||||
LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
|
||||
io->u.Status = fill_name_info( &unix_name, info, &name_len );
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileNetworkOpenInformation:
|
||||
{
|
||||
FILE_NETWORK_OPEN_INFORMATION *info = ptr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
|
||||
{
|
||||
ULONG attributes;
|
||||
struct stat st;
|
||||
|
||||
if (get_file_info( unix_name.Buffer, &st, &attributes ) == -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
|
||||
{
|
||||
FILE_BASIC_INFORMATION basic;
|
||||
FILE_STANDARD_INFORMATION std;
|
||||
|
||||
fill_file_info( &st, attributes, &basic, FileBasicInformation );
|
||||
fill_file_info( &st, attributes, &std, FileStandardInformation );
|
||||
|
||||
info->CreationTime = basic.CreationTime;
|
||||
info->LastAccessTime = basic.LastAccessTime;
|
||||
info->LastWriteTime = basic.LastWriteTime;
|
||||
info->ChangeTime = basic.ChangeTime;
|
||||
info->AllocationSize = std.AllocationSize;
|
||||
info->EndOfFile = std.EndOfFile;
|
||||
info->FileAttributes = basic.FileAttributes;
|
||||
}
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileIdInformation:
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
struct mountmgr_unix_drive *drive;
|
||||
FILE_ID_INFORMATION *info = ptr;
|
||||
|
||||
info->VolumeSerialNumber = 0;
|
||||
if ((drive = get_mountmgr_fs_info( hFile, fd )))
|
||||
{
|
||||
info->VolumeSerialNumber = drive->serial;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, drive );
|
||||
}
|
||||
memset( &info->FileId, 0, sizeof(info->FileId) );
|
||||
*(ULONGLONG *)&info->FileId = st.st_ino;
|
||||
}
|
||||
break;
|
||||
case FileAttributeTagInformation:
|
||||
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr;
|
||||
info->FileAttributes = attr;
|
||||
info->ReparseTag = 0; /* FIXME */
|
||||
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st ))
|
||||
info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported class (%d)\n", class);
|
||||
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
if (needs_close) close( fd );
|
||||
if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
|
||||
return io->u.Status;
|
||||
return unix_funcs->NtQueryInformationFile( hFile, io, ptr, len, class );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -2564,317 +1927,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class)
|
||||
{
|
||||
int fd, needs_close;
|
||||
|
||||
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", handle, io, ptr, len, class);
|
||||
|
||||
io->u.Status = STATUS_SUCCESS;
|
||||
switch (class)
|
||||
{
|
||||
case FileBasicInformation:
|
||||
if (len >= sizeof(FILE_BASIC_INFORMATION))
|
||||
{
|
||||
struct stat st;
|
||||
const FILE_BASIC_INFORMATION *info = ptr;
|
||||
LARGE_INTEGER mtime, atime;
|
||||
|
||||
if ((io->u.Status = unix_funcs->server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
|
||||
mtime.QuadPart = info->LastWriteTime.QuadPart == -1 ? 0 : info->LastWriteTime.QuadPart;
|
||||
atime.QuadPart = info->LastAccessTime.QuadPart == -1 ? 0 : info->LastAccessTime.QuadPart;
|
||||
|
||||
if (atime.QuadPart || mtime.QuadPart)
|
||||
io->u.Status = set_file_times( fd, &mtime, &atime );
|
||||
|
||||
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)
|
||||
{
|
||||
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
if (info->FileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
{
|
||||
if (S_ISDIR( st.st_mode))
|
||||
WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
|
||||
else
|
||||
st.st_mode &= ~0222; /* clear write permission bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add write permission only where we already have read permission */
|
||||
st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~FILE_umask);
|
||||
}
|
||||
if (fchmod( fd, st.st_mode ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FilePositionInformation:
|
||||
if (len >= sizeof(FILE_POSITION_INFORMATION))
|
||||
{
|
||||
const FILE_POSITION_INFORMATION *info = ptr;
|
||||
|
||||
if ((io->u.Status = unix_funcs->server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
|
||||
if (lseek( fd, info->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
|
||||
io->u.Status = FILE_GetNtStatus();
|
||||
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileEndOfFileInformation:
|
||||
if (len >= sizeof(FILE_END_OF_FILE_INFORMATION))
|
||||
{
|
||||
struct stat st;
|
||||
const FILE_END_OF_FILE_INFORMATION *info = ptr;
|
||||
|
||||
if ((io->u.Status = unix_funcs->server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
|
||||
/* first try normal truncate */
|
||||
if (ftruncate( fd, (off_t)info->EndOfFile.QuadPart ) != -1) break;
|
||||
|
||||
/* now check for the need to extend the file */
|
||||
if (fstat( fd, &st ) != -1 && (off_t)info->EndOfFile.QuadPart > st.st_size)
|
||||
{
|
||||
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 &&
|
||||
ftruncate( fd, (off_t)info->EndOfFile.QuadPart ) != -1) break;
|
||||
}
|
||||
io->u.Status = FILE_GetNtStatus();
|
||||
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FilePipeInformation:
|
||||
if (len >= sizeof(FILE_PIPE_INFORMATION))
|
||||
{
|
||||
FILE_PIPE_INFORMATION *info = ptr;
|
||||
|
||||
if ((info->CompletionMode | info->ReadMode) & ~1)
|
||||
{
|
||||
io->u.Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_named_pipe_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = (info->CompletionMode ? NAMED_PIPE_NONBLOCKING_MODE : 0) |
|
||||
(info->ReadMode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0);
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileMailslotSetInformation:
|
||||
{
|
||||
FILE_MAILSLOT_SET_INFORMATION *info = ptr;
|
||||
|
||||
SERVER_START_REQ( set_mailslot_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = MAILSLOT_SET_READ_TIMEOUT;
|
||||
req->read_timeout = info->ReadTimeout.QuadPart;
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
break;
|
||||
|
||||
case FileCompletionInformation:
|
||||
if (len >= sizeof(FILE_COMPLETION_INFORMATION))
|
||||
{
|
||||
FILE_COMPLETION_INFORMATION *info = ptr;
|
||||
|
||||
SERVER_START_REQ( set_completion_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->chandle = wine_server_obj_handle( info->CompletionPort );
|
||||
req->ckey = info->CompletionKey;
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
} else
|
||||
io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileIoCompletionNotificationInformation:
|
||||
if (len >= sizeof(FILE_IO_COMPLETION_NOTIFICATION_INFORMATION))
|
||||
{
|
||||
FILE_IO_COMPLETION_NOTIFICATION_INFORMATION *info = ptr;
|
||||
|
||||
if (info->Flags & FILE_SKIP_SET_USER_EVENT_ON_FAST_IO)
|
||||
FIXME( "FILE_SKIP_SET_USER_EVENT_ON_FAST_IO not supported\n" );
|
||||
|
||||
SERVER_START_REQ( set_fd_completion_mode )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = info->Flags;
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
} else
|
||||
io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
|
||||
case FileIoPriorityHintInformation:
|
||||
if (len >= sizeof(FILE_IO_PRIORITY_HINT_INFO))
|
||||
{
|
||||
FILE_IO_PRIORITY_HINT_INFO *info = ptr;
|
||||
if (info->PriorityHint < MaximumIoPriorityHintType)
|
||||
TRACE( "ignoring FileIoPriorityHintInformation %u\n", info->PriorityHint );
|
||||
else
|
||||
io->u.Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
|
||||
case FileAllInformation:
|
||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
|
||||
case FileValidDataLengthInformation:
|
||||
if (len >= sizeof(FILE_VALID_DATA_LENGTH_INFORMATION))
|
||||
{
|
||||
struct stat st;
|
||||
const FILE_VALID_DATA_LENGTH_INFORMATION *info = ptr;
|
||||
|
||||
if ((io->u.Status = unix_funcs->server_get_unix_fd( handle, FILE_WRITE_DATA, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
|
||||
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else if (info->ValidDataLength.QuadPart <= 0 || (off_t)info->ValidDataLength.QuadPart > st.st_size)
|
||||
io->u.Status = STATUS_INVALID_PARAMETER;
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_FALLOCATE
|
||||
if (fallocate( fd, 0, 0, (off_t)info->ValidDataLength.QuadPart ) == -1)
|
||||
{
|
||||
NTSTATUS status = FILE_GetNtStatus();
|
||||
if (status == STATUS_NOT_SUPPORTED) WARN( "fallocate not supported on this filesystem\n" );
|
||||
else io->u.Status = status;
|
||||
}
|
||||
#else
|
||||
FIXME( "setting valid data length not supported\n" );
|
||||
#endif
|
||||
}
|
||||
if (needs_close) close( fd );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileDispositionInformation:
|
||||
if (len >= sizeof(FILE_DISPOSITION_INFORMATION))
|
||||
{
|
||||
FILE_DISPOSITION_INFORMATION *info = ptr;
|
||||
|
||||
SERVER_START_REQ( set_fd_disp_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->unlink = info->DoDeleteFile;
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
} else
|
||||
io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileRenameInformation:
|
||||
if (len >= sizeof(FILE_RENAME_INFORMATION))
|
||||
{
|
||||
FILE_RENAME_INFORMATION *info = ptr;
|
||||
UNICODE_STRING name_str;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
name_str.Buffer = info->FileName;
|
||||
name_str.Length = info->FileNameLength;
|
||||
name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR);
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.ObjectName = &name_str;
|
||||
attr.RootDirectory = info->RootDirectory;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
|
||||
io->u.Status = unix_funcs->nt_to_unix_file_name_attr( &attr, &unix_name, FILE_OPEN_IF );
|
||||
if (io->u.Status != STATUS_SUCCESS && io->u.Status != STATUS_NO_SUCH_FILE)
|
||||
break;
|
||||
|
||||
SERVER_START_REQ( set_fd_name_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->rootdir = wine_server_obj_handle( attr.RootDirectory );
|
||||
req->link = FALSE;
|
||||
req->replace = info->ReplaceIfExists;
|
||||
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
case FileLinkInformation:
|
||||
if (len >= sizeof(FILE_LINK_INFORMATION))
|
||||
{
|
||||
FILE_LINK_INFORMATION *info = ptr;
|
||||
UNICODE_STRING name_str;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
name_str.Buffer = info->FileName;
|
||||
name_str.Length = info->FileNameLength;
|
||||
name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR);
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.ObjectName = &name_str;
|
||||
attr.RootDirectory = info->RootDirectory;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
|
||||
io->u.Status = unix_funcs->nt_to_unix_file_name_attr( &attr, &unix_name, FILE_OPEN_IF );
|
||||
if (io->u.Status != STATUS_SUCCESS && io->u.Status != STATUS_NO_SUCH_FILE)
|
||||
break;
|
||||
|
||||
SERVER_START_REQ( set_fd_name_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->rootdir = wine_server_obj_handle( attr.RootDirectory );
|
||||
req->link = TRUE;
|
||||
req->replace = info->ReplaceIfExists;
|
||||
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
}
|
||||
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unsupported class (%d)\n", class);
|
||||
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
io->Information = 0;
|
||||
return io->u.Status;
|
||||
return unix_funcs->NtSetInformationFile( handle, io, ptr, len, class );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4384,10 +4384,6 @@ void __wine_process_init(void)
|
|||
init_user_process_params( info_size );
|
||||
params = peb->ProcessParameters;
|
||||
|
||||
/* retrieve current umask */
|
||||
FILE_umask = umask(0777);
|
||||
umask( FILE_umask );
|
||||
|
||||
load_global_options();
|
||||
version_init();
|
||||
|
||||
|
|
|
@ -203,7 +203,6 @@ static inline int get_unix_exit_code( NTSTATUS status )
|
|||
return status;
|
||||
}
|
||||
|
||||
extern mode_t FILE_umask DECLSPEC_HIDDEN;
|
||||
extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN;
|
||||
|
||||
#define HASH_STRING_ALGORITHM_DEFAULT 0
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -864,6 +864,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtQueryDirectoryFile,
|
||||
NtQueryEvent,
|
||||
NtQueryFullAttributesFile,
|
||||
NtQueryInformationFile,
|
||||
NtQueryInformationJobObject,
|
||||
NtQueryIoCompletion,
|
||||
NtQueryMutant,
|
||||
|
@ -886,6 +887,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtResumeThread,
|
||||
NtSetContextThread,
|
||||
NtSetEvent,
|
||||
NtSetInformationFile,
|
||||
NtSetInformationJobObject,
|
||||
NtSetIoCompletion,
|
||||
NtSetLdtEntries,
|
||||
|
@ -955,8 +957,6 @@ static struct unix_funcs unix_funcs =
|
|||
server_handle_to_fd,
|
||||
server_release_fd,
|
||||
server_init_process_done,
|
||||
file_id_to_unix_file_name,
|
||||
nt_to_unix_file_name_attr,
|
||||
nt_to_unix_file_name,
|
||||
unmount_device,
|
||||
set_show_dot_files,
|
||||
|
|
|
@ -120,9 +120,6 @@ extern NTSTATUS CDECL exec_process( const UNICODE_STRING *cmdline, const pe_imag
|
|||
extern NTSTATUS CDECL fork_and_exec( const char *unix_name, const char *unix_dir,
|
||||
const RTL_USER_PROCESS_PARAMETERS *params ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern NTSTATUS CDECL file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
|
||||
UINT disposition ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
||||
UINT disposition, BOOLEAN check_case ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL unmount_device( HANDLE handle ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 45
|
||||
#define NTDLL_UNIXLIB_VERSION 46
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -129,6 +129,8 @@ struct unix_funcs
|
|||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQueryFullAttributesFile)( const OBJECT_ATTRIBUTES *attr,
|
||||
FILE_NETWORK_OPEN_INFORMATION *info );
|
||||
NTSTATUS (WINAPI *NtQueryInformationFile)( HANDLE hFile, IO_STATUS_BLOCK *io,
|
||||
void *ptr, LONG len, FILE_INFORMATION_CLASS class );
|
||||
NTSTATUS (WINAPI *NtQueryInformationJobObject)( HANDLE handle, JOBOBJECTINFOCLASS class,
|
||||
void *info, ULONG len, ULONG *ret_len );
|
||||
NTSTATUS (WINAPI *NtQueryIoCompletion)( HANDLE handle, IO_COMPLETION_INFORMATION_CLASS class,
|
||||
|
@ -165,6 +167,8 @@ struct unix_funcs
|
|||
NTSTATUS (WINAPI *NtResumeThread)( HANDLE handle, ULONG *count );
|
||||
NTSTATUS (WINAPI *NtSetContextThread)( HANDLE handle, const CONTEXT *context );
|
||||
NTSTATUS (WINAPI *NtSetEvent)( HANDLE handle, LONG *prev_state );
|
||||
NTSTATUS (WINAPI *NtSetInformationFile)( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||
void *ptr, ULONG len, FILE_INFORMATION_CLASS class );
|
||||
NTSTATUS (WINAPI *NtSetInformationJobObject)( HANDLE handle, JOBOBJECTINFOCLASS class,
|
||||
void *info, ULONG len );
|
||||
NTSTATUS (WINAPI *NtSetIoCompletion)( HANDLE handle, ULONG_PTR key, ULONG_PTR value,
|
||||
|
@ -273,10 +277,6 @@ struct unix_funcs
|
|||
void (CDECL *server_init_process_done)( void *relay );
|
||||
|
||||
/* file functions */
|
||||
NTSTATUS (CDECL *file_id_to_unix_file_name)( const OBJECT_ATTRIBUTES *attr,
|
||||
ANSI_STRING *unix_name );
|
||||
NTSTATUS (CDECL *nt_to_unix_file_name_attr)( const OBJECT_ATTRIBUTES *attr,
|
||||
ANSI_STRING *unix_name_ret, UINT disposition );
|
||||
NTSTATUS (CDECL *nt_to_unix_file_name)( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
||||
UINT disposition, BOOLEAN check_case );
|
||||
NTSTATUS (CDECL *unmount_device)( HANDLE handle );
|
||||
|
|
Loading…
Reference in New Issue