Implemented sub-second W32 filesystem interface by new: CaptiveFileInfoObject
[captive.git] / src / libcaptive / client / file-slave.c
index 8193e38..08bc4d5 100644 (file)
@@ -38,6 +38,7 @@
 #include "vfs.h"
 #include "vfs-slave.h"
 #include "../cc/sharedcachemap.h"
+#include "captive/rtl-time.h"
 
 
 /* Config: */
@@ -70,9 +71,9 @@ static GnomeVFSResult captive_file_slave_seek
 static GnomeVFSResult captive_file_slave_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return);
 static GnomeVFSResult captive_file_slave_remove(CaptiveFileObject *captive_file_object);
 static GnomeVFSResult captive_file_slave_file_info_get
-               (CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info);
+               (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject **captive_file_info_object_return);
 static GnomeVFSResult captive_file_slave_file_info_set
-               (CaptiveFileObject *captive_file_object,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask);
+               (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject *captive_file_info_object,GnomeVFSSetFileInfoMask mask);
 static GnomeVFSResult captive_file_slave_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size);
 static GnomeVFSResult captive_file_slave_move
                (CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace);
@@ -357,10 +358,11 @@ CaptiveFileSlaveObject *captive_file_slave_object;
 NTSTATUS err;
 IO_STATUS_BLOCK file_IoStatusBlock;
 LARGE_INTEGER file_offset;
-GnomeVFSFileInfo file_info;
+CaptiveFileInfoObject *captive_file_info_object;
 GnomeVFSFileSize endoffile_wanted;
 GnomeVFSResult errvfsresult;
 static GnomeVFSFileSize total_written=0;
+gboolean extension_needed;
 
        g_return_val_if_fail(CAPTIVE_FILE_SLAVE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -380,9 +382,12 @@ static GnomeVFSFileSize total_written=0;
                return GNOME_VFS_ERROR_TOO_BIG;
        endoffile_wanted=captive_file_slave_object->offset+num_bytes;
        if (GNOME_VFS_OK!=(errvfsresult=captive_file_slave_file_info_get(
-                       CAPTIVE_FILE_OBJECT(captive_file_slave_object),&file_info)))
+                       CAPTIVE_FILE_OBJECT(captive_file_slave_object),&captive_file_info_object)))
                return errvfsresult;
-       if (file_info.size<endoffile_wanted) {
+       g_assert(captive_file_info_object->p.valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SIZE);
+       extension_needed=(captive_file_info_object->p.size<endoffile_wanted);
+       g_object_unref(captive_file_info_object);
+       if (extension_needed) {
                if (GNOME_VFS_OK!=(errvfsresult=captive_file_slave_truncate(
                                CAPTIVE_FILE_OBJECT(captive_file_slave_object),endoffile_wanted)))
                        return errvfsresult;
@@ -502,12 +507,12 @@ GnomeVFSResult errvfsresult;
 /* Use 'FileNameInformationStruct' identifier instead of the logical 'FileNameInformation'
  * to prevent override of enum member 'FileNameInformation'
  */
-static GnomeVFSResult FileNameInformationStruct_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
-               FILE_NAME_INFORMATION *FileNameInformationStruct)
+static GnomeVFSResult FileNameInformationStruct_to_CaptiveFileInfoObject_in_place
+               (CaptiveFileInfoObject *captive_file_info_object,FILE_NAME_INFORMATION *FileNameInformationStruct)
 {
 UNICODE_STRING FileName_UnicodeString;
 
-       g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_GENERIC);
+       g_return_val_if_fail(CAPTIVE_FILE_INFO_IS_OBJECT(captive_file_info_object),GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(FileNameInformationStruct!=NULL,GNOME_VFS_ERROR_GENERIC);
 
        FileName_UnicodeString.Length=FileNameInformationStruct->FileNameLength;
@@ -523,8 +528,8 @@ UNICODE_STRING FileName_UnicodeString;
        FileNameInformationStruct->FileName[FileNameInformationStruct->FileNameLength
                        /sizeof(*FileNameInformationStruct->FileName)]=0;       /* 0-terminate it */
        FileName_UnicodeString.Buffer=FileNameInformationStruct->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' */
 
        return GNOME_VFS_OK;
 }
@@ -533,57 +538,66 @@ UNICODE_STRING FileName_UnicodeString;
 /* Use 'FileBasicInformationStruct' identifier instead of the logical 'FileBasicInformation'
  * to prevent override of enum member 'FileBasicInformation'
  */
-static GnomeVFSResult FileBasicInformationStruct_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
-               FILE_BASIC_INFORMATION *FileBasicInformationStruct)
+static GnomeVFSResult FileBasicInformationStruct_to_CaptiveFileInfoObject_in_place
+               (CaptiveFileInfoObject *captive_file_info_object,FILE_BASIC_INFORMATION *FileBasicInformationStruct)
 {
-BOOLEAN errBOOLEAN;
-ULONG tmp_ULONG;
+GnomeVFSResult errvfsresult;
+
+       g_return_val_if_fail(CAPTIVE_FILE_INFO_IS_OBJECT(captive_file_info_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        /* FIXME: What is 'FILE_ATTRIBUTE_NORMAL'? */
        switch (FileBasicInformationStruct->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 (!(FileBasicInformationStruct->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;
 
        if (FileBasicInformationStruct->LastAccessTime.QuadPart) {      /* it may be 0 if not set */
-               errBOOLEAN=RtlTimeToSecondsSince1970(&FileBasicInformationStruct->LastAccessTime,&tmp_ULONG);
-               g_assert(errBOOLEAN==TRUE);
-               file_info->atime=tmp_ULONG;
-               file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME;
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,&FileBasicInformationStruct->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 (FileBasicInformationStruct->LastWriteTime.QuadPart || FileBasicInformationStruct->ChangeTime.QuadPart) {
-               errBOOLEAN=RtlTimeToSecondsSince1970(
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,
                                /* take the more recent (==bigger) time: */
                                (FileBasicInformationStruct->LastWriteTime.QuadPart > FileBasicInformationStruct->ChangeTime.QuadPart
-                                               ? &FileBasicInformationStruct->LastWriteTime : &FileBasicInformationStruct->ChangeTime),
-                               &tmp_ULONG);
-               g_assert(errBOOLEAN==TRUE);
-               file_info->mtime=tmp_ULONG;
-               file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME;
+                                               ? &FileBasicInformationStruct->LastWriteTime : &FileBasicInformationStruct->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 (FileBasicInformationStruct->CreationTime.QuadPart) {        /* it may be 0 if not set */
-               errBOOLEAN=RtlTimeToSecondsSince1970(&FileBasicInformationStruct->CreationTime,&tmp_ULONG);
-               g_assert(errBOOLEAN==TRUE);
-               file_info->ctime=tmp_ULONG;
-               file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME;
+struct timespec timespec;
+
+               errvfsresult=Time_to_timespec(&timespec,&FileBasicInformationStruct->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;
                }
 
        return GNOME_VFS_OK;
@@ -593,22 +607,25 @@ ULONG tmp_ULONG;
 /* Use 'FileStandardInformationStruct' identifier instead of the logical 'FileStandardInformation'
  * to prevent override of enum member 'FileStandardInformation'
  */
-static GnomeVFSResult FileStandardInformationStruct_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
-               FILE_STANDARD_INFORMATION *FileStandardInformationStruct)
+static GnomeVFSResult FileStandardInformationStruct_to_CaptiveFileInfoObject_in_place
+               (CaptiveFileInfoObject *captive_file_info_object,FILE_STANDARD_INFORMATION *FileStandardInformationStruct)
 {
-       file_info->size=FileStandardInformationStruct->EndOfFile.QuadPart;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
+       g_return_val_if_fail(CAPTIVE_FILE_INFO_IS_OBJECT(captive_file_info_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       captive_file_info_object->p.size=FileStandardInformationStruct->EndOfFile.QuadPart;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
 
-       file_info->block_count=FileStandardInformationStruct->AllocationSize.QuadPart/512;
-       file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
+       captive_file_info_object->p.block_count=FileStandardInformationStruct->AllocationSize.QuadPart/512;
+       captive_file_info_object->p.valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
 
        return GNOME_VFS_OK;
 }
 
 
 GnomeVFSResult captive_file_slave_file_info_get(CaptiveFileObject *captive_file_object,
-               GnomeVFSFileInfo *file_info)
+               CaptiveFileInfoObject **captive_file_info_object_return)
 {
+CaptiveFileInfoObject *captive_file_info_object;
 CaptiveFileSlaveObject *captive_file_slave_object;
 NTSTATUS err;
 IO_STATUS_BLOCK file_IoStatusBlock;
@@ -620,22 +637,23 @@ char QueryFile_buf[sizeof(FILE_NAME_INFORMATION)
                +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ALL_INFORMATION.NameInformation.FileName */ )];
 
        g_return_val_if_fail(CAPTIVE_FILE_SLAVE_IS_OBJECT(captive_file_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_file_slave_object=CAPTIVE_FILE_SLAVE_OBJECT(captive_file_object);
 
        g_return_val_if_fail(captive_file_slave_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       errvfsresult=captive_file_info_object_new(&captive_file_info_object);
+       g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
+
        /* ntfs.sys of NT-5.1sp1 has *(FILE_BASIC_INFORMATION *)FILE_ALL_INFORMATION.BasicInformation
         * size 0x28 although reactos includes and all the information says 0x24.
         * fastfat.sys of NT-5.1sp1 also has the 'official' sizeof 0x24.
         * It would be a bit of heuristic to correctly detect its expected sizeof.
         */
 
-       file_info->valid_fields=0;
-
-       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;
 
        /* query NameInformation */
        FileNameInformationStruct=(void *)QueryFile_buf;
@@ -650,7 +668,8 @@ char QueryFile_buf[sizeof(FILE_NAME_INFORMATION)
                return errvfsresult;
        g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-       errvfsresult=FileNameInformationStruct_to_GnomeVFSFileInfo(file_info,FileNameInformationStruct);
+       errvfsresult=FileNameInformationStruct_to_CaptiveFileInfoObject_in_place(captive_file_info_object,
+                       FileNameInformationStruct);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
 
        /* query BasicInformation */
@@ -665,7 +684,8 @@ char QueryFile_buf[sizeof(FILE_NAME_INFORMATION)
                return errvfsresult;
        g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-       errvfsresult=FileBasicInformationStruct_to_GnomeVFSFileInfo(file_info,FileBasicInformationStruct);
+       errvfsresult=FileBasicInformationStruct_to_CaptiveFileInfoObject_in_place(captive_file_info_object,
+                       FileBasicInformationStruct);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
 
        /* query StandardInformation */
@@ -680,21 +700,23 @@ char QueryFile_buf[sizeof(FILE_NAME_INFORMATION)
                return errvfsresult;
        g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
        g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-       errvfsresult=FileStandardInformationStruct_to_GnomeVFSFileInfo(file_info,FileStandardInformationStruct);
+       errvfsresult=FileStandardInformationStruct_to_CaptiveFileInfoObject_in_place(captive_file_info_object,
+                       FileStandardInformationStruct);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
 
+       *captive_file_info_object_return=captive_file_info_object;
        captive_leave();
        return GNOME_VFS_OK;
 }
 
 
-GnomeVFSResult captive_file_slave_file_info_set(CaptiveFileObject *captive_file_object,
-    const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask)
+static GnomeVFSResult captive_file_slave_file_info_set
+               (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject *captive_file_info_object,GnomeVFSSetFileInfoMask mask)
 {
 CaptiveFileSlaveObject *captive_file_slave_object;
 
        g_return_val_if_fail(CAPTIVE_FILE_SLAVE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(CAPTIVE_FILE_INFO_IS_OBJECT(captive_file_info_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_file_slave_object=CAPTIVE_FILE_SLAVE_OBJECT(captive_file_object);
 
@@ -710,7 +732,7 @@ NTSTATUS err=STATUS_SUCCESS;        /* Prevent: ... might be used uninitialized in this
 GnomeVFSResult errvfsresult;
 
                /* non-existing dirname assertion */
-               name_dirname=g_path_get_dirname(info->name);
+               name_dirname=g_path_get_dirname(captive_file_info_object->p.name);
                if (*name_dirname) {
                        g_assert_not_reached();
                        errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS;
@@ -718,14 +740,14 @@ GnomeVFSResult errvfsresult;
                        }
 
                /* fully-matching basename assertion */
-               name_basename=g_path_get_basename(info->name);
-               if (strcmp(name_basename,info->name)) {
+               name_basename=g_path_get_basename(captive_file_info_object->p.name);
+               if (strcmp(name_basename,captive_file_info_object->p.name)) {
                        g_assert_not_reached();
                        errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS;
                        goto err_free_name_dirname;
                        }
 
-               name_UnicodeString=captive_utf8_to_UnicodeString_alloca(info->name);
+               name_UnicodeString=captive_utf8_to_UnicodeString_alloca(captive_file_info_object->p.name);
                FileRenameInformation_struct_len=sizeof(*FileRenameInformation_structp)
                                +name_UnicodeString->MaximumLength;     /* ==Length+(0-terminator); is the terminator needed? */
 
@@ -778,31 +800,49 @@ NTSTATUS err;
 
                if (mask & GNOME_VFS_SET_FILE_INFO_PERMISSIONS) {
                        FileBasicInformationp->FileAttributes&=~FILE_ATTRIBUTE_READONLY;
-                       g_assert(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS);
-                       if (!(info->permissions&0200))
+                       g_assert(captive_file_info_object->p.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS);
+                       if (!(captive_file_info_object->p.permissions&0200))
                                FileBasicInformationp->FileAttributes|=FILE_ATTRIBUTE_READONLY;
                        }
 
                if (mask & GNOME_VFS_SET_FILE_INFO_TIME) {
-                       g_assert(info->valid_fields & (0
+                       g_assert(captive_file_info_object->p.valid_fields & (0
                                        | GNOME_VFS_FILE_INFO_FIELDS_ATIME
-                                       | GNOME_VFS_FILE_INFO_FIELDS_MTIME));
-                       /* !GNOME_VFS_FILE_INFO_FIELDS_CTIME is used by FUSE op_utime(). */
-                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) {
-                               RtlSecondsSince1970ToTime(
-                                               info->atime,    /* SecondsSince1970 */
-                                               &FileBasicInformationp->LastAccessTime);        /* Time */
+                                       | GNOME_VFS_FILE_INFO_FIELDS_MTIME
+                                       | GNOME_VFS_FILE_INFO_FIELDS_CTIME));
+                       if (captive_file_info_object->p.valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) {
+struct timespec timespec;
+GnomeVFSResult errvfsresult;
+
+                               timespec.tv_sec=captive_file_info_object->p.atime;
+                               timespec.tv_nsec=captive_file_info_object->atime_nsec;
+                               errvfsresult=timespec_to_Time(
+                                               &FileBasicInformationp->LastAccessTime, /* Time */
+                                               &timespec);     /* timespec */
+                               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
                                }
-                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) {
-                               RtlSecondsSince1970ToTime(
-                                               info->mtime,    /* SecondsSince1970 */
-                                               &FileBasicInformationp->LastWriteTime); /* Time */
+                       if (captive_file_info_object->p.valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) {
+struct timespec timespec;
+GnomeVFSResult errvfsresult;
+
+                               timespec.tv_sec=captive_file_info_object->p.mtime;
+                               timespec.tv_nsec=captive_file_info_object->mtime_nsec;
+                               errvfsresult=timespec_to_Time(
+                                               &FileBasicInformationp->LastWriteTime,  /* Time */
+                                               &timespec);     /* timespec */
+                               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
                                FileBasicInformationp->ChangeTime=FileBasicInformationp->LastWriteTime;
                                }
-                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) {
-                               RtlSecondsSince1970ToTime(
-                                               info->ctime,    /* SecondsSince1970 */
-                                               &FileBasicInformationp->CreationTime);  /* Time */
+                       if (captive_file_info_object->p.valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) {
+struct timespec timespec;
+GnomeVFSResult errvfsresult;
+
+                               timespec.tv_sec=captive_file_info_object->p.ctime;
+                               timespec.tv_nsec=captive_file_info_object->ctime_nsec;
+                               errvfsresult=timespec_to_Time(
+                                               &FileBasicInformationp->CreationTime,   /* Time */
+                                               &timespec);     /* timespec */
+                               g_return_val_if_fail(GNOME_VFS_OK==errvfsresult,errvfsresult);
                                }
                        }
 
@@ -816,7 +856,7 @@ NTSTATUS err;
                }
 
        if (mask & GNOME_VFS_SET_FILE_INFO_OWNER) {
-               /* FIXME: g_assert(info->valid_fields & ???); */
+               /* FIXME: g_assert(captive_file_info_object->p.valid_fields & ???); */
                /* owner ignored for W32 */
                }