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
12 KiB

  1. #include "kernel.h"
  2. #define WINAPI _far _pascal _loadds
  3. typedef unsigned int UINT;
  4. typedef const char _far* LPCSTR;
  5. typedef HANDLE HTASK;
  6. #include "logerror.h"
  7. int WINAPI FatalExitC(WORD);
  8. void WINAPI OutputDebugString(LPCSTR);
  9. void DebugLogParamError(VOID FAR* param, FARPROC lpfn, WORD err);
  10. void DebugLogError(WORD err, VOID FAR* lpInfo);
  11. int WINAPI GetOwnerName(WORD sel, char far *buf, WORD buflen);
  12. int WINAPI FarGetOwner(WORD sel);
  13. #define CODESEG _based(_segname("_CODE"))
  14. #define SELECTOROF(lp) HIWORD(lp)
  15. #define OFFSETOF(lp) LOWORD((DWORD)lp)
  16. #define MAKELONG(a, b) ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
  17. #define MAKELP(sel, off) ((VOID FAR *)MAKELONG(off, sel))
  18. #if KDEBUG
  19. UINT DebugOptions = 0;
  20. UINT DebugFilter = 0;
  21. #define FMT_WORD 0
  22. #define FMT_DWORD 1
  23. #define FMT_LP 2
  24. struct TYPEMAP
  25. {
  26. UINT err;
  27. char CODESEG* szType; // Compiler bug: this can't be _based
  28. char CODESEG* szFmt;
  29. };
  30. static char CODESEG szParam[] = "parameter";
  31. static char CODESEG szD16[] = "%s: Invalid %s: %d\r\n";
  32. static char CODESEG szD32[] = "%s: Invalid %s: %ld\r\n";
  33. static char CODESEG szX16[] = "%s: Invalid %s: %#04x\r\n";
  34. static char CODESEG szX32[] = "%s: Invalid %s: %#08lx\r\n";
  35. static char CODESEG szLP[] = "%s: Invalid %s: %#04x:%#04x\r\n";
  36. static char CODESEG sz_value[] = "value";
  37. static char CODESEG sz_index[] = "index";
  38. static char CODESEG sz_flags[] = "flags";
  39. static char CODESEG sz_selector[] = "selector";
  40. static char CODESEG sz_pointer[] = "pointer";
  41. static char CODESEG sz_function_pointer [] = "function pointer";
  42. static char CODESEG sz_string_pointer [] = "string pointer";
  43. static char CODESEG sz_HINSTANCE[] = "HINSTANCE";
  44. static char CODESEG sz_HMODULE[] = "HMODULE";
  45. static char CODESEG sz_global_handle [] = "global handle";
  46. static char CODESEG sz_local_handle [] = "local handle";
  47. static char CODESEG sz_atom[] = "atom";
  48. static char CODESEG sz_HWND[] = "HWND";
  49. static char CODESEG sz_HMENU[] = "HMENU";
  50. static char CODESEG sz_HCURSOR[] = "HCURSOR";
  51. static char CODESEG sz_HICON[] = "HICON";
  52. static char CODESEG sz_HGDIOBJ[] = "HGDIOBJ";
  53. static char CODESEG sz_HDC[] = "HDC";
  54. static char CODESEG sz_HPEN[] = "HPEN";
  55. static char CODESEG sz_HFONT[] = "HFONT";
  56. static char CODESEG sz_HBRUSH[] = "HBRUSH";
  57. static char CODESEG sz_HBITMAP[] = "HBITMAP";
  58. static char CODESEG sz_HRGN[] = "HRGN";
  59. static char CODESEG sz_HPALETTE[] = "HPALETTE";
  60. static char CODESEG sz_HANDLE[] = "HANDLE";
  61. static char CODESEG sz_HFILE[] = "HFILE";
  62. static char CODESEG sz_HMETAFILE[] = "HMETAFILE";
  63. static char CODESEG sz_CID[] = "CID";
  64. static char CODESEG sz_HDRVR[] = "HDRVR";
  65. static char CODESEG sz_HDWP[] = "HDWP";
  66. static char CODESEG*pszLP = szLP;
  67. static char CODESEG*pszD32 = szD32;
  68. static char CODESEG*pszX32 = szX32;
  69. #define DEFMAP(err, type, fmt) \
  70. { err, type, fmt }
  71. struct TYPEMAP CODESEG typemap[] =
  72. {
  73. DEFMAP(ERR_BAD_VALUE, sz_value, szD16),
  74. DEFMAP(ERR_BAD_INDEX, sz_index, szD16),
  75. DEFMAP(ERR_BAD_FLAGS, sz_flags, szX16),
  76. DEFMAP(ERR_BAD_SELECTOR, sz_selector, szX16),
  77. DEFMAP(ERR_BAD_DFLAGS, sz_flags, szX32),
  78. DEFMAP(ERR_BAD_DVALUE, sz_value, szD32),
  79. DEFMAP(ERR_BAD_DINDEX, sz_index, szD32),
  80. DEFMAP(ERR_BAD_PTR, sz_pointer, szLP),
  81. DEFMAP(ERR_BAD_FUNC_PTR, sz_function_pointer, szLP),
  82. DEFMAP(ERR_BAD_STRING_PTR, sz_string_pointer, szLP),
  83. DEFMAP(ERR_BAD_HINSTANCE, sz_HINSTANCE, szX16),
  84. DEFMAP(ERR_BAD_HMODULE, sz_HMODULE, szX16),
  85. DEFMAP(ERR_BAD_GLOBAL_HANDLE,sz_global_handle, szX16),
  86. DEFMAP(ERR_BAD_LOCAL_HANDLE, sz_local_handle, szX16),
  87. DEFMAP(ERR_BAD_ATOM, sz_atom, szX16),
  88. DEFMAP(ERR_BAD_HWND, sz_HWND, szX16),
  89. DEFMAP(ERR_BAD_HMENU, sz_HMENU, szX16),
  90. DEFMAP(ERR_BAD_HCURSOR, sz_HCURSOR, szX16),
  91. DEFMAP(ERR_BAD_HICON, sz_HICON, szX16),
  92. DEFMAP(ERR_BAD_GDI_OBJECT, sz_HGDIOBJ, szX16),
  93. DEFMAP(ERR_BAD_HDC, sz_HDC, szX16),
  94. DEFMAP(ERR_BAD_HPEN, sz_HPEN, szX16),
  95. DEFMAP(ERR_BAD_HFONT, sz_HFONT, szX16),
  96. DEFMAP(ERR_BAD_HBRUSH, sz_HBRUSH, szX16),
  97. DEFMAP(ERR_BAD_HBITMAP, sz_HBITMAP, szX16),
  98. DEFMAP(ERR_BAD_HRGN, sz_HRGN, szX16),
  99. DEFMAP(ERR_BAD_HPALETTE, sz_HPALETTE, szX16),
  100. DEFMAP(ERR_BAD_HANDLE, sz_HANDLE, szX16),
  101. DEFMAP(ERR_BAD_HFILE, sz_HFILE, szX16),
  102. DEFMAP(ERR_BAD_HMETAFILE, sz_HMETAFILE, szX16),
  103. DEFMAP(ERR_BAD_CID, sz_CID, szX16),
  104. DEFMAP(ERR_BAD_HDRVR, sz_HDRVR, szX16),
  105. DEFMAP(ERR_BAD_HDWP, sz_HDWP, szX16)
  106. };
  107. int (_cdecl _far *wsprintf)(LPSTR, LPCSTR, ...) = NULL;
  108. int (WINAPI *wvsprintf)(LPSTR lpszOut, LPCSTR lpszFmt, const void FAR* lpParams) = NULL;
  109. #define ORD_WSPRINTF 420
  110. #define ORD_WVSPRINTF 421
  111. BOOL _fastcall LoadWsprintf(void)
  112. {
  113. static char CODESEG rgchUSER[] = "USER";
  114. HANDLE hmod;
  115. hmod = GetModuleHandle(rgchUSER);
  116. if (!hmod)
  117. return FALSE;
  118. (FARPROC)wsprintf = GetProcAddress(hmod, MAKELP(NULL, ORD_WSPRINTF));
  119. (FARPROC)wvsprintf = GetProcAddress(hmod, MAKELP(NULL, ORD_WVSPRINTF));
  120. if (!SELECTOROF(wsprintf))
  121. {
  122. static char CODESEG rgch[] = "KERNEL: Can't call wsprintf: USER not initialized\r\n";
  123. OutputDebugString(rgch);
  124. return FALSE;
  125. }
  126. return TRUE;
  127. }
  128. typedef struct
  129. {
  130. UINT flags;
  131. LPCSTR lpszFmt;
  132. WORD args[1];
  133. } DOPARAMS;
  134. #define BUFFERSLOP 32
  135. BOOL DebugOutput2(DOPARAMS FAR* pparams)
  136. {
  137. UINT flags = pparams->flags;
  138. BOOL fBreak = FALSE;
  139. BOOL fPrint = TRUE;
  140. char rgch[80*2 + BUFFERSLOP]; // max 2 lines (don't want to hog too much stack space)
  141. static char CODESEG szCRLF[] = "\r\n";
  142. char far *prefix, far *prefix1;
  143. switch (flags & DBF_SEVMASK)
  144. {
  145. case DBF_TRACE:
  146. // If the flags don't match the debug filter,
  147. // don't print the trace message.
  148. // If the trace matches the filter, check for TRACEBREAK.
  149. //
  150. prefix = "t ";
  151. if (!((flags & DBF_FILTERMASK) & DebugFilter))
  152. fPrint = FALSE;
  153. else if (DebugOptions & DBO_TRACEBREAK)
  154. fBreak = TRUE;
  155. break;
  156. case DBF_WARNING:
  157. prefix = "wn ";
  158. if (DebugOptions & DBO_WARNINGBREAK)
  159. fBreak = TRUE;
  160. break;
  161. case DBF_ERROR:
  162. prefix = "err ";
  163. if (!(DebugOptions & DBO_NOERRORBREAK))
  164. fBreak = TRUE;
  165. break;
  166. case DBF_FATAL:
  167. prefix = "fatl ";
  168. if (!(DebugOptions & DBO_NOFATALBREAK))
  169. fBreak = TRUE;
  170. break;
  171. }
  172. // If DBO_SILENT is specified, don't print anything.
  173. //
  174. if (DebugOptions & DBO_SILENT)
  175. fPrint = FALSE;
  176. if ((lstrlen((LPSTR)pparams->lpszFmt) <= sizeof(rgch) - BUFFERSLOP) &&
  177. (SELECTOROF(wsprintf) || LoadWsprintf()) && (fPrint || fBreak))
  178. {
  179. int hinst = HIWORD(pparams);
  180. for (prefix1 = rgch; *prefix; ) *prefix1++ = *prefix++;
  181. prefix1 += GetOwnerName(hinst, prefix1, 16);
  182. *prefix1++ = ' ';
  183. wvsprintf(prefix1, pparams->lpszFmt, (void FAR*)pparams->args);
  184. OutputDebugString(rgch);
  185. OutputDebugString(szCRLF);
  186. }
  187. if (fBreak)
  188. {
  189. // If we are supposed to break with an int 3, then return TRUE.
  190. //
  191. if (DebugOptions & DBO_INT3BREAK)
  192. return TRUE;
  193. return FatalExitC(flags);
  194. }
  195. return FALSE;
  196. }
  197. BOOL LogParamError2(WORD err, FARPROC lpfn, VOID FAR* param, WORD caller)
  198. {
  199. BOOL fBreak;
  200. fBreak = FALSE;
  201. if (err & ERR_WARNING)
  202. {
  203. if (DebugOptions & DBO_WARNINGBREAK)
  204. fBreak = TRUE;
  205. }
  206. else
  207. {
  208. if (!(DebugOptions & DBO_NOERRORBREAK))
  209. fBreak = TRUE;
  210. }
  211. // If we're not breaking and SILENT is specified, just return.
  212. //
  213. if (!fBreak && (DebugOptions & DBO_SILENT))
  214. return FALSE;
  215. if (SELECTOROF(wsprintf) || LoadWsprintf())
  216. {
  217. char rgch[128];
  218. char rgchProcName[50], far *rpn;
  219. char CODESEG* pszType; // compiler bug: see above
  220. char CODESEG* pszFmt;
  221. int i, hinst;
  222. WORD errT;
  223. void FAR GetProcName(FARPROC lpfn, LPSTR lpch, int cch);
  224. char far *prefix1;
  225. GetProcName(lpfn, rgchProcName, sizeof(rgchProcName));
  226. /* if we got a real proc name, then copy just the proc name */
  227. for (rpn = rgchProcName; *rpn && (*rpn != '(') && (*rpn != ':'); rpn++)
  228. ;
  229. if (*rpn == ':') {
  230. lstrcpy(rgchProcName, rpn+1);
  231. }
  232. pszFmt = szX32;
  233. pszType = szParam;
  234. errT = (err & ~ERR_WARNING);
  235. for (i = 0; i < (sizeof(typemap) / sizeof(struct TYPEMAP)); i++)
  236. {
  237. if (typemap[i].err == errT)
  238. {
  239. pszFmt = typemap[i].szFmt;
  240. pszType = typemap[i].szType;
  241. break;
  242. }
  243. }
  244. if (err & ERR_WARNING) {
  245. lstrcpy(rgch, "wn ");
  246. prefix1 = rgch+3;
  247. } else {
  248. lstrcpy(rgch, "err ");
  249. prefix1 = rgch+4;
  250. }
  251. hinst = HIWORD(prefix1);
  252. prefix1 += GetOwnerName(hinst, prefix1, 16);
  253. if (FarGetOwner(hinst) != FarGetOwner(caller)) {
  254. *prefix1++ = '-';
  255. *prefix1++ = '>';
  256. prefix1 += GetOwnerName(caller, prefix1, 16);
  257. }
  258. *prefix1++ = ' ';
  259. if (pszFmt == pszLP)
  260. wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, SELECTOROF(param), OFFSETOF(param));
  261. else if (pszFmt == pszD32 || pszFmt == pszX32)
  262. wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, (DWORD)param);
  263. else
  264. wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, (WORD)(DWORD)param);
  265. OutputDebugString(rgch);
  266. }
  267. if (fBreak)
  268. {
  269. // If we are supposed to break with an int 3, then return TRUE.
  270. //
  271. if (DebugOptions & DBO_INT3BREAK)
  272. return TRUE;
  273. return FatalExitC(err);
  274. }
  275. return FALSE;
  276. }
  277. extern HTASK allocTask;
  278. extern DWORD allocCount;
  279. extern DWORD allocBreak;
  280. extern char allocModName[8];
  281. void FAR _loadds SetupAllocBreak(HTASK htask);
  282. char far* GetTaskModNamePtr(HTASK htask);
  283. BOOL WINAPI IGetWinDebugInfo(WINDEBUGINFO FAR* lpwdi, UINT flags)
  284. {
  285. int i;
  286. lpwdi->flags = flags;
  287. if (flags & WDI_OPTIONS)
  288. lpwdi->dwOptions = DebugOptions;
  289. if (flags & WDI_FILTER)
  290. lpwdi->dwFilter = DebugFilter;
  291. if (flags & WDI_ALLOCBREAK)
  292. {
  293. lpwdi->dwAllocBreak = allocBreak;
  294. lpwdi->dwAllocCount = allocCount;
  295. for (i = 0; i < 8; i++)
  296. lpwdi->achAllocModule[i] = allocModName[i];
  297. }
  298. return TRUE;
  299. }
  300. BOOL WINAPI ISetWinDebugInfo(const WINDEBUGINFO FAR* lpwdi)
  301. {
  302. int i;
  303. if (lpwdi->flags & WDI_OPTIONS)
  304. DebugOptions = (UINT)lpwdi->dwOptions;
  305. if (lpwdi->flags & WDI_FILTER)
  306. DebugFilter = (UINT)lpwdi->dwFilter;
  307. if (lpwdi->flags & WDI_ALLOCBREAK)
  308. {
  309. allocTask = NULL;
  310. allocBreak = lpwdi->dwAllocBreak;
  311. allocCount = 0; // Always reset count to 0.
  312. for (i = 0; i < 8; i++)
  313. allocModName[i] = lpwdi->achAllocModule[i];
  314. {
  315. extern HTASK headTDB;
  316. HTASK htask;
  317. // Enumerate all current tasks to see if any match
  318. //
  319. #define TDB_next 0
  320. for (htask = headTDB; htask; htask = *((HTASK FAR*)MAKELP(htask, TDB_next)))
  321. SetupAllocBreak(htask);
  322. }
  323. }
  324. return TRUE;
  325. }
  326. void FAR _loadds SetupAllocBreak(HTASK htask)
  327. {
  328. int i;
  329. char far* pchAlloc;
  330. char far* pchTask;
  331. // If alloc break task already set up, exit.
  332. //
  333. if (allocTask)
  334. return;
  335. // If no alloc break in effect, nothing to do.
  336. //
  337. if (allocModName[0] == 0)
  338. return;
  339. pchAlloc = allocModName;
  340. pchTask = GetTaskModNamePtr(htask);
  341. for (i = 8; --i != 0; pchAlloc++, pchTask++)
  342. {
  343. char ch1 = *pchAlloc;
  344. char ch2 = *pchTask;
  345. if (ch1 >= 'a' && ch1 <= 'z')
  346. ch1 -= ('a' - 'A');
  347. if (ch2 >= 'a' && ch2 <= 'z')
  348. ch2 -= ('a' - 'A');
  349. if (ch1 != ch2)
  350. return;
  351. if (ch1 == 0 || ch2 == 0)
  352. break;
  353. }
  354. // Set the alloc break task, and init the count to 0.
  355. //
  356. allocTask = htask;
  357. allocCount = 0;
  358. }
  359. #else // !KDEBUG
  360. BOOL WINAPI GetWinDebugInfo(WINDEBUGINFO FAR* lpwdi, UINT flags)
  361. {
  362. return FALSE;
  363. }
  364. BOOL WINAPI SetWinDebugInfo(const WINDEBUGINFO FAR* lpwdi)
  365. {
  366. return FALSE;
  367. }
  368. #endif // !KDEBUG