DWORD WINAPI thread_installation(LPVOID param) { InstallEngine *This = param; ICifComponent *comp; HRESULT hr; if (This->callback) IInstallEngineCallback_OnStartInstall(This->callback, This->thread.download_size, This->thread.install_size); for (;;) { hr = get_next_component(This->thread.enum_comp, This->thread.operation, &comp); if (FAILED(hr)) break; if (hr == S_FALSE) { hr = S_OK; break; } hr = process_component(This, comp); if (FAILED(hr)) break; } if (This->callback) IInstallEngineCallback_OnStopInstall(This->callback, hr, NULL, 0); IEnumCifComponents_Release(This->thread.enum_comp); IInstallEngine2_Release(&This->IInstallEngine2_iface); set_status(This, ENGINESTATUS_READY); return 0; }
static ULONG WINAPI downloadcb_Release(IBindStatusCallback *iface) { struct downloadcb *This = impl_from_IBindStatusCallback(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref = %d\n", This, ref); if (!ref) { heap_free(This->file_name); heap_free(This->cache_file); IInstallEngine2_Release(&This->engine->IInstallEngine2_iface); heap_free(This); } return ref; }
static HRESULT WINAPI InstallEngineCF_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) { InstallEngine *engine; HRESULT hres; TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv); engine = heap_alloc(sizeof(*engine)); if(!engine) return E_OUTOFMEMORY; engine->IInstallEngine2_iface.lpVtbl = &InstallEngine2Vtbl; engine->ref = 1; hres = IInstallEngine2_QueryInterface(&engine->IInstallEngine2_iface, riid, ppv); IInstallEngine2_Release(&engine->IInstallEngine2_iface); return hres; }
static HRESULT start_installation(InstallEngine *This, DWORD operation, DWORD jobflags) { HANDLE thread; HRESULT hr; This->thread.operation = operation; This->thread.jobflags = jobflags; This->thread.downloaded_kb = 0; This->thread.download_start = 0; /* Windows sends the OnStartInstall event from a different thread, * but OnStartInstall already contains the required download and install size. * The only way to signal an error from the thread is to send an OnStopComponent / * OnStopInstall signal which can only occur after OnStartInstall. We need to * precompute the sizes here to be able inform the application about errors while * calculating the required sizes. */ hr = ICifFile_EnumComponents(This->icif, &This->thread.enum_comp, 0, NULL); if (FAILED(hr)) return hr; hr = calc_sizes(This->thread.enum_comp, operation, &This->thread.download_size, &This->thread.install_size); if (FAILED(hr)) goto error; IInstallEngine2_AddRef(&This->IInstallEngine2_iface); thread = CreateThread(NULL, 0, thread_installation, This, 0, NULL); if (!thread) { IInstallEngine2_Release(&This->IInstallEngine2_iface); hr = E_FAIL; goto error; } CloseHandle(thread); return S_OK; error: IEnumCifComponents_Release(This->thread.enum_comp); return hr; }
static ULONG WINAPI InstallEngineTiming_Release(IInstallEngineTiming *iface) { InstallEngine *This = impl_from_IInstallEngineTiming(iface); return IInstallEngine2_Release(&This->IInstallEngine2_iface); }