mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
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.@)
|
||||
*/
|
||||
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
|
||||
{
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
if (!GetFileInformationByHandle( hFile, &info )) return -1;
|
||||
if (filesizehigh) *filesizehigh = info.nFileSizeHigh;
|
||||
return info.nFileSizeLow;
|
||||
LARGE_INTEGER size;
|
||||
if (!GetFileSizeEx( hFile, &size )) return INVALID_FILE_SIZE;
|
||||
if (filesizehigh) *filesizehigh = size.u.HighPart;
|
||||
if (size.u.LowPart == INVALID_FILE_SIZE) SetLastError(0);
|
||||
return size.u.LowPart;
|
||||
}
|
||||
|
||||
|
||||
@ -347,23 +380,53 @@ DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
|
||||
*/
|
||||
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 );
|
||||
return FALSE;
|
||||
*lpFileSize = info.EndOfFile;
|
||||
return TRUE;
|
||||
}
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetFileInformationByHandle( hFile, &info ))
|
||||
|
||||
/***********************************************************************
|
||||
* 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)
|
||||
{
|
||||
return FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
lpFileSize->u.LowPart = info.nFileSizeLow;
|
||||
lpFileSize->u.HighPart = info.nFileSizeHigh;
|
||||
|
||||
return TRUE;
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1037,27 +1037,29 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
|
||||
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
|
||||
{
|
||||
HANDLE ret;
|
||||
DWORD len;
|
||||
static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
|
||||
UNICODE_STRING nt_name;
|
||||
static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
|
||||
|
||||
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
|
||||
debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
|
||||
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
|
||||
|
||||
if (!name)
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
len = strlenW(name);
|
||||
if (len >= MAX_PATH)
|
||||
if (nt_name.Length >= MAX_PATH * sizeof(WCHAR) )
|
||||
{
|
||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
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 );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
SERVER_START_REQ( create_named_pipe )
|
||||
@ -1069,12 +1071,13 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
|
||||
req->insize = nInBufferSize;
|
||||
req->timeout = nDefaultTimeOut;
|
||||
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);
|
||||
if (!wine_server_call_err( req )) ret = reply->handle;
|
||||
else ret = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -156,8 +156,8 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||
{
|
||||
req->access = access;
|
||||
req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer + sizeof(pipeW)/sizeof(WCHAR),
|
||||
attr->ObjectName->Length - sizeof(pipeW) );
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer + 4,
|
||||
attr->ObjectName->Length - 4*sizeof(WCHAR) );
|
||||
io->u.Status = wine_server_call( req );
|
||||
*handle = reply->handle;
|
||||
}
|
||||
@ -835,11 +835,64 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
|
||||
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 */
|
||||
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;
|
||||
|
||||
TRACE("(%p,%p,%p,0x%08lx,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])
|
||||
{
|
||||
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 )))
|
||||
return io->u.Status;
|
||||
|
||||
@ -849,25 +902,19 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
{
|
||||
FILE_BASIC_INFORMATION *info = ptr;
|
||||
|
||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -875,29 +922,22 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
{
|
||||
FILE_STANDARD_INFORMATION *info = ptr;
|
||||
|
||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||
if ((info->Directory = S_ISDIR(st.st_mode)))
|
||||
{
|
||||
info->AllocationSize.QuadPart = 0;
|
||||
info->EndOfFile.QuadPart = 0;
|
||||
info->NumberOfLinks = 1;
|
||||
info->DeletePending = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((info->Directory = S_ISDIR(st.st_mode)))
|
||||
{
|
||||
info->AllocationSize.QuadPart = 0;
|
||||
info->EndOfFile.QuadPart = 0;
|
||||
info->NumberOfLinks = 1;
|
||||
info->DeletePending = FALSE;
|
||||
}
|
||||
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);
|
||||
info->AllocationSize.QuadPart = (ULONGLONG)st.st_blocks * 512;
|
||||
info->EndOfFile.QuadPart = st.st_size;
|
||||
info->NumberOfLinks = st.st_nlink;
|
||||
info->DeletePending = FALSE; /* FIXME */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -905,17 +945,72 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
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:
|
||||
{
|
||||
FILE_INTERNAL_INFORMATION *info = ptr;
|
||||
|
||||
if (len < sizeof(*info)) io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
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
|
||||
{
|
||||
off_t res = lseek( fd, 0, SEEK_CUR );
|
||||
if (res == (off_t)-1) io->u.Status = FILE_GetNtStatus();
|
||||
if ((info->StandardInformation.Directory = S_ISDIR(st.st_mode)))
|
||||
{
|
||||
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->CurrentByteOffset.QuadPart = res;
|
||||
io->Information = sizeof(*info);
|
||||
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;
|
||||
@ -925,6 +1020,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
||||
break;
|
||||
}
|
||||
wine_server_release_fd( hFile, fd );
|
||||
if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
|
||||
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.@)
|
||||
*/
|
||||
|
@ -306,6 +306,41 @@ typedef struct _FILE_STANDARD_INFORMATION {
|
||||
BOOLEAN Directory;
|
||||
} 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 {
|
||||
LARGE_INTEGER CurrentByteOffset;
|
||||
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
|
||||
@ -314,6 +349,14 @@ typedef struct _FILE_ALIGNMENT_INFORMATION {
|
||||
ULONG AlignmentRequirement;
|
||||
} 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 {
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
@ -332,6 +375,10 @@ typedef struct _FILE_FULL_EA_INFORMATION {
|
||||
CHAR EaName[1];
|
||||
} 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
|
||||
{
|
||||
ULONG NextEntryOffset;
|
||||
@ -347,6 +394,19 @@ struct _FILE_ATTRIBUTE_TAG_INFORMATION
|
||||
ULONG ReparseTag;
|
||||
} 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 {
|
||||
FileFsVolumeInformation = 1,
|
||||
FileFsLabelInformation,
|
||||
|
Loading…
Reference in New Issue
Block a user