Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

746 lines
21 KiB

  1. #include "precomp.h"
  2. //
  3. // RBC.CPP
  4. // Received Bitmap Cache
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_CORE
  9. //
  10. // RBC_ViewStarting()
  11. //
  12. // For 3.0 nodes, we create the cache each time they start hosting.
  13. // For 2.x nodes, we create the cache once and use it until they leave the
  14. // share.
  15. //
  16. BOOL ASShare::RBC_ViewStarting(ASPerson * pasPerson)
  17. {
  18. BOOL rc = FALSE;
  19. DebugEntry(ASShare::RBC_ViewStarting);
  20. ValidatePerson(pasPerson);
  21. if (pasPerson->prbcHost != NULL)
  22. {
  23. ASSERT(pasPerson->cpcCaps.general.version < CAPS_VERSION_30);
  24. TRACE_OUT(("RBC_ViewStarting: Reusing rbc cache for 2.x node [%d]",
  25. pasPerson->mcsID));
  26. rc = TRUE;
  27. DC_QUIT;
  28. }
  29. //
  30. // Allocate the INCOMING cache data for this host.
  31. //
  32. pasPerson->prbcHost = new RBC_HOST_INFO;
  33. if (!pasPerson->prbcHost)
  34. {
  35. ERROR_OUT(( "Failed to get memory for prbcHost info"));
  36. DC_QUIT;
  37. }
  38. ZeroMemory(pasPerson->prbcHost, sizeof(*(pasPerson->prbcHost)));
  39. SET_STAMP(pasPerson->prbcHost, RBCHOST);
  40. TRACE_OUT(( "Allocated RBC root for host [%d] at 0x%08x",
  41. pasPerson->mcsID, pasPerson->prbcHost));
  42. //
  43. // Create the bitmap caches for the sender
  44. //
  45. // SMALL
  46. if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsSmallCacheNumEntries,
  47. pasPerson->cpcCaps.bitmaps.sender.capsSmallCacheCellSize,
  48. ID_SMALL_BMP_CACHE,
  49. &(pasPerson->prbcHost->bitmapCache[ID_SMALL_BMP_CACHE])))
  50. {
  51. DC_QUIT;
  52. }
  53. // MEDIUM
  54. if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsMediumCacheNumEntries,
  55. pasPerson->cpcCaps.bitmaps.sender.capsMediumCacheCellSize,
  56. ID_MEDIUM_BMP_CACHE,
  57. &(pasPerson->prbcHost->bitmapCache[ID_MEDIUM_BMP_CACHE])))
  58. {
  59. DC_QUIT;
  60. }
  61. // LARGE
  62. if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsLargeCacheNumEntries,
  63. pasPerson->cpcCaps.bitmaps.sender.capsLargeCacheCellSize,
  64. ID_LARGE_BMP_CACHE,
  65. &(pasPerson->prbcHost->bitmapCache[ID_LARGE_BMP_CACHE])))
  66. {
  67. DC_QUIT;
  68. }
  69. //
  70. // The host can join the share.
  71. //
  72. rc = TRUE;
  73. DC_EXIT_POINT:
  74. DebugExitBOOL(ASShare::RBC_ViewStarting, rc);
  75. return(rc);
  76. }
  77. //
  78. // RBC_ViewEnded()
  79. //
  80. void ASShare::RBC_ViewEnded(ASPerson * pasPerson)
  81. {
  82. DebugEntry(ASShare::RBC_ViewEnded);
  83. ValidatePerson(pasPerson);
  84. //
  85. // For 3.0 NODES, we can free the cache; 3.0 senders clear theirs
  86. // every time they host.
  87. // For 2.x NODES, we must keep it around while they are in the share.
  88. //
  89. if (pasPerson->cpcCaps.general.version >= CAPS_VERSION_30)
  90. {
  91. RBCFreeIncoming(pasPerson);
  92. }
  93. else
  94. {
  95. TRACE_OUT(("RBC_ViewEnded: Keeping rbc cache for 2.x node [%d]",
  96. pasPerson->mcsID));
  97. }
  98. DebugExitVOID(ASShare::RBC_ViewEnded);
  99. }
  100. //
  101. // RBC_PartyLeftShare()
  102. // For 2.x nodes, frees the incoming RBC data
  103. //
  104. void ASShare::RBC_PartyLeftShare(ASPerson * pasPerson)
  105. {
  106. DebugEntry(ASShare::RBC_PartyLeftShare);
  107. ValidatePerson(pasPerson);
  108. if (pasPerson->cpcCaps.general.version >= CAPS_VERSION_30)
  109. {
  110. // This should be gone!
  111. ASSERT(pasPerson->prbcHost == NULL);
  112. }
  113. else
  114. {
  115. TRACE_OUT(("RBC_PartyLeftShare: Freeing rbc cache for 2.x node [%d]",
  116. pasPerson->mcsID));
  117. RBCFreeIncoming(pasPerson);
  118. }
  119. DebugExitVOID(ASShare::RBC_PartyLeftShare);
  120. }
  121. //
  122. // RBCFreeIncoming()
  123. // Frees the party RBC incoming structures. This happens
  124. // * For 3.0 nodes when they stop hosting
  125. // * For 2.x nodes when leave the share
  126. //
  127. void ASShare::RBCFreeIncoming(ASPerson * pasPerson)
  128. {
  129. DebugEntry(ASShare::RBCFreeIncoming);
  130. //
  131. // Free this host's cache bitmaps.
  132. //
  133. if (pasPerson->prbcHost != NULL)
  134. {
  135. UINT i;
  136. //
  137. // Delete all of this host's cache bitmaps.
  138. //
  139. for (i = 0; i < NUM_BMP_CACHES; i++)
  140. {
  141. BMCFreeCacheData(&(pasPerson->prbcHost->bitmapCache[i]));
  142. }
  143. delete pasPerson->prbcHost;
  144. pasPerson->prbcHost = NULL;
  145. }
  146. DebugExitVOID(ASShare::RBCFreeIncoming);
  147. }
  148. //
  149. // RBC_ProcessCacheOrder(..)
  150. //
  151. void ASShare::RBC_ProcessCacheOrder
  152. (
  153. ASPerson * pasPerson,
  154. LPCOM_ORDER_UA pOrder
  155. )
  156. {
  157. PBMC_ORDER_HDR pBmcOrderHdr;
  158. PBMC_COLOR_TABLE_ORDER_UA pColorOrder;
  159. PBMC_BITMAP_BITS_ORDER_R2_UA pBitsOrderR2;
  160. BOOL fCompressed = FALSE;
  161. UINT cxFixedBitmapWidth;
  162. UINT iCacheEntry;
  163. LPBYTE pBitmapBits;
  164. UINT cbBitmapBits;
  165. DebugEntry(ASShare::RBC_ProcessCacheOrder);
  166. ValidatePerson(pasPerson);
  167. //
  168. // The rectangle is not included in the header for private order data
  169. // (see SBC_CopyPrivateOrderData) so we must take this into account
  170. // when working out the address of the order data.
  171. //
  172. pBmcOrderHdr = (PBMC_ORDER_HDR)
  173. (pOrder->abOrderData - sizeof(pOrder->OrderHeader.rcsDst));
  174. switch (pBmcOrderHdr->bmcPacketType)
  175. {
  176. case BMC_PT_COLOR_TABLE:
  177. //
  178. // This is a new color table. Simply cache the RGB values for
  179. // use when we come to process a memblt order
  180. // For backlevel calls the color table is always stored at
  181. // index 0 because the index field in the order reuses a
  182. // zero initialized "padding" field in the old structure.
  183. //
  184. TRACE_OUT(("Person [%d] Caching color table", pasPerson->mcsID));
  185. pColorOrder = (PBMC_COLOR_TABLE_ORDER_UA)pBmcOrderHdr;
  186. PM_CacheRxColorTable(pasPerson, pColorOrder->index,
  187. EXTRACT_TSHR_UINT16_UA(&(pColorOrder->colorTableSize)),
  188. (LPTSHR_RGBQUAD)&pColorOrder->data[0]);
  189. break;
  190. case BMC_PT_BITMAP_BITS_COMPRESSED:
  191. fCompressed = TRUE;
  192. TRACE_OUT(( "Compressed BMP"));
  193. case BMC_PT_BITMAP_BITS_UNCOMPRESSED:
  194. //
  195. // This is some cached bitmap data. We have to store it in the
  196. // specified slot in the specified cache.
  197. //
  198. //
  199. // The width of the bitmaps we use are actually fixed as
  200. // multiples of 16 pels wide. Work out the width that
  201. // corresponds to the sub-bitmap width of data we are caching.
  202. //
  203. pBitsOrderR2 = (PBMC_BITMAP_BITS_ORDER_R2_UA)pBmcOrderHdr;
  204. cbBitmapBits = EXTRACT_TSHR_UINT16_UA(
  205. &(pBitsOrderR2->header.cbBitmapBits));
  206. cxFixedBitmapWidth =
  207. ((pBitsOrderR2->header.cxSubBitmapWidth +15)/16)*16;
  208. //
  209. // The location of cache entry field depends on the R1/R2
  210. // protocol
  211. //
  212. iCacheEntry = EXTRACT_TSHR_UINT16_UA(&(pBitsOrderR2->iCacheEntryR2));
  213. pBitmapBits = pBitsOrderR2->data;
  214. TRACE_OUT(("Person [%d] Rx bmp: id(%d) entry(%d) size(%dx%d) " \
  215. "fixed(%d) bpp(%d) bytes(%d) compressed(%d)",
  216. pasPerson->mcsID,
  217. pBitsOrderR2->header.cacheID,
  218. iCacheEntry,
  219. pBitsOrderR2->header.cxSubBitmapWidth,
  220. pBitsOrderR2->header.cySubBitmapHeight,
  221. cxFixedBitmapWidth,
  222. pBitsOrderR2->header.bpp,
  223. cbBitmapBits,
  224. fCompressed));
  225. //
  226. // Pass the BMC data to the caching code. When calculating the
  227. // pointer to the bitmap bits remember that we did not send the
  228. // pBitmapBits field of the BMC_BITMAP_BITS_ORDER_Rx structure
  229. // (see SBC_CopyPrivateOrderData).
  230. //
  231. RBCStoreBitsInCacheBitmap(pasPerson,
  232. pBitsOrderR2->header.cacheID,
  233. iCacheEntry,
  234. pBitsOrderR2->header.cxSubBitmapWidth,
  235. cxFixedBitmapWidth,
  236. pBitsOrderR2->header.cySubBitmapHeight,
  237. pBitsOrderR2->header.bpp,
  238. pBitmapBits,
  239. cbBitmapBits,
  240. fCompressed);
  241. break;
  242. default:
  243. ERROR_OUT(( "[%u]Invalid packet type(%d)",
  244. pasPerson,
  245. (UINT)pBmcOrderHdr->bmcPacketType));
  246. break;
  247. }
  248. DebugExitVOID(ASShare::RBC_ProcessCacheOrder);
  249. }
  250. //
  251. // RBC_MapCacheIDToBitmapHandle(..)
  252. //
  253. HBITMAP ASShare::RBC_MapCacheIDToBitmapHandle
  254. (
  255. ASPerson * pasPerson,
  256. UINT cache,
  257. UINT cacheEntry,
  258. UINT colorIndex
  259. )
  260. {
  261. PBMC_DIB_CACHE pDIBCache;
  262. PBMC_DIB_ENTRY pDIBEntry;
  263. BITMAPINFO_ours bitmapInfo;
  264. UINT cColors;
  265. HBITMAP hWorkBitmap = NULL;
  266. HPALETTE hpalOldDIB = NULL;
  267. LPBYTE pBits;
  268. UINT cacheOffset;
  269. DebugEntry(ASShare::RBC_MapCacheIDToBitmapHandle);
  270. ValidateView(pasPerson);
  271. //
  272. // Check that the supplied cache ID is valid.
  273. //
  274. if (cache >= NUM_BMP_CACHES)
  275. {
  276. ERROR_OUT(( "[%u]Invalid cache ID (%d)", pasPerson, cache));
  277. cache = 0;
  278. }
  279. //
  280. // Get a pointer to the bitmap data
  281. //
  282. // Note that there are two indexes floating around. From the host's
  283. // perspective this index is a Cache Handler token and it must be
  284. // translated in order to address the associated data. However we
  285. // use it as the direct index into our receive cache and so the
  286. // slots used on host and remote will be diferent.
  287. //
  288. // There is no reason why the slots should be the same. This is just
  289. // to warn you that if you try correlating cache offsets between
  290. // host and remote you will get confused as soon as the cache fills
  291. // up and entries are reallocated in different positions.
  292. //
  293. //
  294. pDIBCache = &(pasPerson->prbcHost->bitmapCache[cache]);
  295. TRACE_OUT(( "Local person [%d] cache id %d pointer %lx",
  296. pasPerson->mcsID, cache, pDIBCache));
  297. cacheOffset = cacheEntry * pDIBCache->cSize;
  298. pDIBEntry = (PBMC_DIB_ENTRY)(pDIBCache->data + cacheOffset);
  299. TRACE_OUT(( "Bits for index %u are at offset %ld, pointer 0x%08x",
  300. cacheEntry, (cacheEntry * pDIBCache->cSize), pDIBEntry));
  301. //
  302. // Set up the BitmapInfo structure.
  303. //
  304. USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&bitmapInfo, pDIBEntry->bpp);
  305. bitmapInfo.bmiHeader.biWidth = pDIBEntry->cxFixed;
  306. bitmapInfo.bmiHeader.biHeight = pDIBEntry->cy;
  307. //
  308. // Copy the Rx color table into the bitmap header.
  309. //
  310. if ( (pDIBEntry->bpp == 1) ||
  311. (pDIBEntry->bpp == 4) ||
  312. (pDIBEntry->bpp == 8) )
  313. {
  314. cColors = COLORS_FOR_BPP(pDIBEntry->bpp);
  315. PM_GetColorTable( pasPerson,
  316. colorIndex,
  317. &cColors,
  318. (LPTSHR_RGBQUAD)(&bitmapInfo.bmiColors) );
  319. TRACE_OUT(( "Got %u colors from table",cColors));
  320. bitmapInfo.bmiHeader.biClrUsed = cColors;
  321. }
  322. else if (pDIBEntry->bpp == 24)
  323. {
  324. ASSERT(colorIndex == COLORCACHEINDEX_NONE);
  325. }
  326. else
  327. {
  328. ERROR_OUT(("RBC: Unexpected bpp %d from [%d]", pDIBEntry->bpp, pasPerson->mcsID));
  329. DC_QUIT;
  330. }
  331. //
  332. // Select which fixed width bitmap we are going to use to store the
  333. // incoming DIB bits.
  334. //
  335. switch (pDIBEntry->cxFixed)
  336. {
  337. case 16:
  338. hWorkBitmap = m_usrBmp16;
  339. break;
  340. case 32:
  341. hWorkBitmap = m_usrBmp32;
  342. break;
  343. case 48:
  344. hWorkBitmap = m_usrBmp48;
  345. break;
  346. case 64:
  347. hWorkBitmap = m_usrBmp64;
  348. break;
  349. case 80:
  350. hWorkBitmap = m_usrBmp80;
  351. break;
  352. case 96:
  353. hWorkBitmap = m_usrBmp96;
  354. break;
  355. case 112:
  356. hWorkBitmap = m_usrBmp112;
  357. break;
  358. case 128:
  359. hWorkBitmap = m_usrBmp128;
  360. break;
  361. case 256:
  362. hWorkBitmap = m_usrBmp256;
  363. break;
  364. default:
  365. ERROR_OUT(("RBC_MapCacheIDToBitmapHandle: invalid size from [%d]",
  366. pDIBEntry->cxFixed, pasPerson->mcsID));
  367. hWorkBitmap = m_usrBmp256;
  368. break;
  369. }
  370. ASSERT(hWorkBitmap != NULL);
  371. //
  372. // If the cached bitmap bits are compressed, we first have to
  373. // decompress them.
  374. //
  375. if (pDIBEntry->bCompressed)
  376. {
  377. ASSERT(pDIBEntry->bpp <= 8);
  378. //
  379. // Use the decompression buffer to decompress the bitmap data.
  380. //
  381. if (!BD_DecompressBitmap(pDIBEntry->bits, m_usrPBitmapBuffer,
  382. pDIBEntry->cCompressed,
  383. pDIBEntry->cxFixed,
  384. pDIBEntry->cy,
  385. pDIBEntry->bpp))
  386. {
  387. ERROR_OUT((
  388. "Failed to decompress bitmap pBits(%lx)"
  389. " pBuf(%lx) cb(%x) cx(%d) cy(%d) bpp(%d)",
  390. pDIBEntry->bits,
  391. m_usrPBitmapBuffer,
  392. pDIBEntry->cCompressed,
  393. pDIBEntry->cxFixed,
  394. pDIBEntry->cy,
  395. pDIBEntry->bpp));
  396. DC_QUIT;
  397. }
  398. pBits = m_usrPBitmapBuffer;
  399. }
  400. else
  401. {
  402. //
  403. // For uncompressed data just use direct from the cache
  404. //
  405. TRACE_OUT(( "Bitmap bits are uncompressed"));
  406. pBits = pDIBEntry->bits;
  407. }
  408. //
  409. // Set the bits into the bitmap we are about to return to the caller
  410. //
  411. hpalOldDIB = SelectPalette(pasPerson->m_pView->m_usrWorkDC,
  412. pasPerson->pmPalette, FALSE);
  413. RealizePalette(pasPerson->m_pView->m_usrWorkDC);
  414. if (!SetDIBits(pasPerson->m_pView->m_usrWorkDC,
  415. hWorkBitmap,
  416. 0,
  417. pDIBEntry->cy,
  418. pBits,
  419. (BITMAPINFO *)&bitmapInfo,
  420. DIB_RGB_COLORS))
  421. {
  422. ERROR_OUT(("SetDIBits failed in RBC_MapCacheIDToBitmapHandle"));
  423. }
  424. SelectPalette(pasPerson->m_pView->m_usrWorkDC, hpalOldDIB, FALSE );
  425. TRACE_OUT(( "Returning bitmap for person [%d] cache %u index %u color %u",
  426. pasPerson->mcsID, cache, cacheEntry, colorIndex));
  427. DC_EXIT_POINT:
  428. DebugExitVOID(ASShare::RBC_MapCacheIDToBitmapHandle);
  429. return(hWorkBitmap);
  430. }
  431. //
  432. // FUNCTION: RBCStoreBitsInCacheBitmap(..)
  433. //
  434. // DESCRIPTION:
  435. //
  436. // Stores received bitmap bits into one of the receiver's cache bitmaps.
  437. //
  438. // PARAMETERS:
  439. //
  440. // pasPerson - pasPerson of host the bits came from.
  441. //
  442. // cache - the id of the cache bitmap to store the bits in.
  443. //
  444. // iCacheEntry - the cache entry number (index).
  445. //
  446. // cxSubBitmapWidth - the width in pels of the actual sub-bitmap (ie.
  447. // excluding padding)
  448. //
  449. // cxFixedWidth - the fixed width in pels of the supplied bits (ie.
  450. // including padding)
  451. //
  452. // cySubBitmapHeight - the height in pels of the sub-bitmap.
  453. //
  454. // pBitmapBits - a pointer to the actual bitmap bits. These may or may
  455. // not be compressed (determined by the value of the fCompressed
  456. // flag).
  457. //
  458. // cbBitmapBits - the size of the bitmap bits pointed to by pBitmapBits.
  459. //
  460. // fCompressed - a flag specifying whether the supplied bitmap
  461. // bits are compressed.
  462. //
  463. // RETURNS:
  464. //
  465. // Nothing.
  466. //
  467. //
  468. void ASShare::RBCStoreBitsInCacheBitmap
  469. (
  470. ASPerson * pasPerson,
  471. UINT cache,
  472. UINT iCacheEntry,
  473. UINT cxSubBitmapWidth,
  474. UINT cxFixedWidth,
  475. UINT cySubBitmapHeight,
  476. UINT bpp,
  477. LPBYTE pBitmapBits,
  478. UINT cbBitmapBits,
  479. BOOL fCompressed
  480. )
  481. {
  482. PBMC_DIB_ENTRY pDIBEntry;
  483. DebugEntry(ASShare::RBCStoreBitsInCacheBitmap);
  484. ValidatePerson(pasPerson);
  485. //
  486. // Do some error checking.
  487. //
  488. if (cache >= NUM_BMP_CACHES)
  489. {
  490. ERROR_OUT(("Invalid cache ID %d from [%d]", cache, pasPerson->mcsID));
  491. DC_QUIT;
  492. }
  493. //
  494. // Now store the bits in the cache
  495. // The cache is a huge chunk of memory comprising cache slots of cSize
  496. // bytes each. cSize is rounded to a power of 2 to ensure the array
  497. // spans segment boundaries cleanly for segmented architecture OSs.
  498. //
  499. pDIBEntry = (PBMC_DIB_ENTRY)
  500. (((LPBYTE)(pasPerson->prbcHost->bitmapCache[cache].data) +
  501. (iCacheEntry * pasPerson->prbcHost->bitmapCache[cache].cSize)));
  502. TRACE_OUT(( "Selected cache entry 0x%08x",pDIBEntry));
  503. pDIBEntry->inUse = TRUE;
  504. pDIBEntry->cx = (TSHR_UINT16)cxSubBitmapWidth;
  505. pDIBEntry->cxFixed = (TSHR_UINT16)cxFixedWidth;
  506. pDIBEntry->cy = (TSHR_UINT16)cySubBitmapHeight;
  507. pDIBEntry->bpp = (TSHR_UINT16)bpp;
  508. pDIBEntry->bCompressed = (fCompressed != FALSE);
  509. pDIBEntry->cCompressed = cbBitmapBits;
  510. //
  511. // Now copy the bits into the cache entry
  512. //
  513. memcpy(pDIBEntry->bits, pBitmapBits, cbBitmapBits);
  514. //
  515. // THIS FIELD IS NEVER ACCESSED.
  516. //
  517. pDIBEntry->cBits = BYTES_IN_BITMAP(cxFixedWidth, cySubBitmapHeight,
  518. pDIBEntry->bpp);
  519. DC_EXIT_POINT:
  520. DebugExitVOID(ASShare::RBCStoreBitsInCacheBitmap);
  521. }
  522. //
  523. // BMCAllocateCacheData()
  524. //
  525. // DESCRIPTION:
  526. //
  527. // Allocates memory for a bitmap cache
  528. //
  529. // PARAMETERS:
  530. //
  531. // cellSize
  532. //
  533. // RETURNS:
  534. //
  535. // Area needed
  536. //
  537. //
  538. BOOL BMCAllocateCacheData
  539. (
  540. UINT numEntries,
  541. UINT cellSize,
  542. UINT cacheID,
  543. PBMC_DIB_CACHE pCache
  544. )
  545. {
  546. BOOL rc = TRUE;
  547. UINT memoryNeeded;
  548. UINT workSize;
  549. PBMC_DIB_ENTRY pCacheEntry;
  550. UINT i;
  551. DebugEntry(BMCAllocateCacheData);
  552. //
  553. // First we must free up any data, if it has been allocated
  554. //
  555. BMCFreeCacheData(pCache);
  556. //
  557. // For 2.x compat, we have SEND caps of 1 entry, 1 byte since 2.x
  558. // remotes fail for zero entries. But we don't want a small cache
  559. // at all, and for W95 nodes that don't have a cache at all, we don't
  560. // want viewers to alloc memory which will never be used.
  561. //
  562. if ((cellSize > 1) && (numEntries > 1))
  563. {
  564. //
  565. // Calculate the cell area
  566. //
  567. workSize = cellSize + sizeof(BMC_DIB_ENTRY) - 1;
  568. memoryNeeded = numEntries * workSize;
  569. TRACE_OUT(("Need 0x%08x bytes for cache %d, %d cells of size 0x%08x",
  570. memoryNeeded, cacheID, numEntries, cellSize));
  571. //
  572. // Malloc the huge space
  573. //
  574. pCache->data = new BYTE[memoryNeeded];
  575. if (pCache->data == NULL)
  576. {
  577. ERROR_OUT(( "Failed to alloc bitmap cache %d", cacheID));
  578. rc = FALSE;
  579. DC_QUIT;
  580. }
  581. pCache->cCellSize = cellSize;
  582. pCache->cEntries = numEntries;
  583. pCache->cSize = workSize;
  584. pCache->freeEntry = NULL;
  585. pCacheEntry = (PBMC_DIB_ENTRY)(pCache->data);
  586. for (i = 0; i < numEntries; i++)
  587. {
  588. pCacheEntry->inUse = FALSE;
  589. pCacheEntry = (PBMC_DIB_ENTRY)(((LPBYTE)pCacheEntry) + workSize);
  590. }
  591. TRACE_OUT(( "Allocated cache %d size %d, pointer 0x%08x stored at 0x%08x",
  592. cacheID,
  593. memoryNeeded,
  594. pCache->data,
  595. &pCache->data));
  596. }
  597. DC_EXIT_POINT:
  598. DebugExitBOOL(BMCAllocateCacheData, rc);
  599. return(rc);
  600. }
  601. //
  602. // FUNCTION: BMCFreeCacheData()
  603. //
  604. // DESCRIPTION:
  605. //
  606. // Deletes selected cache's memory
  607. //
  608. // PARAMETERS:
  609. //
  610. // cacheID - id of cache for free
  611. // pCache - pointer to memory to be freed
  612. //
  613. //
  614. // RETURNS:
  615. //
  616. // Nothing.
  617. //
  618. //
  619. void BMCFreeCacheData(PBMC_DIB_CACHE pCache)
  620. {
  621. DebugEntry(BMCFreeCacheData);
  622. if (pCache->data)
  623. {
  624. delete[] pCache->data;
  625. pCache->data = NULL;
  626. }
  627. pCache->cCellSize = 0;
  628. pCache->cEntries = 0;
  629. DebugExitVOID(BMCFreeCacheData);
  630. }
  631.