Trouble with IXMLDOMDocument::save

So at last I figured out how to grab the xml contents of an IE browser.  The only problem I have now is that it won't save it for me.  Every time I call IXMLDOMDocument::save (even to a constant string location that I know permissions are not a problem for) it returns E_ACCESSDENIED.  Any ideas?  Here is my code:

// Get the document's IDispatchEx
pHTMLDocument2->QueryInterface(IID_IDispatchEx, (void**) &spDispEx);
      bstr = ConvertStringToBSTR("XMLDocument");

      // Get the XMLDocument expando property
      hr = spDispEx->GetDispID(bstr, fdexNameCaseSensitive, &dispid);

      if(hr==E_OUTOFMEMORY) throw 2000;
      if(hr==DISP_E_UNKNOWNNAME) throw 1003;

      // Get the XMLDocument value
      hr = spDispEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpNoArgs, &var, NULL, NULL);
      if(hr==S_OK && var.vt==VT_DISPATCH){
            // Get the IXMLDOMDocument interface
            var.pdispVal->QueryInterface(IID_IXMLDOMDocument, (void**) &pXMLDoc);
                  _variant_t varString = _T("C:\\sample.xml");
                  hr = pXMLDoc->save(varString);
                  if(hr!=S_OK) throw 2001;
}else throw 1003;

Any ideas why it seems to not be able to create the file?  It doesn't seem to matter where I try to put it - it just won't write the file.

David Johns
Who is Participating?
_ys_Connect With a Mentor Commented:
Complete illsutration code:

#import "msxml.dll" named_guids raw_interfaces_only

int main(int argc, char* argv[])
    MSXML::IXMLDOMDocument *pXmlDoc = 0;
    HRESULT hr = CoInitialize (0);

    if (SUCCEEDED (hr))
        if (SUCCEEDED (hr = CoCreateInstance (MSXML::CLSID_DOMDocument, 0, CLSCTX_SERVER,
            MSXML::IID_IXMLDOMDocument, reinterpret_cast<void**>(&pXmlDoc))))
            BSTR bstrXml = SysAllocString (L"<test>abc</test>");

            VARIANT_BOOL isLoaded;
            pXmlDoc->loadXML (bstrXml, &isLoaded);
            SysFreeString (bstrXml);

            pXmlDoc->get_xml (&bstrXml);

            MSXML::IXMLDOMDocument *pNewDoc = 0;
            if (SUCCEEDED (hr = CoCreateInstance (MSXML::CLSID_DOMDocument, 0, CLSCTX_SERVER,
                MSXML::IID_IXMLDOMDocument, reinterpret_cast<void**>(&pNewDoc))))
                pNewDoc->loadXML (bstrXml, &isLoaded);
                pNewDoc->save (_variant_t (L"C:\\TestXml.xml") );

            SysFreeString (bstrXml);
            pXmlDoc->Release ();

        CoUninitialize ();

    return 0;

Where pXmlDoc and pNewDoc are your original IE XMl document and new SML Document respectively.
The documentation is quite explicit when trying to save to a file-name:
"This mode is not intended for use from a secure client, such as Microsoft® Internet Explorer."

I would suggest creating a secondary DOM document, loading the XML into it, and saving it from there:

IXMLDOMDocument *pNewDoc = 0;
       IID_IXMLDOMDocument, reinterpret_cast<void**>(&pNewDoc));

BSTR *pbstrXml = 0;
pXmlDoc->xml ( pbstrXml );

VARIANT_BOOL  isSuccessful;
pNewDoc->loadXml ( *pbstrXml, &isSuccessful );

pNewDoc->save ( varString );
david_johnsAuthor Commented:
Excellent Post!!! I actually found that phrase in MSDN just after posting and had thought about trying to copy the xml document into another object, but couldn't get IXMLDOMDocument::save to save it into another document.  This was a clever approach that I hadn't thought of.  Thanks.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.