mirror of
https://github.com/reactos/reactos.git
synced 2025-04-06 05:34:22 +00:00
[URLMON]
* Sync with Wine 1.5.26. svn path=/trunk/; revision=58569
This commit is contained in:
parent
a1407ecabc
commit
1516b0c82d
27 changed files with 3777 additions and 1278 deletions
|
@ -1,5 +1,11 @@
|
|||
|
||||
add_definitions(-D__WINESRC__)
|
||||
add_definitions(
|
||||
-D__WINESRC__
|
||||
-D_URLMON_
|
||||
-DENTRY_PREFIX=URLMON_
|
||||
-DPROXY_DELEGATION
|
||||
-DWINE_REGISTER_DLL
|
||||
-DPROXY_CLSID_IS="{0x79EAC9F1,0xBAF9,0x11CE,{0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B}}")
|
||||
|
||||
remove_definitions(-D_WIN32_WINNT=0x502)
|
||||
add_definitions(-D_WIN32_WINNT=0x600)
|
||||
|
@ -11,6 +17,7 @@ spec2def(urlmon.dll urlmon.spec ADD_IMPORTLIB)
|
|||
add_rpcproxy_files(urlmon_urlmon.idl)
|
||||
|
||||
list(APPEND SOURCE
|
||||
axinstall.c
|
||||
bindctx.c
|
||||
binding.c
|
||||
bindprot.c
|
||||
|
@ -24,7 +31,6 @@ list(APPEND SOURCE
|
|||
mimefilter.c
|
||||
mk.c
|
||||
protocol.c
|
||||
protproxy.c
|
||||
sec_mgr.c
|
||||
session.c
|
||||
umon.c
|
||||
|
@ -32,40 +38,15 @@ list(APPEND SOURCE
|
|||
uri.c
|
||||
urlmon_main.c
|
||||
usrmarshal.c
|
||||
rsrc.rc
|
||||
urlmon.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/urlmon_urlmon_p.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/urlmon_stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/urlmon.def)
|
||||
|
||||
add_library(urlmon SHARED ${SOURCE})
|
||||
|
||||
set_module_type(urlmon win32dll)
|
||||
|
||||
target_link_libraries(urlmon
|
||||
uuid
|
||||
wine
|
||||
${PSEH_LIB})
|
||||
|
||||
add_importlibs(urlmon
|
||||
rpcrt4
|
||||
ole32
|
||||
oleaut32
|
||||
shlwapi
|
||||
shell32
|
||||
wininet
|
||||
user32
|
||||
advapi32
|
||||
msvcrt
|
||||
kernel32
|
||||
ntdll)
|
||||
|
||||
add_definitions(
|
||||
-DENTRY_PREFIX=URLMON_
|
||||
-DPROXY_DELEGATION
|
||||
-DWINE_REGISTER_DLL
|
||||
-D_URLMON_)
|
||||
|
||||
target_link_libraries(urlmon uuid wine ${PSEH_LIB})
|
||||
add_importlibs(urlmon rpcrt4 propsys ole32 oleaut32 shlwapi shell32 wininet user32 advapi32 advpack msvcrt kernel32 ntdll)
|
||||
add_pch(urlmon urlmon_main.h)
|
||||
add_definitions(-DPROXY_CLSID_IS="{0x79EAC9F1,0xBAF9,0x11CE,{0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B}}")
|
||||
add_cd_file(TARGET urlmon DESTINATION reactos/system32 FOR all)
|
||||
|
|
525
reactos/dll/win32/urlmon/axinstall.c
Normal file
525
reactos/dll/win32/urlmon/axinstall.c
Normal file
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
* Copyright 2012 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "urlmon_main.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "advpub.h"
|
||||
#include "fdi.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
static const WCHAR ctxW[] = {'c','t','x',0};
|
||||
static const WCHAR cab_extW[] = {'.','c','a','b',0};
|
||||
static const WCHAR infW[] = {'i','n','f',0};
|
||||
static const WCHAR dllW[] = {'d','l','l',0};
|
||||
static const WCHAR ocxW[] = {'o','c','x',0};
|
||||
|
||||
enum install_type {
|
||||
INSTALL_UNKNOWN,
|
||||
INSTALL_DLL,
|
||||
INSTALL_INF
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
IUri *uri;
|
||||
IBindStatusCallback *callback;
|
||||
BOOL release_on_stop;
|
||||
BOOL cancel;
|
||||
WCHAR *install_file;
|
||||
const WCHAR *cache_file;
|
||||
const WCHAR *tmp_dir;
|
||||
const WCHAR *file_name;
|
||||
enum install_type install_type;
|
||||
HWND hwnd;
|
||||
int counter;
|
||||
INT_PTR timer;
|
||||
} install_ctx_t;
|
||||
|
||||
static void release_install_ctx(install_ctx_t *ctx)
|
||||
{
|
||||
if(ctx->uri)
|
||||
IUri_Release(ctx->uri);
|
||||
if(ctx->callback)
|
||||
IBindStatusCallback_Release(ctx->callback);
|
||||
heap_free(ctx->install_file);
|
||||
heap_free(ctx);
|
||||
}
|
||||
|
||||
static inline BOOL file_exists(const WCHAR *file_name)
|
||||
{
|
||||
return GetFileAttributesW(file_name) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
static HRESULT extract_cab_file(install_ctx_t *ctx)
|
||||
{
|
||||
size_t path_len, file_len;
|
||||
WCHAR *ptr;
|
||||
HRESULT hres;
|
||||
|
||||
hres = ExtractFilesW(ctx->cache_file, ctx->tmp_dir, 0, NULL, NULL, 0);
|
||||
if(FAILED(hres)) {
|
||||
WARN("ExtractFilesW failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
path_len = strlenW(ctx->tmp_dir);
|
||||
file_len = strlenW(ctx->file_name);
|
||||
ctx->install_file = heap_alloc((path_len+file_len+2)*sizeof(WCHAR));
|
||||
if(!ctx->install_file)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(ctx->install_file, ctx->tmp_dir, path_len*sizeof(WCHAR));
|
||||
ctx->install_file[path_len] = '\\';
|
||||
memcpy(ctx->install_file+path_len+1, ctx->file_name, (file_len+1)*sizeof(WCHAR));
|
||||
|
||||
/* NOTE: Assume that file_name contains ".cab" extension */
|
||||
ptr = ctx->install_file+path_len+1+file_len-3;
|
||||
|
||||
memcpy(ptr, infW, sizeof(infW));
|
||||
if(file_exists(ctx->install_file)) {
|
||||
ctx->install_type = INSTALL_INF;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
memcpy(ptr, dllW, sizeof(dllW));
|
||||
if(file_exists(ctx->install_file)) {
|
||||
ctx->install_type = INSTALL_DLL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
memcpy(ptr, ocxW, sizeof(ocxW));
|
||||
if(file_exists(ctx->install_file)) {
|
||||
ctx->install_type = INSTALL_DLL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("No known install file\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT setup_dll(install_ctx_t *ctx)
|
||||
{
|
||||
HMODULE module;
|
||||
HRESULT hres;
|
||||
|
||||
HRESULT (WINAPI *reg_func)(void);
|
||||
|
||||
module = LoadLibraryW(ctx->install_file);
|
||||
if(!module)
|
||||
return E_FAIL;
|
||||
|
||||
reg_func = (void*)GetProcAddress(module, "DllRegisterServer");
|
||||
if(reg_func) {
|
||||
hres = reg_func();
|
||||
}else {
|
||||
WARN("no DllRegisterServer function\n");
|
||||
hres = E_FAIL;
|
||||
}
|
||||
|
||||
FreeLibrary(module);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static void expand_command(install_ctx_t *ctx, const WCHAR *cmd, WCHAR *buf, size_t *size)
|
||||
{
|
||||
const WCHAR *ptr = cmd, *prev_ptr = cmd;
|
||||
size_t len = 0, len2;
|
||||
|
||||
static const WCHAR expand_dirW[] = {'%','E','X','T','R','A','C','T','_','D','I','R','%'};
|
||||
|
||||
while((ptr = strchrW(ptr, '%'))) {
|
||||
if(buf)
|
||||
memcpy(buf+len, prev_ptr, ptr-prev_ptr);
|
||||
len += ptr-prev_ptr;
|
||||
|
||||
if(!strncmpiW(ptr, expand_dirW, sizeof(expand_dirW)/sizeof(WCHAR))) {
|
||||
len2 = strlenW(ctx->tmp_dir);
|
||||
if(buf)
|
||||
memcpy(buf+len, ctx->tmp_dir, len2*sizeof(WCHAR));
|
||||
len += len2;
|
||||
ptr += sizeof(expand_dirW)/sizeof(WCHAR);
|
||||
}else {
|
||||
FIXME("Can't expand %s\n", debugstr_w(ptr));
|
||||
if(buf)
|
||||
buf[len] = '%';
|
||||
len++;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
prev_ptr = ptr;
|
||||
}
|
||||
|
||||
if(buf)
|
||||
strcpyW(buf+len, prev_ptr);
|
||||
*size = len + strlenW(prev_ptr) + 1;
|
||||
}
|
||||
|
||||
static HRESULT process_hook_section(install_ctx_t *ctx, const WCHAR *sect_name)
|
||||
{
|
||||
WCHAR buf[2048], val[2*MAX_PATH];
|
||||
const WCHAR *key;
|
||||
DWORD len;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR runW[] = {'r','u','n',0};
|
||||
|
||||
len = GetPrivateProfileStringW(sect_name, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
|
||||
if(!len)
|
||||
return S_OK;
|
||||
|
||||
for(key = buf; *key; key += strlenW(key)+1) {
|
||||
if(!strcmpiW(key, runW)) {
|
||||
WCHAR *cmd;
|
||||
size_t size;
|
||||
|
||||
len = GetPrivateProfileStringW(sect_name, runW, NULL, val, sizeof(val)/sizeof(*val), ctx->install_file);
|
||||
|
||||
TRACE("Run %s\n", debugstr_w(val));
|
||||
|
||||
expand_command(ctx, val, NULL, &size);
|
||||
|
||||
cmd = heap_alloc(size*sizeof(WCHAR));
|
||||
if(!cmd)
|
||||
heap_free(cmd);
|
||||
|
||||
expand_command(ctx, val, cmd, &size);
|
||||
hres = RunSetupCommandW(ctx->hwnd, cmd, NULL, ctx->tmp_dir, NULL, NULL, 0, NULL);
|
||||
heap_free(cmd);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}else {
|
||||
FIXME("Unsupported hook %s\n", debugstr_w(key));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT install_inf_file(install_ctx_t *ctx)
|
||||
{
|
||||
WCHAR buf[2048], sect_name[128];
|
||||
BOOL default_install = TRUE;
|
||||
const WCHAR *key;
|
||||
DWORD len;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR setup_hooksW[] = {'S','e','t','u','p',' ','H','o','o','k','s',0};
|
||||
static const WCHAR add_codeW[] = {'A','d','d','.','C','o','d','e',0};
|
||||
|
||||
len = GetPrivateProfileStringW(setup_hooksW, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
|
||||
if(len) {
|
||||
default_install = FALSE;
|
||||
|
||||
for(key = buf; *key; key += strlenW(key)+1) {
|
||||
TRACE("[Setup Hooks] key: %s\n", debugstr_w(key));
|
||||
|
||||
len = GetPrivateProfileStringW(setup_hooksW, key, NULL, sect_name, sizeof(sect_name)/sizeof(*sect_name),
|
||||
ctx->install_file);
|
||||
if(!len) {
|
||||
WARN("Could not get key value\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hres = process_hook_section(ctx, sect_name);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
len = GetPrivateProfileStringW(add_codeW, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
|
||||
if(len) {
|
||||
FIXME("[Add.Code] section not supported\n");
|
||||
|
||||
/* Don't throw an error if we successfully ran setup hooks;
|
||||
installation is likely to be complete enough */
|
||||
if(default_install)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(default_install) {
|
||||
hres = RunSetupCommandW(ctx->hwnd, ctx->install_file, NULL, ctx->tmp_dir, NULL, NULL, RSC_FLAG_INF, NULL);
|
||||
if(FAILED(hres)) {
|
||||
WARN("RunSetupCommandW failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT install_cab_file(install_ctx_t *ctx)
|
||||
{
|
||||
WCHAR tmp_path[MAX_PATH], tmp_dir[MAX_PATH];
|
||||
BOOL res = FALSE, leave_temp = FALSE;
|
||||
DWORD i;
|
||||
HRESULT hres;
|
||||
|
||||
GetTempPathW(sizeof(tmp_path)/sizeof(WCHAR), tmp_path);
|
||||
|
||||
for(i=0; !res && i < 100; i++) {
|
||||
GetTempFileNameW(tmp_path, NULL, GetTickCount() + i*17037, tmp_dir);
|
||||
res = CreateDirectoryW(tmp_dir, NULL);
|
||||
}
|
||||
if(!res)
|
||||
return E_FAIL;
|
||||
|
||||
ctx->tmp_dir = tmp_dir;
|
||||
|
||||
TRACE("Using temporary directory %s\n", debugstr_w(tmp_dir));
|
||||
|
||||
hres = extract_cab_file(ctx);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(ctx->callback)
|
||||
IBindStatusCallback_OnProgress(ctx->callback, 0, 0, BINDSTATUS_INSTALLINGCOMPONENTS, ctx->install_file);
|
||||
|
||||
switch(ctx->install_type) {
|
||||
case INSTALL_INF:
|
||||
hres = install_inf_file(ctx);
|
||||
break;
|
||||
case INSTALL_DLL:
|
||||
FIXME("Installing DLL, registering in temporary location\n");
|
||||
hres = setup_dll(ctx);
|
||||
if(SUCCEEDED(hres))
|
||||
leave_temp = TRUE;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(!leave_temp)
|
||||
RemoveDirectoryW(ctx->tmp_dir);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static void update_counter(install_ctx_t *ctx, HWND hwnd)
|
||||
{
|
||||
WCHAR text[100];
|
||||
|
||||
if(--ctx->counter <= 0) {
|
||||
HWND button_hwnd;
|
||||
|
||||
KillTimer(hwnd, ctx->timer);
|
||||
LoadStringW(urlmon_instance, IDS_AXINSTALL_INSTALL, text, sizeof(text)/sizeof(WCHAR));
|
||||
|
||||
button_hwnd = GetDlgItem(hwnd, ID_AXINSTALL_INSTALL_BTN);
|
||||
EnableWindow(button_hwnd, TRUE);
|
||||
}else {
|
||||
WCHAR buf[100];
|
||||
LoadStringW(urlmon_instance, IDS_AXINSTALL_INSTALLN, buf, sizeof(buf)/sizeof(WCHAR));
|
||||
sprintfW(text, buf, ctx->counter);
|
||||
}
|
||||
|
||||
SetDlgItemTextW(hwnd, ID_AXINSTALL_INSTALL_BTN, text);
|
||||
}
|
||||
|
||||
static BOOL init_warning_dialog(HWND hwnd, install_ctx_t *ctx)
|
||||
{
|
||||
BSTR display_uri;
|
||||
HRESULT hres;
|
||||
|
||||
if(!SetPropW(hwnd, ctxW, ctx))
|
||||
return FALSE;
|
||||
|
||||
hres = IUri_GetDisplayUri(ctx->uri, &display_uri);
|
||||
if(FAILED(hres))
|
||||
return FALSE;
|
||||
|
||||
SetDlgItemTextW(hwnd, ID_AXINSTALL_LOCATION, display_uri);
|
||||
SysFreeString(display_uri);
|
||||
|
||||
SendDlgItemMessageW(hwnd, ID_AXINSTALL_ICON, STM_SETICON,
|
||||
(WPARAM)LoadIconW(0, (const WCHAR*)OIC_WARNING), 0);
|
||||
|
||||
ctx->counter = 4;
|
||||
update_counter(ctx, hwnd);
|
||||
ctx->timer = SetTimer(hwnd, 1, 1000, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR WINAPI warning_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch(msg) {
|
||||
case WM_INITDIALOG: {
|
||||
if(!init_warning_dialog(hwnd, (install_ctx_t*)lparam))
|
||||
EndDialog(hwnd, 0);
|
||||
return TRUE;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
switch(wparam) {
|
||||
case ID_AXINSTALL_INSTALL_BTN: {
|
||||
install_ctx_t *ctx = GetPropW(hwnd, ctxW);
|
||||
if(ctx)
|
||||
ctx->cancel = FALSE;
|
||||
EndDialog(hwnd, 0);
|
||||
return FALSE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
return FALSE;
|
||||
}
|
||||
case WM_TIMER:
|
||||
update_counter(GetPropW(hwnd, ctxW), hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL install_warning(install_ctx_t *ctx)
|
||||
{
|
||||
IWindowForBindingUI *window_iface;
|
||||
HWND parent_hwnd = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
if(!ctx->callback) {
|
||||
FIXME("no callback\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hres = IBindStatusCallback_QueryInterface(ctx->callback, &IID_IWindowForBindingUI, (void**)&window_iface);
|
||||
if(FAILED(hres))
|
||||
return FALSE;
|
||||
|
||||
hres = IWindowForBindingUI_GetWindow(window_iface, &IID_ICodeInstall, &ctx->hwnd);
|
||||
IWindowForBindingUI_Release(window_iface);
|
||||
if(FAILED(hres))
|
||||
return FALSE;
|
||||
|
||||
ctx->cancel = TRUE;
|
||||
DialogBoxParamW(urlmon_instance, MAKEINTRESOURCEW(ID_AXINSTALL_WARNING_DLG), parent_hwnd, warning_proc, (LPARAM)ctx);
|
||||
return !ctx->cancel;
|
||||
}
|
||||
|
||||
static HRESULT install_file(install_ctx_t *ctx, const WCHAR *cache_file)
|
||||
{
|
||||
BSTR path;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("%s\n", debugstr_w(cache_file));
|
||||
|
||||
ctx->cache_file = cache_file;
|
||||
|
||||
if(!install_warning(ctx)) {
|
||||
TRACE("Installation cancelled\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = IUri_GetPath(ctx->uri, &path);
|
||||
if(SUCCEEDED(hres)) {
|
||||
const WCHAR *ptr, *ptr2, *ext;
|
||||
|
||||
ptr = strrchrW(path, '/');
|
||||
if(!ptr)
|
||||
ptr = path;
|
||||
else
|
||||
ptr++;
|
||||
|
||||
ptr2 = strrchrW(ptr, '\\');
|
||||
if(ptr2)
|
||||
ptr = ptr2+1;
|
||||
|
||||
ctx->file_name = ptr;
|
||||
ext = strrchrW(ptr, '.');
|
||||
if(!ext)
|
||||
ext = ptr;
|
||||
|
||||
if(!strcmpW(ext, cab_extW)) {
|
||||
hres = install_cab_file(ctx);
|
||||
}else {
|
||||
FIXME("Unsupported extension %s\n", debugstr_w(ext));
|
||||
hres = E_NOTIMPL;
|
||||
}
|
||||
SysFreeString(path);
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static void failure_msgbox(install_ctx_t *ctx, HRESULT hres)
|
||||
{
|
||||
WCHAR buf[1024], fmt[1024];
|
||||
|
||||
LoadStringW(urlmon_instance, IDS_AXINSTALL_FAILURE, fmt, sizeof(fmt)/sizeof(WCHAR));
|
||||
sprintfW(buf, fmt, hres);
|
||||
MessageBoxW(ctx->hwnd, buf, NULL, MB_OK);
|
||||
}
|
||||
|
||||
static HRESULT distunit_on_stop(void *ctx, const WCHAR *cache_file, HRESULT hresult, const WCHAR *error_str)
|
||||
{
|
||||
install_ctx_t *install_ctx = ctx;
|
||||
|
||||
TRACE("(%p %s %08x %s)\n", ctx, debugstr_w(cache_file), hresult, debugstr_w(error_str));
|
||||
|
||||
if(hresult == S_OK) {
|
||||
hresult = install_file(install_ctx, cache_file);
|
||||
if(FAILED(hresult))
|
||||
failure_msgbox(ctx, hresult);
|
||||
}
|
||||
|
||||
if(install_ctx->callback)
|
||||
IBindStatusCallback_OnStopBinding(install_ctx->callback, hresult, error_str);
|
||||
|
||||
if(install_ctx->release_on_stop)
|
||||
release_install_ctx(install_ctx);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* AsyncInstallDistributionUnit (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI AsyncInstallDistributionUnit(const WCHAR *szDistUnit, const WCHAR *szTYPE, const WCHAR *szExt,
|
||||
DWORD dwFileVersionMS, DWORD dwFileVersionLS, const WCHAR *szURL, IBindCtx *pbc, void *pvReserved, DWORD flags)
|
||||
{
|
||||
install_ctx_t *ctx;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %s %s %x %x %s %p %p %x)\n", debugstr_w(szDistUnit), debugstr_w(szTYPE), debugstr_w(szExt),
|
||||
dwFileVersionMS, dwFileVersionLS, debugstr_w(szURL), pbc, pvReserved, flags);
|
||||
|
||||
if(szDistUnit || szTYPE || szExt)
|
||||
FIXME("Unsupported arguments\n");
|
||||
|
||||
ctx = heap_alloc_zero(sizeof(*ctx));
|
||||
if(!ctx)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = CreateUri(szURL, 0, 0, &ctx->uri);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(ctx);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ctx->callback = bsc_from_bctx(pbc);
|
||||
|
||||
hres = download_to_cache(ctx->uri, distunit_on_stop, ctx, ctx->callback);
|
||||
if(hres == MK_S_ASYNCHRONOUS)
|
||||
ctx->release_on_stop = TRUE;
|
||||
else
|
||||
release_install_ctx(ctx);
|
||||
|
||||
return hres;
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
|
||||
static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
|
||||
|
||||
extern IID IID_IBindStatusCallbackHolder;
|
||||
|
||||
|
@ -51,6 +51,45 @@ static void *get_callback_iface(BindStatusCallback *This, REFIID riid)
|
|||
return SUCCEEDED(hres) ? ret : NULL;
|
||||
}
|
||||
|
||||
static IBindStatusCallback *bsch_from_bctx(IBindCtx *bctx)
|
||||
{
|
||||
IBindStatusCallback *bsc;
|
||||
IUnknown *unk;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IBindCtx_GetObjectParam(bctx, bscb_holderW, &unk);
|
||||
if(FAILED(hres))
|
||||
return NULL;
|
||||
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc);
|
||||
IUnknown_Release(unk);
|
||||
return SUCCEEDED(hres) ? bsc : NULL;
|
||||
}
|
||||
|
||||
IBindStatusCallback *bsc_from_bctx(IBindCtx *bctx)
|
||||
{
|
||||
BindStatusCallback *holder;
|
||||
IBindStatusCallback *bsc;
|
||||
HRESULT hres;
|
||||
|
||||
bsc = bsch_from_bctx(bctx);
|
||||
if(!bsc)
|
||||
return NULL;
|
||||
|
||||
hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
|
||||
if(FAILED(hres))
|
||||
return bsc;
|
||||
|
||||
if(holder->callback) {
|
||||
IBindStatusCallback_Release(bsc);
|
||||
bsc = holder->callback;
|
||||
IBindStatusCallback_AddRef(bsc);
|
||||
}
|
||||
|
||||
IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface);
|
||||
return bsc;
|
||||
}
|
||||
|
||||
static inline BindStatusCallback *impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallbackEx_iface);
|
||||
|
@ -90,7 +129,7 @@ static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *i
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IBindStatusCallback_AddRef((IUnknown*)*ppv);
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -158,7 +197,7 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface
|
|||
{
|
||||
BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
|
||||
|
||||
TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
|
||||
TRACE("%p)->(%u %u %s %s)\n", This, ulProgress, ulProgressMax, debugstr_bindstatus(ulStatusCode),
|
||||
debugstr_w(szStatusText));
|
||||
|
||||
return IBindStatusCallback_OnProgress(This->callback, ulProgress,
|
||||
|
@ -261,19 +300,19 @@ static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface,
|
|||
REFIID riid, void **ppv)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IServiceProvider(iface);
|
||||
return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IServiceProvider(iface);
|
||||
return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IServiceProvider(iface);
|
||||
return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
|
||||
|
@ -284,17 +323,17 @@ static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
|
|||
|
||||
if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
|
||||
TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
|
||||
TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
|
||||
TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
|
||||
|
@ -328,19 +367,19 @@ static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface,
|
|||
REFIID riid, void **ppv)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
|
||||
return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
|
||||
return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
|
||||
return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
|
||||
|
@ -428,19 +467,19 @@ static inline BindStatusCallback *impl_from_IAuthenticate(IAuthenticate *iface)
|
|||
static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IAuthenticate(iface);
|
||||
return IBindStatusCallback_QueryInterface(&This->IAuthenticate_iface, riid, ppv);
|
||||
return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IAuthenticate(iface);
|
||||
return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface)
|
||||
{
|
||||
BindStatusCallback *This = impl_from_IAuthenticate(iface);
|
||||
return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
|
||||
return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
|
||||
|
@ -516,7 +555,6 @@ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pb
|
|||
{
|
||||
BindStatusCallback *holder;
|
||||
IBindStatusCallback *bsc, *prev = NULL;
|
||||
IUnknown *unk;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved);
|
||||
|
@ -524,34 +562,30 @@ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pb
|
|||
if (!pbc || !pbsc)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc);
|
||||
IUnknown_Release(unk);
|
||||
bsc = bsch_from_bctx(pbc);
|
||||
if(bsc) {
|
||||
hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(ppbscPrevious) {
|
||||
IBindStatusCallback_AddRef(holder->callback);
|
||||
*ppbscPrevious = holder->callback;
|
||||
}
|
||||
|
||||
set_callback(holder, pbsc);
|
||||
|
||||
IBindStatusCallback_Release(bsc);
|
||||
IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
|
||||
return S_OK;
|
||||
}else {
|
||||
prev = bsc;
|
||||
if(ppbscPrevious) {
|
||||
IBindStatusCallback_AddRef(holder->callback);
|
||||
*ppbscPrevious = holder->callback;
|
||||
}
|
||||
|
||||
set_callback(holder, pbsc);
|
||||
|
||||
IBindStatusCallback_Release(bsc);
|
||||
IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface);
|
||||
return S_OK;
|
||||
}else {
|
||||
prev = bsc;
|
||||
}
|
||||
|
||||
IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
|
||||
IBindCtx_RevokeObjectParam(pbc, bscb_holderW);
|
||||
}
|
||||
|
||||
hres = wrap_callback(pbsc, &bsc);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc);
|
||||
hres = IBindCtx_RegisterObjectParam(pbc, bscb_holderW, (IUnknown*)bsc);
|
||||
IBindStatusCallback_Release(bsc);
|
||||
}
|
||||
if(FAILED(hres)) {
|
||||
|
@ -579,39 +613,21 @@ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pb
|
|||
*/
|
||||
HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
|
||||
{
|
||||
BindStatusCallback *holder;
|
||||
IBindStatusCallback *callback;
|
||||
IUnknown *unk;
|
||||
BOOL dorevoke = FALSE;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %p)\n", pbc, pbsc);
|
||||
|
||||
if (!pbc || !pbsc)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
|
||||
if(FAILED(hres))
|
||||
callback = bsc_from_bctx(pbc);
|
||||
if(!callback)
|
||||
return S_OK;
|
||||
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback);
|
||||
IUnknown_Release(unk);
|
||||
if(FAILED(hres))
|
||||
return S_OK;
|
||||
if(callback == pbsc)
|
||||
IBindCtx_RevokeObjectParam(pbc, bscb_holderW);
|
||||
|
||||
hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(pbsc == holder->callback)
|
||||
dorevoke = TRUE;
|
||||
IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
|
||||
}else if(pbsc == callback) {
|
||||
dorevoke = TRUE;
|
||||
}
|
||||
IBindStatusCallback_Release(callback);
|
||||
|
||||
if(dorevoke)
|
||||
IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ typedef struct {
|
|||
BOOL use_cache_file;
|
||||
DWORD state;
|
||||
HRESULT hres;
|
||||
CLSID clsid;
|
||||
download_state_t download_state;
|
||||
IUnknown *obj;
|
||||
IMoniker *mon;
|
||||
|
@ -107,7 +108,7 @@ static void read_protocol_data(stgmed_buf_t *stgmed_buf)
|
|||
DWORD read;
|
||||
HRESULT hres;
|
||||
|
||||
do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
|
||||
do hres = IInternetProtocolEx_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
|
||||
while(hres == S_OK);
|
||||
}
|
||||
|
||||
|
@ -178,8 +179,8 @@ static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
|
|||
if(!(binding->state & BINDING_STOPPED)) {
|
||||
binding->state |= BINDING_STOPPED;
|
||||
|
||||
IBindStatusCallback_OnStopBinding(binding->callback, hres, str);
|
||||
binding->hres = hres;
|
||||
IBindStatusCallback_OnStopBinding(binding->callback, hres, str);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,6 +311,7 @@ static void create_object(Binding *binding)
|
|||
heap_free(clsid_str);
|
||||
|
||||
IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_ENDSYNCOPERATION, NULL);
|
||||
binding->clsid = CLSID_NULL;
|
||||
|
||||
stop_binding(binding, hres, NULL);
|
||||
if(FAILED(hres))
|
||||
|
@ -372,7 +374,7 @@ static ULONG WINAPI StgMedUnk_Release(IUnknown *iface)
|
|||
if(!ref) {
|
||||
if(This->file != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(This->file);
|
||||
IInternetProtocol_Release(This->protocol);
|
||||
IInternetProtocolEx_Release(This->protocol);
|
||||
heap_free(This->cache_file);
|
||||
heap_free(This);
|
||||
|
||||
|
@ -398,7 +400,7 @@ static stgmed_buf_t *create_stgmed_buf(IInternetProtocolEx *protocol)
|
|||
ret->hres = S_OK;
|
||||
ret->cache_file = NULL;
|
||||
|
||||
IInternetProtocol_AddRef(protocol);
|
||||
IInternetProtocolEx_AddRef(protocol);
|
||||
ret->protocol = protocol;
|
||||
|
||||
URLMON_LockModule();
|
||||
|
@ -484,7 +486,7 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv,
|
|||
TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if(This->buf->file == INVALID_HANDLE_VALUE) {
|
||||
hres = This->buf->hres = IInternetProtocol_Read(This->buf->protocol, (PBYTE)pv, cb, &read);
|
||||
hres = This->buf->hres = IInternetProtocolEx_Read(This->buf->protocol, (PBYTE)pv, cb, &read);
|
||||
}else {
|
||||
hres = ReadFile(This->buf->file, pv, cb, &read, NULL) ? S_OK : INET_E_DOWNLOAD_FAILURE;
|
||||
}
|
||||
|
@ -881,8 +883,23 @@ static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtoc
|
|||
DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
|
||||
{
|
||||
Binding *This = impl_from_IBinding(iface);
|
||||
FIXME("(%p)->(%p %p %p %p)\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%p %p %p %p)\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
|
||||
|
||||
if(!pdwResult || !pszResult || pdwReserved)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(!(This->state & BINDING_STOPPED)) {
|
||||
*pclsidProtocol = CLSID_NULL;
|
||||
*pdwResult = 0;
|
||||
*pszResult = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*pclsidProtocol = This->hres==S_OK ? CLSID_NULL : This->clsid;
|
||||
*pdwResult = This->hres;
|
||||
*pszResult = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IBindingVtbl BindingVtbl = {
|
||||
|
@ -963,7 +980,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
|
|||
{
|
||||
Binding *This = impl_from_IInternetProtocolSink(iface);
|
||||
|
||||
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
|
||||
TRACE("(%p)->(%s %s)\n", This, debugstr_bindstatus(ulStatusCode), debugstr_w(szStatusText));
|
||||
|
||||
switch(ulStatusCode) {
|
||||
case BINDSTATUS_FINDINGRESOURCE:
|
||||
|
@ -983,6 +1000,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
|
|||
on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText);
|
||||
break;
|
||||
case BINDSTATUS_PROTOCOLCLASSID:
|
||||
CLSIDFromString(szStatusText, &This->clsid);
|
||||
break;
|
||||
case BINDSTATUS_MIMETYPEAVAILABLE:
|
||||
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
|
||||
|
@ -1077,8 +1095,19 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
|
|||
formatetc.tymed = stgmed.tymed;
|
||||
formatetc.cfFormat = This->clipboard_format;
|
||||
|
||||
IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
|
||||
hres = IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
|
||||
&formatetc, &stgmed);
|
||||
if(hres != S_OK) {
|
||||
if(This->download_state != END_DOWNLOAD) {
|
||||
This->download_state = END_DOWNLOAD;
|
||||
IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
|
||||
BINDSTATUS_ENDDOWNLOADDATA, This->url);
|
||||
}
|
||||
|
||||
WARN("OnDataAvailable returned %x\n", hres);
|
||||
stop_binding(This, hres, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(This->download_state == END_DOWNLOAD)
|
||||
stop_binding(This, S_OK, NULL);
|
||||
|
@ -1104,6 +1133,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *i
|
|||
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
|
||||
|
||||
stop_binding(This, hrResult, szResult);
|
||||
|
||||
IInternetProtocolEx_Terminate(&This->protocol->IInternetProtocolEx_iface, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1150,19 +1180,7 @@ static HRESULT WINAPI InternetBindInfo_GetBindInfo(IInternetBindInfo *iface,
|
|||
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
|
||||
|
||||
*grfBINDF = This->bindf;
|
||||
|
||||
*pbindinfo = This->bindinfo;
|
||||
|
||||
if(pbindinfo->szExtraInfo || pbindinfo->szCustomVerb)
|
||||
FIXME("copy strings\n");
|
||||
|
||||
if(pbindinfo->stgmedData.pUnkForRelease)
|
||||
IUnknown_AddRef(pbindinfo->stgmedData.pUnkForRelease);
|
||||
|
||||
if(pbindinfo->pUnk)
|
||||
IUnknown_AddRef(pbindinfo->pUnk);
|
||||
|
||||
return S_OK;
|
||||
return CopyBindInfo(&This->bindinfo, pbindinfo);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetBindInfo_GetBindString(IInternetBindInfo *iface,
|
||||
|
|
|
@ -34,32 +34,38 @@ struct _task_header_t {
|
|||
#define WM_MK_CONTINUE (WM_USER+101)
|
||||
#define WM_MK_RELEASE (WM_USER+102)
|
||||
|
||||
static void process_tasks(BindProtocol *This)
|
||||
{
|
||||
task_header_t *task;
|
||||
|
||||
while(1) {
|
||||
EnterCriticalSection(&This->section);
|
||||
|
||||
task = This->task_queue_head;
|
||||
if(task) {
|
||||
This->task_queue_head = task->next;
|
||||
if(!This->task_queue_head)
|
||||
This->task_queue_tail = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->section);
|
||||
|
||||
if(!task)
|
||||
break;
|
||||
|
||||
This->continue_call++;
|
||||
task->proc(This, task);
|
||||
This->continue_call--;
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg) {
|
||||
case WM_MK_CONTINUE: {
|
||||
BindProtocol *This = (BindProtocol*)lParam;
|
||||
task_header_t *task;
|
||||
|
||||
while(1) {
|
||||
EnterCriticalSection(&This->section);
|
||||
|
||||
task = This->task_queue_head;
|
||||
if(task) {
|
||||
This->task_queue_head = task->next;
|
||||
if(!This->task_queue_head)
|
||||
This->task_queue_tail = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->section);
|
||||
|
||||
if(!task)
|
||||
break;
|
||||
|
||||
This->continue_call++;
|
||||
task->proc(This, task);
|
||||
This->continue_call--;
|
||||
}
|
||||
process_tasks(This);
|
||||
|
||||
IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
|
||||
return 0;
|
||||
|
@ -165,48 +171,45 @@ static void push_task(BindProtocol *This, task_header_t *task, task_proc_t proc)
|
|||
}
|
||||
}
|
||||
|
||||
static inline BOOL do_direct_notif(BindProtocol *This)
|
||||
static inline BOOL is_apartment_thread(BindProtocol *This)
|
||||
{
|
||||
return !(This->pi & PI_APARTMENTTHREADED) || (This->apartment_thread == GetCurrentThreadId() && !This->continue_call);
|
||||
return This->apartment_thread == GetCurrentThreadId();
|
||||
}
|
||||
|
||||
static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter, LPCWSTR mime)
|
||||
static inline BOOL do_direct_notif(BindProtocol *This)
|
||||
{
|
||||
return !(This->pi & PI_APARTMENTTHREADED) || (is_apartment_thread(This) && !This->continue_call);
|
||||
}
|
||||
|
||||
static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter)
|
||||
{
|
||||
PROTOCOLFILTERDATA filter_data = { sizeof(PROTOCOLFILTERDATA), NULL, NULL, NULL, 0 };
|
||||
IInternetProtocolSink *protocol_sink, *old_sink;
|
||||
ProtocolProxy *filter_proxy;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&protocol_sink);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_protocol_proxy(&This->default_protocol_handler.IInternetProtocol_iface, This->protocol_sink, &filter_proxy);
|
||||
hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&This->protocol_sink_handler);
|
||||
if(FAILED(hres)) {
|
||||
IInternetProtocolSink_Release(protocol_sink);
|
||||
This->protocol_sink_handler = &This->default_protocol_handler.IInternetProtocolSink_iface;
|
||||
return hres;
|
||||
}
|
||||
|
||||
old_sink = This->protocol_sink;
|
||||
This->protocol_sink = protocol_sink;
|
||||
This->filter_proxy = filter_proxy;
|
||||
|
||||
IInternetProtocol_AddRef(mime_filter);
|
||||
This->protocol_handler = mime_filter;
|
||||
|
||||
filter_data.pProtocol = &filter_proxy->IInternetProtocol_iface;
|
||||
hres = IInternetProtocol_Start(mime_filter, mime, &filter_proxy->IInternetProtocolSink_iface,
|
||||
filter_data.pProtocol = &This->default_protocol_handler.IInternetProtocol_iface;
|
||||
hres = IInternetProtocol_Start(mime_filter, This->mime, &This->default_protocol_handler.IInternetProtocolSink_iface,
|
||||
&This->IInternetBindInfo_iface, PI_FILTER_MODE|PI_FORCE_ASYNC,
|
||||
(HANDLE_PTR)&filter_data);
|
||||
if(FAILED(hres)) {
|
||||
IInternetProtocolSink_Release(old_sink);
|
||||
IInternetProtocolSink_Release(This->protocol_sink_handler);
|
||||
IInternetProtocol_Release(This->protocol_handler);
|
||||
This->protocol_sink_handler = &This->default_protocol_handler.IInternetProtocolSink_iface;
|
||||
This->protocol_handler = &This->default_protocol_handler.IInternetProtocol_iface;
|
||||
return hres;
|
||||
}
|
||||
|
||||
IInternetProtocolSink_ReportProgress(old_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL);
|
||||
IInternetProtocolSink_Release(old_sink);
|
||||
/* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense to is seems to be a bug there. */
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL);
|
||||
|
||||
This->pi &= ~PI_MIMEVERIFICATION; /* FIXME: more tests */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -216,25 +219,21 @@ static void mime_available(BindProtocol *This, LPCWSTR mime, BOOL verified)
|
|||
HRESULT hres;
|
||||
|
||||
heap_free(This->mime);
|
||||
This->mime = NULL;
|
||||
This->mime = heap_strdupW(mime);
|
||||
|
||||
mime_filter = get_mime_filter(mime);
|
||||
if(mime_filter) {
|
||||
if(This->protocol_handler==&This->default_protocol_handler.IInternetProtocol_iface
|
||||
&& (mime_filter = get_mime_filter(mime))) {
|
||||
TRACE("Got mime filter for %s\n", debugstr_w(mime));
|
||||
|
||||
hres = handle_mime_filter(This, mime_filter, mime);
|
||||
hres = handle_mime_filter(This, mime_filter);
|
||||
IInternetProtocol_Release(mime_filter);
|
||||
if(FAILED(hres))
|
||||
FIXME("MIME filter failed: %08x\n", hres);
|
||||
}else {
|
||||
This->mime = heap_strdupW(mime);
|
||||
}
|
||||
|
||||
if(verified || !(This->pi & PI_MIMEVERIFICATION)) {
|
||||
This->reported_mime = TRUE;
|
||||
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
|
||||
}
|
||||
if(This->reported_mime || verified || !(This->pi & PI_MIMEVERIFICATION)) {
|
||||
This->reported_mime = TRUE;
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,15 +336,18 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocolEx *iface)
|
|||
IInternetBindInfo_Release(This->bind_info);
|
||||
if(This->protocol_handler && This->protocol_handler != &This->default_protocol_handler.IInternetProtocol_iface)
|
||||
IInternetProtocol_Release(This->protocol_handler);
|
||||
if(This->filter_proxy)
|
||||
IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface);
|
||||
if(This->protocol_sink_handler &&
|
||||
This->protocol_sink_handler != &This->default_protocol_handler.IInternetProtocolSink_iface)
|
||||
IInternetProtocolSink_Release(This->protocol_sink_handler);
|
||||
if(This->uri)
|
||||
IUri_Release(This->uri);
|
||||
SysFreeString(This->display_uri);
|
||||
|
||||
set_binding_sink(This, NULL, NULL);
|
||||
|
||||
if(This->notif_hwnd)
|
||||
release_notif_hwnd(This->notif_hwnd);
|
||||
This->section.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->section);
|
||||
|
||||
heap_free(This->mime);
|
||||
|
@ -544,17 +546,16 @@ static HRESULT WINAPI BindProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
|
|||
&This->IInternetBindInfo_iface, 0, NULL);
|
||||
IInternetProtocolEx_Release(protocolex);
|
||||
}else {
|
||||
BSTR display_uri;
|
||||
|
||||
hres = IUri_GetDisplayUri(pUri, &display_uri);
|
||||
hres = IUri_GetDisplayUri(pUri, &This->display_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IInternetProtocol_Start(protocol, display_uri, &This->IInternetProtocolSink_iface,
|
||||
hres = IInternetProtocol_Start(protocol, This->display_uri, &This->IInternetProtocolSink_iface,
|
||||
&This->IInternetBindInfo_iface, 0, 0);
|
||||
SysFreeString(display_uri);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
process_tasks(This);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -606,7 +607,29 @@ static inline BindProtocol *impl_from_IInternetProtocol(IInternetProtocol *iface
|
|||
|
||||
static HRESULT WINAPI ProtocolHandler_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
ERR("should not be called\n");
|
||||
BindProtocol *This = impl_from_IInternetProtocol(iface);
|
||||
|
||||
*ppv = NULL;
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||
*ppv = &This->default_protocol_handler.IInternetProtocol_iface;
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
|
||||
*ppv = &This->default_protocol_handler.IInternetProtocol_iface;
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
|
||||
*ppv = &This->default_protocol_handler.IInternetProtocol_iface;
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
|
||||
*ppv = &This->default_protocol_handler.IInternetProtocolSink_iface;
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("not supported interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -667,11 +690,6 @@ static HRESULT WINAPI ProtocolHandler_Terminate(IInternetProtocol *iface, DWORD
|
|||
|
||||
IInternetProtocol_Terminate(This->protocol, 0);
|
||||
|
||||
if(This->filter_proxy) {
|
||||
IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface);
|
||||
This->filter_proxy = NULL;
|
||||
}
|
||||
|
||||
set_binding_sink(This, NULL, NULL);
|
||||
|
||||
if(This->bind_info) {
|
||||
|
@ -722,7 +740,11 @@ static HRESULT WINAPI ProtocolHandler_Read(IInternetProtocol *iface, void *pv,
|
|||
if(read < cb) {
|
||||
ULONG cread = 0;
|
||||
|
||||
if(is_apartment_thread(This))
|
||||
This->continue_call++;
|
||||
hres = IInternetProtocol_Read(This->protocol, (BYTE*)pv+read, cb-read, &cread);
|
||||
if(is_apartment_thread(This))
|
||||
This->continue_call--;
|
||||
read += cread;
|
||||
}
|
||||
|
||||
|
@ -772,6 +794,188 @@ static const IInternetProtocolVtbl InternetProtocolHandlerVtbl = {
|
|||
ProtocolHandler_UnlockRequest
|
||||
};
|
||||
|
||||
static inline BindProtocol *impl_from_IInternetProtocolSinkHandler(IInternetProtocolSink *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BindProtocol, default_protocol_handler.IInternetProtocolSink_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ProtocolSinkHandler_QueryInterface(IInternetProtocolSink *iface,
|
||||
REFIID riid, void **ppvObject)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
return IInternetProtocol_QueryInterface(&This->default_protocol_handler.IInternetProtocol_iface,
|
||||
riid, ppvObject);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ProtocolSinkHandler_AddRef(IInternetProtocolSink *iface)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ProtocolSinkHandler_Release(IInternetProtocolSink *iface)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ProtocolSinkHandler_Switch(IInternetProtocolSink *iface,
|
||||
PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pProtocolData);
|
||||
|
||||
if(!This->protocol_sink) {
|
||||
IInternetProtocol_Continue(This->protocol_handler, pProtocolData);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ProtocolSinkHandler_ReportProgress(IInternetProtocolSink *iface,
|
||||
ULONG status_code, LPCWSTR status_text)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
|
||||
TRACE("(%p)->(%s %s)\n", This, debugstr_bindstatus(status_code), debugstr_w(status_text));
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
||||
switch(status_code) {
|
||||
case BINDSTATUS_FINDINGRESOURCE:
|
||||
case BINDSTATUS_CONNECTING:
|
||||
case BINDSTATUS_REDIRECTING:
|
||||
case BINDSTATUS_SENDINGREQUEST:
|
||||
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
|
||||
case BINDSTATUS_DIRECTBIND:
|
||||
case BINDSTATUS_ACCEPTRANGES:
|
||||
case BINDSTATUS_DECODING:
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_BEGINDOWNLOADDATA:
|
||||
IInternetProtocolSink_ReportData(This->protocol_sink, This->bscf, This->progress, This->progress_max);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_MIMETYPEAVAILABLE:
|
||||
mime_available(This, status_text, FALSE);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
|
||||
mime_available(This, status_text, TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unsupported ulStatusCode %u\n", status_code);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface,
|
||||
DWORD bscf, ULONG progress, ULONG progress_max)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
|
||||
TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max);
|
||||
|
||||
This->bscf = bscf;
|
||||
This->progress = progress;
|
||||
This->progress_max = progress_max;
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
||||
if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) {
|
||||
BYTE buf[BUFFER_SIZE];
|
||||
DWORD read = 0;
|
||||
LPWSTR mime;
|
||||
HRESULT hres;
|
||||
|
||||
do {
|
||||
read = 0;
|
||||
hres = IInternetProtocol_Read(This->protocol, buf,
|
||||
sizeof(buf)-This->buf_size, &read);
|
||||
if(FAILED(hres) && hres != E_PENDING)
|
||||
return hres;
|
||||
|
||||
if(!This->buf) {
|
||||
This->buf = heap_alloc(BUFFER_SIZE);
|
||||
if(!This->buf)
|
||||
return E_OUTOFMEMORY;
|
||||
}else if(read + This->buf_size > BUFFER_SIZE) {
|
||||
BYTE *tmp;
|
||||
|
||||
tmp = heap_realloc(This->buf, read+This->buf_size);
|
||||
if(!tmp)
|
||||
return E_OUTOFMEMORY;
|
||||
This->buf = tmp;
|
||||
}
|
||||
|
||||
memcpy(This->buf+This->buf_size, buf, read);
|
||||
This->buf_size += read;
|
||||
}while(This->buf_size < MIME_TEST_SIZE && hres == S_OK);
|
||||
|
||||
if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE)
|
||||
return S_OK;
|
||||
|
||||
bscf = BSCF_FIRSTDATANOTIFICATION;
|
||||
if(hres == S_FALSE)
|
||||
bscf |= BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
|
||||
|
||||
if(!This->reported_mime) {
|
||||
BSTR raw_uri;
|
||||
|
||||
hres = IUri_GetRawUri(This->uri, &raw_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = FindMimeFromData(NULL, raw_uri, This->buf, min(This->buf_size, MIME_TEST_SIZE),
|
||||
This->mime, 0, &mime, 0);
|
||||
SysFreeString(raw_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
heap_free(This->mime);
|
||||
This->mime = heap_strdupW(mime);
|
||||
CoTaskMemFree(mime);
|
||||
This->reported_mime = TRUE;
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, This->mime);
|
||||
}
|
||||
}
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
||||
return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ProtocolSinkHandler_ReportResult(IInternetProtocolSink *iface,
|
||||
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
|
||||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
|
||||
|
||||
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
|
||||
|
||||
if(This->protocol_sink)
|
||||
return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IInternetProtocolSinkVtbl InternetProtocolSinkHandlerVtbl = {
|
||||
ProtocolSinkHandler_QueryInterface,
|
||||
ProtocolSinkHandler_AddRef,
|
||||
ProtocolSinkHandler_Release,
|
||||
ProtocolSinkHandler_Switch,
|
||||
ProtocolSinkHandler_ReportProgress,
|
||||
ProtocolSinkHandler_ReportData,
|
||||
ProtocolSinkHandler_ReportResult
|
||||
};
|
||||
|
||||
static inline BindProtocol *impl_from_IInternetBindInfo(IInternetBindInfo *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BindProtocol, IInternetBindInfo_iface);
|
||||
|
@ -939,12 +1143,16 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface
|
|||
return E_OUTOFMEMORY;
|
||||
memcpy(data, pProtocolData, sizeof(PROTOCOLDATA));
|
||||
|
||||
if(!do_direct_notif(This)) {
|
||||
if((This->pi&PI_APARTMENTTHREADED && pProtocolData->grfFlags&PI_FORCE_ASYNC)
|
||||
|| !do_direct_notif(This)) {
|
||||
switch_task_t *task;
|
||||
|
||||
task = heap_alloc(sizeof(switch_task_t));
|
||||
if(!task)
|
||||
{
|
||||
heap_free(data);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
task->data = data;
|
||||
|
||||
|
@ -952,44 +1160,7 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if(!This->protocol_sink) {
|
||||
IInternetProtocol_Continue(This->protocol_handler, data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return IInternetProtocolSink_Switch(This->protocol_sink, data);
|
||||
}
|
||||
|
||||
static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text)
|
||||
{
|
||||
switch(status_code) {
|
||||
case BINDSTATUS_FINDINGRESOURCE:
|
||||
case BINDSTATUS_CONNECTING:
|
||||
case BINDSTATUS_REDIRECTING:
|
||||
case BINDSTATUS_SENDINGREQUEST:
|
||||
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
|
||||
case BINDSTATUS_DIRECTBIND:
|
||||
case BINDSTATUS_ACCEPTRANGES:
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_BEGINDOWNLOADDATA:
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_ReportData(This->protocol_sink, This->bscf, This->progress, This->progress_max);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_MIMETYPEAVAILABLE:
|
||||
mime_available(This, status_text, FALSE);
|
||||
break;
|
||||
|
||||
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
|
||||
mime_available(This, status_text, TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unsupported ulStatusCode %u\n", status_code);
|
||||
}
|
||||
return IInternetProtocolSink_Switch(This->protocol_sink_handler, data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -1003,7 +1174,7 @@ static void on_progress_proc(BindProtocol *This, task_header_t *t)
|
|||
{
|
||||
on_progress_task_t *task = (on_progress_task_t*)t;
|
||||
|
||||
report_progress(This, task->status_code, task->status_text);
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink_handler, task->status_code, task->status_text);
|
||||
|
||||
heap_free(task->status_text);
|
||||
heap_free(task);
|
||||
|
@ -1017,7 +1188,7 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSin
|
|||
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
|
||||
|
||||
if(do_direct_notif(This)) {
|
||||
report_progress(This, ulStatusCode, szStatusText);
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink_handler, ulStatusCode, szStatusText);
|
||||
}else {
|
||||
on_progress_task_t *task;
|
||||
|
||||
|
@ -1032,76 +1203,6 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSin
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max)
|
||||
{
|
||||
This->bscf = bscf;
|
||||
This->progress = progress;
|
||||
This->progress_max = progress_max;
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
||||
if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) {
|
||||
BYTE buf[BUFFER_SIZE];
|
||||
DWORD read = 0;
|
||||
LPWSTR mime;
|
||||
HRESULT hres;
|
||||
|
||||
do {
|
||||
read = 0;
|
||||
hres = IInternetProtocol_Read(This->protocol, buf,
|
||||
sizeof(buf)-This->buf_size, &read);
|
||||
if(FAILED(hres) && hres != E_PENDING)
|
||||
return hres;
|
||||
|
||||
if(!This->buf) {
|
||||
This->buf = heap_alloc(BUFFER_SIZE);
|
||||
if(!This->buf)
|
||||
return E_OUTOFMEMORY;
|
||||
}else if(read + This->buf_size > BUFFER_SIZE) {
|
||||
BYTE *tmp;
|
||||
|
||||
tmp = heap_realloc(This->buf, read+This->buf_size);
|
||||
if(!tmp)
|
||||
return E_OUTOFMEMORY;
|
||||
This->buf = tmp;
|
||||
}
|
||||
|
||||
memcpy(This->buf+This->buf_size, buf, read);
|
||||
This->buf_size += read;
|
||||
}while(This->buf_size < MIME_TEST_SIZE && hres == S_OK);
|
||||
|
||||
if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE)
|
||||
return S_OK;
|
||||
|
||||
bscf = BSCF_FIRSTDATANOTIFICATION;
|
||||
if(hres == S_FALSE)
|
||||
bscf |= BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
|
||||
|
||||
if(!This->reported_mime) {
|
||||
BSTR raw_uri;
|
||||
|
||||
hres = IUri_GetRawUri(This->uri, &raw_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = FindMimeFromData(NULL, raw_uri, This->buf, min(This->buf_size, MIME_TEST_SIZE),
|
||||
This->mime, 0, &mime, 0);
|
||||
SysFreeString(raw_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
mime_available(This, mime, TRUE);
|
||||
CoTaskMemFree(mime);
|
||||
}
|
||||
}
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
||||
return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
task_header_t header;
|
||||
DWORD bscf;
|
||||
|
@ -1113,7 +1214,9 @@ static void report_data_proc(BindProtocol *This, task_header_t *t)
|
|||
{
|
||||
report_data_task_t *task = (report_data_task_t*)t;
|
||||
|
||||
report_data(This, task->bscf, task->progress, task->progress_max);
|
||||
IInternetProtocolSink_ReportData(This->protocol_sink_handler,
|
||||
task->bscf, task->progress, task->progress_max);
|
||||
|
||||
heap_free(task);
|
||||
}
|
||||
|
||||
|
@ -1122,7 +1225,7 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *i
|
|||
{
|
||||
BindProtocol *This = impl_from_IInternetProtocolSink(iface);
|
||||
|
||||
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
|
||||
TRACE("(%p)->(%x %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
|
||||
|
||||
if(!This->protocol_sink)
|
||||
return S_OK;
|
||||
|
@ -1142,7 +1245,8 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *i
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
return report_data(This, grfBSCF, ulProgress, ulProgressMax);
|
||||
return IInternetProtocolSink_ReportData(This->protocol_sink_handler,
|
||||
grfBSCF, ulProgress, ulProgressMax);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -1157,8 +1261,7 @@ static void report_result_proc(BindProtocol *This, task_header_t *t)
|
|||
{
|
||||
report_result_task_t *task = (report_result_task_t*)t;
|
||||
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_ReportResult(This->protocol_sink, task->hres, task->err, task->str);
|
||||
IInternetProtocolSink_ReportResult(This->protocol_sink_handler, task->hres, task->err, task->str);
|
||||
|
||||
heap_free(task->str);
|
||||
heap_free(task);
|
||||
|
@ -1173,7 +1276,6 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink
|
|||
|
||||
if(!This->protocol_sink)
|
||||
return E_FAIL;
|
||||
|
||||
This->reported_result = TRUE;
|
||||
|
||||
if(!do_direct_notif(This)) {
|
||||
|
@ -1191,7 +1293,7 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
|
||||
return IInternetProtocolSink_ReportResult(This->protocol_sink_handler, hrResult, dwError, szResult);
|
||||
}
|
||||
|
||||
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
|
||||
|
@ -1307,13 +1409,16 @@ HRESULT create_binding_protocol(BOOL from_urlmon, BindProtocol **protocol)
|
|||
ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
|
||||
|
||||
ret->default_protocol_handler.IInternetProtocol_iface.lpVtbl = &InternetProtocolHandlerVtbl;
|
||||
ret->default_protocol_handler.IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkHandlerVtbl;
|
||||
|
||||
ret->ref = 1;
|
||||
ret->from_urlmon = from_urlmon;
|
||||
ret->apartment_thread = GetCurrentThreadId();
|
||||
ret->notif_hwnd = get_notif_hwnd();
|
||||
ret->protocol_handler = &ret->default_protocol_handler.IInternetProtocol_iface;
|
||||
ret->protocol_sink_handler = &ret->default_protocol_handler.IInternetProtocolSink_iface;
|
||||
InitializeCriticalSection(&ret->section);
|
||||
ret->section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BindProtocol.section");
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ typedef struct {
|
|||
IBinding *binding;
|
||||
LPWSTR file_name;
|
||||
LPWSTR cache_file;
|
||||
DWORD bindf;
|
||||
|
||||
stop_cache_binding_proc_t onstop_proc;
|
||||
void *ctx;
|
||||
} DownloadBSC;
|
||||
|
||||
static inline DownloadBSC *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
|
||||
|
@ -62,7 +66,7 @@ static HRESULT WINAPI DownloadBSC_QueryInterface(IBindStatusCallback *iface,
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IBindStatusCallback_AddRef((IUnknown*)*ppv);
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -189,6 +193,7 @@ static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface,
|
|||
HRESULT hresult, LPCWSTR szError)
|
||||
{
|
||||
DownloadBSC *This = impl_from_IBindStatusCallback(iface);
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
|
||||
|
||||
|
@ -204,7 +209,9 @@ static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface,
|
|||
}
|
||||
}
|
||||
|
||||
if(This->callback)
|
||||
if(This->onstop_proc)
|
||||
hres = This->onstop_proc(This->ctx, This->cache_file, hresult, szError);
|
||||
else if(This->callback)
|
||||
IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
|
||||
|
||||
if(This->binding) {
|
||||
|
@ -212,7 +219,7 @@ static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface,
|
|||
This->binding = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DownloadBSC_GetBindInfo(IBindStatusCallback *iface,
|
||||
|
@ -235,7 +242,7 @@ static HRESULT WINAPI DownloadBSC_GetBindInfo(IBindStatusCallback *iface,
|
|||
ReleaseBindInfo(&bindinfo);
|
||||
}
|
||||
|
||||
*grfBINDF = BINDF_PULLDATA | BINDF_NEEDFILE | (bindf & BINDF_ENFORCERESTRICTED);
|
||||
*grfBINDF = BINDF_PULLDATA | BINDF_NEEDFILE | (bindf & BINDF_ENFORCERESTRICTED) | This->bindf;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -323,39 +330,84 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
|
|||
DwlServiceProvider_QueryService
|
||||
};
|
||||
|
||||
static HRESULT DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_name, IBindStatusCallback **ret_callback)
|
||||
static HRESULT DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_name, DownloadBSC **ret_callback)
|
||||
{
|
||||
DownloadBSC *ret = heap_alloc(sizeof(*ret));
|
||||
DownloadBSC *ret;
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ret->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl;
|
||||
ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
|
||||
ret->ref = 1;
|
||||
ret->file_name = heap_strdupW(file_name);
|
||||
ret->cache_file = NULL;
|
||||
ret->binding = NULL;
|
||||
|
||||
if(file_name) {
|
||||
ret->file_name = heap_strdupW(file_name);
|
||||
if(!ret->file_name) {
|
||||
heap_free(ret);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(callback)
|
||||
IBindStatusCallback_AddRef(callback);
|
||||
ret->callback = callback;
|
||||
|
||||
*ret_callback = &ret->IBindStatusCallback_iface;
|
||||
*ret_callback = ret;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT create_default_callback(IBindStatusCallback **ret)
|
||||
{
|
||||
IBindStatusCallback *callback;
|
||||
DownloadBSC *callback;
|
||||
HRESULT hres;
|
||||
|
||||
hres = DownloadBSC_Create(NULL, NULL, &callback);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = wrap_callback(callback, ret);
|
||||
IBindStatusCallback_Release(callback);
|
||||
hres = wrap_callback(&callback->IBindStatusCallback_iface, ret);
|
||||
IBindStatusCallback_Release(&callback->IBindStatusCallback_iface);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT download_to_cache(IUri *uri, stop_cache_binding_proc_t proc, void *ctx, IBindStatusCallback *callback)
|
||||
{
|
||||
DownloadBSC *dwl_bsc;
|
||||
IBindCtx *bindctx;
|
||||
IMoniker *mon;
|
||||
IUnknown *unk;
|
||||
HRESULT hres;
|
||||
|
||||
hres = DownloadBSC_Create(callback, NULL, &dwl_bsc);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
dwl_bsc->onstop_proc = proc;
|
||||
dwl_bsc->ctx = ctx;
|
||||
dwl_bsc->bindf = BINDF_ASYNCHRONOUS;
|
||||
|
||||
hres = CreateAsyncBindCtx(0, &dwl_bsc->IBindStatusCallback_iface, NULL, &bindctx);
|
||||
IBindStatusCallback_Release(&dwl_bsc->IBindStatusCallback_iface);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = CreateURLMonikerEx2(NULL, uri, &mon, 0);
|
||||
if(FAILED(hres)) {
|
||||
IBindCtx_Release(bindctx);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = IMoniker_BindToStorage(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk);
|
||||
IMoniker_Release(mon);
|
||||
IBindCtx_Release(bindctx);
|
||||
if(SUCCEEDED(hres) && unk)
|
||||
IUnknown_Release(unk);
|
||||
return hres;
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* URLDownloadToFileW (URLMON.@)
|
||||
*
|
||||
|
@ -375,7 +427,7 @@ HRESULT create_default_callback(IBindStatusCallback **ret)
|
|||
HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, LPCWSTR szURL, LPCWSTR szFileName,
|
||||
DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB)
|
||||
{
|
||||
IBindStatusCallback *callback;
|
||||
DownloadBSC *callback;
|
||||
IUnknown *unk;
|
||||
IMoniker *mon;
|
||||
IBindCtx *bindctx;
|
||||
|
@ -390,8 +442,8 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, LPCWSTR szURL, LPCWSTR szFi
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = CreateAsyncBindCtx(0, callback, NULL, &bindctx);
|
||||
IBindStatusCallback_Release(callback);
|
||||
hres = CreateAsyncBindCtx(0, &callback->IBindStatusCallback_iface, NULL, &bindctx);
|
||||
IBindStatusCallback_Release(&callback->IBindStatusCallback_iface);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, RE
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
IInternetProtocolEx_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -245,12 +245,13 @@ static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
|
|||
DWORD grfPI, HANDLE *dwReserved)
|
||||
{
|
||||
FileProtocol *This = impl_from_IInternetProtocolEx(iface);
|
||||
WCHAR path[MAX_PATH];
|
||||
BINDINFO bindinfo;
|
||||
DWORD grfBINDF = 0;
|
||||
DWORD scheme;
|
||||
DWORD scheme, size;
|
||||
LPWSTR mime = NULL;
|
||||
WCHAR null_char = 0;
|
||||
BSTR path, url;
|
||||
BSTR url;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
|
||||
|
@ -288,14 +289,14 @@ static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
|
|||
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
|
||||
|
||||
hres = IUri_GetPath(pUri, &path);
|
||||
size = 0;
|
||||
hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0);
|
||||
if(FAILED(hres)) {
|
||||
ERR("GetPath failed: %08x\n", hres);
|
||||
WARN("CoInternetParseIUri failed: %08x\n", hres);
|
||||
return report_result(pOIProtSink, hres, 0);
|
||||
}
|
||||
|
||||
hres = open_file(This, path, pOIProtSink);
|
||||
SysFreeString(path);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REF
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
IInternetProtocolEx_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,18 +79,13 @@ static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline BOOL set_security_flag(HttpProtocol *This, DWORD new_flag)
|
||||
static inline BOOL set_security_flag(HttpProtocol *This, DWORD flags)
|
||||
{
|
||||
DWORD flags, size = sizeof(flags);
|
||||
BOOL res;
|
||||
|
||||
res = InternetQueryOptionW(This->base.request, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
|
||||
if(res) {
|
||||
flags |= new_flag;
|
||||
res = InternetSetOptionW(This->base.request, INTERNET_OPTION_SECURITY_FLAGS, &flags, size);
|
||||
}
|
||||
res = InternetSetOptionW(This->base.request, INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
|
||||
if(!res)
|
||||
ERR("Failed to set security flag(s): %x\n", new_flag);
|
||||
ERR("Failed to set security flags: %x\n", flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -103,6 +98,11 @@ static inline HRESULT internet_error_to_hres(DWORD error)
|
|||
case ERROR_INTERNET_SEC_CERT_CN_INVALID:
|
||||
case ERROR_INTERNET_INVALID_CA:
|
||||
case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
|
||||
case ERROR_INTERNET_SEC_INVALID_CERT:
|
||||
case ERROR_INTERNET_SEC_CERT_ERRORS:
|
||||
case ERROR_INTERNET_SEC_CERT_REV_FAILED:
|
||||
case ERROR_INTERNET_SEC_CERT_NO_REV:
|
||||
case ERROR_INTERNET_SEC_CERT_REVOKED:
|
||||
return INET_E_INVALID_CERTIFICATE;
|
||||
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
|
||||
case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
|
||||
|
@ -119,16 +119,26 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
|
|||
IWindowForBindingUI *wfb_ui;
|
||||
IHttpSecurity *http_security;
|
||||
BOOL security_problem;
|
||||
DWORD dlg_flags;
|
||||
HWND hwnd;
|
||||
DWORD res;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %u)\n", This, error);
|
||||
|
||||
switch(error) {
|
||||
case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
|
||||
case ERROR_INTERNET_SEC_CERT_CN_INVALID:
|
||||
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
|
||||
case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
|
||||
case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
|
||||
case ERROR_INTERNET_INVALID_CA:
|
||||
case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
|
||||
case ERROR_INTERNET_SEC_INVALID_CERT:
|
||||
case ERROR_INTERNET_SEC_CERT_ERRORS:
|
||||
case ERROR_INTERNET_SEC_CERT_REV_FAILED:
|
||||
case ERROR_INTERNET_SEC_CERT_NO_REV:
|
||||
case ERROR_INTERNET_SEC_CERT_REVOKED:
|
||||
case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
|
||||
security_problem = TRUE;
|
||||
break;
|
||||
default:
|
||||
|
@ -149,6 +159,8 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
|
|||
hres = IHttpSecurity_OnSecurityProblem(http_security, error);
|
||||
IHttpSecurity_Release(http_security);
|
||||
|
||||
TRACE("OnSecurityProblem returned %08x\n", hres);
|
||||
|
||||
if(hres != S_FALSE)
|
||||
{
|
||||
BOOL res = FALSE;
|
||||
|
@ -180,42 +192,43 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
|
|||
}
|
||||
}
|
||||
|
||||
hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI,
|
||||
(void**)&wfb_ui);
|
||||
if(SUCCEEDED(hres)) {
|
||||
HWND hwnd;
|
||||
const IID *iid_reason;
|
||||
|
||||
if(security_problem)
|
||||
iid_reason = &IID_IHttpSecurity;
|
||||
else if(error == ERROR_INTERNET_INCORRECT_PASSWORD)
|
||||
iid_reason = &IID_IAuthenticate;
|
||||
else
|
||||
iid_reason = &IID_IWindowForBindingUI;
|
||||
|
||||
hres = IWindowForBindingUI_GetWindow(wfb_ui, iid_reason, &hwnd);
|
||||
if(SUCCEEDED(hres) && hwnd)
|
||||
{
|
||||
DWORD res;
|
||||
|
||||
res = InternetErrorDlg(hwnd, This->base.request, error,
|
||||
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
|
||||
NULL);
|
||||
|
||||
if(res == ERROR_INTERNET_FORCE_RETRY || res == ERROR_SUCCESS)
|
||||
hres = RPC_E_RETRY;
|
||||
else
|
||||
hres = E_FAIL;
|
||||
switch(error) {
|
||||
case ERROR_INTERNET_SEC_CERT_REV_FAILED:
|
||||
if(hres != S_FALSE) {
|
||||
/* Silently ignore the error. We will get more detailed error from wininet anyway. */
|
||||
set_security_flag(This, SECURITY_FLAG_IGNORE_REVOCATION);
|
||||
hres = RPC_E_RETRY;
|
||||
break;
|
||||
}
|
||||
IWindowForBindingUI_Release(wfb_ui);
|
||||
/* fallthrough */
|
||||
default:
|
||||
hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI, (void**)&wfb_ui);
|
||||
if(SUCCEEDED(hres)) {
|
||||
const IID *iid_reason;
|
||||
|
||||
if(security_problem)
|
||||
iid_reason = &IID_IHttpSecurity;
|
||||
else if(error == ERROR_INTERNET_INCORRECT_PASSWORD)
|
||||
iid_reason = &IID_IAuthenticate;
|
||||
else
|
||||
iid_reason = &IID_IWindowForBindingUI;
|
||||
|
||||
hres = IWindowForBindingUI_GetWindow(wfb_ui, iid_reason, &hwnd);
|
||||
IWindowForBindingUI_Release(wfb_ui);
|
||||
}
|
||||
|
||||
if(FAILED(hres)) hwnd = NULL;
|
||||
|
||||
dlg_flags = FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA;
|
||||
if(This->base.bindf & BINDF_NO_UI)
|
||||
dlg_flags |= FLAGS_ERROR_UI_FLAGS_NO_UI;
|
||||
|
||||
res = InternetErrorDlg(hwnd, This->base.request, error, dlg_flags, NULL);
|
||||
hres = res == ERROR_INTERNET_FORCE_RETRY || res == ERROR_SUCCESS ? RPC_E_RETRY : internet_error_to_hres(error);
|
||||
}
|
||||
|
||||
IServiceProvider_Release(serv_prov);
|
||||
|
||||
if(hres == RPC_E_RETRY)
|
||||
return hres;
|
||||
|
||||
return internet_error_to_hres(error);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static ULONG send_http_request(HttpProtocol *This)
|
||||
|
@ -276,7 +289,7 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
|
|||
LPOLESTR accept_mimes[257];
|
||||
const WCHAR **accept_types;
|
||||
BYTE security_id[512];
|
||||
DWORD len, port;
|
||||
DWORD len, port, flags;
|
||||
ULONG num, error;
|
||||
BOOL res, b;
|
||||
HRESULT hres;
|
||||
|
@ -419,19 +432,31 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
|
|||
}
|
||||
}
|
||||
|
||||
flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT;
|
||||
res = InternetSetOptionW(This->base.request, INTERNET_OPTION_ERROR_MASK, &flags, sizeof(flags));
|
||||
if(!res)
|
||||
WARN("InternetSetOption(INTERNET_OPTION_ERROR_MASK) failed: %u\n", GetLastError());
|
||||
|
||||
b = TRUE;
|
||||
res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
|
||||
if(!res)
|
||||
WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x\n", GetLastError());
|
||||
WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %u\n", GetLastError());
|
||||
|
||||
do {
|
||||
error = send_http_request(This);
|
||||
|
||||
if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS)
|
||||
switch(error) {
|
||||
case ERROR_IO_PENDING:
|
||||
return S_OK;
|
||||
|
||||
hres = handle_http_error(This, error);
|
||||
|
||||
case ERROR_SUCCESS:
|
||||
/*
|
||||
* If sending response ended synchronously, it means that we have the whole data
|
||||
* available locally (most likely in cache).
|
||||
*/
|
||||
return protocol_syncbinding(&This->base);
|
||||
default:
|
||||
hres = handle_http_error(This, error);
|
||||
}
|
||||
} while(hres == RPC_E_RETRY);
|
||||
|
||||
WARN("HttpSendRequest failed: %d\n", error);
|
||||
|
@ -528,10 +553,8 @@ static void HttpProtocol_close_connection(Protocol *prot)
|
|||
This->http_negotiate = NULL;
|
||||
}
|
||||
|
||||
if(This->full_header) {
|
||||
heap_free(This->full_header);
|
||||
This->full_header = NULL;
|
||||
}
|
||||
heap_free(This->full_header);
|
||||
This->full_header = NULL;
|
||||
}
|
||||
|
||||
static void HttpProtocol_on_error(Protocol *prot, DWORD error)
|
||||
|
@ -595,7 +618,7 @@ static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, RE
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
IInternetProtocolEx_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -549,39 +549,34 @@ static HRESULT set_internet_feature(INTERNETFEATURELIST feature, DWORD flags, BO
|
|||
|
||||
static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPCWSTR process_name, BOOL *enabled)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
DWORD type, value, size;
|
||||
HKEY feature;
|
||||
DWORD res;
|
||||
|
||||
static const WCHAR wildcardW[] = {'*',0};
|
||||
|
||||
res = RegOpenKeyW(feature_control, feature_name, &feature);
|
||||
if(res == ERROR_SUCCESS) {
|
||||
DWORD type, value, size;
|
||||
if(res != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
|
||||
if(res != ERROR_SUCCESS || type != REG_DWORD) {
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
|
||||
if(type != REG_DWORD)
|
||||
WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(process_name));
|
||||
|
||||
if(res == ERROR_SUCCESS && type == REG_DWORD) {
|
||||
*enabled = value == 1;
|
||||
ret = TRUE;
|
||||
} else {
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(feature, wildcardW, NULL, &type, (BYTE*)&value, &size);
|
||||
if(type != REG_DWORD)
|
||||
WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(wildcardW));
|
||||
|
||||
if(res == ERROR_SUCCESS && type == REG_DWORD) {
|
||||
*enabled = value == 1;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
RegCloseKey(feature);
|
||||
res = RegQueryValueExW(feature, wildcardW, NULL, &type, (BYTE*)&value, &size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
RegCloseKey(feature);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if(type != REG_DWORD) {
|
||||
WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(wildcardW));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*enabled = value == 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Assumes 'process_features_cs' is held. */
|
||||
|
@ -698,3 +693,102 @@ HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWOR
|
|||
TRACE("(%d, %08x)\n", FeatureEntry, dwFlags);
|
||||
return get_internet_feature(FeatureEntry, dwFlags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoInternetIsFeatureEnabledForUrl (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CoInternetIsFeatureEnabledForUrl(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, LPCWSTR szURL,
|
||||
IInternetSecurityManager *pSecMgr)
|
||||
{
|
||||
DWORD urlaction = 0;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%d %08x %s %p)\n", FeatureEntry, dwFlags, debugstr_w(szURL), pSecMgr);
|
||||
|
||||
if(FeatureEntry == FEATURE_MIME_SNIFFING)
|
||||
urlaction = URLACTION_FEATURE_MIME_SNIFFING;
|
||||
else if(FeatureEntry == FEATURE_WINDOW_RESTRICTIONS)
|
||||
urlaction = URLACTION_FEATURE_WINDOW_RESTRICTIONS;
|
||||
else if(FeatureEntry == FEATURE_ZONE_ELEVATION)
|
||||
urlaction = URLACTION_FEATURE_ZONE_ELEVATION;
|
||||
|
||||
if(!szURL || !urlaction || !pSecMgr)
|
||||
return CoInternetIsFeatureEnabled(FeatureEntry, dwFlags);
|
||||
|
||||
switch(dwFlags) {
|
||||
case GET_FEATURE_FROM_THREAD:
|
||||
case GET_FEATURE_FROM_THREAD_LOCALMACHINE:
|
||||
case GET_FEATURE_FROM_THREAD_INTRANET:
|
||||
case GET_FEATURE_FROM_THREAD_TRUSTED:
|
||||
case GET_FEATURE_FROM_THREAD_INTERNET:
|
||||
case GET_FEATURE_FROM_THREAD_RESTRICTED:
|
||||
FIXME("unsupported flags %x\n", dwFlags);
|
||||
return E_NOTIMPL;
|
||||
|
||||
case GET_FEATURE_FROM_PROCESS:
|
||||
hres = CoInternetIsFeatureEnabled(FeatureEntry, dwFlags);
|
||||
if(hres != S_OK)
|
||||
return hres;
|
||||
/* fall through */
|
||||
|
||||
default: {
|
||||
DWORD policy = URLPOLICY_DISALLOW;
|
||||
|
||||
hres = IInternetSecurityManager_ProcessUrlAction(pSecMgr, szURL, urlaction,
|
||||
(BYTE*)&policy, sizeof(DWORD), NULL, 0, PUAF_NOUI, 0);
|
||||
if(hres!=S_OK || policy!=URLPOLICY_ALLOW)
|
||||
return S_OK;
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoInternetIsFeatureZoneElevationEnabled (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CoInternetIsFeatureZoneElevationEnabled(LPCWSTR szFromURL, LPCWSTR szToURL,
|
||||
IInternetSecurityManager *pSecMgr, DWORD dwFlags)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %s %p %x)\n", debugstr_w(szFromURL), debugstr_w(szToURL), pSecMgr, dwFlags);
|
||||
|
||||
if(!pSecMgr || !szToURL)
|
||||
return CoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, dwFlags);
|
||||
|
||||
switch(dwFlags) {
|
||||
case GET_FEATURE_FROM_THREAD:
|
||||
case GET_FEATURE_FROM_THREAD_LOCALMACHINE:
|
||||
case GET_FEATURE_FROM_THREAD_INTRANET:
|
||||
case GET_FEATURE_FROM_THREAD_TRUSTED:
|
||||
case GET_FEATURE_FROM_THREAD_INTERNET:
|
||||
case GET_FEATURE_FROM_THREAD_RESTRICTED:
|
||||
FIXME("unsupported flags %x\n", dwFlags);
|
||||
return E_NOTIMPL;
|
||||
|
||||
case GET_FEATURE_FROM_PROCESS:
|
||||
hres = CoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, dwFlags);
|
||||
if(hres != S_OK)
|
||||
return hres;
|
||||
/* fall through */
|
||||
|
||||
default: {
|
||||
DWORD policy = URLPOLICY_DISALLOW;
|
||||
|
||||
hres = IInternetSecurityManager_ProcessUrlAction(pSecMgr, szToURL,
|
||||
URLACTION_FEATURE_ZONE_ELEVATION, (BYTE*)&policy, sizeof(DWORD),
|
||||
NULL, 0, PUAF_NOUI, 0);
|
||||
if(FAILED(hres))
|
||||
return S_OK;
|
||||
|
||||
switch(policy) {
|
||||
case URLPOLICY_ALLOW:
|
||||
return S_FALSE;
|
||||
case URLPOLICY_QUERY:
|
||||
FIXME("Ask user dialog not implemented\n");
|
||||
default:
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFI
|
|||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
IInternetProtocolEx_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,55 @@ static void all_data_read(Protocol *protocol)
|
|||
report_result(protocol, S_OK);
|
||||
}
|
||||
|
||||
static HRESULT start_downloading(Protocol *protocol)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = protocol->vtbl->start_downloading(protocol);
|
||||
if(FAILED(hres)) {
|
||||
protocol_close_connection(protocol);
|
||||
report_result(protocol, hres);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(protocol->bindf & BINDF_NEEDFILE) {
|
||||
WCHAR cache_file[MAX_PATH];
|
||||
DWORD buflen = sizeof(cache_file);
|
||||
|
||||
if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) {
|
||||
report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file);
|
||||
}else {
|
||||
FIXME("Could not get cache file\n");
|
||||
}
|
||||
}
|
||||
|
||||
protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT protocol_syncbinding(Protocol *protocol)
|
||||
{
|
||||
BOOL res;
|
||||
HRESULT hres;
|
||||
|
||||
protocol->flags |= FLAG_SYNC_READ;
|
||||
|
||||
hres = start_downloading(protocol);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0);
|
||||
if(res)
|
||||
protocol->available_bytes = protocol->query_available;
|
||||
else
|
||||
WARN("InternetQueryDataAvailable failed: %u\n", GetLastError());
|
||||
|
||||
protocol->flags |= FLAG_FIRST_DATA_REPORTED|FLAG_LAST_DATA_REPORTED;
|
||||
IInternetProtocolSink_ReportData(protocol->protocol_sink, BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE,
|
||||
protocol->available_bytes, protocol->content_length);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void request_complete(Protocol *protocol, INTERNET_ASYNC_RESULT *ar)
|
||||
{
|
||||
PROTOCOLDATA data;
|
||||
|
@ -89,13 +138,13 @@ static void request_complete(Protocol *protocol, INTERNET_ASYNC_RESULT *ar)
|
|||
}
|
||||
|
||||
if(protocol->flags & FLAG_FIRST_CONTINUE_COMPLETE)
|
||||
data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
|
||||
data.pData = UlongToPtr(BINDSTATUS_ENDDOWNLOADCOMPONENTS);
|
||||
else
|
||||
data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
|
||||
data.pData = UlongToPtr(BINDSTATUS_DOWNLOADINGDATA);
|
||||
|
||||
}else {
|
||||
protocol->flags |= FLAG_ERROR;
|
||||
data.pData = (LPVOID)ar->dwError;
|
||||
data.pData = UlongToPtr(ar->dwError);
|
||||
}
|
||||
|
||||
if (protocol->bindf & BINDF_FROMURLMON)
|
||||
|
@ -115,10 +164,19 @@ static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR contex
|
|||
report_progress(protocol, BINDSTATUS_FINDINGRESOURCE, (LPWSTR)status_info);
|
||||
break;
|
||||
|
||||
case INTERNET_STATUS_CONNECTING_TO_SERVER:
|
||||
TRACE("%p INTERNET_STATUS_CONNECTING_TO_SERVER\n", protocol);
|
||||
report_progress(protocol, BINDSTATUS_CONNECTING, (LPWSTR)status_info);
|
||||
case INTERNET_STATUS_CONNECTING_TO_SERVER: {
|
||||
WCHAR *info;
|
||||
|
||||
TRACE("%p INTERNET_STATUS_CONNECTING_TO_SERVER %s\n", protocol, (const char*)status_info);
|
||||
|
||||
info = heap_strdupAtoW(status_info);
|
||||
if(!info)
|
||||
return;
|
||||
|
||||
report_progress(protocol, BINDSTATUS_CONNECTING, info);
|
||||
heap_free(info);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERNET_STATUS_SENDING_REQUEST:
|
||||
TRACE("%p INTERNET_STATUS_SENDING_REQUEST\n", protocol);
|
||||
|
@ -286,12 +344,10 @@ HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, IUri *uri,
|
|||
|
||||
HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
|
||||
{
|
||||
BOOL is_start;
|
||||
HRESULT hres;
|
||||
|
||||
if (!data) {
|
||||
WARN("Expected pProtocolData to be non-NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
is_start = !data || data->pData == UlongToPtr(BINDSTATUS_DOWNLOADINGDATA);
|
||||
|
||||
if(!protocol->request) {
|
||||
WARN("Expected request to be non-NULL\n");
|
||||
|
@ -305,52 +361,56 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
|
|||
|
||||
if(protocol->flags & FLAG_ERROR) {
|
||||
protocol->flags &= ~FLAG_ERROR;
|
||||
protocol->vtbl->on_error(protocol, (DWORD)data->pData);
|
||||
protocol->vtbl->on_error(protocol, PtrToUlong(data->pData));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(protocol->post_stream)
|
||||
return write_post_stream(protocol);
|
||||
|
||||
if(data->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA) {
|
||||
hres = protocol->vtbl->start_downloading(protocol);
|
||||
if(FAILED(hres)) {
|
||||
protocol_close_connection(protocol);
|
||||
report_result(protocol, hres);
|
||||
if(is_start) {
|
||||
hres = start_downloading(protocol);
|
||||
if(FAILED(hres))
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(protocol->bindf & BINDF_NEEDFILE) {
|
||||
WCHAR cache_file[MAX_PATH];
|
||||
DWORD buflen = sizeof(cache_file);
|
||||
|
||||
if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME,
|
||||
cache_file, &buflen)) {
|
||||
report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file);
|
||||
}else {
|
||||
FIXME("Could not get cache file\n");
|
||||
}
|
||||
}
|
||||
|
||||
protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
|
||||
}
|
||||
|
||||
if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA && !protocol->available_bytes) {
|
||||
BOOL res;
|
||||
if(!data || data->pData >= UlongToPtr(BINDSTATUS_DOWNLOADINGDATA)) {
|
||||
if(!protocol->available_bytes) {
|
||||
if(protocol->query_available) {
|
||||
protocol->available_bytes = protocol->query_available;
|
||||
}else {
|
||||
BOOL res;
|
||||
|
||||
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
|
||||
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
|
||||
* after the status callback is called */
|
||||
protocol->flags &= ~FLAG_REQUEST_COMPLETE;
|
||||
res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0);
|
||||
if(res) {
|
||||
TRACE("available %u bytes\n", protocol->query_available);
|
||||
if(!protocol->query_available) {
|
||||
if(is_start) {
|
||||
TRACE("empty file\n");
|
||||
all_data_read(protocol);
|
||||
}else {
|
||||
WARN("unexpected end of file?\n");
|
||||
report_result(protocol, INET_E_DOWNLOAD_FAILURE);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
protocol->available_bytes = protocol->query_available;
|
||||
}else if(GetLastError() != ERROR_IO_PENDING) {
|
||||
protocol->flags |= FLAG_REQUEST_COMPLETE;
|
||||
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
|
||||
report_result(protocol, INET_E_DATA_NOT_AVAILABLE);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
|
||||
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
|
||||
* after the status callback is called */
|
||||
protocol->flags &= ~FLAG_REQUEST_COMPLETE;
|
||||
res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0);
|
||||
if(res) {
|
||||
protocol->flags |= FLAG_REQUEST_COMPLETE;
|
||||
report_data(protocol);
|
||||
}else if(GetLastError() != ERROR_IO_PENDING) {
|
||||
protocol->flags |= FLAG_REQUEST_COMPLETE;
|
||||
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
|
||||
report_result(protocol, INET_E_DATA_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
report_data(protocol);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -367,7 +427,7 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
if(!(protocol->flags & FLAG_REQUEST_COMPLETE) || !protocol->available_bytes) {
|
||||
if(!(protocol->flags & FLAG_SYNC_READ) && (!(protocol->flags & FLAG_REQUEST_COMPLETE) || !protocol->available_bytes)) {
|
||||
*read_ret = 0;
|
||||
return E_PENDING;
|
||||
}
|
||||
|
@ -393,12 +453,14 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
|
|||
protocol->current_position += len;
|
||||
protocol->available_bytes -= len;
|
||||
|
||||
TRACE("current_position %d, available_bytes %d\n", protocol->current_position, protocol->available_bytes);
|
||||
|
||||
if(!protocol->available_bytes) {
|
||||
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
|
||||
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
|
||||
* after the status callback is called */
|
||||
protocol->flags &= ~FLAG_REQUEST_COMPLETE;
|
||||
res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0);
|
||||
res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0);
|
||||
if(!res) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
hres = E_PENDING;
|
||||
|
@ -410,10 +472,12 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
|
|||
break;
|
||||
}
|
||||
|
||||
if(!protocol->available_bytes) {
|
||||
if(!protocol->query_available) {
|
||||
all_data_read(protocol);
|
||||
break;
|
||||
}
|
||||
|
||||
protocol->available_bytes = protocol->query_available;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
26
reactos/dll/win32/urlmon/resource.h
Normal file
26
reactos/dll/win32/urlmon/resource.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2012 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define ID_AXINSTALL_WARNING_DLG 1000
|
||||
#define ID_AXINSTALL_LOCATION 1001
|
||||
#define ID_AXINSTALL_INSTALL_BTN 1002
|
||||
#define ID_AXINSTALL_ICON 1003
|
||||
|
||||
#define IDS_AXINSTALL_FAILURE 1100
|
||||
#define IDS_AXINSTALL_INSTALLN 1101
|
||||
#define IDS_AXINSTALL_INSTALL 1102
|
|
@ -57,6 +57,20 @@ static const WCHAR wszZoneMapDomainsKey[] = {'S','o','f','t','w','a','r','e','\\
|
|||
'Z','o','n','e','M','a','p','\\',
|
||||
'D','o','m','a','i','n','s',0};
|
||||
|
||||
static inline BOOL is_drive_path(const WCHAR *path)
|
||||
{
|
||||
return isalphaW(*path) && *(path+1) == ':';
|
||||
}
|
||||
|
||||
/* List of schemes types Windows seems to expect to be hierarchical. */
|
||||
static inline BOOL is_hierarchical_scheme(URL_SCHEME type) {
|
||||
return(type == URL_SCHEME_HTTP || type == URL_SCHEME_FTP ||
|
||||
type == URL_SCHEME_GOPHER || type == URL_SCHEME_NNTP ||
|
||||
type == URL_SCHEME_TELNET || type == URL_SCHEME_WAIS ||
|
||||
type == URL_SCHEME_FILE || type == URL_SCHEME_HTTPS ||
|
||||
type == URL_SCHEME_RES);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* get_string_from_reg [internal]
|
||||
*
|
||||
|
@ -256,18 +270,24 @@ static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone)
|
|||
|
||||
/* See if the key contains a value for the scheme first. */
|
||||
res = RegQueryValueExW(key, schema, NULL, &type, (BYTE*)zone, &size);
|
||||
if(type != REG_DWORD)
|
||||
if(res == ERROR_SUCCESS) {
|
||||
if(type == REG_DWORD)
|
||||
return TRUE;
|
||||
WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(schema));
|
||||
|
||||
if(res != ERROR_SUCCESS || type != REG_DWORD) {
|
||||
/* Try to get the zone for the wildcard scheme. */
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size);
|
||||
if(type != REG_DWORD)
|
||||
WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW));
|
||||
}
|
||||
|
||||
return res == ERROR_SUCCESS && type == REG_DWORD;
|
||||
/* Try to get the zone for the wildcard scheme. */
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if(type != REG_DWORD) {
|
||||
WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -433,50 +453,51 @@ static HRESULT search_for_domain_mapping(HKEY domains, LPCWSTR schema, LPCWSTR h
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT get_zone_from_domains(LPCWSTR url, LPCWSTR schema, DWORD *zone)
|
||||
static HRESULT get_zone_from_domains(IUri *uri, DWORD *zone)
|
||||
{
|
||||
HRESULT hres;
|
||||
WCHAR *host_name;
|
||||
DWORD host_len = lstrlenW(url)+1;
|
||||
BSTR host, scheme;
|
||||
DWORD res;
|
||||
HKEY domains;
|
||||
DWORD scheme_type;
|
||||
|
||||
host_name = heap_alloc(host_len*sizeof(WCHAR));
|
||||
if(!host_name)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len, &host_len, 0);
|
||||
if(hres == S_FALSE) {
|
||||
WCHAR *tmp = heap_realloc(host_name, (host_len+1)*sizeof(WCHAR));
|
||||
if(!tmp) {
|
||||
heap_free(host_name);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
host_name = tmp;
|
||||
hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len+1, &host_len, 0);
|
||||
}
|
||||
hres = IUri_GetScheme(uri, &scheme_type);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
/* Windows doesn't play nice with unknown scheme types when it tries
|
||||
* to check if a host name maps into any domains.
|
||||
*
|
||||
* The reason is with how CoInternetParseUrl handles unknown scheme types
|
||||
* when it's parsing the domain of a URL (IE it always returns E_FAIL).
|
||||
*
|
||||
* Windows doesn't compenstate for this and simply doesn't check if
|
||||
* the URL maps into any domains.
|
||||
*/
|
||||
if(hres != S_OK) {
|
||||
heap_free(host_name);
|
||||
if(hres == E_FAIL)
|
||||
return S_FALSE;
|
||||
if(scheme_type == URL_SCHEME_UNKNOWN)
|
||||
return S_FALSE;
|
||||
|
||||
hres = IUri_GetHost(uri, &host);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
/* Known hierarchical scheme types must have a host. If they don't Windows
|
||||
* assigns URLZONE_INVALID to the zone.
|
||||
*/
|
||||
if((scheme_type != URL_SCHEME_UNKNOWN && scheme_type != URL_SCHEME_FILE)
|
||||
&& is_hierarchical_scheme(scheme_type) && !*host) {
|
||||
*zone = URLZONE_INVALID;
|
||||
|
||||
SysFreeString(host);
|
||||
|
||||
/* The MapUrlToZone functions return S_OK when this condition occurs. */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = IUri_GetSchemeName(uri, &scheme);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(host);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* First try CURRENT_USER. */
|
||||
res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapDomainsKey, &domains);
|
||||
if(res == ERROR_SUCCESS) {
|
||||
hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone);
|
||||
hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone);
|
||||
RegCloseKey(domains);
|
||||
} else
|
||||
WARN("Failed to open HKCU's %s key\n", debugstr_w(wszZoneMapDomainsKey));
|
||||
|
@ -485,55 +506,48 @@ static HRESULT get_zone_from_domains(LPCWSTR url, LPCWSTR schema, DWORD *zone)
|
|||
if(hres == S_FALSE) {
|
||||
res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapDomainsKey, &domains);
|
||||
if(res == ERROR_SUCCESS) {
|
||||
hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone);
|
||||
hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone);
|
||||
RegCloseKey(domains);
|
||||
} else
|
||||
WARN("Failed to open HKLM's %s key\n", debugstr_w(wszZoneMapDomainsKey));
|
||||
}
|
||||
|
||||
heap_free(host_name);
|
||||
SysFreeString(host);
|
||||
SysFreeString(scheme);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
|
||||
static HRESULT map_security_uri_to_zone(IUri *uri, DWORD *zone)
|
||||
{
|
||||
LPWSTR secur_url;
|
||||
WCHAR schema[64];
|
||||
DWORD size=0;
|
||||
HRESULT hres;
|
||||
BSTR scheme;
|
||||
|
||||
*zone = URLZONE_INVALID;
|
||||
|
||||
hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
|
||||
if(hres != S_OK) {
|
||||
size = strlenW(url)*sizeof(WCHAR);
|
||||
hres = IUri_GetSchemeName(uri, &scheme);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
secur_url = heap_alloc(size);
|
||||
if(!secur_url)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!strcmpiW(scheme, fileW)) {
|
||||
BSTR path;
|
||||
WCHAR *ptr, *path_start, root[20];
|
||||
|
||||
memcpy(secur_url, url, size);
|
||||
}
|
||||
hres = IUri_GetPath(uri, &path);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(scheme);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = CoInternetParseUrl(secur_url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0);
|
||||
if(FAILED(hres) || !*schema) {
|
||||
heap_free(secur_url);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if(*path == '/' && is_drive_path(path+1))
|
||||
path_start = path+1;
|
||||
else
|
||||
path_start = path;
|
||||
|
||||
/* file protocol is a special case */
|
||||
if(!strcmpW(schema, fileW)) {
|
||||
WCHAR path[MAX_PATH], root[20];
|
||||
WCHAR *ptr;
|
||||
|
||||
hres = CoInternetParseUrl(secur_url, PARSE_PATH_FROM_URL, 0, path,
|
||||
sizeof(path)/sizeof(WCHAR), &size, 0);
|
||||
|
||||
if(SUCCEEDED(hres) && (ptr = strchrW(path, '\\')) && ptr-path < sizeof(root)/sizeof(WCHAR)) {
|
||||
if((ptr = strchrW(path_start, ':')) && ptr-path_start+1 < sizeof(root)/sizeof(WCHAR)) {
|
||||
UINT type;
|
||||
|
||||
memcpy(root, path, (ptr-path)*sizeof(WCHAR));
|
||||
root[ptr-path] = 0;
|
||||
memcpy(root, path_start, (ptr-path_start+1)*sizeof(WCHAR));
|
||||
root[ptr-path_start+1] = 0;
|
||||
|
||||
type = GetDriveTypeW(root);
|
||||
|
||||
|
@ -556,22 +570,73 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
|
|||
FIXME("unsupported drive type %d\n", type);
|
||||
}
|
||||
}
|
||||
SysFreeString(path);
|
||||
}
|
||||
|
||||
if(*zone == URLZONE_INVALID) {
|
||||
hres = get_zone_from_domains(secur_url, schema, zone);
|
||||
hres = get_zone_from_domains(uri, zone);
|
||||
if(hres == S_FALSE)
|
||||
hres = get_zone_from_reg(schema, zone);
|
||||
hres = get_zone_from_reg(scheme, zone);
|
||||
}
|
||||
|
||||
SysFreeString(scheme);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
|
||||
{
|
||||
IUri *secur_uri;
|
||||
LPWSTR secur_url;
|
||||
HRESULT hres;
|
||||
|
||||
*zone = URLZONE_INVALID;
|
||||
|
||||
hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
|
||||
if(hres != S_OK) {
|
||||
DWORD size = strlenW(url)*sizeof(WCHAR);
|
||||
|
||||
secur_url = CoTaskMemAlloc(size);
|
||||
if(!secur_url)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(secur_url, url, size);
|
||||
}
|
||||
|
||||
hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &secur_uri);
|
||||
if(FAILED(hres)) {
|
||||
CoTaskMemFree(secur_url);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = map_security_uri_to_zone(secur_uri, zone);
|
||||
IUri_Release(secur_uri);
|
||||
|
||||
if(FAILED(hres) || !ret_url)
|
||||
heap_free(secur_url);
|
||||
CoTaskMemFree(secur_url);
|
||||
else
|
||||
*ret_url = secur_url;
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT map_uri_to_zone(IUri *uri, DWORD *zone, IUri **ret_uri)
|
||||
{
|
||||
HRESULT hres;
|
||||
IUri *secur_uri;
|
||||
|
||||
hres = CoInternetGetSecurityUrlEx(uri, &secur_uri, PSU_SECURITY_URL_ONLY, 0);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = map_security_uri_to_zone(secur_uri, zone);
|
||||
if(FAILED(hres) || !ret_uri)
|
||||
IUri_Release(secur_uri);
|
||||
else
|
||||
*ret_uri = secur_uri;
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
|
||||
{
|
||||
static const WCHAR wszFormat[] = {'%','s','%','u',0};
|
||||
|
@ -646,12 +711,133 @@ static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD s
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT generate_security_id(IUri *uri, BYTE *secid, DWORD *secid_len, DWORD zone)
|
||||
{
|
||||
DWORD len;
|
||||
HRESULT hres;
|
||||
DWORD scheme_type;
|
||||
|
||||
if(zone == URLZONE_INVALID)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hres = IUri_GetScheme(uri, &scheme_type);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
/* Windows handles opaque URLs differently then hierarchical ones. */
|
||||
if(!is_hierarchical_scheme(scheme_type) && scheme_type != URL_SCHEME_WILDCARD) {
|
||||
BSTR display_uri;
|
||||
|
||||
hres = IUri_GetDisplayUri(uri, &display_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
len = WideCharToMultiByte(CP_ACP, 0, display_uri, -1, NULL, 0, NULL, NULL)-1;
|
||||
|
||||
if(len+sizeof(DWORD) > *secid_len) {
|
||||
SysFreeString(display_uri);
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, display_uri, -1, (LPSTR)secid, len, NULL, NULL);
|
||||
SysFreeString(display_uri);
|
||||
|
||||
*(DWORD*)(secid+len) = zone;
|
||||
} else {
|
||||
BSTR host, scheme;
|
||||
DWORD host_len, scheme_len;
|
||||
BYTE *ptr;
|
||||
|
||||
hres = IUri_GetHost(uri, &host);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
/* The host can't be empty for Wildcard URIs. */
|
||||
if(scheme_type == URL_SCHEME_WILDCARD && !*host) {
|
||||
SysFreeString(host);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hres = IUri_GetSchemeName(uri, &scheme);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(host);
|
||||
return hres;
|
||||
}
|
||||
|
||||
host_len = WideCharToMultiByte(CP_ACP, 0, host, -1, NULL, 0, NULL, NULL)-1;
|
||||
scheme_len = WideCharToMultiByte(CP_ACP, 0, scheme, -1, NULL, 0, NULL, NULL)-1;
|
||||
|
||||
len = host_len+scheme_len+sizeof(BYTE);
|
||||
|
||||
if(len+sizeof(DWORD) > *secid_len) {
|
||||
SysFreeString(host);
|
||||
SysFreeString(scheme);
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, scheme, -1, (LPSTR)secid, len, NULL, NULL);
|
||||
SysFreeString(scheme);
|
||||
|
||||
ptr = secid+scheme_len;
|
||||
*ptr++ = ':';
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, host, -1, (LPSTR)ptr, host_len, NULL, NULL);
|
||||
SysFreeString(host);
|
||||
|
||||
ptr += host_len;
|
||||
|
||||
*(DWORD*)ptr = zone;
|
||||
}
|
||||
|
||||
*secid_len = len+sizeof(DWORD);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT get_security_id_for_url(LPCWSTR url, BYTE *secid, DWORD *secid_len)
|
||||
{
|
||||
HRESULT hres;
|
||||
DWORD zone = URLZONE_INVALID;
|
||||
LPWSTR secur_url = NULL;
|
||||
IUri *uri;
|
||||
|
||||
hres = map_url_to_zone(url, &zone, &secur_url);
|
||||
if(FAILED(hres))
|
||||
return hres == 0x80041001 ? E_INVALIDARG : hres;
|
||||
|
||||
hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &uri);
|
||||
CoTaskMemFree(secur_url);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = generate_security_id(uri, secid, secid_len, zone);
|
||||
IUri_Release(uri);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT get_security_id_for_uri(IUri *uri, BYTE *secid, DWORD *secid_len)
|
||||
{
|
||||
HRESULT hres;
|
||||
IUri *secur_uri;
|
||||
DWORD zone = URLZONE_INVALID;
|
||||
|
||||
hres = map_uri_to_zone(uri, &zone, &secur_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = generate_security_id(secur_uri, secid, secid_len, zone);
|
||||
IUri_Release(secur_uri);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* InternetSecurityManager implementation
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
IInternetSecurityManager IInternetSecurityManager_iface;
|
||||
IInternetSecurityManagerEx2 IInternetSecurityManagerEx2_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
|
@ -659,44 +845,38 @@ typedef struct {
|
|||
IInternetSecurityManager *custom_manager;
|
||||
} SecManagerImpl;
|
||||
|
||||
static inline SecManagerImpl *impl_from_IInternetSecurityManager(IInternetSecurityManager *iface)
|
||||
static inline SecManagerImpl *impl_from_IInternetSecurityManagerEx2(IInternetSecurityManagerEx2 *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManager_iface);
|
||||
return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManagerEx2_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManager* iface,REFIID riid,void** ppvObject)
|
||||
static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManagerEx2* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
||||
TRACE("(%p)->(%s %p)\n",This,debugstr_guid(riid),ppvObject);
|
||||
|
||||
/* Perform a sanity check on the parameters.*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
if(!ppvObject)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Initialize the return parameter */
|
||||
*ppvObject = 0;
|
||||
|
||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IInternetSecurityManager, riid))
|
||||
if(IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IInternetSecurityManager, riid) ||
|
||||
IsEqualIID(&IID_IInternetSecurityManagerEx, riid) ||
|
||||
IsEqualIID(&IID_IInternetSecurityManagerEx2, riid)) {
|
||||
*ppvObject = iface;
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if (!*ppvObject) {
|
||||
} else {
|
||||
WARN("not supported interface %s\n", debugstr_guid(riid));
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* Query Interface always increases the reference count by one when it is successful */
|
||||
IInternetSecurityManager_AddRef(iface);
|
||||
|
||||
IInternetSecurityManagerEx2_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface)
|
||||
static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManagerEx2* iface)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%u\n", This, refCount);
|
||||
|
@ -704,9 +884,9 @@ static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface)
|
|||
return refCount;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
|
||||
static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManagerEx2* iface)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%u\n", This, refCount);
|
||||
|
@ -726,10 +906,10 @@ static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
|
|||
return refCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManagerEx2 *iface,
|
||||
IInternetSecurityMgrSite *pSite)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pSite);
|
||||
|
||||
|
@ -761,10 +941,10 @@ static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManager *i
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManagerEx2 *iface,
|
||||
IInternetSecurityMgrSite **ppSite)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, ppSite);
|
||||
|
||||
|
@ -778,11 +958,11 @@ static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManager *i
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManagerEx2 *iface,
|
||||
LPCWSTR pwszUrl, DWORD *pdwZone,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);
|
||||
|
@ -805,20 +985,17 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
|
|||
return map_url_to_zone(pwszUrl, pdwZone, NULL);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManagerEx2 *iface,
|
||||
LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
LPWSTR url, ptr, ptr2;
|
||||
DWORD zone, len;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR wszFile[] = {'f','i','l','e',':'};
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
|
||||
pcbSecurityId, dwReserved);
|
||||
|
||||
if(This->custom_manager) {
|
||||
HRESULT hres;
|
||||
|
||||
hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
|
||||
pwszUrl, pbSecurityId, pcbSecurityId, dwReserved);
|
||||
if(hres != INET_E_DEFAULT_ACTION)
|
||||
|
@ -831,64 +1008,17 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
|
|||
if(dwReserved)
|
||||
FIXME("dwReserved is not supported\n");
|
||||
|
||||
hres = map_url_to_zone(pwszUrl, &zone, &url);
|
||||
if(FAILED(hres))
|
||||
return hres == 0x80041001 ? E_INVALIDARG : hres;
|
||||
|
||||
/* file protocol is a special case */
|
||||
if(strlenW(url) >= sizeof(wszFile)/sizeof(WCHAR)
|
||||
&& !memcmp(url, wszFile, sizeof(wszFile)) && strchrW(url, '\\')) {
|
||||
|
||||
static const BYTE secidFile[] = {'f','i','l','e',':'};
|
||||
|
||||
heap_free(url);
|
||||
|
||||
if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
memcpy(pbSecurityId, secidFile, sizeof(secidFile));
|
||||
*(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
|
||||
|
||||
*pcbSecurityId = sizeof(secidFile)+sizeof(zone);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ptr = strchrW(url, ':');
|
||||
ptr2 = ++ptr;
|
||||
while(*ptr2 == '/')
|
||||
ptr2++;
|
||||
if(ptr2 != ptr)
|
||||
memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
|
||||
|
||||
ptr = strchrW(ptr, '/');
|
||||
if(ptr)
|
||||
*ptr = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL)-1;
|
||||
|
||||
if(len+sizeof(DWORD) > *pcbSecurityId) {
|
||||
heap_free(url);
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, url, -1, (LPSTR)pbSecurityId, len, NULL, NULL);
|
||||
heap_free(url);
|
||||
|
||||
*(DWORD*)(pbSecurityId+len) = zone;
|
||||
|
||||
*pcbSecurityId = len+sizeof(DWORD);
|
||||
|
||||
return S_OK;
|
||||
return get_security_id_for_url(pwszUrl, pbSecurityId, pcbSecurityId);
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManagerEx2 *iface,
|
||||
LPCWSTR pwszUrl, DWORD dwAction,
|
||||
BYTE *pPolicy, DWORD cbPolicy,
|
||||
BYTE *pContext, DWORD cbContext,
|
||||
DWORD dwFlags, DWORD dwReserved)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
DWORD zone, policy;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -937,13 +1067,13 @@ static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *
|
|||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManagerEx2 *iface,
|
||||
LPCWSTR pwszUrl, REFGUID guidKey,
|
||||
BYTE **ppPolicy, DWORD *pcbPolicy,
|
||||
BYTE *pContext, DWORD cbContext,
|
||||
DWORD dwReserved)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
|
||||
|
@ -960,10 +1090,10 @@ static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager
|
|||
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManagerEx2 *iface,
|
||||
DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);
|
||||
|
@ -979,10 +1109,10 @@ static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *if
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *iface,
|
||||
static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManagerEx2 *iface,
|
||||
DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManager(iface);
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags);
|
||||
|
@ -998,7 +1128,97 @@ static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *i
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IInternetSecurityManagerVtbl VT_SecManagerImpl =
|
||||
static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx(IInternetSecurityManagerEx2 *iface,
|
||||
LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext,
|
||||
DWORD dwFlags, DWORD dwReserved, DWORD *pdwOutFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
FIXME("(%p)->(%s %08x %p %d %p %d %08x %08x %p) stub\n", This, debugstr_w(pwszUrl), dwAction, pPolicy, cbPolicy,
|
||||
pContext, cbContext, dwFlags, dwReserved, pdwOutFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_MapUrlToZoneEx2(IInternetSecurityManagerEx2 *iface,
|
||||
IUri *pUri, DWORD *pdwZone, DWORD dwFlags, LPWSTR *ppwszMappedUrl, DWORD *pdwOutFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
|
||||
TRACE("(%p)->(%p %p %08x %p %p)\n", This, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags);
|
||||
|
||||
if(This->custom_manager) {
|
||||
HRESULT hres;
|
||||
IInternetSecurityManagerEx2 *sec_mgr2;
|
||||
|
||||
hres = IInternetSecurityManager_QueryInterface(This->custom_manager, &IID_IInternetSecurityManagerEx2,
|
||||
(void**)&sec_mgr2);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags);
|
||||
IInternetSecurityManagerEx2_Release(sec_mgr2);
|
||||
} else {
|
||||
BSTR url;
|
||||
|
||||
hres = IUri_GetDisplayUri(pUri, &url);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager, url, pdwZone, dwFlags);
|
||||
SysFreeString(url);
|
||||
}
|
||||
|
||||
if(hres != INET_E_DEFAULT_ACTION)
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(!pdwZone)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(!pUri) {
|
||||
*pdwZone = URLZONE_INVALID;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(dwFlags)
|
||||
FIXME("Unsupported flags: %08x\n", dwFlags);
|
||||
|
||||
return map_uri_to_zone(pUri, pdwZone, NULL);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx2(IInternetSecurityManagerEx2 *iface,
|
||||
IUri *pUri, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext,
|
||||
DWORD dwFlags, DWORD_PTR dwReserved, DWORD *pdwOutFlags)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
FIXME("(%p)->(%p %08x %p %d %p %d %08x %08x %p) stub\n", This, pUri, dwAction, pPolicy,
|
||||
cbPolicy, pContext, cbContext, dwFlags, (DWORD)dwReserved, pdwOutFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_GetSecurityIdEx2(IInternetSecurityManagerEx2 *iface,
|
||||
IUri *pUri, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
TRACE("(%p)->(%p %p %p %08x) stub\n", This, pUri, pbSecurityId, pcbSecurityId, (DWORD)dwReserved);
|
||||
|
||||
if(dwReserved)
|
||||
FIXME("dwReserved is not supported yet\n");
|
||||
|
||||
if(!pUri || !pcbSecurityId || !pbSecurityId)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return get_security_id_for_uri(pUri, pbSecurityId, pcbSecurityId);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SecManagerImpl_QueryCustomPolicyEx2(IInternetSecurityManagerEx2 *iface,
|
||||
IUri *pUri, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext,
|
||||
DWORD cbContext, DWORD_PTR dwReserved)
|
||||
{
|
||||
SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface);
|
||||
FIXME("(%p)->(%p %s %p %p %p %d %08x) stub\n", This, pUri, debugstr_guid(guidKey), ppPolicy, pcbPolicy,
|
||||
pContext, cbContext, (DWORD)dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IInternetSecurityManagerEx2Vtbl VT_SecManagerImpl =
|
||||
{
|
||||
SecManagerImpl_QueryInterface,
|
||||
SecManagerImpl_AddRef,
|
||||
|
@ -1010,7 +1230,12 @@ static const IInternetSecurityManagerVtbl VT_SecManagerImpl =
|
|||
SecManagerImpl_ProcessUrlAction,
|
||||
SecManagerImpl_QueryCustomPolicy,
|
||||
SecManagerImpl_SetZoneMapping,
|
||||
SecManagerImpl_GetZoneMappings
|
||||
SecManagerImpl_GetZoneMappings,
|
||||
SecManagerImpl_ProcessUrlActionEx,
|
||||
SecManagerImpl_MapUrlToZoneEx2,
|
||||
SecManagerImpl_ProcessUrlActionEx2,
|
||||
SecManagerImpl_GetSecurityIdEx2,
|
||||
SecManagerImpl_QueryCustomPolicyEx2
|
||||
};
|
||||
|
||||
HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||
|
@ -1021,7 +1246,7 @@ HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
|||
This = heap_alloc(sizeof(*This));
|
||||
|
||||
/* Initialize the virtual function table. */
|
||||
This->IInternetSecurityManager_iface.lpVtbl = &VT_SecManagerImpl;
|
||||
This->IInternetSecurityManagerEx2_iface.lpVtbl = &VT_SecManagerImpl;
|
||||
|
||||
This->ref = 1;
|
||||
This->mgrsite = NULL;
|
||||
|
@ -1138,7 +1363,7 @@ static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface,
|
|||
}
|
||||
|
||||
*ppvObject = iface;
|
||||
IInternetZoneManager_AddRef(iface);
|
||||
IInternetZoneManagerEx2_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1512,7 +1737,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* i
|
|||
if (dwFlags)
|
||||
FIXME("dwFlags 0x%x ignored\n", dwFlags);
|
||||
|
||||
return IInternetZoneManager_GetZoneAttributes(iface, dwZone, pZoneAttributes);
|
||||
return IInternetZoneManagerEx2_GetZoneAttributes(iface, dwZone, pZoneAttributes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1817,12 +2042,6 @@ HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
|
||||
if(FAILED(hres)) {
|
||||
CoTaskMemFree(ret_url);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* File URIs have to hierarchical. */
|
||||
hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type);
|
||||
if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) {
|
||||
|
@ -1839,3 +2058,12 @@ HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION
|
|||
CoTaskMemFree(ret_url);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* CompareSecurityIds (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CompareSecurityIds(BYTE *secid1, DWORD size1, BYTE *secid2, DWORD size2, DWORD reserved)
|
||||
{
|
||||
FIXME("(%p %d %p %d %x)\n", secid1, size1, secid2, size2, reserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -23,25 +23,25 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
typedef struct name_space {
|
||||
typedef struct {
|
||||
LPWSTR protocol;
|
||||
IClassFactory *cf;
|
||||
CLSID clsid;
|
||||
BOOL urlmon;
|
||||
|
||||
struct name_space *next;
|
||||
struct list entry;
|
||||
} name_space;
|
||||
|
||||
typedef struct mime_filter {
|
||||
typedef struct {
|
||||
IClassFactory *cf;
|
||||
CLSID clsid;
|
||||
LPWSTR mime;
|
||||
|
||||
struct mime_filter *next;
|
||||
struct list entry;
|
||||
} mime_filter;
|
||||
|
||||
static name_space *name_space_list = NULL;
|
||||
static mime_filter *mime_filter_list = NULL;
|
||||
static struct list name_space_list = LIST_INIT(name_space_list);
|
||||
static struct list mime_filter_list = LIST_INIT(mime_filter_list);
|
||||
|
||||
static CRITICAL_SECTION session_cs;
|
||||
static CRITICAL_SECTION_DEBUG session_cs_dbg =
|
||||
|
@ -63,8 +63,8 @@ static name_space *find_name_space(LPCWSTR protocol)
|
|||
{
|
||||
name_space *iter;
|
||||
|
||||
for(iter = name_space_list; iter; iter = iter->next) {
|
||||
if(!strcmpW(iter->protocol, protocol))
|
||||
LIST_FOR_EACH_ENTRY(iter, &name_space_list, name_space, entry) {
|
||||
if(!strcmpiW(iter->protocol, protocol))
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid,
|
|||
return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX;
|
||||
}
|
||||
|
||||
static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol)
|
||||
HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol)
|
||||
{
|
||||
name_space *new_name_space;
|
||||
|
||||
|
@ -134,8 +134,7 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto
|
|||
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
new_name_space->next = name_space_list;
|
||||
name_space_list = new_name_space;
|
||||
list_add_head(&name_space_list, &new_name_space->entry);
|
||||
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
|
@ -144,44 +143,28 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto
|
|||
|
||||
static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol)
|
||||
{
|
||||
name_space *iter, *last = NULL;
|
||||
name_space *iter;
|
||||
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
for(iter = name_space_list; iter; iter = iter->next) {
|
||||
if(iter->cf == cf && !strcmpW(iter->protocol, protocol))
|
||||
break;
|
||||
last = iter;
|
||||
}
|
||||
LIST_FOR_EACH_ENTRY(iter, &name_space_list, name_space, entry) {
|
||||
if(iter->cf == cf && !strcmpiW(iter->protocol, protocol)) {
|
||||
list_remove(&iter->entry);
|
||||
|
||||
if(iter) {
|
||||
if(last)
|
||||
last->next = iter->next;
|
||||
else
|
||||
name_space_list = iter->next;
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
if(!iter->urlmon)
|
||||
IClassFactory_Release(iter->cf);
|
||||
heap_free(iter->protocol);
|
||||
heap_free(iter);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
if(iter) {
|
||||
if(!iter->urlmon)
|
||||
IClassFactory_Release(iter->cf);
|
||||
heap_free(iter->protocol);
|
||||
heap_free(iter);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void register_urlmon_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL do_register)
|
||||
{
|
||||
if(do_register)
|
||||
register_namespace(cf, clsid, protocol, TRUE);
|
||||
else
|
||||
unregister_namespace(cf, protocol);
|
||||
}
|
||||
|
||||
BOOL is_registered_protocol(LPCWSTR url)
|
||||
{
|
||||
DWORD schema_len;
|
||||
|
@ -277,14 +260,22 @@ HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, BOOL *urlmon_protocol, ICl
|
|||
|
||||
IInternetProtocol *get_mime_filter(LPCWSTR mime)
|
||||
{
|
||||
static const WCHAR filtersW[] = {'P','r','o','t','o','c','o','l','s',
|
||||
'\\','F','i','l','t','e','r',0 };
|
||||
static const WCHAR CLSIDW[] = {'C','L','S','I','D',0};
|
||||
|
||||
IClassFactory *cf = NULL;
|
||||
IInternetProtocol *ret;
|
||||
mime_filter *iter;
|
||||
HKEY hlist, hfilter;
|
||||
WCHAR clsidw[64];
|
||||
CLSID clsid;
|
||||
DWORD res, type, size;
|
||||
HRESULT hres;
|
||||
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
for(iter = mime_filter_list; iter; iter = iter->next) {
|
||||
LIST_FOR_EACH_ENTRY(iter, &mime_filter_list, mime_filter, entry) {
|
||||
if(!strcmpW(iter->mime, mime)) {
|
||||
cf = iter->cf;
|
||||
break;
|
||||
|
@ -293,12 +284,44 @@ IInternetProtocol *get_mime_filter(LPCWSTR mime)
|
|||
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
if(!cf)
|
||||
if(cf) {
|
||||
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret);
|
||||
if(FAILED(hres)) {
|
||||
WARN("CreateInstance failed: %08x\n", hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
res = RegOpenKeyW(HKEY_CLASSES_ROOT, filtersW, &hlist);
|
||||
if(res != ERROR_SUCCESS) {
|
||||
TRACE("Could not open MIME filters key\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = RegOpenKeyW(hlist, mime, &hfilter);
|
||||
CloseHandle(hlist);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret);
|
||||
size = sizeof(clsidw);
|
||||
res = RegQueryValueExW(hfilter, CLSIDW, NULL, &type, (LPBYTE)clsidw, &size);
|
||||
CloseHandle(hfilter);
|
||||
if(res!=ERROR_SUCCESS || type!=REG_SZ) {
|
||||
WARN("Could not get filter CLSID for %s\n", debugstr_w(mime));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hres = CLSIDFromString(clsidw, &clsid);
|
||||
if(FAILED(hres)) {
|
||||
WARN("CreateInstance failed: %08x\n", hres);
|
||||
WARN("CLSIDFromString failed for %s (%x)\n", debugstr_w(mime), hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&ret);
|
||||
if(FAILED(hres)) {
|
||||
WARN("CoCreateInstance failed: %08x\n", hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -379,8 +402,7 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface
|
|||
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
filter->next = mime_filter_list;
|
||||
mime_filter_list = filter;
|
||||
list_add_head(&mime_filter_list, &filter->entry);
|
||||
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
|
@ -390,33 +412,26 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface
|
|||
static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *iface,
|
||||
IClassFactory *pCF, LPCWSTR pwzType)
|
||||
{
|
||||
mime_filter *iter, *prev = NULL;
|
||||
mime_filter *iter;
|
||||
|
||||
TRACE("(%p %s)\n", pCF, debugstr_w(pwzType));
|
||||
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
for(iter = mime_filter_list; iter; iter = iter->next) {
|
||||
if(iter->cf == pCF && !strcmpW(iter->mime, pwzType))
|
||||
break;
|
||||
prev = iter;
|
||||
}
|
||||
LIST_FOR_EACH_ENTRY(iter, &mime_filter_list, mime_filter, entry) {
|
||||
if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) {
|
||||
list_remove(&iter->entry);
|
||||
|
||||
if(iter) {
|
||||
if(prev)
|
||||
prev->next = iter->next;
|
||||
else
|
||||
mime_filter_list = iter->next;
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
IClassFactory_Release(iter->cf);
|
||||
heap_free(iter->mime);
|
||||
heap_free(iter);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
if(iter) {
|
||||
IClassFactory_Release(iter->cf);
|
||||
heap_free(iter->mime);
|
||||
heap_free(iter);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -517,31 +532,38 @@ static LPWSTR user_agent;
|
|||
|
||||
static void ensure_useragent(void)
|
||||
{
|
||||
DWORD size = sizeof(DWORD), res, type;
|
||||
HKEY hkey;
|
||||
OSVERSIONINFOW info = {sizeof(info)};
|
||||
const WCHAR *os_type, *is_nt;
|
||||
WCHAR buf[512];
|
||||
BOOL is_wow;
|
||||
|
||||
static const WCHAR user_agentW[] = {'U','s','e','r',' ','A','g','e','n','t',0};
|
||||
static const WCHAR formatW[] =
|
||||
{'M','o','z','i','l','l','a','/','4','.','0',
|
||||
' ','(','c','o','m','p','a','t','i','b','l','e',';',
|
||||
' ','M','S','I','E',' ','8','.','0',';',
|
||||
' ','W','i','n','d','o','w','s',' ','%','s','%','d','.','%','d',';',
|
||||
' ','%','s',';',' ','T','r','i','d','e','n','t','/','5','.','0',')',0};
|
||||
static const WCHAR ntW[] = {'N','T',' ',0};
|
||||
static const WCHAR win32W[] = {'W','i','n','3','2',0};
|
||||
static const WCHAR win64W[] = {'W','i','n','6','4',0};
|
||||
static const WCHAR wow64W[] = {'W','O','W','6','4',0};
|
||||
static const WCHAR emptyW[] = {0};
|
||||
|
||||
if(user_agent)
|
||||
return;
|
||||
|
||||
res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings_keyW, &hkey);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return;
|
||||
GetVersionExW(&info);
|
||||
is_nt = info.dwPlatformId == VER_PLATFORM_WIN32_NT ? ntW : emptyW;
|
||||
|
||||
res = RegQueryValueExW(hkey, user_agentW, NULL, &type, NULL, &size);
|
||||
if(res == ERROR_SUCCESS && type == REG_SZ) {
|
||||
user_agent = heap_alloc(size);
|
||||
res = RegQueryValueExW(hkey, user_agentW, NULL, &type, (LPBYTE)user_agent, &size);
|
||||
if(res != ERROR_SUCCESS) {
|
||||
heap_free(user_agent);
|
||||
user_agent = NULL;
|
||||
}
|
||||
}else {
|
||||
WARN("Could not find User Agent value: %u\n", res);
|
||||
}
|
||||
if(sizeof(void*) == 8)
|
||||
os_type = win64W;
|
||||
else if(IsWow64Process(GetCurrentProcess(), &is_wow) && is_wow)
|
||||
os_type = wow64W;
|
||||
else
|
||||
os_type = win32W;
|
||||
|
||||
RegCloseKey(hkey);
|
||||
sprintfW(buf, formatW, is_nt, info.dwMajorVersion, info.dwMinorVersion, os_type);
|
||||
user_agent = heap_strdupW(buf);
|
||||
}
|
||||
|
||||
LPWSTR get_useragent(void)
|
||||
|
@ -691,5 +713,21 @@ HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbS
|
|||
|
||||
void free_session(void)
|
||||
{
|
||||
name_space *ns_iter, *ns_last;
|
||||
mime_filter *mf_iter, *mf_last;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(ns_iter, ns_last, &name_space_list, name_space, entry) {
|
||||
if(!ns_iter->urlmon)
|
||||
IClassFactory_Release(ns_iter->cf);
|
||||
heap_free(ns_iter->protocol);
|
||||
heap_free(ns_iter);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(mf_iter, mf_last, &mime_filter_list, mime_filter, entry) {
|
||||
IClassFactory_Release(mf_iter->cf);
|
||||
heap_free(mf_iter->mime);
|
||||
heap_free(mf_iter);
|
||||
}
|
||||
|
||||
heap_free(user_agent);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ typedef struct {
|
|||
|
||||
LONG ref;
|
||||
|
||||
LPOLESTR URLName; /* URL string identified by this URLmoniker */
|
||||
IUri *uri;
|
||||
BSTR URLName;
|
||||
} URLMoniker;
|
||||
|
||||
static inline URLMoniker *impl_from_IMoniker(IMoniker *iface)
|
||||
|
@ -76,7 +77,7 @@ static HRESULT WINAPI URLMoniker_QueryInterface(IMoniker *iface, REFIID riid, vo
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IMoniker_AddRef((IUnknown*)*ppv);
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -98,7 +99,9 @@ static ULONG WINAPI URLMoniker_Release(IMoniker *iface)
|
|||
TRACE("(%p) ref=%u\n",This, refCount);
|
||||
|
||||
if (!refCount) {
|
||||
heap_free(This->URLName);
|
||||
if(This->uri)
|
||||
IUri_Release(This->uri);
|
||||
SysFreeString(This->URLName);
|
||||
heap_free(This);
|
||||
|
||||
URLMON_UnlockModule();
|
||||
|
@ -136,9 +139,12 @@ static HRESULT WINAPI URLMoniker_IsDirty(IMoniker *iface)
|
|||
static HRESULT WINAPI URLMoniker_Load(IMoniker* iface,IStream* pStm)
|
||||
{
|
||||
URLMoniker *This = impl_from_IMoniker(iface);
|
||||
HRESULT res;
|
||||
WCHAR *new_uri_str;
|
||||
IUri *new_uri;
|
||||
BSTR new_url;
|
||||
ULONG size;
|
||||
ULONG got;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p,%p)\n",This,pStm);
|
||||
|
||||
|
@ -150,23 +156,37 @@ static HRESULT WINAPI URLMoniker_Load(IMoniker* iface,IStream* pStm)
|
|||
* Writes a ULONG containing length of unicode string, followed
|
||||
* by that many unicode characters
|
||||
*/
|
||||
res = IStream_Read(pStm, &size, sizeof(ULONG), &got);
|
||||
if(SUCCEEDED(res)) {
|
||||
if(got == sizeof(ULONG)) {
|
||||
heap_free(This->URLName);
|
||||
This->URLName = heap_alloc(size);
|
||||
if(!This->URLName)
|
||||
res = E_OUTOFMEMORY;
|
||||
else {
|
||||
res = IStream_Read(pStm, This->URLName, size, NULL);
|
||||
This->URLName[size/sizeof(WCHAR) - 1] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = E_FAIL;
|
||||
hres = IStream_Read(pStm, &size, sizeof(ULONG), &got);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(got != sizeof(ULONG))
|
||||
return E_FAIL;
|
||||
|
||||
new_uri_str = heap_alloc(size+sizeof(WCHAR));
|
||||
if(!new_uri_str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = IStream_Read(pStm, new_uri_str, size, NULL);
|
||||
new_uri_str[size/sizeof(WCHAR)] = 0;
|
||||
if(SUCCEEDED(hres))
|
||||
hres = CreateUri(new_uri_str, 0, 0, &new_uri);
|
||||
heap_free(new_uri_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IUri_GetDisplayUri(new_uri, &new_url);
|
||||
if(FAILED(hres)) {
|
||||
IUri_Release(new_uri);
|
||||
return hres;
|
||||
}
|
||||
|
||||
return res;
|
||||
SysFreeString(This->URLName);
|
||||
if(This->uri)
|
||||
IUri_Release(This->uri);
|
||||
|
||||
This->uri = new_uri;
|
||||
This->URLName = new_url;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI URLMoniker_Save(IMoniker *iface, IStream* pStm, BOOL fClearDirty)
|
||||
|
@ -180,7 +200,7 @@ static HRESULT WINAPI URLMoniker_Save(IMoniker *iface, IStream* pStm, BOOL fClea
|
|||
if(!pStm)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size = (strlenW(This->URLName) + 1)*sizeof(WCHAR);
|
||||
size = (SysStringLen(This->URLName) + 1)*sizeof(WCHAR);
|
||||
res=IStream_Write(pStm,&size,sizeof(ULONG),NULL);
|
||||
if(SUCCEEDED(res))
|
||||
res=IStream_Write(pStm,This->URLName,size,NULL);
|
||||
|
@ -198,7 +218,7 @@ static HRESULT WINAPI URLMoniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER *pcb
|
|||
if(!pcbSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pcbSize->QuadPart = sizeof(ULONG) + ((strlenW(This->URLName)+1) * sizeof(WCHAR));
|
||||
pcbSize->QuadPart = sizeof(ULONG) + ((SysStringLen(This->URLName)+1) * sizeof(WCHAR));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -207,10 +227,9 @@ static HRESULT WINAPI URLMoniker_BindToObject(IMoniker *iface, IBindCtx* pbc, IM
|
|||
{
|
||||
URLMoniker *This = impl_from_IMoniker(iface);
|
||||
IRunningObjectTable *obj_tbl;
|
||||
IUri *uri;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p,%p,%s,%p): stub\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppv);
|
||||
TRACE("(%p)->(%p,%p,%s,%p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppv);
|
||||
|
||||
hres = IBindCtx_GetRunningObjectTable(pbc, &obj_tbl);
|
||||
if(SUCCEEDED(hres)) {
|
||||
|
@ -218,22 +237,18 @@ static HRESULT WINAPI URLMoniker_BindToObject(IMoniker *iface, IBindCtx* pbc, IM
|
|||
IRunningObjectTable_Release(obj_tbl);
|
||||
}
|
||||
|
||||
hres = CreateUri(This->URLName, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(!This->uri) {
|
||||
*ppv = NULL;
|
||||
return MK_E_SYNTAX;
|
||||
}
|
||||
|
||||
hres = bind_to_object(iface, uri, pbc, riid, ppv);
|
||||
|
||||
IUri_Release(uri);
|
||||
return hres;
|
||||
return bind_to_object(&This->IMoniker_iface, This->uri, pbc, riid, ppv);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI URLMoniker_BindToStorage(IMoniker* iface, IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft, REFIID riid, void **ppvObject)
|
||||
{
|
||||
URLMoniker *This = impl_from_IMoniker(iface);
|
||||
IUri *uri;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
|
||||
|
||||
|
@ -244,14 +259,10 @@ static HRESULT WINAPI URLMoniker_BindToStorage(IMoniker* iface, IBindCtx* pbc,
|
|||
if(pmkToLeft)
|
||||
FIXME("Unsupported pmkToLeft\n");
|
||||
|
||||
hres = CreateUri(This->URLName, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(!This->uri)
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
hres = bind_to_storage(uri, pbc, riid, ppvObject);
|
||||
|
||||
IUri_Release(uri);
|
||||
return hres;
|
||||
return bind_to_storage(This->uri, pbc, riid, ppvObject);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI URLMoniker_Reduce(IMoniker *iface, IBindCtx *pbc,
|
||||
|
@ -320,7 +331,7 @@ static HRESULT WINAPI URLMoniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoni
|
|||
if(result == 0)
|
||||
res = S_OK;
|
||||
}
|
||||
IUnknown_Release(bind);
|
||||
IBindCtx_Release(bind);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -409,7 +420,7 @@ static HRESULT WINAPI URLMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
|
|||
/* FIXME: If this is a partial URL, try and get a URL moniker from SZ_URLCONTEXT in the bind context,
|
||||
then look at pmkToLeft to try and complete the URL
|
||||
*/
|
||||
len = lstrlenW(This->URLName)+1;
|
||||
len = SysStringLen(This->URLName)+1;
|
||||
*ppszDisplayName = CoTaskMemAlloc(len*sizeof(WCHAR));
|
||||
if(!*ppszDisplayName)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -492,10 +503,16 @@ static HRESULT WINAPI UriContainer_GetIUri(IUriContainer *iface, IUri **ppIUri)
|
|||
{
|
||||
URLMoniker *This = impl_from_IUriContainer(iface);
|
||||
|
||||
FIXME("(%p)->(%p)\n", This, ppIUri);
|
||||
TRACE("(%p)->(%p)\n", This, ppIUri);
|
||||
|
||||
*ppIUri = NULL;
|
||||
return S_FALSE;
|
||||
if(!This->uri) {
|
||||
*ppIUri = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
IUri_AddRef(This->uri);
|
||||
*ppIUri = This->uri;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IUriContainerVtbl UriContainerVtbl = {
|
||||
|
@ -505,61 +522,66 @@ static const IUriContainerVtbl UriContainerVtbl = {
|
|||
UriContainer_GetIUri
|
||||
};
|
||||
|
||||
static URLMoniker *alloc_moniker(void)
|
||||
{
|
||||
URLMoniker *ret;
|
||||
|
||||
ret = heap_alloc(sizeof(URLMoniker));
|
||||
if(!ret)
|
||||
return NULL;
|
||||
|
||||
ret->IMoniker_iface.lpVtbl = &URLMonikerVtbl;
|
||||
ret->IUriContainer_iface.lpVtbl = &UriContainerVtbl;
|
||||
ret->ref = 1;
|
||||
ret->URLName = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT URLMoniker_Init(URLMoniker *This, LPCOLESTR lpszLeftURLName, LPCOLESTR lpszURLName)
|
||||
static HRESULT create_moniker(IUri *uri, URLMoniker **ret)
|
||||
{
|
||||
URLMoniker *mon;
|
||||
HRESULT hres;
|
||||
DWORD sizeStr = 0;
|
||||
|
||||
TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszLeftURLName),debugstr_w(lpszURLName));
|
||||
mon = heap_alloc(sizeof(*mon));
|
||||
if(!mon)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->URLName = heap_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR));
|
||||
mon->IMoniker_iface.lpVtbl = &URLMonikerVtbl;
|
||||
mon->IUriContainer_iface.lpVtbl = &UriContainerVtbl;
|
||||
mon->ref = 1;
|
||||
|
||||
if(lpszLeftURLName)
|
||||
hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, URL_FILE_USE_PATHURL,
|
||||
This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
|
||||
else
|
||||
hres = CoInternetParseUrl(lpszURLName, PARSE_CANONICALIZE, URL_FILE_USE_PATHURL,
|
||||
This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
|
||||
if(uri) {
|
||||
/* FIXME: try to avoid it */
|
||||
hres = IUri_GetDisplayUri(uri, &mon->URLName);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(mon);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(FAILED(hres)) {
|
||||
heap_free(This->URLName);
|
||||
return hres;
|
||||
IUri_AddRef(uri);
|
||||
mon->uri = uri;
|
||||
}else {
|
||||
mon->URLName = NULL;
|
||||
mon->uri = NULL;
|
||||
}
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
if(sizeStr != INTERNET_MAX_URL_LENGTH)
|
||||
This->URLName = heap_realloc(This->URLName, (sizeStr+1)*sizeof(WCHAR));
|
||||
|
||||
TRACE("URLName = %s\n", debugstr_w(This->URLName));
|
||||
|
||||
*ret = mon;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT StdURLMoniker_Construct(IUnknown *outer, void **ppv)
|
||||
{
|
||||
URLMoniker *mon;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %p)\n", outer, ppv);
|
||||
|
||||
*ppv = alloc_moniker();
|
||||
return *ppv ? S_OK : E_OUTOFMEMORY;
|
||||
hres = create_moniker(NULL, &mon);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ppv = &mon->IMoniker_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const DWORD create_flags_map[3] = {
|
||||
Uri_CREATE_FILE_USE_DOS_PATH, /* URL_MK_LEGACY */
|
||||
0, /* URL_MK_UNIFORM */
|
||||
Uri_CREATE_NO_CANONICALIZE /* URL_MK_NO_CANONICALIZE */
|
||||
};
|
||||
|
||||
static const DWORD combine_flags_map[3] = {
|
||||
URL_FILE_USE_PATHURL, /* URL_MK_LEGACY */
|
||||
0, /* URL_MK_UNIFORM */
|
||||
URL_DONT_SIMPLIFY /* URL_MK_NO_CANONICALIZE */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CreateURLMonikerEx (URLMON.@)
|
||||
*
|
||||
|
@ -578,9 +600,9 @@ HRESULT StdURLMoniker_Construct(IUnknown *outer, void **ppv)
|
|||
*/
|
||||
HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk, DWORD dwFlags)
|
||||
{
|
||||
IUri *uri, *base_uri = NULL;
|
||||
URLMoniker *obj;
|
||||
HRESULT hres;
|
||||
LPOLESTR lefturl = NULL;
|
||||
|
||||
TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags);
|
||||
|
||||
|
@ -590,28 +612,91 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker
|
|||
if (!szURL || !ppmk)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n");
|
||||
|
||||
if(!(obj = alloc_moniker()))
|
||||
return E_OUTOFMEMORY;
|
||||
if(dwFlags >= sizeof(create_flags_map)/sizeof(*create_flags_map)) {
|
||||
FIXME("Unsupported flags %x\n", dwFlags);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(pmkContext) {
|
||||
IBindCtx* bind;
|
||||
DWORD dwMksys = 0;
|
||||
IMoniker_IsSystemMoniker(pmkContext, &dwMksys);
|
||||
if(dwMksys == MKSYS_URLMONIKER && SUCCEEDED(CreateBindCtx(0, &bind))) {
|
||||
IMoniker_GetDisplayName(pmkContext, bind, NULL, &lefturl);
|
||||
TRACE("lefturl = %s\n", debugstr_w(lefturl));
|
||||
IBindCtx_Release(bind);
|
||||
IUriContainer *uri_container;
|
||||
|
||||
hres = IMoniker_QueryInterface(pmkContext, &IID_IUriContainer, (void**)&uri_container);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IUriContainer_GetIUri(uri_container, &base_uri);
|
||||
IUriContainer_Release(uri_container);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
hres = URLMoniker_Init(obj, lefturl, szURL);
|
||||
CoTaskMemFree(lefturl);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = URLMoniker_QueryInterface(&obj->IMoniker_iface, &IID_IMoniker, (void**)ppmk);
|
||||
IMoniker_Release(&obj->IMoniker_iface);
|
||||
return hres;
|
||||
|
||||
if(base_uri) {
|
||||
hres = CoInternetCombineUrlEx(base_uri, szURL, combine_flags_map[dwFlags], &uri, 0);
|
||||
IUri_Release(base_uri);
|
||||
}else {
|
||||
hres = CreateUri(szURL, Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|create_flags_map[dwFlags], 0, &uri);
|
||||
}
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_moniker(uri, &obj);
|
||||
IUri_Release(uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ppmk = &obj->IMoniker_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CreateURLMonikerEx2 (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CreateURLMonikerEx2(IMoniker *pmkContext, IUri *pUri, IMoniker **ppmk, DWORD dwFlags)
|
||||
{
|
||||
IUri *context_uri = NULL, *uri;
|
||||
IUriContainer *uri_container;
|
||||
URLMoniker *ret;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %p %p %x)\n", pmkContext, pUri, ppmk, dwFlags);
|
||||
|
||||
if (ppmk)
|
||||
*ppmk = NULL;
|
||||
|
||||
if (!pUri || !ppmk)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(dwFlags >= sizeof(create_flags_map)/sizeof(*create_flags_map)) {
|
||||
FIXME("Unsupported flags %x\n", dwFlags);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(pmkContext) {
|
||||
hres = IMoniker_QueryInterface(pmkContext, &IID_IUriContainer, (void**)&uri_container);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IUriContainer_GetIUri(uri_container, &context_uri);
|
||||
if(FAILED(hres))
|
||||
context_uri = NULL;
|
||||
IUriContainer_Release(uri_container);
|
||||
}
|
||||
}
|
||||
|
||||
if(context_uri) {
|
||||
hres = CoInternetCombineIUri(context_uri, pUri, combine_flags_map[dwFlags], &uri, 0);
|
||||
IUri_Release(context_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}else {
|
||||
uri = pUri;
|
||||
IUri_AddRef(uri);
|
||||
}
|
||||
|
||||
hres = create_moniker(uri, &ret);
|
||||
IUri_Release(uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ppmk = &ret->IMoniker_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -865,14 +950,3 @@ HRESULT WINAPI GetSoftwareUpdateInfo( LPCWSTR szDistUnit, LPSOFTDISTINFO psdi )
|
|||
FIXME("%s %p\n", debugstr_w(szDistUnit), psdi );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* AsyncInstallDistributionUnit (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI AsyncInstallDistributionUnit( LPCWSTR szDistUnit, LPCWSTR szTYPE,
|
||||
LPCWSTR szExt, DWORD dwFileVersionMS, DWORD dwFileVersionLS,
|
||||
LPCWSTR szURL, IBindCtx *pbc, LPVOID pvReserved, DWORD flags )
|
||||
{
|
||||
FIXME(": stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback
|
|||
IsEqualGUID(&IID_IUnknown, riid))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
IBindStatusCallback_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
67
reactos/dll/win32/urlmon/urlmon.rc
Normal file
67
reactos/dll/win32/urlmon/urlmon.rc
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2005 Jacek Caban
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <windef.h>
|
||||
#include <winuser.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
ID_AXINSTALL_WARNING_DLG DIALOG 0, 0, 260, 115
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Security Warning"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
CONTROL "Do you want to install this software?",
|
||||
100, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 10, 10, 240, 23
|
||||
CONTROL "Location:", 101, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 10, 26, 40, 13
|
||||
CONTROL "", ID_AXINSTALL_LOCATION, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 50, 26, 200, 13
|
||||
DEFPUSHBUTTON "Don't install", IDCANCEL, 200, 48, 50, 14, WS_GROUP | WS_TABSTOP
|
||||
PUSHBUTTON "", ID_AXINSTALL_INSTALL_BTN, 144, 48, 50, 14, WS_GROUP | WS_TABSTOP | WS_DISABLED
|
||||
CONTROL "", 102, "static", SS_ETCHEDHORZ, 10, 70, 240, 1
|
||||
ICON "", ID_AXINSTALL_ICON, 10, 82, 32, 32, WS_CHILD | WS_VISIBLE
|
||||
CONTROL "When installed, an ActiveX component has full access to your computer. Do not click install unless you have absolute trust in the above source.",
|
||||
22002, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 46, 80, 194, 23
|
||||
}
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
IDS_AXINSTALL_FAILURE "Installation of component failed: %08x"
|
||||
IDS_AXINSTALL_INSTALLN "Install (%d)"
|
||||
IDS_AXINSTALL_INSTALL "Install"
|
||||
}
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
/* @makedep: urlmon.rgs */
|
||||
1 WINE_REGISTRY urlmon.rgs
|
||||
|
||||
2 WINE_REGISTRY urlmon_urlmon.rgs
|
||||
|
||||
/* @makedep: urlmon.inf */
|
||||
REGINST REGINST urlmon.inf
|
||||
|
||||
#define WINE_FILENAME_STR "urlmon.dll"
|
||||
#define WINE_FILEVERSION 6,0,2800,1485
|
||||
#define WINE_FILEVERSION_STR "6.0.2800.1485"
|
||||
#define WINE_PRODUCTVERSION 6,0,2800,1485
|
||||
#define WINE_PRODUCTVERSION_STR "6.0.2800.1485"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
|
@ -10,7 +10,7 @@
|
|||
@ stdcall BindAsyncMoniker(ptr long ptr ptr ptr)
|
||||
@ stdcall CoGetClassObjectFromURL(ptr wstr long long wstr ptr long ptr ptr ptr)
|
||||
@ stub CoInstall
|
||||
@ stdcall CoInternetCombineUrl(wstr wstr long wstr long ptr long)
|
||||
@ stdcall CoInternetCombineUrl(wstr wstr long ptr long ptr long)
|
||||
@ stdcall CoInternetCombineUrlEx(ptr wstr long ptr long)
|
||||
@ stdcall CoInternetCompareUrl(wstr wstr long)
|
||||
@ stdcall CoInternetCombineIUri(ptr ptr long ptr long)
|
||||
|
@ -21,12 +21,14 @@
|
|||
@ stdcall CoInternetGetSecurityUrlEx(ptr ptr long long)
|
||||
@ stdcall CoInternetGetSession(long ptr long)
|
||||
@ stdcall CoInternetIsFeatureEnabled(long long)
|
||||
@ stdcall CoInternetIsFeatureEnabledForUrl(long long wstr ptr)
|
||||
@ stdcall CoInternetIsFeatureZoneElevationEnabled(wstr wstr ptr long)
|
||||
@ stdcall CoInternetParseUrl(wstr long long wstr long ptr long)
|
||||
@ stdcall CoInternetParseIUri(ptr long long wstr long ptr long)
|
||||
@ stdcall CoInternetQueryInfo(ptr long long ptr long ptr long)
|
||||
@ stdcall CoInternetSetFeatureEnabled(long long long)
|
||||
@ stub CompareSecurityIds
|
||||
@ stub CopyBindInfo
|
||||
@ stdcall CompareSecurityIds(ptr long ptr long long)
|
||||
@ stdcall CopyBindInfo(ptr ptr)
|
||||
@ stdcall CopyStgMedium(ptr ptr)
|
||||
@ stdcall CreateAsyncBindCtx(long ptr ptr ptr)
|
||||
@ stdcall CreateAsyncBindCtxEx(ptr long ptr ptr ptr long)
|
||||
|
@ -36,6 +38,7 @@
|
|||
@ stdcall CreateUriWithFragment(wstr wstr long long ptr)
|
||||
@ stdcall CreateURLMoniker(ptr wstr ptr)
|
||||
@ stdcall CreateURLMonikerEx(ptr wstr ptr long)
|
||||
@ stdcall CreateURLMonikerEx2(ptr ptr ptr long)
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllInstall(long wstr)
|
||||
|
@ -69,7 +72,7 @@
|
|||
@ stdcall RegisterBindStatusCallback(ptr ptr ptr long)
|
||||
@ stdcall RegisterFormatEnumerator(ptr ptr long)
|
||||
@ stub RegisterMediaTypeClass
|
||||
@ stub RegisterMediaTypes
|
||||
@ stdcall RegisterMediaTypes(long ptr ptr)
|
||||
@ stdcall ReleaseBindInfo(ptr)
|
||||
@ stdcall RevokeBindStatusCallback(ptr ptr)
|
||||
@ stdcall RevokeFormatEnumerator(ptr ptr)
|
||||
|
@ -92,5 +95,17 @@
|
|||
@ stub WriteHitLogging
|
||||
@ stub ZonesReInit
|
||||
|
||||
410 stdcall @(long long) URLMON_410
|
||||
423 stdcall @(long long long long) URLMON_423
|
||||
111 stdcall @(wstr) IsProtectedModeURL
|
||||
328 stdcall @(ptr ptr) propsys.VariantCompare
|
||||
329 stdcall @(ptr ptr) propsys.VariantToGUID
|
||||
331 stdcall @(ptr long ptr) propsys.InitPropVariantFromBuffer
|
||||
335 stdcall @(ptr long ptr) propsys.InitVariantFromBuffer
|
||||
350 stdcall @(ptr ptr) propsys.PropVariantToGUID
|
||||
362 stdcall @(ptr ptr) propsys.InitVariantFromGUIDAsString
|
||||
363 stdcall @(long long ptr) propsys.InitVariantFromResource
|
||||
387 stdcall @(ptr long) propsys.VariantToUInt32WithDefault
|
||||
410 stdcall @(long long) LogSqmBits
|
||||
423 stdcall @(long long long long) LogSqmUXCommandOffsetInternal
|
||||
444 stdcall @(long long long) MapUriToBrowserEmulationState
|
||||
445 stdcall @(long long) MapBrowserEmulationModeToUserAgent
|
||||
455 stdcall @() FlushUrlmonZonesCache
|
||||
|
|
|
@ -27,19 +27,23 @@
|
|||
#define NO_SHLWAPI_REG
|
||||
//#include "shlwapi.h"
|
||||
#include <advpub.h>
|
||||
#include <initguid.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
|
||||
//#include "urlmon.h"
|
||||
#include "urlmon.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
DEFINE_GUID(CLSID_CUri, 0xDF2FCE13, 0x25EC, 0x45BB, 0x9D,0x4C, 0xCE,0xCD,0x47,0xC2,0x43,0x0C);
|
||||
|
||||
LONG URLMON_refCount = 0;
|
||||
HINSTANCE urlmon_instance;
|
||||
|
||||
static HMODULE hCabinet = NULL;
|
||||
static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
|
||||
|
||||
static void init_session(BOOL);
|
||||
static void init_session(void);
|
||||
|
||||
static struct list tls_list = LIST_INIT(tls_list);
|
||||
|
||||
|
@ -133,7 +137,6 @@ static void process_detach(void)
|
|||
if (hCabinet)
|
||||
FreeLibrary(hCabinet);
|
||||
|
||||
init_session(FALSE);
|
||||
free_session();
|
||||
free_tls_list();
|
||||
}
|
||||
|
@ -149,11 +152,13 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
|||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
init_session(TRUE);
|
||||
urlmon_instance = hinstDLL;
|
||||
init_session();
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
process_detach();
|
||||
DeleteCriticalSection(&tls_cs);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
|
@ -163,6 +168,67 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
const char *debugstr_bindstatus(ULONG status)
|
||||
{
|
||||
switch(status) {
|
||||
#define X(x) case x: return #x
|
||||
X(BINDSTATUS_FINDINGRESOURCE);
|
||||
X(BINDSTATUS_CONNECTING);
|
||||
X(BINDSTATUS_REDIRECTING);
|
||||
X(BINDSTATUS_BEGINDOWNLOADDATA);
|
||||
X(BINDSTATUS_DOWNLOADINGDATA);
|
||||
X(BINDSTATUS_ENDDOWNLOADDATA);
|
||||
X(BINDSTATUS_BEGINDOWNLOADCOMPONENTS);
|
||||
X(BINDSTATUS_INSTALLINGCOMPONENTS);
|
||||
X(BINDSTATUS_ENDDOWNLOADCOMPONENTS);
|
||||
X(BINDSTATUS_USINGCACHEDCOPY);
|
||||
X(BINDSTATUS_SENDINGREQUEST);
|
||||
X(BINDSTATUS_CLASSIDAVAILABLE);
|
||||
X(BINDSTATUS_MIMETYPEAVAILABLE);
|
||||
X(BINDSTATUS_CACHEFILENAMEAVAILABLE);
|
||||
X(BINDSTATUS_BEGINSYNCOPERATION);
|
||||
X(BINDSTATUS_ENDSYNCOPERATION);
|
||||
X(BINDSTATUS_BEGINUPLOADDATA);
|
||||
X(BINDSTATUS_UPLOADINGDATA);
|
||||
X(BINDSTATUS_ENDUPLOADINGDATA);
|
||||
X(BINDSTATUS_PROTOCOLCLASSID);
|
||||
X(BINDSTATUS_ENCODING);
|
||||
X(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE);
|
||||
X(BINDSTATUS_CLASSINSTALLLOCATION);
|
||||
X(BINDSTATUS_DECODING);
|
||||
X(BINDSTATUS_LOADINGMIMEHANDLER);
|
||||
X(BINDSTATUS_CONTENTDISPOSITIONATTACH);
|
||||
X(BINDSTATUS_FILTERREPORTMIMETYPE);
|
||||
X(BINDSTATUS_CLSIDCANINSTANTIATE);
|
||||
X(BINDSTATUS_IUNKNOWNAVAILABLE);
|
||||
X(BINDSTATUS_DIRECTBIND);
|
||||
X(BINDSTATUS_RAWMIMETYPE);
|
||||
X(BINDSTATUS_PROXYDETECTING);
|
||||
X(BINDSTATUS_ACCEPTRANGES);
|
||||
X(BINDSTATUS_COOKIE_SENT);
|
||||
X(BINDSTATUS_COMPACT_POLICY_RECEIVED);
|
||||
X(BINDSTATUS_COOKIE_SUPPRESSED);
|
||||
X(BINDSTATUS_COOKIE_STATE_UNKNOWN);
|
||||
X(BINDSTATUS_COOKIE_STATE_ACCEPT);
|
||||
X(BINDSTATUS_COOKIE_STATE_REJECT);
|
||||
X(BINDSTATUS_COOKIE_STATE_PROMPT);
|
||||
X(BINDSTATUS_COOKIE_STATE_LEASH);
|
||||
X(BINDSTATUS_COOKIE_STATE_DOWNGRADE);
|
||||
X(BINDSTATUS_POLICY_HREF);
|
||||
X(BINDSTATUS_P3P_HEADER);
|
||||
X(BINDSTATUS_SESSION_COOKIE_RECEIVED);
|
||||
X(BINDSTATUS_PERSISTENT_COOKIE_RECEIVED);
|
||||
X(BINDSTATUS_SESSION_COOKIES_ALLOWED);
|
||||
X(BINDSTATUS_CACHECONTROL);
|
||||
X(BINDSTATUS_CONTENTDISPOSITIONFILENAME);
|
||||
X(BINDSTATUS_MIMETEXTPLAINMISMATCH);
|
||||
X(BINDSTATUS_PUBLISHERAVAILABLE);
|
||||
X(BINDSTATUS_DISPLAYNAMEAVAILABLE);
|
||||
#undef X
|
||||
default:
|
||||
return wine_dbg_sprintf("(invalid status %u)", status);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllInstall (URLMON.@)
|
||||
|
@ -291,6 +357,8 @@ static ClassFactory StdURLMonikerCF =
|
|||
{ { &ClassFactoryVtbl }, StdURLMoniker_Construct};
|
||||
static ClassFactory MimeFilterCF =
|
||||
{ { &ClassFactoryVtbl }, MimeFilter_Construct};
|
||||
static ClassFactory CUriCF =
|
||||
{ { &ClassFactoryVtbl }, Uri_Construct};
|
||||
|
||||
struct object_creation_info
|
||||
{
|
||||
|
@ -317,18 +385,18 @@ static const struct object_creation_info object_creation[] =
|
|||
{ &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL },
|
||||
{ &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL },
|
||||
{ &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL },
|
||||
{ &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL }
|
||||
{ &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL },
|
||||
{ &CLSID_CUri, &CUriCF.IClassFactory_iface, NULL }
|
||||
};
|
||||
|
||||
static void init_session(BOOL init)
|
||||
static void init_session(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) {
|
||||
|
||||
if(object_creation[i].protocol)
|
||||
register_urlmon_namespace(object_creation[i].cf, object_creation[i].clsid,
|
||||
object_creation[i].protocol, init);
|
||||
register_namespace(object_creation[i].cf, object_creation[i].clsid,
|
||||
object_creation[i].protocol, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,6 +594,8 @@ HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
|
|||
if(src->u.lpszFileName && !src->pUnkForRelease) {
|
||||
DWORD size = (strlenW(src->u.lpszFileName)+1)*sizeof(WCHAR);
|
||||
dst->u.lpszFileName = CoTaskMemAlloc(size);
|
||||
if(!dst->u.lpszFileName)
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(dst->u.lpszFileName, src->u.lpszFileName, size);
|
||||
}
|
||||
break;
|
||||
|
@ -537,6 +607,21 @@ HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
|
|||
if(dst->u.pstg)
|
||||
IStorage_AddRef(dst->u.pstg);
|
||||
break;
|
||||
case TYMED_HGLOBAL:
|
||||
if(dst->u.hGlobal) {
|
||||
SIZE_T size = GlobalSize(src->u.hGlobal);
|
||||
char *src_ptr, *dst_ptr;
|
||||
|
||||
dst->u.hGlobal = GlobalAlloc(GMEM_FIXED, size);
|
||||
if(!dst->u.hGlobal)
|
||||
return E_OUTOFMEMORY;
|
||||
dst_ptr = GlobalLock(dst->u.hGlobal);
|
||||
src_ptr = GlobalLock(src->u.hGlobal);
|
||||
memcpy(dst_ptr, src_ptr, size);
|
||||
GlobalUnlock(src_ptr);
|
||||
GlobalUnlock(dst_ptr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unimplemented tymed %d\n", src->tymed);
|
||||
}
|
||||
|
@ -547,6 +632,70 @@ HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CopyBindInfo (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
|
||||
{
|
||||
DWORD size;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %p)\n", pcbiSrc, pcbiDest);
|
||||
|
||||
if(!pcbiSrc || !pcbiDest)
|
||||
return E_POINTER;
|
||||
if(!pcbiSrc->cbSize || !pcbiDest->cbSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size = pcbiDest->cbSize;
|
||||
if(size > pcbiSrc->cbSize) {
|
||||
memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize);
|
||||
memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize);
|
||||
} else {
|
||||
memcpy(pcbiDest, pcbiSrc, size);
|
||||
}
|
||||
pcbiDest->cbSize = size;
|
||||
|
||||
size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*);
|
||||
if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) {
|
||||
size = (strlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR);
|
||||
pcbiDest->szExtraInfo = CoTaskMemAlloc(size);
|
||||
if(!pcbiDest->szExtraInfo)
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size);
|
||||
}
|
||||
|
||||
size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM);
|
||||
if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) {
|
||||
hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData);
|
||||
if(FAILED(hres)) {
|
||||
CoTaskMemFree(pcbiDest->szExtraInfo);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*);
|
||||
if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) {
|
||||
size = (strlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR);
|
||||
pcbiDest->szCustomVerb = CoTaskMemAlloc(size);
|
||||
if(!pcbiDest->szCustomVerb) {
|
||||
CoTaskMemFree(pcbiDest->szExtraInfo);
|
||||
ReleaseStgMedium(&pcbiDest->stgmedData);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size);
|
||||
}
|
||||
|
||||
size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES);
|
||||
if(pcbiDest->cbSize >= size)
|
||||
memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
|
||||
if(pcbiSrc->pUnk)
|
||||
IUnknown_AddRef(pcbiDest->pUnk);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL text_richtext_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 5 && !memcmp(b, "{\\rtf", 5);
|
||||
|
@ -554,19 +703,33 @@ static BOOL text_richtext_filter(const BYTE *b, DWORD size)
|
|||
|
||||
static BOOL text_html_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if(size < 5)
|
||||
if(size < 6)
|
||||
return FALSE;
|
||||
|
||||
for(i=0; i < size-5; i++) {
|
||||
if(b[i] == '<'
|
||||
&& (b[i+1] == 'h' || b[i+1] == 'H')
|
||||
&& (b[i+2] == 't' || b[i+2] == 'T')
|
||||
&& (b[i+3] == 'm' || b[i+3] == 'M')
|
||||
&& (b[i+4] == 'l' || b[i+4] == 'L'))
|
||||
return TRUE;
|
||||
}
|
||||
if((b[0] == '<'
|
||||
&& (b[1] == 'h' || b[1] == 'H')
|
||||
&& (b[2] == 't' || b[2] == 'T')
|
||||
&& (b[3] == 'm' || b[3] == 'M')
|
||||
&& (b[4] == 'l' || b[4] == 'L'))
|
||||
|| (b[0] == '<'
|
||||
&& (b[1] == 'h' || b[1] == 'H')
|
||||
&& (b[2] == 'e' || b[2] == 'E')
|
||||
&& (b[3] == 'a' || b[3] == 'A')
|
||||
&& (b[4] == 'd' || b[4] == 'D'))) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL text_xml_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
if(size < 7)
|
||||
return FALSE;
|
||||
|
||||
if(b[0] == '<' && b[1] == '?'
|
||||
&& (b[2] == 'x' || b[2] == 'X')
|
||||
&& (b[3] == 'm' || b[3] == 'M')
|
||||
&& (b[4] == 'l' || b[4] == 'L')
|
||||
&& b[5] == ' ') return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -602,7 +765,10 @@ static BOOL image_pjpeg_filter(const BYTE *b, DWORD size)
|
|||
|
||||
static BOOL image_tiff_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 0x4d && b[1] == 0x4d;
|
||||
static const BYTE magic1[] = {0x4d,0x4d,0x00,0x2a};
|
||||
static const BYTE magic2[] = {0x49,0x49,0x2a,0xff};
|
||||
|
||||
return size >= 4 && (!memcmp(b, magic1, 4) || !memcmp(b, magic2, 4));
|
||||
}
|
||||
|
||||
static BOOL image_xpng_filter(const BYTE *b, DWORD size)
|
||||
|
@ -662,12 +828,19 @@ static BOOL application_xmsdownload(const BYTE *b, DWORD size)
|
|||
return size > 2 && b[0] == 'M' && b[1] == 'Z';
|
||||
}
|
||||
|
||||
static inline BOOL is_text_plain_char(BYTE b)
|
||||
{
|
||||
if(b < 0x20 && b != '\n' && b != '\r' && b != '\t')
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL text_plain_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
const BYTE *ptr;
|
||||
|
||||
for(ptr = b; ptr < b+size-1; ptr++) {
|
||||
if(*ptr < 0x20 && *ptr != '\n' && *ptr != '\r' && *ptr != '\t')
|
||||
if(!is_text_plain_char(*ptr))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -682,10 +855,11 @@ static BOOL application_octet_stream_filter(const BYTE *b, DWORD size)
|
|||
static HRESULT find_mime_from_buffer(const BYTE *buf, DWORD size, const WCHAR *proposed_mime, WCHAR **ret_mime)
|
||||
{
|
||||
LPCWSTR ret = NULL;
|
||||
DWORD len, i;
|
||||
int len, i, any_pos_mime = -1;
|
||||
|
||||
static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
|
||||
static const WCHAR text_richtextW[] = {'t','e','x','t','/','r','i','c','h','t','e','x','t',0};
|
||||
static const WCHAR text_xmlW[] = {'t','e','x','t','/','x','m','l',0};
|
||||
static const WCHAR audio_basicW[] = {'a','u','d','i','o','/','b','a','s','i','c',0};
|
||||
static const WCHAR audio_wavW[] = {'a','u','d','i','o','/','w','a','v',0};
|
||||
static const WCHAR image_gifW[] = {'i','m','a','g','e','/','g','i','f',0};
|
||||
|
@ -713,8 +887,10 @@ static HRESULT find_mime_from_buffer(const BYTE *buf, DWORD size, const WCHAR *p
|
|||
static const struct {
|
||||
LPCWSTR mime;
|
||||
BOOL (*filter)(const BYTE *,DWORD);
|
||||
} mime_filters[] = {
|
||||
} mime_filters_any_pos[] = {
|
||||
{text_htmlW, text_html_filter},
|
||||
{text_xmlW, text_xml_filter}
|
||||
}, mime_filters[] = {
|
||||
{text_richtextW, text_richtext_filter},
|
||||
/* {audio_xaiffW, audio_xaiff_filter}, */
|
||||
{audio_basicW, audio_basic_filter},
|
||||
|
@ -756,20 +932,47 @@ static HRESULT find_mime_from_buffer(const BYTE *buf, DWORD size, const WCHAR *p
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if(proposed_mime && strcmpW(proposed_mime, app_octetstreamW)) {
|
||||
for(i=0; i < sizeof(mime_filters)/sizeof(*mime_filters); i++) {
|
||||
if(!strcmpW(proposed_mime, mime_filters[i].mime))
|
||||
if(proposed_mime && (!strcmpW(proposed_mime, app_octetstreamW)
|
||||
|| !strcmpW(proposed_mime, text_plainW)))
|
||||
proposed_mime = NULL;
|
||||
|
||||
if(proposed_mime) {
|
||||
ret = proposed_mime;
|
||||
|
||||
for(i=0; i < sizeof(mime_filters_any_pos)/sizeof(*mime_filters_any_pos); i++) {
|
||||
if(!strcmpW(proposed_mime, mime_filters_any_pos[i].mime)) {
|
||||
any_pos_mime = i;
|
||||
for(len=size; len>0; len--) {
|
||||
if(mime_filters_any_pos[i].filter(buf+size-len, len))
|
||||
break;
|
||||
}
|
||||
if(!len)
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == sizeof(mime_filters)/sizeof(*mime_filters) || mime_filters[i].filter(buf, size)) {
|
||||
len = strlenW(proposed_mime)+1;
|
||||
*ret_mime = CoTaskMemAlloc(len*sizeof(WCHAR));
|
||||
if(!*ret_mime)
|
||||
return E_OUTOFMEMORY;
|
||||
if(i == sizeof(mime_filters_any_pos)/sizeof(*mime_filters_any_pos)) {
|
||||
for(i=0; i < sizeof(mime_filters)/sizeof(*mime_filters); i++) {
|
||||
if(!strcmpW(proposed_mime, mime_filters[i].mime)) {
|
||||
if(!mime_filters[i].filter(buf, size))
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(*ret_mime, proposed_mime, len*sizeof(WCHAR));
|
||||
return S_OK;
|
||||
/* Looks like a bug in native implementation, html and xml mimes
|
||||
* are not looked for if none of them was proposed */
|
||||
if(!proposed_mime || any_pos_mime!=-1) {
|
||||
for(len=size; !ret && len>0; len--) {
|
||||
for(i=0; i<sizeof(mime_filters_any_pos)/sizeof(*mime_filters_any_pos); i++) {
|
||||
if(mime_filters_any_pos[i].filter(buf+size-len, len)) {
|
||||
ret = mime_filters_any_pos[i].mime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -780,16 +983,24 @@ static HRESULT find_mime_from_buffer(const BYTE *buf, DWORD size, const WCHAR *p
|
|||
i++;
|
||||
}
|
||||
|
||||
TRACE("found %s for %s\n", debugstr_w(ret), debugstr_an((const char*)buf, min(32, size)));
|
||||
if(any_pos_mime!=-1 && ret==text_plainW)
|
||||
ret = mime_filters_any_pos[any_pos_mime].mime;
|
||||
else if(proposed_mime && ret==app_octetstreamW) {
|
||||
for(len=size; ret==app_octetstreamW && len>0; len--) {
|
||||
if(!is_text_plain_char(buf[size-len]))
|
||||
break;
|
||||
for(i=0; i<sizeof(mime_filters_any_pos)/sizeof(*mime_filters_any_pos); i++) {
|
||||
if(mime_filters_any_pos[i].filter(buf+size-len, len)) {
|
||||
ret = text_plainW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(proposed_mime) {
|
||||
if(i == sizeof(mime_filters)/sizeof(*mime_filters))
|
||||
if(ret == app_octetstreamW)
|
||||
ret = proposed_mime;
|
||||
|
||||
/* text/html is a special case */
|
||||
if(!strcmpW(proposed_mime, text_htmlW) && !strcmpW(ret, text_plainW))
|
||||
ret = text_htmlW;
|
||||
}
|
||||
TRACE("found %s for %s\n", debugstr_w(ret), debugstr_an((const char*)buf, min(32, size)));
|
||||
|
||||
len = strlenW(ret)+1;
|
||||
*ret_mime = CoTaskMemAlloc(len*sizeof(WCHAR));
|
||||
|
@ -865,9 +1076,8 @@ HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename,
|
|||
LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved,
|
||||
CLSID *pclsid)
|
||||
{
|
||||
FIXME("(%p, %s, %p, %d, %p, 0x%08x, %p): stub\n", pBC,
|
||||
debugstr_w(pszFilename), pBuffer, cbBuffer, debugstr_w(pszMimeType),
|
||||
dwReserved, pclsid);
|
||||
FIXME("(%p, %s, %p, %d, %s, 0x%08x, %p): stub\n", pBC, debugstr_w(pszFilename), pBuffer,
|
||||
cbBuffer, debugstr_w(pszMimeType), dwReserved, pclsid);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
@ -907,21 +1117,69 @@ BOOL WINAPI IsLoggingEnabledW(LPCWSTR url)
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* URLMON_410 (URLMON.410)
|
||||
* Undocumented, added in IE8
|
||||
* IsProtectedModeURL (URLMON.111)
|
||||
* Undocumented, added in IE7
|
||||
*/
|
||||
BOOL WINAPI URLMON_410(DWORD unknown1, DWORD unknown2)
|
||||
BOOL WINAPI IsProtectedModeURL(const WCHAR *url)
|
||||
{
|
||||
FIXME("stub: %d %d\n", unknown1, unknown2);
|
||||
return FALSE;
|
||||
FIXME("stub: %s\n", debugstr_w(url));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* URLMON_423 (URLMON.423)
|
||||
* LogSqmBits (URLMON.410)
|
||||
* Undocumented, added in IE8
|
||||
*/
|
||||
BOOL WINAPI URLMON_423(DWORD unknown1, DWORD unknown2, DWORD unknown3, DWORD unknown4)
|
||||
int WINAPI LogSqmBits(DWORD unk1, DWORD unk2)
|
||||
{
|
||||
FIXME("stub: %d %d %d %d\n", unknown1, unknown2, unknown3, unknown4);
|
||||
return FALSE;
|
||||
FIXME("stub: %d %d\n", unk1, unk2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LogSqmUXCommandOffsetInternal (URLMON.423)
|
||||
* Undocumented, added in IE8
|
||||
*/
|
||||
void WINAPI LogSqmUXCommandOffsetInternal(DWORD unk1, DWORD unk2, DWORD unk3, DWORD unk4)
|
||||
{
|
||||
FIXME("stub: %d %d %d %d\n", unk1, unk2, unk3, unk4);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MapUriToBrowserEmulationState (URLMON.444)
|
||||
* Undocumented, added in IE8
|
||||
*/
|
||||
int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
|
||||
{
|
||||
FIXME("stub: %d %d %d\n", unk1, unk2, unk3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MapBrowserEmulationModeToUserAgent (URLMON.445)
|
||||
* Undocumented, added in IE8
|
||||
*/
|
||||
int WINAPI MapBrowserEmulationModeToUserAgent(DWORD unk1, DWORD unk2)
|
||||
{
|
||||
FIXME("stub: %d %d\n", unk1, unk2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FlushUrlmonZonesCache (URLMON.455)
|
||||
* Undocumented, added in IE8
|
||||
*/
|
||||
void WINAPI FlushUrlmonZonesCache(void)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterMediaTypes
|
||||
* Added in IE3, registers known MIME-type strings.
|
||||
*/
|
||||
HRESULT WINAPI RegisterMediaTypes(UINT types, LPCSTR *szTypes, CLIPFORMAT *cfTypes)
|
||||
{
|
||||
FIXME("stub: %u %p %p\n", types, szTypes, cfTypes);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPE
|
|||
extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
|
||||
extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
|
||||
extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
|
||||
extern HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL WINAPI URLMON_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DECLSPEC_HIDDEN;
|
||||
extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
|
@ -60,6 +61,7 @@ extern HRESULT WINAPI URLMON_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
|||
extern HRESULT WINAPI URLMON_DllUnregisterServer(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN;
|
||||
extern GUID const CLSID_CUri DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* Dll lifetime tracking declaration for urlmon.dll
|
||||
|
@ -68,11 +70,13 @@ extern LONG URLMON_refCount DECLSPEC_HIDDEN;
|
|||
static inline void URLMON_LockModule(void) { InterlockedIncrement( &URLMON_refCount ); }
|
||||
static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_refCount ); }
|
||||
|
||||
extern HINSTANCE urlmon_instance;
|
||||
|
||||
IInternetProtocolInfo *get_protocol_info(LPCWSTR) DECLSPEC_HIDDEN;
|
||||
HRESULT get_protocol_handler(IUri*,CLSID*,BOOL*,IClassFactory**) DECLSPEC_HIDDEN;
|
||||
IInternetProtocol *get_mime_filter(LPCWSTR) DECLSPEC_HIDDEN;
|
||||
BOOL is_registered_protocol(LPCWSTR) DECLSPEC_HIDDEN;
|
||||
void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL) DECLSPEC_HIDDEN;
|
||||
HRESULT register_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL) DECLSPEC_HIDDEN;
|
||||
HINTERNET get_internet_session(IInternetBindInfo*) DECLSPEC_HIDDEN;
|
||||
LPWSTR get_useragent(void) DECLSPEC_HIDDEN;
|
||||
void free_session(void) DECLSPEC_HIDDEN;
|
||||
|
@ -82,6 +86,10 @@ HRESULT bind_to_object(IMoniker*,IUri*,IBindCtx*,REFIID,void**ppv) DECLSPEC_HIDD
|
|||
|
||||
HRESULT create_default_callback(IBindStatusCallback**) DECLSPEC_HIDDEN;
|
||||
HRESULT wrap_callback(IBindStatusCallback*,IBindStatusCallback**) DECLSPEC_HIDDEN;
|
||||
IBindStatusCallback *bsc_from_bctx(IBindCtx*) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef HRESULT (*stop_cache_binding_proc_t)(void*,const WCHAR*,HRESULT,const WCHAR*);
|
||||
HRESULT download_to_cache(IUri*,stop_cache_binding_proc_t,void*,IBindStatusCallback*) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct ProtocolVtbl ProtocolVtbl;
|
||||
|
||||
|
@ -102,6 +110,7 @@ typedef struct {
|
|||
ULONG current_position;
|
||||
ULONG content_length;
|
||||
ULONG available_bytes;
|
||||
ULONG query_available;
|
||||
|
||||
IStream *post_stream;
|
||||
|
||||
|
@ -146,6 +155,7 @@ struct ProtocolVtbl {
|
|||
#define FLAG_LAST_DATA_REPORTED 0x0010
|
||||
#define FLAG_RESULT_REPORTED 0x0020
|
||||
#define FLAG_ERROR 0x0040
|
||||
#define FLAG_SYNC_READ 0x0080
|
||||
|
||||
HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN;
|
||||
HRESULT protocol_continue(Protocol*,PROTOCOLDATA*) DECLSPEC_HIDDEN;
|
||||
|
@ -153,22 +163,11 @@ HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*) DECLSPEC_HIDDEN;
|
|||
HRESULT protocol_lock_request(Protocol*) DECLSPEC_HIDDEN;
|
||||
HRESULT protocol_unlock_request(Protocol*) DECLSPEC_HIDDEN;
|
||||
HRESULT protocol_abort(Protocol*,HRESULT) DECLSPEC_HIDDEN;
|
||||
HRESULT protocol_syncbinding(Protocol*) DECLSPEC_HIDDEN;
|
||||
void protocol_close_connection(Protocol*) DECLSPEC_HIDDEN;
|
||||
|
||||
void find_domain_name(const WCHAR*,DWORD,INT*) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct {
|
||||
IInternetProtocol IInternetProtocol_iface;
|
||||
IInternetProtocolSink IInternetProtocolSink_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
IInternetProtocolSink *protocol_sink;
|
||||
IInternetProtocol *protocol;
|
||||
} ProtocolProxy;
|
||||
|
||||
HRESULT create_protocol_proxy(IInternetProtocol*,IInternetProtocolSink*,ProtocolProxy**) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct _task_header_t task_header_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -190,8 +189,10 @@ typedef struct {
|
|||
|
||||
struct {
|
||||
IInternetProtocol IInternetProtocol_iface;
|
||||
IInternetProtocolSink IInternetProtocolSink_iface;
|
||||
} default_protocol_handler;
|
||||
IInternetProtocol *protocol_handler;
|
||||
IInternetProtocolSink *protocol_sink_handler;
|
||||
|
||||
LONG priority;
|
||||
|
||||
|
@ -215,7 +216,7 @@ typedef struct {
|
|||
DWORD buf_size;
|
||||
LPWSTR mime;
|
||||
IUri *uri;
|
||||
ProtocolProxy *filter_proxy;
|
||||
BSTR display_uri;
|
||||
} BindProtocol;
|
||||
|
||||
HRESULT create_binding_protocol(BOOL,BindProtocol**) DECLSPEC_HIDDEN;
|
||||
|
@ -233,6 +234,8 @@ tls_data_t *get_tls_data(void) DECLSPEC_HIDDEN;
|
|||
HWND get_notif_hwnd(void) DECLSPEC_HIDDEN;
|
||||
void release_notif_hwnd(HWND) DECLSPEC_HIDDEN;
|
||||
|
||||
const char *debugstr_bindstatus(ULONG) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline void *heap_alloc(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||
|
@ -267,7 +270,8 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
|
|||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = heap_alloc(size);
|
||||
memcpy(ret, str, size);
|
||||
if(ret)
|
||||
memcpy(ret, str, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -295,7 +299,22 @@ static inline LPWSTR heap_strdupAtoW(const char *str)
|
|||
if(str) {
|
||||
DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
|
||||
ret = heap_alloc(len*sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
|
||||
if(ret)
|
||||
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *heap_strdupWtoA(const WCHAR *str)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
if(str) {
|
||||
size_t size = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
|
||||
ret = heap_alloc(size);
|
||||
if(ret)
|
||||
WideCharToMultiByte(CP_ACP, 0, str, -1, ret, size, NULL, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -18,20 +18,12 @@
|
|||
|
||||
#include "urlmon.idl"
|
||||
|
||||
#ifndef __WIDL__
|
||||
#define threading(model)
|
||||
#define progid(str)
|
||||
#define vi_progid(str)
|
||||
#endif
|
||||
|
||||
#ifndef __midl
|
||||
[
|
||||
helpstring("URL Moniker"),
|
||||
threading(apartment),
|
||||
uuid(79eac9e0-baf9-11ce-8c82-00aa004ba90b)
|
||||
]
|
||||
coclass StdURLMoniker { interface IMoniker; }
|
||||
#endif
|
||||
|
||||
[
|
||||
helpstring("http: Asynchronous Pluggable Protocol Handler"),
|
||||
|
@ -68,14 +60,12 @@ coclass HttpsProtocol { interface IInternetProtocolEx; interface IInternetPriori
|
|||
]
|
||||
coclass MkProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
|
||||
|
||||
#ifndef __midl
|
||||
[
|
||||
helpstring("file:, local: Asynchronous Pluggable Protocol Handler"),
|
||||
threading(apartment),
|
||||
uuid(79eac9e7-baf9-11ce-8c82-00aa004ba90b)
|
||||
]
|
||||
coclass FileProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
|
||||
#endif
|
||||
|
||||
[
|
||||
helpstring("CDL: Asynchronous Pluggable Protocol Handler"),
|
||||
|
@ -111,3 +101,10 @@ coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
|||
uuid(8f6b0360-b80d-11d0-a9b3-006097942311)
|
||||
]
|
||||
coclass DeCompMimeFilter { interface IInternetProtocol; interface IInternetProtocolSink; }
|
||||
|
||||
[
|
||||
helpstring("CUri"),
|
||||
threading(apartment),
|
||||
uuid(df2fce13-25ec-45bb-9d4c-cecd47c2430c)
|
||||
]
|
||||
coclass CUri { interface IUri; }
|
||||
|
|
141
reactos/dll/win32/urlmon/urlmon_urlmon.rgs
Normal file
141
reactos/dll/win32/urlmon/urlmon_urlmon.rgs
Normal file
|
@ -0,0 +1,141 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove Interface
|
||||
{
|
||||
'{79EAC9C0-BAF9-11CE-8C82-00AA004BA90B}' = s 'IBinding'
|
||||
{
|
||||
NumMethods = s 9
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9C1-BAF9-11CE-8C82-00AA004BA90B}' = s 'IBindStatusCallback'
|
||||
{
|
||||
NumMethods = s 11
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{AAA74EF9-8EE7-4659-88D9-F8C504DA73CC}' = s 'IBindStatusCallbackEx'
|
||||
{
|
||||
NumMethods = s 12
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}' = s 'IAuthenticate'
|
||||
{
|
||||
NumMethods = s 4
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9D2-BAF9-11CE-8C82-00AA004BA90B}' = s 'IHttpNegotiate'
|
||||
{
|
||||
NumMethods = s 5
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{4F9F9FCB-E0F4-48EB-B7AB-FA2EA9365CB4}' = s 'IHttpNegotiate2'
|
||||
{
|
||||
NumMethods = s 6
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{FC4801A1-2BA9-11CF-A229-00AA003D7352}' = s 'IBindHost'
|
||||
{
|
||||
NumMethods = s 6
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9D6-BAFA-11CE-8C82-00AA004BA90B}' = s 'IWinInetInfo'
|
||||
{
|
||||
NumMethods = s 4
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9D8-BAFA-11CE-8C82-00AA004BA90B}' = s 'IWinInetHttpInfo'
|
||||
{
|
||||
NumMethods = s 5
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9D7-BAFA-11CE-8C82-00AA004BA90B}' = s 'IHttpSecurity'
|
||||
{
|
||||
NumMethods = s 5
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9C9-BAF9-11CE-8C82-00AA004BA90B}' = s 'IPersistMoniker'
|
||||
{
|
||||
NumMethods = s 9
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{A5CA5F7F-1847-4D87-9C5B-918509F7511D}' = s 'IMonikerProp'
|
||||
{
|
||||
NumMethods = s 4
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{79EAC9EE-BAF9-11CE-8C82-00AA004BA90B}' = s 'IInternetSecurityManager'
|
||||
{
|
||||
NumMethods = s 11
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{F164EDF1-CC7C-4F0D-9A94-34222625C393}' = s 'IInternetSecurityManagerEx'
|
||||
{
|
||||
NumMethods = s 12
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{F1E50292-A795-4117-8E09-2B560A72AC60}' = s 'IInternetSecurityManagerEx2'
|
||||
{
|
||||
NumMethods = s 16
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
'{A39EE748-6A27-4817-A6F2-13914BEF5890}' = s 'IUri'
|
||||
{
|
||||
NumMethods = s 28
|
||||
ProxyStubClsid32 = s '{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}'
|
||||
}
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
'{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}' = s 'URL Moniker'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E2-BAF9-11CE-8C82-00AA004BA90B}' = s 'http: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E3-BAF9-11CE-8C82-00AA004BA90B}' = s 'ftp: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E4-BAF9-11CE-8C82-00AA004BA90B}' = s 'gopher: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E5-BAF9-11CE-8C82-00AA004BA90B}' = s 'https: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E6-BAF9-11CE-8C82-00AA004BA90B}' = s 'mk: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{79EAC9E7-BAF9-11CE-8C82-00AA004BA90B}' = s 'file:, local: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{3DD53D40-7B8B-11D0-B013-00AA0059CE02}' = s 'CDL: Asynchronous Pluggable Protocol Handler'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{7B8A2D94-0AC9-11D1-896C-00C04FB6BFC4}' = s 'Security Manager'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
}
|
||||
'{7B8A2D95-0AC9-11D1-896C-00C04FB6BFC4}' = s 'URL Zone Manager'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
}
|
||||
'{79EAC9F1-BAF9-11CE-8C82-00AA004BA90B}' = s 'URLMoniker ProxyStub Factory'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{8F6B0360-B80D-11D0-A9B3-006097942311}' = s 'AP lzdhtml encoding/decoding Filter'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
'{DF2FCE13-25EC-45BB-9D4C-CECD47C2430C}' = s 'CUri'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,30 +26,30 @@ HRESULT CALLBACK IWinInetHttpInfo_QueryInfo_Proxy(IWinInetHttpInfo* This,
|
|||
DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
|
||||
DWORD *pdwReserved)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
|
||||
return IWinInetHttpInfo_RemoteQueryInfo_Proxy(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
|
||||
}
|
||||
|
||||
HRESULT __RPC_STUB IWinInetHttpInfo_QueryInfo_Stub(IWinInetHttpInfo* This,
|
||||
DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
|
||||
DWORD *pdwReserved)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
|
||||
return IWinInetHttpInfo_QueryInfo(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
|
||||
}
|
||||
|
||||
HRESULT CALLBACK IWinInetInfo_QueryOption_Proxy(IWinInetInfo* This,
|
||||
DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
|
||||
return IWinInetInfo_RemoteQueryOption_Proxy(This, dwOption, pBuffer, pcbBuf);
|
||||
}
|
||||
|
||||
HRESULT __RPC_STUB IWinInetInfo_QueryOption_Stub(IWinInetInfo* This,
|
||||
DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
|
||||
return IWinInetInfo_QueryOption(This, dwOption, pBuffer, pcbBuf);
|
||||
}
|
||||
|
||||
HRESULT CALLBACK IBindHost_MonikerBindToStorage_Proxy(IBindHost* This,
|
||||
|
@ -146,17 +146,3 @@ HRESULT __RPC_STUB IBinding_GetBindResult_Stub(IBinding* This,
|
|||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IWindowForBindingUI_GetWindow_Proxy(
|
||||
IWindowForBindingUI* This, REFGUID rguidReason, HWND *phwnd)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
void __RPC_STUB IWindowForBindingUI_GetWindow_Stub(IRpcStubBuffer* This,
|
||||
IRpcChannelBuffer* pRpcChannelBuffer, PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ cpp_quote("#undef SetPort")
|
|||
cpp_quote("#endif")
|
||||
|
||||
interface IInternetProtocolSink;
|
||||
interface IUri;
|
||||
|
||||
/*****************************************************************************
|
||||
* IInternet interface
|
||||
|
@ -354,7 +355,6 @@ interface IBindStatusCallbackEx : IBindStatusCallback
|
|||
* IAuthenticate interface
|
||||
*/
|
||||
[
|
||||
local,
|
||||
object,
|
||||
uuid(79EAC9D0-BAf9-11CE-8C82-00AA004BA90B),
|
||||
pointer_default(unique)
|
||||
|
@ -540,6 +540,39 @@ interface IWindowForBindingUI : IUnknown
|
|||
[out] HWND *phwnd);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ICodeInstall interface
|
||||
*/
|
||||
[
|
||||
local,
|
||||
object,
|
||||
uuid(79eac9d1-baf9-11ce-8c82-00aa004ba90b),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ICodeInstall : IWindowForBindingUI
|
||||
{
|
||||
typedef [unique] ICodeInstall *LPCODEINSTALL;
|
||||
|
||||
typedef enum {
|
||||
CIP_DISK_FULL,
|
||||
CIP_ACCESS_DENIED,
|
||||
CIP_NEWER_VERSION_EXISTS,
|
||||
CIP_OLDER_VERSION_EXISTS,
|
||||
CIP_NAME_CONFLICT,
|
||||
CIP_TRUST_VERIFICATION_COMPONENT_MISSING,
|
||||
CIP_EXE_SELF_REGISTERATION_TIMEOUT,
|
||||
CIP_UNSAFE_TO_ABORT,
|
||||
CIP_NEED_REBOOT,
|
||||
CIP_NEED_REBOOT_UI_PERMISSION
|
||||
} CIP_STATUS;
|
||||
|
||||
HRESULT OnCodeInstallProblem(
|
||||
[in] ULONG ulStatusCode,
|
||||
[in, unique] LPCWSTR szDestination,
|
||||
[in, unique] LPCWSTR szSource,
|
||||
[in] DWORD dwReserved);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IHttpSecurity interface
|
||||
*/
|
||||
|
@ -880,7 +913,8 @@ interface IInternetProtocolInfo : IUnknown
|
|||
QUERY_USES_CACHE,
|
||||
QUERY_IS_SECURE,
|
||||
QUERY_IS_SAFE,
|
||||
QUERY_USES_HISTORYFOLDER
|
||||
QUERY_USES_HISTORYFOLDER,
|
||||
QUERY_IS_CACHED_AND_USABLE_OFFLINE
|
||||
} QUERYOPTION;
|
||||
|
||||
HRESULT ParseUrl(
|
||||
|
@ -1066,6 +1100,76 @@ cpp_quote("#define MAX_SIZE_SECURITY_ID 512")
|
|||
[in] DWORD dwFlags);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IInternetSecurityManagerEx interface
|
||||
*/
|
||||
cpp_quote("#define SID_SInternetSecurityManagerEx IID_IInternetSecurityManagerEx")
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(f164edf1-cc7c-4f0d-9a94-34222625C393),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IInternetSecurityManagerEx : IInternetSecurityManager
|
||||
{
|
||||
HRESULT ProcessUrlActionEx(
|
||||
[in] LPCWSTR pwszUrl,
|
||||
[in] DWORD dwAction,
|
||||
[out] BYTE *pPolicy,
|
||||
[in] DWORD cbPolicy,
|
||||
[in] BYTE *pContext,
|
||||
[in] DWORD cbContext,
|
||||
[in] DWORD dwFlags,
|
||||
[in] DWORD dwReserved,
|
||||
[out] DWORD *pdwOutFlags);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IInternetSecurityManagerEx2 interface
|
||||
*/
|
||||
cpp_quote("#define SID_SInternetSecurityManagerEx2 IID_IInternetSecurityManagerEx2")
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(f1e50292-a795-4117-8e09-2b560a72ac60),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IInternetSecurityManagerEx2 : IInternetSecurityManagerEx
|
||||
{
|
||||
HRESULT MapUrlToZoneEx2(
|
||||
[in] IUri *pUri,
|
||||
[out] DWORD *pdwZone,
|
||||
[in] DWORD dwFlags,
|
||||
[out] LPWSTR *ppwszMappedUrl,
|
||||
[out] DWORD *pdwOutFlags);
|
||||
|
||||
HRESULT ProcessUrlActionEx2(
|
||||
[in] IUri *pUri,
|
||||
[in] DWORD dwAction,
|
||||
[out] BYTE *pPolicy,
|
||||
[in] DWORD cbPolicy,
|
||||
[in] BYTE *pContext,
|
||||
[in] DWORD cbContext,
|
||||
[in] DWORD dwFlags,
|
||||
[in] DWORD_PTR dwReserved,
|
||||
[out] DWORD *pdwOutFlags);
|
||||
|
||||
HRESULT GetSecurityIdEx2(
|
||||
[in] IUri *pUri,
|
||||
[out] BYTE *pbSecurityId,
|
||||
[in, out] DWORD *pcbSecurityId,
|
||||
[in] DWORD_PTR dwReserved);
|
||||
|
||||
HRESULT QueryCustomPolicyEx2(
|
||||
[in] IUri *pUri,
|
||||
[in] REFGUID guidKey,
|
||||
[out] BYTE **ppPolicy,
|
||||
[out] DWORD *pcbPolicy,
|
||||
[in] BYTE *pContext,
|
||||
[in] DWORD cbContext,
|
||||
[in] DWORD_PTR dwReserved);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IInternetHostSecurityManager interface
|
||||
*/
|
||||
|
@ -1191,6 +1295,18 @@ cpp_quote("#define URLPOLICY_CHANNEL_SOFTDIST_PRECACHE 0x00020000")
|
|||
cpp_quote("#define URLPOLICY_CHANNEL_SOFTDIST_AUTOINSTALL 0x00030000")
|
||||
cpp_quote("#define URLACTION_CHANNEL_SOFTDIST_MAX 0x00001eff")
|
||||
|
||||
cpp_quote("#define URLACTION_BEHAVIOR_MIN 0x00002000")
|
||||
cpp_quote("#define URLACTION_BEHAVIOR_RUN 0x00002000")
|
||||
cpp_quote("#define URLPOLICY_BEHAVIOR_CHECK_LIST 0x00010000")
|
||||
|
||||
cpp_quote("#define URLACTION_FEATURE_MIN 0x00002100")
|
||||
cpp_quote("#define URLACTION_FEATURE_MIME_SNIFFING 0x00002100")
|
||||
cpp_quote("#define URLACTION_FEATURE_ZONE_ELEVATION 0x00002101")
|
||||
cpp_quote("#define URLACTION_FEATURE_WINDOW_RESTRICTIONS 0x00002102")
|
||||
cpp_quote("#define URLACTION_FEATURE_SCRIPT_STATUS_BAR 0x00002103")
|
||||
cpp_quote("#define URLACTION_FEATURE_FORCE_ADDR_AND_STATUS 0x00002104")
|
||||
cpp_quote("#define URLACTION_FEATURE_BLOCK_INPUT_PROMPTS 0x00002105")
|
||||
|
||||
cpp_quote("#define URLPOLICY_ALLOW 0x00")
|
||||
cpp_quote("#define URLPOLICY_QUERY 0x01")
|
||||
cpp_quote("#define URLPOLICY_DISALLOW 0x03")
|
||||
|
@ -1544,7 +1660,6 @@ typedef struct _tagPROTOCOLFILTERDATA {
|
|||
* IUri interface
|
||||
*/
|
||||
[
|
||||
local,
|
||||
object,
|
||||
uuid(a39ee748-6a27-4817-a6f2-13914bef5890),
|
||||
pointer_default(unique)
|
||||
|
@ -1883,6 +1998,30 @@ interface IInternetProtocolEx : IInternetProtocol
|
|||
[in] HANDLE *dwReserved);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IGetBindHandle interface
|
||||
*/
|
||||
[
|
||||
local,
|
||||
object,
|
||||
uuid(AF0FF408-129D-4b20-91F0-02BD23D88352),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IGetBindHandle : IUnknown
|
||||
{
|
||||
typedef [unique] IGetBindHandle *LPGETBINDHANDLE;
|
||||
|
||||
typedef enum {
|
||||
BINDHANDLETYPES_APPCACHE = 0x00000000,
|
||||
BINDHANDLETYPES_DEPENDENCY = 0x00000001,
|
||||
BINDHANDLETYPES_COUNT
|
||||
} BINDHANDLETYPES;
|
||||
|
||||
HRESULT GetBindHandle(
|
||||
[in] BINDHANDLETYPES enumRequestedHandle,
|
||||
[out] HANDLE *pRetHandle);
|
||||
}
|
||||
|
||||
cpp_quote("#define CONFIRMSAFETYACTION_LOADOBJECT 0x00000001")
|
||||
|
||||
struct CONFIRMSAFETY
|
||||
|
@ -1977,8 +2116,11 @@ cpp_quote("HRESULT WINAPI CoInternetParseUrl(LPCWSTR,PARSEACTION,DWORD,LPWSTR,DW
|
|||
cpp_quote("HRESULT WINAPI CoInternetParseIUri(IUri*,PARSEACTION,DWORD,LPWSTR,DWORD,DWORD*,DWORD_PTR);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetQueryInfo(LPCWSTR,QUERYOPTION,DWORD,LPVOID,DWORD,DWORD*,DWORD);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST,DWORD,BOOL);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST,DWORD dwFlags);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetIsFeatureEnabledForUrl(INTERNETFEATURELIST,DWORD,LPCWSTR,IInternetSecurityManager*);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR,LPWSTR*,PSUACTION,DWORD);")
|
||||
cpp_quote("HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri*,IUri**,PSUACTION,DWORD_PTR);")
|
||||
cpp_quote("HRESULT WINAPI AsyncInstallDistributionUnit(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,DWORD,LPCWSTR,IBindCtx*,LPVOID,DWORD);")
|
||||
cpp_quote("HRESULT WINAPI CreateFormatEnumerator(UINT,FORMATETC*,IEnumFORMATETC**);")
|
||||
cpp_quote("HRESULT WINAPI GetSoftwareUpdateInfo( LPCWSTR szDistUnit, LPSOFTDISTINFO psdi);")
|
||||
cpp_quote("HRESULT WINAPI FaultInIEFeature(HWND,uCLSSPEC*,QUERYCONTEXT*,DWORD);")
|
||||
|
@ -1996,6 +2138,7 @@ cpp_quote("HRESULT WINAPI RegisterFormatEnumerator(LPBC,IEnumFORMATETC*,DWORD);"
|
|||
cpp_quote("HRESULT WINAPI RevokeFormatEnumerator(LPBC,IEnumFORMATETC*);")
|
||||
cpp_quote("HRESULT WINAPI RevokeBindStatusCallback(LPBC,IBindStatusCallback*);")
|
||||
cpp_quote("HRESULT WINAPI CopyStgMedium(const STGMEDIUM*,STGMEDIUM*);")
|
||||
cpp_quote("HRESULT WINAPI CopyBindInfo(const BINDINFO*,BINDINFO*);")
|
||||
cpp_quote("void WINAPI ReleaseBindInfo(BINDINFO*);")
|
||||
cpp_quote("HRESULT WINAPI UrlMkGetSessionOption(DWORD,LPVOID,DWORD,DWORD*,DWORD);")
|
||||
cpp_quote("HRESULT WINAPI UrlMkSetSessionOption(DWORD,LPVOID,DWORD,DWORD);")
|
||||
|
@ -2017,3 +2160,4 @@ cpp_quote("#define IsLoggingEnabled WINELIB_NAME_AW(IsLoggingEnabled)")
|
|||
cpp_quote("#define MKSYS_URLMONIKER 6")
|
||||
cpp_quote("#define URL_MK_LEGACY 0")
|
||||
cpp_quote("#define URL_MK_UNIFORM 1")
|
||||
cpp_quote("#define URL_MK_NO_CANONICALIZE 2")
|
||||
|
|
|
@ -179,7 +179,7 @@ reactos/dll/win32/twain_32 # Out of sync
|
|||
reactos/dll/win32/unicows # Synced to Wine-1.3.32 (Win9x only, why do we need this?!)
|
||||
reactos/dll/win32/updspapi # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/url # Synced to Wine-1.5.19
|
||||
reactos/dll/win32/urlmon # Autosync
|
||||
reactos/dll/win32/urlmon # Synced to Wine-1.5.26
|
||||
reactos/dll/win32/usp10 # Synced to Wine-1.5.24
|
||||
reactos/dll/win32/uxtheme # Forked
|
||||
reactos/dll/win32/version # Autosync
|
||||
|
|
Loading…
Reference in a new issue