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.

199 lines
4.3 KiB

  1. // memmgr.c
  2. //
  3. // This file contains definitions for the memory management.
  4. // Implementation details may change so beware of relying on internal details.
  5. //
  6. #include "private.h"
  7. #include "memmgr.h"
  8. #ifdef DEBUG
  9. int cAllocMem = 0; // Amount of memory alloced
  10. int cAlloc = 0; // Count of allocs outstanding
  11. int cAllocMaxMem = 0; // Max amount of memory ever alloced.
  12. #endif
  13. #ifdef DEBUG
  14. int gFailure = 0;
  15. #endif
  16. /******************************Public*Routine******************************\
  17. * ExternAlloc
  18. *
  19. * This guy keeps the size in the first long so we can fake a realloc. Lot's
  20. * of debug checking for heap overwrites.
  21. *
  22. * History:
  23. * 19-Nov-1996 -by- Patrick Haluptzok patrickh
  24. * Wrote it.
  25. \**************************************************************************/
  26. void *ExternAlloc(DWORD cb)
  27. {
  28. long *pl;
  29. DWORD cbAlloc;
  30. #ifdef DEBUG
  31. #ifndef WINCE
  32. //
  33. // If gFailure is 0 nothing happens, if it's non-zero we
  34. // fail 1 in gFailure allocations.
  35. //
  36. if (gFailure)
  37. {
  38. if (((rand() * gFailure) / (RAND_MAX + 1)) == 0)
  39. {
  40. return (void *) NULL;
  41. }
  42. }
  43. #endif
  44. #endif
  45. // Since we can't use realloc on WINCE, we need to save the original size for memcpy
  46. // in our own realloc function.
  47. cbAlloc = cb + 4;
  48. #ifdef DEBUG
  49. cbAlloc += 3; // round it up to DWORD boundary
  50. cbAlloc &= ~3;
  51. cbAlloc += 8; // write size at begining and overwrite detector at begining and end
  52. #endif
  53. pl = (long *) malloc(cbAlloc);
  54. if (pl == (long *) NULL)
  55. return pl;
  56. // Stamp this baby full of invalid bytes so code that relies on 0's in it are sniffed out.
  57. #ifdef DEBUG
  58. memset(pl,0xff,cbAlloc);
  59. #endif
  60. // OK, tuck the object size away at the begining
  61. *(pl++) = cb;
  62. #ifdef DEBUG
  63. *(pl++) = 0xDEADBEEF;
  64. pl[(cbAlloc / 4) - 3] = 0xDEADBEEF;
  65. cAlloc++;
  66. cAllocMem += cb;
  67. if (cAllocMem > cAllocMaxMem)
  68. {
  69. TCHAR szDebug[128];
  70. cAllocMaxMem = cAllocMem;
  71. wsprintf(szDebug, TEXT("cAllocMaxMem = %d \r\n"), cAllocMaxMem);
  72. OutputDebugString(szDebug);
  73. }
  74. #endif
  75. return pl;
  76. }
  77. /******************************Public*Routine******************************\
  78. * ExternRealloc
  79. *
  80. * Well this not good but we want the same exact code on NT and WINCE and
  81. * we can't find a way to use the flags and have Realloc work the same on
  82. * both. Realloc is a very infrequent event so this work for us.
  83. *
  84. * History:
  85. * 19-Nov-1996 -by- Patrick Haluptzok patrickh
  86. * Wrote it.
  87. \**************************************************************************/
  88. void *ExternRealloc(void *pv, DWORD cbNew)
  89. {
  90. void *pvNew = ExternAlloc(cbNew);
  91. if (pv && pvNew)
  92. {
  93. long *pl;
  94. DWORD cb;
  95. pl = (long *) pv;
  96. #ifdef DEBUG
  97. pl--;
  98. #endif
  99. cb = (DWORD) *(--pl);
  100. memcpy(pvNew, pv, min(cbNew, cb));
  101. ExternFree(pv);
  102. }
  103. return pvNew;
  104. }
  105. /******************************Public*Routine******************************\
  106. * ExternFree
  107. *
  108. * Free up the memory, in debug mode check for heap corruption !
  109. *
  110. * History:
  111. * 19-Nov-1996 -by- Patrick Haluptzok patrickh
  112. * Wrote it.
  113. \**************************************************************************/
  114. void ExternFree(void *pv)
  115. {
  116. long *pl;
  117. // We now allow freeing of null pointers
  118. if (pv == (void *) NULL)
  119. return;
  120. pl = (long *) pv;
  121. pl--;
  122. #ifdef DEBUG
  123. {
  124. int cbAlloc;
  125. // Check nothing has been stepped on.
  126. pl--;
  127. cbAlloc = *pl;
  128. cAllocMem -= cbAlloc;
  129. cbAlloc = (cbAlloc + 11) & ~3;
  130. cAlloc--;
  131. }
  132. #endif
  133. free(pl);
  134. }
  135. char *Externstrdup( const char *strSource )
  136. {
  137. int nLen = 0;
  138. char* pszOut = NULL;
  139. // fail immediately on a null pointer
  140. if (NULL == strSource)
  141. return NULL;
  142. // get the length of the ansi string
  143. nLen = strlen(strSource) * sizeof(char);
  144. // fail on a 0 length string
  145. // @todo(petewil) - is this right, or return 0 length string instead?
  146. if (0 == nLen)
  147. return NULL;
  148. // allow room for a trailing null
  149. nLen += sizeof(char);
  150. // allocate space for the string
  151. pszOut = (char*)ExternAlloc(nLen);
  152. if (NULL == pszOut)
  153. return NULL;
  154. // copy the string into the buffer provided
  155. StringCchCopyA(pszOut, nLen, strSource);
  156. return pszOut;
  157. }