X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fclient%2Fdirectory.c;h=eacc458cbf31c72b0024e3ffe1b4f69848bb43f4;hb=a2dd38f86df22c46ae18f3ad7d9850eaacb02b92;hp=e77e76f3a804cc4ba29da083a36fbd3ca4538385;hpb=2e93665e66c900fe0c254a7b6b39a2235e06591c;p=captive.git diff --git a/src/libcaptive/client/directory.c b/src/libcaptive/client/directory.c index e77e76f..eacc458 100644 --- a/src/libcaptive/client/directory.c +++ b/src/libcaptive/client/directory.c @@ -21,16 +21,8 @@ #include "captive/client-directory.h" /* self */ #include "directory.h" /* self-priv */ -#include "lib.h" #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/leave.h" -#include "captive/usecount.h" +#include "vfs.h" static gpointer captive_directory_object_parent_class=NULL; @@ -40,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); } @@ -55,17 +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; - captive_directory_object->CaptiveDirectoryObject_QueryDirectory_type= - CaptiveDirectoryObject_QueryDirectory_type_FileIdBothDirInformation; } @@ -87,397 +72,88 @@ 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; } -static GnomeVFSResult captive_directory_new_internal(CaptiveDirectoryObject **captive_directory_object_return, - const gchar *pathname,gboolean create,guint create_perm) -{ -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(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 */ - (!create || create_perm&0200 ? FILE_ATTRIBUTE_NORMAL: FILE_ATTRIBUTE_READONLY), /* FileAttributes; ignored for open */ - (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), /* ShareAccess; 0 means exclusive */ - (!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_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); - 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(dir_IoStatusBlock.Information - ==(!create ? FILE_OPENED : FILE_CREATED), - 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; -} - - GnomeVFSResult captive_directory_new_open(CaptiveDirectoryObject **captive_directory_object_return, - const gchar *pathname) + CaptiveVfsObject *captive_vfs_object,const gchar *pathname) { -GnomeVFSResult r; - - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_new_open(captive_directory_object_return,pathname); - 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); - r=captive_directory_new_internal(captive_directory_object_return,pathname, - FALSE, /* create */ - 0); /* create_perm; ignored */ - - captive_leave(); - if (r==GNOME_VFS_OK) - captive_usecount(+1); - return r; + return (*CAPTIVE_VFS_OBJECT_GET_CLASS(captive_vfs_object)->directory_new_open) + (captive_directory_object_return,captive_vfs_object,pathname); } GnomeVFSResult captive_directory_new_make(CaptiveDirectoryObject **captive_directory_object_return, - const gchar *pathname,guint perm) + CaptiveVfsObject *captive_vfs_object,const gchar *pathname,guint perm) { -GnomeVFSResult r; - 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); - r=captive_directory_new_internal(captive_directory_object_return,pathname, - TRUE, /* create */ - perm); /* create_perm; ignored */ - - captive_leave(); - if (r==GNOME_VFS_OK) - captive_usecount(+1); - return r; + 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(IoStatusBlock!=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; Redundant now, see below. */ - g_assert((gpointer)(((char *)FileIdBothDirInformation)+FileIdBothDirInformation->NextEntryOffset) - <=(gpointer)(((char *)FileIdBothDirInformation)+IoStatusBlock->Information)); - /* '->NextEntryOffset' is ==0 as we used 'ReturnSingleEntry==TRUE' */ - g_assert(FileIdBothDirInformation->NextEntryOffset==0); - - 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; } -static GnomeVFSResult FileBothDirInformation_to_FileIdBothDirInformation(FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation, - FILE_BOTH_DIR_INFORMATION *FileBothDirInformation,IO_STATUS_BLOCK *IoStatusBlock) +static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_directory_object) { -static LARGE_INTEGER FileId_counter; - - g_return_val_if_fail(FileIdBothDirInformation!=NULL,GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(FileBothDirInformation!=NULL,GNOME_VFS_ERROR_GENERIC); - g_return_val_if_fail(IoStatusBlock!=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; Redundant now, see below. */ - g_assert((gpointer)(((char *)FileBothDirInformation)+FileBothDirInformation->NextEntryOffset) - <=(gpointer)(((char *)FileBothDirInformation)+IoStatusBlock->Information)); - /* '->NextEntryOffset' is ==0 as we used 'ReturnSingleEntry==TRUE' */ - g_assert(FileBothDirInformation->NextEntryOffset==0); - - g_assert((gpointer)(((char *)FileBothDirInformation->FileName)+FileBothDirInformation->FileNameLength) - <=(gpointer)(((char *)FileBothDirInformation)+IoStatusBlock->Information)); - /* ensure we fit below '->IoStatusBlock->Information' at least without the 0-terminator */ - memcpy(FileIdBothDirInformation->FileName,FileBothDirInformation->FileName, - FileBothDirInformation->FileNameLength); - - /* NextEntryOffset already handled */ - FileIdBothDirInformation->FileIndex =FileBothDirInformation->FileIndex; - FileIdBothDirInformation->CreationTime =FileBothDirInformation->CreationTime; - FileIdBothDirInformation->LastAccessTime =FileBothDirInformation->LastAccessTime; - FileIdBothDirInformation->LastWriteTime =FileBothDirInformation->LastWriteTime; - FileIdBothDirInformation->ChangeTime =FileBothDirInformation->ChangeTime; - FileIdBothDirInformation->EndOfFile =FileBothDirInformation->EndOfFile; - FileIdBothDirInformation->AllocationSize =FileBothDirInformation->AllocationSize; - FileIdBothDirInformation->FileAttributes =FileBothDirInformation->FileAttributes; - FileIdBothDirInformation->FileNameLength =FileBothDirInformation->FileNameLength; - FileIdBothDirInformation->EaSize =FileBothDirInformation->EaSize; - FileIdBothDirInformation->ShortNameLength=FileBothDirInformation->ShortNameLength; - g_assert(sizeof(FileIdBothDirInformation->ShortName)==sizeof(FileBothDirInformation->ShortName)); - memcpy(FileIdBothDirInformation->ShortName,FileBothDirInformation->ShortName, - sizeof(FileBothDirInformation->ShortName)); - /* FIXME: Register filenames for uniqueness; - * Not needed now as 'FileId' field not used by libcaptive anywhere anyway. - */ - FileIdBothDirInformation->FileId.QuadPart=FileId_counter.QuadPart++; - /* FileName already handled */ - - IoStatusBlock->Information=sizeof(*FileIdBothDirInformation)+FileIdBothDirInformation->FileNameLength; - /* '->NextEntryOffset' is ==0 as we used 'ReturnSingleEntry==TRUE' */ - FileIdBothDirInformation->NextEntryOffset=0; + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + + 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; + } return GNOME_VFS_OK; } -static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_directory_object) +CaptiveVfsObject *captive_directory_ref_vfs(CaptiveDirectoryObject *captive_directory_object) { -NTSTATUS err; -HANDLE dir_Handle; + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),NULL); - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_close(captive_directory_object); + g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(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 */ - - captive_usecount(-1); /* close() errors notwithstanding */ - - 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); - - captive_leave(); - return GNOME_VFS_OK; + 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; -FILE_BOTH_DIR_INFORMATION *FileBothDirInformation; -GnomeVFSResult errvfsresult; - - if (CAPTIVE_IS_SANDBOX_PARENT()) - return captive_sandbox_parent_directory_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(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); - FileIdBothDirInformation=(void *)captive_directory_object->QueryDirectory_buf.FileIdBothDirInformation; -retry: - switch (captive_directory_object->CaptiveDirectoryObject_QueryDirectory_type) { - - case CaptiveDirectoryObject_QueryDirectory_type_FileIdBothDirInformation: - 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.FileIdBothDirInformation, /* FileInformation */ - sizeof(captive_directory_object->QueryDirectory_buf.FileIdBothDirInformation) /* 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 */ - if (err==STATUS_NO_SUCH_FILE) { - /* 'FileIdBothDirInformation' not supported at least by ext2fsd.sys. - * Emulate it from 'FileBothDirectoryInformation' here. - */ - captive_directory_object->CaptiveDirectoryObject_QueryDirectory_type= - CaptiveDirectoryObject_QueryDirectory_type_FileBothDirInformation; - goto retry; - } - - captive_directory_object->read_first=FALSE; - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - break; - - case CaptiveDirectoryObject_QueryDirectory_type_FileBothDirInformation: - FileBothDirInformation=(void *)captive_directory_object->QueryDirectory_buf.FileBothDirInformation; - /* SL_INDEX_SPECIFIED is forbidden for ext2fsd.sys-V0.10A although - * IIRC it was required for the native W32 filesystems. - * Fortunately 'FileBothDirInformation' is just a workaround for ext2fsd.sys-V0.10A - * which is not used for the native W32 filesystems and therefore it should be safe. - * WARNING: Hack with 'FileIndex==0' to prevent SL_INDEX_SPECIFIED is just libcaptive - * specific hack of reactos! See also NtQueryDirectoryFile(). - */ - FileBothDirInformation->FileIndex=0; - 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.FileBothDirInformation, /* FileInformation */ - sizeof(captive_directory_object->QueryDirectory_buf.FileBothDirInformation) /* Length */ - -sizeof(*FileBothDirInformation->FileName), /* reserve space for 0-terminator */ - FileBothDirectoryInformation, /* FileInformationClass; =>FILE_BOTH_DIR_INFORMATION */ - TRUE, /* ReturnSingleEntry */ - NULL, /* FileName; wildcards possible; optional */ - captive_directory_object->read_first); /* RestartScan */ - - captive_directory_object->read_first=FALSE; - if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) - return errvfsresult; - g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC); - - errvfsresult=FileBothDirInformation_to_FileIdBothDirInformation(FileIdBothDirInformation,FileBothDirInformation, - &dir_IoStatusBlock); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); - break; - - default: g_assert_not_reached(); - } - - errvfsresult=FileIdBothDirInformation_to_GnomeVFSFileInfo(file_info,FileIdBothDirInformation, - &dir_IoStatusBlock); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); - - captive_leave(); - return GNOME_VFS_OK; + return (*CAPTIVE_DIRECTORY_OBJECT_GET_CLASS(captive_directory_object)->read) + (captive_directory_object,file_info); } GnomeVFSResult captive_directory_remove(CaptiveDirectoryObject *captive_directory_object) { -NTSTATUS err; -FILE_DISPOSITION_INFORMATION FileDispositionInformation_struct; -IO_STATUS_BLOCK dir_IoStatusBlock; -GnomeVFSResult errvfsresult; - - 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); - - FileDispositionInformation_struct.DoDeleteFile=TRUE; - - err=NtSetInformationFile( - captive_directory_object->dir_Handle, /* FileHandle */ - &dir_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); - - captive_leave(); - return GNOME_VFS_OK; + g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); + + return (*CAPTIVE_DIRECTORY_OBJECT_GET_CLASS(captive_directory_object)->remove) + (captive_directory_object); }