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.

318 lines
7.0 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991-1996 **/
  4. /**********************************************************************/
  5. /*
  6. buffer.cxx
  7. Implementation of the BUFFER class.
  8. FILE HISTORY:
  9. MuraliK 3-July-1996 Rewrote the buffer class
  10. */
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <buffer.hxx>
  16. /*******************************************************************
  17. NAME: BUFFER::GetNewStorage
  18. SYNOPSIS: Given an object with no allocated storage,
  19. allocate the initial memory.
  20. ENTRY: cbRequested - amount of storage requested in bytes
  21. EXIT: Either storage alloc'd, or error reported
  22. Sets m_cb, m_pb and m_fIsDynAlloced
  23. RETURNS: TRUE if successful, FALSE for GetLastError()
  24. NOTES:
  25. Private member function.
  26. ********************************************************************/
  27. BOOL
  28. BUFFER::GetNewStorage( UINT cbRequested )
  29. {
  30. if ( cbRequested <= m_cb) {
  31. return TRUE;
  32. }
  33. m_pb = (BYTE *) ::LocalAlloc( NONZEROLPTR, cbRequested );
  34. if ( !m_pb ) {
  35. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  36. } else {
  37. m_pb[0] = '\0'; // just store null
  38. m_cb = cbRequested;
  39. m_fIsDynAlloced = 1;
  40. }
  41. return (m_pb != NULL);
  42. } // BUFFER::GetNewStorage()
  43. /*******************************************************************
  44. NAME: BUFFER::ReallocStorage
  45. SYNOPSIS: Do a "hard" reallocation to the new size
  46. ENTRY: cbNewRequested - new size, in bytes
  47. EXIT: Storage realloc'd. m_pb, m_cb, m_fIsDynAlloced changed
  48. RETURNS: TRUE if successful, FALSE for GetLastError()
  49. ********************************************************************/
  50. BOOL
  51. BUFFER::ReallocStorage( UINT cbNewRequested )
  52. {
  53. if ( cbNewRequested <= m_cb) {
  54. return (TRUE);
  55. }
  56. HANDLE hNewMem = ((IsDynAlloced()) ?
  57. (::LocalReAlloc( m_pb, cbNewRequested, LMEM_MOVEABLE )):
  58. (::LocalAlloc( NONZEROLPTR, cbNewRequested))
  59. );
  60. if (hNewMem == 0)
  61. {
  62. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  63. return FALSE;
  64. }
  65. if ( !IsDynAlloced()) {
  66. // First time this block is allocated. Copy over old contents.
  67. CopyMemory( (BYTE* ) hNewMem, m_pb, m_cb);
  68. m_fIsDynAlloced = 1;
  69. }
  70. m_pb = (BYTE *) hNewMem;
  71. m_cb = cbNewRequested;
  72. return TRUE;
  73. } // BUFFER::ReallocStorage()
  74. /*******************************************************************
  75. NAME: BUFFER::VerifyState
  76. SYNOPSIS: Verifies the state of the object.
  77. Asserts out if the state is invalid, i.e. if an
  78. internal error took place.
  79. NOTES: This function does nothing in the retail version.
  80. ********************************************************************/
  81. VOID BUFFER::VerifyState() const
  82. {
  83. //
  84. // 1. If Dynamically Allocated ==>
  85. // m_pb points to something other than m_rgb &
  86. // m_cb > INLINED_BUFFER_LEN
  87. // 2. If not Dynamicall Allocated ==>
  88. // (a) it can be using user-supplied buffer & any sized
  89. // (b) it can be using inlined buffer & m_cb == INLINED_BUFFER_LEN
  90. //
  91. } // BUFFER::VerifyState()
  92. /*******************************************************************
  93. NAME: BUFFER::FreeMemory
  94. SYNOPSIS: Frees the heap memory associated with this buffer object
  95. ********************************************************************/
  96. VOID
  97. BUFFER::FreeMemory(
  98. VOID
  99. )
  100. {
  101. if ( IsDynAlloced()) {
  102. ::LocalFree( (HANDLE)m_pb );
  103. m_pb = m_rgb;
  104. m_cb = INLINED_BUFFER_LEN;
  105. m_fIsDynAlloced = 0;
  106. }
  107. m_rgb[0] = '\0'; // reset the contents
  108. }
  109. BOOL
  110. BUFFER_CHAIN::AppendBuffer(
  111. BUFFER_CHAIN_ITEM * pBCI
  112. )
  113. /*++
  114. Routine Description:
  115. Adds a new buffer chain item to the end of the buffer chain
  116. Arguments:
  117. pBCI - Chain item to append
  118. Return Value:
  119. TRUE if successful, FALSE on error
  120. --*/
  121. {
  122. InsertTailList( &_ListHead,
  123. &pBCI->_ListEntry );
  124. return TRUE;
  125. }
  126. DWORD
  127. BUFFER_CHAIN::DeleteChain(
  128. VOID
  129. )
  130. /*++
  131. Routine Description:
  132. Deletes all of the buffers in this chain
  133. Return Value:
  134. Total number of allocated bytes freed by this call
  135. --*/
  136. {
  137. BUFFER_CHAIN_ITEM * pBCI;
  138. DWORD cbFreed = 0;
  139. while ( !IsListEmpty( &_ListHead ))
  140. {
  141. pBCI = CONTAINING_RECORD( _ListHead.Flink,
  142. BUFFER_CHAIN_ITEM,
  143. _ListEntry );
  144. RemoveEntryList( &pBCI->_ListEntry );
  145. cbFreed += pBCI->QuerySize();
  146. delete pBCI;
  147. }
  148. return cbFreed;
  149. }
  150. BUFFER_CHAIN_ITEM *
  151. BUFFER_CHAIN::NextBuffer(
  152. BUFFER_CHAIN_ITEM * pBCI
  153. )
  154. /*++
  155. Routine Description:
  156. Returns the next buffer in the chain. Start the enumeration by
  157. passing pBCI as NULL. Continue it by passing the return value
  158. Arguments:
  159. pBCI - Previous item in enumeration
  160. Return Value:
  161. Pointer to next item in chain, NULL when done
  162. --*/
  163. {
  164. if ( pBCI != NULL )
  165. {
  166. if ( pBCI->_ListEntry.Flink != &_ListHead )
  167. {
  168. return CONTAINING_RECORD( pBCI->_ListEntry.Flink,
  169. BUFFER_CHAIN_ITEM,
  170. _ListEntry );
  171. }
  172. else
  173. {
  174. return NULL;
  175. }
  176. }
  177. if ( !IsListEmpty( &_ListHead ))
  178. {
  179. return CONTAINING_RECORD( _ListHead.Flink,
  180. BUFFER_CHAIN_ITEM,
  181. _ListEntry );
  182. }
  183. return NULL;
  184. }
  185. DWORD
  186. BUFFER_CHAIN::CalcTotalSize(
  187. BOOL fUsed
  188. ) const
  189. /*++
  190. Routine Description:
  191. Returns the total amount of memory allocated by this buffer chain
  192. excluding the size of the structures themselves
  193. Arguments:
  194. fUsed - If FALSE, returns total allocated by chain, if TRUE returns
  195. total used by chain
  196. Return Value:
  197. Total bytes allocated or total bytes used
  198. --*/
  199. {
  200. LIST_ENTRY * pEntry;
  201. BUFFER_CHAIN_ITEM * pBCI;
  202. DWORD cbRet = 0;
  203. for ( pEntry = _ListHead.Flink;
  204. pEntry != &_ListHead;
  205. pEntry = pEntry->Flink )
  206. {
  207. pBCI = CONTAINING_RECORD( pEntry, BUFFER_CHAIN_ITEM, _ListEntry );
  208. if ( fUsed == FALSE )
  209. cbRet += pBCI->QuerySize();
  210. else
  211. cbRet += pBCI->QueryUsed();
  212. }
  213. return cbRet;
  214. }
  215. /***************************** End Of File ******************************/
  216.