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.

320 lines
8.3 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. memmngr.cpp
  7. memory manager for the WINS db object
  8. FILE HISTORY:
  9. Oct 13 1997 EricDav Modifed
  10. */
  11. #include "stdafx.h"
  12. #include "wins.h"
  13. #include "memmngr.h"
  14. CMemoryManager::CMemoryManager()
  15. {
  16. m_hHeap = NULL;
  17. }
  18. CMemoryManager::~CMemoryManager()
  19. {
  20. Reset();
  21. }
  22. /*!--------------------------------------------------------------------------
  23. CMemoryManager::Initialize
  24. Initializes the memory manager to free up and existing blocks
  25. and pre-allocate one block
  26. Author: EricDav, v-shubk
  27. ---------------------------------------------------------------------------*/
  28. HRESULT
  29. CMemoryManager::Initialize()
  30. {
  31. HRESULT hr = hrOK;
  32. CORg (Reset());
  33. CORg (Allocate());
  34. // create a heap for allocation of the multiple IP address blocks
  35. m_hHeap = HeapCreate(0, 4096, 0);
  36. if (m_hHeap == NULL)
  37. {
  38. Trace1("CMemoryManager::Initialize - HeapCreate failed! %d\n", GetLastError());
  39. return E_FAIL;
  40. }
  41. Error:
  42. return hr;
  43. }
  44. /*!--------------------------------------------------------------------------
  45. CMemoryManager::Reset
  46. Free's up all memory
  47. Author: EricDav, v-shubk
  48. ---------------------------------------------------------------------------*/
  49. HRESULT
  50. CMemoryManager::Reset()
  51. {
  52. // free the memory allocated
  53. for (int i = 0; i< m_BlockArray.GetSize(); i++)
  54. {
  55. ::GlobalFree(m_BlockArray.GetAt(i));
  56. }
  57. m_BlockArray.RemoveAll();
  58. if (m_hHeap)
  59. {
  60. HeapDestroy(m_hHeap);
  61. m_hHeap = NULL;
  62. }
  63. return hrOK;
  64. }
  65. /*!--------------------------------------------------------------------------
  66. CMemoryManager::Allocate
  67. Allocates one memory block
  68. Author: EricDav, v-shubk
  69. ---------------------------------------------------------------------------*/
  70. HRESULT
  71. CMemoryManager::Allocate()
  72. {
  73. HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, BLOCK_SIZE);
  74. if (hMem != NULL)
  75. {
  76. m_hrowCurrent = (LPWINSDBRECORD) hMem;
  77. m_BlockArray.Add(hMem);
  78. return hrOK;
  79. }
  80. return E_FAIL;
  81. }
  82. /*!--------------------------------------------------------------------------
  83. CMemoryManager::IsvalidHRow
  84. Verifies that the given HROW is valid
  85. Author: EricDav, v-shubk
  86. ---------------------------------------------------------------------------*/
  87. BOOL
  88. CMemoryManager::IsValidHRow(HROW hrow)
  89. {
  90. // check to see thet this HROW lies between the
  91. // limits, i.e b/n hMem and hMem + INIT_SIZE
  92. for (int i = 0; i < m_BlockArray.GetSize(); i++)
  93. {
  94. if (hrow >= (HROW)(m_BlockArray.GetAt(i)) && (hrow < (HROW)(m_BlockArray.GetAt(i)) + BLOCK_SIZE))
  95. return TRUE;
  96. }
  97. return FALSE;
  98. }
  99. /*!--------------------------------------------------------------------------
  100. CMemoryManager::AddData
  101. Copies a record into our internal store
  102. Author: EricDav, v-shubk
  103. ---------------------------------------------------------------------------*/
  104. HRESULT
  105. CMemoryManager::AddData(const WinsRecord & wRecord, LPHROW phrow)
  106. {
  107. HRESULT hr = hrOK;
  108. CSingleLock cLock(&m_cs);
  109. cLock.Lock();
  110. Assert((BYTE) wRecord.szRecordName[15] == (BYTE) wRecord.dwType);
  111. // check if for the validity fo the current
  112. // m_hrowCurrent
  113. if (!IsValidHRow((HROW) m_hrowCurrent))
  114. {
  115. Allocate();
  116. m_hrowCurrent = (LPWINSDBRECORD) (m_BlockArray.GetAt(m_BlockArray.GetSize() - 1));
  117. }
  118. WinsRecordToWinsDbRecord(m_hHeap, wRecord, m_hrowCurrent);
  119. if (phrow)
  120. *phrow = (HROW) m_hrowCurrent;
  121. // move our pointer to the next record
  122. m_hrowCurrent++;
  123. return hr;
  124. }
  125. /*!--------------------------------------------------------------------------
  126. CMemoryManager::GetData
  127. Copies a record into our internal store
  128. Author: EricDav, v-shubk
  129. ---------------------------------------------------------------------------*/
  130. HRESULT
  131. CMemoryManager::GetData(HROW hrow, LPWINSRECORD pWinsRecord)
  132. {
  133. HRESULT hr = hrOK;
  134. LPWINSDBRECORD pDbRec = (LPWINSDBRECORD) hrow;
  135. CSingleLock cLock(&m_cs);
  136. cLock.Lock();
  137. // check if for the validity fo the current
  138. // m_hrowCurrent
  139. if (!IsValidHRow(hrow))
  140. {
  141. return E_FAIL;
  142. }
  143. WinsDbRecordToWinsRecord(pDbRec, pWinsRecord);
  144. return hr;
  145. }
  146. /*!--------------------------------------------------------------------------
  147. CMemoryManager::Delete
  148. Marks a record as deleted
  149. Author: EricDav, v-shubk
  150. ---------------------------------------------------------------------------*/
  151. HRESULT
  152. CMemoryManager::Delete(HROW hrow)
  153. {
  154. HRESULT hr = hrOK;
  155. CSingleLock cLock(&m_cs);
  156. cLock.Lock();
  157. LPWINSDBRECORD pRec = (LPWINSDBRECORD) hrow;
  158. pRec->szRecordName[17] |= WINSDB_INTERNAL_DELETED;
  159. return hr;
  160. }
  161. void
  162. WinsRecordToWinsDbRecord(HANDLE hHeap, const WinsRecord & wRecord, const LPWINSDBRECORD pRec)
  163. {
  164. ZeroMemory(pRec, sizeof(WinsDBRecord));
  165. // fill in our internal struct, first the name
  166. if (IS_WINREC_LONGNAME(&wRecord))
  167. {
  168. // name is too long for our internal struct, allocate space off of our heap
  169. // this shouldn't happen very often. Only for scoped names.
  170. pRec->szRecordName[17] |= WINSDB_INTERNAL_LONG_NAME;
  171. char * pName = (char *) ::HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (wRecord.dwNameLen + 1));
  172. if (pName)
  173. {
  174. memcpy(pName, &wRecord.szRecordName[0], wRecord.dwNameLen);
  175. memcpy(&pRec->szRecordName[0], &pName, sizeof(char *));
  176. }
  177. }
  178. else
  179. {
  180. memcpy(&pRec->szRecordName[0], &wRecord.szRecordName[0], 16);
  181. }
  182. pRec->dwExpiration = (DWORD) wRecord.dwExpiration;
  183. pRec->liVersion.QuadPart = wRecord.liVersion.QuadPart;
  184. pRec->dwOwner = wRecord.dwOwner;
  185. // max length is 255, so this is OK
  186. pRec->szRecordName[19] = LOBYTE(LOWORD(wRecord.dwNameLen));
  187. BYTE bTest = HIBYTE(LOWORD(wRecord.dwState));
  188. pRec->szRecordName[20] = HIBYTE(LOWORD(wRecord.dwState));
  189. // only the low byte of the dwState field is used
  190. pRec->szRecordName[18] = (BYTE) wRecord.dwState;
  191. pRec->szRecordName[17] |= HIWORD (wRecord.dwType);
  192. // now figure out how many IP addrs there are
  193. if (wRecord.dwNoOfAddrs > 1)
  194. {
  195. Assert(hHeap);
  196. LPDWORD pdwIpAddrs = (LPDWORD) ::HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (wRecord.dwNoOfAddrs + 1) * sizeof(DWORD));
  197. if (pdwIpAddrs)
  198. {
  199. // first DWORD contains the # of addrs
  200. pdwIpAddrs[0] = wRecord.dwNoOfAddrs;
  201. for (UINT i = 0; i < wRecord.dwNoOfAddrs; i++)
  202. pdwIpAddrs[i+1] = wRecord.dwIpAdd[i];
  203. // now store our pointer off
  204. pRec->dwIpAdd = (DWORD_PTR) pdwIpAddrs;
  205. }
  206. }
  207. else
  208. {
  209. pRec->dwIpAdd = wRecord.dwIpAdd[0];
  210. }
  211. Assert((BYTE) pRec->szRecordName[16] == NULL);
  212. }
  213. void
  214. WinsDbRecordToWinsRecord(const LPWINSDBRECORD pDbRec, LPWINSRECORD pWRec)
  215. {
  216. Assert((BYTE) pDbRec->szRecordName[16] == NULL);
  217. ZeroMemory(pWRec, sizeof(WinsRecord));
  218. DWORD dwType = 0;
  219. size_t length = pDbRec->szRecordName[19] & 0x000000FF;
  220. // fill in our internal struct, name first
  221. if (IS_DBREC_LONGNAME(pDbRec))
  222. {
  223. char * pName = *((char **) pDbRec->szRecordName);
  224. memcpy(&pWRec->szRecordName[0], pName, length);
  225. dwType = (DWORD) pName[15];
  226. }
  227. else
  228. {
  229. memcpy(&pWRec->szRecordName[0], &pDbRec->szRecordName[0], 16);
  230. dwType = (DWORD) pWRec->szRecordName[15];
  231. }
  232. pWRec->dwExpiration = pDbRec->dwExpiration;
  233. pWRec->liVersion.QuadPart = pDbRec->liVersion.QuadPart;
  234. pWRec->dwOwner = pDbRec->dwOwner;
  235. pWRec->dwNameLen = length;
  236. WORD wState = MAKEWORD(pDbRec->szRecordName[18], pDbRec->szRecordName[20]);
  237. pWRec->dwState = wState;
  238. //pWRec->dwState = pDbRec->szRecordName[18];
  239. pWRec->dwType = pDbRec->szRecordName[17] & 0x03;
  240. pWRec->dwType = pWRec->dwType << 16;
  241. pWRec->dwType |= dwType;
  242. // now the ip address(es)
  243. if (pWRec->dwState & (BYTE) WINSDB_REC_MULT_ADDRS)
  244. {
  245. LPDWORD pdwIpAddrs = (LPDWORD) pDbRec->dwIpAdd;
  246. // the first DWORD is the count
  247. int nCount = pdwIpAddrs[0];
  248. for (int i = 0; i < nCount; i++)
  249. pWRec->dwIpAdd[i] = pdwIpAddrs[i+1];
  250. pWRec->dwNoOfAddrs = (DWORD) nCount;
  251. }
  252. else
  253. {
  254. pWRec->dwIpAdd[0] = (DWORD) pDbRec->dwIpAdd;
  255. pWRec->dwNoOfAddrs = 1;
  256. }
  257. }