2
0

Debug.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421
  1. #include <windows.h>
  2. #include <richedit.h>
  3. #include <stdio.h>
  4. #include "Debug.h"
  5. #define Title "Debugger for WinAos"
  6. #define ModNext 4 // 0 + 4
  7. #define ModName 8 // 4 +4
  8. #define ModRefCnt 44 // 40 +4
  9. #define ModSB 48 // 44 +4
  10. #define ModData 80 //
  11. #define ModCode 84 //
  12. #define ModRefs 92 //
  13. #define TypeTagName 20 // was 16
  14. #define TypeTagMod 16 // was 48
  15. #define MAX_THREADS 1024
  16. #define MAX_OUTBUF 1024
  17. #define MAX_FRAMES 64
  18. #define MAX_VARS 32
  19. #define MaxString 64
  20. #define MaxArray 8
  21. #define LONGINT long int
  22. #define OCHAR unsigned char
  23. static HANDLE hInst, hThread = INVALID_HANDLE_VALUE;
  24. static HWND hwndMain, hwndMDIClient, hwndCon, hwndExc, hwndSys;
  25. static OCHAR exePath[MAX_PATH] = "", workPath[MAX_PATH] = "", iniFile[MAX_PATH];
  26. static OCHAR module[MaxString];
  27. static PROCESS_INFORMATION proc;
  28. static STARTUPINFO start;
  29. static DWORD threadId, debugAction;
  30. static char outBuf[MAX_OUTBUF+1] = "";
  31. static int outBufLen = 0;
  32. static HWND outBufHwnd = NULL;
  33. static LPVOID modules;
  34. static EXCEPTION_POINTERS excPtrs;
  35. static struct thread {HANDLE hThread; DWORD dwThreadId;} threads[MAX_THREADS];
  36. static BOOL ignoreExceptions = FALSE;
  37. static BOOL clearAlways = FALSE;
  38. static BOOL trapByDefault = FALSE;
  39. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  40. {
  41. WNDCLASS wndclass;
  42. MSG msg;
  43. if(!hPrevInstance) {
  44. wndclass.style = 0;
  45. wndclass.lpfnWndProc = WndProc;
  46. wndclass.cbClsExtra = 0;
  47. wndclass.cbWndExtra = 0;
  48. wndclass.hInstance = hInstance;
  49. wndclass.hIcon = LoadIcon(hInstance, "DEBUG");
  50. wndclass.hCursor = NULL;
  51. wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  52. wndclass.lpszMenuName = "Debug_Menu";
  53. wndclass.lpszClassName = "Debug_Class";
  54. if (!RegisterClass(&wndclass)) {
  55. return 1;
  56. }
  57. wndclass.lpfnWndProc = ChildWndProc;
  58. wndclass.cbWndExtra = 4;
  59. wndclass.lpszMenuName = NULL;
  60. wndclass.lpszClassName = "Debug_Child_Class";
  61. if (!RegisterClass(&wndclass)) {
  62. return 1;
  63. }
  64. }
  65. hwndMain = CreateWindow("Debug_Class", Title, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
  66. WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN | WS_OVERLAPPED,
  67. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  68. if (hwndMain == NULL) {
  69. return 1;
  70. }
  71. hInst = hInstance;
  72. ShowWindow(hwndMain, nCmdShow);
  73. while(GetMessage(&msg, NULL, 0, 0)) {
  74. TranslateMessage(&msg);
  75. DispatchMessage(&msg);
  76. }
  77. UnregisterClass("Debug_Class", hInstance);
  78. UnregisterClass("Debug_Child_Class", hInstance);
  79. return msg.wParam;
  80. }
  81. void Flush(void) {
  82. HWND hwndE;
  83. int len;
  84. if ((outBufLen > 0) && (outBufHwnd != NULL)) {
  85. hwndE = (HWND)GetWindowWord(outBufHwnd, GWW_HWNDEDIT);
  86. len = (int)SendMessage(hwndE, EM_GETLIMITTEXT, 0, 0);
  87. SendMessage(hwndE, EM_SETSEL, (WPARAM)len, (LPARAM)len);
  88. outBuf[outBufLen] = (char)0;
  89. SendMessage(hwndE, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)(&outBuf));
  90. }
  91. outBufLen = 0; outBufHwnd = NULL;
  92. }
  93. void Clear(HWND hWnd) {
  94. HWND hwndE;
  95. int len;
  96. char msg[4] = "";
  97. Flush();
  98. if (hWnd != NULL) {
  99. hwndE = (HWND)GetWindowWord(hWnd, GWW_HWNDEDIT);
  100. len = (int)SendMessage(hwndE, EM_GETLIMITTEXT, 0, 0);
  101. SendMessage(hwndE, EM_SETSEL, (WPARAM)0, (LPARAM)len);
  102. SendMessage(hwndE, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)(&msg));
  103. }
  104. }
  105. void String(HWND hWnd, LPCSTR msg) {
  106. int i;
  107. if (hWnd != NULL) {
  108. if (hWnd != outBufHwnd) {
  109. Flush(); outBufHwnd = hWnd;
  110. }
  111. i = 0;
  112. while (msg[i] != (char)0) {
  113. outBuf[outBufLen] = msg[i];
  114. outBufLen++; i++;
  115. if (outBufLen >= MAX_OUTBUF) {
  116. Flush(); outBufHwnd = hWnd;
  117. }
  118. }
  119. } else {
  120. MessageBox(hwndMain, msg, Title, MB_OK | MB_APPLMODAL);
  121. }
  122. }
  123. LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  124. switch (uMsg) {
  125. case WM_CREATE: {
  126. HWND hwnd;
  127. if (LoadLibrary("RichED32.DLL") == NULL) {
  128. String(NULL, "Requires RichED32.DLL!\n");
  129. } else {
  130. hwnd = CreateWindow("RichEdit", NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL |
  131. WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE,
  132. 0, 0, 0, 0, hWnd, (HMENU)ID_EDIT, hInst, (LPVOID)NULL);
  133. SetWindowWord(hWnd, GWW_HWNDEDIT, (WORD)hwnd);
  134. }
  135. break;
  136. }
  137. case WM_SIZE: {
  138. RECT rc;
  139. HWND hwnd;
  140. GetClientRect(hWnd, &rc);
  141. hwnd = (HWND)GetWindowWord(hWnd, GWW_HWNDEDIT);
  142. MoveWindow(hwnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
  143. return DefMDIChildProc(hWnd, uMsg, wParam, lParam);
  144. break;
  145. }
  146. case WM_CLOSE:
  147. return 0;
  148. break;
  149. default:
  150. return DefMDIChildProc(hWnd, uMsg, wParam, lParam);
  151. }
  152. return 0;
  153. }
  154. BOOL CALLBACK AboutDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  155. if ((uMsg == WM_COMMAND) && (LOWORD(wParam) == IDD_Ok)) {
  156. EndDialog(hwndDlg, 0);
  157. return TRUE;
  158. }
  159. return FALSE;
  160. }
  161. OCHAR Get(LPVOID adr, LONGINT* i) {
  162. DWORD read;
  163. OCHAR ch;
  164. ReadProcessMemory(proc.hProcess, (LPVOID)((LONGINT)adr+(*i)), &ch, 1, &read);
  165. (*i)++;
  166. if (read < 1) {
  167. return (OCHAR)0;
  168. } else {
  169. return ch;
  170. }
  171. }
  172. short int GetInt(LPVOID adr, LONGINT* i) {
  173. DWORD read; short int x;
  174. ReadProcessMemory(proc.hProcess, (LPVOID)((LONGINT)adr+(*i)), &x, 2, &read);
  175. (*i) += 2;
  176. if (read < 2) {
  177. return 0;
  178. } else {
  179. return x;
  180. }
  181. }
  182. LONGINT GetLInt(LPVOID adr, LONGINT* i) {
  183. DWORD read; LONGINT x;
  184. ReadProcessMemory(proc.hProcess, (LPVOID)((LONGINT)adr+(*i)), &x, 4, &read);
  185. (*i) += 4;
  186. if (read < 4) {
  187. return 0;
  188. } else {
  189. return x;
  190. }
  191. }
  192. LONGINT GetNum(LPVOID adr, LONGINT* i) {
  193. LONGINT n, s; OCHAR x;
  194. return GetLInt(adr,i);
  195. s = 0; n = 0;
  196. x = Get(adr, i);
  197. while (x >= 128) {
  198. n = n + ((x-128) << s); s = s + 7;
  199. x = Get(adr, i);
  200. }
  201. return (n + (( (x % 64) - (x / 64) * 64) << s));
  202. }
  203. LONGINT FindProc(LPVOID refs, LONGINT reflen, LONGINT ofs) {
  204. LONGINT proc, i, t, start, end;
  205. OCHAR ch;
  206. proc = -1; i = 1;
  207. ch = Get(refs, &i);
  208. while ((i < reflen) && ((ch == (OCHAR)0xf8) || (ch == (OCHAR)0xf9))) {
  209. start = GetNum(refs, &i);
  210. end = GetNum(refs, &i);
  211. if (ch == (OCHAR)0xf9) {
  212. t = GetNum(refs, &i);
  213. i += 9;
  214. }
  215. proc = i;
  216. do { ch = Get(refs, &i); } while (ch != 0);
  217. if (i < reflen) {
  218. ch = Get(refs, &i);
  219. while ((i < reflen) && (ch >= 0x1) && (ch <= 0x3)) {
  220. ch = Get(refs, &i);
  221. if ((ch >= 0x81) || (ch == 0x16) || (ch == 0x1D)) {
  222. t = GetNum(refs, &i);
  223. }
  224. t = GetNum(refs, &i);
  225. do { ch = Get(refs, &i); } while (ch != 0);
  226. if (i < reflen) { ch = Get(refs, &i); }
  227. }
  228. };
  229. if ((start <= ofs) && (ofs <= end)) {ch = 0;}
  230. }
  231. if ((proc == -1) && (i != 0)) { proc = i; }
  232. return proc;
  233. }
  234. LPVOID GetMod(LONGINT pc) {
  235. LPVOID m;
  236. LONGINT base, len, i;
  237. //OCHAR msg[128];
  238. i = 0; m = (LPVOID)GetLInt(modules, &i);
  239. if (m==NULL) String(hwndSys, "no modules found at all");
  240. while (m != NULL) {
  241. i = 0; base = GetLInt((LPVOID)((DWORD)m+ModCode), &i); // code table
  242. i = 0; len = GetLInt((LPVOID)((DWORD)base+12), &i); // len (code table)
  243. // better: read len from len table within module desc
  244. //wsprintf(msg,"module from 0%lXH to 0%lXH with len 0%lXH \n",base+16,base+16+len,len);
  245. //String(hwndSys,msg);
  246. base = base+16;
  247. if ((base <= pc) && (pc <= (base+len))) {
  248. return m;
  249. }
  250. i = 0; base = GetLInt((LPVOID)((DWORD)m+ModData), &i);
  251. i = 0; len = GetLInt((LPVOID)((DWORD)base+12), &i);
  252. base = base+16;
  253. if ((pc >= base) && (pc <= (base+len))) {
  254. return m;
  255. }
  256. i = 0; m = (LPVOID)GetLInt((LPVOID)((DWORD)m+ModNext), &i);
  257. }
  258. return NULL;
  259. }
  260. void WriteProc(HWND hWnd, LPVOID mod, LONGINT pc, LONGINT bp, LPVOID* refs, LONGINT* reflen, LONGINT* refpos, LONGINT* base) {
  261. OCHAR msg[128];
  262. LONGINT i, j;
  263. DWORD read;
  264. OCHAR ch;
  265. (*refpos) = -1; (*reflen) = 0; (*base) = 0;
  266. if (mod == NULL) {
  267. wsprintf(msg, "Unknown EIP = 0%lXH", pc);
  268. String(hWnd, msg);
  269. if (bp != -1) {
  270. wsprintf(msg, " EBP = 0%lXH", bp);
  271. String(hWnd, msg);
  272. }
  273. } else {
  274. ReadProcessMemory(proc.hProcess, (LPVOID)((DWORD)mod+ModName), msg, 32, &read);
  275. String(hWnd, msg);
  276. j = 0; i = GetLInt((LPVOID)((DWORD)mod+ModCode), &j);
  277. //wsprintf(msg,"module code 0%lXH \n",i);
  278. //String(hwndSys,msg);
  279. i = i+16;
  280. j = 0; i = GetLInt((LPVOID)((DWORD)mod+ModRefs), &j);
  281. //wsprintf(msg,"module refs 0%lXH \n",i);
  282. //String(hwndSys,msg);
  283. j = 0; (*reflen) = GetLInt((LPVOID)((DWORD)i+12), &j);
  284. (*refs) = (LPVOID)(i+16);
  285. if (((*refs) != NULL) && (reflen > 0)) {
  286. (*refpos) = FindProc((*refs), (*reflen), pc);
  287. if ((*refpos) != -1) {
  288. ch = Get((*refs), refpos);
  289. if (ch == '$') {
  290. j = 0; i = GetLInt((LPVOID)((DWORD)mod+ModSB), &j);
  291. (*base) = i;
  292. } else {
  293. (*base) = bp;
  294. }
  295. msg[0] = '.'; i = 1;
  296. while (ch != 0) {
  297. msg[i] = ch; i++;
  298. ch = Get((*refs), refpos);
  299. }
  300. msg[i] = 0;
  301. String(hWnd, msg);
  302. }
  303. }
  304. wsprintf(msg, " PC = %i", pc);
  305. String(hWnd, msg);
  306. }
  307. }
  308. void GetTypeName(LPVOID ptr, char* name) {
  309. LPVOID tag, type, mod;
  310. int i;
  311. DWORD read;
  312. char mname[32], tname[32];
  313. if ((DWORD)ptr > 1024*1024) {
  314. i = -4; tag = (LPVOID)GetLInt(ptr, &i);
  315. if ((DWORD)tag > 1024*1024) {
  316. i = -4; type = (LPVOID)GetLInt(tag, &i);
  317. if ((DWORD)type > 1024*1024) {
  318. i = TypeTagMod; mod = (LPVOID)GetLInt(type, &i); // 48 -> TypeTagMod
  319. ReadProcessMemory(proc.hProcess, (LPVOID)((DWORD)mod+ModName), mname, 32, &read);
  320. ReadProcessMemory(proc.hProcess, (LPVOID)((DWORD)type+TypeTagName), tname, 32, &read); // 16 -> TypeTagName
  321. if (strcmp(tname,"") == 0) {strcpy(tname,"ANONYMOUS");}
  322. if (strcmp(mname,"") == 0) {strcpy(mname,"ANONYMOUS");}
  323. sprintf(name, "%s.%s", mname, tname);
  324. return;
  325. }
  326. }
  327. }
  328. strcpy(name, "");
  329. }
  330. void WriteType(HWND hWnd, LPVOID dynamictdadr, LPVOID statictdadr) {
  331. char dname[64], sname[64];
  332. char msg[128];
  333. GetTypeName(dynamictdadr, dname);
  334. if (strcmp(dname, "") != 0) {
  335. wsprintf(msg, " %s", dname);
  336. String(hWnd, msg);
  337. }
  338. /* not supported any more since records do not have a type descriptor in the module heap
  339. GetTypeName(statictdadr, sname);
  340. if ((strcmp(sname, "") != 0)&& (strcmp(sname, dname) != 0)) {
  341. wsprintf(msg, " (%s)", dname);
  342. String(hWnd, msg);
  343. }
  344. */
  345. }
  346. void Variables(HWND hWnd, LPVOID mod, LPVOID refs, LONGINT reflen, LONGINT i, LONGINT base, LONGINT sb) {
  347. OCHAR msg[MaxString+4];
  348. LPVOID tmp, tdadr0, tdadr1;
  349. LONGINT n, adr, size, j, k, t, t2, t3, vars;
  350. DWORD read;
  351. OCHAR mode, type, ch;
  352. BOOLEAN writeType;
  353. short int si;
  354. BOOLEAN etc;
  355. float x;
  356. double y;
  357. mode = Get(refs, &i); vars = 0;
  358. while ((i < reflen) && (mode >= 0x1) && (mode <= 0x3) && (vars < MAX_VARS)) {
  359. tdadr0 = NULL; tdadr1 = NULL;
  360. type = Get(refs, &i); etc = FALSE;
  361. //wsprintf(msg,"type: 0%lXH \n",type);
  362. //String(hwndSys,msg);
  363. if (type > 0x80) {
  364. if (type == 0x83) { type = 15; } else { type -= 0x80; }
  365. n = GetNum(refs, &i);
  366. } else if ((type == 0x16) || (type == 0x1D)) {
  367. tdadr0 = (LPVOID)GetNum(refs, &i); n = 1;
  368. //wsprintf(msg,"tdadr0: 0%lXH \n",tdadr0);
  369. //String(hwndSys,msg);
  370. if (((DWORD)tdadr0 >= 0) && ((DWORD)tdadr0 <= 1024*1024)) {
  371. j = 0; k = GetLInt((LPVOID)((DWORD)mod+ModSB), &j);
  372. j = 0; tdadr0 = (LPVOID)GetLInt((LPVOID)(k+(DWORD)tdadr0), &j);
  373. //wsprintf(msg,"tdadr0(2): 0%lXH \n",tdadr0);
  374. //String(hwndSys,msg);
  375. }
  376. } else {
  377. if (type == 15) { n = MaxString; } else { n = 1; }
  378. }
  379. adr = GetNum(refs, &i); adr = adr+base;
  380. wsprintf(msg, "\t"); j = 1;
  381. ch = Get(refs, &i);
  382. while (ch != 0) {
  383. msg[j] = ch; j++;
  384. ch = Get(refs, &i);
  385. }
  386. msg[j] = 0; String(hWnd, msg);
  387. String(hWnd, " = ");
  388. if (n == 0) {
  389. k = 0; n = GetLInt((LPVOID)(adr+4), &k);
  390. }
  391. if (type == 15) {
  392. if (n > MaxString) { etc = TRUE; n = MaxString; }
  393. } else {
  394. if (n > MaxArray) { etc = TRUE; n = MaxArray; }
  395. }
  396. if (mode != 0x1) {
  397. k = 0; adr = GetLInt((LPVOID)(adr), &k);
  398. }
  399. if ((adr >= -4) && (adr < 4096)) {
  400. wsprintf(msg, "NIL reference (0%lXH)", adr);
  401. String(hWnd, msg);
  402. } else {
  403. if (type == 15) {
  404. msg[0] = '"'; j = 1; k = 0;
  405. while (n > 0) {
  406. ch = Get((LPVOID)adr, &k);
  407. if ((ch < ' ') || (ch > '~')) { break; }
  408. msg[j] = ch; j++; n--;
  409. }
  410. msg[j] = '"'; msg[j+1] = (OCHAR)0;
  411. etc = (ch != 0); String(hWnd, msg);
  412. } else {
  413. switch (type) {
  414. case 1: case 2: case 3: case 4: size = 1; break;
  415. case 5: size = 2; break;
  416. case 6: case 7: case 9: case 13: case 14: case 29: size = 4; break;
  417. case 8: case 16: size = 8; break;
  418. case 22: size = 0; break;
  419. default:
  420. wsprintf(msg, "bad type %i", (int)type);
  421. String(hWnd, msg);
  422. n = 0; size = 0;
  423. }
  424. while (n > 0) {
  425. k = 0;
  426. writeType = 0;
  427. switch (type) {
  428. case 1: case 3: // byte, char
  429. ch = Get((LPVOID)adr, &k);
  430. if ((ch > ' ') && (ch <= '~')) {
  431. msg[0] = ch; msg[1] = 0;
  432. } else {
  433. wsprintf(msg, "%uX", ch);
  434. }
  435. break;
  436. case 2: // BOOLEAN
  437. ch = Get((LPVOID)adr, &k);
  438. if (ch == 0) {
  439. wsprintf(msg, "FALSE");
  440. } else if (ch == 1) {
  441. wsprintf(msg, "TRUE");
  442. } else {
  443. wsprintf(msg, "%i", ch);
  444. }
  445. break;
  446. case 4: // SHORTINT
  447. ch = Get((LPVOID)adr, &k);
  448. wsprintf(msg, "%i", ch);
  449. break;
  450. case 5: // INTEGER
  451. si = GetInt((LPVOID)adr, &k);
  452. wsprintf(msg, "%i", si);
  453. break;
  454. case 6: // LONGINT
  455. j = GetLInt((LPVOID)adr, &k);
  456. wsprintf(msg, "%i", j);
  457. break;
  458. case 7: // REAL
  459. ReadProcessMemory(proc.hProcess, (LPVOID)adr, &x, 4, &read);
  460. sprintf(msg, "%E", x);
  461. break;
  462. case 8: // LONGREAL
  463. ReadProcessMemory(proc.hProcess, (LPVOID)adr, &y, 8, &read);
  464. sprintf(msg, "%E", y);
  465. break;
  466. case 9: // SET
  467. j = GetLInt((LPVOID)adr, &k);
  468. wsprintf(msg, "0%lXH", j);
  469. break;
  470. case 13: case 29: // pointer
  471. tdadr1 = (LPVOID)GetLInt((LPVOID)adr, &k);
  472. wsprintf(msg, "0%lXH", tdadr1);
  473. writeType = 1;
  474. break;
  475. case 22: // RECORD
  476. tdadr1 = tdadr0;
  477. wsprintf(msg, "RECORD 0%lXH", tdadr1);
  478. break;
  479. case 14: // PROC
  480. j = GetLInt((LPVOID)adr, &k);
  481. if (j == 0) {
  482. wsprintf(msg, "NIL");
  483. } else {
  484. tmp = NULL; t = 0; t2 = 0; t3 = 0;
  485. WriteProc(hWnd, GetMod(j), j, -1, &tmp, &t, &t2, &t3);
  486. wsprintf(msg, "");
  487. }
  488. break;
  489. }
  490. String(hWnd, msg);
  491. if (writeType==1) {
  492. WriteType(hWnd, tdadr1, tdadr0);
  493. }
  494. n--; adr += size;
  495. if (n > 0) { String(hWnd, ","); }
  496. }
  497. }
  498. }
  499. if (etc) {
  500. wsprintf(msg, "...\n");
  501. } else {
  502. wsprintf(msg, "\n");
  503. }
  504. String(hWnd, msg);
  505. if (i < reflen) { mode = Get(refs, &i); }
  506. vars++;
  507. }
  508. }
  509. void ShowState(OCHAR* module) {
  510. LPVOID mod, refs;
  511. LONGINT sb, reflen, refpos, i;
  512. DWORD read;
  513. OCHAR modName[32] = "";
  514. OCHAR msg[64];
  515. OCHAR ch;
  516. wsprintf(msg, "Module State %s\n", module); String(hwndSys, msg);
  517. i = 0; mod = (LPVOID)GetLInt(modules, &i);
  518. while (mod != NULL) {
  519. ReadProcessMemory(proc.hProcess, (LPVOID)((DWORD)mod+ModName), modName, 32, &read);
  520. if (strcmp(modName, module) != 0) {
  521. i = 0; mod = (LPVOID)GetLInt((LPVOID)((DWORD)mod+ModNext), &i);
  522. } else {
  523. break;
  524. }
  525. }
  526. if (strcmp(modName, module) == 0) {
  527. i = 0; sb = GetLInt((LPVOID)((DWORD)mod+ModSB), &i);
  528. wsprintf(msg, " SB = 0%lXH\n", sb); String(hwndSys, msg);
  529. i = 0; refs = (LPVOID)GetLInt((LPVOID)((DWORD)mod+ModRefs), &i);
  530. i = 0; reflen = GetLInt((LPVOID)((DWORD)refs+12), &i);
  531. refs = (LPVOID)((DWORD)refs+16);
  532. if ((refs != NULL) && (reflen > 0)) {
  533. refpos = FindProc(refs, reflen, 0);
  534. if (refpos != -1) {
  535. do { ch = Get(refs, &refpos); } while (ch != 0);
  536. Variables(hwndSys, mod, refs, reflen, refpos, sb, sb);
  537. }
  538. }
  539. } else {
  540. wsprintf(msg, "\tNot Loaded\n"); String(hwndSys, msg);
  541. }
  542. String(hwndSys, "\n"); Flush();
  543. }
  544. void TrapMsg(EXCEPTION_POINTERS *exp, LPSTR msg, BOOL ln) {
  545. OCHAR form[32];
  546. DWORD excode;
  547. if (ln) {
  548. strcpy(form, "%s\n");
  549. } else {
  550. strcpy(form, "%s");
  551. }
  552. excode = exp->ExceptionRecord->ExceptionCode;
  553. if (excode == EXCEPTION_GUARD_PAGE) {
  554. wsprintf(msg, form, "guard page violation");
  555. } else if (excode == EXCEPTION_BREAKPOINT) {
  556. LONGINT i, code;
  557. i = 0; code = GetLInt((LPVOID)(exp->ContextRecord->Esp), &i);
  558. if (ln) {
  559. wsprintf(form, "%i %s\n", code, "%s");
  560. } else {
  561. wsprintf(form, "%i %s", code, "%s");
  562. }
  563. if (code == 1) {
  564. wsprintf(msg, form, "WITH guard failed");
  565. } else if (code == 2) {
  566. wsprintf(msg, form, "CASE invalid");
  567. } else if (code == 3) {
  568. wsprintf(msg, form, "RETURN missing");
  569. } else if (code == 5) {
  570. wsprintf(msg, form, "Implicit type guard failed");
  571. } else if (code == 6) {
  572. wsprintf(msg, form, "Type guard failed");
  573. } else if (code == 7) {
  574. wsprintf(msg, form, "Index out of range");
  575. } else if (code == 8) {
  576. wsprintf(msg, form, "ASSERT failed");
  577. } else if (code == 9) {
  578. wsprintf(msg, form, "Array dimension error");
  579. } else if (code == 13) {
  580. wsprintf(msg, form, "Keyboard interrupt");
  581. } else if (code == 14) {
  582. wsprintf(msg, form, "Out of memory");
  583. } else if (code == 23) {
  584. wsprintf(msg, form, "Exceptions.Raise");
  585. } else {
  586. wsprintf(msg, form, "HALT statement");
  587. }
  588. } else if (excode == EXCEPTION_SINGLE_STEP) {
  589. wsprintf(msg, form, "single step");
  590. } else if (excode == EXCEPTION_ACCESS_VIOLATION) {
  591. wsprintf(msg, form, "access violation");
  592. } else if (excode == EXCEPTION_ILLEGAL_INSTRUCTION) {
  593. wsprintf(msg, form, "illegal instruction");
  594. } else if (excode == EXCEPTION_ARRAY_BOUNDS_EXCEEDED) {
  595. wsprintf(msg, form, "index out of range");
  596. } else if (excode == EXCEPTION_FLT_DENORMAL_OPERAND) {
  597. wsprintf(msg, form, "FPU: denormal operand");
  598. } else if (excode == EXCEPTION_FLT_DIVIDE_BY_ZERO) {
  599. wsprintf(msg, form, "FPU: divide by zero");
  600. } else if (excode == EXCEPTION_FLT_INEXACT_RESULT) {
  601. wsprintf(msg, form, "FPU: inexact result");
  602. } else if (excode == EXCEPTION_FLT_INVALID_OPERATION) {
  603. wsprintf(msg, form, "FPU: invalid operation");
  604. } else if (excode == EXCEPTION_FLT_OVERFLOW) {
  605. wsprintf(msg, form, "FPU: overflow");
  606. } else if (excode == EXCEPTION_FLT_STACK_CHECK) {
  607. wsprintf(msg, form, "FPU: stack check");
  608. } else if (excode == EXCEPTION_FLT_UNDERFLOW) {
  609. wsprintf(msg, form, "FPU: undeflow");
  610. } else if (excode == EXCEPTION_INT_DIVIDE_BY_ZERO) {
  611. wsprintf(msg, form, "integer division by zero");
  612. } else if (excode == EXCEPTION_INT_OVERFLOW) {
  613. wsprintf(msg, form, "integer overflow");
  614. } else if (excode == EXCEPTION_PRIV_INSTRUCTION) {
  615. wsprintf(msg, form, "privileged instruction");
  616. } else if (excode == EXCEPTION_STACK_OVERFLOW) {
  617. wsprintf(msg, form, "stack overflow");
  618. } else {
  619. if (ln) {
  620. wsprintf(msg, "exception %i\n", excode);
  621. } else {
  622. wsprintf(msg, "exception %i\n", excode);
  623. }
  624. }
  625. }
  626. void ShowStack(EXCEPTION_POINTERS *exp, BOOL trap) {
  627. LONGINT pc, bp, sp, reflen, refpos, base, sb, lastbp, frames, i;
  628. LPVOID mod, refs;
  629. OCHAR msg[128];
  630. pc = (LONGINT)(exp->ExceptionRecord->ExceptionAddress);
  631. bp = exp->ContextRecord->Ebp; sp = exp->ContextRecord->Esp;
  632. if (pc == (LONGINT)NULL) {
  633. i = 0; pc = GetLInt((LPVOID)(sp), &i);
  634. }
  635. if (trap) {
  636. TrapMsg(exp, msg, TRUE);
  637. } else {
  638. //wsprintf(msg, StackFrames\n");
  639. wsprintf(msg,"");
  640. }
  641. String(hwndSys, msg);
  642. wsprintf(msg, "\n"); String(hwndSys, msg);
  643. mod = GetMod(pc); frames = 0;
  644. while (frames < MAX_FRAMES){
  645. refs = NULL; refpos = 0; base = 0;
  646. WriteProc(hwndSys, mod, pc, bp, &refs, &reflen, &refpos, &base);
  647. wsprintf(msg, "\n");
  648. String(hwndSys, msg);
  649. if (refpos != -1) {
  650. i = 0; sb = GetLInt((LPVOID)((DWORD)mod+ModSB), &i);
  651. Variables(hwndSys, mod, refs, reflen, refpos, base, sb);
  652. }
  653. lastbp = bp;
  654. i = 0; pc = GetLInt((LPVOID)(bp+4), &i);
  655. i = 0; bp = GetLInt((LPVOID)(bp), &i);
  656. if ((bp < lastbp) || (bp == 0)) { break; }
  657. mod = GetMod(pc); frames++;
  658. }
  659. Flush();
  660. }
  661. void ShowAllStacks()
  662. {
  663. OCHAR str[64]; int i;
  664. i = 0;excPtrs.ExceptionRecord = (PEXCEPTION_RECORD)malloc(sizeof(EXCEPTION_RECORD));
  665. while (i < MAX_THREADS) {
  666. if (threads[i].hThread != INVALID_HANDLE_VALUE) {
  667. excPtrs.ContextRecord->ContextFlags = CONTEXT_FULL;
  668. GetThreadContext(threads[i].hThread, excPtrs.ContextRecord);
  669. excPtrs.ExceptionRecord->ExceptionCode = 0;
  670. excPtrs.ExceptionRecord->ExceptionAddress = (LPVOID)(excPtrs.ContextRecord->Eip);
  671. wsprintf(str, "\n ThreadId: %lu", threads[i].dwThreadId);
  672. String(hwndSys, str);
  673. ShowStack(&excPtrs, FALSE);
  674. }
  675. i++;
  676. }
  677. free(excPtrs.ExceptionRecord);
  678. }
  679. DWORD WINAPI ThreadProc(LPVOID arg) {
  680. HANDLE hProcess = NULL, hExcThread;
  681. DEBUG_EVENT event;
  682. DWORD processId, read, len, i, val, level;
  683. LPCSTR debStr;
  684. OCHAR msg[1024];
  685. OCHAR mystring[64];
  686. BOOL ignore, fetchAdr;
  687. ignore = TRUE;
  688. if (CreateProcess(exePath, NULL, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, workPath,
  689. &start, &proc)) {
  690. WritePrivateProfileString("Debug", "Exe", exePath, iniFile);
  691. ignore = FALSE;
  692. } else {
  693. sscanf(exePath, "%lu", &processId);
  694. if (DebugActiveProcess(processId) != 0) {
  695. ignore = FALSE;
  696. }
  697. }
  698. if (!ignore) {
  699. EnableMenuItem(GetMenu(hwndMain), IDM_D_Stop, MF_BYCOMMAND);
  700. String(hwndSys, "Debugger started\n"); Flush();
  701. modules = NULL; ignore = TRUE; fetchAdr = FALSE; level = 0;
  702. i = 0;
  703. while (i < MAX_THREADS) {
  704. threads[i].hThread = INVALID_HANDLE_VALUE;
  705. threads[i].dwThreadId = 0;
  706. i++;
  707. }
  708. while (WaitForDebugEvent(&event, INFINITE)) {
  709. debugAction = DBG_CONTINUE;
  710. switch (event.dwDebugEventCode) {
  711. case EXCEPTION_DEBUG_EVENT:
  712. if (!ignore) {
  713. if (!ignoreExceptions) {
  714. i = 0;
  715. while ( (i < MAX_THREADS) && (threads[i].dwThreadId != event.dwThreadId)) {
  716. i++;
  717. }
  718. if (i < MAX_THREADS) {
  719. hExcThread = threads[i].hThread;
  720. excPtrs.ExceptionRecord = &(event.u.Exception.ExceptionRecord);
  721. excPtrs.ContextRecord->ContextFlags = CONTEXT_FULL;
  722. GetThreadContext(hExcThread, excPtrs.ContextRecord);
  723. TrapMsg(&excPtrs, msg, FALSE);
  724. String(hwndExc, msg); Flush();
  725. if (trapByDefault == TRUE)
  726. {
  727. if (clearAlways==TRUE) Clear(hwndSys);
  728. ShowStack(&excPtrs, TRUE);
  729. debugAction = DBG_EXCEPTION_NOT_HANDLED;
  730. } else {
  731. EnableMenuItem(GetMenu(hwndMain), IDM_A_CONTINUE, MF_BYCOMMAND);
  732. EnableMenuItem(GetMenu(hwndMain), IDM_A_EXCEPTION, MF_BYCOMMAND);
  733. EnableMenuItem(GetMenu(hwndMain), IDM_A_TRAP, MF_BYCOMMAND);
  734. SuspendThread(hThread);
  735. }
  736. if (debugAction == DBG_CONTINUE) {
  737. String(hwndExc, " Continue\n");
  738. } else {
  739. String(hwndExc, " Exception\n");
  740. }
  741. } else {
  742. debugAction = DBG_EXCEPTION_NOT_HANDLED;
  743. String(hwndExc, " unknown thread\n");
  744. }
  745. } else {
  746. debugAction = DBG_EXCEPTION_NOT_HANDLED;
  747. }
  748. } else {
  749. ignore = FALSE;
  750. }
  751. break;
  752. case CREATE_THREAD_DEBUG_EVENT:
  753. wsprintf(msg, "CreateThread %i\n", event.dwThreadId);
  754. String(hwndExc, msg);
  755. i = 0;
  756. while ((threads[i].dwThreadId != event.dwThreadId) && (threads[i].hThread != INVALID_HANDLE_VALUE)) {
  757. i++;
  758. }
  759. threads[i].hThread = event.u.CreateThread.hThread;
  760. threads[i].dwThreadId = event.dwThreadId;
  761. break;
  762. case EXIT_THREAD_DEBUG_EVENT:
  763. wsprintf(msg, "ExitThread %i\n", event.dwThreadId);
  764. String(hwndExc, msg);
  765. i = 0;
  766. while (threads[i].dwThreadId != event.dwThreadId) {
  767. i++;
  768. }
  769. threads[i].hThread = INVALID_HANDLE_VALUE;
  770. threads[i].dwThreadId = 0;
  771. break;
  772. case CREATE_PROCESS_DEBUG_EVENT:
  773. if (hProcess == NULL) {
  774. hProcess = event.u.CreateProcessInfo.hProcess;
  775. processId = event.dwProcessId;
  776. wsprintf(msg, "CreateProcess (Thread %i)\n", event.dwThreadId);
  777. String(hwndExc, msg);
  778. i = 0;
  779. while ((threads[i].dwThreadId != event.dwThreadId) && (threads[i].hThread != INVALID_HANDLE_VALUE)) {
  780. i++;
  781. }
  782. threads[i].hThread = event.u.CreateProcessInfo.hThread;
  783. threads[i].dwThreadId = event.dwThreadId;
  784. } else {
  785. }
  786. break;
  787. case EXIT_PROCESS_DEBUG_EVENT:
  788. if (event.dwProcessId == processId) {
  789. wsprintf(msg, "ExitProcess (ret %i)\n", event.u.ExitProcess.dwExitCode);
  790. String(hwndExc, msg); Flush();
  791. PostMessage(hwndMain, WM_STOP, 0, 0);
  792. ExitThread(0);
  793. } else {
  794. }
  795. break;
  796. case OUTPUT_DEBUG_STRING_EVENT:
  797. debStr = event.u.DebugString.lpDebugStringData;
  798. len = event.u.DebugString.nDebugStringLength; read = len;
  799. while ((len > 0) && (read > 0)) {
  800. if (len > 1023 ) {
  801. ReadProcessMemory(proc.hProcess, debStr, msg, 1023, &read);
  802. } else {
  803. ReadProcessMemory(proc.hProcess, debStr, msg, len, &read);
  804. if (level == 0 ) {
  805. if (fetchAdr) {
  806. modules = NULL; i = 0;
  807. while ((msg[i] > ' ') && (i < read)) {
  808. if ((msg[i] >= '0') && (msg[i] <= '9')) {
  809. val = (DWORD)(msg[i])-(DWORD)'0';
  810. } else {
  811. val = 10+(DWORD)(msg[i])-(DWORD)'A';
  812. }
  813. modules = (LPVOID)(16*(DWORD)modules+val);
  814. i++;
  815. }
  816. wsprintf(mystring,"Oberon ready. (Modules= 0%lXH) \n",modules);
  817. level++; String(hwndSys, mystring);
  818. EnableMenuItem(GetMenu(hwndMain), IDM_A_STATE, MF_BYCOMMAND);
  819. EnableMenuItem(GetMenu(hwndMain), IDM_A_STACK, MF_BYCOMMAND);
  820. EnableMenuItem(GetMenu(hwndMain), IDM_A_ALLSTACKS, MF_BYCOMMAND);
  821. fetchAdr = FALSE;
  822. } else if (strncmp(msg, "Modules.root", 21) == 0) {
  823. fetchAdr = TRUE;
  824. }
  825. } else if ((level > 0) && (strncmp(msg, "Modules.Shutdown", 19) == 0)) {
  826. EnableMenuItem(GetMenu(hwndMain), IDM_A_STATE, MF_BYCOMMAND | MF_GRAYED);
  827. EnableMenuItem(GetMenu(hwndMain), IDM_A_STACK, MF_BYCOMMAND | MF_GRAYED);
  828. EnableMenuItem(GetMenu(hwndMain), IDM_A_ALLSTACKS, MF_BYCOMMAND | MF_GRAYED);
  829. level = 0; fetchAdr = FALSE; modules = NULL;
  830. String(hwndSys, "Oberon stopped\n");
  831. }
  832. }
  833. debStr = debStr+read; len = len-read;
  834. msg[read] = (OCHAR)0;
  835. // translate from Oberon to Windows
  836. String(hwndCon, msg);
  837. }
  838. break;
  839. default:
  840. break;
  841. }
  842. Flush();
  843. ContinueDebugEvent(event.dwProcessId, event.dwThreadId, debugAction);
  844. }
  845. } else {
  846. String(hwndExc, "CreateProcess failed!\n"); Flush();
  847. }
  848. PostMessage(hwndMain, WM_STOP, 0, 0);
  849. ExitThread(0);
  850. return 0;
  851. }
  852. BOOL CALLBACK StateDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  853. switch (uMsg) {
  854. case WM_INITDIALOG: {
  855. HWND hwndCB;
  856. LPVOID mod;
  857. DWORD read;
  858. LONGINT i;
  859. OCHAR modName[32];
  860. strcpy(module, ""); strcpy(workPath, "");
  861. GetPrivateProfileString("Debug", "Module", workPath, module, MaxString, iniFile);
  862. SetDlgItemText(hwndDlg, IDD_State, module);
  863. hwndCB = GetDlgItem(hwndDlg, IDD_State);
  864. i = 0; mod = (LPVOID)GetLInt(modules, &i);
  865. while (mod != NULL) {
  866. ReadProcessMemory(proc.hProcess, (LPVOID)((DWORD)mod+ModName), modName, 32, &read);
  867. SendMessage(hwndCB, CB_ADDSTRING, (WPARAM)0, (LPARAM)(&modName));
  868. i = 0; mod = (LPVOID)GetLInt((LPVOID)((DWORD)mod+ModNext), &i);
  869. }
  870. return TRUE;
  871. }
  872. break;
  873. case WM_COMMAND:
  874. if (LOWORD(wParam) == IDD_Ok) {
  875. GetDlgItemText(hwndDlg, IDD_State, module, MaxString);
  876. if (strcmp(module, "") != 0) {
  877. WritePrivateProfileString("Debug", "Module", module, iniFile);
  878. }
  879. EndDialog(hwndDlg, 0);
  880. return TRUE;
  881. } else if (LOWORD(wParam) == IDD_Cancel) {
  882. strcpy(module, "");
  883. EndDialog(hwndDlg, 0);
  884. return TRUE;
  885. }
  886. break;
  887. default:
  888. return FALSE;
  889. }
  890. return FALSE;
  891. }
  892. BOOL CALLBACK StackDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  893. int i;
  894. switch (uMsg) {
  895. case WM_INITDIALOG: {
  896. HWND hwndCB;
  897. DWORD i;
  898. OCHAR str[64];
  899. strcpy(module, ""); strcpy(workPath, "");
  900. GetPrivateProfileString("Debug", "Thread", workPath, module, MaxString, iniFile);
  901. SetDlgItemText(hwndDlg, IDD_Stack, module);
  902. hwndCB = GetDlgItem(hwndDlg, IDD_Stack);
  903. i = 0;
  904. while (i < MAX_THREADS) {
  905. if (threads[i].hThread != INVALID_HANDLE_VALUE) {
  906. wsprintf(str, "%lu", threads[i].dwThreadId);
  907. SendMessage(hwndCB, CB_ADDSTRING, (WPARAM)0, (LPARAM)(&str));
  908. }
  909. i++;
  910. }
  911. return TRUE;
  912. }
  913. break;
  914. case WM_COMMAND:
  915. if (LOWORD(wParam) == IDD_Ok) {
  916. GetDlgItemText(hwndDlg, IDD_Stack, module, MaxString);
  917. if (strcmp(module, "") != 0) {
  918. WritePrivateProfileString("Debug", "Thread", module, iniFile);
  919. }
  920. EndDialog(hwndDlg, 0);
  921. return TRUE;
  922. } else if (LOWORD(wParam) == IDD_Cancel) {
  923. strcpy(module, "");
  924. EndDialog(hwndDlg, 0);
  925. return TRUE;
  926. } else if (LOWORD(wParam) == IDD_AllStacks) // show all stacks
  927. {
  928. if (clearAlways==TRUE) Clear(hwndSys);
  929. ShowAllStacks();
  930. /* OCHAR str[64];
  931. i = 0;excPtrs.ExceptionRecord = (PEXCEPTION_RECORD)malloc(sizeof(EXCEPTION_RECORD));
  932. if (clearAlways==TRUE) Clear(hwndSys);
  933. while (i < MAX_THREADS) {
  934. if (threads[i].hThread != INVALID_HANDLE_VALUE) {
  935. excPtrs.ContextRecord->ContextFlags = CONTEXT_FULL;
  936. GetThreadContext(threads[i].hThread, excPtrs.ContextRecord);
  937. excPtrs.ExceptionRecord->ExceptionCode = 0;
  938. excPtrs.ExceptionRecord->ExceptionAddress = (LPVOID)(excPtrs.ContextRecord->Eip);
  939. wsprintf(str, "\n ThreadId: %lu", threads[i].dwThreadId);
  940. String(hwndSys, str);
  941. ShowStack(&excPtrs, FALSE);
  942. }
  943. i++;
  944. }
  945. free(excPtrs.ExceptionRecord);
  946. */
  947. EndDialog(hwndDlg, 0);
  948. strcpy(module, "");
  949. return TRUE;
  950. }
  951. break;
  952. default:
  953. return FALSE;
  954. }
  955. return FALSE;
  956. }
  957. BOOL CALLBACK StartDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  958. INT i, j;
  959. switch (uMsg) {
  960. case WM_INITDIALOG: {
  961. HWND hwndCB;
  962. char key[32];
  963. char str[MAX_PATH];
  964. SetDlgItemText(hwndDlg, IDD_ExePath, exePath);
  965. hwndCB = GetDlgItem(hwndDlg, IDD_ExePath);
  966. i = 1; j = 0;
  967. do {
  968. wsprintf(key, "Exe%i", i); i++;
  969. strcpy(str, ""); strcpy(workPath, "");
  970. j = GetPrivateProfileString("Debug", key, workPath, str, MAX_PATH, iniFile);
  971. if (j > 0) {
  972. SendMessage(hwndCB, CB_ADDSTRING, (WPARAM)0, (LPARAM)(&str));
  973. }
  974. } while (j > 0);
  975. return TRUE;
  976. }
  977. break;
  978. case WM_COMMAND:
  979. if (LOWORD(wParam) == IDD_Ok) {
  980. GetDlgItemText(hwndDlg, IDD_ExePath, exePath, MAX_PATH);
  981. strcpy(workPath, exePath);
  982. i = 0; j = -1;
  983. while (workPath[i] != (OCHAR)0) {
  984. if (workPath[i] == '\\') {
  985. j = i;
  986. }
  987. i++;
  988. }
  989. workPath[j+1] = (OCHAR)0;
  990. SendMessage(hwndMain, WM_START, 0, 0);
  991. EndDialog(hwndDlg, 0);
  992. return TRUE;
  993. } else if (LOWORD(wParam) == IDD_Open) {
  994. OPENFILENAME ofn;
  995. char filter[32];
  996. ZeroMemory(&ofn, sizeof(ofn));
  997. ofn.lStructSize = sizeof(ofn);
  998. ofn.hwndOwner = hwndDlg;
  999. strcpy(filter, "Executable Files *.EXE");
  1000. filter[16] = 0; filter[22] = 0; filter[23] = 0;
  1001. ofn.lpstrFilter = filter;
  1002. ofn.lpstrFile = exePath;
  1003. ofn.nMaxFile = MAX_PATH;
  1004. if (GetOpenFileName(&ofn)) {
  1005. SetDlgItemText(hwndDlg, IDD_ExePath, exePath);
  1006. }
  1007. return TRUE;
  1008. } else if (LOWORD(wParam) == IDD_Cancel) {
  1009. EnableMenuItem(GetMenu(hwndMain), IDM_D_Start, MF_BYCOMMAND);
  1010. EnableMenuItem(GetMenu(hwndMain), IDM_D_Attach, MF_BYCOMMAND);
  1011. EndDialog(hwndDlg, 0);
  1012. return TRUE;
  1013. }
  1014. break;
  1015. default:
  1016. return FALSE;
  1017. }
  1018. return FALSE;
  1019. }
  1020. BOOL CALLBACK AttachDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  1021. switch (uMsg) {
  1022. case WM_INITDIALOG:
  1023. SetDlgItemText(hwndDlg, IDD_ProcessID, "");
  1024. return TRUE;
  1025. break;
  1026. case WM_COMMAND:
  1027. if (LOWORD(wParam) == IDD_Ok) {
  1028. GetDlgItemText(hwndDlg, IDD_ProcessID, exePath, MAX_PATH);
  1029. SendMessage(hwndMain, WM_START, 0, 0);
  1030. EndDialog(hwndDlg, 0);
  1031. return TRUE;
  1032. } else if (LOWORD(wParam) == IDD_Cancel) {
  1033. EnableMenuItem(GetMenu(hwndMain), IDM_D_Start, MF_BYCOMMAND);
  1034. EnableMenuItem(GetMenu(hwndMain), IDM_D_Attach, MF_BYCOMMAND);
  1035. EndDialog(hwndDlg, 0);
  1036. return TRUE;
  1037. }
  1038. break;
  1039. default:
  1040. return FALSE;
  1041. }
  1042. return FALSE;
  1043. }
  1044. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  1045. switch (uMsg) {
  1046. case WM_START:
  1047. Clear(hwndCon); Clear(hwndExc); Clear(hwndSys);
  1048. EnableMenuItem(GetMenu(hWnd), IDM_D_Start, MF_BYCOMMAND | MF_GRAYED);
  1049. EnableMenuItem(GetMenu(hWnd), IDM_D_Attach, MF_BYCOMMAND | MF_GRAYED);
  1050. hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadId);
  1051. break;
  1052. case WM_STOP:
  1053. EnableMenuItem(GetMenu(hWnd), IDM_A_STATE, MF_BYCOMMAND | MF_GRAYED);
  1054. EnableMenuItem(GetMenu(hWnd), IDM_A_STACK, MF_BYCOMMAND | MF_GRAYED);
  1055. EnableMenuItem(GetMenu(hWnd), IDM_A_ALLSTACKS, MF_BYCOMMAND | MF_GRAYED);
  1056. EnableMenuItem(GetMenu(hWnd), IDM_D_Stop, MF_BYCOMMAND | MF_GRAYED);
  1057. if (proc.hThread != INVALID_HANDLE_VALUE) {
  1058. CloseHandle(proc.hThread);
  1059. proc.hThread = INVALID_HANDLE_VALUE;
  1060. }
  1061. if (proc.hProcess != INVALID_HANDLE_VALUE) {
  1062. TerminateProcess(proc.hProcess, 0);
  1063. CloseHandle(proc.hProcess);
  1064. proc.hProcess = INVALID_HANDLE_VALUE;
  1065. }
  1066. TerminateThread(hThread, 0);
  1067. CloseHandle(hThread);
  1068. String(hwndSys, "Debugger stopped\n"); Flush();
  1069. hThread = INVALID_HANDLE_VALUE;
  1070. EnableMenuItem(GetMenu(hwndMain), IDM_D_Start, MF_BYCOMMAND);
  1071. EnableMenuItem(GetMenu(hwndMain), IDM_D_Attach, MF_BYCOMMAND);
  1072. break;
  1073. case WM_COMMAND:
  1074. switch (LOWORD(wParam)) {
  1075. case IDM_D_Start:
  1076. EnableMenuItem(GetMenu(hWnd), IDM_D_Start, MF_BYCOMMAND | MF_GRAYED);
  1077. EnableMenuItem(GetMenu(hWnd), IDM_D_Attach, MF_BYCOMMAND | MF_GRAYED);
  1078. DialogBox(hInst, "Debug_Start_Dialog", hWnd, StartDlgProc);
  1079. break;
  1080. case IDM_D_Attach:
  1081. EnableMenuItem(GetMenu(hWnd), IDM_D_Start, MF_BYCOMMAND | MF_GRAYED);
  1082. EnableMenuItem(GetMenu(hWnd), IDM_D_Attach, MF_BYCOMMAND | MF_GRAYED);
  1083. DialogBox(hInst, "Debug_Attach_Dialog", hWnd, AttachDlgProc);
  1084. break;
  1085. case IDM_D_Stop:
  1086. SendMessage(hWnd, WM_STOP, 0, 0);
  1087. break;
  1088. case IDM_D_Exit:
  1089. SendMessage(hWnd, WM_CLOSE, 0, 0);
  1090. break;
  1091. case IDM_W_ONTOP:
  1092. if (CheckMenuItem(GetMenu(hWnd), IDM_W_ONTOP, MF_BYCOMMAND | MF_CHECKED) == MF_CHECKED) {
  1093. CheckMenuItem(GetMenu(hWnd), IDM_W_ONTOP, MF_BYCOMMAND | MF_UNCHECKED);
  1094. SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  1095. WritePrivateProfileString("Debug", "OnTop", "Off", iniFile);
  1096. } else {
  1097. SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  1098. WritePrivateProfileString("Debug", "OnTop", "On", iniFile);
  1099. }
  1100. break;
  1101. case IDM_W_TILE:
  1102. SendMessage(hwndMDIClient, WM_MDITILE, 0, 0);
  1103. break;
  1104. case IDM_W_CASCADE:
  1105. SendMessage(hwndMDIClient, WM_MDICASCADE, 0, 0);
  1106. break;
  1107. case IDM_W_ICONS:
  1108. SendMessage(hwndMDIClient, WM_MDIICONARRANGE, 0, 0);
  1109. break;
  1110. case IDM_W_CALL:
  1111. Clear(hwndCon); Clear(hwndExc); Clear(hwndSys);
  1112. break;
  1113. case IDM_W_CCONSOLE:
  1114. Clear(hwndCon);
  1115. break;
  1116. case IDM_W_CEXCEPTION:
  1117. Clear(hwndExc);
  1118. break;
  1119. case IDM_W_CSYSTEM:
  1120. Clear(hwndSys);
  1121. break;
  1122. case IDM_H_About:
  1123. DialogBox(hInst, "Debug_About_Dialog", hWnd, AboutDlgProc);
  1124. break;
  1125. case IDM_A_IGNORE:
  1126. if (CheckMenuItem(GetMenu(hWnd), IDM_A_IGNORE, MF_BYCOMMAND | MF_CHECKED) == MF_CHECKED) {
  1127. CheckMenuItem(GetMenu(hWnd), IDM_A_IGNORE, MF_BYCOMMAND | MF_UNCHECKED);
  1128. ignoreExceptions = FALSE;
  1129. WritePrivateProfileString("Debug", "Ignore", "Off", iniFile);
  1130. } else {
  1131. ignoreExceptions = TRUE;
  1132. WritePrivateProfileString("Debug", "Ignore", "On", iniFile);
  1133. }
  1134. break;
  1135. case IDM_A_CLEARDEFAULT:
  1136. if (CheckMenuItem(GetMenu(hWnd), IDM_A_CLEARDEFAULT, MF_BYCOMMAND | MF_CHECKED) == MF_CHECKED) {
  1137. CheckMenuItem(GetMenu(hWnd), IDM_A_CLEARDEFAULT, MF_BYCOMMAND | MF_UNCHECKED);
  1138. clearAlways = FALSE;
  1139. WritePrivateProfileString("Debug", "Clear", "Off", iniFile);
  1140. } else {
  1141. clearAlways = TRUE;
  1142. WritePrivateProfileString("Debug", "Clear", "On", iniFile);
  1143. }
  1144. break;
  1145. case IDM_A_TRAPDEFAULT:
  1146. if (CheckMenuItem(GetMenu(hWnd), IDM_A_TRAPDEFAULT, MF_BYCOMMAND | MF_CHECKED) == MF_CHECKED) {
  1147. CheckMenuItem(GetMenu(hWnd), IDM_A_TRAPDEFAULT, MF_BYCOMMAND | MF_UNCHECKED);
  1148. trapByDefault = FALSE;
  1149. WritePrivateProfileString("Debug", "TrapByDefault", "Off", iniFile);
  1150. } else {
  1151. trapByDefault = TRUE;
  1152. WritePrivateProfileString("Debug", "TrapByDefault", "On", iniFile);
  1153. }
  1154. break;
  1155. case IDM_A_EXCEPTION:
  1156. debugAction = DBG_EXCEPTION_NOT_HANDLED;
  1157. case IDM_A_CONTINUE:
  1158. EnableMenuItem(GetMenu(hWnd), IDM_A_CONTINUE, MF_BYCOMMAND | MF_GRAYED);
  1159. EnableMenuItem(GetMenu(hWnd), IDM_A_EXCEPTION, MF_BYCOMMAND | MF_GRAYED);
  1160. EnableMenuItem(GetMenu(hWnd), IDM_A_TRAP, MF_BYCOMMAND | MF_GRAYED);
  1161. ResumeThread(hThread);
  1162. break;
  1163. case IDM_A_TRAP:
  1164. if (clearAlways == TRUE) Clear(hwndSys);
  1165. ShowStack(&excPtrs, TRUE);
  1166. break;
  1167. case IDM_A_STATE:
  1168. DialogBox(hInst, "Debug_State_Dialog", hWnd, StateDlgProc);
  1169. if (strcmp(module, "") != 0) {
  1170. if (clearAlways==TRUE) Clear(hwndSys);
  1171. ShowState(module);
  1172. }
  1173. break;
  1174. case IDM_A_ALLSTACKS:{
  1175. if (clearAlways==TRUE) Clear(hwndSys);
  1176. ShowAllStacks();
  1177. }
  1178. break;
  1179. case IDM_A_STACK: {
  1180. DWORD dw, i;
  1181. OCHAR msg[128];
  1182. DialogBox(hInst, "Debug_Stack_Dialog", hWnd, StackDlgProc);
  1183. if (strcmp(module, "") != 0) {
  1184. sscanf(module, "%lu", &dw);
  1185. i = 0;
  1186. while ((i < MAX_THREADS) && (threads[i].dwThreadId != dw)) {
  1187. i++;
  1188. }
  1189. if (i < MAX_THREADS) {
  1190. excPtrs.ExceptionRecord = (PEXCEPTION_RECORD)malloc(sizeof(EXCEPTION_RECORD));
  1191. excPtrs.ContextRecord->ContextFlags = CONTEXT_FULL;
  1192. GetThreadContext(threads[i].hThread, excPtrs.ContextRecord);
  1193. excPtrs.ExceptionRecord->ExceptionCode = 0;
  1194. excPtrs.ExceptionRecord->ExceptionAddress = (LPVOID)(excPtrs.ContextRecord->Eip);
  1195. if (clearAlways==TRUE) Clear(hwndSys);
  1196. ShowStack(&excPtrs, FALSE);
  1197. free(excPtrs.ExceptionRecord);
  1198. } else {
  1199. if (clearAlways==TRUE) Clear(hwndSys);
  1200. wsprintf(msg, "ShowStack %i\n", dw);
  1201. String(hwndSys, msg);
  1202. wsprintf(msg, "\tThread not found\n\n", dw);
  1203. String(hwndSys, msg);
  1204. Flush();
  1205. }
  1206. }
  1207. break;
  1208. }
  1209. default:
  1210. return DefFrameProc(hWnd, hwndMDIClient, uMsg, wParam, lParam);
  1211. break;
  1212. }
  1213. break;
  1214. case WM_CREATE: {
  1215. CLIENTCREATESTRUCT ccs;
  1216. INT i, j;
  1217. proc.hThread = INVALID_HANDLE_VALUE;
  1218. proc.hProcess = INVALID_HANDLE_VALUE;
  1219. ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), IDM_W_POS);
  1220. ccs.idFirstChild = IDM_WIN_CHILD;
  1221. hwndMDIClient = CreateWindow("MDIClient", NULL, WS_CHILD | WS_CLIPCHILDREN |
  1222. WS_VSCROLL | WS_HSCROLL, 0, 0, 0, 0, hWnd, (HMENU)ID_EDIT, hInst, (LPVOID)&ccs);
  1223. ShowWindow(hwndMDIClient, SW_SHOW);
  1224. hwndCon = CreateMDIWindow("Debug_Child_class", "Console", MDIS_ALLCHILDSTYLES |
  1225. WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN,
  1226. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndMDIClient,
  1227. hInst, (LPARAM)NULL);
  1228. ShowWindow(hwndCon, SW_SHOW);
  1229. hwndExc = CreateMDIWindow("Debug_Child_class", "Exception", MDIS_ALLCHILDSTYLES |
  1230. WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN,
  1231. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndMDIClient,
  1232. hInst, (LPARAM)NULL);
  1233. ShowWindow(hwndExc, SW_SHOW);
  1234. hwndSys = CreateMDIWindow("Debug_Child_class", "System", MDIS_ALLCHILDSTYLES |
  1235. WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN,
  1236. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndMDIClient,
  1237. hInst, (LPARAM)NULL);
  1238. ShowWindow(hwndSys, SW_SHOW);
  1239. PostMessage(hwndMDIClient, WM_MDITILE, 0, 0);
  1240. GetModuleFileName(NULL, iniFile, MAX_PATH);
  1241. i = 0; j = 0;
  1242. while (iniFile[i] != (OCHAR)0) {
  1243. if (iniFile[i] == '.') {
  1244. j = i;
  1245. }
  1246. i++;
  1247. }
  1248. iniFile[j+1] = 'i'; iniFile[j+2] = 'n';
  1249. iniFile[j+3] = 'i'; iniFile[j+4] = (OCHAR)0;
  1250. strcpy(exePath, ""); strcpy(workPath, "");
  1251. GetPrivateProfileString("Debug", "OnTop", workPath, exePath, MAX_PATH, iniFile);
  1252. if (strcmp(exePath, "On") == 0) {
  1253. CheckMenuItem(GetMenu(hWnd), IDM_W_ONTOP, MF_BYCOMMAND | MF_CHECKED);
  1254. SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  1255. }
  1256. GetPrivateProfileString("Debug", "Ignore", workPath, exePath, MAX_PATH, iniFile);
  1257. if (strcmp(exePath, "On") == 0) {
  1258. CheckMenuItem(GetMenu(hWnd), IDM_A_IGNORE, MF_BYCOMMAND | MF_CHECKED);
  1259. ignoreExceptions = TRUE;
  1260. }
  1261. GetPrivateProfileString("Debug", "Clear", workPath, exePath, MAX_PATH, iniFile);
  1262. if (strcmp(exePath, "On") == 0) {
  1263. CheckMenuItem(GetMenu(hWnd), IDM_A_CLEARDEFAULT, MF_BYCOMMAND | MF_CHECKED);
  1264. clearAlways = TRUE;
  1265. }
  1266. GetPrivateProfileString("Debug", "TrapByDefault", workPath, exePath, MAX_PATH, iniFile);
  1267. if (strcmp(exePath, "Off") == 0)
  1268. {
  1269. CheckMenuItem(GetMenu(hWnd), IDM_A_TRAPDEFAULT, MF_BYCOMMAND);
  1270. trapByDefault = FALSE;
  1271. }
  1272. else
  1273. {
  1274. CheckMenuItem(GetMenu(hWnd), IDM_A_TRAPDEFAULT, MF_BYCOMMAND | MF_CHECKED);
  1275. trapByDefault = TRUE;
  1276. }
  1277. strcpy(exePath, ""); strcpy(workPath, "");
  1278. GetPrivateProfileString("Debug", "Exe", workPath, exePath, MAX_PATH, iniFile);
  1279. excPtrs.ContextRecord = (PCONTEXT)malloc(sizeof(CONTEXT));
  1280. break;
  1281. }
  1282. case WM_CLOSE:
  1283. SendMessage(hWnd, WM_STOP, 0, 0);
  1284. DestroyWindow(hWnd);
  1285. break;
  1286. case WM_DESTROY:
  1287. free(excPtrs.ContextRecord);
  1288. PostQuitMessage(0);
  1289. break;
  1290. default:
  1291. return DefFrameProc(hWnd, hwndMDIClient, uMsg, wParam, lParam);
  1292. }
  1293. return 0;
  1294. }