From da1df74147698dd083d438688736f62ef0ad571c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 18 Nov 2009 17:23:55 +0100 Subject: [PATCH] ntdll: Use the common fill_stat_info function from the directory code too. --- dlls/ntdll/directory.c | 32 ++++-------------- dlls/ntdll/file.c | 74 +++++++++++++++++++++++++++++++++-------- dlls/ntdll/ntdll_misc.h | 2 ++ 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index e7f1dd45f0..6784e68fac 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -933,6 +933,7 @@ static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, ULONG_PTR *pos, WCHAR long_nameW[MAX_DIR_ENTRY_LEN]; WCHAR short_nameW[12]; UNICODE_STRING str; + ULONG attributes = 0; long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN ); if (long_len == -1) return NULL; @@ -973,45 +974,24 @@ static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, ULONG_PTR *pos, if (*pos + total_len > max_length) total_len = max_length - *pos; - info->FileAttributes = 0; if (lstat( long_name, &st ) == -1) return NULL; if (S_ISLNK( st.st_mode )) { if (stat( long_name, &st ) == -1) return NULL; - if (S_ISDIR( st.st_mode )) info->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT; + if (S_ISDIR( st.st_mode )) attributes |= FILE_ATTRIBUTE_REPARSE_POINT; } if (is_ignored_file( &st )) { TRACE( "ignoring file %s\n", long_name ); return NULL; } + if (!show_dot_files && long_name[0] == '.' && long_name[1] && (long_name[1] != '.' || long_name[2])) + attributes |= FILE_ATTRIBUTE_HIDDEN; + fill_stat_info( &st, info, FileBothDirectoryInformation ); info->NextEntryOffset = total_len; info->FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */ - - RtlSecondsSince1970ToTime( st.st_mtime, &info->CreationTime ); - RtlSecondsSince1970ToTime( st.st_mtime, &info->LastWriteTime ); - RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime ); - RtlSecondsSince1970ToTime( st.st_ctime, &info->ChangeTime ); - - if (S_ISDIR(st.st_mode)) - { - info->EndOfFile.QuadPart = info->AllocationSize.QuadPart = 0; - info->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; - } - else - { - info->EndOfFile.QuadPart = st.st_size; - info->AllocationSize.QuadPart = (ULONGLONG)st.st_blocks * 512; - info->FileAttributes |= FILE_ATTRIBUTE_ARCHIVE; - } - - if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) - info->FileAttributes |= FILE_ATTRIBUTE_READONLY; - - if (!show_dot_files && long_name[0] == '.' && long_name[1] && (long_name[1] != '.' || long_name[2])) - info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; - + info->FileAttributes |= attributes; info->EaSize = 0; /* FIXME */ info->ShortNameLength = short_len * sizeof(WCHAR); for (i = 0; i < short_len; i++) info->ShortName[i] = toupperW(short_nameW[i]); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 8014e15044..32e5f93a0e 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1486,8 +1486,26 @@ NTSTATUS WINAPI NtSetVolumeInformationFile( return 0; } +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; +#endif +#ifdef HAVE_STRUCT_STAT_ST_CTIM + ctime->QuadPart += st->st_ctim.tv_nsec / 100; +#endif +#ifdef HAVE_STRUCT_STAT_ST_ATIM + atime->QuadPart += st->st_atim.tv_nsec / 100; +#endif + *creation = *mtime; +} + /* fill in the file information that depends on the stat info */ -static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) +NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) { switch (class) { @@ -1495,23 +1513,12 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI { FILE_BASIC_INFORMATION *info = ptr; + get_file_times( st, &info->LastWriteTime, &info->ChangeTime, + &info->LastAccessTime, &info->CreationTime ); if (S_ISDIR(st->st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE; if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) info->FileAttributes |= FILE_ATTRIBUTE_READONLY; - RtlSecondsSince1970ToTime( st->st_mtime, &info->LastWriteTime ); - RtlSecondsSince1970ToTime( st->st_ctime, &info->ChangeTime ); - RtlSecondsSince1970ToTime( st->st_atime, &info->LastAccessTime ); -#ifdef HAVE_STRUCT_STAT_ST_MTIM - info->LastWriteTime.QuadPart += st->st_mtim.tv_nsec / 100; -#endif -#ifdef HAVE_STRUCT_STAT_ST_CTIM - info->ChangeTime.QuadPart += st->st_ctim.tv_nsec / 100; -#endif -#ifdef HAVE_STRUCT_STAT_ST_ATIM - info->LastAccessTime.QuadPart += st->st_atim.tv_nsec / 100; -#endif - info->CreationTime = info->LastWriteTime; } break; case FileStandardInformation: @@ -1552,6 +1559,45 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI fill_stat_info( st, &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; + info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; + } + else + { + info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512; + info->EndOfFile.QuadPart = st->st_size; + info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE; + } + if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) + info->FileAttributes |= FILE_ATTRIBUTE_READONLY; + } + break; + case FileIdFullDirectoryInformation: + { + FILE_ID_FULL_DIRECTORY_INFORMATION *info = ptr; + info->FileId.QuadPart = st->st_ino; + fill_stat_info( st, info, FileDirectoryInformation ); + } + break; + case FileIdBothDirectoryInformation: + { + FILE_ID_BOTH_DIRECTORY_INFORMATION *info = ptr; + info->FileId.QuadPart = st->st_ino; + fill_stat_info( st, info, FileDirectoryInformation ); + } + break; default: return STATUS_INVALID_INFO_CLASS; diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index b3842e0396..be6c770afe 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -138,7 +138,9 @@ extern NTSTATUS TAPE_DeviceIoControl(HANDLE hDevice, LPVOID lpOutBuffer, DWORD nOutBufferSize); /* file I/O */ +struct stat; extern NTSTATUS FILE_GetNtStatus(void); +extern NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ); extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ); extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ); extern NTSTATUS DIR_unmount_device( HANDLE handle ); -- 2.32.0.93.g670b81a890