summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2008-08-12 23:09:04 +0000
committerTor Lillqvist <tml@src.gnome.org>2008-08-12 23:09:04 +0000
commit7261372b4534336fbe12d4d5f2aef9460d50bde3 (patch)
treed174328f6c5f1e38515f671e64f083dc1197008c /gio
parent70323cf69413664979846e226daf63f86b23f818 (diff)
win32/gwinhttpvfs.c win32/gwinhttpvfs.h win32/gwinhttpfile.c
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. svn path=/trunk/; revision=7344
Diffstat (limited to 'gio')
-rw-r--r--gio/ChangeLog27
-rw-r--r--gio/giomodule.c4
-rw-r--r--gio/win32/Makefile.am11
-rw-r--r--gio/win32/gwinhttpfile.c602
-rw-r--r--gio/win32/gwinhttpfile.h64
-rw-r--r--gio/win32/gwinhttpfileinputstream.c170
-rw-r--r--gio/win32/gwinhttpfileinputstream.h52
-rw-r--r--gio/win32/gwinhttpfileoutputstream.c204
-rw-r--r--gio/win32/gwinhttpfileoutputstream.h51
-rw-r--r--gio/win32/gwinhttpvfs.c274
-rw-r--r--gio/win32/gwinhttpvfs.h88
-rw-r--r--gio/win32/winhttp.h236
12 files changed, 1782 insertions, 1 deletions
diff --git a/gio/ChangeLog b/gio/ChangeLog
index f15561274..1ea03f047 100644
--- a/gio/ChangeLog
+++ b/gio/ChangeLog
@@ -1,3 +1,30 @@
+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
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 46c23fd3f..867b14126 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -294,6 +294,7 @@ extern GType _g_local_vfs_get_type (void);
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)
@@ -364,6 +365,9 @@ _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)
diff --git a/gio/win32/Makefile.am b/gio/win32/Makefile.am
index 0b8b30a5e..19c4a564b 100644
--- a/gio/win32/Makefile.am
+++ b/gio/win32/Makefile.am
@@ -4,9 +4,18 @@ NULL =
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 = \
diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
new file mode 100644
index 000000000..2e24116e4
--- /dev/null
+++ b/gio/win32/gwinhttpfile.c
@@ -0,0 +1,602 @@
+/* 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
+}
diff --git a/gio/win32/gwinhttpfile.h b/gio/win32/gwinhttpfile.h
new file mode 100644
index 000000000..9a0c3929a
--- /dev/null
+++ b/gio/win32/gwinhttpfile.h
@@ -0,0 +1,64 @@
+/* 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__ */
diff --git a/gio/win32/gwinhttpfileinputstream.c b/gio/win32/gwinhttpfileinputstream.c
new file mode 100644
index 000000000..f00bc7828
--- /dev/null
+++ b/gio/win32/gwinhttpfileinputstream.c
@@ -0,0 +1,170 @@
+/* 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;
+}
diff --git a/gio/win32/gwinhttpfileinputstream.h b/gio/win32/gwinhttpfileinputstream.h
new file mode 100644
index 000000000..80e02b475
--- /dev/null
+++ b/gio/win32/gwinhttpfileinputstream.h
@@ -0,0 +1,52 @@
+/* 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__ */
diff --git a/gio/win32/gwinhttpfileoutputstream.c b/gio/win32/gwinhttpfileoutputstream.c
new file mode 100644
index 000000000..19b6e8538
--- /dev/null
+++ b/gio/win32/gwinhttpfileoutputstream.c
@@ -0,0 +1,204 @@
+/* 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;
+}
diff --git a/gio/win32/gwinhttpfileoutputstream.h b/gio/win32/gwinhttpfileoutputstream.h
new file mode 100644
index 000000000..4cc7e6177
--- /dev/null
+++ b/gio/win32/gwinhttpfileoutputstream.h
@@ -0,0 +1,51 @@
+/* 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__ */
diff --git a/gio/win32/gwinhttpvfs.c b/gio/win32/gwinhttpvfs.c
new file mode 100644
index 000000000..dddf12eeb
--- /dev/null
+++ b/gio/win32/gwinhttpvfs.c
@@ -0,0 +1,274 @@
+/* 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);
+}
diff --git a/gio/win32/gwinhttpvfs.h b/gio/win32/gwinhttpvfs.h
new file mode 100644
index 000000000..a7597a477
--- /dev/null
+++ b/gio/win32/gwinhttpvfs.h
@@ -0,0 +1,88 @@
+/* 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__ */
diff --git a/gio/win32/winhttp.h b/gio/win32/winhttp.h
new file mode 100644
index 000000000..1bc7f4836
--- /dev/null
+++ b/gio/win32/winhttp.h
@@ -0,0 +1,236 @@
+/*
+ * 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 */