X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fclient%2Fdirectory.c;h=eacc458cbf31c72b0024e3ffe1b4f69848bb43f4;hb=a2dd38f86df22c46ae18f3ad7d9850eaacb02b92;hp=4400eb7f0774ebc2fb030843282f366d3958866b;hpb=896a9847bd6482dd0d4c2b44b6b86e4918461aa7;p=captive.git diff --git a/src/libcaptive/client/directory.c b/src/libcaptive/client/directory.c index 4400eb7..eacc458 100644 --- a/src/libcaptive/client/directory.c +++ b/src/libcaptive/client/directory.c @@ -20,13 +20,9 @@ #include "config.h" #include "captive/client-directory.h" /* self */ -#include "lib.h" +#include "directory.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 "vfs.h" static gpointer captive_directory_object_parent_class=NULL; @@ -36,12 +32,9 @@ static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_di static void captive_directory_object_finalize(CaptiveDirectoryObject *captive_directory_object) { -GnomeVFSResult errvfsresult; - g_return_if_fail(captive_directory_object!=NULL); - errvfsresult=captive_directory_close(captive_directory_object); - g_assert(errvfsresult==GNOME_VFS_OK); + captive_directory_close(captive_directory_object); /* errors ignored */ G_OBJECT_CLASS(captive_directory_object_parent_class)->finalize((GObject *)captive_directory_object); } @@ -51,15 +44,13 @@ static void captive_directory_object_class_init(CaptiveDirectoryObjectClass *cla { GObjectClass *gobject_class=G_OBJECT_CLASS(class); - captive_directory_object_parent_class=g_type_class_ref(G_TYPE_OBJECT); + captive_directory_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class))); gobject_class->finalize=(void (*)(GObject *object))captive_directory_object_finalize; } static void captive_directory_object_init(CaptiveDirectoryObject *captive_directory_object) { - captive_directory_object->dir_Handle=NULL; - captive_directory_object->read_first=TRUE; } @@ -81,158 +72,45 @@ static const GTypeInfo captive_directory_object_info={ }; captive_directory_object_type=g_type_register_static(G_TYPE_OBJECT, - "CaptiveDirectoryObject",&captive_directory_object_info,0); + "CaptiveDirectoryObject",&captive_directory_object_info,G_TYPE_FLAG_ABSTRACT); } return captive_directory_object_type; } -GnomeVFSResult captive_directory_new_open(CaptiveDirectoryObject **captive_directory_object_return,const gchar *pathname) +GnomeVFSResult captive_directory_new_open(CaptiveDirectoryObject **captive_directory_object_return, + CaptiveVfsObject *captive_vfs_object,const gchar *pathname) { -GnomeVFSResult errvfsresult; -OBJECT_ATTRIBUTES dir_ObjectAttributes; -HANDLE dir_Handle; -IO_STATUS_BLOCK dir_IoStatusBlock; -NTSTATUS err; -CaptiveDirectoryObject *captive_directory_object; + g_return_val_if_fail(captive_directory_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_VFS_OBJECT_GET_CLASS(captive_vfs_object)->directory_new_open) + (captive_directory_object_return,captive_vfs_object,pathname); +} - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_new_open(captive_directory_object_return,pathname); +GnomeVFSResult captive_directory_new_make(CaptiveDirectoryObject **captive_directory_object_return, + CaptiveVfsObject *captive_vfs_object,const gchar *pathname,guint perm) +{ g_return_val_if_fail(captive_directory_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_directory_object_return=NULL; - - errvfsresult=captive_ObjectAttributes_init(pathname,&dir_ObjectAttributes); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); - - /* wanted: * IoCreateFile()->ObCreateObject(,,,IoFileObjectType)-> - * ->(IoFileObjectType->Create==IopCreateFile)()->IoMountVolume() - */ - err=IoCreateFile( - &dir_Handle, /* FileHandle */ - FILE_LIST_DIRECTORY, /* DesiredAccess */ - &dir_ObjectAttributes, /* ObjectAttributes */ - &dir_IoStatusBlock, /* IoStatusBlock */ - NULL, /* AllocationSize; ignored for open */ - FILE_ATTRIBUTE_NORMAL, /* FileAttributes; ignored for open */ - FILE_SHARE_WRITE, /* ShareAccess; 0 means exclusive */ - FILE_OPEN, /* 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_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT, /* CreateOptions */ - NULL, /* EaBuffer */ - 0, /* EaLength */ - CreateFileTypeNone, /* CreateFileType */ - NULL, /* ExtraCreateParameters */ - 0); /* Options */ - g_free(dir_ObjectAttributes.ObjectName); /* left from captive_gnomevfs_uri_parent_init() */ - g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(dir_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(dir_IoStatusBlock.Information==FILE_OPENED,GNOME_VFS_ERROR_GENERIC); - - captive_directory_object=g_object_new( - CAPTIVE_DIRECTORY_TYPE_OBJECT, /* object_type */ - NULL); /* first_property_name; FIXME: support properties */ - - captive_directory_object->dir_Handle=dir_Handle; - - *captive_directory_object_return=captive_directory_object; - return GNOME_VFS_OK; + return (*CAPTIVE_VFS_OBJECT_GET_CLASS(captive_vfs_object)->directory_new_make) + (captive_directory_object_return,captive_vfs_object,pathname,perm); } -static GnomeVFSResult FileIdBothDirInformation_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info, - FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation,IO_STATUS_BLOCK *IoStatusBlock) +GnomeVFSResult captive_directory_init(CaptiveDirectoryObject *captive_directory_object,CaptiveVfsObject *captive_vfs_object) { -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(FileIdBothDirInformation!=NULL,GNOME_VFS_ERROR_GENERIC); - - g_return_val_if_fail(NT_SUCCESS(IoStatusBlock->Status),GNOME_VFS_ERROR_GENERIC); - /* do not exceed the returned buffer by this record; - * '->NextEntryOffset' is ==0 as we used 'ReturnSingleEntry==TRUE' - */ - g_assert((gpointer)(((char *)FileIdBothDirInformation)+FileIdBothDirInformation->NextEntryOffset) - <=(gpointer)(((char *)FileIdBothDirInformation)+IoStatusBlock->Information)); - - file_info->valid_fields=0; - - FileName_UnicodeString.Length=FileIdBothDirInformation->FileNameLength; - FileName_UnicodeString.MaximumLength=FileIdBothDirInformation->FileNameLength - +sizeof(*FileIdBothDirInformation->FileName); /* 0-terminator */ - g_assert((gpointer)(((char *)FileIdBothDirInformation->FileName)+FileName_UnicodeString.Length) - <=(gpointer)(((char *)FileIdBothDirInformation)+IoStatusBlock->Information)); - /* ensure we fit below '->IoStatusBlock->Information' at least without the 0-terminator */ - 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' */ - - /* 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; - /* 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 (!(FileIdBothDirInformation->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=FileIdBothDirInformation->EndOfFile.QuadPart; - file_info->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; - - file_info->flags=GNOME_VFS_FILE_FLAGS_LOCAL; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_FLAGS; - - if (FileIdBothDirInformation->LastAccessTime.QuadPart) { /* it may be 0 if not set */ - errBOOLEAN=RtlTimeToSecondsSince1970(&FileIdBothDirInformation->LastAccessTime,&tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->atime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME; - } + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - /* it may be 0 if not set */ - if (FileIdBothDirInformation->LastWriteTime.QuadPart || FileIdBothDirInformation->ChangeTime.QuadPart) { - errBOOLEAN=RtlTimeToSecondsSince1970( - /* take the more recent (==bigger) time: */ - (FileIdBothDirInformation->LastWriteTime.QuadPart > FileIdBothDirInformation->ChangeTime.QuadPart - ? &FileIdBothDirInformation->LastWriteTime : &FileIdBothDirInformation->ChangeTime), - &tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->mtime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME; - } + g_return_val_if_fail(captive_directory_object->vfs==NULL,GNOME_VFS_ERROR_GENERIC); - if (FileIdBothDirInformation->CreationTime.QuadPart) { /* it may be 0 if not set */ - errBOOLEAN=RtlTimeToSecondsSince1970(&FileIdBothDirInformation->CreationTime,&tmp_ULONG); - g_assert(errBOOLEAN==TRUE); - file_info->ctime=tmp_ULONG; - file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME; - } + captive_directory_object->vfs=g_object_ref(captive_vfs_object); return GNOME_VFS_OK; } @@ -240,60 +118,42 @@ ULONG tmp_ULONG; static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_directory_object) { -NTSTATUS err; -HANDLE dir_Handle; + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_close(captive_directory_object); + if (captive_directory_object->vfs!=NULL) { + g_assert(CAPTIVE_VFS_IS_OBJECT(captive_directory_object->vfs)); + g_object_unref(captive_directory_object->vfs); + captive_directory_object->vfs=NULL; + } - g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_directory_object->dir_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* already closed */ + return GNOME_VFS_OK; +} - dir_Handle=captive_directory_object->dir_Handle; - captive_directory_object->dir_Handle=NULL; - err=NtClose(dir_Handle); - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - return GNOME_VFS_OK; +CaptiveVfsObject *captive_directory_ref_vfs(CaptiveDirectoryObject *captive_directory_object) +{ + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),NULL); + + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_directory_object->vfs),NULL); + + return g_object_ref(captive_directory_object->vfs); } GnomeVFSResult captive_directory_read(CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info) { -NTSTATUS err; -IO_STATUS_BLOCK dir_IoStatusBlock; -FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation; -GnomeVFSResult errvfsresult; + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_read(captive_directory_object,file_info); + return (*CAPTIVE_DIRECTORY_OBJECT_GET_CLASS(captive_directory_object)->read) + (captive_directory_object,file_info); +} - g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(captive_directory_object->dir_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - FileIdBothDirInformation=(void *)captive_directory_object->QueryDirectory_buf; - err=NtQueryDirectoryFile( - captive_directory_object->dir_Handle, /* FileHandle */ - NULL, /* PEvent; completion signalling; optional */ - NULL, /* ApcRoutine; optional */ - NULL, /* ApcContext; optional */ - &dir_IoStatusBlock, /* IoStatusBlock */ - (gpointer)captive_directory_object->QueryDirectory_buf, /* FileInformation */ - sizeof(captive_directory_object->QueryDirectory_buf) /* Length */ - -sizeof(*FileIdBothDirInformation->FileName), /* reserve space for 0-terminator */ - FileIdBothDirectoryInformation, /* FileInformationClass; =>FILE_ID_BOTH_DIR_INFORMATION */ - TRUE, /* ReturnSingleEntry */ - NULL, /* FileName; wildcards possible; optional */ - captive_directory_object->read_first); /* RestartScan */ - captive_directory_object->read_first=FALSE; - if (err==STATUS_NO_MORE_FILES) - return GNOME_VFS_ERROR_EOF; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - - errvfsresult=FileIdBothDirInformation_to_GnomeVFSFileInfo(file_info,FileIdBothDirInformation, - &dir_IoStatusBlock); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); +GnomeVFSResult captive_directory_remove(CaptiveDirectoryObject *captive_directory_object) +{ + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - return GNOME_VFS_OK; + return (*CAPTIVE_DIRECTORY_OBJECT_GET_CLASS(captive_directory_object)->remove) + (captive_directory_object); }