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.

246 lines
6.4 KiB

  1. /**************************************************************************
  2. * GLOBAL.C
  3. *
  4. * Routines used to walk the global heap.
  5. *
  6. **************************************************************************/
  7. #include "toolpriv.h"
  8. #include <newexe.h>
  9. #include <string.h>
  10. /* GlobalInfo
  11. * Reports information about the state of the global heap,
  12. * specifically, the number of elements that will be returned by
  13. * a global heap walk.
  14. */
  15. BOOL TOOLHELPAPI GlobalInfo(
  16. GLOBALINFO FAR *lpGlobalInfo)
  17. {
  18. /* Check the structure size and verify proper installation */
  19. if (!wLibInstalled || lpGlobalInfo->dwSize != sizeof (GLOBALINFO))
  20. return FALSE;
  21. /* Get the item counts */
  22. if (wTHFlags & TH_KERNEL_386)
  23. {
  24. lpGlobalInfo->wcItems = Walk386Count(GLOBAL_ALL);
  25. lpGlobalInfo->wcItemsFree = Walk386Count(GLOBAL_FREE);
  26. lpGlobalInfo->wcItemsLRU = Walk386Count(GLOBAL_LRU);
  27. }
  28. else
  29. {
  30. lpGlobalInfo->wcItems = Walk286Count(GLOBAL_ALL);
  31. lpGlobalInfo->wcItemsFree = Walk286Count(GLOBAL_FREE);
  32. lpGlobalInfo->wcItemsLRU = Walk286Count(GLOBAL_LRU);
  33. }
  34. return TRUE;
  35. }
  36. /* GlobalFirst
  37. * Finds the first element in the global heap. This is modified by
  38. * wFlags which modifies which list (GLOBAL_ALL, GLOBAL_FREE,
  39. * GLOBAL_LRU) should be walked
  40. */
  41. BOOL TOOLHELPAPI GlobalFirst(
  42. GLOBALENTRY FAR *lpGlobal,
  43. WORD wFlags)
  44. {
  45. DWORD dwFirst;
  46. /* Check the structure size and verify proper installation */
  47. if (!wLibInstalled || !lpGlobal ||
  48. lpGlobal->dwSize != sizeof (GLOBALENTRY))
  49. return FALSE;
  50. /* Call the appropriate low-level routine to find the first block */
  51. if (wTHFlags & TH_KERNEL_386)
  52. {
  53. /* Get the first item. Return false if no items in this list */
  54. if (!(dwFirst = Walk386First(wFlags)))
  55. return FALSE;
  56. /* Return information about this first item */
  57. Walk386(dwFirst, lpGlobal, wFlags);
  58. }
  59. else
  60. {
  61. /* Get the first item. Return false if no items in this list */
  62. if (!(dwFirst = Walk286First(wFlags)))
  63. return FALSE;
  64. /* Return information about this first item */
  65. Walk286(dwFirst, lpGlobal, wFlags);
  66. }
  67. /* Guess at the type of the object */
  68. HelperGlobalType(lpGlobal);
  69. return TRUE;
  70. }
  71. /* GlobalNext
  72. * Returns the next item in the chain pointed to by lpGlobal and
  73. * in the list indicated by wFlags (same choices as for GlobalFirst().
  74. */
  75. BOOL TOOLHELPAPI GlobalNext(
  76. GLOBALENTRY FAR *lpGlobal,
  77. WORD wFlags)
  78. {
  79. DWORD dwNext;
  80. /* Check the structure size and verify proper installation */
  81. if (!wLibInstalled || !lpGlobal ||
  82. lpGlobal->dwSize != sizeof (GLOBALENTRY))
  83. return FALSE;
  84. /* Check to see if we're at the end of the list */
  85. dwNext = wFlags & 3 ? lpGlobal->dwNextAlt : lpGlobal->dwNext;
  86. if (!dwNext)
  87. return FALSE;
  88. /* If we're using the 386 kernel, call the 386 heap walk routine with
  89. * a pointer to the appropriate heap item
  90. * (Note that this depends on GLOBAL_ALL being zero)
  91. */
  92. if (wTHFlags & TH_KERNEL_386)
  93. Walk386(dwNext, lpGlobal, wFlags);
  94. else
  95. Walk286(dwNext, lpGlobal, wFlags);
  96. /* Guess at the type of the object */
  97. HelperGlobalType(lpGlobal);
  98. return TRUE;
  99. }
  100. /* GlobalEntryHandle
  101. * Used to find information about a global heap entry. Information
  102. * about this entry is returned in the structure.
  103. */
  104. BOOL TOOLHELPAPI GlobalEntryHandle(
  105. GLOBALENTRY FAR *lpGlobal,
  106. HANDLE hItem)
  107. {
  108. DWORD dwBlock;
  109. /* Check the structure size and verify proper installation */
  110. if (!wLibInstalled || !lpGlobal ||
  111. lpGlobal->dwSize != sizeof (GLOBALENTRY))
  112. return FALSE;
  113. /* Make sure this is a valid block */
  114. if (wTHFlags & TH_KERNEL_386)
  115. {
  116. if (!(dwBlock = Walk386Handle(hItem)))
  117. return FALSE;
  118. }
  119. else
  120. {
  121. if (!(dwBlock = Walk286Handle(hItem)))
  122. return FALSE;
  123. }
  124. /* Return information about this item */
  125. if (wTHFlags & TH_KERNEL_386)
  126. Walk386(dwBlock, lpGlobal, GLOBAL_ALL);
  127. else
  128. Walk286(dwBlock, lpGlobal, GLOBAL_ALL);
  129. /* Guess at the type of the object */
  130. HelperGlobalType(lpGlobal);
  131. return TRUE;
  132. }
  133. /* GlobalEntryModule
  134. * Returns global information about the block with the given module
  135. * handle and segment number.
  136. */
  137. BOOL TOOLHELPAPI GlobalEntryModule(
  138. GLOBALENTRY FAR *lpGlobal,
  139. HANDLE hModule,
  140. WORD wSeg)
  141. {
  142. struct new_exe FAR *lpNewExe;
  143. struct new_seg1 FAR *lpSeg;
  144. DWORD dwBlock;
  145. /* Check the structure size and verify proper installation */
  146. if (!wLibInstalled || !lpGlobal ||
  147. lpGlobal->dwSize != sizeof (GLOBALENTRY))
  148. return FALSE;
  149. /* Grunge in the module database to find the proper selector. Start
  150. * by first verifying the module database pointer
  151. */
  152. if (!HelperVerifySeg(hModule, sizeof (struct new_exe)))
  153. return FALSE;
  154. /* Get a pointer to the module database */
  155. lpNewExe = MAKEFARPTR(hModule, 0);
  156. /* Make sure this is a module database */
  157. if (lpNewExe->ne_magic != NEMAGIC)
  158. return FALSE;
  159. /* See if the number requested is past the end of the segment table.
  160. * Note that the first segment is segment 1.
  161. */
  162. --wSeg;
  163. if (lpNewExe->ne_cseg <= wSeg)
  164. return FALSE;
  165. /* Get a pointer to the segment table */
  166. lpSeg = MAKEFARPTR(hModule, lpNewExe->ne_segtab);
  167. /* Jump to the right spot in the segment table */
  168. lpSeg += wSeg;
  169. /* Make sure this is a valid block and get its arena pointer */
  170. if (wTHFlags & TH_KERNEL_386)
  171. {
  172. if (!(dwBlock = Walk386Handle(lpSeg->ns_handle)))
  173. return FALSE;
  174. }
  175. else
  176. {
  177. if (!(dwBlock = Walk286Handle(lpSeg->ns_handle)))
  178. return FALSE;
  179. }
  180. /* Return information about this item */
  181. if (wTHFlags & TH_KERNEL_386)
  182. Walk386(dwBlock, lpGlobal, GLOBAL_ALL);
  183. else
  184. Walk286(dwBlock, lpGlobal, GLOBAL_ALL);
  185. /* Guess at the type of the object */
  186. HelperGlobalType(lpGlobal);
  187. /* If we've gotten to here, it must be OK */
  188. return TRUE;
  189. }
  190. /* GlobalHandleToSel
  191. * Provides a generic method of converting a handle to a selector.
  192. * This works across Windows versions as well as working when the
  193. * value is already a selector.
  194. */
  195. WORD TOOLHELPAPI GlobalHandleToSel(
  196. HANDLE hMem)
  197. {
  198. return HelperHandleToSel(hMem);
  199. }