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.

336 lines
7.0 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "modlist.h"
  4. BOOL
  5. CModuleList::FDumpToString (
  6. OUT PSTR pszBuf,
  7. IN OUT ULONG* pcchBuf) const
  8. {
  9. const_iterator iter;
  10. const CModule* pMod;
  11. ULONG cch;
  12. ULONG cchIn;
  13. BOOL fFirstTime;
  14. Assert (this);
  15. Assert (pcchBuf);
  16. cch = 0;
  17. cchIn = *pcchBuf;
  18. for (iter = begin(), fFirstTime = TRUE; iter != end(); iter++)
  19. {
  20. if (!fFirstTime)
  21. {
  22. cch += 2;
  23. if (pszBuf && (cch <= cchIn))
  24. {
  25. strcat (pszBuf, "->");
  26. }
  27. }
  28. else
  29. {
  30. fFirstTime = FALSE;
  31. if (pszBuf && (cch <= cchIn))
  32. {
  33. *pszBuf = 0;
  34. }
  35. }
  36. pMod = *iter;
  37. Assert (pMod);
  38. cch += strlen (pMod->m_pszFileName);
  39. if (pszBuf && (cch <= cchIn))
  40. {
  41. strcat (pszBuf, pMod->m_pszFileName);
  42. }
  43. }
  44. // If we ran out of room, erase the partial stuff we wrote.
  45. //
  46. if (pszBuf && cchIn && (cch > cchIn))
  47. {
  48. *pszBuf = 0;
  49. }
  50. *pcchBuf = cch;
  51. return cch <= cchIn;
  52. }
  53. BOOL
  54. CModuleList::FIsSameModuleListAs (
  55. IN const CModuleList* pOtherList) const
  56. {
  57. UINT unThisSize;
  58. UINT unOtherSize;
  59. UINT cb;
  60. Assert (this);
  61. Assert (pOtherList);
  62. unThisSize = this->size();
  63. unOtherSize = pOtherList->size();
  64. if ((0 == unThisSize) || (0 == unOtherSize) || (unThisSize != unOtherSize))
  65. {
  66. return FALSE;
  67. }
  68. // Sizes are non-zero and equal. Compare the data.
  69. //
  70. cb = (BYTE*)(end()) - (BYTE*)(begin());
  71. Assert (cb == unThisSize * sizeof(CModule*));
  72. return (0 == memcmp (
  73. (BYTE*)(this->begin()),
  74. (BYTE*)(pOtherList->begin()),
  75. cb));
  76. }
  77. VOID
  78. CModuleList::GrowBufferIfNeeded ()
  79. {
  80. if (m_Granularity && (size() == capacity()))
  81. {
  82. //fprintf(stderr, "growing module list buffer\n");
  83. __try
  84. {
  85. reserve (size() + m_Granularity);
  86. }
  87. __except(EXCEPTION_EXECUTE_HANDLER)
  88. {
  89. ;
  90. }
  91. }
  92. }
  93. HRESULT
  94. CModuleList::HrInsertModule (
  95. IN const CModule* pMod,
  96. IN DWORD dwFlags /* INS_FLAGS */)
  97. {
  98. HRESULT hr;
  99. Assert (this);
  100. Assert (pMod);
  101. Assert (dwFlags);
  102. Assert (dwFlags & (INS_ASSERT_IF_DUP | INS_IGNORE_IF_DUP));
  103. Assert (!(dwFlags & (INS_SORTED | INS_NON_SORTED)));
  104. Assert (dwFlags & (INS_APPEND | INS_INSERT));
  105. if (FLinearFindModuleByPointer (pMod))
  106. {
  107. Assert (dwFlags & INS_IGNORE_IF_DUP);
  108. return S_OK;
  109. }
  110. GrowBufferIfNeeded ();
  111. __try
  112. {
  113. iterator InsertPosition = begin();
  114. if (dwFlags & INS_APPEND)
  115. {
  116. InsertPosition = end();
  117. }
  118. insert (InsertPosition, (CModule*)pMod);
  119. hr = S_OK;
  120. }
  121. __except(EXCEPTION_EXECUTE_HANDLER)
  122. {
  123. hr = E_OUTOFMEMORY;
  124. }
  125. return hr;
  126. }
  127. HRESULT
  128. CModuleList::HrInsertNewModule (
  129. IN PCSTR pszFileName,
  130. IN ULONG cbFileSize,
  131. IN DWORD dwFlags, /* INS_FLAGS */
  132. OUT CModule** ppMod)
  133. {
  134. HRESULT hr;
  135. iterator InsertPosition = NULL;
  136. CModule* pMod;
  137. CHAR szLowerCaseFileName [MAX_PATH];
  138. Assert (dwFlags);
  139. Assert (dwFlags & (INS_ASSERT_IF_DUP | INS_IGNORE_IF_DUP));
  140. Assert (dwFlags & INS_SORTED);
  141. Assert (!(dwFlags & (INS_APPEND | INS_INSERT)));
  142. GrowBufferIfNeeded ();
  143. hr = S_OK;
  144. strcpy (szLowerCaseFileName, pszFileName);
  145. _strlwr (szLowerCaseFileName);
  146. pMod = PBinarySearchModuleByName (szLowerCaseFileName, &InsertPosition);
  147. if (!pMod)
  148. {
  149. Assert (!PLinearFindModuleByName (szLowerCaseFileName));
  150. hr = CModule::HrCreateInstance (szLowerCaseFileName, cbFileSize, &pMod);
  151. if (S_OK == hr)
  152. {
  153. if (dwFlags & INS_NON_SORTED)
  154. {
  155. InsertPosition = (dwFlags & INS_APPEND) ? end() : begin();
  156. }
  157. __try
  158. {
  159. Assert (InsertPosition);
  160. insert (InsertPosition, pMod);
  161. Assert (S_OK == hr);
  162. DbgVerifySorted();
  163. }
  164. __except(EXCEPTION_EXECUTE_HANDLER)
  165. {
  166. hr = E_OUTOFMEMORY;
  167. delete pMod;
  168. pMod = NULL;
  169. }
  170. }
  171. }
  172. else
  173. {
  174. Assert (dwFlags & INS_IGNORE_IF_DUP);
  175. // Update the file size of the module if we didn't have it
  176. // when it was first created.
  177. //
  178. if (0 == pMod->m_cbFileSize)
  179. {
  180. pMod->m_cbFileSize = cbFileSize;
  181. }
  182. }
  183. *ppMod = pMod;
  184. return hr;
  185. }
  186. CModule*
  187. CModuleList::PBinarySearchModuleByName (
  188. IN PCSTR pszFileName,
  189. OUT CModuleList::iterator* pInsertPosition OPTIONAL)
  190. {
  191. // Find the module using a binary search.
  192. //
  193. if (size())
  194. {
  195. LONG Lo;
  196. LONG Hi;
  197. LONG Mid;
  198. INT Result;
  199. CModule* pScan;
  200. Lo = 0;
  201. Hi = size() - 1;
  202. while (Hi >= Lo)
  203. {
  204. Mid = (Lo + Hi) / 2;
  205. pScan = at(Mid);
  206. Result = strcmp (pszFileName, pScan->m_pszFileName);
  207. if (Result < 0)
  208. {
  209. Hi = Mid - 1;
  210. }
  211. else if (Result > 0)
  212. {
  213. Lo = Mid + 1;
  214. }
  215. else
  216. {
  217. return pScan;
  218. }
  219. }
  220. // If we make it to here, the module was not found.
  221. //
  222. if (pInsertPosition)
  223. {
  224. *pInsertPosition = begin() + Lo;
  225. Assert (*pInsertPosition >= begin());
  226. Assert (*pInsertPosition <= end());
  227. }
  228. }
  229. else if (pInsertPosition)
  230. {
  231. // Empty collection. Insert position is at the beginning.
  232. //
  233. *pInsertPosition = begin();
  234. }
  235. return NULL;
  236. }
  237. CModule*
  238. CModuleList::PLinearFindModuleByName (
  239. IN PCSTR pszFileName)
  240. {
  241. const_iterator iter;
  242. CModule* pScan;
  243. for (iter = begin(); iter != end(); iter++)
  244. {
  245. pScan = *iter;
  246. Assert (pScan);
  247. if (0 == strcmp(pszFileName, pScan->m_pszFileName))
  248. {
  249. return pScan;
  250. }
  251. }
  252. return NULL;
  253. }
  254. CModule*
  255. CModuleList::RemoveLastModule ()
  256. {
  257. CModule* pMod = NULL;
  258. if (size() > 0)
  259. {
  260. pMod = back();
  261. AssertH(pMod);
  262. pop_back();
  263. }
  264. return pMod;
  265. }
  266. #if DBG
  267. VOID
  268. CModuleList::DbgVerifySorted ()
  269. {
  270. const_iterator iter;
  271. CModule* pScan;
  272. CModule* pPrev = NULL;
  273. if (size() > 1)
  274. {
  275. for (pPrev = *begin(), iter = begin() + 1; iter != end(); iter++)
  276. {
  277. pScan = *iter;
  278. Assert (pScan);
  279. Assert (strcmp(pPrev->m_pszFileName, pScan->m_pszFileName) < 0);
  280. pPrev = pScan;
  281. }
  282. }
  283. }
  284. #endif