#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() */
static GnomeVFSMethod GnomeVFSMethod_static;
{
gchar *uri_parent_string;
GnomeVFSResult errvfsresult;
-gchar *w32_path,*s,*d;
+gchar *w32_path,*s,*d,*vfs_path;
g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_INVALID_URI);
* 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",uri->text);
+ captive_printf_alloca("\\Device\\CdRom0\\%s",vfs_path);
+ g_free(vfs_path);
/* translate '/' -> '\' */
for (s=w32_path;(s=strchr(s,'/'));s++)
*s='\\';
0); /* Options */
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(NT_SUCCESS(dir_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
g_return_val_if_fail(dir_IoStatusBlock.Information==FILE_OPENED,GNOME_VFS_ERROR_GENERIC);
captive_new(directory_handle);
/* 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;
}
+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)
{
- g_return_val_if_reached(GNOME_VFS_ERROR_NOT_SUPPORTED); /* FIXME: NOT IMPLEMENTED YET */
+IO_STATUS_BLOCK file_IoStatusBlock;
+GnomeVFSResult errvfsresult;
+OBJECT_ATTRIBUTES file_ObjectAttributes;
+HANDLE file_Handle;
+struct captive_gnomevfs_file_handle *file_handle;
+NTSTATUS err;
+
+ 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);
+ 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 */
+ 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;
+}
+
+
+static GnomeVFSResult captive_gnomevfs_close(GnomeVFSMethod *method,
+ GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context)
+{
+struct captive_gnomevfs_file_handle *file_handle;
+NTSTATUS err;
+
+ 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);
+
+ file_handle=(struct captive_gnomevfs_file_handle *)method_handle;
+ G_LOCK(libcaptive);
+ err=NtClose(file_handle->file_Handle);
+ G_UNLOCK(libcaptive);
+ g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+
+ g_free(file_handle);
+ return GNOME_VFS_OK;
+}
+
+
+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;
+
+ 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(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 */
+ 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;
+}
+
+
+static GnomeVFSResult captive_gnomevfs_seek(GnomeVFSMethod *method,
+ GnomeVFSMethodHandle *method_handle,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset,GnomeVFSContext *context)
+{
+struct captive_gnomevfs_file_handle *file_handle;
+
+ 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);
+
+ 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);
+ }
+
+ return GNOME_VFS_OK;
+}
+
+static GnomeVFSResult captive_gnomevfs_tell(GnomeVFSMethod *method,
+ GnomeVFSMethodHandle *method_handle,GnomeVFSFileOffset *offset_return)
+{
+struct captive_gnomevfs_file_handle *file_handle;
+
+ 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(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_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
- return gnome_vfs_uri_is_local (uri->parent);
+ return gnome_vfs_uri_is_local(uri->parent);
}
/* 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;
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(NT_SUCCESS(file_IoStatusBlock.Status),GNOME_VFS_ERROR_GENERIC);
g_return_val_if_fail(file_IoStatusBlock.Information==FILE_OPENED,GNOME_VFS_ERROR_GENERIC);
/* query */
GnomeVFSMethod_static.close_directory=captive_gnomevfs_close_directory;
GnomeVFSMethod_static.read_directory =captive_gnomevfs_read_directory;
GnomeVFSMethod_static.open =captive_gnomevfs_open; /* mandatory */
+ GnomeVFSMethod_static.close =captive_gnomevfs_close;
+ GnomeVFSMethod_static.read =captive_gnomevfs_read;
+ GnomeVFSMethod_static.seek =captive_gnomevfs_seek;
+ GnomeVFSMethod_static.tell =captive_gnomevfs_tell;
GnomeVFSMethod_static.create =captive_gnomevfs_create; /* mandatory */
GnomeVFSMethod_static.is_local =captive_gnomevfs_is_local; /* mandatory */
GnomeVFSMethod_static.get_file_info =captive_gnomevfs_get_file_info; /* mandatory */