Added a few more info classes in NtQueryInformationFile.
Use NT file names in CreateNamedPipeW. Reimplemented GetFileInformationByHandle, GetFileSize and GetFileTime using ntdll functions.
This commit is contained in:
parent
ff07c20446
commit
d4874d6406
|
@ -330,15 +330,48 @@ BOOL WINAPI FlushFileBuffers( HANDLE hFile )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetFileInformationByHandle (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION *info )
|
||||||
|
{
|
||||||
|
FILE_ALL_INFORMATION all_info;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
status = NtQueryInformationFile( hFile, &io, &all_info, sizeof(all_info), FileAllInformation );
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
info->dwFileAttributes = all_info.BasicInformation.FileAttributes;
|
||||||
|
info->ftCreationTime.dwHighDateTime = all_info.BasicInformation.CreationTime.u.HighPart;
|
||||||
|
info->ftCreationTime.dwLowDateTime = all_info.BasicInformation.CreationTime.u.LowPart;
|
||||||
|
info->ftLastAccessTime.dwHighDateTime = all_info.BasicInformation.LastAccessTime.u.HighPart;
|
||||||
|
info->ftLastAccessTime.dwLowDateTime = all_info.BasicInformation.LastAccessTime.u.LowPart;
|
||||||
|
info->ftLastWriteTime.dwHighDateTime = all_info.BasicInformation.LastWriteTime.u.HighPart;
|
||||||
|
info->ftLastWriteTime.dwLowDateTime = all_info.BasicInformation.LastWriteTime.u.LowPart;
|
||||||
|
info->dwVolumeSerialNumber = 0; /* FIXME */
|
||||||
|
info->nFileSizeHigh = all_info.StandardInformation.EndOfFile.u.HighPart;
|
||||||
|
info->nFileSizeLow = all_info.StandardInformation.EndOfFile.u.LowPart;
|
||||||
|
info->nNumberOfLinks = all_info.StandardInformation.NumberOfLinks;
|
||||||
|
info->nFileIndexHigh = all_info.InternalInformation.IndexNumber.u.HighPart;
|
||||||
|
info->nFileIndexLow = all_info.InternalInformation.IndexNumber.u.LowPart;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetFileSize (KERNEL32.@)
|
* GetFileSize (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
|
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
|
||||||
{
|
{
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
LARGE_INTEGER size;
|
||||||
if (!GetFileInformationByHandle( hFile, &info )) return -1;
|
if (!GetFileSizeEx( hFile, &size )) return INVALID_FILE_SIZE;
|
||||||
if (filesizehigh) *filesizehigh = info.nFileSizeHigh;
|
if (filesizehigh) *filesizehigh = size.u.HighPart;
|
||||||
return info.nFileSizeLow;
|
if (size.u.LowPart == INVALID_FILE_SIZE) SetLastError(0);
|
||||||
|
return size.u.LowPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,24 +380,54 @@ DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
|
BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
|
||||||
{
|
{
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
FILE_END_OF_FILE_INFORMATION info;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!lpFileSize)
|
status = NtQueryInformationFile( hFile, &io, &info, sizeof(info), FileEndOfFileInformation );
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_PARAMETER );
|
*lpFileSize = info.EndOfFile;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetFileInformationByHandle( hFile, &info ))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpFileSize->u.LowPart = info.nFileSizeLow;
|
|
||||||
lpFileSize->u.HighPart = info.nFileSizeHigh;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetFileTime (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI GetFileTime( HANDLE hFile, FILETIME *lpCreationTime,
|
||||||
|
FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime )
|
||||||
|
{
|
||||||
|
FILE_BASIC_INFORMATION info;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
status = NtQueryInformationFile( hFile, &io, &info, sizeof(info), FileBasicInformation );
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
if (lpCreationTime)
|
||||||
|
{
|
||||||
|
lpCreationTime->dwHighDateTime = info.CreationTime.u.HighPart;
|
||||||
|
lpCreationTime->dwLowDateTime = info.CreationTime.u.LowPart;
|
||||||
|
}
|
||||||
|
if (lpLastAccessTime)
|
||||||
|
{
|
||||||
|
lpLastAccessTime->dwHighDateTime = info.LastAccessTime.u.HighPart;
|
||||||
|
lpLastAccessTime->dwLowDateTime = info.LastAccessTime.u.LowPart;
|
||||||
|
}
|
||||||
|
if (lpLastWriteTime)
|
||||||
|
{
|
||||||
|
lpLastWriteTime->dwHighDateTime = info.LastWriteTime.u.HighPart;
|
||||||
|
lpLastWriteTime->dwLowDateTime = info.LastWriteTime.u.LowPart;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -1037,27 +1037,29 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
|
||||||
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
|
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
|
||||||
{
|
{
|
||||||
HANDLE ret;
|
HANDLE ret;
|
||||||
DWORD len;
|
UNICODE_STRING nt_name;
|
||||||
static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
|
static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
|
||||||
|
|
||||||
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
|
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
|
||||||
debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
|
debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
|
||||||
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
|
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
|
||||||
|
|
||||||
if (!name)
|
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
len = strlenW(name);
|
if (nt_name.Length >= MAX_PATH * sizeof(WCHAR) )
|
||||||
if (len >= MAX_PATH)
|
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0])))
|
if (nt_name.Length < sizeof(leadin) ||
|
||||||
|
strncmpiW( nt_name.Buffer, leadin, sizeof(leadin)/sizeof(leadin[0])))
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_NAME );
|
SetLastError( ERROR_INVALID_NAME );
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
SERVER_START_REQ( create_named_pipe )
|
SERVER_START_REQ( create_named_pipe )
|
||||||
|
@ -1069,12 +1071,13 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
|
||||||
req->insize = nInBufferSize;
|
req->insize = nInBufferSize;
|
||||||
req->timeout = nDefaultTimeOut;
|
req->timeout = nDefaultTimeOut;
|
||||||
req->inherit = (attr && (attr->nLength>=sizeof(*attr)) && attr->bInheritHandle);
|
req->inherit = (attr && (attr->nLength>=sizeof(*attr)) && attr->bInheritHandle);
|
||||||
wine_server_add_data( req, name, len * sizeof(WCHAR) );
|
wine_server_add_data( req, nt_name.Buffer + 4, nt_name.Length - 4*sizeof(WCHAR) );
|
||||||
SetLastError(0);
|
SetLastError(0);
|
||||||
if (!wine_server_call_err( req )) ret = reply->handle;
|
if (!wine_server_call_err( req )) ret = reply->handle;
|
||||||
else ret = INVALID_HANDLE_VALUE;
|
else ret = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,8 +156,8 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
{
|
{
|
||||||
req->access = access;
|
req->access = access;
|
||||||
req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
|
req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
|
||||||
wine_server_add_data( req, attr->ObjectName->Buffer + sizeof(pipeW)/sizeof(WCHAR),
|
wine_server_add_data( req, attr->ObjectName->Buffer + 4,
|
||||||
attr->ObjectName->Length - sizeof(pipeW) );
|
attr->ObjectName->Length - 4*sizeof(WCHAR) );
|
||||||
io->u.Status = wine_server_call( req );
|
io->u.Status = wine_server_call( req );
|
||||||
*handle = reply->handle;
|
*handle = reply->handle;
|
||||||
}
|
}
|
||||||
|
@ -835,11 +835,64 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
|
||||||
NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
PVOID ptr, LONG len, FILE_INFORMATION_CLASS class )
|
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 */
|
||||||
|
sizeof(FILE_ACCESS_INFORMATION), /* FileAccessInformation */
|
||||||
|
sizeof(FILE_NAME_INFORMATION)-sizeof(WCHAR), /* 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 */
|
||||||
|
sizeof(FILE_MODE_INFORMATION), /* FileModeInformation */
|
||||||
|
sizeof(FILE_ALIGNMENT_INFORMATION), /* FileAlignmentInformation */
|
||||||
|
sizeof(FILE_ALL_INFORMATION)-sizeof(WCHAR), /* FileAllInformation */
|
||||||
|
sizeof(FILE_ALLOCATION_INFORMATION), /* FileAllocationInformation */
|
||||||
|
sizeof(FILE_END_OF_FILE_INFORMATION), /* FileEndOfFileInformation */
|
||||||
|
0, /* FileAlternateNameInformation */
|
||||||
|
sizeof(FILE_STREAM_INFORMATION)-sizeof(WCHAR), /* FileStreamInformation */
|
||||||
|
0, /* FilePipeInformation */
|
||||||
|
0, /* FilePipeLocalInformation */
|
||||||
|
0, /* FilePipeRemoteInformation */
|
||||||
|
0, /* FileMailslotQueryInformation */
|
||||||
|
0, /* FileMailslotSetInformation */
|
||||||
|
0, /* FileCompressionInformation */
|
||||||
|
0, /* FileObjectIdInformation */
|
||||||
|
0, /* FileCompletionInformation */
|
||||||
|
0, /* FileMoveClusterInformation */
|
||||||
|
0, /* FileQuotaInformation */
|
||||||
|
0, /* FileReparsePointInformation */
|
||||||
|
0, /* FileNetworkOpenInformation */
|
||||||
|
0, /* FileAttributeTagInformation */
|
||||||
|
0 /* FileTrackingInformation */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io, ptr, len, class);
|
TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io, ptr, len, class);
|
||||||
|
|
||||||
io->Information = 0;
|
io->Information = 0;
|
||||||
|
|
||||||
|
if (class <= 0 || class >= FileMaximumInformation)
|
||||||
|
return io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
if (!info_sizes[class])
|
||||||
|
{
|
||||||
|
FIXME("Unsupported class (%d)\n", class);
|
||||||
|
return io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
if (len < info_sizes[class])
|
||||||
|
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
|
||||||
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
|
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
|
||||||
return io->u.Status;
|
return io->u.Status;
|
||||||
|
|
||||||
|
@ -849,11 +902,6 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
{
|
{
|
||||||
FILE_BASIC_INFORMATION *info = ptr;
|
FILE_BASIC_INFORMATION *info = ptr;
|
||||||
|
|
||||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (fstat( fd, &st ) == -1)
|
if (fstat( fd, &st ) == -1)
|
||||||
io->u.Status = FILE_GetNtStatus();
|
io->u.Status = FILE_GetNtStatus();
|
||||||
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
||||||
|
@ -869,17 +917,11 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime);
|
RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
{
|
{
|
||||||
FILE_STANDARD_INFORMATION *info = ptr;
|
FILE_STANDARD_INFORMATION *info = ptr;
|
||||||
|
|
||||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -897,25 +939,78 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
info->NumberOfLinks = st.st_nlink;
|
info->NumberOfLinks = st.st_nlink;
|
||||||
info->DeletePending = FALSE; /* FIXME */
|
info->DeletePending = FALSE; /* FIXME */
|
||||||
}
|
}
|
||||||
io->Information = sizeof(*info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
{
|
{
|
||||||
FILE_POSITION_INFORMATION *info = ptr;
|
FILE_POSITION_INFORMATION *info = ptr;
|
||||||
|
|
||||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
off_t res = lseek( fd, 0, SEEK_CUR );
|
off_t res = lseek( fd, 0, SEEK_CUR );
|
||||||
if (res == (off_t)-1) io->u.Status = FILE_GetNtStatus();
|
if (res == (off_t)-1) io->u.Status = FILE_GetNtStatus();
|
||||||
|
else info->CurrentByteOffset.QuadPart = res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileInternalInformation:
|
||||||
|
{
|
||||||
|
FILE_INTERNAL_INFORMATION *info = ptr;
|
||||||
|
|
||||||
|
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||||
|
else info->IndexNumber.QuadPart = st.st_ino;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileEaInformation:
|
||||||
|
{
|
||||||
|
FILE_EA_INFORMATION *info = ptr;
|
||||||
|
info->EaSize = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileEndOfFileInformation:
|
||||||
|
{
|
||||||
|
FILE_END_OF_FILE_INFORMATION *info = ptr;
|
||||||
|
|
||||||
|
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||||
|
else info->EndOfFile.QuadPart = S_ISDIR(st.st_mode) ? 0 : st.st_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileAllInformation:
|
||||||
|
{
|
||||||
|
FILE_ALL_INFORMATION *info = ptr;
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
info->CurrentByteOffset.QuadPart = res;
|
if ((info->StandardInformation.Directory = S_ISDIR(st.st_mode)))
|
||||||
io->Information = sizeof(*info);
|
{
|
||||||
|
info->BasicInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
info->StandardInformation.AllocationSize.QuadPart = 0;
|
||||||
|
info->StandardInformation.EndOfFile.QuadPart = 0;
|
||||||
|
info->StandardInformation.NumberOfLinks = 1;
|
||||||
|
info->StandardInformation.DeletePending = FALSE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->BasicInformation.FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||||
|
info->StandardInformation.AllocationSize.QuadPart = (ULONGLONG)st.st_blocks * 512;
|
||||||
|
info->StandardInformation.EndOfFile.QuadPart = st.st_size;
|
||||||
|
info->StandardInformation.NumberOfLinks = st.st_nlink;
|
||||||
|
info->StandardInformation.DeletePending = FALSE; /* FIXME */
|
||||||
|
}
|
||||||
|
if (!(st.st_mode & S_IWUSR))
|
||||||
|
info->BasicInformation.FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||||
|
RtlSecondsSince1970ToTime( st.st_mtime, &info->BasicInformation.CreationTime);
|
||||||
|
RtlSecondsSince1970ToTime( st.st_mtime, &info->BasicInformation.LastWriteTime);
|
||||||
|
RtlSecondsSince1970ToTime( st.st_ctime, &info->BasicInformation.ChangeTime);
|
||||||
|
RtlSecondsSince1970ToTime( st.st_atime, &info->BasicInformation.LastAccessTime);
|
||||||
|
info->InternalInformation.IndexNumber.QuadPart = st.st_ino;
|
||||||
|
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 */
|
||||||
|
info->NameInformation.FileNameLength = 0;
|
||||||
|
io->Information = sizeof(*info) - sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -925,6 +1020,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wine_server_release_fd( hFile, fd );
|
wine_server_release_fd( hFile, fd );
|
||||||
|
if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
|
||||||
return io->u.Status;
|
return io->u.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
86
files/file.c
86
files/file.c
|
@ -396,92 +396,6 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* FILE_FillInfo
|
|
||||||
*
|
|
||||||
* Fill a file information from a struct stat.
|
|
||||||
*/
|
|
||||||
static void FILE_FillInfo( struct stat *st, BY_HANDLE_FILE_INFORMATION *info )
|
|
||||||
{
|
|
||||||
if (S_ISDIR(st->st_mode))
|
|
||||||
info->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
else
|
|
||||||
info->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
|
||||||
if (!(st->st_mode & S_IWUSR))
|
|
||||||
info->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
|
|
||||||
|
|
||||||
RtlSecondsSince1970ToTime( st->st_mtime, (LARGE_INTEGER *)&info->ftCreationTime );
|
|
||||||
RtlSecondsSince1970ToTime( st->st_mtime, (LARGE_INTEGER *)&info->ftLastWriteTime );
|
|
||||||
RtlSecondsSince1970ToTime( st->st_atime, (LARGE_INTEGER *)&info->ftLastAccessTime );
|
|
||||||
|
|
||||||
info->dwVolumeSerialNumber = 0; /* FIXME */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetFileInformationByHandle (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION *info )
|
|
||||||
{
|
|
||||||
NTSTATUS status;
|
|
||||||
int fd;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
TRACE("%p,%p\n", hFile, info);
|
|
||||||
|
|
||||||
if (!info) return 0;
|
|
||||||
|
|
||||||
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_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
|
||||||
SetLastError( ERROR_INVALID_FUNCTION );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FILE_FillInfo( &st, info );
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
wine_server_release_fd( hFile, fd );
|
|
||||||
}
|
|
||||||
else SetLastError( RtlNtStatusToDosError(status) );
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetFileTime (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI GetFileTime( HANDLE hFile, FILETIME *lpCreationTime,
|
|
||||||
FILETIME *lpLastAccessTime,
|
|
||||||
FILETIME *lpLastWriteTime )
|
|
||||||
{
|
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
|
||||||
if (!GetFileInformationByHandle( hFile, &info )) return FALSE;
|
|
||||||
if (lpCreationTime) *lpCreationTime = info.ftCreationTime;
|
|
||||||
if (lpLastAccessTime) *lpLastAccessTime = info.ftLastAccessTime;
|
|
||||||
if (lpLastWriteTime) *lpLastWriteTime = info.ftLastWriteTime;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetTempFileNameA (KERNEL32.@)
|
* GetTempFileNameA (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -306,6 +306,41 @@ typedef struct _FILE_STANDARD_INFORMATION {
|
||||||
BOOLEAN Directory;
|
BOOLEAN Directory;
|
||||||
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
|
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_INTERNAL_INFORMATION {
|
||||||
|
LARGE_INTEGER IndexNumber;
|
||||||
|
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_EA_INFORMATION {
|
||||||
|
ULONG EaSize;
|
||||||
|
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ACCESS_INFORMATION {
|
||||||
|
ACCESS_MASK AccessFlags;
|
||||||
|
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_NAME_INFORMATION {
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_RENAME_INFORMATION {
|
||||||
|
BOOLEAN Replace;
|
||||||
|
HANDLE RootDir;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_NAMES_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_DISPOSITION_INFORMATION {
|
||||||
|
BOOLEAN DoDeleteFile;
|
||||||
|
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_POSITION_INFORMATION {
|
typedef struct _FILE_POSITION_INFORMATION {
|
||||||
LARGE_INTEGER CurrentByteOffset;
|
LARGE_INTEGER CurrentByteOffset;
|
||||||
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
|
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
|
||||||
|
@ -314,6 +349,14 @@ typedef struct _FILE_ALIGNMENT_INFORMATION {
|
||||||
ULONG AlignmentRequirement;
|
ULONG AlignmentRequirement;
|
||||||
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
|
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ALLOCATION_INFORMATION {
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
} FILE_ALLOCATION_INFORMATION, *PFILE_ALLOCATION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_END_OF_FILE_INFORMATION {
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
|
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
|
||||||
LARGE_INTEGER CreationTime;
|
LARGE_INTEGER CreationTime;
|
||||||
LARGE_INTEGER LastAccessTime;
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
@ -332,6 +375,10 @@ typedef struct _FILE_FULL_EA_INFORMATION {
|
||||||
CHAR EaName[1];
|
CHAR EaName[1];
|
||||||
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
|
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_MODE_INFORMATION {
|
||||||
|
ULONG Mode;
|
||||||
|
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_STREAM_INFORMATION
|
typedef struct _FILE_STREAM_INFORMATION
|
||||||
{
|
{
|
||||||
ULONG NextEntryOffset;
|
ULONG NextEntryOffset;
|
||||||
|
@ -347,6 +394,19 @@ struct _FILE_ATTRIBUTE_TAG_INFORMATION
|
||||||
ULONG ReparseTag;
|
ULONG ReparseTag;
|
||||||
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
|
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_ALL_INFORMATION
|
||||||
|
{
|
||||||
|
FILE_BASIC_INFORMATION BasicInformation;
|
||||||
|
FILE_STANDARD_INFORMATION StandardInformation;
|
||||||
|
FILE_INTERNAL_INFORMATION InternalInformation;
|
||||||
|
FILE_EA_INFORMATION EaInformation;
|
||||||
|
FILE_ACCESS_INFORMATION AccessInformation;
|
||||||
|
FILE_POSITION_INFORMATION PositionInformation;
|
||||||
|
FILE_MODE_INFORMATION ModeInformation;
|
||||||
|
FILE_ALIGNMENT_INFORMATION AlignmentInformation;
|
||||||
|
FILE_NAME_INFORMATION NameInformation;
|
||||||
|
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
|
||||||
|
|
||||||
typedef enum _FSINFOCLASS {
|
typedef enum _FSINFOCLASS {
|
||||||
FileFsVolumeInformation = 1,
|
FileFsVolumeInformation = 1,
|
||||||
FileFsLabelInformation,
|
FileFsLabelInformation,
|
||||||
|
|
Loading…
Reference in New Issue