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; }
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; }
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; }
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; }
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**)®exp); 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); }
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); }
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; }
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"); }