[VBSCRIPT] Sync with Wine Staging 1.7.47. CORE-9924

svn path=/trunk/; revision=68536
This commit is contained in:
Amine Khaldi 2015-07-22 00:39:49 +00:00
parent 0c3a554a96
commit b9357adadb
6 changed files with 176 additions and 100 deletions

View file

@ -539,6 +539,8 @@ static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
{
WCHAR buf[17], *ptr;
DWORD n;
HRESULT hres;
int ret;
TRACE("%s\n", debugstr_variant(arg));
@ -546,19 +548,16 @@ static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
case VT_I2:
n = (WORD)V_I2(arg);
break;
case VT_I4:
n = V_I4(arg);
break;
case VT_EMPTY:
n = 0;
break;
case VT_NULL:
if(res)
V_VT(res) = VT_NULL;
return S_OK;
default:
FIXME("unsupported type %s\n", debugstr_variant(arg));
return E_NOTIMPL;
hres = to_int(arg, &ret);
if(FAILED(hres))
return hres;
else
n = ret;
}
buf[16] = 0;
@ -579,8 +578,43 @@ static HRESULT Global_Hex(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
static HRESULT Global_Oct(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
HRESULT hres;
WCHAR buf[23], *ptr;
DWORD n;
int ret;
TRACE("%s\n", debugstr_variant(arg));
switch(V_VT(arg)) {
case VT_I2:
n = (WORD)V_I2(arg);
break;
case VT_NULL:
if(res)
V_VT(res) = VT_NULL;
return S_OK;
default:
hres = to_int(arg, &ret);
if(FAILED(hres))
return hres;
else
n = ret;
}
buf[22] = 0;
ptr = buf + 21;
if(n) {
do {
*ptr-- = '0' + (n & 0x7);
n >>= 3;
}while(n);
ptr++;
}else {
*ptr = '0';
}
return return_string(res, ptr);
}
static HRESULT Global_VarType(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
@ -1298,7 +1332,7 @@ static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
buf[len++] = c>>8;
if(!len || IsDBCSLeadByteEx(cp, buf[0]))
buf[len++] = c;
if(!MultiByteToWideChar(0, 0, buf, len, &ch, 1)) {
if(!MultiByteToWideChar(CP_ACP, 0, buf, len, &ch, 1)) {
WARN("invalid arg %d, cp %d\n", c, cp);
return E_FAIL;
}
@ -1788,7 +1822,7 @@ static HRESULT Global_InStrRev(vbdisp_t *This, VARIANT *args, unsigned args_cnt,
assert(2 <= args_cnt && args_cnt <= 4);
if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || V_VT(args+2) == VT_NULL)
if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (args_cnt > 2 && V_VT(args+2) == VT_NULL))
return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
hres = to_string(args, &str1);

View file

@ -214,13 +214,12 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
}
static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
BOOL is_const, VARIANT *val, BOOL own_val, VARIANT **out_var)
BOOL is_const, VARIANT **out_var)
{
dynamic_var_t *new_var;
heap_pool_t *heap;
WCHAR *str;
unsigned size;
HRESULT hres;
heap = ctx->func->type == FUNC_GLOBAL ? &ctx->script->heap : &ctx->heap;
@ -235,15 +234,7 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
memcpy(str, name, size);
new_var->name = str;
new_var->is_const = is_const;
if(own_val) {
new_var->v = *val;
}else {
V_VT(&new_var->v) = VT_EMPTY;
hres = VariantCopy(&new_var->v, val);
if(FAILED(hres))
return hres;
}
V_VT(&new_var->v) = VT_EMPTY;
if(ctx->func->type == FUNC_GLOBAL) {
new_var->next = ctx->script->global_vars;
@ -253,9 +244,7 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
ctx->dynamic_vars = new_var;
}
if(out_var)
*out_var = &new_var->v;
*out_var = &new_var->v;
return S_OK;
}
@ -328,10 +317,9 @@ static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *r)
stack_pop_deref(ctx, r);
if(V_VT(r->v) == VT_DISPATCH) {
DISPPARAMS dp = {0};
HRESULT hres;
hres = disp_call(ctx->script, V_DISPATCH(r->v), DISPID_VALUE, &dp, &r->store);
hres = get_disp_value(ctx->script, V_DISPATCH(r->v), &r->store);
if(r->owned)
IDispatch_Release(V_DISPATCH(r->v));
if(FAILED(hres))
@ -359,12 +347,10 @@ static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
}
if(V_VT(v) == VT_DISPATCH) {
DISPPARAMS dp = {0};
IDispatch *disp;
disp = V_DISPATCH(v);
V_VT(v) = VT_EMPTY;
hres = disp_call(ctx->script, disp, DISPID_VALUE, &dp, v);
hres = get_disp_value(ctx->script, disp, v);
IDispatch_Release(disp);
if(FAILED(hres))
return hres;
@ -614,9 +600,8 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
break;
case REF_NONE:
if(res && !ctx->func->code_ctx->option_explicit && arg_cnt == 0) {
VARIANT v, *new;
VariantInit(&v);
hres = add_dynamic_var(ctx, identifier, FALSE, &v, FALSE, &new);
VARIANT *new;
hres = add_dynamic_var(ctx, identifier, FALSE, &new);
if(FAILED(hres))
return hres;
V_VT(res) = VT_BYREF|VT_VARIANT;
@ -703,7 +688,29 @@ static HRESULT interp_mcallv(exec_ctx_t *ctx)
return do_mcall(ctx, NULL);
}
static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, DISPPARAMS *dp)
static HRESULT assign_value(exec_ctx_t *ctx, VARIANT *dst, VARIANT *src, WORD flags)
{
HRESULT hres;
hres = VariantCopyInd(dst, src);
if(FAILED(hres))
return hres;
if(V_VT(dst) == VT_DISPATCH && !(flags & DISPATCH_PROPERTYPUTREF)) {
VARIANT value;
hres = get_disp_value(ctx->script, V_DISPATCH(dst), &value);
IDispatch_Release(V_DISPATCH(dst));
if(FAILED(hres))
return hres;
*dst = value;
}
return S_OK;
}
static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, WORD flags, DISPPARAMS *dp)
{
ref_t ref;
HRESULT hres;
@ -752,11 +759,11 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, DISPPARAMS *dp)
return E_NOTIMPL;
}
hres = VariantCopyInd(v, dp->rgvarg);
hres = assign_value(ctx, v, dp->rgvarg, flags);
break;
}
case REF_DISP:
hres = disp_propput(ctx->script, ref.u.d.disp, ref.u.d.id, dp);
hres = disp_propput(ctx->script, ref.u.d.disp, ref.u.d.id, flags, dp);
break;
case REF_FUNC:
FIXME("functions not implemented\n");
@ -772,13 +779,17 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, DISPPARAMS *dp)
FIXME("throw exception\n");
hres = E_FAIL;
}else {
VARIANT *new_var;
if(arg_cnt(dp)) {
FIXME("arg_cnt %d not supported\n", arg_cnt(dp));
return E_NOTIMPL;
}
TRACE("creating variable %s\n", debugstr_w(name));
hres = add_dynamic_var(ctx, name, FALSE, dp->rgvarg, FALSE, NULL);
hres = add_dynamic_var(ctx, name, FALSE, &new_var);
if(SUCCEEDED(hres))
hres = assign_value(ctx, new_var, dp->rgvarg, flags);
}
}
@ -794,12 +805,8 @@ static HRESULT interp_assign_ident(exec_ctx_t *ctx)
TRACE("%s\n", debugstr_w(arg));
hres = stack_assume_val(ctx, arg_cnt);
if(FAILED(hres))
return hres;
vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
hres = assign_ident(ctx, arg, &dp);
hres = assign_ident(ctx, arg, DISPATCH_PROPERTYPUT, &dp);
if(FAILED(hres))
return hres;
@ -826,7 +833,7 @@ static HRESULT interp_set_ident(exec_ctx_t *ctx)
return hres;
vbstack_to_dp(ctx, 0, TRUE, &dp);
hres = assign_ident(ctx, ctx->instr->arg1.bstr, &dp);
hres = assign_ident(ctx, ctx->instr->arg1.bstr, DISPATCH_PROPERTYPUTREF, &dp);
if(FAILED(hres))
return hres;
@ -854,14 +861,10 @@ static HRESULT interp_assign_member(exec_ctx_t *ctx)
return E_FAIL;
}
hres = stack_assume_val(ctx, arg_cnt);
if(FAILED(hres))
return hres;
hres = disp_get_id(obj, identifier, VBDISP_LET, FALSE, &id);
if(SUCCEEDED(hres)) {
vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
hres = disp_propput(ctx->script, obj, id, &dp);
hres = disp_propput(ctx->script, obj, id, DISPATCH_PROPERTYPUT, &dp);
}
if(FAILED(hres))
return hres;
@ -902,7 +905,7 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
hres = disp_get_id(obj, identifier, VBDISP_SET, FALSE, &id);
if(SUCCEEDED(hres)) {
vbstack_to_dp(ctx, arg_cnt, TRUE, &dp);
hres = disp_propput(ctx->script, obj, id, &dp);
hres = disp_propput(ctx->script, obj, id, DISPATCH_PROPERTYPUTREF, &dp);
}
if(FAILED(hres))
return hres;
@ -914,7 +917,7 @@ static HRESULT interp_set_member(exec_ctx_t *ctx)
static HRESULT interp_const(exec_ctx_t *ctx)
{
BSTR arg = ctx->instr->arg1.bstr;
variant_val_t val;
VARIANT *v;
ref_t ref;
HRESULT hres;
@ -931,11 +934,16 @@ static HRESULT interp_const(exec_ctx_t *ctx)
return E_FAIL;
}
hres = stack_pop_val(ctx, &val);
hres = stack_assume_val(ctx, 0);
if(FAILED(hres))
return hres;
return add_dynamic_var(ctx, arg, TRUE, val.v, val.owned, NULL);
hres = add_dynamic_var(ctx, arg, TRUE, &v);
if(FAILED(hres))
return hres;
*v = *stack_pop(ctx);
return S_OK;
}
static HRESULT interp_val(exec_ctx_t *ctx)
@ -1170,7 +1178,7 @@ static HRESULT interp_enumnext(exec_ctx_t *ctx)
return hres;
do_continue = hres == S_OK;
hres = assign_ident(ctx, ident, &dp);
hres = assign_ident(ctx, ident, DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &dp);
VariantClear(&v);
if(FAILED(hres))
return hres;

View file

@ -79,19 +79,43 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, vbdisp_invoke_type_t invoke_typ
return DISP_E_UNKNOWNNAME;
}
static VARIANT *get_propput_arg(const DISPPARAMS *dp)
static HRESULT get_propput_arg(script_ctx_t *ctx, const DISPPARAMS *dp, WORD flags, VARIANT *v, BOOL *is_owned)
{
unsigned i;
for(i=0; i < dp->cNamedArgs; i++) {
if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
return dp->rgvarg+i;
break;
}
if(i == dp->cNamedArgs) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
return NULL;
*v = dp->rgvarg[i];
if(V_VT(v) == (VT_VARIANT|VT_BYREF))
*v = *V_VARIANTREF(v);
*is_owned = FALSE;
if(V_VT(v) == VT_DISPATCH) {
if(!(flags & DISPATCH_PROPERTYPUTREF)) {
HRESULT hres;
hres = get_disp_value(ctx, V_DISPATCH(v), v);
if(FAILED(hres))
return hres;
*is_owned = TRUE;
}
}else if(!(flags & DISPATCH_PROPERTYPUT)) {
WARN("%s can't be assigned without DISPATCH_PROPERTYPUT flag\n", debugstr_variant(v));
return DISP_E_EXCEPTION;
}
return S_OK;
}
static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
HRESULT hres;
@ -106,14 +130,15 @@ static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIA
hres = VariantCopyInd(res, v);
break;
case DISPATCH_PROPERTYPUT: {
VARIANT *put_val;
case DISPATCH_PROPERTYPUT:
case DISPATCH_PROPERTYPUTREF:
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
VARIANT put_val;
BOOL own_val;
put_val = get_propput_arg(dp);
if(!put_val) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
hres = get_propput_arg(ctx, dp, flags, &put_val, &own_val);
if(FAILED(hres))
return hres;
if(arg_cnt(dp)) {
FIXME("Arguments not supported\n");
@ -123,7 +148,10 @@ static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIA
if(res)
V_VT(res) = VT_EMPTY;
hres = VariantCopyInd(v, put_val);
if(own_val)
*v = put_val;
else
hres = VariantCopyInd(v, &put_val);
break;
}
@ -403,29 +431,34 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
}
return exec_script(This->desc->ctx, func, This, pdp, pvarRes);
case DISPATCH_PROPERTYPUT: {
VARIANT *put_val;
case DISPATCH_PROPERTYPUT:
case DISPATCH_PROPERTYPUTREF:
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
DISPPARAMS dp = {NULL, NULL, 1, 0};
BOOL needs_release;
VARIANT put_val;
HRESULT hres;
if(arg_cnt(pdp)) {
FIXME("arguments not implemented\n");
return E_NOTIMPL;
}
put_val = get_propput_arg(pdp);
if(!put_val) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
hres = get_propput_arg(This->desc->ctx, pdp, wFlags, &put_val, &needs_release);
if(FAILED(hres))
return hres;
dp.rgvarg = put_val;
func = This->desc->funcs[id].entries[V_VT(put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
dp.rgvarg = &put_val;
func = This->desc->funcs[id].entries[V_VT(&put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
if(!func) {
FIXME("no letter/setter\n");
return DISP_E_MEMBERNOTFOUND;
}
return exec_script(This->desc->ctx, func, This, &dp, NULL);
hres = exec_script(This->desc->ctx, func, This, &dp, NULL);
if(needs_release)
VariantClear(&put_val);
return hres;
}
default:
FIXME("flags %x\n", wFlags);
@ -434,7 +467,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
}
if(id < This->desc->prop_cnt + This->desc->func_cnt)
return invoke_variant_prop(This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
return invoke_variant_prop(This->desc->ctx, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
if(This->desc->builtin_prop_cnt) {
unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
@ -839,7 +872,7 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
return E_NOTIMPL;
}
return invoke_variant_prop(&ident->u.var->v, wFlags, pdp, pvarRes);
return invoke_variant_prop(This->ctx, &ident->u.var->v, wFlags, pdp, pvarRes);
}
switch(wFlags) {
@ -1060,7 +1093,13 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp,
return hres;
}
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp)
HRESULT get_disp_value(script_ctx_t *ctx, IDispatch *disp, VARIANT *v)
{
DISPPARAMS dp = {NULL};
return disp_call(ctx, disp, DISPID_VALUE, &dp, v);
}
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *dp)
{
IDispatchEx *dispex;
EXCEPINFO ei = {0};
@ -1068,13 +1107,13 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, dp, NULL, &ei, NULL /* FIXME! */);
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, NULL, &ei, NULL /* FIXME! */);
IDispatchEx_Release(dispex);
}else {
ULONG err = 0;
TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, dp, NULL, &ei, &err);
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, dp, NULL, &ei, &err);
}
return hres;

View file

@ -1186,29 +1186,23 @@ static HRESULT WINAPI RegExp2_get_Pattern(IRegExp2 *iface, BSTR *pPattern)
static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
{
RegExp2 *This = impl_from_IRegExp2(iface);
WCHAR *p;
DWORD size;
WCHAR *new_pattern;
TRACE("(%p)->(%s)\n", This, wine_dbgstr_w(pattern));
if(!pattern) {
heap_free(This->pattern);
if(This->regexp) {
regexp_destroy(This->regexp);
This->regexp = NULL;
}
This->pattern = NULL;
return S_OK;
if(pattern && *pattern) {
SIZE_T size = (SysStringLen(pattern)+1) * sizeof(WCHAR);
new_pattern = heap_alloc(size);
if(!new_pattern)
return E_OUTOFMEMORY;
memcpy(new_pattern, pattern, size);
}else {
new_pattern = NULL;
}
size = (SysStringLen(pattern)+1) * sizeof(WCHAR);
p = heap_alloc(size);
if(!p)
return E_OUTOFMEMORY;
heap_free(This->pattern);
This->pattern = p;
memcpy(p, pattern, size);
This->pattern = new_pattern;
if(This->regexp) {
regexp_destroy(This->regexp);
This->regexp = NULL;

View file

@ -159,7 +159,8 @@ HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN;
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*) DECLSPEC_HIDDEN;
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*) DECLSPEC_HIDDEN;
HRESULT get_disp_value(script_ctx_t*,IDispatch*,VARIANT*) DECLSPEC_HIDDEN;
void collect_objects(script_ctx_t*) DECLSPEC_HIDDEN;
HRESULT create_procedure_disp(script_ctx_t*,vbscode_t*,IDispatch**) DECLSPEC_HIDDEN;
HRESULT create_script_disp(script_ctx_t*,ScriptDisp**) DECLSPEC_HIDDEN;

View file

@ -198,7 +198,7 @@ reactos/dll/win32/url # Synced to WineStaging-1.7.37
reactos/dll/win32/urlmon # Synced to WineStaging-1.7.47
reactos/dll/win32/usp10 # Synced to WineStaging-1.7.47
reactos/dll/win32/uxtheme # Forked
reactos/dll/win32/vbscript # Synced to WineStaging-1.7.37
reactos/dll/win32/vbscript # Synced to WineStaging-1.7.47
reactos/dll/win32/version # Synced to WineStaging-1.7.37
reactos/dll/win32/wbemdisp # Synced to WineStaging-1.7.37
reactos/dll/win32/wbemprox # Synced to WineStaging-1.7.37