static HRESULT WINAPI xmldoc_put_URL(IXMLDocument *iface, BSTR p) { WCHAR url[INTERNET_MAX_URL_LENGTH]; IStream *stream; IBindCtx *bctx; IMoniker *moniker; IPersistStreamInit *persist; HRESULT hr; TRACE("(%p, %s)\n", iface, debugstr_w(p)); if (!p) return E_INVALIDARG; if (!PathIsURLW(p)) { WCHAR fullpath[MAX_PATH]; DWORD needed = sizeof(url) / sizeof(WCHAR); if (!PathSearchAndQualifyW(p, fullpath, sizeof(fullpath) / sizeof(WCHAR))) { ERR("can't find path\n"); return E_FAIL; } if (FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0))) { ERR("can't create url from path\n"); return E_FAIL; } p = url; } hr = CreateURLMoniker(NULL, p, &moniker); if (FAILED(hr)) return hr; CreateAsyncBindCtx(0, &xmldoc_bsc.IBindStatusCallback_iface, 0, &bctx); hr = IMoniker_BindToStorage(moniker, bctx, NULL, &IID_IStream, (LPVOID *)&stream); IBindCtx_Release(bctx); IMoniker_Release(moniker); if (FAILED(hr)) return hr; hr = IXMLDocument_QueryInterface(iface, &IID_IPersistStreamInit, (LPVOID *)&persist); if (FAILED(hr)) { IStream_Release(stream); return hr; } hr = IPersistStreamInit_Load(persist, stream); IPersistStreamInit_Release(persist); IStream_Release(stream); return hr; }
/************************************************************************ * xmlelem_collection implementation of IEnumVARIANT. */ static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface( IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj) { xmlelem_collection *this = impl_from_IEnumVARIANT(iface); return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj); }
/************************************************************************ * xmldoc implementation of IPersistStreamInit. */ static HRESULT WINAPI xmldoc_IPersistStreamInit_QueryInterface( IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj) { xmldoc *this = impl_from_IPersistStreamInit(iface); return IXMLDocument_QueryInterface(&this->IXMLDocument_iface, riid, ppvObj); }
static void test_xmldoc(void) { IXMLElement *element = NULL, *child = NULL, *value = NULL; IXMLElementCollection *collection = NULL, *inner = NULL; IPersistStreamInit *psi = NULL; IXMLDocument *doc = NULL; IStream *stream = NULL; VARIANT vIndex, vName; LONG type, num_child; CHAR path[MAX_PATH]; IDispatch *disp; ITypeInfo *ti; HRESULT hr; BSTR name; static const WCHAR szBankAccount[] = {'B','A','N','K','A','C','C','O','U','N','T',0}; static const WCHAR szNumber[] = {'N','U','M','B','E','R',0}; static const WCHAR szNumVal[] = {'1','2','3','4',0}; static const WCHAR szName[] = {'N','A','M','E',0}; static const WCHAR szNameVal[] = {'C','a','p','t','a','i','n',' ','A','h','a','b',0}; static const WCHAR szVersion[] = {'1','.','0',0}; static const WCHAR rootW[] = {'r','o','o','t',0}; hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (void**)&doc); EXPECT_HR(hr, S_OK); /* IDispatch */ hr = IXMLDocument_QueryInterface(doc, &IID_IDispatch, (void**)&disp); EXPECT_HR(hr, S_OK); /* just to make sure we're on right type data */ hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti); EXPECT_HR(hr, S_OK); name = NULL; hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLDOCUMENT_ROOT, &name, NULL, NULL, NULL); EXPECT_HR(hr, S_OK); ok(!lstrcmpW(name, rootW), "got name %s\n", wine_dbgstr_w(name)); SysFreeString(name); ITypeInfo_Release(ti); IDispatch_Release(disp); hr = IXMLDocument_QueryInterface(doc, &IID_IXMLDOMDocument, (void**)&disp); EXPECT_HR(hr, E_NOINTERFACE); create_xml_file("bank.xml"); GetFullPathNameA("bank.xml", MAX_PATH, path, NULL); create_stream_on_file(&stream, path); hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&psi); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(psi != NULL, "Expected non-NULL psi\n"); hr = IXMLDocument_get_root(doc, &element); ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr); ok(element == NULL, "Expected NULL element\n"); hr = IPersistStreamInit_Load(psi, stream); ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr); if(hr == XML_E_INVALIDATROOTLEVEL) goto cleanup; ok(stream != NULL, "Expected non-NULL stream\n"); /* version field */ hr = IXMLDocument_get_version(doc, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); name = NULL; hr = IXMLDocument_get_version(doc, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szVersion), "Expected 1.0, got %s\n", wine_dbgstr_w(name)); SysFreeString(name); /* doctype */ hr = IXMLDocument_get_doctype(doc, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); hr = IXMLDocument_get_doctype(doc, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT, got %s\n", wine_dbgstr_w(name)); SysFreeString(name); hr = IXMLDocument_get_root(doc, &element); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(element != NULL, "Expected non-NULL element\n"); /* ::root() returns new instance each time */ hr = IXMLDocument_get_root(doc, &child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(child != NULL, "Expected non-NULL element\n"); ok(child != element, "Expected new element instance\n"); IXMLElement_Release(child); hr = IXMLElement_get_type(element, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type); hr = IXMLElement_get_tagName(element, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT\n"); SysFreeString(name); hr = IXMLElement_get_children(element, &collection); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(collection != NULL, "Expected non-NULL collection\n"); hr = IXMLElementCollection_get_length(collection, &num_child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(num_child == 2, "Expected 2, got %d\n", num_child); 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 %08x\n", hr); ok(child != NULL, "Expected non-NULL child\n"); hr = IXMLElement_get_type(child, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type); hr = IXMLElement_get_tagName(child, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szNumber), "Expected NUMBER\n"); SysFreeString(name); hr = IXMLElement_get_children(child, &inner); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(inner != NULL, "Expected non-NULL inner\n"); hr = IXMLElementCollection_get_length(inner, &num_child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(num_child == 1, "Expected 1, got %d\n", num_child); hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(value != NULL, "Expected non-NULL value\n"); hr = IXMLElement_get_type(value, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type); hr = IXMLElement_get_text(value, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szNumVal), "Expected '1234'\n"); SysFreeString(name); IXMLElementCollection_Release(inner); inner = (IXMLElementCollection *)0xdeadbeef; hr = IXMLElement_get_children(value, &inner); ok(hr == 1, "Expected 1, got %08x\n", hr); ok(inner == NULL, "Expected NULL inner, got %p\n", inner); IXMLElement_Release(value); IXMLElement_Release(child); value = NULL; child = NULL; V_I4(&vIndex) = 1; hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(child != NULL, "Expected non-NULL child\n"); hr = IXMLElement_get_type(child, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type); hr = IXMLElement_get_tagName(child, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szName), "Expected NAME\n"); SysFreeString(name); hr = IXMLElement_get_children(child, &inner); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(inner != NULL, "Expected non-NULL inner\n"); hr = IXMLElementCollection_get_length(inner, &num_child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(num_child == 1, "Expected 1, got %d\n", num_child); V_I4(&vIndex) = 0; hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(value != NULL, "Expected non-NULL value\n"); hr = IXMLElement_get_type(value, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type); hr = IXMLElement_get_text(value, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szNameVal), "Expected 'Captain Ahab'\n"); SysFreeString(name); IXMLElementCollection_Release(inner); inner = (IXMLElementCollection *)0xdeadbeef; hr = IXMLElement_get_children(value, &inner); ok(hr == 1, "Expected 1, got %08x\n", hr); ok(inner == NULL, "Expected NULL inner, got %p\n", inner); IXMLElement_Release(value); IXMLElement_Release(child); IXMLElementCollection_Release(collection); IXMLElement_Release(element); cleanup: IStream_Release(stream); IPersistStreamInit_Release(psi); IXMLDocument_Release(doc); DeleteFileA("bank.xml"); }
static void test_persiststreaminit(void) { IXMLDocument *doc = NULL; IXMLElement *element = NULL; IPersistStreamInit *psi = NULL; IStream *stream = NULL; STATSTG stat; HRESULT hr; ULARGE_INTEGER size; CHAR path[MAX_PATH]; CLSID id; BSTR str; static const WCHAR testW[] = {'t','e','s','t',0}; hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (LPVOID*)&doc); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (LPVOID *)&psi); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(psi != NULL, "Expected non-NULL psi\n"); /* null arguments */ hr = IPersistStreamInit_GetSizeMax(psi, NULL); ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr); hr = IPersistStreamInit_Load(psi, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); hr = IPersistStreamInit_Save(psi, NULL, FALSE); todo_wine ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); hr = IPersistStreamInit_GetClassID(psi, NULL); ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr); hr = IPersistStreamInit_IsDirty(psi); todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); create_xml_file("bank.xml"); GetFullPathNameA("bank.xml", MAX_PATH, path, NULL); create_stream_on_file(&stream, path); /* GetSizeMax not implemented */ size.QuadPart = 0; hr = IPersistStreamInit_GetSizeMax(psi, &size); ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr); ok(size.QuadPart == 0, "Expected 0\n"); hr = IPersistStreamInit_Load(psi, stream); IStream_Release(stream); ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr); if(hr == XML_E_INVALIDATROOTLEVEL) goto cleanup; hr = IPersistStreamInit_IsDirty(psi); todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); /* try to save document */ stream = NULL; hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = IPersistStreamInit_Save(psi, stream, FALSE); todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); stat.cbSize.QuadPart = 0; hr = IStream_Stat(stream, &stat, 0); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n"); IStream_Release(stream); str = SysAllocString(testW); hr = IXMLDocument_get_root(doc, &element); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = IXMLElement_put_text(element, str); ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr); IXMLElement_Release(element); SysFreeString(str); hr = IPersistStreamInit_IsDirty(psi); todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); create_stream_on_file(&stream, path); hr = IPersistStreamInit_Load(psi, stream); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); IStream_Release(stream); hr = IPersistStreamInit_IsDirty(psi); todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); /* reset internal stream */ hr = IPersistStreamInit_InitNew(psi); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = IPersistStreamInit_IsDirty(psi); todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); stream = NULL; hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = IPersistStreamInit_Save(psi, stream, FALSE); todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); stat.cbSize.QuadPart = 0; hr = IStream_Stat(stream, &stat, 0); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n"); IStream_Release(stream); memset(&id, 0, sizeof(id)); hr = IPersistStreamInit_GetClassID(psi, &id); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(IsEqualCLSID(&id, &CLSID_XMLDocument), "Expected CLSID_XMLDocument\n"); cleanup: IPersistStreamInit_Release(psi); IXMLDocument_Release(doc); DeleteFileA("bank.xml"); }