/*============================================================================ Description: (API call) Opens a given stream in a given storage for reading. Only valid if the parent storage is open in STG_READ or STG_RW mode. Arguments: in_pStorage - parent of stream to open in_wszName - name of stream to open out_ppChild - on success, will point to a newly created Stream structure Return: Status code ==========================================================================*/ int openStream (Storage* in_pStorage, const wchar_t* in_wszName, Stream** out_ppChild) { ASSERT(in_pStorage != NULL); ASSERT(in_pStorage->pRoot != NULL); ASSERT(in_wszName != NULL); ASSERT(*in_wszName != 0); ASSERT(out_ppChild != NULL); ASSERT(STG_CANREAD(in_pStorage->mode)); if ((in_pStorage == NULL) || (in_pStorage->pRoot == NULL) || (in_wszName == NULL) || (*in_wszName == 0) || (out_ppChild == NULL)) { return (int)SSTG_ERROR_ILLEGAL_CALL; } if (!STG_CANREAD(in_pStorage->mode)) { return (int)SSTG_ERROR_ILLEGAL_ACCESS; } return (int)openStreamInternal(in_pStorage, in_wszName, out_ppChild); }
/*============================================================================ Description: (API Call) Opens a substorage of a given storage. This call is only legal if the storage being read from is open in read- only mode. Arguments: in_pStorage - pointer to initialized Storage structure representing parent storage of storage to be opened in_wszName - name of substorage to open out_ppChild - points to pointer that will, on success, point to freshly created child storage Return: Status code ==========================================================================*/ int openStorage (Storage* in_pStorage, const wchar_t* in_wszName, Storage** out_ppChild) { DirectoryEntry* pChildEntry = NULL; DirectoryEntry* pParentEntry = NULL; SINT4 iRet = SSTG_OK; TOC* pTOC = NULL; ASSERT(in_pStorage != NULL && in_pStorage->pRoot != NULL && in_wszName != NULL && *in_wszName != 0 && out_ppChild != NULL && STG_CANREAD(in_pStorage->mode)); if (in_pStorage == NULL || in_pStorage->pRoot == NULL || in_wszName == NULL || *in_wszName == 0 || out_ppChild == NULL || (!STG_CANREAD(in_pStorage->mode))) { return (int)SSTG_ERROR_ILLEGAL_CALL; } pTOC = rootStorageGetTOC(in_pStorage->pRoot); pParentEntry = tocGetEntryAtIndex(pTOC, in_pStorage->ulDirIndex); if (pParentEntry == NULL) { return (int)SSTG_ERROR_CHILD_NOT_FOUND; } iRet = tocFindChildEntry (pTOC, pParentEntry, in_wszName, &pChildEntry); if (iRet != SSTG_OK) { return (int)iRet; } _TCHECK; iRet = storageConstructFromDirEntry (pChildEntry, out_ppChild); if (iRet != SSTG_OK) { return (int)iRet; } (*out_ppChild)->pParent = in_pStorage; (*out_ppChild)->pRoot = in_pStorage->pRoot; (*out_ppChild)->mode = in_pStorage->mode; iRet = openListAppend (in_pStorage->pOpenList, STORAGE, *out_ppChild); if (iRet != SSTG_OK) { return (int)iRet; } return (int)iRet; }
/*============================================================================ Description: (API Call) Opens an existing structured storage and compound file, on an existing AAF OMRawStorage Arguments: in_pRaw - OMRawStorage to which the library will connect in_accessMode - Must be STG_WRITE or STG_RW. out_ppRoot - on success, will be filled with a pointer to a new RootStorage structure representing a new structured storage file. Return: Status code ==========================================================================*/ int openStructuredStorageInOMRawStorage ( const OMRawStorage* in_pRaw, StgMode in_accessMode, RootStorage** out_ppRoot) { SSRWIS* pIS = NULL; SINT4 iRet = SSTG_OK; ASSERT (in_pRaw != NULL); ASSERT (STG_CANREAD(in_accessMode)); ASSERT (out_ppRoot != NULL); if ((in_pRaw == NULL) || (out_ppRoot == NULL)) { return SSTG_ERROR_ILLEGAL_CALL; } if (! STG_CANREAD(in_accessMode)) { return SSTG_ERROR_ILLEGAL_ACCESS; } pIS = SsrwConnectToOMRaw(in_pRaw); if (pIS == NULL) { return SSTG_ERROR_FILE_NOT_FOUND; } iRet = openStructuredStorageInSource(pIS, in_accessMode, out_ppRoot); /* iRet = openStructuredStorageInternal(pIS, out_ppRoot, SSRW_FALSE, in_accessMode); */ if (iRet != SSTG_OK) { SsrwDisconnect(pIS); } return iRet; }
/*============================================================================ Description: (API Call) Creates a new stream in a given storage. Only allowed if the parent storage is open in STG_WRITE mode. Arguments: in_pStorage - storage in which to create a new stream in_wszName - name of new stream out_ppChild - pointer to pointer that will, on success, point to freshly created empty stream Return: Status code ==========================================================================*/ int createStream (Storage* in_pStorage, const wchar_t* in_wszName, Stream** out_ppChild) { DirectoryEntry* pEntry = NULL; SINT4 iRet = SSTG_OK; TOC* pTOC = NULL; ASSERT(in_pStorage != NULL && in_wszName != NULL && *in_wszName != 0 && out_ppChild != NULL && STG_CANWRITE(in_pStorage->mode)); if (in_pStorage == NULL || in_wszName == NULL || *in_wszName == 0 || out_ppChild == NULL || (!STG_CANWRITE(in_pStorage->mode))) { return SSTG_ERROR_ILLEGAL_CALL; } *out_ppChild = NULL; /* Mark all metadata as being dirty so it will be rewritten later */ iRet = rootStorageSetDirty(in_pStorage->pRoot); if (iRet != SSTG_OK) { return (int)iRet; } /* create a directory entry for the stream */ pTOC = rootStorageGetTOC (in_pStorage->pRoot); iRet = tocAddEntry(pTOC, &pEntry); if (iRet != SSTG_OK) { streamDestroy(out_ppChild); return iRet; } iRet = directoryInitEntry (pEntry, in_wszName, DIR_STREAM, in_pStorage->pRoot); if (iRet != SSTG_OK) { tocInvalidateEntry (pTOC, directoryGetIndex(pEntry)); return iRet; } /* Make the new entry the child of its parent */ iRet = tocInsertChild(pTOC, tocGetEntryAtIndex (pTOC, in_pStorage->ulDirIndex), pEntry); if (iRet != SSTG_OK) { tocInvalidateEntry (pTOC, directoryGetIndex(pEntry)); return iRet; } /* Construct the stream structure itself */ iRet = streamConstruct (in_pStorage->pRoot, in_pStorage, pEntry, in_pStorage->mode, out_ppChild); if (iRet != SSTG_OK) { return (int)iRet; } _KABOOM3; /* If the stream is read/writable and is a small stream, upgrade it * immediately to a full-size stream. If it is still smaller than the * cutoff when it is closed, it will be demoted again. This is to avoid * having two implementations of all the writing and rewriting code. * * There is a special high-performance case for write-only files, so we * don't have to upgrade the stream in that case. */ if (STG_CANWRITE(in_pStorage->mode) && STG_CANREAD(in_pStorage->mode)) { /* This call returns success if the stream is already a regular stream */ iRet = streamUpgradeMiniToRegular(*out_ppChild); if (iRet != SSTG_OK) { tocInvalidateEntry (pTOC, directoryGetIndex(pEntry)); streamDestroy(out_ppChild); return iRet; } } /* Add this stream to its parent storage's list of open streams and * storages */ iRet = openListAppend (in_pStorage->pOpenList, STREAM, *out_ppChild); if (iRet != SSTG_OK) { tocInvalidateEntry (pTOC, directoryGetIndex(pEntry)); streamDestroy(out_ppChild); return iRet; } return iRet; }