Source code of Windows XP (NT5)
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.

140 lines
3.8 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. brkpt.c
  5. Abstract:
  6. This module contains the debugging support needed to debug
  7. 16-bit VDM applications
  8. Author:
  9. Neil Sandlin (neilsa) 1-Nov-1997 wrote it
  10. Revision History:
  11. --*/
  12. #include <precomp.h>
  13. #pragma hdrstop
  14. #define X86_BP_OPCODE 0xcc
  15. //----------------------------------------------------------------------------
  16. // ProcessBPNotification()
  17. //
  18. //
  19. //----------------------------------------------------------------------------
  20. VOID
  21. ProcessBPNotification(
  22. LPDEBUG_EVENT lpDebugEvent
  23. )
  24. {
  25. BOOL b;
  26. HANDLE hProcess;
  27. HANDLE hThread;
  28. VDMCONTEXT vcContext;
  29. NTSTATUS Status;
  30. OBJECT_ATTRIBUTES Obja;
  31. CLIENT_ID ClientId;
  32. VDM_BREAKPOINT VdmBreakPoints[MAX_VDM_BREAKPOINTS] = {0};
  33. ULONG vdmEip;
  34. DWORD lpNumberOfBytes;
  35. int i;
  36. UCHAR opcode;
  37. PVOID lpInst;
  38. hProcess = OpenProcess( PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
  39. FALSE, lpDebugEvent->dwProcessId );
  40. if ( hProcess == HANDLE_NULL ) {
  41. return;
  42. }
  43. ClientId.UniqueThread = (HANDLE)lpDebugEvent->dwThreadId;
  44. ClientId.UniqueProcess = (HANDLE)NULL;
  45. InitializeObjectAttributes(&Obja, NULL, 0, NULL, NULL);
  46. Status = NtOpenThread(&hThread,
  47. (ACCESS_MASK)THREAD_GET_CONTEXT,
  48. &Obja,
  49. &ClientId);
  50. if (!NT_SUCCESS(Status)) {
  51. CloseHandle( hProcess );
  52. return;
  53. }
  54. vcContext.ContextFlags = VDMCONTEXT_CONTROL;
  55. if (!VDMGetContext(hProcess, hThread, &vcContext)) {
  56. CloseHandle( hProcess );
  57. CloseHandle( hThread);
  58. return;
  59. }
  60. CloseHandle( hThread );
  61. b = ReadProcessMemory(hProcess, lpVdmBreakPoints, &VdmBreakPoints,
  62. sizeof(VdmBreakPoints), &lpNumberOfBytes);
  63. if ( !b || lpNumberOfBytes != sizeof(VdmBreakPoints) ) {
  64. CloseHandle (hProcess);
  65. return;
  66. }
  67. // if ((getMSW() & MSW_PE) && SEGMENT_IS_BIG(vcContext.SegCs)) {
  68. // vdmEip = vcContext.Eip;
  69. // } else {
  70. vdmEip = (ULONG)LOWORD(vcContext.Eip);
  71. // }
  72. for (i=0; i<MAX_VDM_BREAKPOINTS; i++) {
  73. if ((VdmBreakPoints[i].Flags & VDMBP_ENABLED) &&
  74. (VdmBreakPoints[i].Flags & VDMBP_SET) &&
  75. (vcContext.SegCs == VdmBreakPoints[i].Seg) &&
  76. (vdmEip == VdmBreakPoints[i].Offset+1) &&
  77. (!(vcContext.EFlags & V86FLAGS_V86) == !(VdmBreakPoints[i].Flags & VDMBP_V86)) ){
  78. // We must have hit this breakpoint. Back up the eip and
  79. // restore the original data
  80. // setEIP(getEIP()-1);
  81. // vcContext.Eip--;
  82. lpInst = (PVOID)InternalGetPointer(hProcess,
  83. VdmBreakPoints[i].Seg,
  84. VdmBreakPoints[i].Offset,
  85. ((VdmBreakPoints[i].Flags & VDMBP_V86)==0));
  86. b = ReadProcessMemory(hProcess, lpInst, &opcode, 1,
  87. &lpNumberOfBytes);
  88. if (b && (opcode == X86_BP_OPCODE)) {
  89. WriteProcessMemory(hProcess, lpInst, &VdmBreakPoints[i].Opcode, 1,
  90. &lpNumberOfBytes);
  91. VdmBreakPoints[i].Flags |= VDMBP_PENDING;
  92. VdmBreakPoints[i].Flags &= ~VDMBP_FLUSH;
  93. if (i == VDM_TEMPBP) {
  94. // non-persistent breakpoint
  95. VdmBreakPoints[i].Flags &= ~VDMBP_SET;
  96. }
  97. WriteProcessMemory(hProcess, lpVdmBreakPoints, &VdmBreakPoints,
  98. sizeof(VdmBreakPoints), &lpNumberOfBytes);
  99. }
  100. break;
  101. }
  102. }
  103. CloseHandle( hProcess );
  104. }