Changeset 34435 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Nov 28, 2010 2:58:25 PM (14 years ago)
- Location:
- trunk/src/VBox/Runtime/common
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/checksum/manifest3.cpp
r34381 r34435 35 35 #include <iprt/assert.h> 36 36 #include <iprt/err.h> 37 #include <iprt/file.h> 37 38 #include <iprt/md5.h> 38 39 #include <iprt/mem.h> … … 40 41 #include <iprt/string.h> 41 42 #include <iprt/vfs.h> 43 #include <iprt/vfslowlevel.h> 42 44 43 45 … … 81 83 82 84 /** 85 * The internal data of a manifest passthru I/O stream. 86 */ 87 typedef struct RTMANIFESTPTIOS 88 { 89 /** The stream we're reading from or writing to. */ 90 RTVFSIOSTREAM hVfsIos; 91 /** The hashes. */ 92 PRTMANIFESTHASHES pHashes; 93 /** Whether we're reading or writing. */ 94 bool fReadOrWrite; 95 /** Whether we've already added the entry to the manifest. */ 96 bool fAddedEntry; 97 /** The entry name. */ 98 char *pszEntry; 99 /** The manifest to add the entry to. */ 100 RTMANIFEST hManifest; 101 } RTMANIFESTPTIOS; 102 /** Pointer to a the internal data of a manifest passthru I/O stream. */ 103 typedef RTMANIFESTPTIOS *PRTMANIFESTPTIOS; 104 105 106 107 /** 83 108 * Creates a hashes structure. 84 109 * … … 214 239 { 215 240 RTMemTmpFree(pHashes); 241 } 242 243 244 245 /* 246 * 247 * M a n i f e s t p a s s t h r u I / O s t r e a m 248 * M a n i f e s t p a s s t h r u I / O s t r e a m 249 * M a n i f e s t p a s s t h r u I / O s t r e a m 250 * 251 */ 252 253 254 /** 255 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 256 */ 257 static DECLCALLBACK(int) rtManifestPtIos_Close(void *pvThis) 258 { 259 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 260 261 int rc = VINF_SUCCESS; 262 if (!pThis->fAddedEntry) 263 { 264 rtManifestHashesFinal(pThis->pHashes); 265 rc = rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry); 266 } 267 268 RTVfsIoStrmRelease(pThis->hVfsIos); 269 pThis->hVfsIos = NIL_RTVFSIOSTREAM; 270 rtManifestHashesDestroy(pThis->pHashes); 271 pThis->pHashes = NULL; 272 RTStrFree(pThis->pszEntry); 273 pThis->pszEntry = NULL; 274 RTManifestRelease(pThis->hManifest); 275 pThis->hManifest = NIL_RTMANIFEST; 276 277 return rc; 278 } 279 280 281 /** 282 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 283 */ 284 static DECLCALLBACK(int) rtManifestPtIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 285 { 286 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 287 return RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr); 288 } 289 290 /** 291 * Updates the hashes with a scather/gather buffer. 292 * 293 * @param pThis The passthru I/O stream instance data. 294 * @param pSgBuf The scather/gather buffer. 295 * @param cbLeft The number of bytes to take from the buffer. 296 */ 297 static void rtManifestPtIos_UpdateHashes(PRTMANIFESTPTIOS pThis, PCRTSGBUF pSgBuf, size_t cbLeft) 298 { 299 for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++) 300 { 301 size_t cbSeg = pSgBuf->paSegs[iSeg].cbSeg; 302 if (cbSeg > cbLeft) 303 cbSeg = cbLeft; 304 rtManifestHashesUpdate(pThis->pHashes, pSgBuf->paSegs[iSeg].pvSeg, cbSeg); 305 cbLeft -= cbSeg; 306 if (!cbLeft) 307 break; 308 } 309 } 310 311 /** 312 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 313 */ 314 static DECLCALLBACK(int) rtManifestPtIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 315 { 316 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 317 int rc = RTVfsIoStrmSgRead(pThis->hVfsIos, pSgBuf, fBlocking, pcbRead); 318 if (RT_SUCCESS(rc)) 319 rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbRead ? *pcbRead : ~(size_t)0); 320 return rc; 321 } 322 323 324 /** 325 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite} 326 */ 327 static DECLCALLBACK(int) rtManifestPtIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten) 328 { 329 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 330 int rc = RTVfsIoStrmSgWrite(pThis->hVfsIos, pSgBuf, fBlocking, pcbWritten); 331 if (RT_SUCCESS(rc)) 332 rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbWritten ? *pcbWritten : ~(size_t)0); 333 return rc; 334 } 335 336 337 /** 338 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush} 339 */ 340 static DECLCALLBACK(int) rtManifestPtIos_Flush(void *pvThis) 341 { 342 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 343 return RTVfsIoStrmFlush(pThis->hVfsIos); 344 } 345 346 347 /** 348 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne} 349 */ 350 static DECLCALLBACK(int) rtManifestPtIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, 351 uint32_t *pfRetEvents) 352 { 353 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 354 return RTVfsIoStrmPoll(pThis->hVfsIos, fEvents, cMillies, fIntr, pfRetEvents); 355 } 356 357 358 /** 359 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell} 360 */ 361 static DECLCALLBACK(int) rtManifestPtIos_Tell(void *pvThis, PRTFOFF poffActual) 362 { 363 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; 364 RTFOFF off = RTVfsIoStrmTell(pThis->hVfsIos); 365 if (off < 0) 366 return (int)off; 367 *poffActual = off; 368 return VINF_SUCCESS; 369 } 370 371 372 /** 373 * The manifest passthru I/O stream vtable. 374 */ 375 static RTVFSIOSTREAMOPS g_rtManifestPassthruIosOps = 376 { 377 { /* Obj */ 378 RTVFSOBJOPS_VERSION, 379 RTVFSOBJTYPE_IO_STREAM, 380 "manifest passthru I/O stream", 381 rtManifestPtIos_Close, 382 rtManifestPtIos_QueryInfo, 383 RTVFSOBJOPS_VERSION 384 }, 385 RTVFSIOSTREAMOPS_VERSION, 386 0, 387 rtManifestPtIos_Read, 388 rtManifestPtIos_Write, 389 rtManifestPtIos_Flush, 390 rtManifestPtIos_PollOne, 391 rtManifestPtIos_Tell, 392 NULL /* Skip */, 393 NULL /* ZeroFill */, 394 RTVFSIOSTREAMOPS_VERSION, 395 }; 396 397 398 399 /** 400 * Add an entry for an I/O stream using a passthru stream. 401 * 402 * The passthru I/O stream will hash all the data read from or written to the 403 * stream and automatically add an entry to the manifest with the desired 404 * attributes when it is released. Alternatively one can call 405 * RTManifestPtIosAddEntryNow() to have more control over exactly when this 406 * action is performed and which status it yields. 407 * 408 * @returns IPRT status code. 409 * @param hManifest The manifest to add the entry to. 410 * @param hVfsIos The I/O stream to pass thru to/from. 411 * @param pszEntry The entry name. 412 * @param fAttrs The attributes to create for this stream. 413 * @param fReadOrWrite Whether it's a read or write I/O stream. 414 * @param phVfsIosPassthru Where to return the new handle. 415 */ 416 RTDECL(int) RTManifestEntryAddPassthruIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, 417 uint32_t fAttrs, bool fReadOrWrite, PRTVFSIOSTREAM phVfsIosPassthru) 418 { 419 /* 420 * Validate input. 421 */ 422 AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER); 423 AssertPtr(pszEntry); 424 AssertPtr(phVfsIosPassthru); 425 uint32_t cRefs = RTManifestRetain(hManifest); 426 AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE); 427 cRefs = RTVfsIoStrmRetain(hVfsIos); 428 AssertReturnStmt(cRefs != UINT32_MAX, VERR_INVALID_HANDLE, RTManifestRelease(hManifest)); 429 430 /* 431 * Create an instace of the passthru I/O stream. 432 */ 433 PRTMANIFESTPTIOS pThis; 434 RTVFSIOSTREAM hVfsPtIos; 435 int rc = RTVfsNewIoStream(&g_rtManifestPassthruIosOps, sizeof(*pThis), fReadOrWrite ? RTFILE_O_READ : RTFILE_O_WRITE, 436 NIL_RTVFS, NIL_RTVFSLOCK, &hVfsPtIos, (void **)&pThis); 437 if (RT_SUCCESS(rc)) 438 { 439 pThis->hVfsIos = hVfsIos; 440 pThis->pHashes = rtManifestHashesCreate(fAttrs); 441 pThis->hManifest = hManifest; 442 pThis->fReadOrWrite = fReadOrWrite; 443 pThis->fAddedEntry = false; 444 pThis->pszEntry = RTStrDup(pszEntry); 445 if (pThis->pszEntry && pThis->pHashes) 446 { 447 *phVfsIosPassthru = hVfsPtIos; 448 return VINF_SUCCESS; 449 } 450 451 RTVfsIoStrmRelease(hVfsPtIos); 452 } 453 else 454 { 455 RTVfsIoStrmRelease(hVfsIos); 456 RTManifestRelease(hManifest); 457 } 458 return rc; 459 } 460 461 462 /** 463 * Adds the entry to the manifest right now. 464 * 465 * @returns IPRT status code. 466 * @param hVfsPtIos The manifest passthru I/O stream returned by 467 * RTManifestEntryAddPassthruIoStream(). 468 */ 469 RTDECL(int) RTManifestPtIosAddEntryNow(RTVFSIOSTREAM hVfsPtIos) 470 { 471 PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)RTVfsIoStreamToPrivate(hVfsPtIos, &g_rtManifestPassthruIosOps); 472 AssertReturn(pThis, VERR_INVALID_HANDLE); 473 AssertReturn(pThis->fAddedEntry, VERR_WRONG_ORDER); 474 475 pThis->fAddedEntry = true; 476 rtManifestHashesFinal(pThis->pHashes); 477 return rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry); 216 478 } 217 479 -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r34413 r34435 1912 1912 1913 1913 1914 RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps) 1915 { 1916 RTVFSIOSTREAMINTERNAL *pThis = hVfsIos; 1917 AssertPtrReturn(pThis, NULL); 1918 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, NULL); 1919 if (pThis->pOps != pIoStreamOps) 1920 return NULL; 1921 return pThis->Base.pvThis; 1922 } 1923 1924 1914 1925 RTDECL(uint32_t) RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos) 1915 1926 {
Note:
See TracChangeset
for help on using the changeset viewer.