static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = DISPATCHEX_THIS(iface); HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(is_custom_dispid(id) && This->data->vtbl && This->data->vtbl->invoke) return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(wFlags == DISPATCH_CONSTRUCT) { if(id == DISPID_VALUE) { if(This->data->vtbl && This->data->vtbl->value) { return This->data->vtbl->value(This->outer, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } FIXME("DISPATCH_CONSTRUCT flag but missing value function\n"); return E_FAIL; } FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n"); return E_FAIL; } if(is_dynamic_dispid(id)) { DWORD idx = id - DISPID_DYNPROP_0; dynamic_prop_t *prop; if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; prop = This->dynamic_data->props+idx; switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: if(!pvarRes) return E_INVALIDARG; case DISPATCH_METHOD: { DISPID named_arg = DISPID_THIS; DISPPARAMS dp = {NULL, &named_arg, 0, 1}; IDispatchEx *dispex; if(V_VT(&prop->var) != VT_DISPATCH) { FIXME("invoke %s\n", debugstr_variant(&prop->var)); return E_NOTIMPL; } if(pdp->cNamedArgs) { FIXME("named args not supported\n"); return E_NOTIMPL; } dp.rgvarg = heap_alloc((pdp->cArgs+1)*sizeof(VARIANTARG)); if(!dp.rgvarg) return E_OUTOFMEMORY; dp.cArgs = pdp->cArgs+1; memcpy(dp.rgvarg+1, pdp->rgvarg, pdp->cArgs*sizeof(VARIANTARG)); V_VT(dp.rgvarg) = VT_DISPATCH; V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This); hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex); TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name)); if(SUCCEEDED(hres)) { hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller); IDispatchEx_Release(dispex); } else { ULONG err = 0; hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err); } TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres); heap_free(dp.rgvarg); return hres; } case DISPATCH_PROPERTYGET: if(prop->flags & DYNPROP_DELETED) return DISP_E_UNKNOWNNAME; return VariantCopy(pvarRes, &prop->var); case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT: if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT) || pdp->cNamedArgs > 1) { FIXME("invalid args\n"); return E_INVALIDARG; } TRACE("put %s\n", debugstr_variant(pdp->rgvarg)); VariantClear(&prop->var); hres = VariantCopy(&prop->var, pdp->rgvarg); if(FAILED(hres)) return hres; prop->flags &= ~DYNPROP_DELETED; return S_OK; default: FIXME("unhandled wFlags %x\n", wFlags); return E_NOTIMPL; } } return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { SAFEARRAY *post_array = NULL; PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; HRESULT hres = S_OK; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY && V_VT(Flags) != VT_ERROR) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY && V_VT(TargetFrameName) != VT_ERROR)) FIXME("Unsupported args (Flags %s; TargetFrameName %s)\n", debugstr_variant(Flags), debugstr_variant(TargetFrameName)); if(PostData) { if(V_VT(PostData) & VT_ARRAY) post_array = V_ISBYREF(PostData) ? *V_ARRAYREF(PostData) : V_ARRAY(PostData); else WARN("Invalid post data %s\n", debugstr_variant(PostData)); } if(post_array) { LONG elem_max; SafeArrayAccessData(post_array, (void**)&post_data); SafeArrayGetUBound(post_array, 1, &elem_max); post_data_len = (elem_max+1) * SafeArrayGetElemsize(post_array); } if(Headers && V_VT(Headers) == VT_BSTR) { headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } set_doc_state(This, READYSTATE_LOADING); This->ready_state = READYSTATE_LOADING; if(This->doc_navigate) { WCHAR new_url[INTERNET_MAX_URL_LENGTH]; if(PathIsURLW(url)) { new_url[0] = 0; }else { DWORD size; size = sizeof(new_url)/sizeof(WCHAR); hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT); if(FAILED(hres)) { WARN("UrlApplyScheme failed: %08x\n", hres); new_url[0] = 0; } } hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data, post_data_len, TRUE); }else { task_navigate_bsc_t *task; task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL); } if(post_data) SafeArrayUnaccessData(post_array); return hres; }
void * sml_heap_slow_alloc(size_t alloc_size) { void *obj; #ifdef PRINT_ALLOC_TIME int i; for(i=0;i<THE_NUMBER_OF_FIXED_BLOCK;i++) { if(print_info[i].block_size >= alloc_size) { print_info[i].count_gc++; break; } } #ifdef GC_TIME tmp_mark = count_call_mark - count_not_mark - count_outside; #endif /* GC_TIME */ double st; getRusage(st); #endif /* PRINT_ALLOC_TIME */ #ifdef GCSTAT { struct bitmap_info_space *b_info = MAPPING_HEAP_ALLOC(alloc_size); gcstat.last.trigger = b_info->block_size_bytes; } #endif /* GCSTAT */ sml_heap_gc(); #ifdef PRINT_ALLOC_TIME double en; getRusage(en); all_time_gc += (en - st); #ifdef GC_TIME fprintf(fp_at,"gc %f mark %u live %u alloc %u invoke_size %u\n", (en - st), (count_call_mark - count_not_mark - count_outside)-tmp_mark, live_tmp,count_alloc - tmp_alloc, alloc_size); tmp_alloc = count_alloc; #endif /* GC_TIME */ #endif /* PRINT_ALLOC_TIME */ #ifndef UPPER obj = heap_alloc(alloc_size); #else /* UPPER */ obj = heap_alloc_with_upper(alloc_size); #endif /* UPPER */ if (obj == NULL) { DBG(("alloc failed")); #ifdef GCSTAT stat_notice("---"); stat_notice("event: error"); stat_notice("heap exceeded: intented to allocate %lu bytes.", (unsigned long)alloc_size); if (gcstat.file) fclose(gcstat.file); #endif /* GCSTAT */ sml_fatal(0, "heap exceeded: intended to allocate %"PRIuMAX" bytes", (intmax_t)alloc_size); } return obj; }
static dispex_data_t *preprocess_dispex_data(DispatchEx *This) { const tid_t *tid = This->data->iface_tids; FUNCDESC *funcdesc; dispex_data_t *data; DWORD size = 16, i; ITypeInfo *ti, *dti; HRESULT hres; TRACE("(%p)\n", This); hres = get_typeinfo(This->data->disp_tid, &dti); if(FAILED(hres)) { ERR("Could not get disp type info: %08x\n", hres); return NULL; } data = heap_alloc(sizeof(dispex_data_t)); data->func_cnt = 0; data->funcs = heap_alloc(size*sizeof(func_info_t)); list_add_tail(&dispex_data_list, &data->entry); while(*tid) { hres = get_typeinfo(*tid, &ti); if(FAILED(hres)) break; i=0; while(1) { hres = ITypeInfo_GetFuncDesc(ti, i++, &funcdesc); if(FAILED(hres)) break; add_func_info(data, &size, *tid, funcdesc->memid, dti); ITypeInfo_ReleaseFuncDesc(ti, funcdesc); } ITypeInfo_Release(ti); tid++; } if(!data->func_cnt) { heap_free(data->funcs); data->funcs = NULL; }else if(data->func_cnt != size) { data->funcs = heap_realloc(data->funcs, data->func_cnt * sizeof(func_info_t)); } qsort(data->funcs, data->func_cnt, sizeof(func_info_t), dispid_cmp); if(data->funcs) { data->name_table = heap_alloc(data->func_cnt * sizeof(func_info_t*)); for(i=0; i < data->func_cnt; i++) data->name_table[i] = data->funcs+i; qsort(data->name_table, data->func_cnt, sizeof(func_info_t*), func_name_cmp); }else { data->name_table = NULL; } ITypeInfo_Release(dti); return data; }
/********************************************************************* * security_on_initdialog [internal] * * handle WM_INITDIALOG * */ static INT_PTR security_on_initdialog(HWND hsec) { secdlg_data *sd; HRESULT hr; DWORD current_zone; DWORD lv_index = 0; DWORD i; sd = heap_alloc_zero(sizeof(secdlg_data)); SetWindowLongPtrW(hsec, DWLP_USER, (LONG_PTR) sd); if (!sd) { return FALSE; } sd->hsec = hsec; sd->hlv = GetDlgItem(hsec, IDC_SEC_LISTVIEW); sd->htb = GetDlgItem(hsec, IDC_SEC_TRACKBAR); EnableWindow(sd->htb, FALSE); /* not changeable yet */ TRACE("(%p) (data: %p, listview: %p, trackbar: %p)\n", hsec, sd, sd->hlv, sd->htb); SendMessageW(sd->htb, TBM_SETRANGE, FALSE, MAKELONG(0, NUM_TRACKBAR_POS - 1)); SendMessageW(sd->htb, TBM_SETTICFREQ, 1, 0 ); /* Create the image lists for the listview */ sd->himages = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32 | ILC_MASK, 1, 1); TRACE("using imagelist: %p\n", sd->himages); if (!sd->himages) { ERR("ImageList_Create failed!\n"); return FALSE; } SendMessageW(sd->hlv, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)sd->himages); hr = security_enum_zones(sd); if (FAILED(hr)) { ERR("got 0x%x\n", hr); security_on_destroy(sd); return FALSE; } TRACE("found %d zones\n", sd->num_zones); /* remember ZONEATTRIBUTES for a listview entry */ sd->zone_attr = heap_alloc(sizeof(ZONEATTRIBUTES) * sd->num_zones); if (!sd->zone_attr) { security_on_destroy(sd); return FALSE; } /* remember zone number and current security level for a listview entry */ sd->zones = heap_alloc((sizeof(DWORD) + sizeof(DWORD)) * sd->num_zones); if (!sd->zones) { security_on_destroy(sd); return FALSE; } sd->levels = &sd->zones[sd->num_zones]; /* use the same order as visible with native inetcpl.cpl */ add_zone_to_listview(sd, &lv_index, URLZONE_INTERNET); add_zone_to_listview(sd, &lv_index, URLZONE_INTRANET); add_zone_to_listview(sd, &lv_index, URLZONE_TRUSTED); add_zone_to_listview(sd, &lv_index, URLZONE_UNTRUSTED); for (i = 0; i < sd->num_zones; i++) { hr = IInternetZoneManager_GetZoneAt(sd->zone_mgr, sd->zone_enumerator, i, ¤t_zone); if (SUCCEEDED(hr) && (current_zone != (DWORD)URLZONE_INVALID)) { if (!current_zone || (current_zone > URLZONE_UNTRUSTED)) { add_zone_to_listview(sd, &lv_index, current_zone); } } } return TRUE; }
HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; HRESULT hres = S_OK; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY)) FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n", Flags, Flags ? V_VT(Flags) : -1, TargetFrameName, TargetFrameName ? V_VT(TargetFrameName) : -1); if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) { SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data); post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements; } if(Headers && V_VT(Headers) == VT_BSTR) { headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } set_doc_state(This, READYSTATE_LOADING); This->ready_state = READYSTATE_LOADING; if(This->doc_navigate) { WCHAR new_url[INTERNET_MAX_URL_LENGTH]; if(PathIsURLW(url)) { new_url[0] = 0; }else { DWORD size; size = sizeof(new_url)/sizeof(WCHAR); hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT); if(FAILED(hres)) { WARN("UrlApplyScheme failed: %08x\n", hres); new_url[0] = 0; } } hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data, post_data_len, TRUE); }else { task_navigate_bsc_t *task; task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL); } if(post_data) SafeArrayUnaccessData(V_ARRAY(PostData)); return hres; }
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { DispatchEx *This = impl_from_IDispatchEx(iface); dispex_data_t *data; int min, max, n, c; TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) FIXME("Unsupported grfdex %x\n", grfdex); data = get_dispex_data(This); if(!data) return E_FAIL; min = 0; max = data->func_cnt-1; while(min <= max) { n = (min+max)/2; c = strcmpiW(data->name_table[n]->name, bstrName); if(!c) { if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, bstrName)) break; *pid = data->name_table[n]->id; return S_OK; } if(c > 0) max = n-1; else min = n+1; } if(This->dynamic_data) { unsigned i; for(i=0; i < This->dynamic_data->prop_cnt; i++) { if(!strcmpW(This->dynamic_data->props[i].name, bstrName)) { *pid = DISPID_DYNPROP_0 + i; return S_OK; } } } if(This->data->vtbl && This->data->vtbl->get_dispid) { HRESULT hres; hres = This->data->vtbl->get_dispid(This->outer, bstrName, grfdex, pid); if(hres != DISP_E_UNKNOWNNAME) return hres; } if(grfdex & fdexNameEnsure) { dispex_dynamic_data_t *dynamic_data; TRACE("creating dynamic prop %s\n", debugstr_w(bstrName)); if(This->dynamic_data) { dynamic_data = This->dynamic_data; }else { dynamic_data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)); if(!dynamic_data) return E_OUTOFMEMORY; } if(!dynamic_data->buf_size) { dynamic_data->props = heap_alloc(sizeof(dynamic_prop_t)*4); if(!dynamic_data->props) return E_OUTOFMEMORY; dynamic_data->buf_size = 4; }else if(dynamic_data->buf_size == dynamic_data->prop_cnt) { dynamic_prop_t *new_props; new_props = heap_realloc(dynamic_data->props, sizeof(dynamic_prop_t)*(dynamic_data->buf_size<<1)); if(!new_props) return E_OUTOFMEMORY; dynamic_data->props = new_props; dynamic_data->buf_size <<= 1; } dynamic_data->props[dynamic_data->prop_cnt].name = heap_strdupW(bstrName); VariantInit(&dynamic_data->props[dynamic_data->prop_cnt].var); *pid = DISPID_DYNPROP_0 + dynamic_data->prop_cnt++; return S_OK; } TRACE("not found %s\n", debugstr_w(bstrName)); return DISP_E_UNKNOWNNAME; }
event_t event_create(heap_t h) { event_t e = heap_alloc(h, sizeof(event_s)); e->heap = h; e->first = e->last = e->pool = 0; return e; }
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { #ifdef SONAME_LIBSSL int ret; if (flags & ~(MSG_PEEK | MSG_WAITALL)) FIXME("SSL_read does not support the following flags: %08x\n", flags); /* this ugly hack is all for MSG_PEEK */ if (flags & MSG_PEEK && !conn->peek_msg) { if (!(conn->peek_msg = conn->peek_msg_mem = heap_alloc( len + 1 ))) return FALSE; } else if (flags & MSG_PEEK && conn->peek_msg) { if (len < conn->peek_len) FIXME("buffer isn't big enough, should we wrap?\n"); *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); return TRUE; } else if (conn->peek_msg) { *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); conn->peek_len -= *recvd; conn->peek_msg += *recvd; if (conn->peek_len == 0) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE; } ret = pSSL_read( conn->ssl_conn, (char *)buf + *recvd, len - *recvd ); if (ret < 0) return FALSE; /* check if EOF was received */ if (!ret && (pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_ZERO_RETURN || pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_SYSCALL )) { netconn_close( conn ); return TRUE; } if (flags & MSG_PEEK) /* must copy into buffer */ { conn->peek_len = ret; if (!ret) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } else memcpy( conn->peek_msg, buf, ret ); } *recvd = ret; return TRUE; #else return FALSE; #endif } if ((*recvd = recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback **obj, const VARIANT *body) { BindStatusCallback *bsc; IBindCtx *pbc; HRESULT hr; hr = CreateBindCtx(0, &pbc); if (hr != S_OK) return hr; bsc = heap_alloc(sizeof(*bsc)); if (!bsc) { IBindCtx_Release(pbc); return E_OUTOFMEMORY; } bsc->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; bsc->lpHttpNegotiateVtbl = &BSCHttpNegotiateVtbl; bsc->ref = 1; bsc->request = This; bsc->binding = NULL; bsc->stream = NULL; bsc->body = NULL; TRACE("created callback %p\n", bsc); if (This->verb != BINDVERB_GET) { if (V_VT(body) == VT_BSTR) { LONG size = SysStringLen(V_BSTR(body)) * sizeof(WCHAR); void *ptr; bsc->body = GlobalAlloc(GMEM_FIXED, size); if (!bsc->body) { heap_free(bsc); return E_OUTOFMEMORY; } ptr = GlobalLock(bsc->body); memcpy(ptr, V_BSTR(body), size); GlobalUnlock(bsc->body); } else FIXME("unsupported body data type %d\n", V_VT(body)); } hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)bsc, NULL, 0); if (hr == S_OK) { IMoniker *moniker; hr = CreateURLMoniker(NULL, This->url, &moniker); if (hr == S_OK) { IStream *stream; hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (void**)&stream); IMoniker_Release(moniker); if (stream) IStream_Release(stream); } IBindCtx_Release(pbc); } if (FAILED(hr)) { IBindStatusCallback_Release((IBindStatusCallback*)bsc); bsc = NULL; } *obj = bsc; return hr; }
static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface, DWORD bscf, ULONG progress, ULONG progress_max) { BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface); TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max); This->bscf = bscf; This->progress = progress; This->progress_max = progress_max; if(!This->protocol_sink) return S_OK; if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { BYTE buf[BUFFER_SIZE]; DWORD read = 0; LPWSTR mime; HRESULT hres; do { read = 0; if(is_apartment_thread(This)) This->continue_call++; hres = IInternetProtocol_Read(This->protocol, buf, sizeof(buf)-This->buf_size, &read); if(is_apartment_thread(This)) This->continue_call--; if(FAILED(hres) && hres != E_PENDING) return hres; if(!This->buf) { This->buf = heap_alloc(BUFFER_SIZE); if(!This->buf) return E_OUTOFMEMORY; }else if(read + This->buf_size > BUFFER_SIZE) { BYTE *tmp; tmp = heap_realloc(This->buf, read+This->buf_size); if(!tmp) return E_OUTOFMEMORY; This->buf = tmp; } memcpy(This->buf+This->buf_size, buf, read); This->buf_size += read; }while(This->buf_size < MIME_TEST_SIZE && hres == S_OK); if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE) return S_OK; bscf = BSCF_FIRSTDATANOTIFICATION; if(hres == S_FALSE) bscf |= BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE; if(!This->reported_mime) { BSTR raw_uri; hres = IUri_GetRawUri(This->uri, &raw_uri); if(FAILED(hres)) return hres; hres = FindMimeFromData(NULL, raw_uri, This->buf, min(This->buf_size, MIME_TEST_SIZE), This->mime, 0, &mime, 0); SysFreeString(raw_uri); if(FAILED(hres)) return hres; heap_free(This->mime); This->mime = heap_strdupW(mime); CoTaskMemFree(mime); This->reported_mime = TRUE; if(This->protocol_sink) IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); } } if(!This->protocol_sink) return S_OK; return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); }
/****************************************************************************** * LsaLookupSids [ADVAPI32.@] * * Looks up the names that correspond to an array of SIDs. * * PARAMS * PolicyHandle [I] Handle to a Policy object. * Count [I] Number of SIDs in the Sids array. * Sids [I] Array of SIDs to lookup. * ReferencedDomains [O] Array of domains where the sids were found. * Names [O] Array of names corresponding to Sids. * * RETURNS * Success: STATUS_SUCCESS, * STATUS_SOME_NOT_MAPPED * Failure: STATUS_NONE_MAPPED or NTSTATUS code. */ NTSTATUS WINAPI LsaLookupSids( LSA_HANDLE PolicyHandle, ULONG Count, PSID *Sids, LSA_REFERENCED_DOMAIN_LIST **ReferencedDomains, LSA_TRANSLATED_NAME **Names) { ULONG i, mapped, name_fullsize, domain_fullsize; ULONG name_size, domain_size; LSA_UNICODE_STRING domain; WCHAR *name_buffer; char *domain_data; SID_NAME_USE use; TRACE("(%p, %u, %p, %p, %p)\n", PolicyHandle, Count, Sids, ReferencedDomains, Names); /* this length does not include actual string length yet */ name_fullsize = sizeof(LSA_TRANSLATED_NAME) * Count; if (!(*Names = heap_alloc(name_fullsize))) return STATUS_NO_MEMORY; /* maximum count of stored domain infos is Count, allocate it like that cause really needed count could only be computed after sid data is retrieved */ domain_fullsize = sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION) * (Count + 1); if (!(*ReferencedDomains = heap_alloc(domain_fullsize))) { heap_free(*Names); return STATUS_NO_MEMORY; } (*ReferencedDomains)->Entries = 0; (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)); (*ReferencedDomains)->Domains[-1].Sid = NULL; RtlInitUnicodeStringEx(&(*ReferencedDomains)->Domains[-1].Name, NULL); /* Get full names data length and full length needed to store domain name and SID */ for (i = 0; i < Count; i++) { (*Names)[i].Use = SidTypeUnknown; (*Names)[i].DomainIndex = -1; RtlInitUnicodeStringEx(&(*Names)[i].Name, NULL); memset(&(*ReferencedDomains)->Domains[i], 0, sizeof(LSA_TRUST_INFORMATION)); name_size = domain_size = 0; if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (name_size) { (*Names)[i].Name.Length = (name_size - 1) * sizeof(WCHAR); (*Names)[i].Name.MaximumLength = name_size * sizeof(WCHAR); name_fullsize += (*Names)[i].Name.MaximumLength; } else { (*Names)[i].Name.Length = 0; (*Names)[i].Name.MaximumLength = 0; } /* This potentially allocates more than needed, cause different names will reuse same domain index. Also it's not possible to store domain name length right here for the same reason. */ if (domain_size) { ULONG sid_size = 0; BOOL handled = FALSE; WCHAR *name; domain_fullsize += domain_size * sizeof(WCHAR); /* get domain SID size too */ name = heap_alloc(domain_size * sizeof(WCHAR)); *name = 0; LookupAccountSidW(NULL, Sids[i], NULL, &name_size, name, &domain_size, &use); domain.Buffer = name; domain.Length = domain_size * sizeof(WCHAR); domain.MaximumLength = domain_size * sizeof(WCHAR); lookup_name(&domain, NULL, &sid_size, NULL, &domain_size, &use, &handled); domain_fullsize += sid_size; heap_free(name); } } } /* now we have full length needed for both */ *Names = heap_realloc(*Names, name_fullsize); name_buffer = (WCHAR*)((char*)*Names + sizeof(LSA_TRANSLATED_NAME)*Count); *ReferencedDomains = heap_realloc(*ReferencedDomains, domain_fullsize); /* fix pointer after reallocation */ (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)); domain_data = (char*)(*ReferencedDomains)->Domains + sizeof(LSA_TRUST_INFORMATION)*Count; mapped = 0; for (i = 0; i < Count; i++) { name_size = domain_size = 0; if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { mapped++; if (domain_size) { domain.Length = (domain_size - 1) * sizeof(WCHAR); domain.MaximumLength = domain_size * sizeof(WCHAR); domain.Buffer = heap_alloc(domain.MaximumLength); } (*Names)[i].Name.Buffer = name_buffer; LookupAccountSidW(NULL, Sids[i], (*Names)[i].Name.Buffer, &name_size, domain.Buffer, &domain_size, &use); (*Names)[i].Use = use; if (domain_size) { (*Names)[i].DomainIndex = lsa_reflist_add_domain(*ReferencedDomains, &domain, &domain_data); heap_free(domain.Buffer); } } name_buffer += name_size; } TRACE("mapped %u out of %u\n", mapped, Count); if (mapped == Count) return STATUS_SUCCESS; if (mapped) return STATUS_SOME_NOT_MAPPED; return STATUS_NONE_MAPPED; }
/****************************************************************************** * LsaLookupNames2 [ADVAPI32.@] * */ NTSTATUS WINAPI LsaLookupNames2( LSA_HANDLE policy, ULONG flags, ULONG count, PLSA_UNICODE_STRING names, PLSA_REFERENCED_DOMAIN_LIST *domains, PLSA_TRANSLATED_SID2 *sids ) { ULONG i, sid_size_total = 0, domain_size_max = 0, size, domainname_size_total = 0; ULONG sid_size, domain_size, mapped; LSA_UNICODE_STRING domain; BOOL handled = FALSE; char *domain_data; SID_NAME_USE use; SID *sid; TRACE("(%p,0x%08x,0x%08x,%p,%p,%p)\n", policy, flags, count, names, domains, sids); mapped = 0; for (i = 0; i < count; i++) { handled = FALSE; sid_size = domain_size = 0; lookup_name( &names[i], NULL, &sid_size, NULL, &domain_size, &use, &handled ); if (handled) { sid_size_total += sid_size; domainname_size_total += domain_size; if (domain_size) { if (domain_size > domain_size_max) domain_size_max = domain_size; } mapped++; } } TRACE("mapped %u out of %u\n", mapped, count); size = sizeof(LSA_TRANSLATED_SID2) * count + sid_size_total; if (!(*sids = heap_alloc(size))) return STATUS_NO_MEMORY; sid = (SID *)(*sids + count); /* use maximum domain count */ if (!(*domains = heap_alloc(sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION) * (count + 1) + sid_size_total + domainname_size_total * sizeof(WCHAR)))) { heap_free(*sids); return STATUS_NO_MEMORY; } (*domains)->Entries = 0; (*domains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*domains + sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)); (*domains)->Domains[-1].Sid = NULL; RtlInitUnicodeStringEx(&(*domains)->Domains[-1].Name, NULL); domain_data = (char*)(*domains)->Domains + sizeof(LSA_TRUST_INFORMATION)*count; domain.Buffer = heap_alloc(domain_size_max*sizeof(WCHAR)); for (i = 0; i < count; i++) { domain.Length = domain_size_max*sizeof(WCHAR); domain.MaximumLength = domain_size_max*sizeof(WCHAR); (*sids)[i].Use = SidTypeUnknown; (*sids)[i].DomainIndex = -1; (*sids)[i].Flags = 0; handled = FALSE; sid_size = sid_size_total; domain_size = domain_size_max; lookup_name( &names[i], sid, &sid_size, domain.Buffer, &domain_size, &use, &handled ); if (handled) { (*sids)[i].Sid = sid; (*sids)[i].Use = use; sid = (SID *)((char *)sid + sid_size); sid_size_total -= sid_size; if (domain_size) { domain.Length = domain_size * sizeof(WCHAR); domain.MaximumLength = (domain_size + 1) * sizeof(WCHAR); (*sids)[i].DomainIndex = lsa_reflist_add_domain(*domains, &domain, &domain_data); } } } heap_free(domain.Buffer); if (mapped == count) return STATUS_SUCCESS; if (mapped > 0 && mapped < count) return STATUS_SOME_NOT_MAPPED; return STATUS_NONE_MAPPED; }
static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti) { func_info_t *info; HRESULT hres; for(info = data->funcs; info < data->funcs+data->func_cnt; info++) { if(info->id == desc->memid) { if(info->tid != tid) return; /* Duplicated in other interface */ break; } } if(info == data->funcs+data->func_cnt) { if(data->func_cnt == *size) data->funcs = heap_realloc_zero(data->funcs, (*size <<= 1)*sizeof(func_info_t)); info = data->funcs+data->func_cnt; hres = ITypeInfo_GetDocumentation(dti, desc->memid, &info->name, NULL, NULL, NULL); if(FAILED(hres)) return; data->func_cnt++; info->id = desc->memid; info->tid = tid; info->func_disp_idx = -1; info->prop_vt = VT_EMPTY; } if(desc->invkind & DISPATCH_METHOD) { unsigned i; info->func_disp_idx = data->func_disp_cnt++; info->argc = desc->cParams; assert(info->argc < MAX_ARGS); assert(desc->funckind == FUNC_DISPATCH); info->arg_types = heap_alloc(sizeof(*info->arg_types) * info->argc); if(!info->arg_types) return; /* FIXME: real error instead of fallback */ for(i=0; i < info->argc; i++) info->arg_types[i] = desc->lprgelemdescParam[i].tdesc.vt; info->prop_vt = desc->elemdescFunc.tdesc.vt; if(info->prop_vt != VT_VOID && !is_arg_type_supported(info->prop_vt)) { TRACE("%s: return type %d\n", debugstr_w(info->name), info->prop_vt); return; /* Fallback to ITypeInfo::Invoke */ } if(desc->cParamsOpt) { TRACE("%s: optional params\n", debugstr_w(info->name)); return; /* Fallback to ITypeInfo::Invoke */ } for(i=0; i < info->argc; i++) { if(!is_arg_type_supported(info->arg_types[i])) { return; /* Fallback to ITypeInfo for unsupported arg types */ } if(desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { TRACE("%s param %d: default value\n", debugstr_w(info->name), i); return; /* Fallback to ITypeInfo::Invoke */ } } assert(info->argc <= MAX_ARGS); assert(desc->callconv == CC_STDCALL); info->call_vtbl_off = desc->oVft/sizeof(void*); } else if(desc->invkind & (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYGET)) { VARTYPE vt = VT_EMPTY; if(desc->invkind & DISPATCH_PROPERTYGET) { vt = desc->elemdescFunc.tdesc.vt; info->get_vtbl_off = desc->oVft/sizeof(void*); } if(desc->invkind & DISPATCH_PROPERTYPUT) { assert(desc->cParams == 1); vt = desc->lprgelemdescParam->tdesc.vt; info->put_vtbl_off = desc->oVft/sizeof(void*); } assert(info->prop_vt == VT_EMPTY || vt == info->prop_vt); info->prop_vt = vt; } }
static HRESULT WINAPI MkProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved) { MkProtocol *This = impl_from_IInternetProtocolEx(iface); LPWSTR mime, progid, display_name, colon_ptr; DWORD bindf=0, eaten=0, scheme=0, len; BSTR url, path = NULL; IParseDisplayName *pdn; BINDINFO bindinfo; STATSTG statstg; IMoniker *mon; HRESULT hres; CLSID clsid; TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink, pOIBindInfo, grfPI, dwReserved); hres = IUri_GetScheme(pUri, &scheme); if(FAILED(hres)) return hres; if(scheme != URL_SCHEME_MK) return INET_E_INVALID_URL; memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } ReleaseBindInfo(&bindinfo); IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL); hres = IUri_GetDisplayUri(pUri, &url); if(FAILED(hres)) return hres; hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0); SysFreeString(url); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } hres = IUri_GetPath(pUri, &path); if(FAILED(hres)) return hres; len = SysStringLen(path)+1; hres = UrlUnescapeW(path, NULL, &len, URL_UNESCAPE_INPLACE); if (FAILED(hres)) { SysFreeString(path); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } progid = path+1; /* skip '@' symbol */ colon_ptr = strchrW(path, ':'); if(!colon_ptr) { SysFreeString(path); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } len = strlenW(path); display_name = heap_alloc((len+1)*sizeof(WCHAR)); memcpy(display_name, path, (len+1)*sizeof(WCHAR)); progid[colon_ptr-progid] = 0; /* overwrite ':' with NULL terminator */ hres = CLSIDFromProgID(progid, &clsid); SysFreeString(path); if(FAILED(hres)) { heap_free(display_name); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IParseDisplayName, (void**)&pdn); if(FAILED(hres)) { WARN("Could not create object %s\n", debugstr_guid(&clsid)); heap_free(display_name); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon); heap_free(display_name); IParseDisplayName_Release(pdn); if(FAILED(hres)) { WARN("ParseDisplayName failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } if(This->stream) { IStream_Release(This->stream); This->stream = NULL; } hres = IMoniker_BindToStorage(mon, NULL /* FIXME */, NULL, &IID_IStream, (void**)&This->stream); IMoniker_Release(mon); if(FAILED(hres)) { WARN("BindToStorage failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } hres = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME); if(FAILED(hres)) { WARN("Stat failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, statstg.cbSize.u.LowPart, statstg.cbSize.u.LowPart); return report_result(pOIProtSink, S_OK, ERROR_SUCCESS); }
static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); HRESULT hres = S_OK; TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); *pdisp = NULL; switch(V_VT(&name)) { case VT_I4: if(V_I4(&name) < 0) return E_INVALIDARG; hres = get_item_idx(This, V_I4(&name), pdisp); break; case VT_UINT: hres = get_item_idx(This, V_UINT(&name), pdisp); break; case VT_BSTR: { DWORD i; if(V_VT(&index) == VT_I4) { LONG idx = V_I4(&index); if(idx < 0) return E_INVALIDARG; for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--) break; } if(i != This->len) { *pdisp = (IDispatch*)&This->elems[i]->IHTMLElement_iface; IDispatch_AddRef(*pdisp); } }else { elem_vector_t buf = {NULL, 0, 8}; buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*)); for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name))) { node_addref(&This->elems[i]->node); elem_vector_add(&buf, This->elems[i]); } } if(buf.len > 1) { elem_vector_normalize(&buf); *pdisp = (IDispatch*)HTMLElementCollection_Create(buf.buf, buf.len); }else { if(buf.len == 1) { /* Already AddRef-ed */ *pdisp = (IDispatch*)&buf.buf[0]->IHTMLElement_iface; } heap_free(buf.buf); } } break; } default: FIXME("Unsupported name %s\n", debugstr_variant(&name)); hres = E_NOTIMPL; } if(SUCCEEDED(hres)) TRACE("returning %p\n", *pdisp); return hres; }
static DWORD init_openssl(void) { #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) int i; if(OpenSSL_ssl_handle) return ERROR_SUCCESS; OpenSSL_ssl_handle = wine_dlopen(SONAME_LIBSSL, RTLD_NOW, NULL, 0); if(!OpenSSL_ssl_handle) { ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n", SONAME_LIBSSL); return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; } OpenSSL_crypto_handle = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0); if(!OpenSSL_crypto_handle) { ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n", SONAME_LIBCRYPTO); return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; } /* mmm nice ugly macroness */ #define DYNSSL(x) \ p##x = wine_dlsym(OpenSSL_ssl_handle, #x, NULL, 0); \ if (!p##x) { \ ERR("failed to load symbol %s\n", #x); \ return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; \ } DYNSSL(SSL_library_init); DYNSSL(SSL_load_error_strings); DYNSSL(SSLv23_method); DYNSSL(SSL_CTX_free); DYNSSL(SSL_CTX_new); DYNSSL(SSL_new); DYNSSL(SSL_free); DYNSSL(SSL_set_fd); DYNSSL(SSL_connect); DYNSSL(SSL_shutdown); DYNSSL(SSL_write); DYNSSL(SSL_read); DYNSSL(SSL_pending); DYNSSL(SSL_get_error); DYNSSL(SSL_get_ex_new_index); DYNSSL(SSL_get_ex_data); DYNSSL(SSL_set_ex_data); DYNSSL(SSL_get_ex_data_X509_STORE_CTX_idx); DYNSSL(SSL_get_peer_certificate); DYNSSL(SSL_CTX_get_timeout); DYNSSL(SSL_CTX_set_timeout); DYNSSL(SSL_CTX_set_default_verify_paths); DYNSSL(SSL_CTX_set_verify); DYNSSL(SSL_get_current_cipher); DYNSSL(SSL_CIPHER_get_bits); #undef DYNSSL #define DYNCRYPTO(x) \ p##x = wine_dlsym(OpenSSL_crypto_handle, #x, NULL, 0); \ if (!p##x) { \ ERR("failed to load symbol %s\n", #x); \ return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; \ } DYNCRYPTO(BIO_new_fp); DYNCRYPTO(CRYPTO_num_locks); DYNCRYPTO(CRYPTO_set_id_callback); DYNCRYPTO(CRYPTO_set_locking_callback); DYNCRYPTO(ERR_free_strings); DYNCRYPTO(ERR_get_error); DYNCRYPTO(ERR_error_string); DYNCRYPTO(X509_STORE_CTX_get_ex_data); DYNCRYPTO(X509_STORE_CTX_get_chain); DYNCRYPTO(i2d_X509); DYNCRYPTO(sk_num); DYNCRYPTO(sk_value); #undef DYNCRYPTO pSSL_library_init(); pSSL_load_error_strings(); pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */ meth = pSSLv23_method(); ctx = pSSL_CTX_new(meth); if(!pSSL_CTX_set_default_verify_paths(ctx)) { ERR("SSL_CTX_set_default_verify_paths failed: %s\n", pERR_error_string(pERR_get_error(), 0)); return ERROR_OUTOFMEMORY; } error_idx = pSSL_get_ex_new_index(0, (void *)"error index", NULL, NULL, NULL); if(error_idx == -1) { ERR("SSL_get_ex_new_index failed; %s\n", pERR_error_string(pERR_get_error(), 0)); return ERROR_OUTOFMEMORY; } conn_idx = pSSL_get_ex_new_index(0, (void *)"netconn index", NULL, NULL, NULL); if(conn_idx == -1) { ERR("SSL_get_ex_new_index failed; %s\n", pERR_error_string(pERR_get_error(), 0)); return ERROR_OUTOFMEMORY; } pSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, netconn_secure_verify); pCRYPTO_set_id_callback(ssl_thread_id); num_ssl_locks = pCRYPTO_num_locks(); ssl_locks = heap_alloc(num_ssl_locks * sizeof(CRITICAL_SECTION)); if(!ssl_locks) return ERROR_OUTOFMEMORY; for(i = 0; i < num_ssl_locks; i++) { InitializeCriticalSection(&ssl_locks[i]); ssl_locks[i].DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ssl_locks"); } pCRYPTO_set_locking_callback(ssl_lock_callback); return ERROR_SUCCESS; #else FIXME("can't use SSL, not compiled in.\n"); return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; #endif }
/*********************************************************************** * HlinkCreateFromString (HLINK.@) */ HRESULT WINAPI HlinkCreateFromString( LPCWSTR pwzTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, IHlinkSite* pihlsite, DWORD dwSiteData, IUnknown* piunkOuter, REFIID riid, void** ppvObj) { IHlink *hl = NULL; HRESULT r; WCHAR *hash, *tgt; const WCHAR *loc; TRACE("%s %s %s %p %i %p %s %p\n", debugstr_w(pwzTarget), debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName), pihlsite, dwSiteData, piunkOuter, debugstr_guid(riid), ppvObj); r = CoCreateInstance(&CLSID_StdHlink, piunkOuter, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&hl); if (FAILED(r)) return r; if (pwzTarget) { hash = strchrW(pwzTarget, '#'); if (hash) { if (hash == pwzTarget) tgt = NULL; else { int tgt_len = hash - pwzTarget; tgt = heap_alloc((tgt_len + 1) * sizeof(WCHAR)); if (!tgt) return E_OUTOFMEMORY; memcpy(tgt, pwzTarget, tgt_len * sizeof(WCHAR)); tgt[tgt_len] = 0; } if (!pwzLocation) loc = hash + 1; else loc = pwzLocation; } else { tgt = hlink_strdupW(pwzTarget); if (!tgt) return E_OUTOFMEMORY; loc = pwzLocation; } } else { tgt = NULL; loc = pwzLocation; } IHlink_SetStringReference(hl, HLINKSETF_TARGET | HLINKSETF_LOCATION, tgt, loc); heap_free(tgt); if (pwzFriendlyName) IHlink_SetFriendlyName(hl, pwzFriendlyName); if (pihlsite) IHlink_SetHlinkSite(hl, pihlsite, dwSiteData); TRACE("Returning %i\n",r); *ppvObj = hl; return r; }
static HRESULT WINAPI PersistFile_Save(IPersistFile *pFile, LPCOLESTR pszFileName, BOOL fRemember) { HRESULT hr = S_OK; INT len; CHAR *url; InternetShortcut *This = impl_from_IPersistFile(pFile); TRACE("(%p, %s, %d)\n", pFile, debugstr_w(pszFileName), fRemember); if (pszFileName != NULL && fRemember) { LPOLESTR oldFile = This->currentFile; This->currentFile = co_strdupW(pszFileName); if (This->currentFile == NULL) { This->currentFile = oldFile; return E_OUTOFMEMORY; } CoTaskMemFree(oldFile); } if (This->url == NULL) return E_FAIL; /* Windows seems to always write: * ASCII "[InternetShortcut]" headers * ASCII names in "name=value" pairs * An ASCII (probably UTF8?) value in "URL=..." */ len = WideCharToMultiByte(CP_UTF8, 0, This->url, -1, NULL, 0, 0, 0); url = heap_alloc(len); if (url != NULL) { HANDLE file; WideCharToMultiByte(CP_UTF8, 0, This->url, -1, url, len, 0, 0); file = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) { DWORD bytesWritten; char str_header[] = "[InternetShortcut]"; char str_URL[] = "URL="; char str_eol[] = "\r\n"; WriteFile(file, str_header, lstrlenA(str_header), &bytesWritten, NULL); WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL); WriteFile(file, str_URL, lstrlenA(str_URL), &bytesWritten, NULL); WriteFile(file, url, lstrlenA(url), &bytesWritten, NULL); WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL); CloseHandle(file); if (pszFileName == NULL || fRemember) This->isDirty = FALSE; StartLinkProcessor(pszFileName); } else hr = E_FAIL; heap_free(url); } else hr = E_OUTOFMEMORY; return hr; }
static HRESULT register_server(BOOL do_register) { HRESULT hres; HMODULE hAdvpack; HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable); STRTABLEA strtable; STRENTRYA pse[35]; static CLSID const *clsids[35]; unsigned int i = 0; static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0}; TRACE("(%x)\n", do_register); INF_SET_CLSID(AboutProtocol); INF_SET_CLSID(CAnchorBrowsePropertyPage); INF_SET_CLSID(CBackgroundPropertyPage); INF_SET_CLSID(CCDAnchorPropertyPage); INF_SET_CLSID(CCDGenericPropertyPage); INF_SET_CLSID(CDocBrowsePropertyPage); INF_SET_CLSID(CDwnBindInfo); INF_SET_CLSID(CHiFiUses); INF_SET_CLSID(CHtmlComponentConstructor); INF_SET_CLSID(CImageBrowsePropertyPage); INF_SET_CLSID(CInlineStylePropertyPage); INF_SET_CLSID(CPeerHandler); INF_SET_CLSID(CRecalcEngine); INF_SET_CLSID(CSvrOMUses); INF_SET_CLSID(CrSource); INF_SET_CLSID(ExternalFrameworkSite); INF_SET_CLSID(HTADocument); INF_SET_CLSID(HTMLDocument); INF_SET_CLSID(HTMLLoadOptions); INF_SET_CLSID(HTMLPluginDocument); INF_SET_CLSID(HTMLPopup); INF_SET_CLSID(HTMLPopupDoc); INF_SET_CLSID(HTMLServerDoc); INF_SET_CLSID(HTMLWindowProxy); INF_SET_CLSID(IImageDecodeFilter); INF_SET_CLSID(IImgCtx); INF_SET_CLSID(IntDitherer); INF_SET_CLSID(JSProtocol); INF_SET_CLSID(MHTMLDocument); INF_SET_CLSID(MailtoProtocol); INF_SET_CLSID(ResProtocol); INF_SET_CLSID(Scriptlet); INF_SET_CLSID(SysimageProtocol); INF_SET_CLSID(TridentAPI); INF_SET_ID(LIBID_MSHTML); for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++) { pse[i].pszValue = heap_alloc(39); sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0], clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4], clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]); } strtable.cEntries = sizeof(pse)/sizeof(pse[0]); strtable.pse = pse; hAdvpack = LoadLibraryW(wszAdvpack); pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall"); hres = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll", &strtable); for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++) heap_free(pse[i].pszValue); if(FAILED(hres)) { ERR("RegInstall failed: %08x\n", hres); return hres; } if(do_register) { ITypeLib *typelib; static const WCHAR wszMSHTML[] = {'m','s','h','t','m','l','.','t','l','b',0}; hres = LoadTypeLibEx(wszMSHTML, REGKIND_REGISTER, &typelib); if(SUCCEEDED(hres)) ITypeLib_Release(typelib); }else { hres = UnRegisterTypeLib(&LIBID_MSHTML, 4, 0, LOCALE_SYSTEM_DEFAULT, SYS_WIN32); } if(FAILED(hres)) ERR("typelib registration failed: %08x\n", hres); return hres; }
static HRESULT connect_channel( struct channel *channel, WS_MESSAGE *msg ) { static const WCHAR agentW[] = {'M','S','-','W','e','b','S','e','r','v','i','c','e','s','/','1','.','0',0}; static const WCHAR postW[] = {'P','O','S','T',0}; HINTERNET ses = NULL, con = NULL, req = NULL; WCHAR *path; URL_COMPONENTS uc; DWORD flags = 0; HRESULT hr; if ((hr = parse_url( channel->addr.url.chars, channel->addr.url.length, &uc )) != S_OK) return hr; if (!uc.dwExtraInfoLength) path = uc.lpszUrlPath; else if (!(path = heap_alloc( (uc.dwUrlPathLength + uc.dwExtraInfoLength + 1) * sizeof(WCHAR) ))) { hr = E_OUTOFMEMORY; goto done; } else { strcpyW( path, uc.lpszUrlPath ); strcatW( path, uc.lpszExtraInfo ); } switch (uc.nScheme) { case INTERNET_SCHEME_HTTP: break; case INTERNET_SCHEME_HTTPS: flags |= WINHTTP_FLAG_SECURE; break; default: FIXME( "scheme %u not supported\n", uc.nScheme ); hr = E_NOTIMPL; goto done; } if (!(ses = WinHttpOpen( agentW, 0, NULL, NULL, 0 ))) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto done; } if (!(con = WinHttpConnect( ses, uc.lpszHostName, uc.nPort, 0 ))) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto done; } if (!(req = WinHttpOpenRequest( con, postW, path, NULL, NULL, NULL, flags ))) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto done; } if ((hr = message_insert_http_headers( msg, req )) != S_OK) goto done; channel->http_session = ses; channel->http_connect = con; channel->http_request = req; done: if (hr != S_OK) { WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); } heap_free( uc.lpszHostName ); heap_free( uc.lpszUrlPath ); heap_free( uc.lpszExtraInfo ); if (path != uc.lpszUrlPath) heap_free( path ); return hr; }
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; }
static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface); BINDINFO bindinfo; DWORD grfBINDF = 0; LPCWSTR text = NULL; DWORD data_len; BYTE *data; HRESULT hres; static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0}; static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0}; static const WCHAR wszBlank[] = {'b','l','a','n','k',0}; static const WCHAR wszAbout[] = {'a','b','o','u','t',':'}; static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; /* NOTE: * the about protocol seems not to work as I would expect. It creates html document * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when * some_text = "blank", when document is blank (<HTML></HMTL>). The same happens * when the url does not have "about:" in the beginning. */ 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); TRACE("bindf %x\n", grfBINDF); if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) { text = szUrl + sizeof(wszAbout)/sizeof(WCHAR); if(!strcmpW(wszBlank, text)) text = NULL; } data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR) + (text ? strlenW(text)*sizeof(WCHAR) : 0); data = heap_alloc(data_len); if(!data) return E_OUTOFMEMORY; heap_free(This->data); This->data = data; This->data_len = data_len; memcpy(This->data, html_begin, sizeof(html_begin)); if(text) strcatW((LPWSTR)This->data, text); strcatW((LPWSTR)This->data, html_end); This->cur = 0; IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); 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; }
HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, DWORD dwSize, LPWSTR pszFileName, HANDLE *phfile, IUMCacheStream **ppstr) { IUMCacheStream* ucstr; HANDLE handle; DWORD size; LPWSTR url, c, ext = NULL; HRESULT hr; size = (strlenW(pszURL)+1)*sizeof(WCHAR); url = heap_alloc(size); memcpy(url, pszURL, size); for (c = url; *c && *c != '#' && *c != '?'; ++c) { if (*c == '.') ext = c+1; else if(*c == '/') ext = NULL; } *c = 0; if(!CreateUrlCacheEntryW(url, dwSize, ext, pszFileName, 0)) hr = HRESULT_FROM_WIN32(GetLastError()); else hr = S_OK; heap_free(url); if (hr != S_OK) return hr; TRACE("Opening %s\n", debugstr_w(pszFileName) ); handle = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, (HANDLE)NULL ); if( handle == INVALID_HANDLE_VALUE ) return HRESULT_FROM_WIN32(GetLastError()); if (phfile) { /* Call CreateFileW again because we need a handle with its own file pointer, and DuplicateHandle will return * a handle that shares its file pointer with the original. */ *phfile = CreateFileW( pszFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, (HANDLE)NULL ); if (*phfile == (HANDLE) HFILE_ERROR) { DWORD dwError = GetLastError(); CloseHandle(handle); return HRESULT_FROM_WIN32(dwError); } } ucstr = heap_alloc_zero(sizeof(IUMCacheStream)); if(ucstr) { ucstr->pszURL = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszURL) + 1)); if (ucstr->pszURL) { ucstr->pszFileName = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszFileName) + 1)); if (ucstr->pszFileName) { ucstr->lpVtbl=&stvt; ucstr->ref = 1; ucstr->handle = handle; ucstr->closed = 0; lstrcpyW(ucstr->pszURL, pszURL); lstrcpyW(ucstr->pszFileName, pszFileName); *ppstr = ucstr; return S_OK; } heap_free(ucstr->pszURL); } heap_free(ucstr); } CloseHandle(handle); if (phfile) CloseHandle(*phfile); return E_OUTOFMEMORY; }
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 = (LPWSTR)RT_HTML; } /* Ignore query and hash parts. */ if((ptr = strchrW(url_file, '?'))) *ptr = 0; if(*url_file && (ptr = strchrW(url_file+1, '#'))) *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; }
HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out) { domselection *This = heap_alloc(sizeof(domselection)); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); HRESULT hr; TRACE("(%p, %s, %p)\n", node, debugstr_a((char const*)query), out); *out = NULL; if (!This || !ctxt || !query) { xmlXPathFreeContext(ctxt); heap_free(This); return E_OUTOFMEMORY; } This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl; This->ref = 1; This->resultPos = 0; This->node = node; This->enumvariant = NULL; init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex); xmldoc_add_ref(This->node->doc); ctxt->error = query_serror; ctxt->node = node; registerNamespaces(ctxt); if (is_xpathmode(This->node->doc)) { xmlXPathRegisterAllFunctions(ctxt); This->result = xmlXPathEvalExpression(query, ctxt); } else { xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, query); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq); This->result = xmlXPathEvalExpression(pattern_query, ctxt); xmlFree(pattern_query); } if (!This->result || This->result->type != XPATH_NODESET) { hr = E_FAIL; goto cleanup; } *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface; hr = S_OK; TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval)); cleanup: if (This && FAILED(hr)) IXMLDOMSelection_Release( &This->IXMLDOMSelection_iface ); xmlXPathFreeContext(ctxt); return hr; }
int nt_execve(const char *prog, const char *const *args, const char *const *envir) { STARTUPINFO si; PROCESS_INFORMATION pi; enum {none, directex, shellex} execmode; DWORD exitcode; DWORD dwCreationflags; int priority; char *argv0; char *cmdstr, *cmdend; unsigned int cmdsize; size_t prognamelen, cmdlen; int hasext; char extension[_MAX_FNAME]; const char *begin, *end, *extptr; static char exts[MAX_PATH]; UNREFERENCED_PARAMETER(envir); /* get default PATHEXT or use empty exts */ if (!*exts) { DWORD rc; /* not initialized */ rc = GetEnvironmentVariable("PATHEXT", exts, sizeof(exts)); if ((rc == 0) || (rc >= sizeof(exts))) /* if error or PATHEXT too big will retry at the next call */ *exts = 0; } /* if prog has an extension initialize begin end to skip PATHEXT search */ prognamelen = strlen(prog); extptr = prog + prognamelen - 1; hasext = 0; while (extptr > prog && !ISPATHSEP(*extptr)) { if (*extptr == '.' && *(extptr - 1) != ':' && !ISPATHSEP(*(extptr - 1))) { hasext++; break; } extptr--; } if (hasext) { begin = "."; end = ""; strcpy(extension, extptr); } else { begin = exts; end = exts; *extension = '\0'; } argv0 = (char *)heap_alloc(MAX_PATH); /* (prognamelen + 1) does not really matter, argv0 is '\0' filled */ memcpy(argv0, prog, prognamelen + 1); errno = 0; execmode = none; /* NOTE: loops over PATHEXT if no extension found */ while (*begin) { size_t extlen; if (GetBinaryType(argv0, &exitcode)) { /* exists and is executable NOTE: an "xxx.exe" without a correct PE header (i.e. a text file) has type "DOS binary", but execution will generate a WOW error */ execmode = directex; break; } if (GetLastError() == ERROR_BAD_EXE_FORMAT) { /* exists but is not "executable" */ execmode = shellex; break; } if (hasext) break; /* get next PATHEXT extension */ while (*begin && (*begin != '.')) begin++; while (*end && (*end != ';')) end++; if (!*begin) break; extlen = end - begin; if (extlen < sizeof(extension)) { memcpy(extension, begin, extlen); extension[extlen] = '\0'; /* prognamelen ignores the last '\r' if present */ memcpy(argv0, prog, prognamelen); /* update argv0 adding the extension to prog */ memcpy(argv0 + prognamelen, extension, extlen + 1); } begin = end; /* skip sequences of ';' */ while (*end && *end == ';') end++; }; cmdstr = (char *)heap_alloc(MAX_PATH << 2); cmdsize = MAX_PATH << 2; cmdlen = 0; cmdend = cmdstr; dbgprintf(PR_VERBOSE, "%s(): execute [%s] extension=[%s] mode=%d hasext=%d\n", __FUNCTION__, argv0, extension, execmode, hasext); /* skip over program name */ args++; /* the file (after PATHEXT search) exists, but it's not "executable" */ if (execmode == shellex) { /* if prog had no extension or has the extension associated to shell scripts */ if ((hasext == 0 && *extension == '\0') || is_shell_script(extension)) { int res = process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize); if (res < 0) { execmode = none; } else if (res == 0) { char *newargv[2]; cmdlen = copy_quote_and_fix_slashes(gModuleName, cmdstr); cmdend = cmdstr + cmdlen; newargv[0] = path_to_slash(argv0); newargv[1] = NULL; concat_args_and_quote((const char *const *)newargv, &cmdstr, &cmdlen, &cmdend, &cmdsize); *cmdend = 0; argv0 = gModuleName; execmode = directex; } else { cmdend = cmdstr + cmdlen; execmode = directex; } } else { unsigned long shflags = 0L; /* if the file extension is in pathext, use the same console and wait for child. StrStrI() is from shlwapi */ if (StrStrI(exts, extension)) shflags = SEE_MASK_NO_CONSOLE | SEE_MASK_NOCLOSEPROCESS; if (try_shell_ex(argv0, args, shflags, &cmdstr, &cmdsize)) return (0); /* ShellExecute failed, the file has an unknown extension, but it may be a shell script with a shebang */ if (process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize) > 0) { cmdend = cmdstr + cmdlen; execmode = directex; } else { /* the file extension is NOT known and the file has NO shebang: returns EPERM, see NOTES */ errno = EPERM; return (-1); } } } else if (execmode == directex) { cmdlen = copy_quote_and_fix_slashes(prog, cmdstr); cmdend = cmdstr + cmdlen; } if (execmode == none) { /* error: prog not found even after trying PATHEXT extensions */ errno = ENOENT; return (-1); } concat_args_and_quote(args, &cmdstr, &cmdlen, &cmdend, &cmdsize); if (*cmdstr == ' ') { /* if we left a ' ' for the quote and there is no quote */ cmdstr++; cmdlen--; } *cmdend = 0; init_startupinfo(&si); dwCreationflags = GetPriorityClass(GetCurrentProcess()); priority = GetThreadPriority(GetCurrentThread()); #if defined(W32DEBUG) /* DebugView output is very difficult to read with overlong lines */ if (cmdlen < 128) dbgprintf(PR_EXEC, "%s(): CreateProcess(%s, ..) cmdstr=[%s]\n", __FUNCTION__, argv0, cmdstr); else { char shortbuf[128+4]; memcpy(shortbuf, cmdstr, 128); memcpy(shortbuf + 128, "...", 4); dbgprintf(PR_EXEC, "nt_execve(): CreateProcess(%s, ..) cmdstr=[%s]\n", argv0, shortbuf); } #endif if (!CreateProcess(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles dwCreationflags | CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { exitcode = GetLastError(); if (exitcode == ERROR_BAD_EXE_FORMAT) { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error BAD_EXE_FORMAT in %s\n", argv0, __FUNCTION__); errno = ENOEXEC; } else if (exitcode == ERROR_INVALID_PARAMETER) { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error INVALID_PARAMETER in %s, cmdstr len=%u\n", argv0, __FUNCTION__, strlen(cmdstr)); /* exceeded command line */ /* return NOT found, ENAMETOOLONG is correct but not understood by the shell that will retry with another path ... */ errno = ENOENT; } else { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error %ld in %s\n", argv0, exitcode, __FUNCTION__); errno = ENOENT; } goto fail_return; } else { exitcode = 0; if (!SetThreadPriority(pi.hThread, priority)) dbgprintf(PR_ERROR, "!!! SetThreadPriority(0x%p) failed, error %ld\n", pi.hThread, GetLastError()); ResumeThread(pi.hThread); if (!is_gui(argv0)) { if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) dbgprintf(PR_ERROR, "!!! error %ld waiting for process %ld\n", GetLastError(), pi.dwProcessId); if (!GetExitCodeProcess(pi.hProcess, &exitcode)) dbgprintf(PR_ERROR, "!!! GetExitCodeProcess(0x%p, ..) error %ld in %s\n", pi.hProcess, GetLastError(), __FUNCTION__); } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); close_si_handles(); /* @@@@ should wait for the clipboard ? if (is_dev_clipboard_active) { CloseHandle((HANDLE)_get_osfhandle(0)); CloseHandle((HANDLE)_get_osfhandle(1)); CloseHandle((HANDLE)_get_osfhandle(2)); ... WaitForSingleObject(ghdevclipthread,60*1000); } */ dbgprintf(PR_ALL, "--- %s(): Exec'd process %ld terminated with exitcode %ld\n", __FUNCTION__, pi.dwProcessId, exitcode); exec_exit((int)exitcode); } fail_return: heap_free(cmdstr); close_si_handles(); exec_exit(-1); return (-1); }