X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fclient%2Ffile.c;h=b1268be13e9ec4e09d8a580d8fff64709032c5e6;hb=a2dd38f86df22c46ae18f3ad7d9850eaacb02b92;hp=d53a1647065c7b0d70c92af861cbcf67a417cff3;hpb=d6e13039e254c8580617da345ac4a8109be9b442;p=captive.git diff --git a/src/libcaptive/client/file.c b/src/libcaptive/client/file.c index d53a164..b1268be 100644 --- a/src/libcaptive/client/file.c +++ b/src/libcaptive/client/file.c @@ -20,17 +20,10 @@ #include "config.h" #include "captive/client-file.h" /* self */ -#include "lib.h" +#include "file.h" /* self-priv */ #include -#include "captive/unicode.h" -#include "reactos/ntos/types.h" /* for HANDLE */ -#include "reactos/ddk/iotypes.h" /* for IO_STATUS_BLOCK */ -#include "reactos/ddk/iofuncs.h" /* for IoCreateFile() */ -#include "captive/sandbox.h" -#include "result.h" -#include "captive/client-directory.h" -#include "reactos/ddk/obfuncs.h" /* for ObReferenceObjectByHandle() */ -#include "captive/macros.h" +#include "vfs.h" +#include "reactos/ntos/types.h" /* for ULONG */ static gpointer captive_file_object_parent_class=NULL; @@ -40,12 +33,9 @@ static GnomeVFSResult captive_file_close(CaptiveFileObject *captive_file_object) static void captive_file_object_finalize(CaptiveFileObject *captive_file_object) { -GnomeVFSResult errvfsresult; - g_return_if_fail(captive_file_object!=NULL); - errvfsresult=captive_file_close(captive_file_object); - g_assert(errvfsresult==GNOME_VFS_OK); + captive_file_close(captive_file_object); /* errors ignored */ G_OBJECT_CLASS(captive_file_object_parent_class)->finalize((GObject *)captive_file_object); } @@ -55,14 +45,13 @@ static void captive_file_object_class_init(CaptiveFileObjectClass *class) { GObjectClass *gobject_class=G_OBJECT_CLASS(class); - captive_file_object_parent_class=g_type_class_ref(G_TYPE_OBJECT); + captive_file_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class))); gobject_class->finalize=(void (*)(GObject *object))captive_file_object_finalize; } static void captive_file_object_init(CaptiveFileObject *captive_file_object) { - captive_file_object->file_Handle=NULL; } @@ -84,625 +73,164 @@ static const GTypeInfo captive_file_object_info={ }; captive_file_object_type=g_type_register_static(G_TYPE_OBJECT, - "CaptiveFileObject",&captive_file_object_info,0); + "CaptiveFileObject",&captive_file_object_info,G_TYPE_FLAG_ABSTRACT); } return captive_file_object_type; } -static GnomeVFSResult captive_file_new_internal(CaptiveFileObject **captive_file_object_return, - const gchar *pathname,GnomeVFSOpenMode mode,gboolean create,gboolean create_exclusive,guint create_perm) +GnomeVFSResult captive_file_new_open(CaptiveFileObject **captive_file_object_return, + CaptiveVfsObject *captive_vfs_object,const gchar *pathname,GnomeVFSOpenMode mode) { -IO_STATUS_BLOCK file_IoStatusBlock; -GnomeVFSResult errvfsresult; -OBJECT_ATTRIBUTES file_ObjectAttributes; -HANDLE file_Handle; -CaptiveFileObject *captive_file_object; -NTSTATUS err; - - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_new_open(captive_file_object_return,pathname,mode); - g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - *captive_file_object_return=NULL; - - errvfsresult=captive_ObjectAttributes_init(pathname,&file_ObjectAttributes); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); - - /* open */ - err=IoCreateFile( - &file_Handle, /* FileHandle */ - 0 - |(!(mode&GNOME_VFS_OPEN_READ ) ? 0 : FILE_READ_DATA) - |(!(mode&GNOME_VFS_OPEN_WRITE) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES) - |( mode!=0 ? 0 : FILE_READ_ATTRIBUTES) - , /* DesiredAccess */ - &file_ObjectAttributes, /* ObjectAttributes */ - &file_IoStatusBlock, /* IoStatusBlock */ - NULL, /* AllocationSize; ignored for open */ - (!create || create_perm&0200 ? FILE_ATTRIBUTE_NORMAL: FILE_ATTRIBUTE_READONLY), /* FileAttributes; ignored for open */ - (!create || !create_exclusive /* ShareAccess; 0 means exclusive */ - ? (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) - : 0), - (!create ? FILE_OPEN : FILE_CREATE), /* CreateDisposition */ - /* FILE_SYNCHRONOUS_IO_{,NON}ALERT: We need to allow W32 filesystem - * any waits to not to let it return STATUS_CANT_WAIT us. - * Alertability should have only effect on asynchronous events - * from KeWaitForSingleObject() by setting/clearing its parameter 'Alertable'. - */ - FILE_SYNCHRONOUS_IO_ALERT, /* CreateOptions */ - NULL, /* EaBuffer */ - 0, /* EaLength */ - CreateFileTypeNone, /* CreateFileType */ - NULL, /* ExtraCreateParameters */ - 0); /* Options */ - g_free(file_ObjectAttributes.ObjectName); /* left from captive_file_uri_parent_init() */ - g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC); - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(file_IoStatusBlock.Information - ==(!create ? FILE_OPENED : FILE_CREATED), - GNOME_VFS_ERROR_GENERIC); - - captive_file_object=g_object_new( - CAPTIVE_FILE_TYPE_OBJECT, /* object_type */ - NULL); /* first_property_name; FIXME: support properties */ - - captive_file_object->file_Handle=file_Handle; - captive_file_object->offset=0; - - *captive_file_object_return=captive_file_object; - return GNOME_VFS_OK; + return (*CAPTIVE_VFS_OBJECT_GET_CLASS(captive_vfs_object)->file_new_open) + (captive_file_object_return,captive_vfs_object,pathname,mode); } -GnomeVFSResult captive_file_new_open - (CaptiveFileObject **captive_file_object_return,const gchar *pathname,GnomeVFSOpenMode mode) +GnomeVFSResult captive_file_new_create(CaptiveFileObject **captive_file_object_return, + CaptiveVfsObject *captive_vfs_object,const gchar *pathname,GnomeVFSOpenMode mode,gboolean exclusive,guint perm) { g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - return captive_file_new_internal(captive_file_object_return,pathname,mode, - FALSE, /* create */ - FALSE, /* create_exclusive; ignored */ - 0); /* create_perm; ignored */ + return (*CAPTIVE_VFS_OBJECT_GET_CLASS(captive_vfs_object)->file_new_create) + (captive_file_object_return,captive_vfs_object,pathname,mode,exclusive,perm); } -GnomeVFSResult captive_file_new_create - (CaptiveFileObject **captive_file_object_return,const gchar *pathname,GnomeVFSOpenMode mode,gboolean exclusive,guint perm) +GnomeVFSResult captive_file_init(CaptiveFileObject *captive_file_object,CaptiveVfsObject *captive_vfs_object) { - g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + + g_return_val_if_fail(captive_file_object->vfs==NULL,GNOME_VFS_ERROR_GENERIC); + + captive_file_object->vfs=g_object_ref(captive_vfs_object); - return captive_file_new_internal(captive_file_object_return,pathname,mode, - TRUE, /* create */ - exclusive, /* create_exclusive */ - perm); /* create_perm */ + return GNOME_VFS_OK; } static GnomeVFSResult captive_file_close(CaptiveFileObject *captive_file_object) { -NTSTATUS err; -HANDLE file_Handle; + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_close(captive_file_object); + if (captive_file_object->vfs!=NULL) { + g_assert(CAPTIVE_VFS_IS_OBJECT(captive_file_object->vfs)); + g_object_unref(captive_file_object->vfs); + captive_file_object->vfs=NULL; + } - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* already closed */ + return GNOME_VFS_OK; +} - file_Handle=captive_file_object->file_Handle; - captive_file_object->file_Handle=NULL; - err=NtClose(file_Handle); - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - return GNOME_VFS_OK; +CaptiveVfsObject *captive_file_ref_vfs(CaptiveFileObject *captive_file_object) +{ + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),NULL); + + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_file_object->vfs),NULL); + + return g_object_ref(captive_file_object->vfs); } GnomeVFSResult captive_file_read(CaptiveFileObject *captive_file_object, gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return) { -NTSTATUS err; -IO_STATUS_BLOCK file_IoStatusBlock; -LARGE_INTEGER file_offset; -GnomeVFSResult errvfsresult; - - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_read(captive_file_object,buffer,num_bytes,bytes_read_return); - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(bytes_read_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(num_bytes==(ULONG)num_bytes,GNOME_VFS_ERROR_BAD_PARAMETERS); - file_offset.QuadPart=captive_file_object->offset; - err=NtReadFile( - captive_file_object->file_Handle, /* FileHandle */ - NULL, /* EventHandle; completion signalling; optional */ - NULL, /* ApcRoutine; optional */ - NULL, /* ApcContext; optional */ - &file_IoStatusBlock, /* IoStatusBlock */ - buffer, /* Buffer */ - num_bytes, /* Length */ - &file_offset, /* ByteOffset */ - NULL); /* Key; NULL means no file locking key */ - if (err==STATUS_END_OF_FILE) { - g_return_val_if_fail(file_IoStatusBlock.Status==STATUS_END_OF_FILE,GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(file_IoStatusBlock.Information==0,GNOME_VFS_ERROR_GENERIC); - *bytes_read_return=0; - return GNOME_VFS_ERROR_EOF; - } - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - 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); - g_return_val_if_fail(file_IoStatusBlock.Information<=num_bytes,GNOME_VFS_ERROR_GENERIC); - - captive_file_object->offset+=file_IoStatusBlock.Information; - *bytes_read_return=file_IoStatusBlock.Information; - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->read) + (captive_file_object,buffer,num_bytes,bytes_read_return); } GnomeVFSResult captive_file_write(CaptiveFileObject *captive_file_object, gconstpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_written_return) { -NTSTATUS err; -IO_STATUS_BLOCK file_IoStatusBlock; -LARGE_INTEGER file_offset; - - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_write(captive_file_object,buffer,num_bytes,bytes_written_return); - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(bytes_written_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(num_bytes==(ULONG)num_bytes,GNOME_VFS_ERROR_BAD_PARAMETERS); - file_offset.QuadPart=captive_file_object->offset; - err=NtWriteFile( - captive_file_object->file_Handle, /* FileHandle */ - NULL, /* Event; completion signalling; optional */ - NULL, /* ApcRoutine; optional */ - NULL, /* ApcContext; optional */ - &file_IoStatusBlock, /* IoStatusBlock */ - (gpointer /* de-const */ )buffer, /* Buffer */ - num_bytes, /* Length */ - &file_offset, /* ByteOffset */ - NULL); /* Key; NULL means no file locking key */ - 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); - g_return_val_if_fail(file_IoStatusBlock.Information==num_bytes,GNOME_VFS_ERROR_GENERIC); - - captive_file_object->offset+=file_IoStatusBlock.Information; - *bytes_written_return=file_IoStatusBlock.Information; - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->write) + (captive_file_object,buffer,num_bytes,bytes_written_return); } GnomeVFSResult captive_file_seek (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset) { - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_seek(captive_file_object,whence,offset); - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - - switch (whence) { - case GNOME_VFS_SEEK_START: - captive_file_object->offset=offset; - break; - case GNOME_VFS_SEEK_CURRENT: - if (0 - || (offset>0 && (captive_file_object->offset+offset)offset) - || (offset<0 && (captive_file_object->offset+offset)>captive_file_object->offset)) - return GNOME_VFS_ERROR_BAD_PARAMETERS; - captive_file_object->offset+=offset; - break; - case GNOME_VFS_SEEK_END: - g_assert_not_reached(); /* NOT IMPLEMENTED YET */ - break; - default: - g_return_val_if_reached(GNOME_VFS_ERROR_BAD_PARAMETERS); - } + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->seek) + (captive_file_object,whence,offset); } GnomeVFSResult captive_file_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return) { - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_file_tell(captive_file_object,offset_return); - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - *offset_return=captive_file_object->offset; - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->tell) + (captive_file_object,offset_return); } GnomeVFSResult captive_file_remove(CaptiveFileObject *captive_file_object) { -NTSTATUS err; -FILE_DISPOSITION_INFORMATION FileDispositionInformation_struct; -IO_STATUS_BLOCK file_IoStatusBlock; -GnomeVFSResult errvfsresult; - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - - FileDispositionInformation_struct.DoDeleteFile=TRUE; - - err=NtSetInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - &FileDispositionInformation_struct, /* FileInformation */ - sizeof(FileDispositionInformation_struct), /* Length */ - FileDispositionInformation); /* FileInformationClass */ - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - return GNOME_VFS_OK; -} - - -/* Use 'FileAllInformationStruct' identifier instead of the logical 'FileAllInformation' - * to prevent override of enum member 'FileAllInformation' - */ -static GnomeVFSResult FileAllInformationStruct_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info, - FILE_ALL_INFORMATION *FileAllInformationStruct,IO_STATUS_BLOCK *IoStatusBlock) -{ -UNICODE_STRING FileName_UnicodeString; -BOOLEAN errBOOLEAN; -ULONG tmp_ULONG; - - g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(FileAllInformationStruct!=NULL,GNOME_VFS_ERROR_GENERIC); - - g_return_val_if_fail(NT_SUCCESS(IoStatusBlock->Status),GNOME_VFS_ERROR_GENERIC); - - file_info->valid_fields=0; - - FileName_UnicodeString.Length=FileAllInformationStruct->NameInformation.FileNameLength; - FileName_UnicodeString.MaximumLength=FileAllInformationStruct->NameInformation.FileNameLength - +sizeof(*FileAllInformationStruct->NameInformation.FileName); /* 0-terminator */ - g_assert((gpointer)(((char *)FileAllInformationStruct->NameInformation.FileName)+FileName_UnicodeString.Length) - <=(gpointer)(((char *)FileAllInformationStruct)+IoStatusBlock->Information)); - /* ensure we fit below '->IoStatusBlock->Information' at least without the 0-terminator */ - FileAllInformationStruct->NameInformation.FileName[FileAllInformationStruct->NameInformation.FileNameLength - /sizeof(*FileAllInformationStruct->NameInformation.FileName)]=0; /* 0-terminate it */ - FileName_UnicodeString.Buffer=FileAllInformationStruct->NameInformation.FileName; - file_info->name=captive_UnicodeString_to_utf8_malloc(&FileName_UnicodeString); - /* '->name' assumed for 'file_info->valid_fields' */ - - /* FIXME: What is 'FILE_ATTRIBUTE_NORMAL'? */ - switch (FileAllInformationStruct->BasicInformation.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; - /* 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; - } - file_info->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; - if (!(FileAllInformationStruct->BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)) - file_info->permissions|=GNOME_VFS_PERM_USER_WRITE; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; - - file_info->size=FileAllInformationStruct->StandardInformation.EndOfFile.QuadPart; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE; - - file_info->block_count=FileAllInformationStruct->StandardInformation.AllocationSize.QuadPart/512; - file_info->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; - - if (FileAllInformationStruct->BasicInformation.LastAccessTime.QuadPart) { /* it may be 0 if not set */ - errBOOLEAN=RtlTimeToSecondsSince1970(&FileAllInformationStruct->BasicInformation.LastAccessTime,&tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->atime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME; - } - - /* it may be 0 if not set */ - if (FileAllInformationStruct->BasicInformation.LastWriteTime.QuadPart || FileAllInformationStruct->BasicInformation.ChangeTime.QuadPart) { - errBOOLEAN=RtlTimeToSecondsSince1970( - /* take the more recent (==bigger) time: */ - (FileAllInformationStruct->BasicInformation.LastWriteTime.QuadPart > FileAllInformationStruct->BasicInformation.ChangeTime.QuadPart - ? &FileAllInformationStruct->BasicInformation.LastWriteTime : &FileAllInformationStruct->BasicInformation.ChangeTime), - &tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->mtime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME; - } - - if (FileAllInformationStruct->BasicInformation.CreationTime.QuadPart) { /* it may be 0 if not set */ - errBOOLEAN=RtlTimeToSecondsSince1970(&FileAllInformationStruct->BasicInformation.CreationTime,&tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->ctime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME; - } - - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->remove) + (captive_file_object); } GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object, GnomeVFSFileInfo *file_info) { -NTSTATUS err; -IO_STATUS_BLOCK file_IoStatusBlock; -FILE_ALL_INFORMATION *FileAllInformationStruct; -GnomeVFSResult errvfsresult; -char QueryFile_buf[sizeof(FILE_ALL_INFORMATION) - +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ALL_INFORMATION.NameInformation.FileName */ )]; - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - /* query */ - FileAllInformationStruct=(void *)QueryFile_buf; - err=NtQueryInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - (gpointer)QueryFile_buf, /* FileInformation */ - sizeof(QueryFile_buf) /* Length */ - -sizeof(*FileAllInformationStruct->NameInformation.FileName), /* reserve space for 0-terminator */ - FileAllInformation); /* FileInformationClass; =>FILE_ALL_INFORMATION */ - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - - /* process gathered info */ - errvfsresult=FileAllInformationStruct_to_GnomeVFSFileInfo(file_info,FileAllInformationStruct, - &file_IoStatusBlock); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); - - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->file_info_get) + (captive_file_object,file_info); } GnomeVFSResult captive_file_file_info_set(CaptiveFileObject *captive_file_object, const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask) { - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { -gchar *name_basename,*name_dirname; -UNICODE_STRING *name_UnicodeString; -FILE_RENAME_INFORMATION *FileRenameInformation_structp; -gsize FileRenameInformation_struct_len; -IO_STATUS_BLOCK file_IoStatusBlock; -NTSTATUS err; -GnomeVFSResult errvfsresult; - - /* non-existing dirname assertion */ - name_dirname=g_path_get_dirname(info->name); - if (strcmp(name_basename,info->name)) { - g_assert_not_reached(); - errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS; - goto err_free_name_dirname; - } - - /* fully-matching basename assertion */ - name_basename=g_path_get_basename(info->name); - if (*name_basename) { - g_assert_not_reached(); - errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS; - goto err_free_name_basename; - } - - name_UnicodeString=captive_utf8_to_UnicodeString_alloca(info->name); - FileRenameInformation_struct_len=sizeof(*FileRenameInformation_structp) - +name_UnicodeString->MaximumLength; /* ==Length+(0-terminator); is the terminator needed? */ - - FileRenameInformation_structp=g_alloca(FileRenameInformation_struct_len); - FileRenameInformation_structp->Replace=FALSE; - FileRenameInformation_structp->RootDir=NULL; /* we do 'simple rename' here */ - FileRenameInformation_structp->FileNameLength=name_UnicodeString->Length; - memcpy(FileRenameInformation_structp->FileName,name_UnicodeString->Buffer, - name_UnicodeString->MaximumLength); /* ==Length+(0-terminator); is the terminator needed? */ - - err=NtSetInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - FileRenameInformation_structp, /* FileInformation */ - FileRenameInformation_struct_len, /* Length */ - FileRenameInformation); /* FileInformationClass */ - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) { - g_assert_not_reached(); - errvfsresult=GNOME_VFS_ERROR_GENERIC; - goto err_free_name_basename; - } - - errvfsresult=GNOME_VFS_OK; - -err_free_name_basename: - g_free(name_basename); -err_free_name_dirname: - g_free(name_dirname); - - if (errvfsresult!=GNOME_VFS_OK) - return errvfsresult; - } - - if (mask & (GNOME_VFS_SET_FILE_INFO_PERMISSIONS | GNOME_VFS_SET_FILE_INFO_TIME)) { -FILE_BASIC_INFORMATION FileBasicInformation_struct; -IO_STATUS_BLOCK file_IoStatusBlock; -NTSTATUS err; - - err=NtQueryInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - &FileBasicInformation_struct, /* FileInformation */ - sizeof(FileBasicInformation_struct), /* Length */ - FileBasicInformation); /* FileInformationClass */ - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - - if (mask & GNOME_VFS_SET_FILE_INFO_PERMISSIONS) { - FileBasicInformation_struct.FileAttributes&=~FILE_ATTRIBUTE_READONLY; - g_assert(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS); - if (!(info->permissions&0200)) - FileBasicInformation_struct.FileAttributes|=FILE_ATTRIBUTE_READONLY; - } - - if (mask & GNOME_VFS_SET_FILE_INFO_TIME) { - g_assert(info->valid_fields & (0 - | GNOME_VFS_FILE_INFO_FIELDS_ATIME - | GNOME_VFS_FILE_INFO_FIELDS_MTIME - | GNOME_VFS_FILE_INFO_FIELDS_CTIME)); - if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) { - RtlSecondsSince1970ToTime( - info->atime, /* SecondsSince1970 */ - &FileBasicInformation_struct.LastAccessTime); /* Time */ - } - if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) { - RtlSecondsSince1970ToTime( - info->mtime, /* SecondsSince1970 */ - &FileBasicInformation_struct.LastWriteTime); /* Time */ - FileBasicInformation_struct.ChangeTime=FileBasicInformation_struct.LastWriteTime; - } - if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) { - RtlSecondsSince1970ToTime( - info->ctime, /* SecondsSince1970 */ - &FileBasicInformation_struct.CreationTime); /* Time */ - } - } - - err=NtSetInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - &FileBasicInformation_struct, /* FileInformation */ - sizeof(FileBasicInformation_struct), /* Length */ - FileBasicInformation); /* FileInformationClass */ - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - } - - if (mask & GNOME_VFS_SET_FILE_INFO_OWNER) { - /* FIXME: g_assert(info->valid_fields & ???); */ - /* owner ignored for W32 */ - } - - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->file_info_set) + (captive_file_object,info,mask); } GnomeVFSResult captive_file_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size) { -NTSTATUS err; -FILE_END_OF_FILE_INFORMATION FileEndOfFileInformation_struct; -IO_STATUS_BLOCK file_IoStatusBlock; -GnomeVFSResult errvfsresult; - - g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - - FileEndOfFileInformation_struct.EndOfFile.QuadPart=file_size; - - err=NtSetInformationFile( - captive_file_object->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - &FileEndOfFileInformation_struct, /* FileInformation */ - sizeof(FileEndOfFileInformation_struct), /* Length */ - FileEndOfFileInformation); /* FileInformationClass */ - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - return GNOME_VFS_OK; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object)->truncate) + (captive_file_object,file_size); } GnomeVFSResult captive_file_move(CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace) { -NTSTATUS err; -FILE_RENAME_INFORMATION FileRenameInformation_struct; -IO_STATUS_BLOCK file_IoStatusBlock; -GnomeVFSResult errvfsresult; -gchar *pathname_new_dirname,*pathname_new_basename; -CaptiveDirectoryObject *captive_target_directory_object; -FILE_OBJECT *target_dir_FileObject; -UNICODE_STRING *target_dir_FileObject_FileName_UnicodeString_local; - - g_return_val_if_fail(captive_file_object_old!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_file_object_old->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object_old),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(pathname_new!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - pathname_new_dirname=g_path_get_dirname(pathname_new); - pathname_new_basename=g_path_get_basename(pathname_new); - - errvfsresult=captive_directory_new_open(&captive_target_directory_object,pathname_new_dirname); - if (errvfsresult!=GNOME_VFS_OK) - goto err_free_pathnames; - - err=ObReferenceObjectByHandle( - captive_target_directory_object->dir_Handle, /* Handle */ - (FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY), /* DesiredAccess */ - IoFileObjectType, /* ObjectType */ - KernelMode, /* AccessMode */ - (PVOID *)&target_dir_FileObject, /* Object */ - NULL); /* HandleInfo */ - if (!NT_SUCCESS(err)) { - g_assert_not_reached(); - errvfsresult=GNOME_VFS_ERROR_GENERIC; - goto err_close_captive_target_directory_object; - } - - /* Supply only the 'basename' to 'target_dir_FileObject->FileName' - * as the directory is fully determined by its other attributes. - */ - target_dir_FileObject_FileName_UnicodeString_local=captive_utf8_to_UnicodeString_alloca(pathname_new_basename); - target_dir_FileObject->FileName=*target_dir_FileObject_FileName_UnicodeString_local; - - ObDereferenceObject(target_dir_FileObject); - - FileRenameInformation_struct.Replace=force_replace; - FileRenameInformation_struct.RootDir=captive_target_directory_object->dir_Handle; /* ->'target_dir_FileObject' */ - FileRenameInformation_struct.FileNameLength=0; /* provided by 'FileRenameInformation_struct.RootDir' */ - - err=NtSetInformationFile( - captive_file_object_old->file_Handle, /* FileHandle */ - &file_IoStatusBlock, /* IoStatusBlock */ - &FileRenameInformation_struct, /* FileInformation */ - sizeof(FileRenameInformation_struct), /* Length */ - FileRenameInformation); /* FileInformationClass */ - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) { - g_assert_not_reached(); - errvfsresult=GNOME_VFS_ERROR_GENERIC; - } - - /* PASSTHRU */ - -err_close_captive_target_directory_object: - g_object_unref(captive_target_directory_object); -err_free_pathnames: - g_free(pathname_new_dirname); - g_free(pathname_new_basename); - - return errvfsresult; + return (*CAPTIVE_FILE_OBJECT_GET_CLASS(captive_file_object_old)->move) + (captive_file_object_old,pathname_new,force_replace); }