Source code of Windows XP (NT5)
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.

199 lines
6.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // This class provides an array-based access to a big block of memory. You pass in the fixed size of each element
  7. // to the constructor.
  8. // Get (read) an element with GetItemOfExtBuffer.
  9. // Set (write) an element with InsertIntoExtBuffer.
  10. // You must also pass in the system page size (found with GetSystemInfo). 'hItem' is the index into the array,
  11. // beginning with 1. The array always contains m_cItem elements.
  12. //
  13. // GetItemOfExtBuffer returns element hItem, where hItem=1 is the first element.
  14. // (Copies block to caller's memory.)
  15. //
  16. // InsertIntoExtBuffer always appends elements to the tail of the array,
  17. // and returns the index of the newly appended element.
  18. // (So adding first element will return 1.)
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  21. #include "headers.h"
  22. #include "extbuff.h"
  23. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  24. //
  25. // Constructor for this class
  26. //
  27. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  28. CExtBuffer::CExtBuffer ( void )
  29. {
  30. m_cItem = 0;
  31. m_cbAlloc = 0;
  32. m_rgItem = NULL;
  33. }
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. //
  36. // Destructor for this class
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  39. CExtBuffer:: ~CExtBuffer ( void )
  40. {
  41. if (m_cbAlloc){
  42. VirtualFree((VOID *) m_rgItem, m_cbAlloc, MEM_DECOMMIT );
  43. }
  44. if (m_rgItem){
  45. VirtualFree((VOID *) m_rgItem, 0, MEM_RELEASE );
  46. }
  47. }
  48. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. //
  50. // Allocate and Initialize Buffer
  51. //
  52. // HRESULT indicating routines status
  53. // S_OK Initialization succeeded
  54. // E_OUTOFMEMORY Not enough memory to allocate buffer
  55. //
  56. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. STDMETHODIMP CExtBuffer::FInit ( ULONG cItemMax, // IN Maximum number of items ever
  58. ULONG cbItem, // IN Size of each item, in bytes
  59. ULONG cbPage ) // IN Size of system page size (from SysInfo)
  60. {
  61. BYTE *pb=NULL;
  62. HRESULT hr = S_OK;
  63. m_cbReserved = ((cbItem *cItemMax) / cbPage + 1) *cbPage;
  64. m_rgItem = (BYTE *) VirtualAlloc( NULL, m_cbReserved, MEM_RESERVE, PAGE_READWRITE );
  65. if (m_rgItem == NULL){
  66. hr = E_OUTOFMEMORY;
  67. }
  68. else{
  69. m_cbItem = cbItem;
  70. m_dbAlloc = (cbItem / cbPage + 1) *cbPage;
  71. pb = (BYTE *) VirtualAlloc( m_rgItem, m_dbAlloc, MEM_COMMIT, PAGE_READWRITE );
  72. if (pb == NULL){
  73. VirtualFree((VOID *) m_rgItem, 0, MEM_RELEASE );
  74. m_rgItem = NULL;
  75. hr = E_OUTOFMEMORY;
  76. }
  77. else{
  78. m_cbAlloc = m_dbAlloc;
  79. }
  80. }
  81. return hr;
  82. }
  83. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. //
  85. // Retrieves a pointer to the value at given index
  86. //
  87. // If index is within the range of 1 to m_cItems then a valid pointer is returned, else NULL is returned.
  88. //
  89. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. void* CExtBuffer::operator[] ( ULONG hItem ) // IN Index of element in buffer
  91. {
  92. //====================================================================
  93. // Return ptr to element [n], where n = 1...m_cItem.
  94. // Returns NULL if 'n' is out of range.
  95. //
  96. // You must use InsertIntoExtBuffer to add new elements.
  97. // Thereafter you can use this operator to retrieve the address of the item.
  98. // (You can't delete an element, but you can overwrite its space.)
  99. //====================================================================
  100. if (1 <= hItem && hItem <= m_cItem)
  101. return m_rgItem + (hItem - 1) *m_cbItem;
  102. else
  103. return NULL;
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106. //
  107. // Add Data to the fixed buffers and return the index it was added at.
  108. //
  109. // HRESULT indicating routines status
  110. // S_OK Data copied successfully
  111. // E_OUTOFMEMORY Not enough memory to allocate buffer
  112. //
  113. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. STDMETHODIMP CExtBuffer::InsertIntoExtBuffer ( VOID* pvItem, // IN Pointer to buffer to copy
  115. ULONG &hItem ) // OUT Index of where data was placed
  116. {
  117. HRESULT hr = S_OK;
  118. ULONG cbOffset;
  119. cbOffset = m_cItem*m_cbItem;
  120. if ((cbOffset + m_cbItem) > m_cbAlloc){
  121. BYTE *pb;
  122. if ((m_cbAlloc + m_dbAlloc) > m_cbReserved){
  123. pb = NULL;
  124. }
  125. else{
  126. pb = (BYTE *) VirtualAlloc( m_rgItem + m_cbAlloc, m_dbAlloc, MEM_COMMIT, PAGE_READWRITE );
  127. }
  128. if (pb == NULL){
  129. hr = E_OUTOFMEMORY;
  130. }
  131. else{
  132. m_cbAlloc += m_dbAlloc;
  133. }
  134. }
  135. if( S_OK == hr ){
  136. memcpy((m_rgItem + cbOffset), (BYTE *) pvItem, m_cbItem );
  137. m_cItem++;
  138. hItem = m_cItem;
  139. }
  140. return hr;
  141. }
  142. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  143. //
  144. // Obtain a pointer to the data at a given index into the buffer
  145. //
  146. // HRESULT indicating routines status
  147. // S_OK | pvItem contains a pointer to the data requested
  148. // E_INVALIDARG | Invalid Index passed in
  149. //
  150. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. STDMETHODIMP CExtBuffer::GetItemOfExtBuffer( HACCESSOR hItem, // IN Index of item to get
  152. VOID* pvItem ) // OUT Pointer to block at index
  153. {
  154. HRESULT hr = S_OK;
  155. if ((hItem > m_cItem) || (hItem == 0) ){
  156. hr = E_INVALIDARG;
  157. }
  158. else{
  159. memcpy((BYTE *) pvItem, (m_rgItem + (hItem - 1) *m_cbItem), m_cbItem );
  160. }
  161. return hr;
  162. }
  163. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  164. //
  165. // Get the extents of the currently allocated buffers
  166. //
  167. // HRESULT indicating routines status
  168. // S_OK Extents were obtained successfuly
  169. //
  170. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. STDMETHODIMP CExtBuffer::GetFirstLastItemH( HACCESSOR &hItemFirst, // OUT First item allocated
  172. HACCESSOR &hItemLast )// OUT Last item allocated
  173. {
  174. hItemFirst = 1;
  175. hItemLast = m_cItem;
  176. return S_OK;
  177. }