+2008-08-13 Tor Lillqvist <tml@novell.com>
+
+ * win32/gwinhttpvfs.c
+ * win32/gwinhttpvfs.h
+ * win32/gwinhttpfile.c
+ * win32/gwinhttpfile.h
+ * win32/gwinhttpfileinputstream.c
+ * win32/gwinhttpfileinputstream.h
+ * win32/gwinhttpfileoutputstream.c
+ * win32/gwinhttpfileoutputstream.h: New files implementing
+ GWinHttpVfs and related classes, a GVfs for HTTP and HTTPS URIs on
+ Windows. The implementation uses the WinHttp API. Both reading and
+ writing are supported, i.e. GET and PUT requests. When writing,
+ each write call is done using a separate PUT request with a
+ Content-Range header. Requests for file URIs and plain pathnames
+ are forwarded to GLocalVfs.
+
+ * win32/winhttp.h: Reverse engineered <winhttp.h>, borrowed from
+ WINE. Used as there is no <winhttp.h> bundled with mingw, and
+ requiring people to download the Windows SDK just for this one
+ header is not reasonable.
+
+ * win32/Makefile.am: Add above files.
+
+ * giomodule.c: Call _g_winhttp_vfs_get_type() on Windows to set up
+ the plumbing for the above.
+
2008-08-11 Sven Neumann <sven@gimp.org>
* gfilenamecompleter.c
extern GType _g_win32_volume_monitor_get_type (void);
extern GType g_win32_directory_monitor_get_type (void);
+extern GType _g_winhttp_vfs_get_type (void);
void
_g_io_modules_ensure_loaded (void)
#ifdef G_OS_UNIX
_g_unix_volume_monitor_get_type ();
#endif
+#ifdef G_OS_WIN32
+ _g_winhttp_vfs_get_type ();
+#endif
_g_local_vfs_get_type ();
for (l = modules; l != NULL; l = l->next)
noinst_LTLIBRARIES = libgiowin32.la
-libgiowin32_la_SOURCES = \
+libgiowin32_la_SOURCES = \
gwin32directorymonitor.c \
gwin32directorymonitor.h \
+ gwinhttpvfs.c \
+ gwinhttpvfs.h \
+ gwinhttpfile.c \
+ gwinhttpfile.h \
+ gwinhttpfileinputstream.c \
+ gwinhttpfileinputstream.h \
+ gwinhttpfileoutputstream.c \
+ gwinhttpfileoutputstream.h \
+ winhttp.h \
$(NULL)
libgiowin32_la_CFLAGS = \
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gfile.h"
+#include "gfileattribute.h"
+#include "gwinhttpfile.h"
+#include "gwinhttpfileinputstream.h"
+#include "gwinhttpfileoutputstream.h"
+#include "gioerror.h"
+
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+static void g_winhttp_file_file_iface_init (GFileIface *iface);
+
+#define g_winhttp_file_get_type _g_winhttp_file_get_type
+G_DEFINE_TYPE_WITH_CODE (GWinHttpFile, g_winhttp_file, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
+ g_winhttp_file_file_iface_init))
+
+static void
+g_winhttp_file_finalize (GObject *object)
+{
+ GWinHttpFile *file;
+
+ file = G_WINHTTP_FILE (object);
+
+ g_free (file->url.lpszScheme);
+ g_free (file->url.lpszHostName);
+ g_free (file->url.lpszUserName);
+ g_free (file->url.lpszPassword);
+ g_free (file->url.lpszUrlPath);
+ g_free (file->url.lpszExtraInfo);
+
+ G_OBJECT_CLASS (g_winhttp_file_parent_class)->finalize (object);
+}
+
+static void
+g_winhttp_file_class_init (GWinHttpFileClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = g_winhttp_file_finalize;
+}
+
+static void
+g_winhttp_file_init (GWinHttpFile *winhttp)
+{
+}
+
+/**
+ * _g_winhttp_file_new:
+ * @vfs: GWinHttpVfs to use
+ * @uri: URI of the GWinHttpFile to create.
+ *
+ * Returns: new winhttp #GFile.
+ **/
+GFile *
+_g_winhttp_file_new (GWinHttpVfs *vfs,
+ const char *uri)
+{
+ wchar_t *wuri;
+ GWinHttpFile *file;
+
+ wuri = g_utf8_to_utf16 (uri, -1, NULL, NULL, NULL);
+
+ if (wuri == NULL)
+ return NULL;
+
+ file = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
+ file->vfs = vfs;
+
+ memset (&file->url, 0, sizeof (file->url));
+ file->url.dwStructSize = sizeof (file->url);
+ file->url.dwSchemeLength = 1;
+ file->url.dwHostNameLength = 1;
+ file->url.dwUserNameLength = 1;
+ file->url.dwPasswordLength = 1;
+ file->url.dwUrlPathLength = 1;
+ file->url.dwExtraInfoLength = 1;
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
+ {
+ g_free (wuri);
+ return NULL;
+ }
+
+ file->url.lpszScheme = g_new (wchar_t, ++file->url.dwSchemeLength);
+ file->url.lpszHostName = g_new (wchar_t, ++file->url.dwHostNameLength);
+ file->url.lpszUserName = g_new (wchar_t, ++file->url.dwUserNameLength);
+ file->url.lpszPassword = g_new (wchar_t, ++file->url.dwPasswordLength);
+ file->url.lpszUrlPath = g_new (wchar_t, ++file->url.dwUrlPathLength);
+ file->url.lpszExtraInfo = g_new (wchar_t, ++file->url.dwExtraInfoLength);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
+ {
+ g_free (file->url.lpszScheme);
+ g_free (file->url.lpszHostName);
+ g_free (file->url.lpszUserName);
+ g_free (file->url.lpszPassword);
+ g_free (file->url.lpszUrlPath);
+ g_free (file->url.lpszExtraInfo);
+ g_free (wuri);
+ return NULL;
+ }
+
+ g_free (wuri);
+ return G_FILE (file);
+}
+
+static gboolean
+g_winhttp_file_is_native (GFile *file)
+{
+ return FALSE;
+}
+
+static gboolean
+g_winhttp_file_has_uri_scheme (GFile *file,
+ const char *uri_scheme)
+{
+ return (g_ascii_strcasecmp (uri_scheme, "http") == 0 ||
+ g_ascii_strcasecmp (uri_scheme, "https") == 0);
+}
+
+static char *
+g_winhttp_file_get_uri_scheme (GFile *file)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+
+ return g_utf16_to_utf8 (winhttp_file->url.lpszScheme, -1, NULL, NULL, NULL);
+}
+
+static char *
+g_winhttp_file_get_basename (GFile *file)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ char *basename;
+ char *last_slash;
+ char *retval;
+
+ basename = g_utf16_to_utf8 (winhttp_file->url.lpszUrlPath, -1, NULL, NULL, NULL);
+ last_slash = strrchr (basename, '/');
+ /* If no slash, or only "/" fallback to full path part of URI */
+ if (last_slash == NULL || last_slash[1] == '\0')
+ return basename;
+
+ retval = g_strdup (last_slash + 1);
+ g_free (basename);
+
+ return retval;
+}
+
+static char *
+g_winhttp_file_get_path (GFile *file)
+{
+ return NULL;
+}
+
+static char *
+g_winhttp_file_get_uri (GFile *file)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ DWORD len;
+ wchar_t *wuri;
+ char *retval;
+
+ len = 0;
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, NULL, &len) &&
+ GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ return NULL;
+
+ wuri = g_new (wchar_t, ++len);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, wuri, &len))
+ {
+ g_free (wuri);
+ return NULL;
+ }
+
+ retval = g_utf16_to_utf8 (wuri, -1, NULL, NULL, NULL);
+ g_free (wuri);
+
+ return retval;
+}
+
+static char *
+g_winhttp_file_get_parse_name (GFile *file)
+{
+ /* FIXME: More hair surely needed */
+
+ return g_winhttp_file_get_uri (file);
+}
+
+static GFile *
+g_winhttp_file_get_parent (GFile *file)
+{
+ GWinHttpFile *winhttp_file;
+ char *uri;
+ char *last_slash;
+ GFile *parent;
+
+ winhttp_file = G_WINHTTP_FILE (file);
+
+ uri = g_winhttp_file_get_uri (file);
+ if (uri == NULL)
+ return NULL;
+
+ last_slash = strrchr (uri, '/');
+ if (last_slash == NULL || *(last_slash+1) == 0)
+ {
+ g_free (uri);
+ return NULL;
+ }
+
+ while (last_slash > uri && *last_slash == '/')
+ last_slash--;
+
+ last_slash[1] = '\0';
+
+ parent = _g_winhttp_file_new (winhttp_file->vfs, uri);
+ g_free (uri);
+
+ return parent;
+}
+
+static GFile *
+g_winhttp_file_dup (GFile *file)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ char *uri = g_winhttp_file_get_uri (file);
+ GFile *retval = _g_winhttp_file_new (winhttp_file->vfs, uri);
+
+ g_free (uri);
+
+ return retval;
+}
+
+static guint
+g_winhttp_file_hash (GFile *file)
+{
+ char *uri = g_winhttp_file_get_uri (file);
+ guint retval = g_str_hash (uri);
+
+ g_free (uri);
+
+ return retval;
+}
+
+static gboolean
+g_winhttp_file_equal (GFile *file1,
+ GFile *file2)
+{
+ char *uri1 = g_winhttp_file_get_uri (file1);
+ char *uri2 = g_winhttp_file_get_uri (file2);
+ gboolean retval = g_str_equal (uri1, uri2);
+
+ g_free (uri1);
+ g_free (uri2);
+
+ return retval;
+}
+
+static const char *
+match_prefix (const char *path,
+ const char *prefix)
+{
+ int prefix_len;
+
+ prefix_len = strlen (prefix);
+ if (strncmp (path, prefix, prefix_len) != 0)
+ return NULL;
+
+ if (prefix_len > 0 && prefix[prefix_len-1] == '/')
+ prefix_len--;
+
+ return path + prefix_len;
+}
+
+static gboolean
+g_winhttp_file_prefix_matches (GFile *parent,
+ GFile *descendant)
+{
+ char *parent_uri = g_winhttp_file_get_uri (parent);
+ char *descendant_uri = g_winhttp_file_get_uri (descendant);
+ const char *remainder;
+ gboolean retval;
+
+ remainder = match_prefix (descendant_uri, parent_uri);
+
+ if (remainder != NULL && *remainder == '/')
+ retval = TRUE;
+ else
+ retval = FALSE;
+
+ g_free (parent_uri);
+ g_free (descendant_uri);
+
+ return retval;
+}
+
+static char *
+g_winhttp_file_get_relative_path (GFile *parent,
+ GFile *descendant)
+{
+ char *parent_uri = g_winhttp_file_get_uri (parent);
+ char *descendant_uri = g_winhttp_file_get_uri (descendant);
+ const char *remainder;
+ char *retval;
+
+ remainder = match_prefix (descendant_uri, parent_uri);
+
+ if (remainder != NULL && *remainder == '/')
+ retval = g_strdup (remainder + 1);
+ else
+ retval = NULL;
+
+ g_free (parent_uri);
+ g_free (descendant_uri);
+
+ return retval;
+}
+
+static GFile *
+g_winhttp_file_resolve_relative_path (GFile *file,
+ const char *relative_path)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ GWinHttpFile *child;
+ wchar_t *wnew_path = g_utf8_to_utf16 (relative_path, -1, NULL, NULL, NULL);
+
+ if (wnew_path == NULL)
+ return NULL;
+
+ if (*wnew_path != '/')
+ {
+ wchar_t *tmp = g_new (wchar_t, wcslen (winhttp_file->url.lpszUrlPath) + 1 + wcslen (wnew_path) + 1);
+ wcscpy (tmp, winhttp_file->url.lpszUrlPath);
+ wcscat (tmp, L"/");
+ wcscat (tmp, wnew_path);
+
+ g_free (wnew_path);
+ wnew_path = tmp;
+ }
+
+ child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
+ child->vfs = winhttp_file->vfs;
+ child->url = winhttp_file->url;
+ child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, winhttp_file->url.dwSchemeLength*2);
+ child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, winhttp_file->url.dwHostNameLength*2);
+ child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, winhttp_file->url.dwUserNameLength*2);
+ child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, winhttp_file->url.dwPasswordLength*2);
+ child->url.lpszUrlPath = wnew_path;
+ child->url.dwUrlPathLength = 2*(wcslen (wnew_path)+1);
+ child->url.lpszExtraInfo = NULL;
+ child->url.dwExtraInfoLength = 0;
+
+ return (GFile *) child;
+}
+
+static GFile *
+g_winhttp_file_get_child_for_display_name (GFile *file,
+ const char *display_name,
+ GError **error)
+{
+ GFile *new_file;
+ char *basename;
+
+ basename = g_locale_from_utf8 (display_name, -1, NULL, NULL, NULL);
+ if (basename == NULL)
+ {
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_FILENAME,
+ _("Invalid filename %s"), display_name);
+ return NULL;
+ }
+
+ new_file = g_file_get_child (file, basename);
+ g_free (basename);
+
+ return new_file;
+}
+
+static GFile *
+g_winhttp_file_set_display_name (GFile *file,
+ const char *display_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_set_error_literal (error, G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported"));
+
+ return NULL;
+}
+
+static GFileInputStream *
+g_winhttp_file_read (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ HINTERNET connection, request;
+ const wchar_t *accept_types[] =
+ {
+ L"*/*",
+ NULL,
+ };
+
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ (G_WINHTTP_VFS (winhttp_file->vfs)->session,
+ winhttp_file->url.lpszHostName,
+ winhttp_file->url.nPort,
+ 0);
+
+ if (connection == NULL)
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return NULL;
+ }
+
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpOpenRequest
+ (connection,
+ L"GET",
+ winhttp_file->url.lpszUrlPath,
+ NULL,
+ WINHTTP_NO_REFERER,
+ accept_types,
+ winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
+
+ if (request == NULL)
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return NULL;
+ }
+
+ return _g_winhttp_file_input_stream_new (winhttp_file, connection, request);
+}
+
+static GFileOutputStream *
+g_winhttp_file_create (GFile *file,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ HINTERNET connection, request;
+
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ (G_WINHTTP_VFS (winhttp_file->vfs)->session,
+ winhttp_file->url.lpszHostName,
+ winhttp_file->url.nPort,
+ 0);
+
+ if (connection == NULL)
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return NULL;
+ }
+
+ return _g_winhttp_file_output_stream_new (winhttp_file, connection);
+}
+
+#if 0
+
+static GFileOutputStream *
+g_winhttp_file_replace (GFile *file,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* FIXME: Implement */
+
+ return NULL;
+}
+
+
+static gboolean
+g_winhttp_file_delete (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* FIXME: Implement */
+
+ return FALSE;
+}
+
+static gboolean
+g_winhttp_file_make_directory (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* FIXME: Implement */
+
+ return FALSE;
+}
+
+static gboolean
+g_winhttp_file_copy (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
+{
+ /* Fall back to default copy?? */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Copy not supported");
+
+ return FALSE;
+}
+
+static gboolean
+g_winhttp_file_move (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
+{
+ /* FIXME: Implement */
+
+ return FALSE;
+}
+
+#endif
+
+static void
+g_winhttp_file_file_iface_init (GFileIface *iface)
+{
+ iface->dup = g_winhttp_file_dup;
+ iface->hash = g_winhttp_file_hash;
+ iface->equal = g_winhttp_file_equal;
+ iface->is_native = g_winhttp_file_is_native;
+ iface->has_uri_scheme = g_winhttp_file_has_uri_scheme;
+ iface->get_uri_scheme = g_winhttp_file_get_uri_scheme;
+ iface->get_basename = g_winhttp_file_get_basename;
+ iface->get_path = g_winhttp_file_get_path;
+ iface->get_uri = g_winhttp_file_get_uri;
+ iface->get_parse_name = g_winhttp_file_get_parse_name;
+ iface->get_parent = g_winhttp_file_get_parent;
+ iface->prefix_matches = g_winhttp_file_prefix_matches;
+ iface->get_relative_path = g_winhttp_file_get_relative_path;
+ iface->resolve_relative_path = g_winhttp_file_resolve_relative_path;
+ iface->get_child_for_display_name = g_winhttp_file_get_child_for_display_name;
+ iface->set_display_name = g_winhttp_file_set_display_name;
+ iface->read_fn = g_winhttp_file_read;
+ iface->create = g_winhttp_file_create;
+#if 0
+ iface->replace = g_winhttp_file_replace;
+ iface->delete_file = g_winhttp_file_delete;
+ iface->make_directory = g_winhttp_file_make_directory;
+ iface->copy = g_winhttp_file_copy;
+ iface->move = g_winhttp_file_move;
+#endif
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#ifndef __G_WINHTTP_FILE_H__
+#define __G_WINHTTP_FILE_H__
+
+#include <gio/giotypes.h>
+
+#include "gwinhttpvfs.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WINHTTP_FILE (_g_winhttp_file_get_type ())
+#define G_WINHTTP_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE, GWinHttpFile))
+#define G_WINHTTP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE, GWinHttpFileClass))
+#define G_IS_WINHTTP_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE))
+#define G_IS_WINHTTP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE))
+#define G_WINHTTP_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE, GWinHttpFileClass))
+
+typedef struct _GWinHttpFile GWinHttpFile;
+typedef struct _GWinHttpFileClass GWinHttpFileClass;
+
+struct _GWinHttpFile
+{
+ GObject parent_instance;
+
+ GWinHttpVfs *vfs;
+
+ URL_COMPONENTS url;
+};
+
+struct _GWinHttpFileClass
+{
+ GObjectClass parent_class;
+};
+
+GType _g_winhttp_file_get_type (void) G_GNUC_CONST;
+
+GFile * _g_winhttp_file_new (GWinHttpVfs *vfs, const char *uri);
+
+G_END_DECLS
+
+#endif /* __G_WINHTTP_FILE_H__ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "gcancellable.h"
+#include "gioerror.h"
+#include "gwinhttpfileinputstream.h"
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+struct _GWinHttpFileInputStream
+{
+ GFileInputStream parent_instance;
+
+ GWinHttpFile *file;
+ gboolean request_sent;
+ HINTERNET connection;
+ HINTERNET request;
+};
+
+struct _GWinHttpFileInputStreamClass
+{
+ GFileInputStreamClass parent_class;
+};
+
+#define g_winhttp_file_input_stream_get_type _g_winhttp_file_input_stream_get_type
+G_DEFINE_TYPE (GWinHttpFileInputStream, g_winhttp_file_input_stream, G_TYPE_FILE_INPUT_STREAM);
+
+static gssize g_winhttp_file_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+
+static void
+g_winhttp_file_input_stream_finalize (GObject *object)
+{
+ GWinHttpFileInputStream *winhttp_stream;
+
+ winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (object);
+
+ if (winhttp_stream->request != NULL)
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (winhttp_stream->request);
+ if (winhttp_stream->connection != NULL)
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (winhttp_stream->connection);
+
+ G_OBJECT_CLASS (g_winhttp_file_input_stream_parent_class)->finalize (object);
+}
+
+static void
+g_winhttp_file_input_stream_class_init (GWinHttpFileInputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
+
+ gobject_class->finalize = g_winhttp_file_input_stream_finalize;
+
+ stream_class->read_fn = g_winhttp_file_input_stream_read;
+}
+
+static void
+g_winhttp_file_input_stream_init (GWinHttpFileInputStream *info)
+{
+}
+
+/**
+ * g_winhttp_file_input_stream_new:
+ * @file: the GWinHttpFile being read
+ * @connection: handle to the HTTP connection, as from WinHttpConnect()
+ * @request: handle to the HTTP request, as from WinHttpOpenRequest
+ *
+ * Returns: #GFileInputStream for the given request
+ **/
+GFileInputStream *
+_g_winhttp_file_input_stream_new (GWinHttpFile *file,
+ HINTERNET connection,
+ HINTERNET request)
+{
+ GWinHttpFileInputStream *stream;
+
+ stream = g_object_new (G_TYPE_WINHTTP_FILE_INPUT_STREAM, NULL);
+
+ stream->file = file;
+ stream->request_sent = FALSE;
+ stream->connection = connection;
+ stream->request = request;
+
+ return G_FILE_INPUT_STREAM (stream);
+}
+
+static gssize
+g_winhttp_file_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GWinHttpFileInputStream *winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (stream);
+ DWORD bytes_read;
+
+ if (!winhttp_stream->request_sent)
+ {
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpSendRequest
+ (winhttp_stream->request,
+ NULL, 0,
+ NULL, 0,
+ 0,
+ 0))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return -1;
+ }
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReceiveResponse
+ (winhttp_stream->request, NULL))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return -1;
+ }
+ winhttp_stream->request_sent = TRUE;
+ }
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReadData
+ (winhttp_stream->request, buffer, count, &bytes_read))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return -1;
+ }
+
+ return bytes_read;
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#ifndef __G_WINHTTP_FILE_INPUT_STREAM_H__
+#define __G_WINHTTP_FILE_INPUT_STREAM_H__
+
+#include <gio/gfileinputstream.h>
+
+#include "gwinhttpfile.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WINHTTP_FILE_INPUT_STREAM (_g_winhttp_file_input_stream_get_type ())
+#define G_WINHTTP_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStream))
+#define G_WINHTTP_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStreamClass))
+#define G_IS_WINHTTP_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM))
+#define G_IS_WINHTTP_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE_INPUT_STREAM))
+#define G_WINHTTP_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStreamClass))
+
+typedef struct _GWinHttpFileInputStream GWinHttpFileInputStream;
+typedef struct _GWinHttpFileInputStreamClass GWinHttpFileInputStreamClass;
+
+GType _g_winhttp_file_input_stream_get_type (void) G_GNUC_CONST;
+
+GFileInputStream *_g_winhttp_file_input_stream_new (GWinHttpFile *file,
+ HINTERNET connection,
+ HINTERNET request);
+
+G_END_DECLS
+
+#endif /* __G_WINHTTP_FILE_INPUT_STREAM_H__ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "gcancellable.h"
+#include "gioerror.h"
+#include "gwinhttpfileoutputstream.h"
+#include "glibintl.h"
+
+#include "gioalias.h"
+
+struct _GWinHttpFileOutputStream
+{
+ GFileOutputStream parent_instance;
+
+ GWinHttpFile *file;
+ HINTERNET connection;
+ goffset offset;
+};
+
+struct _GWinHttpFileOutputStreamClass
+{
+ GFileOutputStreamClass parent_class;
+};
+
+#define g_winhttp_file_output_stream_get_type _g_winhttp_file_output_stream_get_type
+G_DEFINE_TYPE (GWinHttpFileOutputStream, g_winhttp_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM);
+
+static gssize g_winhttp_file_output_stream_write (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+
+static void
+g_winhttp_file_output_stream_finalize (GObject *object)
+{
+ GWinHttpFileOutputStream *winhttp_stream;
+
+ winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (object);
+
+ if (winhttp_stream->connection != NULL)
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (winhttp_stream->connection);
+
+ G_OBJECT_CLASS (g_winhttp_file_output_stream_parent_class)->finalize (object);
+}
+
+static void
+g_winhttp_file_output_stream_class_init (GWinHttpFileOutputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
+
+ gobject_class->finalize = g_winhttp_file_output_stream_finalize;
+
+ stream_class->write_fn = g_winhttp_file_output_stream_write;
+}
+
+static void
+g_winhttp_file_output_stream_init (GWinHttpFileOutputStream *info)
+{
+}
+
+/**
+ * g_winhttp_file_output_stream_new:
+ * @file: the GWinHttpFile being read
+ * @connection: handle to the HTTP connection, as from WinHttpConnect()
+ * @request: handle to the HTTP request, as from WinHttpOpenRequest
+ *
+ * Returns: #GFileOutputStream for the given request
+ **/
+GFileOutputStream *
+_g_winhttp_file_output_stream_new (GWinHttpFile *file,
+ HINTERNET connection)
+{
+ GWinHttpFileOutputStream *stream;
+
+ stream = g_object_new (G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, NULL);
+
+ stream->file = file;
+ stream->connection = connection;
+ stream->offset = 0;
+
+ return G_FILE_OUTPUT_STREAM (stream);
+}
+
+static gssize
+g_winhttp_file_output_stream_write (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GWinHttpFileOutputStream *winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (stream);
+ HINTERNET request;
+ char *headers;
+ wchar_t *wheaders;
+ DWORD bytes_written;
+
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpOpenRequest
+ (winhttp_stream->connection,
+ L"PUT",
+ winhttp_stream->file->url.lpszUrlPath,
+ NULL,
+ WINHTTP_NO_REFERER,
+ NULL,
+ winhttp_stream->file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
+
+ if (request == NULL)
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ return -1;
+ }
+
+ headers = g_strdup_printf ("Content-Range: bytes %" G_GINT64_FORMAT "-%" G_GINT64_FORMAT "/*\r\n"
+ "Content-Length: %" G_GSIZE_FORMAT "\r\n",
+ winhttp_stream->offset, winhttp_stream->offset + count, count);
+ wheaders = g_utf8_to_utf16 (headers, -1, NULL, NULL, NULL);
+ g_free (headers);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpSendRequest
+ (request,
+ wheaders, -1,
+ NULL, 0,
+ 0,
+ 0))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "%s", emsg);
+ g_free (emsg);
+
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ g_free (wheaders);
+
+ return -1;
+ }
+
+ winhttp_stream->offset += count;
+ g_free (wheaders);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpWriteData
+ (request, buffer, count, &bytes_written))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s",
+ emsg);
+ g_free (emsg);
+
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+
+ return -1;
+ }
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReceiveResponse
+ (request, NULL))
+ {
+ char *emsg = _g_winhttp_error_message (GetLastError ());
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s",
+ emsg);
+ g_free (emsg);
+
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ return -1;
+ }
+
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+
+ return bytes_written;
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#ifndef __G_WINHTTP_FILE_OUTPUT_STREAM_H__
+#define __G_WINHTTP_FILE_OUTPUT_STREAM_H__
+
+#include <gio/gfileoutputstream.h>
+
+#include "gwinhttpfile.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WINHTTP_FILE_OUTPUT_STREAM (_g_winhttp_file_output_stream_get_type ())
+#define G_WINHTTP_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStream))
+#define G_WINHTTP_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStreamClass))
+#define G_IS_WINHTTP_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM))
+#define G_IS_WINHTTP_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM))
+#define G_WINHTTP_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStreamClass))
+
+typedef struct _GWinHttpFileOutputStream GWinHttpFileOutputStream;
+typedef struct _GWinHttpFileOutputStreamClass GWinHttpFileOutputStreamClass;
+
+GType _g_winhttp_file_output_stream_get_type (void) G_GNUC_CONST;
+
+GFileOutputStream *_g_winhttp_file_output_stream_new (GWinHttpFile *file,
+ HINTERNET connection);
+
+G_END_DECLS
+
+#endif /* __G_WINHTTP_FILE_OUTPUT_STREAM_H__ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#include "config.h"
+
+#include "giomodule.h"
+#include "gvfs.h"
+
+#include "gwinhttpfile.h"
+#include "gwinhttpvfs.h"
+
+#include "gioalias.h"
+
+#define g_winhttp_vfs_get_type _g_winhttp_vfs_get_type
+G_DEFINE_TYPE_WITH_CODE (GWinHttpVfs, g_winhttp_vfs, G_TYPE_VFS,
+ g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "winhttp",
+ 10))
+
+static const gchar *winhttp_uri_schemes[] = { "http", "https" };
+
+static void
+g_winhttp_vfs_finalize (GObject *object)
+{
+ GWinHttpVfs *vfs;
+
+ vfs = G_WINHTTP_VFS (object);
+
+ (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCloseHandle) (vfs->session);
+ vfs->session = NULL;
+
+ if (vfs->wrapped_vfs)
+ g_object_unref (vfs->wrapped_vfs);
+ vfs->wrapped_vfs = NULL;
+
+ G_OBJECT_CLASS (g_winhttp_vfs_parent_class)->finalize (object);
+}
+
+static void
+g_winhttp_vfs_init (GWinHttpVfs *vfs)
+{
+ wchar_t *wagent;
+
+ vfs->wrapped_vfs = g_vfs_get_local ();
+
+ wagent = g_utf8_to_utf16 (g_get_prgname (), -1, NULL, NULL, NULL);
+
+ if (!wagent)
+ wagent = g_utf8_to_utf16 ("GWinHttpVfs", -1, NULL, NULL, NULL);
+
+ vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpOpen)
+ (wagent,
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ WINHTTP_NO_PROXY_NAME,
+ WINHTTP_NO_PROXY_BYPASS,
+ 0);
+}
+
+/**
+ * g_winhttp_vfs_new:
+ *
+ * Returns a new #GVfs handle for a WinHttp vfs.
+ *
+ * Returns: a new #GVfs handle.
+ **/
+GVfs *
+_g_winhttp_vfs_new (void)
+{
+ return g_object_new (G_TYPE_WINHTTP_VFS, NULL);
+}
+
+static GFile *
+g_winhttp_vfs_get_file_for_path (GVfs *vfs,
+ const char *path)
+{
+ return g_vfs_get_file_for_path (G_WINHTTP_VFS (vfs)->wrapped_vfs, path);
+}
+
+static GFile *
+g_winhttp_vfs_get_file_for_uri (GVfs *vfs,
+ const char *uri)
+{
+ GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
+ int i;
+
+ /* If it matches one of "our" schemes, handle it */
+ for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++)
+ if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 &&
+ uri[strlen (winhttp_uri_schemes[i])] == ':')
+ return _g_winhttp_file_new (winhttp_vfs, uri);
+
+ /* For other URIs fallback to the wrapped GVfs */
+ return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, uri);
+}
+
+static const gchar * const *
+g_winhttp_vfs_get_supported_uri_schemes (GVfs *vfs)
+{
+ GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
+ const gchar * const *wrapped_vfs_uri_schemes = g_vfs_get_supported_uri_schemes (winhttp_vfs->wrapped_vfs);
+ int i, n;
+ const gchar **retval;
+
+ n = 0;
+ while (wrapped_vfs_uri_schemes[n] != NULL)
+ n++;
+
+ retval = g_new (const gchar *, n + G_N_ELEMENTS (winhttp_uri_schemes) + 1);
+ n = 0;
+ while (wrapped_vfs_uri_schemes[n] != NULL)
+ {
+ retval[n] = wrapped_vfs_uri_schemes[n];
+ n++;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++)
+ {
+ retval[n] = winhttp_uri_schemes[i];
+ n++;
+ }
+
+ retval[n] = NULL;
+
+ return retval;
+}
+
+static GFile *
+g_winhttp_vfs_parse_name (GVfs *vfs,
+ const char *parse_name)
+{
+ GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
+
+ g_return_val_if_fail (G_IS_VFS (vfs), NULL);
+ g_return_val_if_fail (parse_name != NULL, NULL);
+
+ /* For plain file paths fallback to the wrapped GVfs */
+ if (g_path_is_absolute (parse_name))
+ return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, parse_name);
+
+ /* Otherwise assume it is an URI, so pass on to
+ * g_winhttp_vfs_get_file_for_uri().
+ */
+ return g_winhttp_vfs_get_file_for_uri (vfs, parse_name);
+}
+
+static gboolean
+g_winhttp_vfs_is_active (GVfs *vfs)
+{
+ return TRUE;
+}
+
+static void
+g_winhttp_vfs_class_init (GWinHttpVfsClass *class)
+{
+ GObjectClass *object_class;
+ GVfsClass *vfs_class;
+ HMODULE winhttp;
+
+ object_class = (GObjectClass *) class;
+
+ object_class->finalize = g_winhttp_vfs_finalize;
+
+ vfs_class = G_VFS_CLASS (class);
+
+ vfs_class->is_active = g_winhttp_vfs_is_active;
+ vfs_class->get_file_for_path = g_winhttp_vfs_get_file_for_path;
+ vfs_class->get_file_for_uri = g_winhttp_vfs_get_file_for_uri;
+ vfs_class->get_supported_uri_schemes = g_winhttp_vfs_get_supported_uri_schemes;
+ vfs_class->parse_name = g_winhttp_vfs_parse_name;
+
+ winhttp = LoadLibrary ("winhttp.dll");
+ if (winhttp != NULL)
+ {
+ class->pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle");
+ class->pWinHttpCrackUrl = (BOOL (WINAPI *) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS)) GetProcAddress (winhttp, "WinHttpCrackUrl");
+ class->pWinHttpConnect = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD)) GetProcAddress (winhttp, "WinHttpConnect");
+ class->pWinHttpCreateUrl = (BOOL (WINAPI *) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD)) GetProcAddress (winhttp, "WinHttpCreateUrl");
+ class->pWinHttpOpen = (HINTERNET (WINAPI *) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD)) GetProcAddress (winhttp, "WinHttpOpen");
+ class->pWinHttpOpenRequest = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD)) GetProcAddress (winhttp, "WinHttpOpenRequest");
+ class->pWinHttpQueryDataAvailable = (BOOL (WINAPI *) (HINTERNET,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryDataAvailable");
+ class->pWinHttpQueryHeaders = (BOOL (WINAPI *) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryHeaders");
+ class->pWinHttpReadData = (BOOL (WINAPI *) (HINTERNET,LPVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpReadData");
+ class->pWinHttpReceiveResponse = (BOOL (WINAPI *) (HINTERNET,LPVOID)) GetProcAddress (winhttp, "WinHttpReceiveResponse");
+ class->pWinHttpSendRequest = (BOOL (WINAPI *) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR)) GetProcAddress (winhttp, "WinHttpSendRequest");
+ class->pWinHttpWriteData = (BOOL (WINAPI *) (HINTERNET,LPCVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpWriteData");
+ }
+}
+
+char *
+_g_winhttp_error_message (DWORD error_code)
+{
+ /* The FormatMessage() API that g_win32_error_message() uses doesn't
+ * seem to know about WinHttp errors, unfortunately.
+ */
+ if (error_code >= WINHTTP_ERROR_BASE && error_code < WINHTTP_ERROR_BASE + 200)
+ {
+ switch (error_code)
+ {
+ /* FIXME: Use meaningful error messages */
+#define CASE(x) case ERROR_WINHTTP_##x: return g_strdup ("WinHttp error: " #x);
+ CASE (AUTO_PROXY_SERVICE_ERROR);
+ CASE (AUTODETECTION_FAILED);
+ CASE (BAD_AUTO_PROXY_SCRIPT);
+ CASE (CANNOT_CALL_AFTER_OPEN);
+ CASE (CANNOT_CALL_AFTER_SEND);
+ CASE (CANNOT_CALL_BEFORE_OPEN);
+ CASE (CANNOT_CALL_BEFORE_SEND);
+ CASE (CANNOT_CONNECT);
+ CASE (CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW);
+ CASE (CLIENT_AUTH_CERT_NEEDED);
+ CASE (CONNECTION_ERROR);
+ CASE (HEADER_ALREADY_EXISTS);
+ CASE (HEADER_COUNT_EXCEEDED);
+ CASE (HEADER_NOT_FOUND);
+ CASE (HEADER_SIZE_OVERFLOW);
+ CASE (INCORRECT_HANDLE_STATE);
+ CASE (INCORRECT_HANDLE_TYPE);
+ CASE (INTERNAL_ERROR);
+ CASE (INVALID_OPTION);
+ CASE (INVALID_QUERY_REQUEST);
+ CASE (INVALID_SERVER_RESPONSE);
+ CASE (INVALID_URL);
+ CASE (LOGIN_FAILURE);
+ CASE (NAME_NOT_RESOLVED);
+ CASE (NOT_INITIALIZED);
+ CASE (OPERATION_CANCELLED);
+ CASE (OPTION_NOT_SETTABLE);
+ CASE (OUT_OF_HANDLES);
+ CASE (REDIRECT_FAILED);
+ CASE (RESEND_REQUEST);
+ CASE (RESPONSE_DRAIN_OVERFLOW);
+ CASE (SECURE_CERT_CN_INVALID);
+ CASE (SECURE_CERT_DATE_INVALID);
+ CASE (SECURE_CERT_REV_FAILED);
+ CASE (SECURE_CERT_REVOKED);
+ CASE (SECURE_CERT_WRONG_USAGE);
+ CASE (SECURE_CHANNEL_ERROR);
+ CASE (SECURE_FAILURE);
+ CASE (SECURE_INVALID_CA);
+ CASE (SECURE_INVALID_CERT);
+ CASE (SHUTDOWN);
+ CASE (TIMEOUT);
+ CASE (UNABLE_TO_DOWNLOAD_SCRIPT);
+ CASE (UNRECOGNIZED_SCHEME);
+ #undef CASE
+ default:
+ return g_strdup_printf ("WinHttp error %ld", error_code);
+ }
+ }
+ else
+ return g_win32_error_message (error_code);
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ * Author: Tor Lillqvist <tml@novell.com>
+ */
+
+#ifndef __G_WINHTTP_VFS_H__
+#define __G_WINHTTP_VFS_H__
+
+#include <gio/giotypes.h>
+
+#include "gvfs.h"
+
+#define _WIN32_WINNT 0x0500
+#include <windows.h>
+
+#include "winhttp.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_WINHTTP_VFS (_g_winhttp_vfs_get_type ())
+#define G_WINHTTP_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WINHTTP_VFS, GWinHttpVfs))
+#define G_WINHTTP_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_WINHTTP_VFS, GWinHttpVfsClass))
+#define G_IS_WINHTTP_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_WINHTTP_VFS))
+#define G_IS_WINHTTP_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_WINHTTP_VFS))
+#define G_WINHTTP_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_WINHTTP_VFS, GWinHttpVfsClass))
+
+typedef struct _GWinHttpVfs GWinHttpVfs;
+typedef struct _GWinHttpVfsClass GWinHttpVfsClass;
+
+struct _GWinHttpVfs
+{
+ GVfs parent;
+
+ GVfs *wrapped_vfs;
+ HINTERNET session;
+};
+
+struct _GWinHttpVfsClass
+{
+ GVfsClass parent_class;
+
+ /* As there is no import library for winhttp.dll in mingw, we must
+ * look up the functions we need dynamically. Store the pointers
+ * here.
+ */
+ BOOL (WINAPI *pWinHttpCloseHandle) (HINTERNET);
+ BOOL (WINAPI *pWinHttpCrackUrl) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
+ HINTERNET (WINAPI *pWinHttpConnect) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
+ BOOL (WINAPI *pWinHttpCreateUrl) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
+ HINTERNET (WINAPI *pWinHttpOpen) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
+ HINTERNET (WINAPI *pWinHttpOpenRequest) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
+ BOOL (WINAPI *pWinHttpQueryDataAvailable) (HINTERNET,LPDWORD);
+ BOOL (WINAPI *pWinHttpQueryHeaders) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
+ BOOL (WINAPI *pWinHttpReadData) (HINTERNET,LPVOID,DWORD,LPDWORD);
+ BOOL (WINAPI *pWinHttpReceiveResponse) (HINTERNET,LPVOID);
+ BOOL (WINAPI *pWinHttpSendRequest) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
+ BOOL (WINAPI *pWinHttpWriteData) (HINTERNET,LPCVOID,DWORD,LPDWORD);
+};
+
+
+GType _g_winhttp_vfs_get_type (void) G_GNUC_CONST;
+
+GVfs *_g_winhttp_vfs_new (void);
+
+char *_g_winhttp_error_message (DWORD error_code);
+
+G_END_DECLS
+
+#endif /* __G_WINHTTP_VFS_H__ */
--- /dev/null
+/*
+ * Copyright (C) 2007 Francois Gouget
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_WINHTTP_H
+#define __WINE_WINHTTP_H
+
+#define WINHTTPAPI
+#define BOOLAPI WINHTTPAPI BOOL WINAPI
+
+
+typedef LPVOID HINTERNET;
+typedef HINTERNET *LPHINTERNET;
+
+#define INTERNET_DEFAULT_PORT 0
+#define INTERNET_DEFAULT_HTTP_PORT 80
+#define INTERNET_DEFAULT_HTTPS_PORT 443
+typedef WORD INTERNET_PORT;
+typedef INTERNET_PORT *LPINTERNET_PORT;
+
+#define INTERNET_SCHEME_HTTP 1
+#define INTERNET_SCHEME_HTTPS 2
+typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME;
+
+/* flags for WinHttpOpen */
+#define WINHTTP_FLAG_ASYNC 0x10000000
+
+/* flags for WinHttpOpenRequest */
+#define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004
+#define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008
+#define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040
+#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080
+#define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100
+#define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE
+#define WINHTTP_FLAG_SECURE 0x00800000
+
+#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0
+#define WINHTTP_ACCESS_TYPE_NO_PROXY 1
+#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3
+
+#define WINHTTP_NO_PROXY_NAME NULL
+#define WINHTTP_NO_PROXY_BYPASS NULL
+
+#define WINHTTP_NO_REFERER NULL
+#define WINHTTP_DEFAULT_ACCEPT_TYPES NULL
+
+#define WINHTTP_ERROR_BASE 12000
+
+/* The original WINE winhttp.h didn't contain symbolic names for the
+ * error codes. However, the values of most of them are publicly
+ * documented at
+ * http://msdn.microsoft.com/en-us/library/aa383770(VS.85).aspx so
+ * we can add them here.
+ */
+#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR 12178
+#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT 12166
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN 12103
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND 12102
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN 12100
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND 12101
+#define ERROR_WINHTTP_CANNOT_CONNECT 12029
+#define ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW 12183
+#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED 12044
+#define ERROR_WINHTTP_CONNECTION_ERROR 12030
+#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS 12155
+#define ERROR_WINHTTP_HEADER_COUNT_EXCEEDED 12181
+#define ERROR_WINHTTP_HEADER_NOT_FOUND 12150
+#define ERROR_WINHTTP_HEADER_SIZE_OVERFLOW 12182
+#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE 12019
+#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE 12018
+#define ERROR_WINHTTP_INTERNAL_ERROR 12004
+#define ERROR_WINHTTP_INVALID_OPTION 12009
+#define ERROR_WINHTTP_INVALID_QUERY_REQUEST 12154
+#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE 12152
+#define ERROR_WINHTTP_INVALID_URL 12005
+#define ERROR_WINHTTP_LOGIN_FAILURE 12015
+#define ERROR_WINHTTP_NAME_NOT_RESOLVED 12007
+#define ERROR_WINHTTP_NOT_INITIALIZED 12172
+#define ERROR_WINHTTP_OPERATION_CANCELLED 12017
+#define ERROR_WINHTTP_OPTION_NOT_SETTABLE 12011
+#define ERROR_WINHTTP_OUT_OF_HANDLES 12001
+#define ERROR_WINHTTP_REDIRECT_FAILED 12156
+#define ERROR_WINHTTP_RESEND_REQUEST 12032
+#define ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW 12184
+#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID 12038
+#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID 12037
+#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED 12057
+#define ERROR_WINHTTP_SECURE_CERT_REVOKED 12170
+#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE 12179
+#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR 12157
+#define ERROR_WINHTTP_SECURE_FAILURE 12175
+#define ERROR_WINHTTP_SECURE_INVALID_CA 12045
+#define ERROR_WINHTTP_SECURE_INVALID_CERT 12169
+#define ERROR_WINHTTP_SHUTDOWN 12012
+#define ERROR_WINHTTP_TIMEOUT 12002
+#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT 12167
+#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME 12006
+/* End of added error codes */
+
+#define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180)
+
+typedef struct
+{
+ DWORD dwStructSize;
+ LPWSTR lpszScheme;
+ DWORD dwSchemeLength;
+ INTERNET_SCHEME nScheme;
+ LPWSTR lpszHostName;
+ DWORD dwHostNameLength;
+ INTERNET_PORT nPort;
+ LPWSTR lpszUserName;
+ DWORD dwUserNameLength;
+ LPWSTR lpszPassword;
+ DWORD dwPasswordLength;
+ LPWSTR lpszUrlPath;
+ DWORD dwUrlPathLength;
+ LPWSTR lpszExtraInfo;
+ DWORD dwExtraInfoLength;
+} URL_COMPONENTS, *LPURL_COMPONENTS;
+typedef URL_COMPONENTS URL_COMPONENTSW;
+typedef LPURL_COMPONENTS LPURL_COMPONENTSW;
+
+typedef struct
+{
+ DWORD_PTR dwResult;
+ DWORD dwError;
+} WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT;
+
+typedef struct
+{
+ FILETIME ftExpiry;
+ FILETIME ftStart;
+ LPWSTR lpszSubjectInfo;
+ LPWSTR lpszIssuerInfo;
+ LPWSTR lpszProtocolName;
+ LPWSTR lpszSignatureAlgName;
+ LPWSTR lpszEncryptionAlgName;
+ DWORD dwKeySize;
+} WINHTTP_CERTIFICATE_INFO;
+
+typedef struct
+{
+ DWORD dwAccessType;
+ LPCWSTR lpszProxy;
+ LPCWSTR lpszProxyBypass;
+} WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO;
+typedef WINHTTP_PROXY_INFO WINHTTP_PROXY_INFOW;
+typedef LPWINHTTP_PROXY_INFO LPWINHTTP_PROXY_INFOW;
+
+typedef struct
+{
+ BOOL fAutoDetect;
+ LPWSTR lpszAutoConfigUrl;
+ LPWSTR lpszProxy;
+ LPWSTR lpszProxyBypass;
+} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
+
+typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD_PTR,DWORD,LPVOID,DWORD);
+
+typedef struct
+{
+ DWORD dwFlags;
+ DWORD dwAutoDetectFlags;
+ LPCWSTR lpszAutoConfigUrl;
+ LPVOID lpvReserved;
+ DWORD dwReserved;
+ BOOL fAutoLogonIfChallenged;
+} WINHTTP_AUTOPROXY_OPTIONS;
+
+typedef struct
+{
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+} HTTP_VERSION_INFO, *LPHTTP_VERSION_INFO;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET,LPCWSTR,DWORD,DWORD);
+BOOL WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD,LPWSTR*);
+BOOL WINAPI WinHttpCheckPlatform(void);
+BOOL WINAPI WinHttpCloseHandle(HINTERNET);
+HINTERNET WINAPI WinHttpConnect(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
+BOOL WINAPI WinHttpCrackUrl(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
+BOOL WINAPI WinHttpCreateUrl(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
+BOOL WINAPI WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config);
+BOOL WINAPI WinHttpGetProxyForUrl(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*);
+HINTERNET WINAPI WinHttpOpen(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
+
+/* The sixth parameter to WinHttpOpenRequest was wrong in the original
+ * WINE header. It should be LPCWSTR*, not LPCWSTR, as it points to an
+ * array of wide strings.
+ */
+HINTERNET WINAPI WinHttpOpenRequest(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
+BOOL WINAPI WinHttpQueryAuthParams(HINTERNET,DWORD,LPVOID*);
+BOOL WINAPI WinHttpQueryAuthSchemes(HINTERNET,LPDWORD,LPDWORD,LPDWORD);
+BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET,LPDWORD);
+BOOL WINAPI WinHttpQueryHeaders(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
+BOOL WINAPI WinHttpReadData(HINTERNET,LPVOID,DWORD,LPDWORD);
+BOOL WINAPI WinHttpReceiveResponse(HINTERNET,LPVOID);
+BOOL WINAPI WinHttpSendRequest(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
+BOOL WINAPI WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL WINAPI WinHttpSetCredentials(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID);
+BOOL WINAPI WinHttpSetOption(HINTERNET,DWORD,LPVOID,DWORD);
+WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR);
+BOOL WINAPI WinHttpSetTimeouts(HINTERNET,int,int,int,int);
+BOOL WINAPI WinHttpTimeFromSystemTime(CONST SYSTEMTIME *,LPWSTR);
+BOOL WINAPI WinHttpTimeToSystemTime(LPCWSTR,SYSTEMTIME*);
+BOOL WINAPI WinHttpWriteData(HINTERNET,LPCVOID,DWORD,LPDWORD);
+
+/* Additional definitions, from the public domain <wininet.h> in mingw */
+#define ICU_ESCAPE 0x80000000
+#define ICU_DECODE 0x10000000
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINHTTP_H */