libcaptive-gnomevfs.so separated to Gnome-VFS vs. reactos specific parts
authorshort <>
Sat, 11 Jan 2003 18:23:28 +0000 (18:23 +0000)
committershort <>
Sat, 11 Jan 2003 18:23:28 +0000 (18:23 +0000)
 - Gnome-VFS part remains in src/client/libcaptive-gnomevfs/
 - reactos part implemented by "captive/client-*.h" and "libcaptive/client/*.c"

src/client/libcaptive-gnomevfs/gnome-vfs-method.c
src/libcaptive/client/Makefile.am
src/libcaptive/client/directory.c [new file with mode: 0644]
src/libcaptive/client/file.c [new file with mode: 0644]
src/libcaptive/client/file_info.c [new file with mode: 0644]
src/libcaptive/client/lib.c [new file with mode: 0644]
src/libcaptive/client/lib.h [new file with mode: 0644]
src/libcaptive/include/captive/Makefile.am
src/libcaptive/include/captive/client-directory.h [new file with mode: 0644]
src/libcaptive/include/captive/client-file.h [new file with mode: 0644]
src/libcaptive/include/captive/client-file_info.h [new file with mode: 0644]

index ed26d6b..759c79f 100644 (file)
 #include "giognomevfs.h"
 #include <libgnomevfs/gnome-vfs-method.h>
 #include <glib/gmessages.h>
-#include <string.h>
-#include "reactos/ntos/types.h"        /* for HANDLE */
-#include "reactos/ddk/iotypes.h"       /* for IO_STATUS_BLOCK */
 #include "captive/macros.h"
-#include "reactos/ddk/rtl.h"   /* for InitializeObjectAttributes() */
-#include "captive/unicode.h"
-#include "reactos/ddk/iofuncs.h"       /* for IoCreateFile() */
 #include "gnome-vfs-module.h"
-#include <libgnomevfs/gnome-vfs-utils.h>       /* for gnome_vfs_unescape_string() */
+#include "captive/client-directory.h"
+#include "captive/client-file.h"
+#include "captive/client-file_info.h"
 
 
 static GnomeVFSMethod GnomeVFSMethod_static;
@@ -44,13 +40,10 @@ static gchar *captive_gnomevfs_uri_parent_fs_path;
 static struct captive_gnomevfs_giognomevfs *captive_gnomevfs_uri_parent_giognomevfs;
 
 
-/* function will leave g_malloc()ed 'ObjectAttributes->ObjectName' if ObjectAttributes !
- */
-static GnomeVFSResult captive_gnomevfs_uri_parent_init(GnomeVFSURI *uri,OBJECT_ATTRIBUTES *ObjectAttributes)
+static GnomeVFSResult captive_gnomevfs_uri_parent_init(GnomeVFSURI *uri)
 {
 gchar *uri_parent_string;
 GnomeVFSResult errvfsresult;
-gchar *w32_path,*s,*d,*vfs_path;
 
        g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_INVALID_URI);
 
@@ -74,218 +67,45 @@ gchar *w32_path,*s,*d,*vfs_path;
                }
        G_UNLOCK(captive_gnomevfs_uri_parent);
 
-       if (ObjectAttributes) {
-               /* Do not open "\Cdfs"(anything) as it is just the filesystem implementation.
-                * ntoskrnl/io/fs.c/IoMountVolume() will map
-                *  FILE_DEVICE_CD_ROM -> FILE_DEVICE_CD_ROM_FILE_SYSTEM
-                * for us automatically when opening the device itself.
-                * If you put some trailing content (such as "\\.") there
-                *  IoCreateFile()->ObCreateObject()->ObFindObject()
-                * will not leave 'ObCreateObject::RemainingPath' as NULL
-                * and later IopCreateFile() would not consider it FO_DIRECT_DEVICE_OPEN (e.g. w/o any direct mount!).
-                * On the other side it will somehow get managed automatically and it works even
-                * without the trailing "\\." for root directory open - don't ask me why. :-)
-                */
-               vfs_path=gnome_vfs_unescape_string(     /* decode %xy escaping */
-                               uri->text,      /* escaped */
-                               NULL);  /* illegal_characters */
-               w32_path=(gchar *)/* de-const it as we can modify it but we must not free() it */
-                               captive_printf_alloca("\\Device\\CdRom0\\%s",vfs_path);
-               g_free(vfs_path);
-               /* translate '/' -> '\' */
-               for (s=w32_path;(s=strchr(s,'/'));s++)
-                       *s='\\';
-               /* collapse multiple sequences of '\' as it is a no-no for W32 */
-               for (s=d=w32_path;*s;s++)
-                       if (d==w32_path || !(*s=='\\' && d[-1]=='\\'))
-                               *d++=*s;
-               *d=0;
-               G_LOCK(libcaptive);
-               InitializeObjectAttributes(
-                               ObjectAttributes,       /* InitializedAttributes */
-                               captive_utf8_to_UnicodeString_malloc(w32_path), /* ObjectName */
-                               0,      /* Attributes; I hope no OBJ_KERNEL_HANDLE as we are 'system process' */
-                               NULL,   /* RootDirectory */
-                               NULL);  /* SecurityDescriptor; ignored */
-               G_UNLOCK(libcaptive);
-               }
-
        return GNOME_VFS_OK;
 }
 
 
-struct captive_gnomevfs_directory_handle {
-       HANDLE dir_Handle;
-       gboolean read_first;
-       /* 'QueryDirectory_buf' for NtQueryDirectoryFile() must be persistent
-        * to keep the state if !read_first
-        */
-       char QueryDirectory_buf[sizeof(FILE_ID_BOTH_DIR_INFORMATION)
-                       +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ID_BOTH_DIR_INFORMATION.FileName */ )];
-       };
-
 static GnomeVFSResult captive_gnomevfs_open_directory(GnomeVFSMethod *method,
                GnomeVFSMethodHandle **method_handle,GnomeVFSURI *uri,GnomeVFSFileInfoOptions options,GnomeVFSContext *context)
 {
 GnomeVFSResult errvfsresult;
-OBJECT_ATTRIBUTES dir_ObjectAttributes;
-HANDLE dir_Handle;
-IO_STATUS_BLOCK dir_IoStatusBlock;
-NTSTATUS err;
-struct captive_gnomevfs_directory_handle *directory_handle;
+CaptiveDirectoryObject *captive_directory_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       errvfsresult=captive_gnomevfs_uri_parent_init(uri,&dir_ObjectAttributes);
+       errvfsresult=captive_gnomevfs_uri_parent_init(uri);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
-       
-       /* wanted: * IoCreateFile()->ObCreateObject(,,,IoFileObjectType)->
-        * ->(IoFileObjectType->Create==IopCreateFile)()->IoMountVolume()
-        */
+
        G_LOCK(libcaptive);
-       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 */
+       errvfsresult=captive_directory_new_open(
+                       &captive_directory_object,      /* captive_directory_object_return */
+                       uri->text);     /* pathname */
        G_UNLOCK(libcaptive);
-       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_new(directory_handle);
-       directory_handle->dir_Handle=dir_Handle;
-       directory_handle->read_first=TRUE;
 
-       *method_handle=(GnomeVFSMethodHandle *)directory_handle;
-       return GNOME_VFS_OK;
+       *method_handle=(GnomeVFSMethodHandle *)captive_directory_object;
+       return errvfsresult;
 }
 
 
 static GnomeVFSResult captive_gnomevfs_close_directory(GnomeVFSMethod *method,
                GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context)
 {
-struct captive_gnomevfs_directory_handle *directory_handle;
-NTSTATUS err;
+CaptiveDirectoryObject *captive_directory_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_directory_object=(CaptiveDirectoryObject *)method_handle;
+       g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       directory_handle=(struct captive_gnomevfs_directory_handle *)method_handle;
        G_LOCK(libcaptive);
-       err=NtClose(directory_handle->dir_Handle);
+       g_object_unref(captive_directory_object);
        G_UNLOCK(libcaptive);
-       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-
-       g_free(directory_handle);
-       return GNOME_VFS_OK;
-}
-
-
-static GnomeVFSResult FileIdBothDirInformation_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
-               FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation,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(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;
-               }
-
-       /* 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;
-               }
-
-       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;
-               }
 
        return GNOME_VFS_OK;
 }
@@ -294,125 +114,56 @@ ULONG tmp_ULONG;
 static GnomeVFSResult captive_gnomevfs_read_directory(GnomeVFSMethod *method,
                GnomeVFSMethodHandle *method_handle,GnomeVFSFileInfo *file_info,GnomeVFSContext *context)
 {
-struct captive_gnomevfs_directory_handle *directory_handle;
-NTSTATUS err;
-IO_STATUS_BLOCK dir_IoStatusBlock;
-FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation;
 GnomeVFSResult errvfsresult;
+CaptiveDirectoryObject *captive_directory_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_directory_object=(CaptiveDirectoryObject *)method_handle;
+       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);
 
-       directory_handle=(struct captive_gnomevfs_directory_handle *)method_handle;
-
-       FileIdBothDirInformation=(void *)directory_handle->QueryDirectory_buf;
        G_LOCK(libcaptive);
-       err=NtQueryDirectoryFile(
-                       directory_handle->dir_Handle,   /* FileHandle */
-                       NULL,   /* PEvent; completion signalling; optional */
-                       NULL,   /* ApcRoutine; optional */
-                       NULL,   /* ApcContext; optional */
-                       &dir_IoStatusBlock,     /* IoStatusBlock */
-                       (gpointer)directory_handle->QueryDirectory_buf, /* FileInformation */
-                       sizeof(directory_handle->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 */
-                       directory_handle->read_first);  /* RestartScan */
+       errvfsresult=captive_directory_read(captive_directory_object,file_info);
        G_UNLOCK(libcaptive);
-       directory_handle->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);
-
-       return GNOME_VFS_OK;
+       return errvfsresult;
 }
 
 
-struct captive_gnomevfs_file_handle {
-       HANDLE file_Handle;
-       GnomeVFSFileOffset offset;
-       };
-
 static GnomeVFSResult captive_gnomevfs_open(GnomeVFSMethod *method,
                GnomeVFSMethodHandle **method_handle_return,GnomeVFSURI *uri,GnomeVFSOpenMode mode,GnomeVFSContext *context)
 {
-IO_STATUS_BLOCK file_IoStatusBlock;
 GnomeVFSResult errvfsresult;
-OBJECT_ATTRIBUTES file_ObjectAttributes;
-HANDLE file_Handle;
-struct captive_gnomevfs_file_handle *file_handle;
-NTSTATUS err;
+CaptiveFileObject *captive_file_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       /* init */
-       errvfsresult=captive_gnomevfs_uri_parent_init(uri,&file_ObjectAttributes);
+       errvfsresult=captive_gnomevfs_uri_parent_init(uri);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
-       
-       /* open */
+
        G_LOCK(libcaptive);
-       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)
-                                       ,       /* DesiredAccess */
-                       &file_ObjectAttributes, /* ObjectAttributes */
-                       &file_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_SYNCHRONOUS_IO_ALERT,      /* CreateOptions */
-                       NULL,   /* EaBuffer */
-                       0,      /* EaLength */
-                       CreateFileTypeNone,     /* CreateFileType */
-                       NULL,   /* ExtraCreateParameters */
-                       0);     /* Options */
+       errvfsresult=captive_file_new_open(&captive_file_object,uri->text,mode);
        G_UNLOCK(libcaptive);
-       g_free(file_ObjectAttributes.ObjectName);       /* left from captive_gnomevfs_uri_parent_init() */
-       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==FILE_OPENED,GNOME_VFS_ERROR_GENERIC);
-
-       captive_new(file_handle);
-       file_handle->file_Handle=file_Handle;
-       file_handle->offset=0;
 
-       *method_handle_return=(GnomeVFSMethodHandle *)file_handle;
-       return GNOME_VFS_OK;
+       *method_handle_return=(GnomeVFSMethodHandle *)captive_file_object;
+       return errvfsresult;
 }
 
 
 static GnomeVFSResult captive_gnomevfs_close(GnomeVFSMethod *method,
                GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context)
 {
-struct captive_gnomevfs_file_handle *file_handle;
-NTSTATUS err;
+CaptiveFileObject *captive_file_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_file_object=(CaptiveFileObject *)method_handle;
+       g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       file_handle=(struct captive_gnomevfs_file_handle *)method_handle;
        G_LOCK(libcaptive);
-       err=NtClose(file_handle->file_Handle);
+       g_object_unref(captive_file_object);
        G_UNLOCK(libcaptive);
-       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
 
-       g_free(file_handle);
        return GNOME_VFS_OK;
 }
 
@@ -420,89 +171,56 @@ NTSTATUS err;
 static GnomeVFSResult captive_gnomevfs_read(GnomeVFSMethod *method,GnomeVFSMethodHandle *method_handle,
                gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return,GnomeVFSContext *context)
 {
-struct captive_gnomevfs_file_handle *file_handle;
-NTSTATUS err;
-IO_STATUS_BLOCK file_IoStatusBlock;
-LARGE_INTEGER file_offset;
+GnomeVFSResult errvfsresult;
+CaptiveFileObject *captive_file_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_file_object=(CaptiveFileObject *)method_handle;
+       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_handle=(struct captive_gnomevfs_file_handle *)method_handle;
-       file_offset.QuadPart=file_handle->offset;
        G_LOCK(libcaptive);
-       err=NtReadFile(
-                       file_handle->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 */
+       errvfsresult=captive_file_read(captive_file_object,buffer,num_bytes,bytes_read_return);
        G_UNLOCK(libcaptive);
-       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;
-               }
-       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);
 
-       file_handle->offset+=file_IoStatusBlock.Information;
-       *bytes_read_return=file_IoStatusBlock.Information;
-       return GNOME_VFS_OK;
+       return errvfsresult;
 }
 
 
 static GnomeVFSResult captive_gnomevfs_seek(GnomeVFSMethod *method,
                GnomeVFSMethodHandle *method_handle,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset,GnomeVFSContext *context)
 {
-struct captive_gnomevfs_file_handle *file_handle;
+GnomeVFSResult errvfsresult;
+CaptiveFileObject *captive_file_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_file_object=(CaptiveFileObject *)method_handle;
+       g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       file_handle=(struct captive_gnomevfs_file_handle *)method_handle;
-       switch (whence) {
-               case GNOME_VFS_SEEK_START:
-                       file_handle->offset=offset;
-                       break;
-               case GNOME_VFS_SEEK_CURRENT:
-                       if (0
-                                       || (offset>0 && (file_handle->offset+offset)<file_handle->offset)
-                                       || (offset<0 && (file_handle->offset+offset)>file_handle->offset))
-                               return GNOME_VFS_ERROR_BAD_PARAMETERS;
-                       file_handle->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_LOCK(libcaptive);
+       errvfsresult=captive_file_seek(captive_file_object,whence,offset);
+       G_UNLOCK(libcaptive);
 
-       return GNOME_VFS_OK;
+       return errvfsresult;
 }
 
 static GnomeVFSResult captive_gnomevfs_tell(GnomeVFSMethod *method,
                GnomeVFSMethodHandle *method_handle,GnomeVFSFileOffset *offset_return)
 {
-struct captive_gnomevfs_file_handle *file_handle;
+GnomeVFSResult errvfsresult;
+CaptiveFileObject *captive_file_object;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       captive_file_object=(CaptiveFileObject *)method_handle;
+       g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-       file_handle=(struct captive_gnomevfs_file_handle *)method_handle;
-       *offset_return=file_handle->offset;
-       return GNOME_VFS_OK;
+       G_LOCK(libcaptive);
+       errvfsresult=captive_file_tell(captive_file_object,offset_return);
+       G_UNLOCK(libcaptive);
+
+       return errvfsresult;
 }
 
 
@@ -523,181 +241,23 @@ static gboolean captive_gnomevfs_is_local(GnomeVFSMethod *method,const GnomeVFSU
 }
 
 
-/* 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;
-}
-
-
 static GnomeVFSResult captive_gnomevfs_get_file_info(GnomeVFSMethod *method,
                GnomeVFSURI *uri,GnomeVFSFileInfo *file_info,GnomeVFSFileInfoOptions options,GnomeVFSContext *context)
 {
-NTSTATUS err;
-IO_STATUS_BLOCK file_IoStatusBlock;
-FILE_ALL_INFORMATION *FileAllInformationStruct;
 GnomeVFSResult errvfsresult;
-OBJECT_ATTRIBUTES file_ObjectAttributes;
-HANDLE file_Handle;
-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(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */
 
-       /* init */
-       errvfsresult=captive_gnomevfs_uri_parent_init(uri,&file_ObjectAttributes);
+       errvfsresult=captive_gnomevfs_uri_parent_init(uri);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
-       
-       /* open */
-       G_LOCK(libcaptive);
-       err=IoCreateFile(
-                       &file_Handle,   /* FileHandle */
-                       FILE_READ_ATTRIBUTES,   /* DesiredAccess */
-                       &file_ObjectAttributes, /* ObjectAttributes */
-                       &file_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_SYNCHRONOUS_IO_ALERT,      /* CreateOptions */
-                       NULL,   /* EaBuffer */
-                       0,      /* EaLength */
-                       CreateFileTypeNone,     /* CreateFileType */
-                       NULL,   /* ExtraCreateParameters */
-                       0);     /* Options */
-       G_UNLOCK(libcaptive);
-       g_free(file_ObjectAttributes.ObjectName);       /* left from captive_gnomevfs_uri_parent_init() */
-       g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
-       if (err==STATUS_OBJECT_NAME_NOT_FOUND)
-               return GNOME_VFS_ERROR_NOT_FOUND;
-       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-       g_return_val_if_fail(file_IoStatusBlock.Information==FILE_OPENED,GNOME_VFS_ERROR_GENERIC);
-
-       /* query */
-       FileAllInformationStruct=(void *)QueryFile_buf;
-       G_LOCK(libcaptive);
-       err=NtQueryInformationFile(
-                       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 */
-       G_UNLOCK(libcaptive);
-       if (!NT_SUCCESS(err)) {
-               g_assert_not_reached();
-               goto err_close;
-               }
 
-       /* close */
        G_LOCK(libcaptive);
-       err=NtClose(file_Handle);
+       errvfsresult=captive_file_info_get(uri->text,file_info);
        G_UNLOCK(libcaptive);
-       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;
-
-err_close:
-       G_LOCK(libcaptive);
-       err=NtClose(file_Handle);
-       G_UNLOCK(libcaptive);
-       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
-/* err: */
-       g_return_val_if_reached(GNOME_VFS_ERROR_GENERIC);
+       return errvfsresult;
 }
 
 
index 5808019..6fc288b 100644 (file)
@@ -21,4 +21,8 @@ include $(top_srcdir)/src/libcaptive/Makefile-libcaptive.am
 
 noinst_LTLIBRARIES=libclient.la
 libclient_la_SOURCES= \
-               init.c
+               init.c \
+               lib.c \
+               directory.c \
+               file.c \
+               file_info.c
diff --git a/src/libcaptive/client/directory.c b/src/libcaptive/client/directory.c
new file mode 100644 (file)
index 0000000..41ed664
--- /dev/null
@@ -0,0 +1,298 @@
+/* $Id$
+ * captive vfs 'directory' interface to reactos
+ * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "captive/client-directory.h"  /* self */
+#include "lib.h"
+#include <glib/gmessages.h>
+#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() */
+
+
+static gpointer captive_directory_object_parent_class=NULL;
+
+
+static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_directory_object);
+
+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);
+
+       G_OBJECT_CLASS(captive_directory_object_parent_class)->finalize((GObject *)captive_directory_object);
+}
+
+
+static void captive_directory_object_class_init(CaptiveDirectoryObjectClass *class)
+{
+GObjectClass *gobject_class=G_OBJECT_CLASS(class);
+
+       captive_directory_object_parent_class=g_type_class_ref(G_TYPE_OBJECT);
+       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;
+}
+
+
+GType captive_directory_object_get_type(void)
+{
+static GType captive_directory_object_type=0;
+
+       if (!captive_directory_object_type) {
+static const GTypeInfo captive_directory_object_info={
+                               sizeof(CaptiveDirectoryObjectClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc)captive_directory_object_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof(CaptiveDirectoryObject),
+                               5,      /* n_preallocs */
+                               (GInstanceInitFunc)captive_directory_object_init,
+                               };
+
+               captive_directory_object_type=g_type_register_static(G_TYPE_OBJECT,
+                               "CaptiveDirectoryObject",&captive_directory_object_info,0);
+               }
+
+       return captive_directory_object_type;
+}
+
+
+GnomeVFSResult captive_directory_new_open(CaptiveDirectoryObject **captive_directory_object_return,const gchar *pathname)
+{
+GnomeVFSResult errvfsresult;
+OBJECT_ATTRIBUTES dir_ObjectAttributes;
+HANDLE dir_Handle;
+IO_STATUS_BLOCK dir_IoStatusBlock;
+NTSTATUS err;
+CaptiveDirectoryObject *captive_directory_object;
+
+       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(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;
+}
+
+
+static GnomeVFSResult FileIdBothDirInformation_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
+               FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation,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(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;
+               }
+
+       /* 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;
+               }
+
+       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;
+               }
+
+       return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult captive_directory_close(CaptiveDirectoryObject *captive_directory_object)
+{
+NTSTATUS err;
+HANDLE dir_Handle;
+
+       if (CAPTIVE_IS_SANDBOX_PARENT())
+               return captive_sandbox_parent_directory_close(captive_directory_object);
+
+       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 */
+
+       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;
+}
+
+
+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;
+
+       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(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);
+
+       return GNOME_VFS_OK;
+}
diff --git a/src/libcaptive/client/file.c b/src/libcaptive/client/file.c
new file mode 100644 (file)
index 0000000..bbabcee
--- /dev/null
@@ -0,0 +1,256 @@
+/* $Id$
+ * captive vfs 'file' interface to reactos
+ * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "captive/client-file.h"       /* self */
+#include "lib.h"
+#include <glib/gmessages.h>
+#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() */
+
+
+static gpointer captive_file_object_parent_class=NULL;
+
+
+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);
+
+       G_OBJECT_CLASS(captive_file_object_parent_class)->finalize((GObject *)captive_file_object);
+}
+
+
+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);
+       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;
+}
+
+
+GType captive_file_object_get_type(void)
+{
+static GType captive_file_object_type=0;
+
+       if (!captive_file_object_type) {
+static const GTypeInfo captive_file_object_info={
+                               sizeof(CaptiveFileObjectClass),
+                               NULL,   /* base_init */
+                               NULL,   /* base_finalize */
+                               (GClassInitFunc)captive_file_object_class_init,
+                               NULL,   /* class_finalize */
+                               NULL,   /* class_data */
+                               sizeof(CaptiveFileObject),
+                               5,      /* n_preallocs */
+                               (GInstanceInitFunc)captive_file_object_init,
+                               };
+
+               captive_file_object_type=g_type_register_static(G_TYPE_OBJECT,
+                               "CaptiveFileObject",&captive_file_object_info,0);
+               }
+
+       return captive_file_object_type;
+}
+
+
+GnomeVFSResult captive_file_new_open
+               (CaptiveFileObject **captive_file_object_return,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(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)
+                                       ,       /* DesiredAccess */
+                       &file_ObjectAttributes, /* ObjectAttributes */
+                       &file_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_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);
+       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+       g_return_val_if_fail(file_IoStatusBlock.Information==FILE_OPENED,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;
+}
+
+
+static GnomeVFSResult captive_file_close(CaptiveFileObject *captive_file_object)
+{
+NTSTATUS err;
+HANDLE file_Handle;
+
+       if (CAPTIVE_IS_SANDBOX_PARENT())
+               return captive_sandbox_parent_file_close(captive_file_object);
+
+       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 */
+
+       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;
+}
+
+
+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;
+
+       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(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;
+               }
+       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;
+}
+
+
+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)<captive_file_object->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);
+               }
+
+       return GNOME_VFS_OK;
+}
+
+
+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);
+
+       *offset_return=captive_file_object->offset;
+       return GNOME_VFS_OK;
+}
diff --git a/src/libcaptive/client/file_info.c b/src/libcaptive/client/file_info.c
new file mode 100644 (file)
index 0000000..97a0703
--- /dev/null
@@ -0,0 +1,198 @@
+/* $Id$
+ * captive vfs 'file' interface to reactos
+ * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "captive/client-file_info.h"  /* self */
+#include "lib.h"
+#include <glib/gmessages.h>
+#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() */
+
+
+/* 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;
+}
+
+
+GnomeVFSResult captive_file_info_get(const gchar *pathname,GnomeVFSFileInfo *file_info)
+{
+NTSTATUS err;
+IO_STATUS_BLOCK file_IoStatusBlock;
+FILE_ALL_INFORMATION *FileAllInformationStruct;
+GnomeVFSResult errvfsresult;
+OBJECT_ATTRIBUTES file_ObjectAttributes;
+HANDLE file_Handle;
+char QueryFile_buf[sizeof(FILE_ALL_INFORMATION)
+               +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ALL_INFORMATION.NameInformation.FileName */ )];
+
+       if (CAPTIVE_IS_SANDBOX_PARENT())
+               return captive_sandbox_parent_file_info_get(pathname,file_info);
+
+       g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       errvfsresult=captive_ObjectAttributes_init(pathname,&file_ObjectAttributes);
+       g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
+       
+       /* open */
+       err=IoCreateFile(
+                       &file_Handle,   /* FileHandle */
+                       FILE_READ_ATTRIBUTES,   /* DesiredAccess */
+                       &file_ObjectAttributes, /* ObjectAttributes */
+                       &file_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_SYNCHRONOUS_IO_ALERT,      /* CreateOptions */
+                       NULL,   /* EaBuffer */
+                       0,      /* EaLength */
+                       CreateFileTypeNone,     /* CreateFileType */
+                       NULL,   /* ExtraCreateParameters */
+                       0);     /* Options */
+       g_free(file_ObjectAttributes.ObjectName);       /* left from captive_gnomevfs_uri_parent_init() */
+       g_return_val_if_fail(NT_SUCCESS(err)==NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
+       if (err==STATUS_OBJECT_NAME_NOT_FOUND)
+               return GNOME_VFS_ERROR_NOT_FOUND;
+       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+       g_return_val_if_fail(file_IoStatusBlock.Information==FILE_OPENED,GNOME_VFS_ERROR_GENERIC);
+
+       /* query */
+       FileAllInformationStruct=(void *)QueryFile_buf;
+       err=NtQueryInformationFile(
+                       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 (!NT_SUCCESS(err)) {
+               g_assert_not_reached();
+               goto err_close;
+               }
+
+       /* close */
+       err=NtClose(file_Handle);
+       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;
+
+err_close:
+       err=NtClose(file_Handle);
+       g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+/* err: */
+       g_return_val_if_reached(GNOME_VFS_ERROR_GENERIC);
+}
diff --git a/src/libcaptive/client/lib.c b/src/libcaptive/client/lib.c
new file mode 100644 (file)
index 0000000..ed4ef28
--- /dev/null
@@ -0,0 +1,70 @@
+/* $Id$
+ * captive vfs utility functions for interface to reactos
+ * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "lib.h"       /* self */
+#include <libgnomevfs/gnome-vfs-result.h>
+#include <glib/gmessages.h>
+#include "captive/macros.h"
+#include "reactos/ddk/rtl.h"   /* for InitializeObjectAttributes() */
+#include "captive/unicode.h"
+#include <libgnomevfs/gnome-vfs-utils.h>       /* for gnome_vfs_unescape_string() */
+#include <glib/gprintf.h>
+
+
+/* function will leave g_malloc()ed 'ObjectAttributes->ObjectName'!
+ */
+GnomeVFSResult captive_ObjectAttributes_init(const gchar *pathname,OBJECT_ATTRIBUTES *ObjectAttributes)
+{
+gchar *w32_path,*s,*d;
+
+       g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(ObjectAttributes!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       /* Do not open "\Cdfs"(anything) as it is just the filesystem implementation.
+        * ntoskrnl/io/fs.c/IoMountVolume() will map
+        *  FILE_DEVICE_CD_ROM -> FILE_DEVICE_CD_ROM_FILE_SYSTEM
+        * for us automatically when opening the device itself.
+        * If you put some trailing content (such as "\\.") there
+        *  IoCreateFile()->ObCreateObject()->ObFindObject()
+        * will not leave 'ObCreateObject::RemainingPath' as NULL
+        * and later IopCreateFile() would not consider it FO_DIRECT_DEVICE_OPEN (e.g. w/o any direct mount!).
+        * On the other side it will somehow get managed automatically and it works even
+        * without the trailing "\\." for root directory open - don't ask me why. :-)
+        */
+       w32_path=(gchar *)/* de-const it as we can modify it but we must not free() it */
+                       captive_printf_alloca("\\Device\\CdRom0\\%s",pathname);
+       /* translate '/' -> '\' */
+       for (s=w32_path;(s=strchr(s,'/'));s++)
+               *s='\\';
+       /* collapse multiple sequences of '\' as it is a no-no for W32 */
+       for (s=d=w32_path;*s;s++)
+               if (d==w32_path || !(*s=='\\' && d[-1]=='\\'))
+                       *d++=*s;
+       *d=0;
+       InitializeObjectAttributes(
+                       ObjectAttributes,       /* InitializedAttributes */
+                       captive_utf8_to_UnicodeString_malloc(w32_path), /* ObjectName */
+                       0,      /* Attributes; I hope no OBJ_KERNEL_HANDLE as we are 'system process' */
+                       NULL,   /* RootDirectory */
+                       NULL);  /* SecurityDescriptor; ignored */
+
+       return GNOME_VFS_OK;
+}
diff --git a/src/libcaptive/client/lib.h b/src/libcaptive/client/lib.h
new file mode 100644 (file)
index 0000000..73aeba8
--- /dev/null
@@ -0,0 +1,36 @@
+/* $Id$
+ * Include file for captive vfs utility functions for interface to reactos
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _CAPTIVE_CLIENT_LIB_H
+#define _CAPTIVE_CLIENT_LIB_H 1
+
+
+#include <glib/gmacros.h>
+#include "reactos/ddk/obtypes.h"       /* for OBJECT_ATTRIBUTES */
+#include <libgnomevfs/gnome-vfs-result.h>
+
+
+G_BEGIN_DECLS
+
+GnomeVFSResult captive_ObjectAttributes_init(const gchar *pathname,OBJECT_ATTRIBUTES *ObjectAttributes);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_CLIENT_LIB_H */
index 6648e51..87ecf8d 100644 (file)
@@ -22,12 +22,16 @@ include $(top_srcdir)/src/libcaptive/Makefile-libcaptive.am
 pkginclude_HEADERS+= \
                calltype_reactos.h \
                client.h \
-               file.h \
+               client-directory.h \
+               client-file.h \
+               client-file_info.h \
                ldr.h \
                ldr_exports.h \
                macros.h \
                mm.h \
                ps_reactos.h \
+               rtl-file.h \
+               sandbox.h \
                signal.h \
                storage.h \
                unicode.h \
diff --git a/src/libcaptive/include/captive/client-directory.h b/src/libcaptive/include/captive/client-directory.h
new file mode 100644 (file)
index 0000000..221b013
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id$
+ * Include file with client-application 'directory' access to libcaptive
+ * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _CAPTIVE_CLIENT_DIRECTORY_H
+#define _CAPTIVE_CLIENT_DIRECTORY_H 1
+
+
+#include <glib/gmacros.h>
+#include <glib-object.h>
+#include "reactos/ntos/types.h"        /* for HANDLE */
+#include "reactos/ddk/zwtypes.h"       /* for FILE_ID_BOTH_DIR_INFORMATION */
+#include <libgnomevfs/gnome-vfs-file-info.h>   /* for GnomeVFSFileInfo */
+
+
+G_BEGIN_DECLS
+
+#define CAPTIVE_DIRECTORY_TYPE_OBJECT            (captive_directory_object_get_type())
+#define CAPTIVE_DIRECTORY_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST((object),CAPTIVE_DIRECTORY_TYPE_OBJECT,CaptiveDirectoryObject))
+#define CAPTIVE_DIRECTORY_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),CAPTIVE_DIRECTORY_TYPE_OBJECT,CaptiveDirectoryObjectClass))
+#define CAPTIVE_DIRECTORY_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object),CAPTIVE_DIRECTORY_TYPE_OBJECT))
+#define CAPTIVE_DIRECTORY_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),CAPTIVE_DIRECTORY_TYPE_OBJECT))
+#define CAPTIVE_DIRECTORY_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),CAPTIVE_DIRECTORY_TYPE_OBJECT,CaptiveDirectoryObjectClass))
+typedef struct _CaptiveDirectoryObject      CaptiveDirectoryObject;
+typedef struct _CaptiveDirectoryObjectClass CaptiveDirectoryObjectClass;
+struct _CaptiveDirectoryObject {
+       GObject parent_instance;
+
+       /*< private >*/
+       HANDLE dir_Handle;
+       gboolean read_first;
+       /* 'QueryDirectory_buf' for NtQueryDirectoryFile() must be persistent
+        * to keep the state if !read_first
+        */
+       char QueryDirectory_buf[sizeof(FILE_ID_BOTH_DIR_INFORMATION)
+                       +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ID_BOTH_DIR_INFORMATION.FileName */ )];
+       };
+struct _CaptiveDirectoryObjectClass {
+       GObjectClass parent_class;
+       };
+
+GType captive_directory_object_get_type(void);
+
+GnomeVFSResult captive_directory_new_open(CaptiveDirectoryObject **captive_directory_object_return,const gchar *pathname);
+GnomeVFSResult captive_directory_read(CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info);
+
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_CLIENT_DIRECTORY_H */
diff --git a/src/libcaptive/include/captive/client-file.h b/src/libcaptive/include/captive/client-file.h
new file mode 100644 (file)
index 0000000..1125439
--- /dev/null
@@ -0,0 +1,65 @@
+/* $Id$
+ * Include file with client-application 'file' access to libcaptive
+ * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _CAPTIVE_CLIENT_FILE_H
+#define _CAPTIVE_CLIENT_FILE_H 1
+
+
+#include <glib/gmacros.h>
+#include <glib-object.h>
+#include "reactos/ntos/types.h"        /* for HANDLE */
+#include "reactos/ddk/zwtypes.h"       /* for FILE_ID_BOTH_DIR_INFORMATION */
+#include <libgnomevfs/gnome-vfs-handle.h>      /* for GnomeVFSOpenMode */
+
+
+G_BEGIN_DECLS
+
+#define CAPTIVE_FILE_TYPE_OBJECT            (captive_file_object_get_type())
+#define CAPTIVE_FILE_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST((object),CAPTIVE_FILE_TYPE_OBJECT,CaptiveFileObject))
+#define CAPTIVE_FILE_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),CAPTIVE_FILE_TYPE_OBJECT,CaptiveFileObjectClass))
+#define CAPTIVE_FILE_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object),CAPTIVE_FILE_TYPE_OBJECT))
+#define CAPTIVE_FILE_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),CAPTIVE_FILE_TYPE_OBJECT))
+#define CAPTIVE_FILE_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),CAPTIVE_FILE_TYPE_OBJECT,CaptiveFileObjectClass))
+typedef struct _CaptiveFileObject      CaptiveFileObject;
+typedef struct _CaptiveFileObjectClass CaptiveFileObjectClass;
+struct _CaptiveFileObject {
+       GObject parent_instance;
+
+       /*< private >*/
+       HANDLE file_Handle;
+       GnomeVFSFileOffset offset;
+       };
+struct _CaptiveFileObjectClass {
+       GObjectClass parent_class;
+       };
+
+GType captive_file_object_get_type(void);
+
+GnomeVFSResult captive_file_new_open
+               (CaptiveFileObject **captive_file_object_return,const gchar *pathname,GnomeVFSOpenMode mode);
+GnomeVFSResult captive_file_read
+               (CaptiveFileObject *captive_file_object,gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return);
+GnomeVFSResult captive_file_seek
+               (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset);
+GnomeVFSResult captive_file_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_CLIENT_FILE_H */
diff --git a/src/libcaptive/include/captive/client-file_info.h b/src/libcaptive/include/captive/client-file_info.h
new file mode 100644 (file)
index 0000000..56a4a71
--- /dev/null
@@ -0,0 +1,36 @@
+/* $Id$
+ * Include file with client-application 'GnomeVFSFileInfo' access to libcaptive
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _CAPTIVE_CLIENT_FILE_INFO_H
+#define _CAPTIVE_CLIENT_FILE_INFO_H 1
+
+
+#include <glib/gmacros.h>
+#include <libgnomevfs/gnome-vfs-result.h>      /* for GnomeVFSResult */
+#include <libgnomevfs/gnome-vfs-file-info.h>   /* for GnomeVFSFileInfo */
+
+
+G_BEGIN_DECLS
+
+GnomeVFSResult captive_file_info_get(const gchar *pathname,GnomeVFSFileInfo *file_info);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_CLIENT_FILE_INFO_H */