Implemented sub-second W32 filesystem interface by new: CaptiveFileInfoObject
[captive.git] / src / libcaptive / client / directory-slave.c
index 1a6f6b6..3e8c4be 100644 (file)
 #include "captive/usecount.h"
 #include "vfs.h"
 #include "vfs-slave.h"
+#include "captive/rtl-time.h"
 
 
 static gpointer captive_directory_slave_object_parent_class=NULL;
 
 static GnomeVFSResult captive_directory_slave_close(CaptiveDirectoryObject *captive_directory_object);
 static GnomeVFSResult captive_directory_slave_read
-               (CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info);
+               (CaptiveDirectoryObject *captive_directory_object,CaptiveFileInfoObject **captive_file_info_object_return);
 static GnomeVFSResult captive_directory_slave_remove(CaptiveDirectoryObject *captive_directory_object);
 
 
@@ -218,16 +219,21 @@ CaptiveDirectorySlaveObject *captive_directory_slave_object;
 }
 
 
-static GnomeVFSResult FileIdBothDirInformation_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
+static GnomeVFSResult FileIdBothDirInformation_to_CaptiveFileInfoObject(
+               CaptiveFileInfoObject **captive_file_info_object_return,
                FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation,IO_STATUS_BLOCK *IoStatusBlock)
 {
 UNICODE_STRING FileName_UnicodeString;
-ULONG tmp_ULONG;
+GnomeVFSResult errvfsresult;
+CaptiveFileInfoObject *captive_file_info_object;
 
-       g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_GENERIC);
+       g_return_val_if_fail(captive_file_info_object_return!=NULL,GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(FileIdBothDirInformation!=NULL,GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(IoStatusBlock!=NULL,GNOME_VFS_ERROR_GENERIC);
 
+       errvfsresult=captive_file_info_object_new(&captive_file_info_object);
+       g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
+
        g_return_val_if_fail(NT_SUCCESS(IoStatusBlock->Status),GNOME_VFS_ERROR_GENERIC);
        /* do not exceed the returned buffer by this record; Redundant now, see below. */
        g_assert((gpointer)(((char *)FileIdBothDirInformation)+FileIdBothDirInformation->NextEntryOffset)
@@ -235,7 +241,7 @@ ULONG tmp_ULONG;
        /* '->NextEntryOffset' is ==0 as we used 'ReturnSingleEntry==TRUE' */
        g_assert(FileIdBothDirInformation->NextEntryOffset==0);
 
-       file_info->valid_fields=0;
+       captive_file_info_object->p.valid_fields=0;
 
        FileName_UnicodeString.Length=FileIdBothDirInformation->FileNameLength;
        FileName_UnicodeString.MaximumLength=FileIdBothDirInformation->FileNameLength
@@ -246,65 +252,74 @@ ULONG tmp_ULONG;
        FileIdBothDirInformation->FileName[FileIdBothDirInformation->FileNameLength
                        /sizeof(*FileIdBothDirInformation->FileName)]=0;        /* 0-terminate it */
        FileName_UnicodeString.Buffer=FileIdBothDirInformation->FileName;
-       file_info->name=captive_UnicodeString_to_utf8_malloc(&FileName_UnicodeString);
-       /* '->name' assumed for 'file_info->valid_fields' */
+       captive_file_info_object->p.name=captive_UnicodeString_to_utf8_malloc(&FileName_UnicodeString);
+       /* '->name' assumed for 'captive_file_info_object->p.valid_fields' */
 
        /* FIXME: What is 'FILE_ATTRIBUTE_NORMAL'? */
        switch (FileIdBothDirInformation->FileAttributes & (0
                        | FILE_ATTRIBUTE_DIRECTORY
                        | FILE_ATTRIBUTE_DEVICE)) {
-               case 0:                        file_info->type=GNOME_VFS_FILE_TYPE_REGULAR;   break;
-               case FILE_ATTRIBUTE_DIRECTORY: file_info->type=GNOME_VFS_FILE_TYPE_DIRECTORY; break;
-               case FILE_ATTRIBUTE_DEVICE:    file_info->type=GNOME_VFS_FILE_TYPE_SOCKET;
+               case 0:                        captive_file_info_object->p.type=GNOME_VFS_FILE_TYPE_REGULAR;   break;
+               case FILE_ATTRIBUTE_DIRECTORY: captive_file_info_object->p.type=GNOME_VFS_FILE_TYPE_DIRECTORY; break;
+               case FILE_ATTRIBUTE_DEVICE:    captive_file_info_object->p.type=GNOME_VFS_FILE_TYPE_SOCKET;
                        /* or GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE or GNOME_VFS_FILE_TYPE_BLOCK_DEVICE ? */
                        break;
-               default:                       file_info->type=GNOME_VFS_FILE_TYPE_UNKNOWN;   break;
+               default:                       captive_file_info_object->p.type=GNOME_VFS_FILE_TYPE_UNKNOWN;   break;
                }
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE;
 
        /* we use 0600 for r/w files, 0400 for FILE_ATTRIBUTE_READONLY */
-       file_info->permissions=GNOME_VFS_PERM_USER_READ;
-       if (file_info->type==GNOME_VFS_FILE_TYPE_DIRECTORY)
-               file_info->permissions|=GNOME_VFS_PERM_USER_EXEC;
+       captive_file_info_object->p.permissions=GNOME_VFS_PERM_USER_READ;
+       if (captive_file_info_object->p.type==GNOME_VFS_FILE_TYPE_DIRECTORY)
+               captive_file_info_object->p.permissions|=GNOME_VFS_PERM_USER_EXEC;
        if (!(FileIdBothDirInformation->FileAttributes & FILE_ATTRIBUTE_READONLY))
-               file_info->permissions|=GNOME_VFS_PERM_USER_WRITE;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
+               captive_file_info_object->p.permissions|=GNOME_VFS_PERM_USER_WRITE;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
 
-       file_info->size=FileIdBothDirInformation->EndOfFile.QuadPart;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
+       captive_file_info_object->p.size=FileIdBothDirInformation->EndOfFile.QuadPart;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
 
-       file_info->block_count=FileIdBothDirInformation->AllocationSize.QuadPart/512;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
+       captive_file_info_object->p.block_count=FileIdBothDirInformation->AllocationSize.QuadPart/512;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
 
-       file_info->flags=GNOME_VFS_FILE_FLAGS_LOCAL;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_FLAGS;
+       captive_file_info_object->p.flags=GNOME_VFS_FILE_FLAGS_LOCAL;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_FLAGS;
 
        if (FileIdBothDirInformation->LastAccessTime.QuadPart) {        /* it may be 0 if not set */
-               if (RtlTimeToSecondsSince1970(&FileIdBothDirInformation->LastAccessTime,&tmp_ULONG)) {
-                       file_info->atime=tmp_ULONG;
-                       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME;
-                       }
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,&FileIdBothDirInformation->LastAccessTime);
+               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
+               captive_file_info_object->p.atime=timespec.tv_sec;
+               captive_file_info_object->atime_nsec=timespec.tv_nsec;
+               captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME;
                }
 
        /* it may be 0 if not set */
        if (FileIdBothDirInformation->LastWriteTime.QuadPart || FileIdBothDirInformation->ChangeTime.QuadPart) {
-               if (RtlTimeToSecondsSince1970(
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,
                                /* take the more recent (==bigger) time: */
                                (FileIdBothDirInformation->LastWriteTime.QuadPart > FileIdBothDirInformation->ChangeTime.QuadPart
-                                               ? &FileIdBothDirInformation->LastWriteTime : &FileIdBothDirInformation->ChangeTime),
-                               &tmp_ULONG)) {
-                       file_info->mtime=tmp_ULONG;
-                       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME;
-                       }
+                                               ? &FileIdBothDirInformation->LastWriteTime : &FileIdBothDirInformation->ChangeTime));
+               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
+               captive_file_info_object->p.mtime=timespec.tv_sec;
+               captive_file_info_object->mtime_nsec=timespec.tv_nsec;
+               captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME;
                }
 
        if (FileIdBothDirInformation->CreationTime.QuadPart) {  /* it may be 0 if not set */
-               if (RtlTimeToSecondsSince1970(&FileIdBothDirInformation->CreationTime,&tmp_ULONG)) {
-                       file_info->ctime=tmp_ULONG;
-                       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME;
-                       }
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,&FileIdBothDirInformation->CreationTime);
+               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
+               captive_file_info_object->p.ctime=timespec.tv_sec;
+               captive_file_info_object->ctime_nsec=timespec.tv_nsec;
+               captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME;
                }
 
+       *captive_file_info_object_return=captive_file_info_object;
        return GNOME_VFS_OK;
 }
 
@@ -385,7 +400,7 @@ HANDLE dir_Handle;
 
 
 static GnomeVFSResult captive_directory_slave_read
-               (CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info)
+               (CaptiveDirectoryObject *captive_directory_object,CaptiveFileInfoObject **captive_file_info_object_return)
 {
 CaptiveDirectorySlaveObject *captive_directory_slave_object;
 NTSTATUS err;
@@ -395,7 +410,7 @@ FILE_BOTH_DIR_INFORMATION *FileBothDirInformation;
 GnomeVFSResult errvfsresult;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_SLAVE_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(captive_file_info_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_slave_object=CAPTIVE_DIRECTORY_SLAVE_OBJECT(captive_directory_object);
 
@@ -473,7 +488,7 @@ retry:
                default: g_assert_not_reached();
                }
 
-       errvfsresult=FileIdBothDirInformation_to_GnomeVFSFileInfo(file_info,FileIdBothDirInformation,
+       errvfsresult=FileIdBothDirInformation_to_CaptiveFileInfoObject(captive_file_info_object_return,FileIdBothDirInformation,
                        &dir_IoStatusBlock);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);