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.

212 lines
5.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // MySimpleTable.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // MySimpleTable.cpp: derived from CSimpleTable. Only difference
  12. // is _GetDataPtr now public instead of being protected
  13. //
  14. // MODIFICATION HISTORY
  15. //
  16. // 01/26/1999 Original version.
  17. //
  18. //
  19. //////////////////////////////////////////////////////////////////////
  20. #include "precomp.hpp"
  21. #include "simpletableex.h"
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char THIS_FILE[]=__FILE__;
  25. #define new DEBUG_NEW
  26. #endif
  27. ///////////////////////////////////////////////////////////////////////////////
  28. //
  29. // STRUCT
  30. //
  31. // DBBinding
  32. //
  33. // DESCRIPTION
  34. //
  35. // This struct extends the DBBINDING struct to provide functionality
  36. // to initialize the struct from a DBCOLUMNINFO struct.
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. struct DBBinding : DBBINDING
  40. {
  41. //////////
  42. // 'offset' is the offset in bytes of this column's data within the
  43. // row buffer.
  44. //////////
  45. void Initialize(DBCOLUMNINFO& columnInfo, DBBYTEOFFSET& offset)
  46. {
  47. iOrdinal = columnInfo.iOrdinal;
  48. obValue = offset;
  49. obLength = offset + columnInfo.ulColumnSize;
  50. obStatus = obLength + sizeof(DBLENGTH);
  51. pTypeInfo = NULL;
  52. pObject = NULL;
  53. pBindExt = NULL;
  54. dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
  55. eParamIO = DBPARAMIO_NOTPARAM;
  56. dwMemOwner = (columnInfo.wType & DBTYPE_BYREF) ? DBMEMOWNER_PROVIDEROWNED
  57. : DBMEMOWNER_CLIENTOWNED;
  58. cbMaxLen = columnInfo.ulColumnSize;
  59. dwFlags = 0;
  60. wType = columnInfo.wType;
  61. bPrecision = columnInfo.bPrecision;
  62. bScale = columnInfo.bScale;
  63. offset = obStatus + sizeof(DBSTATUS);
  64. }
  65. };
  66. ///////////////////////////////////////////////////////////////////////////////
  67. //
  68. // METHOD
  69. //
  70. // CSimpleTableEx::Attach
  71. //
  72. // Size bug "fixed"
  73. //
  74. // DESCRIPTION
  75. //
  76. // This method binds the table object to a new rowset. The previous rowset
  77. // (if any) will be detached.
  78. //
  79. // REMARK: see "Changes" below
  80. //
  81. ///////////////////////////////////////////////////////////////////////////////
  82. HRESULT CSimpleTableEx::Attach(IRowset* pRowset)
  83. {
  84. // Make sure we didn't get a null pointer.
  85. if (!pRowset) { return E_POINTER; }
  86. // Detach the current rowset.
  87. Detach();
  88. // We don't care if this returns an error. It will just prevent
  89. // the user from updating.
  90. pRowset->QueryInterface(IID_IRowsetChange, (void**)&rowsetChange);
  91. //////////
  92. // Get the column information for the table.
  93. //////////
  94. CComPtr<IColumnsInfo> ColumnsInfo;
  95. RETURN_ERROR(pRowset->QueryInterface(IID_IColumnsInfo,
  96. (void**)&ColumnsInfo));
  97. RETURN_ERROR(ColumnsInfo->GetColumnInfo(&numColumns,
  98. &columnInfo,
  99. &stringsBuffer));
  100. //////////
  101. // Allocate the per-column data.
  102. //////////
  103. // tperraut Bug 449498
  104. columnBinding = new (std::nothrow) DBBinding[numColumns];
  105. if ( !columnBinding )
  106. {
  107. return E_OUTOFMEMORY;
  108. }
  109. // 449498 resize changed: will not throw an exception.
  110. // false if out of memory
  111. if ( !dirty.resize(numColumns) )
  112. {
  113. return E_OUTOFMEMORY;
  114. }
  115. //////////
  116. // Create a binding for each column.
  117. //////////
  118. bufferLength = 0;
  119. for (DBORDINAL i = 0; i < numColumns; ++i)
  120. {
  121. // Compute the width of the column.
  122. DBLENGTH width = columnInfo[i].ulColumnSize;
  123. //////////////////////////////////////////////////////////////////
  124. //
  125. // CHANGES: if size is too big (1 giga byte), then size = a
  126. // pre-defined value. Note: that's dangerous
  127. //
  128. //////////////////////////////////////////////////////////////////
  129. if (SIZE_MEMO_MAX < width)
  130. {
  131. width = SIZE_MEMO_MAX;
  132. }
  133. // Add room for the null terminator.
  134. if (columnInfo[i].wType == DBTYPE_STR)
  135. {
  136. width += 1;
  137. }
  138. else if (columnInfo[i].wType == DBTYPE_WSTR)
  139. {
  140. width = (width + 1) * sizeof(WCHAR);
  141. }
  142. // Round to an 8-byte boundary (could peek ahead and be more efficient).
  143. width = (width + 7) >> 3 << 3;
  144. columnInfo[i].ulColumnSize = width;
  145. // We're using the pTypeInfo element to store the offset to our data.
  146. // We have to store the offset now, since it will be overwritten by
  147. // DBBinding::Initialize.
  148. columnInfo[i].pTypeInfo = (ITypeInfo*)bufferLength;
  149. columnBinding[i].Initialize(columnInfo[i], bufferLength);
  150. }
  151. //////////
  152. // Allocate a buffer for the row data.
  153. //////////
  154. buffer = new (std::nothrow) BYTE[bufferLength];
  155. if (!buffer) { return E_OUTOFMEMORY; }
  156. //////////
  157. // Create an accessor.
  158. //////////
  159. RETURN_ERROR(pRowset->QueryInterface(IID_IAccessor,
  160. (void**)&accessor));
  161. RETURN_ERROR(accessor->CreateAccessor(DBACCESSOR_ROWDATA,
  162. numColumns,
  163. columnBinding,
  164. bufferLength,
  165. &readAccess,
  166. NULL));
  167. // I used this hokey method of assigning the pointer to avoid a
  168. // dependency on atlimpl.cpp
  169. //
  170. // We do this assignment last, so that the presence of a rowset means the
  171. // entire initialization succeeded.
  172. (rowset.p = pRowset)->AddRef();
  173. endOfRowset = false;
  174. return S_OK;
  175. }