Example #1
0
static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
{
    HRESULT hres;
    VARIANT nextitem;

    if (This->atend)
        return S_OK;

    /* dont leak pervious value */
    jsval_release(This->item);

    /* not at end ... get next item */
    VariantInit(&nextitem);
    hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
    if (hres == S_OK)
    {
        hres = variant_to_jsval(&nextitem, &This->item);
        VariantClear(&nextitem);
        if (FAILED(hres))
        {
            WARN("failed to convert jsval to variant!");
            This->item = jsval_undefined();
            return hres;
        }
    }
    else
    {
        This->item = jsval_undefined();
        This->atend = TRUE;
    }

    return S_OK;
}
Example #2
0
HRESULT __RPC_STUB IEnumVARIANT_Next_Stub(
    IEnumVARIANT* This,
    ULONG celt,
    VARIANT* rgVar,
    ULONG* pCeltFetched)
{
  HRESULT hr;
  *pCeltFetched = 0;
  hr = IEnumVARIANT_Next(This,
			 celt,
			 rgVar,
			 pCeltFetched);
  if (hr == S_OK) *pCeltFetched = celt;
  return hr;
}
Example #3
0
File: main.c Project: GYGit/reactos
HRESULT WINAPI AccessibleChildren(IAccessible *container,
        LONG start, LONG count, VARIANT *children, LONG *children_cnt)
{
    IEnumVARIANT *ev;
    LONG i, child_no;
    HRESULT hr;

    TRACE("%p %d %d %p %p\n", container, start, count, children, children_cnt);

    if(!container || !children || !children_cnt)
        return E_INVALIDARG;

    for(i=0; i<count; i++)
        VariantInit(children+i);

    hr = IAccessible_QueryInterface(container, &IID_IEnumVARIANT, (void**)&ev);
    if(SUCCEEDED(hr)) {
        hr = IEnumVARIANT_Reset(ev);
        if(SUCCEEDED(hr))
            hr = IEnumVARIANT_Skip(ev, start);
        if(SUCCEEDED(hr))
            hr = IEnumVARIANT_Next(ev, count, children, (ULONG*)children_cnt);
        IEnumVARIANT_Release(ev);
        return hr;
    }

    hr = IAccessible_get_accChildCount(container, &child_no);
    if(FAILED(hr))
        return hr;

    for(i=0; i<count && start+i+1<=child_no; i++) {
        IDispatch *disp;

        V_VT(children+i) = VT_I4;
        V_I4(children+i) = start+i+1;

        hr = IAccessible_get_accChild(container, children[i], &disp);
        if(SUCCEEDED(hr) && disp) {
            V_VT(children+i) = VT_DISPATCH;
            V_DISPATCH(children+i) = disp;
        }
    }

    *children_cnt = i;
    return i==count ? S_OK : S_FALSE;
}
Example #4
0
static int com_iter_move_forwards(zend_object_iterator *iter)
{
	struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data);
	unsigned long n_fetched;
	zval ptr;

	/* release current cached element */
	VariantClear(&I->v);

	if (Z_TYPE(I->zdata) != IS_UNDEF) {
		zval_ptr_dtor(&I->zdata);
		ZVAL_UNDEF(&I->zdata);
	}

	if (I->ev) {
		/* Get the next element */
		if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) {
			I->key++;
		} else {
			/* indicate that there are no more items */
			I->key = (ulong)-1;
			return FAILURE;
		}
	} else {
		/* safe array */
		if (I->key >= (ULONG) I->sa_max) {
			I->key = (ulong)-1;
			return FAILURE;
		}
		I->key++;
		if (php_com_safearray_get_elem(&I->safe_array, &I->v, (LONG)I->key) == 0) {
			I->key = (ulong)-1;
			return FAILURE;
		}
	}

	ZVAL_NULL(&ptr);
	php_com_zval_from_variant(&ptr, &I->v, I->code_page);
	/* php_com_wrap_variant(ptr, &I->v, I->code_page); */
	ZVAL_COPY_VALUE(&I->zdata, &ptr);
	return SUCCESS;
}
Example #5
0
static void test_RegExp(void)
{
    IRegExp2 *regexp;
    IMatchCollection2 *mc;
    IMatch2 *match;
    ISubMatches *sm;
    IEnumVARIANT *ev;
    IUnknown *unk;
    IDispatch *disp;
    HRESULT hres;
    BSTR bstr;
    LONG count;
    VARIANT v;
    ULONG fetched;

    hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
            CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
            &IID_IUnknown, (void**)&unk);
    if(hres == REGDB_E_CLASSNOTREG) {
        win_skip("VBScriptRegExp is not registered\n");
        return;
    }
    ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);

    hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)&regexp);
    if(hres == E_NOINTERFACE) {
        win_skip("IRegExp2 interface is not available\n");
        return;
    }
    ok(hres == S_OK, "QueryInterface(IID_IRegExp2) failed: %x\n", hres);
    IUnknown_Release(unk);

    hres = IRegExp2_QueryInterface(regexp, &IID_IRegExp, (void**)&unk);
    ok(hres == S_OK, "QueryInterface(IID_IRegExp) returned %x\n", hres);
    IUnknown_Release(unk);

    hres = IRegExp2_QueryInterface(regexp, &IID_IDispatchEx, (void**)&unk);
    ok(hres == E_NOINTERFACE, "QueryInterface(IID_IDispatchEx) returned %x\n", hres);

    hres = IRegExp2_get_Pattern(regexp, &bstr);
    ok(bstr == NULL, "bstr != NULL\n");
    ok(hres == S_OK, "get_Pattern returned %x, expected S_OK\n", hres);

    hres = IRegExp2_get_Pattern(regexp, NULL);
    ok(hres == E_POINTER, "get_Pattern returned %x, expected E_POINTER\n", hres);

    hres = IRegExp2_get_IgnoreCase(regexp, NULL);
    ok(hres == E_POINTER, "get_IgnoreCase returned %x, expected E_POINTER\n", hres);

    hres = IRegExp2_get_Global(regexp, NULL);
    ok(hres == E_POINTER, "get_Global returned %x, expected E_POINTER\n", hres);

    hres = IRegExp2_Execute(regexp, NULL, &disp);
    ok(hres == S_OK, "Execute returned %x, expected S_OK\n", hres);
    hres = IDispatch_QueryInterface(disp, &IID_IMatchCollection2, (void**)&mc);
    ok(hres == S_OK, "QueryInterface(IID_IMatchCollection2) returned %x\n", hres);
    IDispatch_Release(disp);

    hres = IMatchCollection2_QueryInterface(mc, &IID_IMatchCollection, (void**)&unk);
    ok(hres == S_OK, "QueryInterface(IID_IMatchCollection) returned %x\n", hres);
    IUnknown_Release(unk);

    hres = IMatchCollection2_get_Count(mc, NULL);
    ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);

    hres = IMatchCollection2_get_Count(mc, &count);
    ok(hres == S_OK, "get_Count returned %x, expected S_OK\n", hres);
    ok(count == 1, "count = %d\n", count);

    hres = IMatchCollection2_get_Item(mc, 1, &disp);
    ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);

    hres = IMatchCollection2_get_Item(mc, 1, NULL);
    ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);

    hres = IMatchCollection2_get_Item(mc, 0, &disp);
    ok(hres == S_OK, "get_Item returned %x, expected S_OK\n", hres);
    hres = IDispatch_QueryInterface(disp, &IID_IMatch2, (void**)&match);
    ok(hres == S_OK, "QueryInterface(IID_IMatch2) returned %x\n", hres);
    IDispatch_Release(disp);

    hres = IMatch2_QueryInterface(match, &IID_IMatch, (void**)&unk);
    ok(hres == S_OK, "QueryInterface(IID_IMatch) returned %x\n", hres);
    IUnknown_Release(unk);

    hres = IMatch2_get_Value(match, NULL);
    ok(hres == E_POINTER, "get_Value returned %x, expected E_POINTER\n", hres);

    hres = IMatch2_get_FirstIndex(match, NULL);
    ok(hres == E_POINTER, "get_FirstIndex returned %x, expected E_POINTER\n", hres);

    hres = IMatch2_get_Length(match, NULL);
    ok(hres == E_POINTER, "get_Length returned %x, expected E_POINTER\n", hres);

    hres = IMatch2_get_SubMatches(match, NULL);
    ok(hres == E_POINTER, "get_SubMatches returned %x, expected E_POINTER\n", hres);

    hres = IMatch2_get_SubMatches(match, &disp);
    ok(hres == S_OK, "get_SubMatches returned %x, expected S_OK\n", hres);
    IMatch2_Release(match);
    hres = IDispatch_QueryInterface(disp, &IID_ISubMatches, (void**)&sm);
    ok(hres == S_OK, "QueryInterface(IID_ISubMatches) returned %x\n", hres);
    IDispatch_Release(disp);

    hres = ISubMatches_get_Item(sm, 0, &v);
    ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);

    hres = ISubMatches_get_Item(sm, 0, NULL);
    ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);

    hres = ISubMatches_get_Count(sm, NULL);
    ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);
    ISubMatches_Release(sm);

    hres = IMatchCollection2_get__NewEnum(mc, &unk);
    ok(hres == S_OK, "get__NewEnum returned %x, expected S_OK\n", hres);
    hres = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&ev);
    ok(hres == S_OK, "QueryInterface(IID_IEnumVARIANT) returned %x\n", hres);
    IUnknown_Release(unk);
    IMatchCollection2_Release(mc);

    hres = IEnumVARIANT_Skip(ev, 2);
    ok(hres == S_OK, "Skip returned %x\n", hres);

    hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
    ok(hres == S_FALSE, "Next returned %x, expected S_FALSE\n", hres);
    ok(fetched == 0, "fetched = %d\n", fetched);

    hres = IEnumVARIANT_Skip(ev, -1);
    ok(hres == S_OK, "Skip returned %x\n", hres);

    hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
    ok(hres == S_OK, "Next returned %x\n", hres);
    ok(fetched == 1, "fetched = %d\n", fetched);
    VariantClear(&v);
    IEnumVARIANT_Release(ev);

    IRegExp2_Release(regexp);
}
Example #6
0
static void test_default_client_accessible_object(void)
{
    static const WCHAR testW[] = {'t','e','s','t',' ','t',' ','&','j','u','n','k',0};
    static const WCHAR shortcutW[] = {'A','l','t','+','t',0};

    IAccessible *acc;
    IDispatch *disp;
    IOleWindow *ow;
    IEnumVARIANT *ev;
    HWND chld, hwnd, hwnd2;
    HRESULT hr;
    VARIANT vid, v;
    BSTR str;
    POINT pt;
    RECT rect;
    LONG l, left, top, width, height;
    ULONG fetched;

    hwnd = CreateWindowA("oleacc_test", "test &t &junk", WS_OVERLAPPEDWINDOW,
            0, 0, 100, 100, NULL, NULL, NULL, NULL);
    ok(hwnd != NULL, "CreateWindow failed\n");
    chld = CreateWindowA("static", "message", WS_CHILD | WS_VISIBLE,
            0, 0, 50, 50, hwnd, NULL, NULL, NULL);
    ok(chld != NULL, "CreateWindow failed\n");

    hr = CreateStdAccessibleObject(NULL, OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
    ok(hr == E_FAIL, "got %x\n", hr);

    hr = CreateStdAccessibleObject(hwnd, OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
    ok(hr == S_OK, "got %x\n", hr);

    hr = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void**)&ow);
    ok(hr == S_OK, "got %x\n", hr);
    hr = IOleWindow_GetWindow(ow, &hwnd2);
    ok(hr == S_OK, "got %x\n", hr);
    ok(hwnd == hwnd2, "hwnd2 = %p, expected %p\n", hwnd2, hwnd);
    hr = WindowFromAccessibleObject(acc, &hwnd2);
    ok(hr == S_OK, "got %x\n", hr);
    ok(hwnd == hwnd2, "hwnd2 = %p, expected %p\n", hwnd2, hwnd);
    IOleWindow_Release(ow);

    hr = IAccessible_get_accChildCount(acc, &l);
    ok(hr == S_OK, "got %x\n", hr);
    ok(l == 1, "l = %d\n", l);

    V_VT(&vid) = VT_I4;
    V_I4(&vid) = CHILDID_SELF;
    disp = (void*)0xdeadbeef;
    hr = IAccessible_get_accChild(acc, vid, &disp);
    ok(hr == E_INVALIDARG, "get_accChild returned %x\n", hr);
    ok(disp == NULL, "disp = %p\n", disp);

    V_I4(&vid) = 1;
    disp = (void*)0xdeadbeef;
    hr = IAccessible_get_accChild(acc, vid, &disp);
    ok(hr == E_INVALIDARG, "get_accChild returned %x\n", hr);
    ok(disp == NULL, "disp = %p\n", disp);

    hr = IAccessible_QueryInterface(acc, &IID_IEnumVARIANT, (void**)&ev);
    ok(hr == S_OK, "got %x\n", hr);

    hr = IEnumVARIANT_Skip(ev, 100);
    ok(hr == S_FALSE, "Skip returned %x\n", hr);

    V_VT(&v) = VT_I4;
    fetched = 1;
    hr = IEnumVARIANT_Next(ev, 1, &v, &fetched);
    ok(hr == S_FALSE, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(fetched == 0, "fetched = %d\n", fetched);

    hr = IEnumVARIANT_Reset(ev);
    ok(hr == S_OK, "got %x\n", hr);

    V_VT(&v) = VT_I4;
    fetched = 2;
    hr = IEnumVARIANT_Next(ev, 1, &v, &fetched);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_DISPATCH, "V_VT(&v) = %d\n", V_VT(&v));
    IDispatch_Release(V_DISPATCH(&v));
    ok(fetched == 1, "fetched = %d\n", fetched);
    IEnumVARIANT_Release(ev);

    test_AccessibleChildren(acc);

    V_VT(&vid) = VT_I4;
    V_I4(&vid) = CHILDID_SELF;
    hr = IAccessible_get_accName(acc, vid, &str);
    ok(hr == S_OK, "got %x\n", hr);
    ok(!lstrcmpW(str, testW), "name = %s\n", wine_dbgstr_w(str));
    SysFreeString(str);

    V_I4(&vid) = 1;
    str = (void*)0xdeadbeef;
    hr = IAccessible_get_accName(acc, vid, &str);
    ok(hr == E_INVALIDARG, "got %x\n", hr);
    ok(!str, "str != NULL\n");
    V_I4(&vid) = CHILDID_SELF;

    str = (void*)0xdeadbeef;
    hr = IAccessible_get_accValue(acc, vid, &str);
    ok(hr == S_FALSE, "got %x\n", hr);
    ok(!str, "str != NULL\n");

    str = (void*)0xdeadbeef;
    hr = IAccessible_get_accDescription(acc, vid, &str);
    ok(hr == S_FALSE, "got %x\n", hr);
    ok(!str, "str != NULL\n");

    V_VT(&v) = VT_DISPATCH;
    V_DISPATCH(&v) = (void*)0xdeadbeef;
    hr = IAccessible_get_accRole(acc, vid, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == ROLE_SYSTEM_CLIENT, "V_I4(&v) = %d\n", V_I4(&v));

    V_VT(&v) = VT_DISPATCH;
    V_DISPATCH(&v) = (void*)0xdeadbeef;
    hr = IAccessible_get_accState(acc, vid, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == (STATE_SYSTEM_FOCUSABLE|STATE_SYSTEM_INVISIBLE),
            "V_I4(&v) = %x\n", V_I4(&v));

    str = (void*)0xdeadbeef;
    hr = IAccessible_get_accHelp(acc, vid, &str);
    ok(hr == S_FALSE, "got %x\n", hr);
    ok(!str, "str != NULL\n");

    hr = IAccessible_get_accKeyboardShortcut(acc, vid, &str);
    ok(hr == S_OK, "got %x\n", hr);
    ok(!lstrcmpW(str, shortcutW), "str = %s\n", wine_dbgstr_w(str));
    SysFreeString(str);

    str = (void*)0xdeadbeef;
    hr = IAccessible_get_accDefaultAction(acc, vid, &str);
    ok(hr == S_FALSE, "got %x\n", hr);
    ok(!str, "str != NULL\n");

    pt.x = pt.y = 60;
    ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n");
    hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v));

    pt.x = pt.y = 25;
    ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n");
    hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v));

    ShowWindow(hwnd, TRUE);
    pt.x = pt.y = 60;
    ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n");
    hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v));

    pt.x = pt.y = 25;
    ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n");
    hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_DISPATCH, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(&v) = %p\n", V_DISPATCH(&v));
    VariantClear(&v);

    ShowWindow(chld, FALSE);
    pt.x = pt.y = 25;
    ok(ClientToScreen(hwnd, &pt), "ClientToScreen failed\n");
    hr = IAccessible_accHitTest(acc, pt.x, pt.y, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v));

    hr = IAccessible_get_accParent(acc, &disp);
    ok(hr == S_OK, "got %x\n", hr);
    ok(disp != NULL, "disp == NULL\n");
    IDispatch_Release(disp);

    ok(GetClientRect(hwnd, &rect), "GetClientRect failed\n");
    pt.x = rect.left;
    pt.y = rect.top;
    MapWindowPoints(hwnd, NULL, &pt, 1);
    rect.left = pt.x;
    rect.top = pt.y;
    pt.x = rect.right;
    pt.y = rect.bottom;
    MapWindowPoints(hwnd, NULL, &pt, 1);
    hr = IAccessible_accLocation(acc, &left, &top, &width, &height, vid);
    ok(hr == S_OK, "got %x\n", hr);
    ok(left == rect.left, "left = %d, expected %d\n", left, rect.left);
    ok(top == rect.top, "top = %d, expected %d\n", top, rect.top);
    ok(width == pt.x-rect.left, "width = %d, expected %d\n", width, pt.x-rect.left);
    ok(height == pt.y-rect.top, "height = %d, expected %d\n", height, pt.y-rect.top);

    DestroyWindow(hwnd);

    hr = IAccessible_get_accChildCount(acc, &l);
    ok(hr == S_OK, "got %x\n", hr);
    ok(l == 0, "l = %d\n", l);

    hr = IAccessible_get_accName(acc, vid, &str);
    ok(hr == E_INVALIDARG, "got %x\n", hr);

    hr = IAccessible_get_accValue(acc, vid, &str);
    ok(hr == S_FALSE, "got %x\n", hr);

    hr = IAccessible_get_accRole(acc, vid, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == ROLE_SYSTEM_CLIENT, "V_I4(&v) = %d\n", V_I4(&v));

    hr = IAccessible_get_accState(acc, vid, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == STATE_SYSTEM_INVISIBLE, "V_I4(&v) = %x\n", V_I4(&v));

    hr = IAccessible_accHitTest(acc, 200, 200, &v);
    ok(hr == S_OK, "got %x\n", hr);
    ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
    ok(V_I4(&v) == 0, "V_I4(&v) = %d\n", V_I4(&v));

    disp = (void*)0xdeadbeef;
    hr = IAccessible_get_accParent(acc, &disp);
    ok(hr == E_FAIL, "got %x\n", hr);
    ok(disp == NULL, "disp = %p\n", disp);

    hr = IAccessible_accLocation(acc, &left, &top, &width, &height, vid);
    ok(hr == S_OK, "got %x\n", hr);
    ok(left == 0, "left =  %d\n", left);
    ok(top == 0, "top =  %d\n", top);
    ok(width == 0, "width =  %d\n", width);
    ok(height == 0, "height =  %d\n", height);

    IAccessible_Release(acc);
}
Example #7
0
zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref)
{
	php_com_dotnet_object *obj;
	struct php_com_iterator *I;
	IEnumVARIANT *iev = NULL;
	DISPPARAMS dp;
	VARIANT v;
	unsigned long n_fetched;
	zval ptr;

	if (by_ref) {
		zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
		return NULL;
	}

	obj = CDNO_FETCH(object);

	if (V_VT(&obj->v) != VT_DISPATCH && !V_ISARRAY(&obj->v)) {
		php_error_docref(NULL, E_WARNING, "variant is not an object or array VT=%d", V_VT(&obj->v));
		return NULL;
	}

	memset(&dp, 0, sizeof(dp));
	VariantInit(&v);

	I = (struct php_com_iterator*)ecalloc(1, sizeof(*I));
	zend_iterator_init(&I->iter);
	I->iter.funcs = &com_iter_funcs;
	Z_PTR(I->iter.data) = I;
	I->code_page = obj->code_page;
	ZVAL_UNDEF(&I->zdata);
	VariantInit(&I->safe_array);
	VariantInit(&I->v);

	if (V_ISARRAY(&obj->v)) {
		LONG bound;
		UINT dims;

		dims = SafeArrayGetDim(V_ARRAY(&obj->v));

		if (dims != 1) {
			php_error_docref(NULL, E_WARNING,
				   "Can only handle single dimension variant arrays (this array has %d)", dims);
			goto fail;
		}

		/* same semantics as foreach on a PHP array;
		 * make a copy and enumerate that copy */
		VariantCopy(&I->safe_array, &obj->v);

		/* determine the key value for the array */
		SafeArrayGetLBound(V_ARRAY(&I->safe_array), 1, &bound);
		SafeArrayGetUBound(V_ARRAY(&I->safe_array), 1, &I->sa_max);

		/* pre-fetch the element */
		if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound)) {
			I->key = bound;
			ZVAL_NULL(&ptr);
			php_com_zval_from_variant(&ptr, &I->v, I->code_page);
			ZVAL_COPY_VALUE(&I->zdata, &ptr);
		} else {
			I->key = (ulong)-1;
		}

	} else {
		/* can we enumerate it? */
		if (FAILED(IDispatch_Invoke(V_DISPATCH(&obj->v), DISPID_NEWENUM,
						&IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
						&dp, &v, NULL, NULL))) {
			goto fail;
		}

		/* get something useful out of it */
		if (V_VT(&v) == VT_UNKNOWN) {
			IUnknown_QueryInterface(V_UNKNOWN(&v), &IID_IEnumVARIANT, (void**)&iev);
		} else if (V_VT(&v) == VT_DISPATCH) {
			IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IEnumVARIANT, (void**)&iev);
		}

		VariantClear(&v);

		if (iev == NULL) {
			goto fail;
		}

		I->ev = iev;

		/* Get the first element now */
		if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) {
			/* indicate that we have element 0 */
			I->key = 0;
			ZVAL_NULL(&ptr);
			php_com_zval_from_variant(&ptr, &I->v, I->code_page);
			ZVAL_COPY_VALUE(&I->zdata, &ptr);
		} else {
			/* indicate that there are no more items */
			I->key = (ulong)-1;
		}
	}

	return &I->iter;

fail:
	if (I) {
		VariantClear(&I->safe_array);
		VariantClear(&I->v);
		efree(I);
	}
	return NULL;
}
Example #8
0
static void test_xmlelem_collection(void)
{
    HRESULT hr;
    IUnknown *unk = NULL;
    IXMLDocument *doc = NULL;
    IXMLElement *element = NULL, *child;
    IXMLElementCollection *collection = NULL;
    IEnumVARIANT *enumVar = NULL;
    WCHAR path[MAX_PATH];
    long length, type;
    ULONG num_vars;
    VARIANT var, vIndex, vName;
    BSTR url, str;

    static const WCHAR szBankXML[] = {'b','a','n','k','.','x','m','l',0};
    static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
    static const WCHAR szName[] = {'N','A','M','E',0};

    hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IXMLDocument, (LPVOID*)&doc);
    if (FAILED(hr))
    {
        skip("Failed to create XMLDocument instance\n");
        return;
    }

    create_xml_file("bank.xml");
    GetFullPathNameW(szBankXML, MAX_PATH, path, NULL);

    url = SysAllocString(path);
    hr = IXMLDocument_put_URL(doc, url);
    /* Win98 returns ERROR_URL_NOT_FOUND */
    ok(hr == S_OK || hr == ERROR_URL_NOT_FOUND, "Expected S_OK, got 0x%08x\n", hr);
    SysFreeString(url);

    if(hr != S_OK)
        goto cleanup;

    hr = IXMLDocument_get_root(doc, &element);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(element != NULL, "Expected non-NULL element\n");

    hr = IXMLElement_get_children(element, &collection);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(collection != NULL, "Expected non-NULL collection\n");

    hr = IXMLElementCollection_get_length(collection, NULL);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %d\n", hr);

    hr = IXMLElementCollection_get_length(collection, &length);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(length == 2, "Expected 2, got %ld\n", length);

    /* IXMLElementCollection:put_length does nothing */
    hr = IXMLElementCollection_put_length(collection, -1);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    hr = IXMLElementCollection_put_length(collection, 0);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    hr = IXMLElementCollection_put_length(collection, 1);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    hr = IXMLElementCollection_put_length(collection, 2);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    hr = IXMLElementCollection_put_length(collection, 3);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    hr = IXMLElementCollection_put_length(collection, 50);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);

    /* make sure the length hasn't changed */
    hr = IXMLElementCollection_get_length(collection, &length);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(length == 2, "Expected 2, got %ld\n", length);

    /* IXMLElementCollection implements IEnumVARIANT */
    hr = IXMLElementCollection_QueryInterface(collection, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(enumVar != NULL, "Expected non-NULL enumVar\n");
    IEnumVARIANT_Release(enumVar);

    hr = IXMLElementCollection_get__newEnum(collection, &unk);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(unk != NULL, "Expected non-NULL unk\n");

    hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(enumVar != NULL, "Expected non-NULL enumVar\n");
    IUnknown_Release(unk);

    /* <Number>1234</Number> */
    hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
    ok(num_vars == 1, "Expected 1, got %d\n", 1);

    hr = IUnknown_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(child != NULL, "Expected non-NULL child\n");

    VariantClear(&var);

    hr = IXMLElement_get_type(child, &type);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %ld\n", type);

    hr = IXMLElement_get_tagName(child, &str);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
    SysFreeString(str);
    IXMLElement_Release(child);

    /* <Name>Captain Ahab</Name> */
    hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
    ok(num_vars == 1, "Expected 1, got %d\n", 1);

    hr = IUnknown_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(child != NULL, "Expected non-NULL child\n");

    VariantClear(&var);

    hr = IXMLElement_get_type(child, &type);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %ld\n", type);

    hr = IXMLElement_get_tagName(child, &str);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(!lstrcmpW(str, szName), "Expected NAME\n");
    SysFreeString(str);
    IXMLElement_Release(child);

    /* <Number>1234</Number> */
    V_VT(&vIndex) = VT_I4;
    V_I4(&vIndex) = 0;
    V_VT(&vName) = VT_ERROR;
    V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
    hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(child != NULL, "Expected non-NULL child\n");

    hr = IXMLElement_get_type(child, &type);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %ld\n", type);

    hr = IXMLElement_get_tagName(child, &str);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
    SysFreeString(str);
    IXMLElement_Release(child);

    /* <Name>Captain Ahab</Name> */
    V_VT(&vIndex) = VT_I4;
    V_I4(&vIndex) = 1;
    V_VT(&vName) = VT_ERROR;
    V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
    hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(child != NULL, "Expected non-NULL child\n");

    hr = IXMLElement_get_type(child, &type);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %ld\n", type);

    hr = IXMLElement_get_tagName(child, &str);
    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
    ok(!lstrcmpW(str, szName), "Expected NAME\n");
    SysFreeString(str);
    IXMLElement_Release(child);

    V_I4(&vIndex) = 100;
    hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
    ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
    ok(child == NULL, "Expected NULL child\n");

    V_I4(&vIndex) = -1;
    child = (IXMLElement *)0xdeadbeef;
    hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %d\n", hr);
    ok(child == NULL, "Expected NULL child\n");

    IEnumVARIANT_Release(enumVar);
    IXMLElement_Release(element);
    IXMLElementCollection_Release(collection);
cleanup:
    IXMLDocument_Release(doc);
    DeleteFileA("bank.xml");
}