appwiz.cpl: Use asynchronous binding instead of separated thread to download addons.
This commit is contained in:
parent
b08869420a
commit
c9cef7153c
|
@ -48,7 +48,6 @@
|
||||||
#include "res.h"
|
#include "res.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/unicode.h"
|
|
||||||
#include "wine/library.h"
|
#include "wine/library.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl);
|
WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl);
|
||||||
|
@ -107,6 +106,7 @@ static const addon_info_t *addon;
|
||||||
static HWND install_dialog = NULL;
|
static HWND install_dialog = NULL;
|
||||||
static LPWSTR url = NULL;
|
static LPWSTR url = NULL;
|
||||||
static IBinding *dwl_binding;
|
static IBinding *dwl_binding;
|
||||||
|
static WCHAR *msi_file;
|
||||||
|
|
||||||
static WCHAR * (CDECL *p_wine_get_dos_file_name)(const char*);
|
static WCHAR * (CDECL *p_wine_get_dos_file_name)(const char*);
|
||||||
static const WCHAR kernel32_dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
static const WCHAR kernel32_dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
||||||
|
@ -134,9 +134,11 @@ static BOOL sha_check(const WCHAR *file_name)
|
||||||
SHA_CTX ctx;
|
SHA_CTX ctx;
|
||||||
DWORD size, i;
|
DWORD size, i;
|
||||||
|
|
||||||
file = CreateFileW(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
|
file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
|
||||||
if(file == INVALID_HANDLE_VALUE)
|
if(file == INVALID_HANDLE_VALUE) {
|
||||||
|
WARN("Could not open file: %u\n", GetLastError());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
size = GetFileSize(file, NULL);
|
size = GetFileSize(file, NULL);
|
||||||
|
|
||||||
|
@ -186,8 +188,6 @@ static enum install_res install_file(const WCHAR *file_name)
|
||||||
{
|
{
|
||||||
ULONG res;
|
ULONG res;
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(install_dialog, IDCANCEL), 0);
|
|
||||||
|
|
||||||
res = MsiInstallProductW(file_name, NULL);
|
res = MsiInstallProductW(file_name, NULL);
|
||||||
if(res != ERROR_SUCCESS) {
|
if(res != ERROR_SUCCESS) {
|
||||||
ERR("MsiInstallProduct failed: %u\n", res);
|
ERR("MsiInstallProduct failed: %u\n", res);
|
||||||
|
@ -488,23 +488,57 @@ static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!msi_file) {
|
||||||
|
ERR("No MSI file\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
set_status(IDS_INSTALLING);
|
set_status(IDS_INSTALLING);
|
||||||
|
EnableWindow(GetDlgItem(install_dialog, IDCANCEL), 0);
|
||||||
|
|
||||||
|
if(sha_check(msi_file)) {
|
||||||
|
WCHAR *cache_file_name;
|
||||||
|
|
||||||
|
install_file(msi_file);
|
||||||
|
|
||||||
|
cache_file_name = get_cache_file_name(TRUE);
|
||||||
|
if(cache_file_name) {
|
||||||
|
MoveFileW(msi_file, cache_file_name);
|
||||||
|
heap_free(cache_file_name);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
WCHAR message[256];
|
||||||
|
|
||||||
|
if(LoadStringW(hInst, IDS_INVALID_SHA, message, sizeof(message)/sizeof(WCHAR)))
|
||||||
|
MessageBoxW(NULL, message, NULL, MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteFileW(msi_file);
|
||||||
|
heap_free(msi_file);
|
||||||
|
msi_file = NULL;
|
||||||
|
|
||||||
|
EndDialog(install_dialog, 0);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
|
static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
|
||||||
DWORD* grfBINDF, BINDINFO* pbindinfo)
|
DWORD* grfBINDF, BINDINFO* pbindinfo)
|
||||||
{
|
{
|
||||||
/* FIXME */
|
TRACE("()\n");
|
||||||
*grfBINDF = 0;
|
|
||||||
|
*grfBINDF = BINDF_ASYNCHRONOUS;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
|
static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
|
||||||
DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
|
DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
|
||||||
{
|
{
|
||||||
ERR("\n");
|
if(!msi_file) {
|
||||||
return E_NOTIMPL;
|
msi_file = heap_strdupW(pstgmed->u.lpszFileName);
|
||||||
|
TRACE("got file name %s\n", debugstr_w(msi_file));
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
|
static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
|
||||||
|
@ -578,42 +612,29 @@ found:
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI download_proc(PVOID arg)
|
static BOOL start_download(void)
|
||||||
{
|
{
|
||||||
WCHAR tmp_dir[MAX_PATH], tmp_file[MAX_PATH];
|
IBindCtx *bind_ctx;
|
||||||
|
IMoniker *mon;
|
||||||
|
IUnknown *tmp;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
GetTempPathW(sizeof(tmp_dir)/sizeof(WCHAR), tmp_dir);
|
hres = CreateURLMoniker(NULL, url, &mon);
|
||||||
GetTempFileNameW(tmp_dir, NULL, 0, tmp_file);
|
if(FAILED(hres))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
TRACE("using temp file %s\n", debugstr_w(tmp_file));
|
hres = CreateAsyncBindCtx(0, &InstallCallback, NULL, &bind_ctx);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
hres = URLDownloadToFileW(NULL, url, tmp_file, 0, &InstallCallback);
|
hres = IMoniker_BindToStorage(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&tmp);
|
||||||
if(FAILED(hres)) {
|
IBindCtx_Release(bind_ctx);
|
||||||
ERR("URLDownloadToFile failed: %08x\n", hres);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
IMoniker_Release(mon);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if(sha_check(tmp_file)) {
|
if(tmp)
|
||||||
WCHAR *cache_file_name;
|
IUnknown_Release(tmp);
|
||||||
|
return TRUE;
|
||||||
install_file(tmp_file);
|
|
||||||
|
|
||||||
cache_file_name = get_cache_file_name(TRUE);
|
|
||||||
if(cache_file_name) {
|
|
||||||
MoveFileW(tmp_file, cache_file_name);
|
|
||||||
heap_free(cache_file_name);
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
WCHAR message[256];
|
|
||||||
|
|
||||||
if(LoadStringW(hInst, IDS_INVALID_SHA, message, sizeof(message)/sizeof(WCHAR)))
|
|
||||||
MessageBoxW(NULL, message, NULL, MB_ICONERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteFileW(tmp_file);
|
|
||||||
EndDialog(install_dialog, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_winebrowser(const WCHAR *url)
|
static void run_winebrowser(const WCHAR *url)
|
||||||
|
@ -683,8 +704,8 @@ static INT_PTR CALLBACK installer_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
|
||||||
case ID_DWL_INSTALL:
|
case ID_DWL_INSTALL:
|
||||||
ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_SHOW);
|
ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_SHOW);
|
||||||
EnableWindow(GetDlgItem(hwnd, ID_DWL_INSTALL), 0);
|
EnableWindow(GetDlgItem(hwnd, ID_DWL_INSTALL), 0);
|
||||||
CloseHandle( CreateThread(NULL, 0, download_proc, NULL, 0, NULL));
|
if(!start_download())
|
||||||
return FALSE;
|
EndDialog(install_dialog, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ADDON_GECKO,
|
ADDON_GECKO,
|
||||||
ADDON_MONO
|
ADDON_MONO
|
||||||
|
@ -40,6 +42,22 @@ static inline BOOL heap_free(void *mem)
|
||||||
return HeapFree(GetProcessHeap(), 0, mem);
|
return HeapFree(GetProcessHeap(), 0, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *heap_strdupW(const WCHAR *str)
|
||||||
|
{
|
||||||
|
WCHAR *ret;
|
||||||
|
|
||||||
|
if(str) {
|
||||||
|
size_t size = strlenW(str)+1;
|
||||||
|
ret = heap_alloc(size*sizeof(WCHAR));
|
||||||
|
if(ret)
|
||||||
|
memcpy(ret, str, size*sizeof(WCHAR));
|
||||||
|
}else {
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline WCHAR *heap_strdupAtoW(const char *str)
|
static inline WCHAR *heap_strdupAtoW(const char *str)
|
||||||
{
|
{
|
||||||
WCHAR *ret = NULL;
|
WCHAR *ret = NULL;
|
||||||
|
|
Loading…
Reference in New Issue