#include <libgnomevfs/gnome-vfs-result.h>
#include <glib/gmessages.h>
#include "captive/macros.h"
-#include "reactos/ddk/rtl.h" /* for InitializeObjectAttributes() */
+#include "reactos/ntos/rtl.h" /* for InitializeObjectAttributes() */
#include "captive/unicode.h"
#include <libgnomevfs/gnome-vfs-utils.h> /* for gnome_vfs_unescape_string() */
-#include <glib/gprintf.h>
-#include "captive/client.h"
+#include "captive/options.h"
+#include <glib/gstrfuncs.h>
+/* Returns: g_malloc() allocated absolute pathname string */
+gchar *captive_path_normalize(const gchar *raw_pathname)
+{
+gchar *r,*r_end,*s,*d;
+
+ g_return_val_if_fail(raw_pathname!=NULL,NULL);
+ g_return_val_if_fail(g_path_is_absolute(raw_pathname),NULL);
+
+ r=g_strdup(raw_pathname);
+
+ /* coalesce '/'es */
+ for (d=s=r;*s;s++) {
+ if (*s==G_DIR_SEPARATOR && d>r && d[-1]==G_DIR_SEPARATOR)
+ continue;
+ *d++=*s;
+ }
+ g_assert(d>r);
+ if (d>(r+1) && d[-1]==G_DIR_SEPARATOR)
+ d--;
+ *d++=G_DIR_SEPARATOR;
+ r_end=d;
+
+ /* 'r' is NOT NULL-terminated here! */
+
+ for (d=s=r+1;s<r_end;) {
+ if (!strncmp(s-1,"/./",3)) {
+ s+=2;
+ continue;
+ }
+ if (!strncmp(s-1,"/../",4)) {
+ s+=3;
+ g_assert(d[-1]==G_DIR_SEPARATOR);
+ if (d>r+1) {
+ do {
+ d--;
+ } while (d[-1]!=G_DIR_SEPARATOR);
+ }
+ continue;
+ }
+ *d++=*s++;
+ }
+ g_assert(d[-1]==G_DIR_SEPARATOR); /* trailing '/' */
+ if (d>r+1) /* leave at least "/" */
+ d--;
+ *d='\0';
+
+ g_assert(g_path_is_absolute(r));
+
+ return r;
+}
+
/* function will leave g_malloc()ed 'ObjectAttributes->ObjectName'!
*/
GnomeVFSResult captive_ObjectAttributes_init(const gchar *pathname,OBJECT_ATTRIBUTES *ObjectAttributes)
{
gchar *w32_path,*s,*d;
const gchar *media_root;
+gchar *pathname_normalized;
g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail(ObjectAttributes!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
* 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. :-)
+ * Tested: \\Device\\CaptiveHarddisk0\\. FAIL
+ * \\Device\\CaptiveHarddisk0\\ OK
*/
- switch (captive_option_media) {
+ switch (captive_options->media) {
case CAPTIVE_OPTION_MEDIA_CDROM: media_root="\\Device\\CdRom0"; break; /* libcaptive/storage/cdrom.c */
case CAPTIVE_OPTION_MEDIA_DISK: media_root="\\Device\\CaptiveHarddisk0"; break; /* libcaptive/storage/disk.c */
default:
media_root="";
}
+ pathname_normalized=captive_path_normalize(pathname);
w32_path=(gchar *)/* de-const it as we can modify it but we must not free() it */
- captive_printf_alloca("%s\\%s",media_root,pathname);
+ captive_printf_alloca("%s\\%s",media_root,pathname_normalized);
+ g_free(pathname_normalized);
/* translate '/' -> '\' */
for (s=w32_path;(s=strchr(s,'/'));s++)
*s='\\';
return GNOME_VFS_OK;
}
+
+
+void captive_giochannel_setup(GIOChannel *giochannel)
+{
+GIOStatus erriostatus;
+
+ g_return_if_fail(giochannel!=NULL);
+
+ if (g_io_channel_get_encoding(giochannel)) {
+ if (!g_io_channel_get_buffered(giochannel)) /* Prevent: Need to have NULL encoding to set the buffering state ... */
+ g_io_channel_set_buffered(giochannel,TRUE); /* Prevent: Need to set the channel buffered before setting the encoding. */
+ erriostatus=g_io_channel_set_encoding(giochannel,
+ NULL, /* encoding; force binary data */
+ NULL); /* error */
+ g_assert(erriostatus==G_IO_STATUS_NORMAL);
+ }
+ erriostatus=g_io_channel_flush(giochannel,
+ NULL); /* error */
+ g_assert(erriostatus==G_IO_STATUS_NORMAL);
+ g_io_channel_set_buffered(giochannel,FALSE);
+}