Commit e4409325 authored by Alexandre Julliard's avatar Alexandre Julliard

Reimplemented GetFileAttributesExW and GetCompressedFileSizeW using

the corresponding ntdll functionality.
parent 66834324
......@@ -1081,6 +1081,151 @@ BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes )
}
/**************************************************************************
* GetFileAttributesExW (KERNEL32.@)
*/
BOOL WINAPI GetFileAttributesExW( LPCWSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr )
{
FILE_NETWORK_OPEN_INFORMATION info;
WIN32_FILE_ATTRIBUTE_DATA *data = ptr;
UNICODE_STRING nt_name;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
if (level != GetFileExInfoStandard)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
{
SetLastError( ERROR_PATH_NOT_FOUND );
return FALSE;
}
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
status = NtQueryFullAttributesFile( &attr, &info );
RtlFreeUnicodeString( &nt_name );
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
data->dwFileAttributes = info.FileAttributes;
data->ftCreationTime.dwLowDateTime = info.CreationTime.u.LowPart;
data->ftCreationTime.dwHighDateTime = info.CreationTime.u.HighPart;
data->ftLastAccessTime.dwLowDateTime = info.LastAccessTime.u.LowPart;
data->ftLastAccessTime.dwHighDateTime = info.LastAccessTime.u.HighPart;
data->ftLastWriteTime.dwLowDateTime = info.LastWriteTime.u.LowPart;
data->ftLastWriteTime.dwHighDateTime = info.LastWriteTime.u.HighPart;
data->nFileSizeLow = info.EndOfFile.u.LowPart;
data->nFileSizeHigh = info.EndOfFile.u.HighPart;
return TRUE;
}
/**************************************************************************
* GetFileAttributesExA (KERNEL32.@)
*/
BOOL WINAPI GetFileAttributesExA( LPCSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr )
{
UNICODE_STRING filenameW;
BOOL ret = FALSE;
if (!name)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
{
ret = GetFileAttributesExW(filenameW.Buffer, level, ptr);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/******************************************************************************
* GetCompressedFileSizeW (KERNEL32.@)
*
* RETURNS
* Success: Low-order doubleword of number of bytes
* Failure: INVALID_FILE_SIZE
*/
DWORD WINAPI GetCompressedFileSizeW(
LPCWSTR name, /* [in] Pointer to name of file */
LPDWORD size_high ) /* [out] Receives high-order doubleword of size */
{
UNICODE_STRING nt_name;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
DWORD ret = INVALID_FILE_SIZE;
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
{
SetLastError( ERROR_PATH_NOT_FOUND );
return INVALID_FILE_SIZE;
}
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
status = NtOpenFile( &handle, 0, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
RtlFreeUnicodeString( &nt_name );
if (status == STATUS_SUCCESS)
{
/* we don't support compressed files, simply return the file size */
ret = GetFileSize( handle, size_high );
NtClose( handle );
}
else SetLastError( RtlNtStatusToDosError(status) );
return ret;
}
/******************************************************************************
* GetCompressedFileSizeA (KERNEL32.@)
*/
DWORD WINAPI GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high )
{
UNICODE_STRING filenameW;
DWORD ret;
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
{
ret = GetCompressedFileSizeW(filenameW.Buffer, size_high);
RtlFreeUnicodeString(&filenameW);
}
else
{
ret = INVALID_FILE_SIZE;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
return ret;
}
/***********************************************************************
* OpenFile (KERNEL32.@)
*/
......
......@@ -984,10 +984,10 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
/******************************************************************************
* NtQueryAttributesFile (NTDLL.@)
* ZwQueryAttributesFile (NTDLL.@)
* NtQueryFullAttributesFile (NTDLL.@)
*/
NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info )
NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
FILE_NETWORK_OPEN_INFORMATION *info )
{
ANSI_STRING unix_name;
NTSTATUS status;
......@@ -1003,8 +1003,18 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
status = STATUS_INVALID_INFO_CLASS;
else
{
if (S_ISDIR(st.st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
if (S_ISDIR(st.st_mode))
{
info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
info->AllocationSize.QuadPart = 0;
info->EndOfFile.QuadPart = 0;
}
else
{
info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
info->AllocationSize.QuadPart = (ULONGLONG)st.st_blocks * 512;
info->EndOfFile.QuadPart = st.st_size;
}
if (!(st.st_mode & S_IWUSR)) info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
RtlSecondsSince1970ToTime( st.st_mtime, &info->CreationTime );
RtlSecondsSince1970ToTime( st.st_mtime, &info->LastWriteTime );
......@@ -1021,6 +1031,27 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
/******************************************************************************
* NtQueryAttributesFile (NTDLL.@)
* ZwQueryAttributesFile (NTDLL.@)
*/
NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info )
{
FILE_NETWORK_OPEN_INFORMATION full_info;
NTSTATUS status;
if (!(status = NtQueryFullAttributesFile( attr, &full_info )))
{
info->CreationTime.QuadPart = full_info.CreationTime.QuadPart;
info->LastAccessTime.QuadPart = full_info.LastAccessTime.QuadPart;
info->LastWriteTime.QuadPart = full_info.LastWriteTime.QuadPart;
info->ChangeTime.QuadPart = full_info.ChangeTime.QuadPart;
info->FileAttributes = full_info.FileAttributes;
}
return status;
}
/******************************************************************************
* NtQueryVolumeInformationFile [NTDLL.@]
* ZwQueryVolumeInformationFile [NTDLL.@]
*
......
......@@ -165,6 +165,7 @@
@ stdcall NtQueryDirectoryObject(long ptr long long long ptr ptr)
@ stub NtQueryEaFile
@ stdcall NtQueryEvent(long long ptr long ptr)
@ stdcall NtQueryFullAttributesFile(ptr ptr)
@ stdcall NtQueryInformationFile(long ptr ptr long long)
@ stub NtQueryInformationPort
@ stdcall NtQueryInformationProcess(long long ptr long ptr)
......@@ -1067,7 +1068,6 @@
@ stub NtAddAtom
@ stub NtDeleteAtom
@ stub NtFindAtom
@ stub NtQueryFullAttributesFile
@ stub NtReadFileScatter
@ stub NtSignalAndWaitForSingleObject
@ stub NtWriteFileGather
......
......@@ -635,65 +635,6 @@ BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION
}
/******************************************************************************
* GetCompressedFileSizeA [KERNEL32.@]
*/
DWORD WINAPI GetCompressedFileSizeA(
LPCSTR lpFileName,
LPDWORD lpFileSizeHigh)
{
UNICODE_STRING filenameW;
DWORD ret;
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, lpFileName))
{
ret = GetCompressedFileSizeW(filenameW.Buffer, lpFileSizeHigh);
RtlFreeUnicodeString(&filenameW);
}
else
{
ret = INVALID_FILE_SIZE;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
return ret;
}
/******************************************************************************
* GetCompressedFileSizeW [KERNEL32.@]
*
* RETURNS
* Success: Low-order doubleword of number of bytes
* Failure: INVALID_FILE_SIZE
*/
DWORD WINAPI GetCompressedFileSizeW(
LPCWSTR lpFileName, /* [in] Pointer to name of file */
LPDWORD lpFileSizeHigh) /* [out] Receives high-order doubleword of size */
{
DOS_FULL_NAME full_name;
struct stat st;
DWORD low;
TRACE("(%s,%p)\n",debugstr_w(lpFileName),lpFileSizeHigh);
if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) return INVALID_FILE_SIZE;
if (stat(full_name.long_name, &st) != 0)
{
FILE_SetDosError();
return INVALID_FILE_SIZE;
}
#if HAVE_STRUCT_STAT_ST_BLOCKS
/* blocks are 512 bytes long */
if (lpFileSizeHigh) *lpFileSizeHigh = (st.st_blocks >> 23);
low = (DWORD)(st.st_blocks << 9);
#else
if (lpFileSizeHigh) *lpFileSizeHigh = (st.st_size >> 32);
low = (DWORD)st.st_size;
#endif
return low;
}
/***********************************************************************
* GetFileTime (KERNEL32.@)
*/
......@@ -1576,68 +1517,3 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
RtlFreeUnicodeString(&destW);
return ret;
}
/**************************************************************************
* GetFileAttributesExW (KERNEL32.@)
*/
BOOL WINAPI GetFileAttributesExW(
LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation)
{
DOS_FULL_NAME full_name;
BY_HANDLE_FILE_INFORMATION info;
if (!lpFileName || !lpFileInformation)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (fInfoLevelId == GetFileExInfoStandard) {
LPWIN32_FILE_ATTRIBUTE_DATA lpFad =
(LPWIN32_FILE_ATTRIBUTE_DATA) lpFileInformation;
if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name )) return FALSE;
if (!FILE_Stat( full_name.long_name, &info, NULL )) return FALSE;
lpFad->dwFileAttributes = info.dwFileAttributes;
lpFad->ftCreationTime = info.ftCreationTime;
lpFad->ftLastAccessTime = info.ftLastAccessTime;
lpFad->ftLastWriteTime = info.ftLastWriteTime;
lpFad->nFileSizeHigh = info.nFileSizeHigh;
lpFad->nFileSizeLow = info.nFileSizeLow;
}
else {
FIXME("invalid info level %d!\n", fInfoLevelId);
return FALSE;
}
return TRUE;
}
/**************************************************************************
* GetFileAttributesExA (KERNEL32.@)
*/
BOOL WINAPI GetFileAttributesExA(
LPCSTR filename, GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation)
{
UNICODE_STRING filenameW;
BOOL ret = FALSE;
if (!filename || !lpFileInformation)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, filename))
{
ret = GetFileAttributesExW(filenameW.Buffer, fInfoLevelId, lpFileInformation);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
......@@ -1174,6 +1174,7 @@ NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PT
NTSTATUS WINAPI NtQueryAttributesFile(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
NTSTATUS WINAPI NtQueryDefaultLocale(BOOLEAN,LCID*);
NTSTATUS WINAPI NtQueryDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
NTSTATUS WINAPI NtQueryFullAttributesFile(const OBJECT_ATTRIBUTES*,FILE_NETWORK_OPEN_INFORMATION*);
NTSTATUS WINAPI NtQueryInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS);
NTSTATUS WINAPI NtQueryInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment