/** * Adds an entry for a file with the specified set of attributes. * * @returns IPRT status code. * * @param hManifest The manifest handle. * @param hVfsIos The I/O stream handle of the entry. This will * be processed to its end on successful return. * (Must be positioned at the start to get * the expected results.) * @param pszEntry The entry name. * @param fAttrs The attributes to create for this stream. */ RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs) { /* * Note! This is a convenicence function, so just use the available public * methods to get the job done. */ AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER); AssertPtr(pszEntry); /* * Allocate and initialize the hash contexts, hash digests and I/O buffer. */ PRTMANIFESTHASHES pHashes = rtManifestHashesCreate(fAttrs); if (!pHashes) return VERR_NO_TMP_MEMORY; int rc; size_t cbBuf = _1M; void *pvBuf = RTMemTmpAlloc(cbBuf); if (RT_UNLIKELY(!pvBuf)) { cbBuf = _4K; pvBuf = RTMemTmpAlloc(cbBuf); } if (RT_LIKELY(pvBuf)) { /* * Process the stream data. */ for (;;) { size_t cbRead; rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbBuf, true /*fBlocking*/, &cbRead); if ( (rc == VINF_EOF && cbRead == 0) || RT_FAILURE(rc)) break; rtManifestHashesUpdate(pHashes, pvBuf, cbRead); } RTMemTmpFree(pvBuf); if (RT_SUCCESS(rc)) { /* * Add the entry with the finalized hashes. */ rtManifestHashesFinal(pHashes); rc = RTManifestEntryAdd(hManifest, pszEntry); if (RT_SUCCESS(rc)) rc = rtManifestHashesSetAttrs(pHashes, hManifest, pszEntry); } } else { rtManifestHashesDestroy(pHashes); rc = VERR_NO_TMP_MEMORY; } return rc; }
/** * Adds the entry to the manifest right now. * * @returns IPRT status code. * @param hVfsPtIos The manifest passthru I/O stream returned by * RTManifestEntryAddPassthruIoStream(). */ RTDECL(int) RTManifestPtIosAddEntryNow(RTVFSIOSTREAM hVfsPtIos) { PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)RTVfsIoStreamToPrivate(hVfsPtIos, &g_rtManifestPassthruIosOps); AssertReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(!pThis->fAddedEntry, VERR_WRONG_ORDER); pThis->fAddedEntry = true; rtManifestHashesFinal(pThis->pHashes); return rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry); }
/** * @interface_method_impl{RTVFSOBJOPS,pfnClose} */ static DECLCALLBACK(int) rtManifestPtIos_Close(void *pvThis) { PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; int rc = VINF_SUCCESS; if (!pThis->fAddedEntry) { rtManifestHashesFinal(pThis->pHashes); rc = rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry); } RTVfsIoStrmRelease(pThis->hVfsIos); pThis->hVfsIos = NIL_RTVFSIOSTREAM; rtManifestHashesDestroy(pThis->pHashes); pThis->pHashes = NULL; RTStrFree(pThis->pszEntry); pThis->pszEntry = NULL; RTManifestRelease(pThis->hManifest); pThis->hManifest = NIL_RTMANIFEST; return rc; }