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.

194 lines
3.2 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. memblock.cxx
  6. Abstract:
  7. Memory allocater for chunks of read only memory.
  8. Author:
  9. Albert Ting (AlbertT) 30-Aug-1994
  10. Revision History:
  11. --*/
  12. #include "spllibp.hxx"
  13. #pragma hdrstop
  14. TMemBlock::
  15. TMemBlock(
  16. UINT uGranularity,
  17. DWORD fdwFlags) :
  18. _uGranularity(uGranularity),
  19. _pIterBlock(NULL),
  20. _pIterData(NULL),
  21. _dwCount(0),
  22. _fdwFlags(fdwFlags)
  23. {
  24. DWORD dwSize = dwBlockHeaderSize() + _uGranularity;
  25. if( _fdwFlags & kFlagGlobalNew ){
  26. _pLast = (PBLOCK) new BYTE[dwSize];
  27. } else {
  28. _pLast = (PBLOCK)AllocMem( dwSize );
  29. }
  30. _pFirst = _pLast;
  31. if (_pFirst) {
  32. _pFirst->pNext = NULL;
  33. _dwNextFree = dwBlockHeaderSize();
  34. }
  35. }
  36. TMemBlock::
  37. ~TMemBlock()
  38. {
  39. PBLOCK pBlock;
  40. PBLOCK pBlockNext;
  41. for (pBlock = _pFirst; pBlock; pBlock = pBlockNext) {
  42. pBlockNext = pBlock->pNext;
  43. if( _fdwFlags & kFlagGlobalNew ){
  44. delete [] (PBYTE)pBlock;
  45. } else {
  46. //
  47. // Our Delete must mirror the New.
  48. //
  49. FreeMem(pBlock);
  50. }
  51. }
  52. }
  53. PVOID
  54. TMemBlock::
  55. pvAlloc(
  56. DWORD dwSize
  57. )
  58. {
  59. PDATA pData;
  60. //
  61. // If out of memory, fail.
  62. //
  63. if (!_pFirst) {
  64. goto FailOOM;
  65. }
  66. dwSize = Align(dwSize + dwDataHeaderSize());
  67. SPLASSERT(dwSize <= _uGranularity);
  68. if (dwSize + _dwNextFree > _uGranularity) {
  69. DWORD dwSize = dwBlockHeaderSize() + _uGranularity;
  70. //
  71. // Must allocate a new block
  72. //
  73. if( _fdwFlags & kFlagGlobalNew ){
  74. _pLast->pNext = (PBLOCK) new BYTE[dwSize];
  75. } else {
  76. _pLast->pNext = (PBLOCK)AllocMem( dwSize );
  77. }
  78. if (!_pLast->pNext) {
  79. goto FailOOM;
  80. }
  81. _pLast = _pLast->pNext;
  82. _pLast->pNext = NULL;
  83. _dwNextFree = dwBlockHeaderSize();
  84. }
  85. //
  86. // We have enough space in this link now;
  87. // update everything.
  88. //
  89. pData = (PDATA)((PBYTE)_pLast + _dwNextFree);
  90. pData->dwSize = dwSize;
  91. _dwNextFree += dwSize;
  92. _pLast->pDataLast = pData;
  93. _dwCount++;
  94. return pvDataToUser(pData);
  95. FailOOM:
  96. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  97. return NULL;
  98. }
  99. PVOID
  100. TMemBlock::
  101. pvFirst(
  102. VOID
  103. )
  104. {
  105. if (!_dwCount) {
  106. return NULL;
  107. }
  108. _pIterBlock = _pFirst;
  109. _pIterData = pBlockToData(_pIterBlock);
  110. _dwIterCount = 0;
  111. return pvDataToUser(_pIterData);
  112. }
  113. PVOID
  114. TMemBlock::
  115. pvIter(
  116. VOID
  117. )
  118. {
  119. _dwIterCount++;
  120. if (_dwIterCount == _dwCount)
  121. return NULL;
  122. //
  123. // Go to next block. If we're at the last pData, go to next block.
  124. //
  125. if (_pIterData == _pIterBlock->pDataLast) {
  126. _pIterBlock = _pIterBlock->pNext;
  127. _pIterData = pBlockToData(_pIterBlock);
  128. } else {
  129. _pIterData = pDataNext(_pIterData);
  130. }
  131. return pvDataToUser(_pIterData);
  132. }
  133. UINT
  134. TMemBlock::
  135. uSize(
  136. PVOID pvUser
  137. ) const
  138. {
  139. return pvUserToData(pvUser)->dwSize;
  140. }