Esempio n. 1
0
HRESULT CDocUIHandler::GetOptionKeyPath( 
	/* [out] */ BSTR *pchKey,
	/* [in] */ DWORD dw) 
{

	return E_NOTIMPL;
	HRESULT hr;
	WCHAR* szKey = L"ljwnb";

	//  cbLength is the length of szKey in bytes.
	size_t cbLength;
	hr = StringCbLengthW(szKey, 1280, &cbLength);
	//  TODO: Add error handling code here.

	if (pchKey)
	{
		*pchKey = (LPOLESTR)CoTaskMemAlloc(cbLength + sizeof(WCHAR));
		if (*pchKey)
			hr = StringCbCopyW(*pchKey, cbLength + sizeof(WCHAR), szKey);
	}
	else
		hr = E_INVALIDARG;

	return hr;
    
}
Esempio n. 2
0
/*---------------------------------------------------------------------------------------------*/
static HRESULT _get_value_length(unsigned int value_type, const void* value, size_t* length)
{
	HRESULT hr;
	size_t l;

	switch (value_type)
	{
	case AXV_INT8: case AXV_UINT8: *length = 1; return S_OK;
	case AXV_INT16: case AXV_UINT16: *length = 2; return S_OK;
	case AXV_INT32: case AXV_UINT32: *length = 4; return S_OK;
	case AXV_INT64: case AXV_UINT64: *length = 8; return S_OK;
	case AXV_FLOAT32: *length = 4; return S_OK;
	case AXV_FLOAT64: *length = 8; return S_OK;
	case AXV_STR_ACP: case AXV_STR_UTF8:
	{
		hr = StringCbLengthA((const char*)value, AXTRACE_MAX_VALUE_LENGTH - 1, &l);
		if (FAILED(hr)) return hr;
		*length = l + 1;
		return S_OK;
	}
	case AXV_STR_UTF16:
	{
		hr = StringCbLengthW((const wchar_t*)value, AXTRACE_MAX_VALUE_LENGTH - 1, &l);
		if (FAILED(hr)) return hr;
		*length = l + 2;
		return S_OK;
	}
	default: break;
	}
	return E_FAIL;
}
Esempio n. 3
0
LPWSTR WINAPI StringDupW(_In_ HANDLE hHeap, _In_ LPCWSTR lpszString)
{
	LPWSTR lpszCopy;
	size_t cbCopy;
	HRESULT hr;

	if (!lpszString)
		return NULL;

	hr = StringCbLengthW(lpszString, (STRSAFE_MAX_CCH-1) * sizeof(WCHAR), &cbCopy);
	if (FAILED(hr))
		return NULL;

	if ((cbCopy + sizeof(WCHAR)) <= cbCopy)
		return NULL;

	cbCopy += sizeof(WCHAR);
	lpszCopy = (LPWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbCopy);
	if (!lpszCopy)
		return NULL;

	hr = StringCbCopyNW(lpszCopy, cbCopy, lpszString, cbCopy);
	if (FAILED(hr)) {
		HeapSafeFree(hHeap, 0, lpszCopy);
		return NULL;
	}

	return lpszCopy;
}
Esempio n. 4
0
void _DBGPRINT( LPCWSTR kwszFunction, INT iLineNumber, LPCWSTR kwszDebugFormatString, ... )
{
    INT cbFormatString = 0;
    va_list args;
    PWCHAR wszDebugString = NULL;
    size_t st_Offset = 0;

    va_start( args, kwszDebugFormatString );

    cbFormatString = _scwprintf( L"[%s:%d] ", kwszFunction, iLineNumber ) * sizeof( WCHAR );
    cbFormatString += _vscwprintf( kwszDebugFormatString, args ) * sizeof( WCHAR ) + 2;

    /* Depending on the size of the format string, allocate space on the stack or the heap. */
    wszDebugString = (PWCHAR)_malloca( cbFormatString );

    /* Populate the buffer with the contents of the format string. */
    StringCbPrintfW( wszDebugString, cbFormatString, L"[%s:%d] ", kwszFunction, iLineNumber );
    StringCbLengthW( wszDebugString, cbFormatString, &st_Offset );
    StringCbVPrintfW( &wszDebugString[st_Offset / sizeof(WCHAR)], cbFormatString - st_Offset, kwszDebugFormatString, args );

    OutputDebugStringW( wszDebugString );

    _freea( wszDebugString );
    va_end( args );
}
DWORD CopyWideString(
    IN _In_ LPWSTR pSrcWString,
    OUT _Out_ LPWSTR *pDestWString)
{
    DWORD retCode = NO_ERROR;
    HRESULT hr = S_OK;
    size_t dwStringLength = 0;
    LPWSTR pTempString = NULL;

    *pDestWString = NULL;

    // Nothing to copy
    if(!pSrcWString)
        goto Cleanup;

    hr = StringCbLengthW(pSrcWString, (size_t)(STRSAFE_MAX_CCH * sizeof(wchar_t)), &dwStringLength);
    if (FAILED(hr))
    {
        retCode = HRESULT_CODE(hr);
        goto Cleanup;
    }

    // StringCbLengthW - returns the length of string in bytes (excluding the null character).
    // StringCbCopyW expects the length of string in bytes (including the null character).
    dwStringLength += sizeof(wchar_t);
    retCode = AllocateMemory((DWORD)dwStringLength, (PVOID *)&pTempString);
    if(retCode != NO_ERROR)
    {
        goto Cleanup;
    }

    hr = StringCbCopyW((LPTSTR)pTempString, dwStringLength, pSrcWString);
    if (FAILED(hr))
    {
        retCode = HRESULT_CODE(hr);
        goto Cleanup;
    }

    //
    // Set the OUT parameter
    //
    *pDestWString = pTempString;

Cleanup:
    if((retCode != NO_ERROR) && (pTempString != NULL))
        FreeMemory((PVOID *)&pTempString);
    pTempString = NULL;
    return retCode;
}
Esempio n. 6
0
static
DWORD WINAPI
ThreadFunc(LPVOID Context)
{
    CComPtr<IBindStatusCallback> dl;
    WCHAR path[MAX_PATH];
    LPWSTR p;
    HWND Dlg = (HWND) Context;
    ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus;
    ULONG dwCurrentBytesRead = 0;
    ULONG 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];
    PCWSTR lpszAgent = L"RApps/1.0";
    URL_COMPONENTS urlComponents;
    size_t urlLength;

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

    if (!p)
        goto end;

        if (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0)
        {
            bCab = TRUE;
            if (!GetStorageDirectory(path, sizeof(path) / sizeof(path[0])))
                goto end;
        }
        else
        {
            if (FAILED(StringCbCopyW(path, sizeof(path),  SettingsInfo.szDownloadDir)))
                goto end;
        }


    if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
    {
        if (!CreateDirectoryW(path, NULL))
            goto end;
    }

    if (FAILED(StringCbCatW(path, sizeof(path), L"\\")))
        goto end;
    if (FAILED(StringCbCatW(path, sizeof(path), p + 1)))
        goto end;

    /* download it */
    bTempfile = TRUE;
    CDownloadDialog_Constructor(Dlg, &bCancelled, IID_PPV_ARG(IBindStatusCallback, &dl));

    if (dl == NULL)
        goto end;

    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;
    
    urlComponents.dwSchemeLength = urlLength*sizeof(WCHAR);
    urlComponents.lpszScheme = (PWSTR)malloc(urlComponents.dwSchemeLength);
    
    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);

    free(urlComponents.lpszScheme);

    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;
        dl->OnProgress(dwCurrentBytesRead, dwContentLen, 0, AppInfo->szUrlDownload);
    }
    while (dwBytesRead);

    CloseHandle(hOut);
    hOut = INVALID_HANDLE_VALUE;

    if (bCancelled)
        goto end;

    ShowWindow(Dlg, SW_HIDE);

    /* 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 (bTempfile)
    {
        if (bCancelled || (SettingsInfo.bDelInstaller && !bCab))
            DeleteFileW(path);
    }

    EndDialog(Dlg, 0);

    return 0;
}
Esempio n. 7
0
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    AssertPtr(pCtx);

    LRESULT rc = 0;

    switch (msg)
    {
        case WM_CLIPBOARDUPDATE:
        {
            Log(("WM_CLIPBOARDUPDATE\n"));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                vboxClipboardChanged(pCtx);
            }
        } break;

        case WM_CHANGECBCHAIN:
        {
            if (vboxClipboardIsNewAPI(pCtx))
            {
                rc = DefWindowProc(hwnd, msg, wParam, lParam);
                break;
            }

            HWND hwndRemoved = (HWND)wParam;
            HWND hwndNext    = (HWND)lParam;

            LogFlowFunc(("WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));

            if (hwndRemoved == pCtx->hwndNextInChain)
            {
                /* The window that was next to our in the chain is being removed.
                 * Relink to the new next window. */
                pCtx->hwndNextInChain = hwndNext;
            }
            else
            {
                if (pCtx->hwndNextInChain)
                {
                    /* Pass the message further. */
                    DWORD_PTR dwResult;
                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                    if (!rc)
                        rc = (LRESULT) dwResult;
                }
            }
        } break;

        case WM_DRAWCLIPBOARD:
        {
            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
                int vboxrc = vboxClipboardChanged(pCtx);
                if (RT_FAILURE(vboxrc))
                    LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc));
            }

            if (pCtx->hwndNextInChain)
            {
                /* Pass the message to next windows in the clipboard chain. */
                SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL);
            }
        } break;

        case WM_TIMER:
        {
            if (vboxClipboardIsNewAPI(pCtx))
                break;

            HWND hViewer = GetClipboardViewer();

            /* Re-register ourselves in the clipboard chain if our last ping
             * timed out or there seems to be no valid chain. */
            if (!hViewer || pCtx->fCBChainPingInProcess)
            {
                vboxClipboardRemoveFromCBChain(pCtx);
                vboxClipboardAddToCBChain(pCtx);
            }
            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
             * processed by ourselves to the chain. */
            pCtx->fCBChainPingInProcess = TRUE;
            hViewer = GetClipboardViewer();
            if (hViewer)
                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx);
        } break;

        case WM_CLOSE:
        {
            /* Do nothing. Ignore the message. */
        } break;

        case WM_RENDERFORMAT:
        {
            /* Insert the requested clipboard format data into the clipboard. */
            uint32_t u32Format = 0;
            UINT format = (UINT)wParam;

            LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format));
            switch (format)
            {
                case CF_UNICODETEXT:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                    break;

                case CF_DIB:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                    break;

                default:
                    if (format >= 0xC000)
                    {
                        TCHAR szFormatName[256];

                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
                        if (cActual)
                        {
                            if (strcmp (szFormatName, "HTML Format") == 0)
                            {
                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
                            }
                        }
                    }
                    break;
            }

            if (u32Format == 0)
            {
                /* Unsupported clipboard format is requested. */
                LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format));
                EmptyClipboard();
            }
            else
            {
                const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */
                uint32_t cb = 0;

                /* Preallocate a buffer, most of small text transfers will fit into it. */
                HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
                LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));

                if (hMem)
                {
                    void *pMem = GlobalLock(hMem);
                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                    if (pMem)
                    {
                        /* Read the host data to the preallocated buffer. */
                        int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb);
                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));

                        if (RT_SUCCESS(vboxrc))
                        {
                            if (cb == 0)
                            {
                                /* 0 bytes returned means the clipboard is empty.
                                 * Deallocate the memory and set hMem to NULL to get to
                                 * the clipboard empty code path. */
                                GlobalUnlock(hMem);
                                GlobalFree(hMem);
                                hMem = NULL;
                            }
                            else if (cb > cbPrealloc)
                            {
                                GlobalUnlock(hMem);

                                /* The preallocated buffer is too small, adjust the size. */
                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    pMem = GlobalLock(hMem);
                                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                                    if (pMem)
                                    {
                                        /* Read the host data to the preallocated buffer. */
                                        uint32_t cbNew = 0;
                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew);
                                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));

                                        if (RT_SUCCESS (vboxrc) && cbNew <= cb)
                                        {
                                            cb = cbNew;
                                        }
                                        else
                                        {
                                            GlobalUnlock(hMem);
                                            GlobalFree(hMem);
                                            hMem = NULL;
                                        }
                                    }
                                    else
                                    {
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                }
                            }

                            if (hMem)
                            {
                                /* pMem is the address of the data. cb is the size of returned data. */
                                /* Verify the size of returned text, the memory block for clipboard
                                 * must have the exact string size.
                                 */
                                if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                                {
                                    size_t cbActual = 0;
                                    HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
                                    if (FAILED (hrc))
                                    {
                                        /* Discard invalid data. */
                                        GlobalUnlock(hMem);
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                    else
                                    {
                                        /* cbActual is the number of bytes, excluding those used
                                         * for the terminating null character.
                                         */
                                        cb = (uint32_t)(cbActual + 2);
                                    }
                                }
                            }

                            if (hMem)
                            {
                                GlobalUnlock(hMem);

                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    /* 'hMem' contains the host clipboard data.
                                     * size is 'cb' and format is 'format'. */
                                    HANDLE hClip = SetClipboardData(format, hMem);
                                    LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));

                                    if (hClip)
                                    {
                                        /* The hMem ownership has gone to the system. Finish the processing. */
                                        break;
                                    }

                                    /* Cleanup follows. */
                                }
                            }
                        }
                        if (hMem)
                            GlobalUnlock(hMem);
                    }
                    if (hMem)
                        GlobalFree(hMem);
                }

                /* Something went wrong. */
                EmptyClipboard();
            }
        } break;

        case WM_RENDERALLFORMATS:
        {
            /* Do nothing. The clipboard formats will be unavailable now, because the
             * windows is to be destroyed and therefore the guest side becomes inactive.
             */
            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();
                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_RENDERALLFORMATS: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER:
        {
            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
            uint32_t u32Formats = (uint32_t)lParam;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();

                HANDLE hClip = NULL;

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
                    hClip = SetClipboardData(CF_DIB, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                    if (format != 0)
                    {
                        hClip = SetClipboardData(format, NULL);
                    }
                }

                CloseClipboard();
                LogFlowFunc(("WM_USER: hClip = %p, err = %ld\n", hClip, GetLastError ()));
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! error = %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER + 1:
        {
            /* Send data in the specified format to the host. */
            uint32_t u32Formats = (uint32_t)lParam;
            HANDLE hClip = NULL;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    hClip = GetClipboardData(CF_DIB);

                    if (hClip != NULL)
                    {
                        LPVOID lp = GlobalLock(hClip);
                        if (lp != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_DIB\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
                                                              lp, GlobalSize(hClip));
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    hClip = GetClipboardData(CF_UNICODETEXT);

                    if (hClip != NULL)
                    {
                        LPWSTR uniString = (LPWSTR)GlobalLock(hClip);

                        if (uniString != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_UNICODETEXT\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
                                                              uniString, (lstrlenW(uniString) + 1) * 2);
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    if (format != 0)
                    {
                        hClip = GetClipboardData(format);
                        if (hClip != NULL)
                        {
                            LPVOID lp = GlobalLock(hClip);

                            if (lp != NULL)
                            {
                                LogFlowFunc(("WM_USER + 1: CF_HTML\n"));
                                vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,
                                                                  lp, GlobalSize(hClip));
                                GlobalUnlock(hClip);
                            }
                            else
                            {
                                hClip = NULL;
                            }
                        }
                    }
                }

                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }

            if (hClip == NULL)
            {
                /* Requested clipboard format is not available, send empty data. */
                VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
            }
        } break;

        case WM_DESTROY:
        {
            vboxClipboardRemoveFromCBChain(pCtx);
            if (pCtx->timerRefresh)
                KillTimer(pCtx->hwnd, 0);
            /*
             * don't need to call PostQuitMessage cause
             * the VBoxTray already finished a message loop
             */
        } break;

        default:
        {
            rc = DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }

#ifndef DEBUG_andy
    LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));
#endif
    return rc;
}
Esempio n. 8
0
static size_t mystrlen(const wchar_t *buf) {
    size_t ans = 0;
    if (FAILED(StringCbLengthW(buf, 500, &ans))) return 0;
    return ans;
}
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    AssertPtr(pCtx);

    const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;

    LRESULT rc = 0;

    switch (msg)
    {
        case WM_CLIPBOARDUPDATE:
        {
           Log(("WM_CLIPBOARDUPDATE\n"));

           if (GetClipboardOwner() != hwnd)
           {
               /* Clipboard was updated by another application. */
               uint32_t uFormats;
               int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
               if (RT_SUCCESS(vboxrc))
                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
           }
        }
        break;

        case WM_CHANGECBCHAIN:
        {
           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
           {
               rc = DefWindowProc(hwnd, msg, wParam, lParam);
               break;
           }

           HWND hWndRemoved = (HWND)wParam;
           HWND hWndNext    = (HWND)lParam;

           LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd));

           if (hWndRemoved == pWinCtx->hWndNextInChain)
           {
               /* The window that was next to our in the chain is being removed.
                * Relink to the new next window. */
               pWinCtx->hWndNextInChain = hWndNext;
           }
           else
           {
               if (pWinCtx->hWndNextInChain)
               {
                   /* Pass the message further. */
                   DWORD_PTR dwResult;
                   rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,
                                           VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult);
                   if (!rc)
                       rc = (LRESULT)dwResult;
               }
           }
        }
        break;

        case WM_DRAWCLIPBOARD:
        {
           LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));

           if (GetClipboardOwner() != hwnd)
           {
               /* Clipboard was updated by another application. */
               /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
               uint32_t uFormats;
               int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats);
               if (RT_SUCCESS(vboxrc))
                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
           }

           if (pWinCtx->hWndNextInChain)
           {
               /* Pass the message to next windows in the clipboard chain. */
               SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL);
           }
        }
        break;

        case WM_TIMER:
        {
           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
               break;

           HWND hViewer = GetClipboardViewer();

           /* Re-register ourselves in the clipboard chain if our last ping
            * timed out or there seems to be no valid chain. */
           if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
           {
               VBoxClipboardWinRemoveFromCBChain(pWinCtx);
               VBoxClipboardWinAddToCBChain(pWinCtx);
           }

           /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
            * processed by ourselves to the chain. */
           pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;

           hViewer = GetClipboardViewer();
           if (hViewer)
               SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
                                   VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
        }
        break;

        case WM_CLOSE:
        {
           /* Do nothing. Ignore the message. */
        }
        break;

        case WM_RENDERFORMAT:
        {
           /* Insert the requested clipboard format data into the clipboard. */
           uint32_t fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE;

           const UINT cfFormat = (UINT)wParam;
           switch (cfFormat)
           {
              case CF_UNICODETEXT:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                  break;

              case CF_DIB:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                  break;

#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
              case CF_HDROP:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
                  break;
#endif
              default:
                  if (cfFormat >= 0xC000) /** @todo r=andy Explain. */
                  {
                      TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */

                      int cActual = GetClipboardFormatName(cfFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR));
                      if (cActual)
                      {
                          if (strcmp(szFormatName, "HTML Format") == 0)
                              fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML;
                      }
                  }
                  break;
           }

           LogFunc(("WM_RENDERFORMAT: format=%u -> fFormat=0x%x\n", cfFormat, fFormat));

           if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
           {
               /* Unsupported clipboard format is requested. */
               LogRel(("Clipboard: Unsupported clipboard format requested (0x%x)\n", fFormat));
               VBoxClipboardWinClear();
           }
#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
           else if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
           {

           }
#endif
           else
           {
               const uint32_t cbPrealloc = _4K;
               uint32_t cb = 0;

               /* Preallocate a buffer, most of small text transfers will fit into it. */
               HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
               LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));

               if (hMem)
               {
                   void *pMem = GlobalLock(hMem);
                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                   if (pMem)
                   {
                       /* Read the host data to the preallocated buffer. */
                       int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));

                       if (RT_SUCCESS(vboxrc))
                       {
                           if (cb == 0)
                           {
                               /* 0 bytes returned means the clipboard is empty.
                                * Deallocate the memory and set hMem to NULL to get to
                                * the clipboard empty code path. */
                               GlobalUnlock(hMem);
                               GlobalFree(hMem);
                               hMem = NULL;
                           }
                           else if (cb > cbPrealloc)
                           {
                               GlobalUnlock(hMem);

                               /* The preallocated buffer is too small, adjust the size. */
                               hMem = GlobalReAlloc(hMem, cb, 0);
                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                               if (hMem)
                               {
                                   pMem = GlobalLock(hMem);
                                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                                   if (pMem)
                                   {
                                       /* Read the host data to the preallocated buffer. */
                                       uint32_t cbNew = 0;
                                       vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
                                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));

                                       if (RT_SUCCESS(vboxrc) && cbNew <= cb)
                                       {
                                           cb = cbNew;
                                       }
                                       else
                                       {
                                           GlobalUnlock(hMem);
                                           GlobalFree(hMem);
                                           hMem = NULL;
                                       }
                                   }
                                   else
                                   {
                                       GlobalFree(hMem);
                                       hMem = NULL;
                                   }
                               }
                           }

                           if (hMem)
                           {
                               /* pMem is the address of the data. cb is the size of returned data. */
                               /* Verify the size of returned text, the memory block for clipboard
                                * must have the exact string size.
                                */
                               if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                               {
                                   size_t cbActual = 0;
                                   HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
                                   if (FAILED(hrc))
                                   {
                                       /* Discard invalid data. */
                                       GlobalUnlock(hMem);
                                       GlobalFree(hMem);
                                       hMem = NULL;
                                   }
                                   else
                                   {
                                       /* cbActual is the number of bytes, excluding those used
                                        * for the terminating null character.
                                        */
                                       cb = (uint32_t)(cbActual + 2);
                                   }
                               }
                           }

                           if (hMem)
                           {
                               GlobalUnlock(hMem);

                               hMem = GlobalReAlloc(hMem, cb, 0);
                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                               if (hMem)
                               {
                                   /* 'hMem' contains the host clipboard data.
                                    * size is 'cb' and format is 'format'. */
                                   HANDLE hClip = SetClipboardData(cfFormat, hMem);
                                   LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));

                                   if (hClip)
                                   {
                                       /* The hMem ownership has gone to the system. Finish the processing. */
                                       break;
                                   }

                                   /* Cleanup follows. */
                               }
                           }
                       }
                       if (hMem)
                           GlobalUnlock(hMem);
                   }
                   if (hMem)
                       GlobalFree(hMem);
               }

               /* Something went wrong. */
               VBoxClipboardWinClear();
           }
        }
        break;

        case WM_RENDERALLFORMATS:
        {
           /* Do nothing. The clipboard formats will be unavailable now, because the
            * windows is to be destroyed and therefore the guest side becomes inactive.
            */
           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               VBoxClipboardWinClear();
               VBoxClipboardWinClose();
           }
        }
        break;

        case VBOX_CLIPBOARD_WM_SET_FORMATS:
        {
           /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
           VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;

           LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats));

           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               VBoxClipboardWinClear();

               HANDLE hClip = NULL;

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                   hClip = SetClipboardData(CF_UNICODETEXT, NULL);

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                   hClip = SetClipboardData(CF_DIB, NULL);

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
               {
                   UINT format = RegisterClipboardFormat("HTML Format");
                   if (format != 0)
                       hClip = SetClipboardData(format, NULL);
               }

#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
                   hClip = SetClipboardData(CF_HDROP, NULL);
#endif

               /** @todo Implement more flexible clipboard precedence for supported formats. */

               if (hClip == NULL)
                   LogRel(("Clipboard: Unsupported format(s) from host (0x%x), ignoring\n", fFormats));

               VBoxClipboardWinClose();

               LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError()));
           }
        }
        break;

        case VBOX_CLIPBOARD_WM_READ_DATA:
        {
           /* Send data in the specified format to the host. */
           uint32_t u32Formats = (uint32_t)lParam;
           HANDLE hClip = NULL;

           LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));

           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
               {
                   hClip = GetClipboardData(CF_DIB);

                   if (hClip != NULL)
                   {
                       LPVOID lp = GlobalLock(hClip);
                       if (lp != NULL)
                       {
                           vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
                                                             lp, GlobalSize(hClip));
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
               {
                   hClip = GetClipboardData(CF_UNICODETEXT);

                   if (hClip != NULL)
                   {
                       LPWSTR uniString = (LPWSTR)GlobalLock(hClip);

                       if (uniString != NULL)
                       {
                           vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
                                                             uniString, (lstrlenW(uniString) + 1) * 2);
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
               {
                   UINT format = RegisterClipboardFormat("HTML Format");
                   if (format != 0)
                   {
                       hClip = GetClipboardData(format);
                       if (hClip != NULL)
                       {
                           LPVOID lp = GlobalLock(hClip);

                           if (lp != NULL)
                           {
                               vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,
                                                                 lp, GlobalSize(hClip));
                               GlobalUnlock(hClip);
                           }
                           else
                           {
                               hClip = NULL;
                           }
                       }
                   }
               }
#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
               {
                   hClip = GetClipboardData(CF_HDROP);
                   if (hClip)
                   {
                       HDROP hDrop = (HDROP)GlobalLock(hClip);
                       if (hDrop)
                       {
       /*                    vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
                                                             );*/
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
#endif
               VBoxClipboardWinClose();
           }

           if (hClip == NULL)
           {
               /* Requested clipboard format is not available, send empty data. */
               VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
           }
        }
        break;

        case WM_DESTROY:
        {
           VBoxClipboardWinRemoveFromCBChain(pWinCtx);
           if (pWinCtx->oldAPI.timerRefresh)
               KillTimer(pWinCtx->hWnd, 0);
           /*
            * don't need to call PostQuitMessage cause
            * the VBoxTray already finished a message loop
            */
        }
        break;

        default:
        {
           rc = DefWindowProc(hwnd, msg, wParam, lParam);
        }
        break;
    }

#ifndef DEBUG_andy
    LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));
#endif
    return rc;
}
Esempio n. 10
0
static
DWORD WINAPI
ThreadFunc(LPVOID Context)
{
    CComPtr<IBindStatusCallback> dl;
    WCHAR path[MAX_PATH];
    PWSTR p, q;
    HWND Dlg = (HWND) Context;
    ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus;
    ULONG dwCurrentBytesRead = 0;
    ULONG 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];
    PCWSTR 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;

    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;
    }

    /* download it */
    bTempfile = TRUE;
    CDownloadDialog_Constructor(Dlg, &bCancelled, IID_PPV_ARG(IBindStatusCallback, &dl));

    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 = (LPWSTR)malloc(urlComponents.dwSchemeLength * sizeof(WCHAR));
    urlComponents.dwHostNameLength = urlLength + 1;
    urlComponents.lpszHostName = (LPWSTR)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))
        {
            WCHAR szMsgText[MAX_STR_LEN];

            if (!LoadStringW(hInst, IDS_INTERRUPTED_DOWNLOAD, szMsgText, _countof(szMsgText)))
                goto end;

            MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR);
            goto end;
        }
        if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL))
        {
            WCHAR szMsgText[MAX_STR_LEN];

            if (!LoadStringW(hInst, IDS_UNABLE_TO_WRITE, szMsgText, _countof(szMsgText)))
                goto end;

            MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR);
            goto end;
        }
        dwCurrentBytesRead += dwBytesRead;
        dl->OnProgress(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 (bTempfile)
    {
        if (bCancelled || (SettingsInfo.bDelInstaller && !bCab))
            DeleteFileW(path);
    }

    EndDialog(Dlg, 0);

    return 0;
}