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.

440 lines
14 KiB

  1. /*
  2. #pragma once
  3. */
  4. #ifndef _HEAP_H
  5. #define _HEAP_H
  6. #include <windows.h>
  7. #include <stdio.h>
  8. // Disable warning C4201: nonstandard extension used : nameless struct/union
  9. // Allows shims to be compiled at Warning Level 4
  10. #pragma warning ( disable : 4201 )
  11. #include <mmsystem.h>
  12. #pragma warning ( default : 4201 )
  13. #include <winerror.h>
  14. #include <shellapi.h>
  15. #include <shlobj.h>
  16. #include <ole2.h>
  17. #include <ddraw.h>
  18. #include <dsound.h>
  19. #include <commdlg.h>
  20. #include <winspool.h>
  21. #include "ShimDebug.h"
  22. /*
  23. * heap.h - structures and equates for the Windows 32-bit heap
  24. *
  25. /***LT busyblock_s - busy heap block header structure
  26. *
  27. * This structure is stored at the head of every busy (not free) heap
  28. * block.
  29. *
  30. * The bh_size field is in bytes and includes the size of the
  31. * heap header and any slop at the end of the block that might have
  32. * been included because of the heap granularity, or to keep us
  33. * from leaving a block too small to hold a free heap header.
  34. *
  35. * bh_size is also used as a forward link to the next heap block.
  36. *
  37. * The low two bits of the bh_size field are used to hold flags
  38. * (BP_FREE must be clear and HP_PREVFREE is optionally set).
  39. */
  40. struct busyheap_s {
  41. unsigned long bh_size; /* block size + flags in low 2 bits */
  42. };
  43. /*XLATOFF*/
  44. #define BH_SIGNATURE 0x4842 /* busy heap block signature (BH) */
  45. /*XLATON*/
  46. #define BH_CDWSUM 3 /* count of dwords to sum in struct */
  47. /***LT freeblock_s - free heap block header structure
  48. *
  49. * This structure is stored at the head of every free block on the
  50. * heap. In the last dword of every free heap block is a pointer
  51. * the this structure.
  52. *
  53. * The fh_size field is in bytes and includes the size of the
  54. * heap header and any slop at the end of the block that might have
  55. * been included because of the heap granularity, or to keep us
  56. * from leaving a block too small to hold a free heap header.
  57. *
  58. * fh_size is also used as a forward link to the next heap block.
  59. *
  60. * The low two bits of the fh_size field are used to hold flags
  61. * (HP_FREE must be set and HP_PREVFREE must be clear).
  62. */
  63. struct freeheap_s {
  64. unsigned long fh_size; /* block size + flags in low 2 bits */
  65. struct freeheap_s *fh_flink; /* forward link to next free block */
  66. struct freeheap_s *fh_blink; /* back link to previous free block */
  67. };
  68. /*XLATOFF*/
  69. #define FH_SIGNATURE 0x4846 /* free heap block signature (FH) */
  70. /*XLATON*/
  71. #define FH_CDWSUM 4 /* count of dwords to sum in struct */
  72. /*
  73. * Equates common to all heap blocks.
  74. *
  75. * HP_FREE and HP_PREVFREE (HP_FLAGS) are stored in the low two
  76. * bits of the fh_ and bh_size field.
  77. * The signature is stored in the high three bits of the size.
  78. */
  79. #define HP_FREE 0x00000001 /* block is free */
  80. #define HP_PREVFREE 0x00000002 /* previous block is free */
  81. #define HP_FLAGS 0x00000003 /* mask for all the flags */
  82. #define HP_SIZE 0x0ffffffc /* mask for clearing flags */
  83. #define HP_SIGBITS 0xf0000000 /* bits used for signature */
  84. #define HP_SIGNATURE 0xa0000000 /* valid value of signature */
  85. /*
  86. * Misc heap equates
  87. */
  88. #define hpGRANULARITY 4 /* granularity for heap allocations */
  89. #define hpGRANMASK (hpGRANULARITY - 1) /* for rounding */
  90. /*XLATOFF*/
  91. #define hpMINSIZE (sizeof(struct freeheap_s)+sizeof(struct freeheap_s *))
  92. /* min block size */
  93. #define hpMAXALLOC (HP_SIZE - 100) /* biggest allocatable heap block */
  94. /* overhead for a new heap segment (header plus end sentinel) */
  95. #define hpSEGOVERHEAD (sizeof(struct busyheap_s) + sizeof(struct heapseg_s))
  96. /* default reserved size of new segments added to growable heaps */
  97. #define hpCBRESERVE (4*1024*1024)
  98. /*XLATON*/
  99. /*
  100. * Exported flags for heap calls
  101. */
  102. #define HP_ZEROINIT 0x40 /* zero initialize block on HP(Re)Alloc */
  103. #define HP_MOVEABLE 0x02 /* block can be moved (HP(Re)Alloc) */
  104. #define HP_NOCOPY 0x20 /* don't copy data on HPReAlloc */
  105. #define HP_NOSERIALIZE 0x01 /* don't serialize heap access */
  106. #define HP_EXCEPT 0x04 /* generate exceptions on error */
  107. #define HP_FIXED 0x00 /* block is at a fixed address (HPAlloc) */
  108. #define HP_GROWABLE 0x40 /* heap can grow beyond cbreserve (HPInit) */
  109. /*
  110. * Note that flags above 0x80 will not be stored into the heap header in
  111. * HPInit calls because the flags field in the header is only a byte
  112. */
  113. #define HP_INITSEGMENT 0x100 /* just initialize a heap segment (HPInit) */
  114. #define HP_DECOMMIT 0x200 /* decommit pages in free block (hpFreeSub) */
  115. #define HP_GROWUP 0x400 /* waste last page of heap (HPInit) */
  116. /*XLATOFF*/
  117. /***LP hpSize - pull size field from heap header
  118. *
  119. * This routine depends on the size field being the first
  120. * dword in the header.
  121. *
  122. * ENTRY: ph - pointer to heap header
  123. * EXIT: count of bytes in block (counting header).
  124. */
  125. #define hpSize(ph) (*((unsigned long *)(ph)) & HP_SIZE)
  126. /***LP hpSetSize - set the size parameter in a heap header
  127. *
  128. * This routine depends on the size field being the first
  129. * dword in the header.
  130. *
  131. * ENTRY: ph - pointer to busy heap header
  132. * cb - count of bytes (should be rounded using hpRoundUp)
  133. * EXIT: size is set in heap header
  134. */
  135. #define hpSetSize(ph, cb) (((struct busyheap_s *)(ph))->bh_size = \
  136. ((((struct busyheap_s *)(ph))->bh_size & ~HP_SIZE) | (cb)))
  137. /* the compiler used to do a better version with this macro than the above,
  138. * but not any more
  139. #define hpSetSize2(ph, cb) *(unsigned long *)(ph) &= ~HP_SIZE; \
  140. *(unsigned long *)(ph) |= (cb);
  141. */
  142. /***LP hpSetBusySize - set the entire bh_size dword for a busy block
  143. *
  144. * This macro will set the bh_size field of the given heap header
  145. * to the given size as well as setting the HP_SIGNATURE and clearing
  146. * any HP_FREE or HP_PREVFREE bits.
  147. *
  148. * ENTRY: ph - pointer to busy heap header
  149. * cb - count of bytes (should be rounded using hpRoundUp)
  150. * EXIT: bh_size field is initialized
  151. */
  152. #define hpSetBusySize(ph, cb) ((ph)->bh_size = ((cb) | HP_SIGNATURE))
  153. /***LP hpSetFreeSize - set the entire fh_size dword for a free block
  154. *
  155. * This macro will set the fh_size field of the given heap header
  156. * to the given size as well as setting the HP_SIGNATURE and HP_FREE
  157. * and clearing HP_PREVFREE.
  158. *
  159. * ENTRY: ph - pointer to free heap header
  160. * cb - count of bytes (should be rounded using hpRoundUp)
  161. * EXIT: bh_size field is initialized
  162. */
  163. #define hpSetFreeSize(ph, cb) ((ph)->fh_size = ((cb) | HP_SIGNATURE | HP_FREE))
  164. /***LP hpIsBusySignatureValid - check a busy heap block's signature
  165. *
  166. * This macro checks the tiny signature (HP_SIGNATURE) in the bh_size
  167. * field to see if it is set properly and makes sure that the HP_FREE
  168. * bit is clear.
  169. *
  170. * ENTRY: ph - pointer to a busy heap header
  171. * EXIT: TRUE if signature is ok, else FALSE
  172. */
  173. #define hpIsBusySignatureValid(ph) \
  174. (((ph)->bh_size & (HP_SIGBITS | HP_FREE)) == HP_SIGNATURE)
  175. /***LP hpIsFreeSignatureValid - check a free heap block's signature
  176. *
  177. * This macro checks the tiny signature (HP_SIGNATURE) in the fh_size
  178. * field to see if it is set properly and makes sure that the HP_FREE
  179. * bit is also set and HP_PREVFREE is clear.
  180. *
  181. * ENTRY: ph - pointer to a free heap header
  182. * EXIT: TRUE if signature is ok, else FALSE
  183. */
  184. #define hpIsFreeSignatureValid(ph) \
  185. (((ph)->fh_size & (HP_SIGBITS | HP_FREE | HP_PREVFREE)) == \
  186. (HP_SIGNATURE | HP_FREE))
  187. #define maximum(a,b) \
  188. ( (a) > (b) ) ? (a) : (b)
  189. /***LP hpRoundUp - round up byte count to appropriate heap block size
  190. *
  191. * Heap blocks have a minimum size of hpMINSIZE and hpGRANULARITY
  192. * granularity. This macro also adds on size for the heap header.
  193. *
  194. * ENTRY: cb - count of bytes
  195. * EXIT: count rounded up to hpGANULARITY boundary
  196. */
  197. #define hpRoundUp(cb) \
  198. max(hpMINSIZE, \
  199. (((cb) + sizeof(struct busyheap_s) + hpGRANMASK) & ~hpGRANMASK))
  200. /*XLATON*/
  201. /***LK freelist_s - heap free list head
  202. */
  203. struct freelist_s {
  204. unsigned long fl_cbmax; /* max size block in this free list */
  205. struct freeheap_s fl_header; /* pseudo heap header as list head */
  206. };
  207. #define hpFREELISTHEADS 4 /* number of free list heads in heapinfo_s */
  208. /***LK heapinfo_s - per-heap information (stored at start of heap)
  209. *
  210. */
  211. struct heapinfo_s {
  212. /* These first three fields must match the fields of heapseg_s */
  213. unsigned long hi_cbreserve; /* bytes reserved for heap */
  214. struct heapseg_s *hi_psegnext; /* pointer to next heap segment*/
  215. struct freelist_s hi_freelist[hpFREELISTHEADS]; /* free list heads */
  216. struct heapinfo_s *hi_procnext; /* linked list of process heaps */
  217. CRITICAL_SECTION *hi_pcritsec; /* pointer to serialization obj*/
  218. CRITICAL_SECTION hi_critsec; /* serialize access to heap */
  219. unsigned char hi_flags; /* HP_SERIALIZE, HP_LOCKED */
  220. unsigned char hi_pad2; /* unused */
  221. unsigned short hi_signature; /* should be HI_SIGNATURE */
  222. };
  223. /*
  224. * Heap Measurement functions
  225. */
  226. #define HPMEASURE_FREE 0x8000000L
  227. #define SAMPLE_CACHE_SIZE 1024
  228. struct measure_s {
  229. char szFile[260];
  230. unsigned iCur;
  231. unsigned uSamples[SAMPLE_CACHE_SIZE];
  232. };
  233. /*XLATOFF*/
  234. #define HI_SIGNATURE 0x4948 /* heapinfo_s signature (HI) */
  235. /*XLATON*/
  236. #define HI_CDWSUM 1 /* count of dwords to sum */
  237. typedef struct heapinfo_s *HHEAP;
  238. /***LK heapseg_s - per-heap segment structure
  239. *
  240. * Growable heaps can have multiple discontiguous sections of memory
  241. * allocated to them. Each is headed by one of these structures. The
  242. * first segment is special, in that it has a full heapinfo_s structure,
  243. * but the first fields of heapinfo_s match heapseg_s, so it can be
  244. * treated as just another segment when convenient.
  245. */
  246. struct heapseg_s {
  247. unsigned long hs_cbreserve; /* bytes reserved for this segment */
  248. struct heapseg_s *hs_psegnext; /* pointer to next heap segment*/
  249. };
  250. /* XLATOFF */
  251. /* smallest possible heap */
  252. #define hpMINHEAPSIZE (sizeof(struct heapinfo_s) + hpMINSIZE + \
  253. sizeof(struct busyheap_s))
  254. /***LP hpRemove - remove item from free list
  255. *
  256. * ENTRY: pfh - pointer to free heap block to remove from list
  257. * EXIT: none
  258. */
  259. #define hpRemoveNoSum(pfh) \
  260. (pfh)->fh_flink->fh_blink = (pfh)->fh_blink; \
  261. (pfh)->fh_blink->fh_flink = (pfh)->fh_flink;
  262. #define hpRemove(pfh) hpRemoveNoSum(pfh)
  263. /***LP hpInsert - insert item onto the free list
  264. *
  265. * ENTRY: pfh - free heap block to insert onto the list
  266. * pfhprev - insert pfh after this item
  267. * EXIT: none
  268. */
  269. #define hpInsertNoSum(pfh, pfhprev) \
  270. (pfh)->fh_flink = (pfhprev)->fh_flink; \
  271. (pfh)->fh_flink->fh_blink = (pfh); \
  272. (pfh)->fh_blink = (pfhprev); \
  273. (pfhprev)->fh_flink = (pfh)
  274. #define hpInsert(pfh, pfhprev) hpInsertNoSum(pfh, pfhprev)
  275. /*
  276. * critical section macros to be used by all internal heap functions
  277. */
  278. #define hpEnterCriticalSection(hheap) EnterCriticalSection(hheap->hi_pcritsec)
  279. #define hpLeaveCriticalSection(hheap) LeaveCriticalSection(hheap->hi_pcritsec)
  280. #define hpInitializeCriticalSection(hheap) \
  281. { \
  282. hheap->hi_pcritsec = &(hheap->hi_critsec); \
  283. InitializeCriticalSection(hheap->hi_pcritsec); \
  284. }
  285. /*
  286. * Exported heap functions
  287. */
  288. /*
  289. extern HHEAP HPInit(void *hheap, void *pmem, unsigned long cbreserve,
  290. unsigned long flags);
  291. extern void * HPAlloc(HHEAP hheap, unsigned long cb,
  292. unsigned long flags);
  293. extern void * HPReAlloc(HHEAP hheap, void *pblock, unsigned long cb,
  294. unsigned long flags);
  295. */
  296. /*
  297. * Local heap functions
  298. */
  299. /*
  300. extern void hpFreeSub(HHEAP hheap, void *pblock, unsigned cb,
  301. unsigned flags);
  302. extern BOOL hpCommit(unsigned page, int npages, unsigned flags);
  303. extern unsigned hpCarve(HHEAP hheap, struct freeheap_s *pfh,
  304. unsigned cb, unsigned flags);
  305. extern unsigned hpTakeSem(HHEAP hheap, struct busyheap_s *pbh, unsigned long flags);
  306. extern void hpClearSem(HHEAP hheap, unsigned flags);
  307. */
  308. #define hpWalk(hheap) 1
  309. #define mmError(rc, string) SetLastError(rc)
  310. #define mmAssert(exp, psz)
  311. #define PAGESIZE 1024*4
  312. #define PAGEMASK 0x00000FFF /* Extract the page-relative offset*/
  313. #define ERR_OUT_OF_RANGE 2
  314. // Function prototypes
  315. extern unsigned
  316. hpCarve(HHEAP hheap, struct freeheap_s *pfh, unsigned cb, unsigned flags);
  317. extern unsigned
  318. hpTakeSem(HHEAP hheap, struct busyheap_s *pbh, unsigned long htsflags);
  319. extern void
  320. hpClearSem(HHEAP hheap, unsigned flags);
  321. extern void
  322. hpFreeSub(HHEAP hheap, struct freeheap_s *pblock, unsigned cb, unsigned flags);
  323. extern void *
  324. HPAlloc(HHEAP hheap, unsigned long cb, unsigned long flags);
  325. extern HHEAP
  326. HPInit(struct heapinfo_s *hheap,
  327. struct heapinfo_s *pmem,
  328. unsigned long cbreserve,
  329. unsigned long flags);
  330. extern HANDLE SimHeapCreate(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize);
  331. extern BOOL
  332. hpCommit( unsigned pmem,
  333. int nSize,
  334. unsigned flags
  335. );
  336. extern VOID
  337. hpDeCommit(unsigned pmem,
  338. int nSize,
  339. unsigned flags
  340. );
  341. extern LPVOID PageReserve(unsigned Size);
  342. extern VOID PageFree(LPVOID pmem);
  343. extern void * HPReAlloc(HHEAP hheap, void *pblock, unsigned long cb, unsigned long flags);
  344. extern BOOL HeapFreeInternal(HHEAP hheap, DWORD flags, LPSTR lpMem);
  345. extern BOOL SimHeapDestroy(HHEAP hHeap);
  346. extern HANDLE SIMLocalAlloc(HHEAP hHeap,UINT dwFlags, UINT dwBytes);
  347. extern HANDLE SIMLocalFree(HHEAP hHeap,HANDLE hMem);
  348. extern HANDLE SIMLocalReAlloc(HHEAP hHeap,HANDLE hMem, UINT dwBytes, UINT dwFlags);
  349. extern LPVOID SIMLocalLock(HHEAP hHeap,HANDLE hMem);
  350. extern BOOL SIMLocalUnlock(HHEAP hHeap,HANDLE hMem);
  351. extern HANDLE SIMLocalHandle(HHEAP hHeap,PVOID pMem);
  352. extern DWORD SIMHeapSize(HHEAP hheap, DWORD flags, LPSTR lpMem);
  353. extern UINT SIMLocalSize(HHEAP hHeap,HANDLE hMem);
  354. extern UINT SIMLocalFlags(HHEAP hHeap,HANDLE hMem);
  355. extern ULONG VerifyOnHeap(HHEAP hheap, PVOID p);
  356. extern BOOL SIMHeapValidate(HHEAP hheap, DWORD dwFlags, LPCVOID lpMem);
  357. extern UINT SIMHeapCompact(HHEAP hheap,DWORD dwFlags);
  358. #endif //_AH_H