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.

719 lines
26 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // VDM debugging support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. BOOL fVDMInitDone;
  10. BOOL fVDMActive;
  11. VDMPROCESSEXCEPTIONPROC pfnVDMProcessException;
  12. VDMGETTHREADSELECTORENTRYPROC pfnVDMGetThreadSelectorEntry;
  13. VDMGETPOINTERPROC pfnVDMGetPointer;
  14. VDMGETCONTEXTPROC pfnVDMGetContext;
  15. VDMSETCONTEXTPROC pfnVDMSetContext;
  16. VDMGETSELECTORMODULEPROC pfnVDMGetSelectorModule;
  17. #define SEGTYPE_AVAILABLE 0
  18. #define SEGTYPE_V86 1
  19. #define SEGTYPE_PROT 2
  20. #define MAXSEGENTRY 1024
  21. SEGENTRY segtable[MAXSEGENTRY];
  22. VOID VDMRegCmd(
  23. LPSTR achInput,
  24. X86_NT5_CONTEXT *pvc
  25. )
  26. {
  27. DWORD dwVal;
  28. if ( _stricmp(achInput,"rp") == 0 )
  29. {
  30. g_Target->m_Machines[MACHIDX_I386]->
  31. OutputAll(g_Target->m_Machines[MACHIDX_I386]->m_AllMask,
  32. DEBUG_OUTPUT_NORMAL);
  33. return;
  34. }
  35. if (achInput[1] != 'e')
  36. {
  37. dprintf("VDM R: can only operate on 32-bit registers\n");
  38. return;
  39. }
  40. if (strlen(achInput) < 6) {
  41. dprintf("VDM R: Missing value\n");
  42. return;
  43. }
  44. dwVal = strtoul(&achInput[5], NULL, 16);
  45. if ( _strnicmp(&achInput[2],"ax", 2) == 0 ) {
  46. pvc->Eax = dwVal;
  47. } else if ( _strnicmp(&achInput[2],"bx", 2) == 0 ) {
  48. pvc->Ebx = dwVal;
  49. } else if ( _strnicmp(&achInput[2],"cx", 2) == 0 ) {
  50. pvc->Ecx = dwVal;
  51. } else if ( _strnicmp(&achInput[2],"dx", 2) == 0 ) {
  52. pvc->Edx = dwVal;
  53. } else if ( _strnicmp(&achInput[2],"si", 2) == 0 ) {
  54. pvc->Esi = dwVal;
  55. } else if ( _strnicmp(&achInput[2],"di", 2) == 0 ) {
  56. pvc->Edi = dwVal;
  57. } else if ( _strnicmp(&achInput[2],"ip", 2) == 0 ) {
  58. pvc->Eip = dwVal;
  59. } else if ( _strnicmp(&achInput[2],"sp", 2) == 0 ) {
  60. pvc->Esp = dwVal;
  61. } else if ( _strnicmp(&achInput[2],"bp", 2) == 0 ) {
  62. pvc->Ebp = dwVal;
  63. } else if ( _strnicmp(&achInput[2],"fl", 2) == 0 ) {
  64. pvc->EFlags = dwVal;
  65. } else {
  66. dprintf("Invalid register\n");
  67. return;
  68. }
  69. dprintf("%.8X will be flushed to '%3.3s'. Use 'rp' to display pending values\n",
  70. dwVal,
  71. &achInput[1]);
  72. }
  73. void
  74. DebugEvent64To(LPDEBUG_EVENT64 Event64,
  75. LPDEBUG_EVENT Event)
  76. {
  77. Event->dwDebugEventCode = Event64->dwDebugEventCode;
  78. Event->dwProcessId = Event64->dwProcessId;
  79. Event->dwThreadId = Event64->dwThreadId;
  80. switch(Event64->dwDebugEventCode)
  81. {
  82. case EXCEPTION_DEBUG_EVENT:
  83. ExceptionRecord64To(&Event64->u.Exception.ExceptionRecord,
  84. &Event->u.Exception.ExceptionRecord);
  85. Event->u.Exception.dwFirstChance =
  86. Event64->u.Exception.dwFirstChance;
  87. break;
  88. case CREATE_THREAD_DEBUG_EVENT:
  89. Event->u.CreateThread.hThread =
  90. (PVOID)(ULONG_PTR)(Event64->u.CreateThread.hThread);
  91. Event->u.CreateThread.lpThreadLocalBase =
  92. (PVOID)(ULONG_PTR)(Event64->u.CreateThread.lpThreadLocalBase);
  93. Event->u.CreateThread.lpStartAddress =
  94. (LPTHREAD_START_ROUTINE)(ULONG_PTR)(Event64->u.CreateThread.lpStartAddress);
  95. break;
  96. case CREATE_PROCESS_DEBUG_EVENT:
  97. Event->u.CreateProcessInfo.hFile =
  98. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hFile);
  99. Event->u.CreateProcessInfo.hProcess =
  100. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hProcess);
  101. Event->u.CreateProcessInfo.hThread =
  102. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.hThread);
  103. Event->u.CreateProcessInfo.lpBaseOfImage =
  104. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpBaseOfImage);
  105. Event->u.CreateProcessInfo.dwDebugInfoFileOffset =
  106. Event64->u.CreateProcessInfo.dwDebugInfoFileOffset;
  107. Event->u.CreateProcessInfo.nDebugInfoSize =
  108. Event64->u.CreateProcessInfo.nDebugInfoSize;
  109. Event->u.CreateProcessInfo.lpThreadLocalBase =
  110. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpThreadLocalBase);
  111. Event->u.CreateProcessInfo.lpStartAddress =
  112. (LPTHREAD_START_ROUTINE)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpStartAddress);
  113. Event->u.CreateProcessInfo.lpImageName =
  114. (PVOID)(ULONG_PTR)(Event64->u.CreateProcessInfo.lpImageName);
  115. Event->u.CreateProcessInfo.fUnicode =
  116. Event64->u.CreateProcessInfo.fUnicode;
  117. break;
  118. case EXIT_THREAD_DEBUG_EVENT:
  119. Event->u.ExitThread.dwExitCode =
  120. Event64->u.ExitThread.dwExitCode;
  121. break;
  122. case EXIT_PROCESS_DEBUG_EVENT:
  123. Event->u.ExitProcess.dwExitCode =
  124. Event64->u.ExitProcess.dwExitCode;
  125. break;
  126. case LOAD_DLL_DEBUG_EVENT:
  127. Event->u.LoadDll.hFile =
  128. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.hFile);
  129. Event->u.LoadDll.lpBaseOfDll =
  130. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.lpBaseOfDll);
  131. Event->u.LoadDll.dwDebugInfoFileOffset =
  132. Event64->u.LoadDll.dwDebugInfoFileOffset;
  133. Event->u.LoadDll.nDebugInfoSize =
  134. Event64->u.LoadDll.nDebugInfoSize;
  135. Event->u.LoadDll.lpImageName =
  136. (PVOID)(ULONG_PTR)(Event64->u.LoadDll.lpImageName);
  137. Event->u.LoadDll.fUnicode =
  138. Event64->u.LoadDll.fUnicode;
  139. break;
  140. case UNLOAD_DLL_DEBUG_EVENT:
  141. Event->u.UnloadDll.lpBaseOfDll =
  142. (PVOID)(ULONG_PTR)(Event64->u.UnloadDll.lpBaseOfDll);
  143. break;
  144. case OUTPUT_DEBUG_STRING_EVENT:
  145. Event->u.DebugString.lpDebugStringData =
  146. (LPSTR)(ULONG_PTR)(Event64->u.DebugString.lpDebugStringData);
  147. Event->u.DebugString.fUnicode =
  148. Event64->u.DebugString.fUnicode;
  149. Event->u.DebugString.nDebugStringLength =
  150. Event64->u.DebugString.nDebugStringLength;
  151. break;
  152. case RIP_EVENT:
  153. Event->u.RipInfo.dwError =
  154. Event64->u.RipInfo.dwError;
  155. Event->u.RipInfo.dwType =
  156. Event64->u.RipInfo.dwType;
  157. break;
  158. }
  159. }
  160. ULONG
  161. VDMEvent(DEBUG_EVENT64* pDebugEvent)
  162. /*
  163. returns - 0, if exception not handled
  164. STATUS_VDM_EVENT, if exception handled
  165. otherwise, the return value is the translated event status,
  166. for example STATUS_BREAKPOINT
  167. */
  168. {
  169. LPSTR Str;
  170. LPSTR pFileName;
  171. BOOL b;
  172. ULONG lpNumberOfBytesRead;
  173. UINT_PTR address;
  174. PULONG_PTR lpdw;
  175. int segslot;
  176. int mode;
  177. BOOL fData;
  178. WORD selector;
  179. WORD segment;
  180. WORD newselect;
  181. BOOL fStop;
  182. DWORD ImgLen;
  183. ULONG ulRet;
  184. BOOL fNeedSegTableEdit;
  185. BOOL fNeedInteractive;
  186. BOOL fVerbose;
  187. CHAR achInput[_MAX_PATH];
  188. BOOL fProcess;
  189. SEGMENT_NOTE se;
  190. IMAGE_NOTE im;
  191. BOOL bProtectMode;
  192. WORD EventFlags;
  193. ulRet = VDMEVENT_HANDLED;
  194. if (!fVDMInitDone) {
  195. fVDMInitDone = TRUE;
  196. HINSTANCE hmodVDM = NULL;
  197. const char* c_szVDMFailed = NULL;
  198. fVDMActive = (
  199. (hmodVDM = LoadLibrary("VDMDBG.DLL")) &&
  200. (pfnVDMProcessException = (VDMPROCESSEXCEPTIONPROC)
  201. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMProcessException")
  202. ) &&
  203. (pfnVDMGetPointer = (VDMGETPOINTERPROC)
  204. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetPointer")
  205. ) &&
  206. (pfnVDMGetThreadSelectorEntry = (VDMGETTHREADSELECTORENTRYPROC)
  207. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetThreadSelectorEntry")
  208. ) &&
  209. (pfnVDMGetContext = (VDMGETCONTEXTPROC)
  210. GetProcAddress(hmodVDM, c_szVDMFailed = "VDMGetContext")
  211. ) &&
  212. (pfnVDMSetContext = (VDMSETCONTEXTPROC)
  213. GetProcAddress( hmodVDM, c_szVDMFailed = "VDMSetContext")
  214. ) &&
  215. (pfnVDMGetSelectorModule = (VDMGETSELECTORMODULEPROC)
  216. GetProcAddress( hmodVDM, c_szVDMFailed = "VDMGetSelectorModule")
  217. )
  218. ); // fVDMActive
  219. if (!fVDMActive) { // display error on first time...
  220. if (!hmodVDM) {
  221. dprintf("LoadLibrary(VDMDBG.DLL) failed\n");
  222. }
  223. else if (c_szVDMFailed && *c_szVDMFailed) { // is valid printable string
  224. dprintf("%s can not be found in VDMDBG.DLL\n", c_szVDMFailed);
  225. }
  226. else {
  227. dprintf("Unknown failure while initializing VDMDBG.DLL\n");
  228. } // iff
  229. } // if
  230. } // if
  231. if (!fVDMActive) return VDMEVENT_NOT_HANDLED;
  232. DEBUG_EVENT Event;
  233. DebugEvent64To(pDebugEvent, &Event);
  234. lpdw = &(Event.u.Exception.ExceptionRecord.ExceptionInformation[0]);
  235. fProcess = (*pfnVDMProcessException)(&Event);
  236. fNeedSegTableEdit = FALSE;
  237. fNeedInteractive = FALSE;
  238. fVerbose = FALSE;
  239. mode = LOWORD(lpdw[0]);
  240. EventFlags = HIWORD(lpdw[0]);
  241. bProtectMode = (BOOL) (EventFlags & VDMEVENT_PE);
  242. // Has the caller explicitly asked for interaction?
  243. if (EventFlags & VDMEVENT_NEEDS_INTERACTIVE) {
  244. fNeedInteractive = TRUE;
  245. }
  246. if (EventFlags & VDMEVENT_VERBOSE) {
  247. fVerbose = TRUE;
  248. }
  249. switch( mode ) {
  250. case DBG_SEGLOAD:
  251. case DBG_SEGMOVE:
  252. case DBG_SEGFREE:
  253. case DBG_MODLOAD:
  254. case DBG_MODFREE:
  255. address = lpdw[2];
  256. b = g_Target->ReadVirtual(g_Process, EXTEND64(address),
  257. &se, sizeof(se),
  258. &lpNumberOfBytesRead ) == S_OK;
  259. if ( !b || lpNumberOfBytesRead != sizeof(se) )
  260. {
  261. return( VDMEVENT_NOT_HANDLED );
  262. }
  263. break;
  264. case DBG_DLLSTART:
  265. case DBG_DLLSTOP:
  266. case DBG_TASKSTART:
  267. case DBG_TASKSTOP:
  268. address = lpdw[2];
  269. b = g_Target->ReadVirtual(g_Process, EXTEND64(address),
  270. &im, sizeof(im),
  271. &lpNumberOfBytesRead ) == S_OK;
  272. if ( !b || lpNumberOfBytesRead != sizeof(im) )
  273. {
  274. return( VDMEVENT_NOT_HANDLED );
  275. }
  276. break;
  277. }
  278. switch( mode ) {
  279. default:
  280. ulRet = VDMEVENT_NOT_HANDLED;
  281. break;
  282. case DBG_SEGLOAD:
  283. fNeedSegTableEdit = TRUE;
  284. selector = se.Selector1;
  285. segment = se.Segment;
  286. fData = (BOOL)se.Type;
  287. segslot = 0;
  288. while ( segslot < MAXSEGENTRY ) {
  289. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  290. if ( _stricmp(segtable[segslot].path_name, se.FileName) == 0 ) {
  291. break;
  292. }
  293. }
  294. segslot++;
  295. }
  296. if ( segslot == MAXSEGENTRY ) {
  297. if ( strlen(se.FileName) != 0 ) {
  298. dprintf("Loading [%s]\n", se.FileName );
  299. }
  300. }
  301. if (fVerbose) {
  302. dprintf("VDM SegLoad: %s(%d) %s => %x\n",
  303. se.FileName,
  304. segment,
  305. fData ? "Data" : "Code",
  306. selector);
  307. }
  308. break;
  309. case DBG_SEGMOVE:
  310. fNeedSegTableEdit = TRUE;
  311. segment = se.Segment;
  312. selector = se.Selector1;
  313. newselect = se.Selector2;
  314. if ( newselect == 0 ) {
  315. mode = DBG_SEGFREE;
  316. } else if (segment > 1) {
  317. //
  318. // real mode module is getting split up into different
  319. // segments, so create a new segtable entry
  320. //
  321. segslot = 0;
  322. while ( segslot < MAXSEGENTRY ) {
  323. if (( segtable[segslot].type != SEGTYPE_AVAILABLE ) &&
  324. ( segtable[segslot].selector == selector )) {
  325. mode = DBG_MODLOAD;
  326. segment--; //make it zero-based
  327. selector = newselect;
  328. pFileName = segtable[segslot].path_name;
  329. // Don't have the image length here so
  330. // just choose one.
  331. ImgLen = segtable[segslot].ImgLen;
  332. break;
  333. }
  334. segslot++;
  335. }
  336. }
  337. if (fVerbose) {
  338. dprintf("VDM SegMove: (%d) %x => %x\n",
  339. segment, selector, newselect);
  340. }
  341. break;
  342. case DBG_SEGFREE:
  343. fNeedSegTableEdit = TRUE;
  344. selector = se.Selector1;
  345. if (fVerbose) {
  346. dprintf("VDM SegFree: %x\n",selector);
  347. }
  348. break;
  349. case DBG_MODFREE:
  350. fNeedSegTableEdit = TRUE;
  351. if ( strlen(se.FileName) != 0 ) {
  352. dprintf("Freeing [%s]\n", se.FileName );
  353. } else if (fVerbose) {
  354. dprintf("VDM ModFree: unknown module\n");
  355. }
  356. break;
  357. case DBG_MODLOAD:
  358. fNeedSegTableEdit = TRUE;
  359. selector = se.Selector1;
  360. ImgLen = se.Length;
  361. segment = 0;
  362. pFileName = se.FileName;
  363. segslot = 0;
  364. while ( segslot < MAXSEGENTRY ) {
  365. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  366. if ( _stricmp(segtable[segslot].path_name, se.FileName) == 0 ) {
  367. break;
  368. }
  369. }
  370. segslot++;
  371. }
  372. if ( segslot == MAXSEGENTRY ) {
  373. if ( strlen(se.FileName) != 0 ) {
  374. dprintf("Loading [%s]\n", se.FileName );
  375. }
  376. }
  377. if (fVerbose) {
  378. dprintf("VDM ModLoad: %s => %x, len=%x\n",
  379. se.FileName,
  380. selector,
  381. ImgLen);
  382. }
  383. break;
  384. case DBG_SINGLESTEP:
  385. if (g_Target->m_MachineType == IMAGE_FILE_MACHINE_I386)
  386. {
  387. fNeedInteractive = FALSE;
  388. ulRet = STATUS_SINGLE_STEP;
  389. }
  390. else
  391. {
  392. fNeedInteractive = TRUE;
  393. }
  394. break;
  395. case DBG_BREAK:
  396. if (g_Target->m_MachineType == IMAGE_FILE_MACHINE_I386)
  397. {
  398. fNeedInteractive = FALSE;
  399. ulRet = STATUS_BREAKPOINT;
  400. }
  401. else
  402. {
  403. fNeedInteractive = TRUE;
  404. }
  405. break;
  406. case DBG_GPFAULT:
  407. dprintf(" GP Fault in VDM\n");
  408. if (g_Target->m_MachineType == IMAGE_FILE_MACHINE_I386) {
  409. fNeedInteractive = FALSE;
  410. ulRet = STATUS_ACCESS_VIOLATION;
  411. } else {
  412. fNeedInteractive = TRUE;
  413. }
  414. break;
  415. case DBG_GPFAULT2:
  416. dprintf("GP Fault in VDM\n");
  417. dprintf("!!! second chance !!!\n");
  418. fNeedInteractive = TRUE;
  419. break;
  420. case DBG_INSTRFAULT:
  421. dprintf("invalid opcode fault in VDM\n");
  422. fNeedInteractive = TRUE;
  423. break;
  424. case DBG_DIVOVERFLOW:
  425. dprintf("divide overflow in VDM\n");
  426. fNeedInteractive = TRUE;
  427. break;
  428. case DBG_STACKFAULT:
  429. dprintf("stack fault in VDM\n");
  430. if (g_Target->m_MachineType == IMAGE_FILE_MACHINE_I386) {
  431. fNeedInteractive = FALSE;
  432. ulRet = STATUS_ACCESS_VIOLATION;
  433. } else {
  434. fNeedInteractive = TRUE;
  435. }
  436. break;
  437. case DBG_TASKSTART:
  438. if ( fNeedInteractive || fVerbose ) {
  439. dprintf("VDM Start Task <%s:%s>\n",
  440. im.Module,
  441. im.FileName );
  442. }
  443. break;
  444. case DBG_DLLSTART:
  445. if ( fNeedInteractive || fVerbose ) {
  446. dprintf("VDM Start Dll <%s:%s>\n", im.Module, im.FileName );
  447. }
  448. break;
  449. case DBG_TASKSTOP:
  450. fNeedInteractive = FALSE;
  451. break;
  452. case DBG_DLLSTOP:
  453. fNeedInteractive = FALSE;
  454. break;
  455. }
  456. /*
  457. ** Temporary code to emulate a 16-bit debugger. Eventually I will make
  458. ** NTSD understand these events and call ProcessStateChange to allow
  459. ** real 16-bit debugging and other activities on the other 32-bit threads.
  460. ** -BobDay
  461. */
  462. if ( fNeedInteractive ) {
  463. char text[MAX_DISASM_LEN];
  464. char path[128];
  465. UINT cSeg;
  466. ADDR addr;
  467. X86_NT5_CONTEXT vc;
  468. g_Target->m_Machines[MACHIDX_I386]->
  469. m_Context.X86Nt5Context.ContextFlags = VDMCONTEXT_FULL;
  470. (*pfnVDMGetContext)(OS_HANDLE(g_EventProcess->m_SysHandle),
  471. OS_HANDLE(g_EventThread->m_Handle),
  472. (LPVDMCONTEXT)&g_Target->
  473. m_Machines[MACHIDX_I386]->m_Context);
  474. g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context.EFlags &= ~V86FLAGS_TRACE;
  475. vc = g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context;
  476. // Dump a simulated context
  477. g_Target->m_Machines[MACHIDX_I386]->OutputAll(g_Target->m_Machines[MACHIDX_I386]->m_AllMask,
  478. DEBUG_OUTPUT_PROMPT_REGISTERS);
  479. b = (*pfnVDMGetSelectorModule)(OS_HANDLE(g_EventProcess->m_SysHandle),
  480. OS_HANDLE(g_EventThread->m_Handle),
  481. (WORD)g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context.SegCs, &cSeg, text, 128, path, 128 );
  482. if ( b ) {
  483. dprintf("%s:%d!%04x:\n", text, cSeg, (WORD)g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context.Eip );
  484. }
  485. addr.seg = (WORD)g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context.SegCs;
  486. addr.off = g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context.Eip;
  487. if ( !bProtectMode ) {
  488. addr.type = ADDR_V86 | FLAT_COMPUTED;
  489. addr.flat = (*pfnVDMGetPointer)(
  490. OS_HANDLE(g_EventProcess->m_SysHandle),
  491. OS_HANDLE(g_EventThread->m_Handle),
  492. addr.seg,
  493. (ULONG)addr.off,
  494. FALSE
  495. );
  496. } else {
  497. addr.type = ADDR_16 | FLAT_COMPUTED;
  498. addr.flat = (*pfnVDMGetPointer)(
  499. OS_HANDLE(g_EventProcess->m_SysHandle),
  500. OS_HANDLE(g_EventThread->m_Handle),
  501. addr.seg,
  502. (ULONG)addr.off,
  503. TRUE
  504. );
  505. }
  506. if ( Flat(addr) == 0 ) {
  507. dprintf("Unable to disassemble failing code\n");
  508. } else {
  509. g_Target->m_Machines[MACHIDX_I386]->
  510. Disassemble( g_Process, &addr, text, TRUE );
  511. dprintf("%s", text );
  512. }
  513. AddExtensionDll("vdmexts", TRUE, g_Target, NULL);
  514. while ( TRUE ) {
  515. GetInput("VDM>", achInput, sizeof(achInput),
  516. GETIN_LOG_INPUT_LINE);
  517. if ( _stricmp(achInput,"gh") == 0 || _stricmp(achInput,"g") == 0 ) {
  518. ulRet = VDMEVENT_HANDLED;
  519. break;
  520. }
  521. if ( _stricmp(achInput,"gn") == 0 ) {
  522. ulRet = VDMEVENT_NOT_HANDLED;
  523. break;
  524. }
  525. if ( _stricmp(achInput, "t") == 0 ) {
  526. ulRet = VDMEVENT_HANDLED;
  527. vc.EFlags |= V86FLAGS_TRACE;
  528. break;
  529. }
  530. if ((achInput[0] == 'r') && (_stricmp(achInput, "r") != 0)) {
  531. VDMRegCmd(achInput, &vc);
  532. g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context = vc;
  533. continue;
  534. }
  535. if ( _stricmp(achInput,"?") == 0 ) {
  536. dprintf("\n---------- NTVDM Monitor Help ------------\n\n");
  537. dprintf("g - Go\n");
  538. dprintf("gh - Go : Exception handled\n");
  539. dprintf("gn - Go : Exception not handled\n");
  540. dprintf("help - Display extension help\n");
  541. dprintf("r<reg> <val> - reg=[eax|ebx|ecx|edx|eip|esp|ebp|efl]\n");
  542. dprintf("rp - display pending register set\n");
  543. dprintf("t - Trace 1 instruction\n");
  544. dprintf("!<cmd> - Execute extension command\n");
  545. dprintf(".<cmd> - Execute native NTSD command\n");
  546. dprintf("\nAnything else is interpreted as a VDMEXTS extension command\n\n");
  547. continue;
  548. }
  549. g_CurCmd = &achInput[1];
  550. g_CommandStart = g_CurCmd;
  551. ProcessCommandsAndCatch(NULL);
  552. }
  553. g_Target->m_Machines[MACHIDX_I386]->m_Context.X86Nt5Context = vc;
  554. (*pfnVDMSetContext)(OS_HANDLE(g_EventProcess->m_SysHandle),
  555. OS_HANDLE(g_EventThread->m_Handle),
  556. (LPVDMCONTEXT)&g_Target->m_Machines[MACHIDX_I386]->m_Context);
  557. }
  558. /*
  559. ** End of temporary code
  560. */
  561. if ( fNeedSegTableEdit ) {
  562. segslot = 0;
  563. fStop = FALSE;
  564. while ( segslot < MAXSEGENTRY ) {
  565. switch( mode ) {
  566. case DBG_SEGLOAD:
  567. if ( segtable[segslot].type == SEGTYPE_AVAILABLE ) {
  568. segtable[segslot].segment = segment;
  569. segtable[segslot].selector = selector;
  570. // This notification message is used only by wow in prot
  571. // It could be determined from the current mode to be
  572. // correct
  573. segtable[segslot].type = SEGTYPE_PROT;
  574. Str = (PSTR)calloc(1,strlen(se.FileName)+1);
  575. if ( !Str ) {
  576. return( VDMEVENT_NOT_HANDLED );
  577. }
  578. strcpy( Str, se.FileName );
  579. segtable[segslot].path_name = Str;
  580. segtable[segslot].ImgLen = 0;
  581. fStop = TRUE;
  582. }
  583. break;
  584. case DBG_SEGMOVE:
  585. if (( segtable[segslot].type != SEGTYPE_AVAILABLE ) &&
  586. ( segtable[segslot].selector == selector )) {
  587. segtable[segslot].selector = newselect;
  588. fStop = TRUE;
  589. }
  590. break;
  591. case DBG_SEGFREE:
  592. if ( segtable[segslot].selector == selector ) {
  593. fStop = TRUE;
  594. segtable[segslot].type = SEGTYPE_AVAILABLE;
  595. free(segtable[segslot].path_name);
  596. segtable[segslot].path_name = NULL;
  597. }
  598. break;
  599. case DBG_MODFREE:
  600. if ( segtable[segslot].type != SEGTYPE_AVAILABLE ) {
  601. if ( _stricmp(segtable[segslot].path_name,se.FileName) == 0 ) {
  602. segtable[segslot].type = SEGTYPE_AVAILABLE;
  603. free(segtable[segslot].path_name);
  604. segtable[segslot].path_name = NULL;
  605. }
  606. }
  607. break;
  608. case DBG_MODLOAD:
  609. if ( segtable[segslot].type == SEGTYPE_AVAILABLE ) {
  610. segtable[segslot].segment = segment;
  611. segtable[segslot].selector = selector;
  612. // This notification message is used only by v86 dos
  613. // It could be determined from the current mode to be
  614. // correct
  615. segtable[segslot].type = SEGTYPE_V86;
  616. Str = (PSTR)calloc(1,strlen(pFileName)+1);
  617. if ( !Str ) {
  618. return( VDMEVENT_NOT_HANDLED );
  619. }
  620. strcpy( Str, pFileName );
  621. segtable[segslot].path_name = Str;
  622. segtable[segslot].ImgLen = ImgLen;
  623. fStop = TRUE;
  624. }
  625. break;
  626. }
  627. if ( fStop ) {
  628. break;
  629. }
  630. segslot++;
  631. }
  632. if ( segslot == MAXSEGENTRY ) {
  633. if ( mode == DBG_SEGLOAD ) {
  634. dprintf("Warning - adding selector %04X for segment %d, segtable full\n",
  635. selector, segment );
  636. }
  637. }
  638. }
  639. pDebugEvent->u.Exception.ExceptionRecord.ExceptionCode = ulRet;
  640. return( ulRet );
  641. }