Commit da1df741 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Use the common fill_stat_info function from the directory code too.

parent c3b602aa
...@@ -933,6 +933,7 @@ static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, ULONG_PTR *pos, ...@@ -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 long_nameW[MAX_DIR_ENTRY_LEN];
WCHAR short_nameW[12]; WCHAR short_nameW[12];
UNICODE_STRING str; UNICODE_STRING str;
ULONG attributes = 0;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN ); long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
if (long_len == -1) return NULL; if (long_len == -1) return NULL;
...@@ -973,45 +974,24 @@ static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, ULONG_PTR *pos, ...@@ -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; if (*pos + total_len > max_length) total_len = max_length - *pos;
info->FileAttributes = 0;
if (lstat( long_name, &st ) == -1) return NULL; if (lstat( long_name, &st ) == -1) return NULL;
if (S_ISLNK( st.st_mode )) if (S_ISLNK( st.st_mode ))
{ {
if (stat( long_name, &st ) == -1) return NULL; 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 )) if (is_ignored_file( &st ))
{ {
TRACE( "ignoring file %s\n", long_name ); TRACE( "ignoring file %s\n", long_name );
return NULL; 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->NextEntryOffset = total_len;
info->FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */ info->FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
info->FileAttributes |= attributes;
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->EaSize = 0; /* FIXME */ info->EaSize = 0; /* FIXME */
info->ShortNameLength = short_len * sizeof(WCHAR); info->ShortNameLength = short_len * sizeof(WCHAR);
for (i = 0; i < short_len; i++) info->ShortName[i] = toupperW(short_nameW[i]); for (i = 0; i < short_len; i++) info->ShortName[i] = toupperW(short_nameW[i]);
......
...@@ -1486,8 +1486,26 @@ NTSTATUS WINAPI NtSetVolumeInformationFile( ...@@ -1486,8 +1486,26 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
return 0; 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 */ /* 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) switch (class)
{ {
...@@ -1495,23 +1513,12 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI ...@@ -1495,23 +1513,12 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI
{ {
FILE_BASIC_INFORMATION *info = ptr; 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; if (S_ISDIR(st->st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE; else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
info->FileAttributes |= FILE_ATTRIBUTE_READONLY; 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; break;
case FileStandardInformation: case FileStandardInformation:
...@@ -1552,6 +1559,45 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI ...@@ -1552,6 +1559,45 @@ static NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATI
fill_stat_info( st, &info->InternalInformation, FileInternalInformation ); fill_stat_info( st, &info->InternalInformation, FileInternalInformation );
} }
break; 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: default:
return STATUS_INVALID_INFO_CLASS; return STATUS_INVALID_INFO_CLASS;
......
...@@ -138,7 +138,9 @@ extern NTSTATUS TAPE_DeviceIoControl(HANDLE hDevice, ...@@ -138,7 +138,9 @@ extern NTSTATUS TAPE_DeviceIoControl(HANDLE hDevice,
LPVOID lpOutBuffer, DWORD nOutBufferSize); LPVOID lpOutBuffer, DWORD nOutBufferSize);
/* file I/O */ /* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void); 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 void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir );
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ); extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
extern NTSTATUS DIR_unmount_device( HANDLE handle ); extern NTSTATUS DIR_unmount_device( HANDLE handle );
......
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