예제 #1
0
파일: bindctx.c 프로젝트: hoangduit/reactos
static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
        BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
    IHttpNegotiate2 *http_negotiate2;
    HRESULT hres = E_FAIL;

    TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved);

    http_negotiate2 = get_callback_iface(This, &IID_IHttpNegotiate2);
    if(http_negotiate2) {
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, pbSecurityId,
                pcbSecurityId, dwReserved);
        IHttpNegotiate2_Release(http_negotiate2);
    }

    return hres;
}
예제 #2
0
파일: bindctx.c 프로젝트: NVIDIA/winex_lgpl
static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
{
    BindStatusCallback *This = STATUSCLB_THIS(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref = %d\n", This, ref);

    if(!ref) {
        if(This->serv_prov)
            IServiceProvider_Release(This->serv_prov);
        if(This->http_negotiate)
            IHttpNegotiate_Release(This->http_negotiate);
        if(This->http_negotiate2)
            IHttpNegotiate2_Release(This->http_negotiate2);
        if(This->authenticate)
            IAuthenticate_Release(This->authenticate);
        IBindStatusCallback_Release(This->callback);
        heap_free(This);
    }

    return ref;
}
예제 #3
0
파일: http.c 프로젝트: bilboed/wine
static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
        HINTERNET internet_session, IInternetBindInfo *bind_info)
{
    HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
    LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL;
    IServiceProvider *service_provider = NULL;
    IHttpNegotiate2 *http_negotiate2 = NULL;
    LPWSTR host, user, pass, path;
    LPOLESTR accept_mimes[257];
    URL_COMPONENTSW url_comp;
    BYTE security_id[512];
    DWORD len = 0;
    ULONG num;
    BOOL res, b;
    HRESULT hres;

    static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
        {{'G','E','T',0},
         {'P','O','S','T',0},
         {'P','U','T',0}};

    memset(&url_comp, 0, sizeof(url_comp));
    url_comp.dwStructSize = sizeof(url_comp);
    url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = url_comp.dwExtraInfoLength =
        url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1;
    if (!InternetCrackUrlW(url, 0, 0, &url_comp))
        return MK_E_SYNTAX;

    if(!url_comp.nPort)
        url_comp.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;

    host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength);
    user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength);
    pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength);
    This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass,
            INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
    heap_free(pass);
    heap_free(user);
    heap_free(host);
    if(!This->base.connection) {
        WARN("InternetConnect failed: %d\n", GetLastError());
        return INET_E_CANNOT_CONNECT;
    }

    num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES, accept_mimes, num, &num);
    if(hres != S_OK) {
        WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
        return INET_E_NO_VALID_MEDIA;
    }
    accept_mimes[num] = 0;

    path = heap_alloc((url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength+1)*sizeof(WCHAR));
    if(url_comp.dwUrlPathLength)
        memcpy(path, url_comp.lpszUrlPath, url_comp.dwUrlPathLength*sizeof(WCHAR));
    if(url_comp.dwExtraInfoLength)
        memcpy(path+url_comp.dwUrlPathLength, url_comp.lpszExtraInfo, url_comp.dwExtraInfoLength*sizeof(WCHAR));
    path[url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength] = 0;
    if(This->https)
        request_flags |= INTERNET_FLAG_SECURE;
    This->base.request = HttpOpenRequestW(This->base.connection,
            This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM
                ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb,
            path, NULL, NULL, (LPCWSTR *)accept_mimes, request_flags, (DWORD_PTR)&This->base);
    heap_free(path);
    while(num--)
        CoTaskMemFree(accept_mimes[num]);
    if (!This->base.request) {
        WARN("HttpOpenRequest failed: %d\n", GetLastError());
        return INET_E_RESOURCE_NOT_FOUND;
    }

    hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider,
            (void **)&service_provider);
    if (hres != S_OK) {
        WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
        return hres;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
            &IID_IHttpNegotiate, (void **)&This->http_negotiate);
    if (hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
        return hres;
    }

    hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders,
            0, &addl_header);
    if(hres != S_OK) {
        WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    if(addl_header) {
        int len_addl_header = strlenW(addl_header);

        This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));

        lstrcpyW(This->full_header, addl_header);
        lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
        CoTaskMemFree(addl_header);
    }else {
        This->full_header = (LPWSTR)wszHeaders;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
            &IID_IHttpNegotiate2, (void **)&http_negotiate2);
    IServiceProvider_Release(service_provider);
    if(hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
        /* No goto done as per native */
    }else {
        len = sizeof(security_id)/sizeof(security_id[0]);
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
        IHttpNegotiate2_Release(http_negotiate2);
        if (hres != S_OK)
            WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
    }

    /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */

    if(This->base.bind_info.dwBindVerb == BINDVERB_POST) {
        num = 0;
        hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE, &post_cookie, 1, &num);
        if(hres == S_OK && num) {
            if(!InternetSetOptionW(This->base.request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
                                   post_cookie, lstrlenW(post_cookie)))
                WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n", GetLastError());
            CoTaskMemFree(post_cookie);
        }
    }

    if(This->base.bind_info.dwBindVerb != BINDVERB_GET) {
        /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
        if (This->base.bind_info.stgmedData.tymed != TYMED_HGLOBAL)
            WARN("Expected This->base.bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n",
                 This->base.bind_info.stgmedData.tymed);
        else
            optional = (LPWSTR)This->base.bind_info.stgmedData.u.hGlobal;
    }

    b = TRUE;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x\n", GetLastError());

    res = HttpSendRequestW(This->base.request, This->full_header, lstrlenW(This->full_header),
            optional, optional ? This->base.bind_info.cbstgmedData : 0);
    if(!res && GetLastError() != ERROR_IO_PENDING) {
        WARN("HttpSendRequest failed: %d\n", GetLastError());
        return INET_E_DOWNLOAD_FAILURE;
    }

    return S_OK;
}
예제 #4
0
파일: http.c 프로젝트: ccpgames/wine
static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
        HINTERNET internet_session, IInternetBindInfo *bind_info)
{
    HttpProtocol *This = impl_from_Protocol(prot);
    WCHAR *addl_header = NULL, *post_cookie = NULL, *rootdoc_url = NULL;
    IServiceProvider *service_provider = NULL;
    IHttpNegotiate2 *http_negotiate2 = NULL;
    BSTR url, host, user, pass, path;
    LPOLESTR accept_mimes[257];
    const WCHAR **accept_types;
    BYTE security_id[512];
    DWORD len, port, flags;
    ULONG num, error;
    BOOL res, b;
    HRESULT hres;

    static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
        {{'G','E','T',0},
         {'P','O','S','T',0},
         {'P','U','T',0}};

    hres = IUri_GetPort(uri, &port);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetHost(uri, &host);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetUserName(uri, &user);
    if(SUCCEEDED(hres)) {
        hres = IUri_GetPassword(uri, &pass);

        if(SUCCEEDED(hres)) {
            This->base.connection = InternetConnectW(internet_session, host, port, user, pass,
                    INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
            SysFreeString(pass);
        }
        SysFreeString(user);
    }
    SysFreeString(host);
    if(FAILED(hres))
        return hres;
    if(!This->base.connection) {
        WARN("InternetConnect failed: %d\n", GetLastError());
        return INET_E_CANNOT_CONNECT;
    }

    num = 0;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ROOTDOC_URL, &rootdoc_url, 1, &num);
    if(hres == S_OK && num) {
        FIXME("Use root doc URL %s\n", debugstr_w(rootdoc_url));
        CoTaskMemFree(rootdoc_url);
    }

    num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
    hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES, accept_mimes, num, &num);
    if(hres == INET_E_USE_DEFAULT_SETTING) {
        static const WCHAR default_accept_mimeW[] = {'*','/','*',0};
        static const WCHAR *default_accept_mimes[] = {default_accept_mimeW, NULL};

        accept_types = default_accept_mimes;
        num = 0;
    }else if(hres == S_OK) {
        accept_types = (const WCHAR**)accept_mimes;
    }else {
        WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
        return INET_E_NO_VALID_MEDIA;
    }
    accept_mimes[num] = 0;

    if(This->https)
        request_flags |= INTERNET_FLAG_SECURE;

    hres = IUri_GetPathAndQuery(uri, &path);
    if(SUCCEEDED(hres)) {
        This->base.request = HttpOpenRequestW(This->base.connection,
                This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM
                    ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb,
                path, NULL, NULL, accept_types, request_flags, (DWORD_PTR)&This->base);
        SysFreeString(path);
    }
    while(num--)
        CoTaskMemFree(accept_mimes[num]);
    if(FAILED(hres))
        return hres;
    if (!This->base.request) {
        WARN("HttpOpenRequest failed: %d\n", GetLastError());
        return INET_E_RESOURCE_NOT_FOUND;
    }

    hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider,
            (void **)&service_provider);
    if (hres != S_OK) {
        WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
        return hres;
    }

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
            &IID_IHttpNegotiate, (void **)&This->http_negotiate);
    if (hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    hres = IUri_GetAbsoluteUri(uri, &url);
    if(FAILED(hres)) {
        IServiceProvider_Release(service_provider);
        return hres;
    }

    hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, default_headersW,
            0, &addl_header);
    SysFreeString(url);
    if(hres != S_OK) {
        WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
        IServiceProvider_Release(service_provider);
        return hres;
    }

    len = addl_header ? strlenW(addl_header) : 0;

    This->full_header = heap_alloc(len*sizeof(WCHAR)+sizeof(default_headersW));
    if(!This->full_header) {
        IServiceProvider_Release(service_provider);
        return E_OUTOFMEMORY;
    }

    if(len)
        memcpy(This->full_header, addl_header, len*sizeof(WCHAR));
    CoTaskMemFree(addl_header);
    memcpy(This->full_header+len, default_headersW, sizeof(default_headersW));

    hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
            &IID_IHttpNegotiate2, (void **)&http_negotiate2);
    IServiceProvider_Release(service_provider);
    if(hres != S_OK) {
        WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
        /* No goto done as per native */
    }else {
        len = sizeof(security_id)/sizeof(security_id[0]);
        hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
        IHttpNegotiate2_Release(http_negotiate2);
        if (hres != S_OK)
            WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
    }

    /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */

    if(This->base.bind_info.dwBindVerb == BINDVERB_POST) {
        num = 0;
        hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE, &post_cookie, 1, &num);
        if(hres == S_OK && num) {
            if(!InternetSetOptionW(This->base.request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
                                   post_cookie, lstrlenW(post_cookie)))
                WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n", GetLastError());
            CoTaskMemFree(post_cookie);
        }
    }

    flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_ERROR_MASK, &flags, sizeof(flags));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_ERROR_MASK) failed: %u\n", GetLastError());

    b = TRUE;
    res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
    if(!res)
        WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %u\n", GetLastError());

    do {
        error = send_http_request(This);

        switch(error) {
        case ERROR_IO_PENDING:
            return S_OK;
        case ERROR_SUCCESS:
            /*
             * If sending response ended synchronously, it means that we have the whole data
             * available locally (most likely in cache).
             */
            return protocol_syncbinding(&This->base);
        default:
            hres = handle_http_error(This, error);
        }
    } while(hres == RPC_E_RETRY);

    WARN("HttpSendRequest failed: %d\n", error);
    return hres;
}