+2008-11-12 Tor Lillqvist <tml@novell.com>
+
+ Bug 556415 - Crash on Windows 2000 in g_winhttp_vfs_init()
+
+ * win32/gwinhttpvfs.h: Move the set of function pointers to
+ winhttp.dll into a separate struct GWinHttpDllFuncs. Just have a
+ pointer to that in the GWinHttpVfsClass.
+
+ * win32/gwinhttpvfs.c: Move the lookup of functions from
+ winhttp.dll into a function of its own, that stores the pointers
+ in a separate GWinHttpDllFuncs variable. Add two bookeeping
+ booleans lookup_done and funcs_found.
+
+ Don't call g_io_extension_point_implement() to register the
+ winhttp extension unless winhttp.dll has been successfully loaded
+ and the required functions found in it.
+
+ * win32/gwinhttp*.c: Adjust calls of the functions looked up from
+ winhttp.dll correspondingly.
+
2008-10-28 Cosimo Cecchi <cosimoc@gnome.org>
reviewed by: Alexander Larsson <alexl@redhat.com>
file->url.dwUrlPathLength = 1;
file->url.dwExtraInfoLength = 1;
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
{
g_free (wuri);
return NULL;
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))
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url))
{
g_free (file->url.lpszScheme);
g_free (file->url.lpszHostName);
char *retval;
len = 0;
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, NULL, &len) &&
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->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))
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, wuri, &len))
{
g_free (wuri);
return NULL;
SYSTEMTIME last_modified;
DWORD last_modified_len;
- connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
(G_WINHTTP_VFS (winhttp_file->vfs)->session,
winhttp_file->url.lpszHostName,
winhttp_file->url.nPort,
return NULL;
}
- request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpOpenRequest
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest
(connection,
L"HEAD",
winhttp_file->url.lpszUrlPath,
return NULL;
}
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpSendRequest
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpSendRequest
(request,
NULL, 0,
NULL, 0,
}
last_modified_len = sizeof (last_modified);
- if (G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpQueryHeaders
+ if (G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpQueryHeaders
(request,
WINHTTP_QUERY_LAST_MODIFIED | WINHTTP_QUERY_FLAG_SYSTEMTIME,
NULL,
NULL,
};
- connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
(G_WINHTTP_VFS (winhttp_file->vfs)->session,
winhttp_file->url.lpszHostName,
winhttp_file->url.nPort,
return NULL;
}
- request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpOpenRequest
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest
(connection,
L"GET",
winhttp_file->url.lpszUrlPath,
GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
HINTERNET connection;
- connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect
(G_WINHTTP_VFS (winhttp_file->vfs)->session,
winhttp_file->url.lpszHostName,
winhttp_file->url.nPort,
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);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->request);
if (winhttp_stream->connection != NULL)
- G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (winhttp_stream->connection);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection);
G_OBJECT_CLASS (g_winhttp_file_input_stream_parent_class)->finalize (object);
}
if (!winhttp_stream->request_sent)
{
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpSendRequest
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpSendRequest
(winhttp_stream->request,
NULL, 0,
NULL, 0,
winhttp_stream->request_sent = TRUE;
}
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReadData
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpReadData
(winhttp_stream->request, buffer, count, &bytes_read))
{
_g_winhttp_set_error (error, GetLastError (), "GET request");
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_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection);
G_OBJECT_CLASS (g_winhttp_file_output_stream_parent_class)->finalize (object);
}
wchar_t *wheaders;
DWORD bytes_written;
- request = G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpOpenRequest
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpOpenRequest
(winhttp_stream->connection,
L"PUT",
winhttp_stream->file->url.lpszUrlPath,
wheaders = g_utf8_to_utf16 (headers, -1, NULL, NULL, NULL);
g_free (headers);
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpSendRequest
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpSendRequest
(request,
wheaders, -1,
NULL, 0,
{
_g_winhttp_set_error (error, GetLastError (), "PUT request");
- G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
g_free (wheaders);
return -1;
g_free (wheaders);
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpWriteData
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpWriteData
(request, buffer, count, &bytes_written))
{
_g_winhttp_set_error (error, GetLastError (), "PUT request");
- G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
return -1;
}
error,
"PUT request"))
{
- G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
return -1;
}
- G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+ G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
return bytes_written;
}
#include "gioalias.h"
+static gboolean lookup_done = FALSE;
+static gboolean funcs_found = FALSE;
+static GWinHttpDllFuncs funcs;
+
+static void
+lookup_funcs (void)
+{
+ HMODULE winhttp;
+
+ if (lookup_done)
+ return;
+
+ winhttp = LoadLibrary ("winhttp.dll");
+ if (winhttp != NULL)
+ {
+ funcs.pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle");
+ funcs.pWinHttpCrackUrl = (BOOL (WINAPI *) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS)) GetProcAddress (winhttp, "WinHttpCrackUrl");
+ funcs.pWinHttpConnect = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD)) GetProcAddress (winhttp, "WinHttpConnect");
+ funcs.pWinHttpCreateUrl = (BOOL (WINAPI *) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD)) GetProcAddress (winhttp, "WinHttpCreateUrl");
+ funcs.pWinHttpOpen = (HINTERNET (WINAPI *) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD)) GetProcAddress (winhttp, "WinHttpOpen");
+ funcs.pWinHttpOpenRequest = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD)) GetProcAddress (winhttp, "WinHttpOpenRequest");
+ funcs.pWinHttpQueryDataAvailable = (BOOL (WINAPI *) (HINTERNET,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryDataAvailable");
+ funcs.pWinHttpQueryHeaders = (BOOL (WINAPI *) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryHeaders");
+ funcs.pWinHttpReadData = (BOOL (WINAPI *) (HINTERNET,LPVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpReadData");
+ funcs.pWinHttpReceiveResponse = (BOOL (WINAPI *) (HINTERNET,LPVOID)) GetProcAddress (winhttp, "WinHttpReceiveResponse");
+ funcs.pWinHttpSendRequest = (BOOL (WINAPI *) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR)) GetProcAddress (winhttp, "WinHttpSendRequest");
+ funcs.pWinHttpWriteData = (BOOL (WINAPI *) (HINTERNET,LPCVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpWriteData");
+
+ if (funcs.pWinHttpCloseHandle &&
+ funcs.pWinHttpCrackUrl &&
+ funcs.pWinHttpConnect &&
+ funcs.pWinHttpCreateUrl &&
+ funcs.pWinHttpOpen &&
+ funcs.pWinHttpOpenRequest &&
+ funcs.pWinHttpQueryDataAvailable &&
+ funcs.pWinHttpQueryHeaders &&
+ funcs.pWinHttpReadData &&
+ funcs.pWinHttpReceiveResponse &&
+ funcs.pWinHttpSendRequest &&
+ funcs.pWinHttpWriteData)
+ funcs_found = TRUE;
+ }
+ lookup_done = TRUE;
+}
+
#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))
+ {
+ lookup_funcs ();
+ if (funcs_found)
+ g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "winhttp",
+ 10);
+ })
static const gchar *winhttp_uri_schemes[] = { "http", "https" };
vfs = G_WINHTTP_VFS (object);
- (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCloseHandle) (vfs->session);
+ (G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCloseHandle) (vfs->session);
vfs->session = NULL;
if (vfs->wrapped_vfs)
if (!wagent)
wagent = g_utf8_to_utf16 ("GWinHttpVfs", -1, NULL, NULL, NULL);
- vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpOpen)
+ vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpOpen)
(wagent,
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
{
GObjectClass *object_class;
GVfsClass *vfs_class;
- HMODULE winhttp;
object_class = (GObjectClass *) class;
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");
- }
+ lookup_funcs ();
+ if (funcs_found)
+ class->funcs = &funcs;
+ else
+ class->funcs = NULL;
}
char *
wchar_t *status_code;
DWORD status_code_len;
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpReceiveResponse (request, NULL))
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpReceiveResponse (request, NULL))
{
_g_winhttp_set_error (error, GetLastError (), what);
}
status_code_len = 0;
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
WINHTTP_QUERY_STATUS_CODE,
NULL,
status_code = g_malloc (status_code_len);
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
WINHTTP_QUERY_STATUS_CODE,
NULL,
wchar_t *status_text = NULL;
DWORD status_text_len;
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
WINHTTP_QUERY_STATUS_TEXT,
NULL,
{
status_text = g_malloc (status_text_len);
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
WINHTTP_QUERY_STATUS_TEXT,
NULL,
{
DWORD header_len = 0;
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
which_header,
NULL,
}
*header = g_malloc (header_len);
- if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders
(request,
which_header,
NULL,
#define G_WINHTTP_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_WINHTTP_VFS, GWinHttpVfsClass))
typedef struct _GWinHttpVfs GWinHttpVfs;
+typedef struct _GWinHttpDllFuncs GWinHttpDllFuncs;
typedef struct _GWinHttpVfsClass GWinHttpVfsClass;
struct _GWinHttpVfs
HINTERNET session;
};
-struct _GWinHttpVfsClass
+struct _GWinHttpDllFuncs
{
- 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 *pWinHttpWriteData) (HINTERNET,LPCVOID,DWORD,LPDWORD);
};
+struct _GWinHttpVfsClass
+{
+ GVfsClass parent_class;
+
+ /* As there is no import library for winhttp.dll in mingw, and
+ * winhttp.dll isn't present on Windows 2000 anyway, we must look up
+ * the functions we need dynamically. Store the pointers here.
+ */
+ GWinHttpDllFuncs *funcs;
+};
+
GType _g_winhttp_vfs_get_type (void) G_GNUC_CONST;