Example #1
0
static void create_object(Binding *binding)
{
    LPWSTR clsid_str;
    CLSID clsid;
    HRESULT hres;

    if(!binding->mime) {
        FIXME("MIME not available\n");
        return;
    }

    if(!(clsid_str = get_mime_clsid(binding->mime, &clsid))) {
        FIXME("Could not find object for MIME %s\n", debugstr_w(binding->mime));
        return;
    }

    IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_CLASSIDAVAILABLE, clsid_str);
    IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_BEGINSYNCOPERATION, NULL);

    hres = create_mime_object(binding, &clsid, clsid_str);
    heap_free(clsid_str);

    IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_ENDSYNCOPERATION, NULL);

    stop_binding(binding, hres, NULL);
    if(FAILED(hres))
        IInternetProtocol_Terminate(binding->protocol, 0);
}
Example #2
0
static HRESULT on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text)
{
    HRESULT hres;

    if(!This->callback)
        return S_OK;

    hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text);
    return hres;
}
Example #3
0
static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
        ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);

    TRACE("%p)->(%u %u %s %s)\n", This, ulProgress, ulProgressMax, debugstr_bindstatus(ulStatusCode),
            debugstr_w(szStatusText));

    return IBindStatusCallback_OnProgress(This->callback, ulProgress,
            ulProgressMax, ulStatusCode, szStatusText);
}
Example #4
0
static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
        ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    BindStatusCallback *This = STATUSCLB_THIS(iface);

    TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
            debugstr_w(szStatusText));

    return IBindStatusCallback_OnProgress(This->callback, ulProgress,
            ulProgressMax, ulStatusCode, szStatusText);
}
Example #5
0
static HRESULT start_binding(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc,
                             BOOL to_obj, REFIID riid, Binding **ret)
{
    Binding *binding = NULL;
    HRESULT hres;
    MSG msg;

    hres = Binding_Create(mon, binding_ctx, uri, pbc, to_obj, riid, &binding);
    if(FAILED(hres))
        return hres;

    hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, &binding->IBinding_iface);
    if(FAILED(hres)) {
        WARN("OnStartBinding failed: %08x\n", hres);
        stop_binding(binding, INET_E_DOWNLOAD_FAILURE, NULL);
        IBinding_Release(&binding->IBinding_iface);
        return hres;
    }

    if(binding_ctx) {
        set_binding_sink(binding->protocol, &binding->IInternetProtocolSink_iface,
                &binding->IInternetBindInfo_iface);
        if(binding_ctx->redirect_url)
            IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_REDIRECTING, binding_ctx->redirect_url);
        report_data(binding, BSCF_FIRSTDATANOTIFICATION | (binding_ctx->download_state == END_DOWNLOAD ? BSCF_LASTDATANOTIFICATION : 0),
                0, 0);
    }else {
        hres = IInternetProtocolEx_StartEx(&binding->protocol->IInternetProtocolEx_iface, uri,
                &binding->IInternetProtocolSink_iface, &binding->IInternetBindInfo_iface,
                PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0);

        TRACE("start ret %08x\n", hres);

        if(FAILED(hres) && hres != E_PENDING) {
            stop_binding(binding, hres, NULL);
            IBinding_Release(&binding->IBinding_iface);

            return hres;
        }
    }

    while(!(binding->bindf & BINDF_ASYNCHRONOUS) &&
          !(binding->state & BINDING_STOPPED)) {
        MsgWaitForMultipleObjects(0, NULL, FALSE, 5000, QS_POSTMESSAGE);
        while (PeekMessageW(&msg, binding->notif_hwnd, WM_USER, WM_USER+117, PM_REMOVE|PM_NOYIELD)) {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
        }
    }

    *ret = binding;
    return S_OK;
}
Example #6
0
static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
                                           ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;

    if(This->pBSC)
        return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
                                          ulProgressMax, ulStatusCode,
                                          szStatusText);

    return S_OK;
}
Example #7
0
static void mime_available(Binding *This, LPCWSTR mime)
{
    heap_free(This->mime);
    This->mime = heap_strdupW(mime);

    if(!This->mime || !This->report_mime)
        return;

    IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, This->mime);

    This->clipboard_format = RegisterClipboardFormatW(This->mime);
}
Example #8
0
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
        ULONG ulStatusCode, LPCWSTR szStatusText)
{
    Binding *This = PROTSINK_THIS(iface);

    TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));

    switch(ulStatusCode) {
    case BINDSTATUS_FINDINGRESOURCE:
        on_progress(This, 0, 0, BINDSTATUS_FINDINGRESOURCE, szStatusText);
        break;
    case BINDSTATUS_CONNECTING:
        on_progress(This, 0, 0, BINDSTATUS_CONNECTING, szStatusText);
        break;
    case BINDSTATUS_REDIRECTING:
        heap_free(This->redirect_url);
        This->redirect_url = heap_strdupW(szStatusText);
        on_progress(This, 0, 0, BINDSTATUS_REDIRECTING, szStatusText);
        break;
    case BINDSTATUS_BEGINDOWNLOADDATA:
        fill_stgmed_buffer(This->stgmed_buf);
        break;
    case BINDSTATUS_SENDINGREQUEST:
        on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText);
        break;
    case BINDSTATUS_PROTOCOLCLASSID:
        break;
    case BINDSTATUS_MIMETYPEAVAILABLE:
    case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
        mime_available(This, szStatusText);
        break;
    case BINDSTATUS_CACHEFILENAMEAVAILABLE:
        cache_file_available(This, szStatusText);
        break;
    case BINDSTATUS_DECODING:
        IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText);
        break;
    case BINDSTATUS_LOADINGMIMEHANDLER:
        on_progress(This, 0, 0, BINDSTATUS_LOADINGMIMEHANDLER, szStatusText);
        break;
    case BINDSTATUS_DIRECTBIND: /* FIXME: Handle BINDSTATUS_DIRECTBIND in BindProtocol */
        This->report_mime = FALSE;
        break;
    case BINDSTATUS_ACCEPTRANGES:
        break;
    default:
        FIXME("Unhandled status code %d\n", ulStatusCode);
        return E_NOTIMPL;
    };

    return S_OK;
}
Example #9
0
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 = 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);
            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;
}
Example #10
0
static HRESULT on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text)
{
    HRESULT hres;

    if(!This->callback)
        return S_OK;

    hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text);
    if(hres == E_ABORT) {
        if(This->binding)
            IBinding_Abort(This->binding);
        else
            FIXME("No binding, not sure what to do!\n");
    }

    return hres;
}
Example #11
0
static HRESULT Binding_MoreCacheData(Binding *This, const char *buf, DWORD dwBytes)
{
    DWORD written;

    if (WriteFile(This->hCacheFile, buf, dwBytes, &written, NULL) && written == dwBytes)
    {
	HRESULT hr;

	This->total_read += written;
        hr = IBindStatusCallback_OnProgress(This->pbscb,
					    This->total_read + written,
					    This->expected_size,
					    (This->total_read == written) ?
					        BINDSTATUS_BEGINDOWNLOADDATA :
					        BINDSTATUS_DOWNLOADINGDATA,
					    This->URLName);
	if (hr == S_OK)
	{
	    STGMEDIUM stg;
	    FORMATETC fmt;

            fmt.cfFormat = 0;
            fmt.ptd = NULL;
            fmt.dwAspect = 0;
            fmt.lindex = -1;
            fmt.tymed = TYMED_ISTREAM;

	    stg.tymed = TYMED_ISTREAM;
	    stg.u.pstm = (IStream *)This->pstrCache;
	    stg.pUnkForRelease = NULL;

            hr = IBindStatusCallback_OnDataAvailable(This->pbscb,
			    			     (This->total_read == written) ?
							 BSCF_FIRSTDATANOTIFICATION :
						         BSCF_INTERMEDIATEDATANOTIFICATION,
						     This->total_read + written,
                                                     &fmt,
						     &stg);
	}
	if (written < dwBytes)
	    return STG_E_MEDIUMFULL;
	else
	    return hr;
    }
    return HRESULT_FROM_WIN32(GetLastError());
}
Example #12
0
static HRESULT WINAPI XMLView_BindStatusCallback_OnProgress(
        IBindStatusCallback *iface, ULONG ulProgress, ULONG ulProgressMax,
        ULONG ulStatusCode, LPCWSTR szStatusText)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    TRACE("(%p)->(%d %d %x %s)\n", This, ulProgress, ulProgressMax,
            ulStatusCode, debugstr_w(szStatusText));

    switch(ulStatusCode) {
    case BINDSTATUS_BEGINDOWNLOADDATA:
        return IBindStatusCallback_OnProgress(This->bsc, ulProgress,
                ulProgressMax, ulStatusCode, szStatusText);
    case BINDSTATUS_MIMETYPEAVAILABLE:
        return S_OK;
    default:
        FIXME("ulStatusCode: %d\n", ulStatusCode);
        return E_NOTIMPL;
    }
}
Example #13
0
static void Binding_FinishedDownload(Binding *This, HRESULT hr)
{
    STGMEDIUM stg;
    FORMATETC fmt;

    fmt.ptd = NULL;
    fmt.dwAspect = 0;
    fmt.lindex = -1;
    fmt.tymed = TYMED_ISTREAM;

    stg.tymed = TYMED_ISTREAM;
    stg.u.pstm = (IStream *)This->pstrCache;
    stg.pUnkForRelease = NULL;

    IBindStatusCallback_OnProgress(This->pbscb, This->total_read, This->expected_size,
                                   BINDSTATUS_ENDDOWNLOADDATA, This->URLName);
    IBindStatusCallback_OnDataAvailable(This->pbscb, BSCF_LASTDATANOTIFICATION, This->total_read, &fmt, &stg);
    if (hr != S_OK)
    {
	WCHAR *pwchError = 0;

        FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
	                 FORMAT_MESSAGE_ALLOCATE_BUFFER,
                        NULL, (DWORD) hr,
		        0, (LPWSTR) &pwchError,
		        0, NULL);
	if (!pwchError)
	{
	    static const WCHAR achFormat[] = { '%', '0', '8', 'x', 0 };

	    pwchError =(WCHAR *) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * 9);
	    wsprintfW(pwchError, achFormat, hr);
	}
        IBindStatusCallback_OnStopBinding(This->pbscb, hr, pwchError);
	LocalFree(pwchError);
    }
    else
    {
        IBindStatusCallback_OnStopBinding(This->pbscb, hr, NULL);
    }
    IBindStatusCallback_Release(This->pbscb);
    This->pbscb = 0;
}
Example #14
0
static
DWORD WINAPI
ThreadFunc(LPVOID Context)
{
    IBindStatusCallback *dl = NULL;
    WCHAR path[MAX_PATH];
    PWSTR p, q;
    HWND Dlg = (HWND) Context;
    DWORD dwContentLen, dwBytesWritten, dwBytesRead, dwStatus;
    DWORD dwCurrentBytesRead = 0;
    DWORD dwStatusLen = sizeof(dwStatus);
    BOOL bCancelled = FALSE;
    BOOL bTempfile = FALSE;
    BOOL bCab = FALSE;
    HINTERNET hOpen = NULL;
    HINTERNET hFile = NULL;
    HANDLE hOut = INVALID_HANDLE_VALUE;
    unsigned char lpBuffer[4096];
    const LPWSTR lpszAgent = L"RApps/1.0";
    URL_COMPONENTS urlComponents;
    size_t urlLength, filenameLength;

    /* build the path for the download */
    p = wcsrchr(AppInfo->szUrlDownload, L'/');
    q = wcsrchr(AppInfo->szUrlDownload, L'?');

    /* do we have a final slash separator? */
    if (!p)
        goto end;

    /* prepare the tentative length of the filename, maybe we've to remove part of it later on */
    filenameLength = wcslen(p) * sizeof(WCHAR);

    /* do we have query arguments in the target URL after the filename? account for them
      (e.g. https://example.org/myfile.exe?no_adware_plz) */
    if (q && q > p && (q - p) > 0)
        filenameLength -= wcslen(q - 1) * sizeof(WCHAR);

    /* is this URL an update package for RAPPS? if so store it in a different place */
    if (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0)
    {
        bCab = TRUE;
        if (!GetStorageDirectory(path, _countof(path)))
            goto end;
    }
    else
    {
        if (FAILED(StringCbCopyW(path, sizeof(path),  SettingsInfo.szDownloadDir)))
            goto end;
    }

    /* is the path valid? can we access it? */
    if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
    {
        if (!CreateDirectoryW(path, NULL))
            goto end;
    }

    /* append a \ to the provided file system path, and the filename portion from the URL after that */
    if (FAILED(StringCbCatW(path, sizeof(path), L"\\")))
        goto end;
    if (FAILED(StringCbCatNW(path, sizeof(path), p + 1, filenameLength)))
        goto end;

    /* is the file already there? let's avoid having to download it */
    if (!bCab && AppInfo->szSHA1[0] != 0 && GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
    {
        /* only open it in case of total correctness */
        if (VerifyInteg(AppInfo->szSHA1, path))
            goto run;
    }

    /* create an async download context for it */
    bTempfile = TRUE;
    dl = CreateDl(Context, &bCancelled);

    if (dl == NULL)
        goto end;

    /* FIXME: this should just be using the system-wide proxy settings */
    switch(SettingsInfo.Proxy)
    {
        case 0: /* preconfig */
            hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
            break;
        case 1: /* direct (no proxy) */
            hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
            break;
        case 2: /* use proxy */
            hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0);
            break;
        default: /* preconfig */
            hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
            break;
    }

    if (!hOpen)
        goto end;

    hFile = InternetOpenUrlW(hOpen, AppInfo->szUrlDownload, NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
    if (!hFile)
        goto end;

    if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL))
        goto end;

    if(dwStatus != HTTP_STATUS_OK)
    {
        WCHAR szMsgText[MAX_STR_LEN];

        if (!LoadStringW(hInst, IDS_UNABLE_TO_DOWNLOAD, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)))
            goto end;

        MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR);
        goto end;
    }

    dwStatusLen = sizeof(dwStatus);

    memset(&urlComponents, 0, sizeof(urlComponents));
    urlComponents.dwStructSize = sizeof(urlComponents);

    if(FAILED(StringCbLengthW(AppInfo->szUrlDownload, sizeof(AppInfo->szUrlDownload), &urlLength)))
        goto end;

    urlLength /= sizeof(WCHAR);
    urlComponents.dwSchemeLength = urlLength + 1;
    urlComponents.lpszScheme = malloc(urlComponents.dwSchemeLength * sizeof(WCHAR));
    urlComponents.dwHostNameLength = urlLength + 1;
    urlComponents.lpszHostName = malloc(urlComponents.dwHostNameLength * sizeof(WCHAR));

    if(!InternetCrackUrlW(AppInfo->szUrlDownload, urlLength+1, ICU_DECODE | ICU_ESCAPE, &urlComponents))
        goto end;

    if(urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS)
        HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatus, 0);

    if(urlComponents.nScheme == INTERNET_SCHEME_FTP)
        dwContentLen = FtpGetFileSize(hFile, &dwStatus);

#ifdef USE_CERT_PINNING
    /* are we using HTTPS to download the RAPPS update package? check if the certificate is original */
    if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) &&
        (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0) &&
        (!CertIsValid(hOpen, urlComponents.lpszHostName)))
    {
        WCHAR szMsgText[MAX_STR_LEN];

        if (!LoadStringW(hInst, IDS_CERT_DOES_NOT_MATCH, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)))
            goto end;

        MessageBoxW(Dlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
        goto end;
    }
#endif

    free(urlComponents.lpszScheme);
    free(urlComponents.lpszHostName);

    hOut = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);

    if (hOut == INVALID_HANDLE_VALUE)
        goto end;

    do
    {
        if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead)) goto end;
        if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL)) goto end;
        dwCurrentBytesRead += dwBytesRead;
        IBindStatusCallback_OnProgress(dl, dwCurrentBytesRead, dwContentLen, 0, AppInfo->szUrlDownload);
    }
    while (dwBytesRead && !bCancelled);

    CloseHandle(hOut);
    hOut = INVALID_HANDLE_VALUE;

    if (bCancelled)
        goto end;

    /* if this thing isn't a RAPPS update and it has a SHA-1 checksum
       verify its integrity by using the native advapi32.A_SHA1 functions */
    if (!bCab && AppInfo->szSHA1[0] != 0)
    {
        WCHAR szMsgText[MAX_STR_LEN];

        /* change a few strings in the download dialog to reflect the verification process */
        LoadStringW(hInst, IDS_INTEG_CHECK_TITLE, szMsgText, _countof(szMsgText));

        SetWindowText(Dlg, szMsgText);
        SendMessageW(GetDlgItem(Dlg, IDC_DOWNLOAD_STATUS), WM_SETTEXT, 0, (LPARAM)path);

        /* this may take a while, depending on the file size */
        if (!VerifyInteg(AppInfo->szSHA1, path))
        {
            if (!LoadStringW(hInst, IDS_INTEG_CHECK_FAIL, szMsgText, _countof(szMsgText)))
                goto end;

            MessageBoxW(Dlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
            goto end;
        }
    }

    ShowWindow(Dlg, SW_HIDE);

run:
    /* run it */
    if (!bCab)
        ShellExecuteW( NULL, L"open", path, NULL, NULL, SW_SHOWNORMAL );

end:
    if (hOut != INVALID_HANDLE_VALUE)
        CloseHandle(hOut);

    InternetCloseHandle(hFile);
    InternetCloseHandle(hOpen);

    if (dl)
        IBindStatusCallback_Release(dl);

    if (bTempfile)
    {
        if (bCancelled || (SettingsInfo.bDelInstaller && !bCab))
            DeleteFileW(path);
    }

    EndDialog(Dlg, 0);

    return 0;
}
Example #15
0
static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progress_max)
{
    FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
    BOOL sent_begindownloaddata = FALSE;

    TRACE("(%p)->(%d %u %u)\n", This, bscf, progress, progress_max);

    if(This->download_state == END_DOWNLOAD || (This->state & (BINDING_STOPPED|BINDING_ABORTED)))
        return;

    if(This->stgmed_buf->file != INVALID_HANDLE_VALUE)
        read_protocol_data(This->stgmed_buf);
    else if(This->download_state == BEFORE_DOWNLOAD)
        fill_stgmed_buffer(This->stgmed_buf);

    if(This->download_state == BEFORE_DOWNLOAD) {
        This->download_state = DOWNLOADING;
        sent_begindownloaddata = TRUE;
        IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
                                       BINDSTATUS_BEGINDOWNLOADDATA, This->url);

        if(This->stgmed_buf->cache_file)
            IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
                                           BINDSTATUS_CACHEFILENAMEAVAILABLE, This->stgmed_buf->cache_file);
    }

    if(This->stgmed_buf->hres == S_FALSE || (bscf & BSCF_LASTDATANOTIFICATION)) {
        This->download_state = END_DOWNLOAD;
        IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
                                       BINDSTATUS_ENDDOWNLOADDATA, This->url);
    } else if(!sent_begindownloaddata) {
        IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
                                       BINDSTATUS_DOWNLOADINGDATA, This->url);
    }

    if(This->state & (BINDING_STOPPED|BINDING_ABORTED))
        return;

    if(This->to_object) {
        if(!(This->state & BINDING_OBJAVAIL)) {
            IBinding_AddRef(BINDING(This));
            create_object(This);
            IBinding_Release(BINDING(This));
        }
    } else {
        STGMEDIUM stgmed;
        HRESULT hres;

        if(!(This->state & BINDING_LOCKED)) {
            HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0);
            if(SUCCEEDED(hres))
                This->state |= BINDING_LOCKED;
        }

        hres = This->stgmed_obj->vtbl->fill_stgmed(This->stgmed_obj, &stgmed);
        if(FAILED(hres)) {
            stop_binding(This, hres, NULL);
            return;
        }

        formatetc.tymed = stgmed.tymed;
        formatetc.cfFormat = This->clipboard_format;

        IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
                                            &formatetc, &stgmed);

        if(This->download_state == END_DOWNLOAD)
            stop_binding(This, S_OK, NULL);
    }
}
Example #16
0
static void on_progress(Binding *This, ULONG progress, ULONG progress_max,
                        ULONG status_code, LPCWSTR status_text)
{
    IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
                                   status_code, status_text);
}
Example #17
0
/******************************************************************************
 *        URLMoniker_BindToStorage
 ******************************************************************************/
static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, IBindCtx* pbc, VOID** ppvObject)
{
    HRESULT hres;
    BINDINFO bi;
    DWORD bindf;
    WCHAR szFileName[MAX_PATH + 1];
    Binding *bind;
    int len;

    WARN("(%s %p %p)\n", debugstr_w(URLName), pbc, ppvObject);

    bind = heap_alloc_zero(sizeof(Binding));
    bind->lpVtbl = &BindingVtbl;
    bind->ref = 1;
    URLMON_LockModule();

    len = lstrlenW(URLName)+1;
    bind->URLName = heap_alloc(len*sizeof(WCHAR));
    memcpy(bind->URLName, URLName, len*sizeof(WCHAR));

    hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache);

    if(SUCCEEDED(hres)) {
        TRACE("Created stream...\n");

        *ppvObject = (void *) bind->pstrCache;
        IStream_AddRef((IStream *) bind->pstrCache);

        hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&bind->pbscb);
        if(SUCCEEDED(hres)) {
            TRACE("Got IBindStatusCallback...\n");

            memset(&bi, 0, sizeof(bi));
            bi.cbSize = sizeof(bi);
            bindf = 0;
            hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi);
            if(SUCCEEDED(hres)) {
                URL_COMPONENTSW url;
                WCHAR *host, *path, *user, *pass;
                DWORD dwService = 0;
                BOOL bSuccess;

                TRACE("got bindinfo. bindf = %08x extrainfo = %s bindinfof = %08x bindverb = %08x iid %s\n",
                      bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid));
                hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind);
                TRACE("OnStartBinding rets %08x\n", hres);

                bind->expected_size = 0;
                bind->total_read = 0;

                memset(&url, 0, sizeof(url));
                url.dwStructSize = sizeof(url);
                url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1;
                InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url);
                host = heap_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR));
                memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
                host[url.dwHostNameLength] = '\0';
                path = heap_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR));
                memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
                path[url.dwUrlPathLength] = '\0';
                if (url.dwUserNameLength)
                {
                    user = heap_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR)));
                    memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR));
                    user[url.dwUserNameLength] = 0;
                }
                else
                {
                    user = 0;
                }
                if (url.dwPasswordLength)
                {
                    pass = heap_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR)));
                    memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR));
                    pass[url.dwPasswordLength] = 0;
                }
                else
                {
                    pass = 0;
                }


                do {
                    bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0);
                    if (!bind->hinternet)
                    {
                            hres = HRESULT_FROM_WIN32(GetLastError());
                            break;
                    }

                    switch ((DWORD) url.nScheme)
                    {
                    case INTERNET_SCHEME_FTP:
                        if (!url.nPort)
                            url.nPort = INTERNET_DEFAULT_FTP_PORT;
                        dwService = INTERNET_SERVICE_FTP;
                        break;
    
                    case INTERNET_SCHEME_GOPHER:
                        if (!url.nPort)
                            url.nPort = INTERNET_DEFAULT_GOPHER_PORT;
                        dwService = INTERNET_SERVICE_GOPHER;
                        break;
                    }

                    bind->hconnect = InternetConnectW(bind->hinternet, host, url.nPort, user, pass,
                                                      dwService, 0, (DWORD_PTR)bind);
                    if (!bind->hconnect)
                    {
                            hres = HRESULT_FROM_WIN32(GetLastError());
                            CloseHandle(bind->hinternet);
                            break;
                    }

                    hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, 0x22, NULL);
                    hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
                    hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL);
                    hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);

                    bSuccess = FALSE;

                    switch (dwService)
                    {
                    case INTERNET_SERVICE_GOPHER:
                        bind->hrequest = GopherOpenFileW(bind->hconnect,
                                                         path,
                                                         0,
                                                         INTERNET_FLAG_RELOAD,
                                                         0);
                        if (bind->hrequest)
                                bSuccess = TRUE;
                        else
                                hres = HRESULT_FROM_WIN32(GetLastError());
                        break;

                    case INTERNET_SERVICE_FTP:
                        bind->hrequest = FtpOpenFileW(bind->hconnect,
                                                      path,
                                                      GENERIC_READ,
                                                      FTP_TRANSFER_TYPE_BINARY |
                                                       INTERNET_FLAG_TRANSFER_BINARY |
                                                       INTERNET_FLAG_RELOAD,
                                                      0);
                        if (bind->hrequest)
                                bSuccess = TRUE;
                        else
                                hres = HRESULT_FROM_WIN32(GetLastError());
                        break;
                    }
                    if(bSuccess)
                    {
                        TRACE("res = %d gle = %u url len = %d\n", hres, GetLastError(), bind->expected_size);

                        IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName);

                        while(1) {
                            char buf[4096];
                            DWORD bufread;
                            if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) {
                                TRACE("read %d bytes %s...\n", bufread, debugstr_an(buf, 10));
                                if(bufread == 0) break;
                                hres = Binding_MoreCacheData(bind, buf, bufread);
                            } else
                                break;
                        }
                        InternetCloseHandle(bind->hrequest);
                            hres = S_OK;
                    }
            
                    InternetCloseHandle(bind->hconnect);
                    InternetCloseHandle(bind->hinternet);
                } while(0);

                Binding_FinishedDownload(bind, hres);
                Binding_CloseCacheDownload(bind);

                heap_free(user);
                heap_free(pass);
                heap_free(path);
                heap_free(host);
            }
        }
    }

    IBinding_Release((IBinding*)bind);

    return hres;
}