示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
static ULONG WINAPI InstallEngineTiming_Release(IInstallEngineTiming *iface)
{
    InstallEngine *This = impl_from_IInstallEngineTiming(iface);
    return IInstallEngine2_Release(&This->IInstallEngine2_iface);
}