Example #1
0
/* FIXME: urlmon should handle it */
static BOOL try_application_url(LPCWSTR url)
{
    SHELLEXECUTEINFOW exec_info;
    WCHAR app[64];
    HKEY hkey;
    DWORD res, type;
    HRESULT hres;

    static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};

    hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
    if(FAILED(hres))
        return FALSE;

    res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
    if(res != ERROR_SUCCESS)
        return FALSE;

    res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return FALSE;

    TRACE("openning application %s\n", debugstr_w(app));
 
    memset(&exec_info, 0, sizeof(exec_info));
    exec_info.cbSize = sizeof(exec_info);
    exec_info.lpFile = url;
    exec_info.nShow = SW_SHOW;

    return ShellExecuteExW(&exec_info);
}
Example #2
0
/******************************************************************************
 *         URLMoniker_Construct (local function)
 *******************************************************************************/
static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeftURLName, LPCOLESTR lpszURLName)
{
    HRESULT hres;
    DWORD sizeStr = 0;

    TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszLeftURLName),debugstr_w(lpszURLName));

    This->lpvtbl = &VT_URLMonikerImpl;
    This->ref = 0;

    This->URLName = heap_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR));

    if(lpszLeftURLName)
        hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, URL_FILE_USE_PATHURL,
                This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
    else
        hres = CoInternetParseUrl(lpszURLName, PARSE_CANONICALIZE, URL_FILE_USE_PATHURL,
                This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);

    if(FAILED(hres)) {
        heap_free(This->URLName);
        return hres;
    }

    URLMON_LockModule();

    if(sizeStr != INTERNET_MAX_URL_LENGTH)
        This->URLName = heap_realloc(This->URLName, (sizeStr+1)*sizeof(WCHAR));

    TRACE("URLName = %s\n", debugstr_w(This->URLName));

    return S_OK;
}
Example #3
0
BOOL is_registered_protocol(LPCWSTR url)
{
    DWORD schema_len;
    WCHAR schema[64];
    HRESULT hres;

    hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
            &schema_len, 0);
    if(FAILED(hres))
        return FALSE;

    return get_protocol_cf(schema, schema_len, NULL, NULL) == S_OK;
}
Example #4
0
static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx,
                              IBindStatusCallback *callback)
{
    WCHAR schema[30];
    DWORD schema_len;
    HRESULT hres;

    static const WCHAR httpW[] = {'h','t','t','p',0};
    static const WCHAR httpsW[] = {'h','t','t','p','s',0};
    static const WCHAR ftpW[]= {'f','t','p',0};

    if(mon) {
        IMoniker_AddRef(mon);
    }else {
        hres = create_moniker(url, &mon);
        if(FAILED(hres))
            return hres;
    }

    CoTaskMemFree(This->url);
    hres = IMoniker_GetDisplayName(mon, 0, NULL, &This->url);
    if(FAILED(hres))
        FIXME("GetDisplayName failed: %08x\n", hres);

    IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM,
                                 (IUnknown*)CLIENTSITE(This));

    hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
            &schema_len, 0);
    if(SUCCEEDED(hres) &&
       (!strcmpW(schema, httpW) || !strcmpW(schema, httpsW) || !strcmpW(schema, ftpW))) {
        hres = http_load_hack(This, mon, callback, bindctx);
    }else {
        IUnknown *unk = NULL;

        hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk);
        if(SUCCEEDED(hres)) {
            hres = S_OK;
            if(unk)
                IUnknown_Release(unk);
        }else if(try_application_url(url)) {
            hres = S_OK;
        }else {
            FIXME("BindToObject failed: %08x\n", hres);
        }
    }

    IMoniker_Release(mon);
    return S_OK;
}
Example #5
0
static HRESULT WINAPI UniformResourceLocatorW_InvokeCommand(IUniformResourceLocatorW *url, PURLINVOKECOMMANDINFOW pCommandInfo)
{
    InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
    WCHAR app[64];
    HKEY hkey;
    static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
    SHELLEXECUTEINFOW sei;
    DWORD res, type;
    HRESULT hres;

    TRACE("%p %p\n", This, pCommandInfo );

    if (pCommandInfo->dwcbSize < sizeof (URLINVOKECOMMANDINFOW))
        return E_INVALIDARG;

    if (pCommandInfo->dwFlags != IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB)
    {
        FIXME("(%p, %p): non-default verbs not implemented\n", url, pCommandInfo);
        return E_NOTIMPL;
    }

    hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
    if(FAILED(hres))
        return E_FAIL;

    res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
    if(res != ERROR_SUCCESS)
        return E_FAIL;

    res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return E_FAIL;

    memset(&sei, 0, sizeof(sei));
    sei.cbSize = sizeof(sei);
    sei.lpFile = This->url;
    sei.nShow = SW_SHOW;

    if( ShellExecuteExW(&sei) )
        return S_OK;
    else
        return E_FAIL;
}
Example #6
0
IInternetProtocolInfo *get_protocol_info(LPCWSTR url)
{
    IInternetProtocolInfo *ret = NULL;
    IClassFactory *cf;
    name_space *ns;
    WCHAR schema[64];
    DWORD schema_len;
    HRESULT hres;

    hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
            &schema_len, 0);
    if(FAILED(hres) || !schema_len)
        return NULL;

    EnterCriticalSection(&session_cs);

    ns = find_name_space(schema);
    if(ns && !ns->urlmon) {
        hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret);
        if(FAILED(hres))
            hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
    }

    LeaveCriticalSection(&session_cs);

    if(ns && SUCCEEDED(hres))
        return ret;

    hres = get_protocol_cf(schema, schema_len, NULL, &cf);
    if(FAILED(hres))
        return NULL;

    hres = IClassFactory_QueryInterface(cf, &IID_IInternetProtocolInfo, (void**)&ret);
    if(FAILED(hres))
        IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
    IClassFactory_Release(cf);

    return ret;
}
HRESULT OpenURL(HWND hWnd)
{
    HRESULT hr = S_OK;
    INT_PTR ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_OPENURL), hWnd, OpenURLDlgProc);
    if (LOWORD(ret) == IDCANCEL)
    {
        return E_FAIL;
    }
    InvalidateRect(hWnd, NULL, TRUE);

    WCHAR wcDomain[MAX_URL_LENGTH] = {0};
    DWORD cchDecodeUrl = 0;
    CoInternetParseUrl(g_wcURL, PARSE_DOMAIN, 0, wcDomain, MAX_URL_LENGTH, &cchDecodeUrl, 0);

    //int nbytes = WideCharToMultiByte(0, 0, g_szURL, nLength, NULL, 0, NULL, NULL);
    ZeroMemory(g_acURL, MAX_URL_LENGTH);
    WideCharToMultiByte(0, 0, g_wcURL, wcslen(g_wcURL), g_acURL, wcslen(g_wcURL), NULL, NULL);
    
    ZeroMemory(g_acDomain, MAX_URL_LENGTH);
    //nbytes = WideCharToMultiByte(0, 0, szDomain, wcslen(szDomain), NULL, 0, NULL, NULL);
    WideCharToMultiByte(0, 0, wcDomain, wcslen(wcDomain), g_acDomain, wcslen(wcDomain), NULL, NULL);
    
    char sendBuff[DEFAULT_BUFFER_LENGTH] = {0};
    sprintf_s(sendBuff, DEFAULT_BUFFER_LENGTH,
        "HEAD %s HTTP/1.1\r\n" \
        "Host: %s\r\n" \
        "Proxy-Connection: keep-alive\r\n" \
        "Proxy-Authorization: Basic ***********\r\n" \
        "Accept: */*\r\n" \
        "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36\r\n\r\n",
        strstr(g_acURL, g_acDomain)+strlen(g_acDomain), g_acDomain);

    int iResult = 0;
    ADDRINFOW* result = NULL;
    ADDRINFOW* ptr = NULL;
    ADDRINFOW hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    WCHAR* strProxyURL = L"test.proxy.com";
    WCHAR* strProxyPort = L"8080";

    iResult = GetAddrInfo(strProxyURL, strProxyPort, &hints, &result);
    if (iResult != 0)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"getaddrinfo failed: %d", iResult);
        return E_FAIL;
    }

    SOCKET connectSocket = INVALID_SOCKET;
    ptr = result;
    connectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
    if (connectSocket == INVALID_SOCKET)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"socket failed: %ld\n", WSAGetLastError());
        FreeAddrInfo(result);
        return E_FAIL;
    }

    int value = 0;
    int size = sizeof(value);
    iResult = getsockopt(connectSocket, SOL_SOCKET, SO_RCVBUF, (char*)&value, &size);

    iResult = connect(connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    FreeAddrInfo(result);
    if (iResult == SOCKET_ERROR)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"connect failed: %d", iResult);
        closesocket(connectSocket);
        return E_FAIL;
    }


    char recvBuff[DEFAULT_BUFFER_LENGTH] = {0};
    iResult = send(connectSocket, sendBuff, (int)strlen(sendBuff), 0);
    if (iResult == SOCKET_ERROR)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"send failed: %d", WSAGetLastError());
        closesocket(connectSocket);
        return E_FAIL;
    }

    iResult = shutdown(connectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"shutdown failed %d", WSAGetLastError());
        closesocket(connectSocket);
        return E_FAIL;
    }

    CStringA strHeader("");
    do
    {
        iResult = recv(connectSocket, recvBuff, DEFAULT_BUFFER_LENGTH, 0);
        if (iResult > 0)
        {
            strHeader += recvBuff;
        }
        else if (iResult == 0)
        {
            ICSE_OUTPUTDEBUGSTRING_W(L"Connection closed");
        }
        else
        {
            ICSE_OUTPUTDEBUGSTRING_W(L"recv failed %d", WSAGetLastError());
        }
    } while (iResult > 0);

    if (strHeader.GetLength() > 0)
    {
        int begin = strHeader.Find("Content-Length: ");
        int end = strHeader.Find("\r\n", begin);
        CStringA strLength = strHeader.Mid(begin + 16, end - begin - 16);
        __int64 length = _atoi64(strLength);
        ICSE_OUTPUTDEBUGSTRING_W(L"content length: %I64d", length);

        HANDLE hFile = ::CreateFile(g_wcFile, GENERIC_READ|GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        DWORD dwTemp = 0;
        ::DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL);
        CloseHandle(hFile);

        __int64 segmentLength = length / g_factor;
        for (int i = 0; i < g_factor; i++)
        {
            g_segmentMatrix[i][0] = i * segmentLength;
            g_segmentMatrix[i][1] = g_segmentMatrix[i][0] + segmentLength - 1;
            length -= segmentLength;
        }
        g_segmentMatrix[g_factor-1][1] += length;

        for (int i = 0; i < g_factor; i++)
        {
            _beginthread(ThreadProc, 0, (void*)i);
        }
    }

    closesocket(connectSocket);
    return hr;
}
void ThreadProc(void* param)
{
    int index = (int)param;
    ICSE_OUTPUTDEBUGSTRING_W(L"[%d][%I64d:%I64d]", index, g_segmentMatrix[index][0], g_segmentMatrix[index][1]);
    __int64 begin = 0;
    __int64 end = g_segmentMatrix[index][0] - 1;
    __int64 backup = end;
    __int64 writeSize = 0LL;

LOOP:
    int iResult = 0;
    ADDRINFOW* result = NULL;
    ADDRINFOW* ptr = NULL;
    ADDRINFOW hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    WCHAR szDomain[MAX_URL_LENGTH] = {0};
    DWORD cchDecodeUrl = 0;
    CoInternetParseUrl(g_wcURL, PARSE_DOMAIN, 0, szDomain, MAX_URL_LENGTH, &cchDecodeUrl, 0);

    WCHAR* strProxyURL = L"test.proxy.com";
    WCHAR* strProxyPort = L"8080";
    iResult = GetAddrInfo(strProxyURL, strProxyPort, &hints, &result);
    if (iResult != 0)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"[%d]getaddrinfo failed: %d", index, iResult);
    }

    SOCKET connectSocket = INVALID_SOCKET;
    ptr = result;
    connectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
    if (connectSocket == INVALID_SOCKET)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"[%d]socket failed: %ld\n", index, WSAGetLastError());
        FreeAddrInfo(result);
    }

    int value = 0;
    int size = sizeof(value);
    iResult = getsockopt(connectSocket, SOL_SOCKET, SO_RCVBUF, (char*)&value, &size);

    iResult = connect(connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    FreeAddrInfo(result);
    if (iResult == SOCKET_ERROR)
    {
        ICSE_OUTPUTDEBUGSTRING_W(L"[%d]connect failed: %d", index, iResult);
        closesocket(connectSocket);
    }

    do
    {
        begin = end + 1;
        end = ((begin + 32767) > g_segmentMatrix[index][1] ? g_segmentMatrix[index][1] : (begin + 32767));
        char sendBuff[DEFAULT_BUFFER_LENGTH] = {0};
        sprintf_s(sendBuff, DEFAULT_BUFFER_LENGTH,
            "GET %s HTTP/1.1\r\n" \
            "Host: %s\r\n" \
            "Proxy-Connection: keep-alive\r\n" \
            "Proxy-Authorization: Basic ***********\r\n" \
            "Accept: */*\r\n" \
            "Range: bytes=%I64d-%I64d\r\n"
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36\r\n\r\n",
            strstr(g_acURL, g_acDomain)+strlen(g_acDomain), g_acDomain, begin, end);
        iResult = send(connectSocket, sendBuff, (int)strlen(sendBuff), 0);
        if (iResult == SOCKET_ERROR)
        {
            ICSE_OUTPUTDEBUGSTRING_W(L"[%d]send failed: %d", index, WSAGetLastError());
            closesocket(connectSocket);
        }

        char recvBuff[DEFAULT_BUFFER_LENGTH * 33] = {0};
        int recvLength = 0;
        char* dataAddress = NULL;
        bool bRecvSucess = false;
        do
        {
            iResult = recv(connectSocket, recvBuff + recvLength, DEFAULT_BUFFER_LENGTH * 33 - recvLength, 0);
            if (iResult > 0)
            {
                recvLength += iResult;
                ICSE_OUTPUTDEBUGSTRING_W(L"[%d]recv length %d", index, iResult);
                dataAddress = StrStrA(recvBuff, "\r\n\r\n") + 4;
                if ((recvLength - (dataAddress - recvBuff)) == (int)(end - begin + 1))
                {
                    bRecvSucess = true;
                    break;
                }
            }
            else if (iResult == 0)
            {
                ICSE_OUTPUTDEBUGSTRING_W(L"[%d]Connection closed", index);
            }
            else
            {
                ICSE_OUTPUTDEBUGSTRING_W(L"[%d]recv failed %d", index, WSAGetLastError());
            }
        } while (iResult > 0);

        if (bRecvSucess)
        {
            HANDLE hFile = CreateFile(g_wcFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == NULL)
            {
                ICSE_OUTPUTDEBUGSTRING_W(L"[%d]file open failed %d", index, GetLastError());
                break;
            }
            LONG llow = (LONG)(begin & 0x0FFFFFFFF);
            LONG lhigh = (LONG)((begin & 0xFFFFFFFF00000000)>>32);
            DWORD dwPrt = SetFilePointer(hFile, llow, &lhigh, FILE_BEGIN);
            if (dwPrt == INVALID_SET_FILE_POINTER)
            {
                ICSE_OUTPUTDEBUGSTRING_W(L"[%d]move pointer failed %d", index, GetLastError());
                break;
            }
            DWORD dwSize = 0;
            WriteFile(hFile, dataAddress, (int)(end - begin + 1), &dwSize, NULL);
            CloseHandle(hFile);

            backup = end;
            writeSize += (__int64)dwSize;
            g_segmentMatrix[index][2] =writeSize;
            InvalidateRect(g_hWndMain, NULL, TRUE);
        }
        else
        {
            ICSE_OUTPUTDEBUGSTRING_W(L"[%d]recv error! %d", index, recvLength);
            closesocket(connectSocket);
            end = backup;
            goto LOOP;
        }
    } while (end < g_segmentMatrix[index][1]);
Example #9
0
static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
{
    LPWSTR secur_url;
    WCHAR schema[64];
    DWORD size=0;
    HRESULT hres;

    *zone = URLZONE_INVALID;

    hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
    if(hres != S_OK) {
        size = strlenW(url)*sizeof(WCHAR);

        secur_url = heap_alloc(size);
        if(!secur_url)
            return E_OUTOFMEMORY;

        memcpy(secur_url, url, size);
    }

    hres = CoInternetParseUrl(secur_url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0);
    if(FAILED(hres) || !*schema) {
        heap_free(secur_url);
        return E_INVALIDARG;
    }

    /* file protocol is a special case */
    if(!strcmpW(schema, fileW)) {
        WCHAR path[MAX_PATH], root[20];
        WCHAR *ptr;

        hres = CoInternetParseUrl(secur_url, PARSE_PATH_FROM_URL, 0, path,
                sizeof(path)/sizeof(WCHAR), &size, 0);

        if(SUCCEEDED(hres) && (ptr = strchrW(path, '\\')) && ptr-path < sizeof(root)/sizeof(WCHAR)) {
            UINT type;

            memcpy(root, path, (ptr-path)*sizeof(WCHAR));
            root[ptr-path] = 0;

            type = GetDriveTypeW(root);

            switch(type) {
            case DRIVE_UNKNOWN:
            case DRIVE_NO_ROOT_DIR:
                break;
            case DRIVE_REMOVABLE:
            case DRIVE_FIXED:
            case DRIVE_CDROM:
            case DRIVE_RAMDISK:
                *zone = URLZONE_LOCAL_MACHINE;
                hres = S_OK;
                break;
            case DRIVE_REMOTE:
                *zone = URLZONE_INTERNET;
                hres = S_OK;
                break;
            default:
                FIXME("unsupported drive type %d\n", type);
            }
        }
    }

    if(*zone == URLZONE_INVALID) {
        WARN("domains are not yet implemented\n");
        hres = get_zone_from_reg(schema, zone);
    }

    if(FAILED(hres) || !ret_url)
        heap_free(secur_url);
    else
        *ret_url = secur_url;

    return hres;
}
Example #10
0
static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    FileProtocol *This = PROTOCOL_THIS(iface);
    BINDINFO bindinfo;
    DWORD grfBINDF = 0;
    LARGE_INTEGER size;
    DWORD len;
    LPWSTR url, mime = NULL, file_name;
    WCHAR null_char = 0;
    BOOL first_call = FALSE;
    HRESULT hres;

    static const WCHAR wszFile[]  = {'f','i','l','e',':'};

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
            pOIBindInfo, grfPI, dwReserved);

    if(!szUrl || strlenW(szUrl) < sizeof(wszFile)/sizeof(WCHAR)
            || memcmp(szUrl, wszFile, sizeof(wszFile)))
        return E_INVALIDARG;

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
    if(FAILED(hres)) {
        WARN("GetBindInfo failed: %08x\n", hres);
        return hres;
    }

    ReleaseBindInfo(&bindinfo);

    len = lstrlenW(szUrl)+16;
    url = heap_alloc(len*sizeof(WCHAR));
    hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0);
    if(FAILED(hres)) {
        heap_free(url);
        return hres;
    }

    if(!(grfBINDF & BINDF_FROMURLMON))
        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);

    if(!This->file) {
        WCHAR *ptr;

        first_call = TRUE;

        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);

        file_name = url+sizeof(wszFile)/sizeof(WCHAR);

        /* Strip both forward and back slashes */
        if( (file_name[0] == '/' && file_name[1] == '/') ||
            (file_name[0] == '\\' && file_name[1] == '\\'))
            file_name += 2;
        if(*file_name == '/')
            file_name++;

        for(ptr = file_name; *ptr; ptr++) {
            if(*ptr == '?' || *ptr == '#') {
                *ptr = 0;
                break;
            }
        }

        if(file_name[1] == '|')
            file_name[1] = ':';

        This->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

        if(This->file == INVALID_HANDLE_VALUE) {
            This->file = NULL;
            IInternetProtocolSink_ReportResult(pOIProtSink, INET_E_RESOURCE_NOT_FOUND,
                    GetLastError(), NULL);
            heap_free(url);
            return INET_E_RESOURCE_NOT_FOUND;
        }

        IInternetProtocolSink_ReportProgress(pOIProtSink,
                BINDSTATUS_CACHEFILENAMEAVAILABLE, file_name);

        hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
        if(SUCCEEDED(hres)) {
            IInternetProtocolSink_ReportProgress(pOIProtSink,
                    (grfBINDF & BINDF_FROMURLMON) ?
                    BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
                    mime);
            CoTaskMemFree(mime);
        }
    }

    heap_free(url);

    if(GetFileSizeEx(This->file, &size))
        IInternetProtocolSink_ReportData(pOIProtSink,
                BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
                size.u.LowPart, size.u.LowPart);

    if(first_call)
        IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);

    return S_OK;
}
Example #11
0
static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);
    WCHAR *url_dll, *url_file, *url, *mime, *res_type = (LPWSTR)RT_HTML, *ptr;
    DWORD grfBINDF = 0, len;
    BINDINFO bindinfo;
    HMODULE hdll;
    HRSRC src;
    HRESULT hres;

    static const WCHAR wszRes[] = {'r','e','s',':','/','/'};

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
            pOIBindInfo, grfPI, dwReserved);

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
    if(FAILED(hres))
        return hres;
    ReleaseBindInfo(&bindinfo);

    len = strlenW(szUrl)+16;
    url = heap_alloc(len*sizeof(WCHAR));
    hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0);
    if(FAILED(hres)) {
        WARN("CoInternetParseUrl failed: %08x\n", hres);
        heap_free(url);
        IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL);
        return hres;
    }

    if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(url, wszRes, sizeof(wszRes))) {
        WARN("Wrong protocol of url: %s\n", debugstr_w(url));
        IInternetProtocolSink_ReportResult(pOIProtSink, E_INVALIDARG, 0, NULL);
        heap_free(url);
        return E_INVALIDARG;
    }

    url_dll = url + sizeof(wszRes)/sizeof(wszRes[0]);
    if(!(res_type = strchrW(url_dll, '/'))) {
        WARN("wrong url: %s\n", debugstr_w(url));
        IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
        heap_free(url);
        return MK_E_SYNTAX;
    }

    *res_type++ = 0;
    if ((url_file = strchrW(res_type, '/'))) {
        *url_file++ = 0;
    }else {
        url_file = res_type;
        res_type = MAKEINTRESOURCEW(RT_HTML);
    }

    /* Ignore query and hash parts. */
    if((ptr = strchrW(url_file, '?')))
        *ptr = 0;
    if((ptr = strchrW(url_file, '#')))
        *ptr = 0;

    hdll = LoadLibraryExW(url_dll, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if(!hdll) {
        WARN("Could not open dll: %s\n", debugstr_w(url_dll));
        IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
        heap_free(url);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    TRACE("trying to find resource type %s, name %s\n", debugstr_w(res_type), debugstr_w(url_file));

    src = FindResourceW(hdll, url_file, res_type);
    if(!src) {
        LPWSTR endpoint = NULL;
        DWORD file_id = strtolW(url_file, &endpoint, 10);
        if(endpoint == url_file+strlenW(url_file))
            src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), res_type);

        if(!src) {
            WARN("Could not find resource\n");
            IInternetProtocolSink_ReportResult(pOIProtSink,
                    HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
            heap_free(url);
            return HRESULT_FROM_WIN32(GetLastError());
        }
    }

    if(This->data) {
        WARN("data already loaded\n");
        heap_free(This->data);
    }

    This->data_len = SizeofResource(hdll, src);
    This->data = heap_alloc(This->data_len);
    memcpy(This->data, LoadResource(hdll, src), This->data_len);
    This->cur = 0;

    FreeLibrary(hdll);

    hres = FindMimeFromData(NULL, url_file, This->data, This->data_len, NULL, 0, &mime, 0);
    heap_free(url);
    if(SUCCEEDED(hres)) {
        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
        CoTaskMemFree(mime);
    }

    IInternetProtocolSink_ReportData(pOIProtSink,
            BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
            This->data_len, This->data_len);

    IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
    
    return S_OK;
}
Example #12
0
static NPError
_OpenURL(NPP npp, const char *szURL, const char *szTarget, void *pNotifyData, const char *pData, uint32 len, NPBool isFile)
{
    if (!npp)
    {
        return NPERR_INVALID_INSTANCE_ERROR;
    }

    void *postData = NULL;
    uint32 postDataLen = 0;
    if (pData)
    {
        if (!isFile)
        {
            postData = (void *) pData;
            postDataLen = len;
        }
        else
        {
            // TODO read the file specified in the postdata param into memory
        }
    }

    nsPluginHostWnd *pWnd = (nsPluginHostWnd *) npp->ndata;
    ATLASSERT(pWnd);

    // Other window targets
    if (szTarget)
    {
        CComPtr<IWebBrowserApp> cpBrowser;
        pWnd->GetWebBrowserApp(&cpBrowser);
        if (!cpBrowser)
        {
            return NPERR_GENERIC_ERROR;
        }

        CComBSTR url(szURL);
        
        HRESULT hr;

        // Test if the input URL has a schema which means it's relative,
        // otherwise consider it to be relative to the current URL

        WCHAR szSchema[10];
        const DWORD cbSchema = sizeof(szSchema) / sizeof(szSchema[0]);
        DWORD cbSchemaUsed = 0;

        memset(szSchema, 0, cbSchema);
        hr = CoInternetParseUrl(url.m_str, PARSE_SCHEMA, 0,
            szSchema, cbSchema, &cbSchemaUsed, 0);

        if (hr != S_OK || cbSchemaUsed == 0)
        {
            // Convert relative URLs to absolute, so that they can be loaded
            // by the Browser

            CComBSTR bstrCurrentURL;
            cpBrowser->get_LocationURL(&bstrCurrentURL);
        
            if (bstrCurrentURL.Length())
            {
                USES_CONVERSION;
                DWORD cbNewURL = (url.Length() + bstrCurrentURL.Length() + 1) * sizeof(WCHAR);
                DWORD cbNewURLUsed = 0;
                WCHAR *pszNewURL = (WCHAR *) calloc(cbNewURL, 1);
                ATLASSERT(pszNewURL);

                CoInternetCombineUrl(
                    bstrCurrentURL.m_str,
                    url.m_str,
                    0,
                    pszNewURL,
                    cbNewURL,
                    &cbNewURLUsed,
                    0);

                ATLASSERT(cbNewURLUsed < cbNewURL);

                url = pszNewURL;
                free(pszNewURL);
            }
        }

        CComVariant vFlags;
        CComVariant vTarget(szTarget);
        CComVariant vPostData;
        CComVariant vHeaders;

        // Initialise postdata
        if (postData)
        {
            // According to the documentation.
            // The post data specified by PostData is passed as a SAFEARRAY
            // structure. The variant should be of type VT_ARRAY and point to
            // a SAFEARRAY. The SAFEARRAY should be of element type VT_UI1,
            // dimension one, and have an element count equal to the number of
            // bytes of post data.

            SAFEARRAYBOUND saBound[1];
            saBound[0].lLbound = 0;
            saBound[0].cElements = len;
            vPostData.vt = VT_ARRAY | VT_UI1;
            vPostData.parray = SafeArrayCreate(VT_UI1, 1, saBound);
            SafeArrayLock(vPostData.parray);
            memcpy(vPostData.parray->pvData, postData, postDataLen);
            SafeArrayUnlock(vPostData.parray);
        }

        cpBrowser->Navigate(url, &vFlags, &vTarget, &vPostData, &vHeaders);
        // TODO listen to navigation & send a URL notify to plugin when completed
        return NPERR_NO_ERROR;
    }

    USES_CONVERSION;
    HRESULT hr = pWnd->OpenURLStream(A2CT(szURL), pNotifyData, postData, postDataLen);
    return SUCCEEDED(hr) ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
}