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.

521 lines
12 KiB

  1. /*-----------------------------------------------------------------------------
  2. * Copyright (C) Microsoft Corporation, 1995 - 1996.
  3. * All rights reserved.
  4. *
  5. * Snipped from SChannel sources
  6. *
  7. * 1/23/96
  8. *----------------------------------------------------------------------------*/
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <windows.h>
  13. #include <debug.h>
  14. DWORD g_dwEventLogging=0;
  15. typedef LONG HRESULT;
  16. #include "pstdef.h"
  17. /*----------------------------------------------------------------------------*/
  18. /* NOTE: This file not compiled for retail builds */
  19. /*----------------------------------------------------------------------------*/
  20. #if DBG
  21. #ifdef HEAPDUMP
  22. #include <winbasep.h>
  23. #endif
  24. #define WINDEBUG
  25. #ifndef min
  26. #define min(x,y) ((x)<(y)?(x):(y))
  27. #endif
  28. DWORD g_dwInfoLevel = SS_LOG_WARNING | SS_LOG_ERROR;
  29. DWORD SSTraceIndent = 0;
  30. #define MAX_DEBUG_BUFFER 2048
  31. // This function simply outputs information to the debugging log file handle.
  32. void
  33. SSDebugOutput(char *szOutString)
  34. {
  35. OutputDebugStringA(szOutString);
  36. }
  37. void
  38. DbgDumpHexString(const unsigned char *String, DWORD cbString)
  39. {
  40. unsigned int i;
  41. for (i = 0; i < cbString; i++)
  42. {
  43. int j;
  44. char *pch;
  45. char ach[9];
  46. pch = &ach[wsprintf(ach, "%2.2x", String[i])];
  47. SS_ASSERT(pch - ach <= sizeof(ach) - 4);
  48. if ((i & 1) == 1)
  49. {
  50. *pch++ = ' ';
  51. }
  52. if ((i & 7) == 7)
  53. {
  54. *pch++ = ' ';
  55. }
  56. if ((i & 15) == 15)
  57. {
  58. *pch++ = '\n';
  59. }
  60. *pch = '\0';
  61. SSDebugOutput(ach);
  62. }
  63. }
  64. char *aszSSDebugLevel[] =
  65. {
  66. "Error ",
  67. "Warning",
  68. "Trace ",
  69. "Mem ",
  70. "Result "
  71. };
  72. void
  73. SSDebugLog(long Mask, const char *Format, ...)
  74. {
  75. va_list ArgList;
  76. int Level = 0;
  77. int PrefixSize = 0;
  78. int iOut;
  79. char szOutString[MAX_DEBUG_BUFFER];
  80. long OriginalMask = Mask;
  81. if (Mask & g_dwInfoLevel)
  82. {
  83. while (!(Mask & 1))
  84. {
  85. Level++;
  86. Mask >>= 1;
  87. }
  88. if (Level >= sizeof(aszSSDebugLevel) / sizeof(char *))
  89. {
  90. Level = sizeof(aszSSDebugLevel) / sizeof(char *) - 1;
  91. }
  92. // Make the prefix first: "Process.Thread> GINA-XXX"
  93. iOut = wsprintf(
  94. szOutString,
  95. "%3d.%3d> %s: ",
  96. GetCurrentProcessId(),
  97. GetCurrentThreadId(),
  98. aszSSDebugLevel[Level]);
  99. PrefixSize = min(60, SSTraceIndent * 3);
  100. FillMemory(szOutString+iOut, PrefixSize, ' ');
  101. PrefixSize += iOut;
  102. szOutString[PrefixSize] = '\0';
  103. va_start(ArgList, Format);
  104. if (wvsprintf(&szOutString[PrefixSize], Format, ArgList) < 0)
  105. {
  106. static char szOverFlow[] = "\n<256 byte OVERFLOW!>\n";
  107. // Less than zero indicates that the string would not fit into the
  108. // buffer. Output a special message indicating overflow.
  109. lstrcpy(
  110. &szOutString[sizeof(szOutString) - sizeof(szOverFlow)],
  111. szOverFlow);
  112. }
  113. va_end(ArgList);
  114. SSDebugOutput(szOutString);
  115. }
  116. }
  117. LPSTR SzErrorCase(long err)
  118. {
  119. char *szName = "Unknown";
  120. switch(err)
  121. {
  122. case PST_E_OK: szName = "PST_OK"; break;
  123. case PST_E_FAIL: szName = "PST_FAIL"; break;
  124. case PST_E_PROV_DLL_NOT_FOUND: szName = "PST_PROV_DLL_NOT_FOUND"; break;
  125. case PST_E_INVALID_HANDLE: szName = "PST_INVALID_HANDLE"; break;
  126. case PST_E_TYPE_EXISTS: szName = "PST_TYPE_EXISTS"; break;
  127. case PST_E_TYPE_NO_EXISTS: szName = "PST_TYPE_NO_EXISTS"; break;
  128. case PST_E_INVALID_RULESET: szName = "PST_INVALID_RULESET"; break;
  129. case PST_E_NO_PERMISSIONS: szName = "PST_NO_PERMISSIONS"; break;
  130. case PST_E_STORAGE_ERROR: szName = "PST_STORAGE_ERROR"; break;
  131. case PST_E_CALLER_NOT_VERIFIED: szName = "PST_CALLER_NOT_VERIFIED"; break;
  132. case PST_E_WRONG_PASSWORD: szName = "PST_WRONG_PASSWORD"; break;
  133. case PST_E_DISK_IMAGE_MISMATCH: szName = "PST_DISK_IMAGE_MISMATCH"; break;
  134. case PST_E_MEMORY_IMAGE_MISMATCH: szName = "PST_MEMORY_IMAGE_MISMATCH"; break;
  135. case PST_E_UNKNOWN_EXCEPTION: szName = "PST_UNKNOWN_EXCEPTION"; break;
  136. case PST_E_NYI: szName = "PST_NYI"; break;
  137. }
  138. return szName;
  139. }
  140. long
  141. SSLogErrorCode(
  142. long err,
  143. const char *szFile,
  144. long lLine)
  145. {
  146. LPSTR szName;
  147. szName = SzErrorCase(err);
  148. SSDebugLog(SS_LOG_RES, "Result: %s (0x%lx) - %s, Line %d\n", szName, err, szFile, lLine);
  149. return err;
  150. }
  151. #pragma warning(disable:4206) /* Disable the empty translation unit */
  152. /* warning/error */
  153. void
  154. SSAssert(
  155. void * FailedAssertion,
  156. void * FileName,
  157. unsigned long LineNumber,
  158. char * Message)
  159. {
  160. SSDebugLog(SS_LOG_ERROR,
  161. "Assertion FAILED, %s, %s : %d\n",
  162. FailedAssertion,
  163. FileName,
  164. LineNumber);
  165. DebugBreak();
  166. }
  167. // NOTE: heap dumping reqs winbasep.h, generated by
  168. // windows build. Therefore, heap dumping unsupported
  169. // in this build.
  170. // Get winbasep.h and define HEAPDUMP to dump heap.
  171. int HeapFlags = 0x0; // no trace
  172. //int HeapFlags = 0x2; // output window trace
  173. VOID
  174. DumpHeapState(char *pszMsg)
  175. {
  176. #ifdef HEAPDUMP
  177. DWORD dwWritten;
  178. char szOutString[256];
  179. if (HeapFlags & 2)
  180. {
  181. HANDLE BaseHeap = RtlProcessHeap();
  182. HEAP_SUMMARY HeapSum;
  183. wsprintf(szOutString, "%s: HeapSummary(%p): ", pszMsg, BaseHeap);
  184. HeapSum.cb = sizeof(HeapSum);
  185. if (!HeapSummary(BaseHeap, 0, &HeapSum))
  186. {
  187. wsprintf(
  188. &szOutString[lstrlen(szOutString)],
  189. "FAILED: %u\n",
  190. GetLastError());
  191. }
  192. else
  193. {
  194. wsprintf(
  195. &szOutString[lstrlen(szOutString)],
  196. "Allocated=%x Committed=%x\n",
  197. HeapSum.cbAllocated,
  198. HeapSum.cbCommitted);
  199. }
  200. SSDebugOutput(szOutString);
  201. }
  202. #endif // HEAPDUMP
  203. }
  204. VOID
  205. CaptureStackBackTrace(
  206. EXCEPTION_POINTERS *pep,
  207. ULONG cSkip,
  208. ULONG cFrames,
  209. ULONG *aeip)
  210. {
  211. FillMemory(aeip, cFrames * sizeof(aeip[0]), 0);
  212. #if i386 == 1
  213. {
  214. ULONG ieip, *pebp;
  215. ULONG *pebpMax;
  216. ULONG *pebpMin;
  217. if (pep == NULL)
  218. {
  219. ieip = 0;
  220. cSkip++; // always skip current frame
  221. pebp = ((ULONG *) &pep) - 2;
  222. }
  223. else
  224. {
  225. ieip = 1;
  226. SS_ASSERT(cSkip == 0);
  227. aeip[0] = pep->ContextRecord->Eip;
  228. pebp = (ULONG *) pep->ContextRecord->Ebp;
  229. }
  230. pebpMin = (ULONG *) &pep - 3; // start below current frame
  231. pebpMax = pebpMin + 16*1024/sizeof(ULONG);
  232. if (pebp >= pebpMin && pebp < pebpMax)
  233. {
  234. // __try
  235. {
  236. for ( ; ieip < cSkip + cFrames; ieip++)
  237. {
  238. ULONG *pebpNext;
  239. if (ieip >= cSkip)
  240. {
  241. aeip[ieip - cSkip] = *(pebp + 1); // save an eip
  242. }
  243. pebpNext = (ULONG *) *pebp;
  244. if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1)
  245. {
  246. break;
  247. }
  248. pebp = pebpNext;
  249. }
  250. }
  251. // __except(EXCEPTION_EXECUTE_HANDLER)
  252. {
  253. }
  254. }
  255. }
  256. #endif // i386 == 1
  257. }
  258. ////////////////////////////////////////////////////////
  259. // debug mem routines
  260. #define CMEMMAX 500
  261. #define CEIP 6
  262. int cMemAlloc;
  263. int cMemAlloc2;
  264. ULONG cbMemTotal;
  265. ULONG cbMemTotal2;
  266. typedef struct _MEM {
  267. VOID *pv;
  268. ULONG cb;
  269. ULONG aeip[CEIP];
  270. } MEM;
  271. MEM amem[CMEMMAX];
  272. VOID *
  273. SSAlloc(DWORD cb)
  274. {
  275. VOID *pv;
  276. int i;
  277. char szOutString[256];
  278. int iRecorded = -1;
  279. MEM mem;
  280. DumpHeapState("Before Alloc");
  281. if (HeapFlags & 2)
  282. {
  283. CaptureStackBackTrace(NULL, 1, CEIP, mem.aeip);
  284. wsprintf(szOutString, "AllocMem(%x bytes): ", cb);
  285. cMemAlloc2++;
  286. cbMemTotal2 += cb;
  287. mem.cb = cb;
  288. }
  289. pv = LocalAlloc(LMEM_FIXED, cb);
  290. if (HeapFlags & 2)
  291. {
  292. mem.pv = pv;
  293. if (pv != NULL)
  294. {
  295. for (i = 0; i < CMEMMAX; i++)
  296. {
  297. if (amem[i].pv == pv)
  298. {
  299. char szOutString2[256];
  300. wsprintf(
  301. szOutString2,
  302. "FreeDup(%p) (%x bytes) from %x %x %x %x %x %x (%d)\n",
  303. pv,
  304. amem[i].cb,
  305. amem[i].aeip[0],
  306. amem[i].aeip[1],
  307. amem[i].aeip[2],
  308. amem[i].aeip[3],
  309. amem[i].aeip[4],
  310. amem[i].aeip[5],
  311. i);
  312. SSDebugOutput(szOutString2);
  313. cMemAlloc--;
  314. cbMemTotal -= amem[i].cb;
  315. amem[i].pv = NULL;
  316. }
  317. if (amem[i].pv == NULL && iRecorded == -1)
  318. {
  319. amem[i] = mem;
  320. cMemAlloc++;
  321. cbMemTotal += cb;
  322. iRecorded = i;
  323. }
  324. }
  325. }
  326. else
  327. {
  328. lstrcat(szOutString, "FAILED: ");
  329. }
  330. wsprintf(
  331. &szOutString[lstrlen(szOutString)],
  332. "0x%p from %x %x %x %x %x %x (%d)\n",
  333. mem.pv,
  334. mem.aeip[0],
  335. mem.aeip[1],
  336. mem.aeip[2],
  337. mem.aeip[3],
  338. mem.aeip[4],
  339. mem.aeip[5],
  340. iRecorded);
  341. SSDebugOutput(szOutString);
  342. }
  343. DumpHeapState("After Alloc");
  344. return(pv);
  345. }
  346. VOID *
  347. SSReAlloc(VOID *pv, DWORD cb)
  348. {
  349. void* pTemp;
  350. pTemp = LocalReAlloc(pv, cb, LMEM_MOVEABLE); // allow realloc to move this memory
  351. if (pTemp == NULL)
  352. {
  353. CHAR sz[50];
  354. wsprintf(sz, "ReAlloc Failed! error %d\n", GetLastError());
  355. SSDebugOutput(sz);
  356. }
  357. else
  358. {
  359. if (pv != pTemp)
  360. SSDebugOutput("Performance: ReAlloc forced to move memory!\n");
  361. }
  362. return pTemp;
  363. }
  364. VOID
  365. SSFree(VOID *pv)
  366. {
  367. int i;
  368. char szOutString[256];
  369. DumpHeapState("Before Free");
  370. if (HeapFlags & 2)
  371. {
  372. cMemAlloc2--;
  373. wsprintf(szOutString, "FreeMem(%p)", pv);
  374. for (i = 0; i < CMEMMAX; i++)
  375. {
  376. if (pv == amem[i].pv)
  377. {
  378. cMemAlloc--;
  379. cbMemTotal -= amem[i].cb;
  380. amem[i].pv = NULL;
  381. wsprintf(
  382. &szOutString[lstrlen(szOutString)],
  383. " (%x bytes) from %x %x %x %x %x %x (%d)",
  384. amem[i].cb,
  385. amem[i].aeip[0],
  386. amem[i].aeip[1],
  387. amem[i].aeip[2],
  388. amem[i].aeip[3],
  389. amem[i].aeip[4],
  390. amem[i].aeip[5],
  391. i);
  392. break;
  393. }
  394. }
  395. }
  396. LocalFree(pv);
  397. if (HeapFlags & 2)
  398. {
  399. lstrcat(szOutString, "\n");
  400. SSDebugOutput(szOutString);
  401. }
  402. DumpHeapState("After Free");
  403. }
  404. SIZE_T
  405. SSSize(HLOCAL hMem)
  406. {
  407. return LocalSize( hMem );
  408. }
  409. #endif /* DBG */
  410. /*----------------------------------------------------------------------------*/
  411. /* NOTE: This file not compiled for retail builds */
  412. /*----------------------------------------------------------------------------*/