FARINTERNAL_(void) UtRemoveExtraOlePresStreams(LPSTORAGE pstg, int iStart) { VDATEHEAP(); HRESULT hr; // error code from stream deletion OLECHAR szName[sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR)]; // space for the stream names // if the stream number is invalid, do nothing if ((iStart < 0) || (iStart >= OLE_MAX_PRES_STREAMS)) return; // create presentation stream name _xstrcpy(szName, OLE_PRESENTATION_STREAM); UtGetPresStreamName(szName, iStart); // for each of these streams that exists, get rid of it while((hr = pstg->DestroyElement(szName)) == NOERROR) { // if we've gotten to the end of the possible streams, quit if (++iStart >= OLE_MAX_PRES_STREAMS) break; // Get the next presentation stream name UtGetPresStreamName(szName, iStart); } // since the only reason these streams should be open, the first // failure had better be that the file was not found, and not // anything else (such as STG_E_ACCESSDENIED) AssertSz(hr == STG_E_FILENOTFOUND, "UtRemoveExtraOlePresStreams failure"); }
FARINTERNAL Ut10NativeStmToContentsStm (LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm) { CLIPFORMAT cfOld; CLIPFORMAT cfNew; LPOLESTR lpszUserType = NULL; HRESULT error; LPSTREAM pstmSrc = NULL; LPSTREAM pstmDst = NULL; if (error = ReadFmtUserTypeStg(pstg, &cfOld, &lpszUserType)) return error; if (rclsid == CLSID_StaticDib) cfNew = CF_DIB; else if (rclsid == CLSID_StaticMetafile) cfNew = CF_METAFILEPICT; else { AssertSz(FALSE, "Internal Error: this routine shouldn't have been called for this class"); return ResultFromScode(E_FAIL); } if (cfOld == g_cfPBrush) { if (cfNew != CF_DIB) { error = ResultFromScode(DV_E_CLIPFORMAT); goto errRtn; } } else if (cfOld == g_cfMSDraw) { if (cfNew != CF_METAFILEPICT) { error = ResultFromScode(DV_E_CLIPFORMAT); goto errRtn; } } else { // Converted to static object from some class other than PBrush or // MSDraw. The data must be in a proper format in the CONTENTS // stream. return NOERROR; } if (error = pstg->OpenStream(OLE10_NATIVE_STREAM, NULL, (STGM_READ|STGM_SHARE_EXCLUSIVE), 0, &pstmSrc)) goto errRtn; if (error = OpenOrCreateStream(pstg, OLE_CONTENTS_STREAM, &pstmDst)) goto errRtn; DWORD dwSize; if (error = pstmSrc->Read(&dwSize, sizeof(DWORD), NULL)) goto errRtn; if (cfOld == g_cfMSDraw) { WORD mfp[3]; // mm, xExt, yExt if (error = pstmSrc->Read(mfp, sizeof(mfp), NULL)) goto errRtn; dwSize -= sizeof(mfp); error = UtMFStmToPlaceableMFStm(pstmSrc, dwSize, (LONG) mfp[1], (LONG) mfp[2], pstmDst); } else { // The PBrush native data format is DIB File format. So all we got to // do is CopyTo. ULARGE_INTEGER ularge_int; ULISet32(ularge_int, dwSize); if ((error = pstmSrc->CopyTo(pstmDst, ularge_int, NULL, NULL)) == NOERROR) StSetSize(pstmDst, 0, TRUE); } errRtn: if (pstmDst) pstmDst->Release(); if (pstmSrc) pstmSrc->Release(); if (error == NOERROR) { error = WriteFmtUserTypeStg(pstg, cfNew, lpszUserType); if (fDeleteSrcStm) pstg->DestroyElement(OLE10_NATIVE_STREAM); } else { pstg->DestroyElement(OLE_CONTENTS_STREAM); } if (lpszUserType) PubMemFree(lpszUserType); return error; }
FARINTERNAL UtContentsStmTo10NativeStm (LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm, UINT FAR* puiStatus) { CLIPFORMAT cf; LPOLESTR lpszUserType = NULL; HRESULT error; LPSTREAM pstmSrc = NULL; LPSTREAM pstmDst = NULL; *puiStatus = NULL; if (error = ReadFmtUserTypeStg(pstg, &cf, &lpszUserType)) return error; if (! ((cf == CF_DIB && rclsid == CLSID_PBrush) || (cf == CF_METAFILEPICT && rclsid == CLSID_MSDraw))) { error = ResultFromScode(DV_E_CLIPFORMAT); goto errRtn; } if (error = pstg->OpenStream(OLE_CONTENTS_STREAM, NULL, (STGM_READ|STGM_SHARE_EXCLUSIVE), 0, &pstmSrc)) { *puiStatus |= CONVERT_NOSOURCE; // check whether OLE10_NATIVE_STREAM exists if (pstg->OpenStream(OLE10_NATIVE_STREAM, NULL, (STGM_READ|STGM_SHARE_EXCLUSIVE), 0, &pstmDst)) *puiStatus |= CONVERT_NODESTINATION; else { pstmDst->Release(); pstmDst = NULL; } goto errRtn; } if (error = OpenOrCreateStream(pstg, OLE10_NATIVE_STREAM, &pstmDst)) { *puiStatus |= CONVERT_NODESTINATION; goto errRtn; } if (cf == CF_METAFILEPICT) error = UtPlaceableMFStmToMSDrawNativeStm(pstmSrc, pstmDst); else error = UtDIBFileStmToPBrushNativeStm(pstmSrc, pstmDst); errRtn: if (pstmDst) pstmDst->Release(); if (pstmSrc) pstmSrc->Release(); if (error == NOERROR) { LPOLESTR lpszProgId = NULL; ProgIDFromCLSID(rclsid, &lpszProgId); error = WriteFmtUserTypeStg(pstg, RegisterClipboardFormat(lpszProgId), lpszUserType); if (lpszProgId) delete lpszProgId; } if (error == NOERROR) { if (fDeleteSrcStm) pstg->DestroyElement(OLE_CONTENTS_STREAM); } else { pstg->DestroyElement(OLE10_NATIVE_STREAM); } if (lpszUserType) delete lpszUserType; return error; }
STDAPI UtDoStreamOperation(LPSTORAGE pstgSrc, LPSTORAGE pstgDst, int iOpCode, DWORD grfAllowedStmTypes) { VDATEHEAP(); HRESULT error; // error status so far IEnumSTATSTG FAR* penumStg; // used to enumerate the storage elements ULONG celtFetched; // how many storage elements were fetched STATSTG statstg; // get an enumerator over the source storage if (error = pstgSrc->EnumElements(NULL, NULL, NULL, &penumStg)) return error; // repeat for every storage while(penumStg->Next(1, &statstg, &celtFetched) == NOERROR) { // operate on streams that we're interested in if (statstg.type == STGTY_STREAM) { DWORD stmType; // find the type of the stream // REVIEW, we must have constants for these name // prefixes!!! switch (statstg.pwcsName[0]) { case '\1': stmType = STREAMTYPE_CONTROL; break; case '\2': stmType = STREAMTYPE_CACHE; break; case '\3': stmType = STREAMTYPE_CONTAINER; break; default: stmType = (DWORD)STREAMTYPE_OTHER; } // check whether it should be operated upon if (stmType & grfAllowedStmTypes) { switch(iOpCode) { #ifdef LATER case OPCODE_COPY: pstgDst->DestroyElement( statstg.pwcsName); error = pstgSrc->MoveElementTo( statstg.pwcsName, pstgDst, statstg.pwcsName, STGMOVE_COPY); break; case OPCODE_MOVE: pstgDst->DestroyElement( statstg.pwcsName); error = pstgSrc->MoveElementTo( statstg.pwcsName, pstgDst, statstg.pwcsName, STGMOVE_MOVE); break; case OPCODE_EXCLUDEFROMCOPY: AssertSz(FALSE, "Not yet implemented"); break; #endif // LATER case OPCODE_REMOVE: error = pstgSrc->DestroyElement( statstg.pwcsName); break; default: AssertSz(FALSE, "Invalid opcode"); break; } } } // if the enumerator allocated a new name string, get rid of it if (statstg.pwcsName) PubMemFree(statstg.pwcsName); // quit the enumeration loop if we've hit an error if (error != NOERROR) break; } // release the enumerator penumStg->Release(); // return the error state return error; }