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.

269 lines
7.0 KiB

  1. /*
  2. * dbg.c - Main Module of DBG DLL.
  3. *
  4. * BobDay 13-Jan-1992 Created
  5. * Neilsa 13-Mar-1997 Moved guts to dbgdll
  6. *
  7. */
  8. #include <nt.h>
  9. #include <ntrtl.h>
  10. #include <nturtl.h>
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <mvdm.h>
  15. #include <bop.h>
  16. #include <softpc.h>
  17. #include <dbgexp.h>
  18. #include <dbgsvc.h>
  19. #include <vdmdbg.h>
  20. #include <dbginfo.h>
  21. #include <vdm.h>
  22. #include <host_def.h>
  23. BOOL (WINAPI *pfnDbgInit)(ULONG, ULONG, PVOID);
  24. BOOL (WINAPI *pfnDbgIsDebuggee)(VOID);
  25. VOID (WINAPI *pfnDbgDispatch)(VOID);
  26. VOID (WINAPI *pfnDbgDosAppStart)(WORD, WORD);
  27. VOID (WINAPI *pfnDbgSegmentNotice)(WORD, WORD, WORD, WORD, LPSTR, LPSTR, DWORD);
  28. VOID (WINAPI *pfnDbgTraceEvent)(PVDM_TRACEINFO, WORD, WORD, DWORD);
  29. BOOL (WINAPI *pfnDbgFault)(ULONG);
  30. BOOL (WINAPI *pfnDbgBPInt)(VOID);
  31. BOOL (WINAPI *pfnDbgTraceInt)(VOID);
  32. VOID (WINAPI *pfnDbgNotifyNewTask)(LPVOID, UINT);
  33. VOID (WINAPI *pfnDbgNotifyRemoteThreadAddress)(LPVOID, DWORD);
  34. VOID (WINAPI *pfnDbgNotifyDebugged)(BOOL);
  35. #ifdef i386
  36. BYTE nt_cpu_info;
  37. #else
  38. extern ULONG Start_of_M_area;
  39. extern BYTE nt_cpu_info;
  40. #define IntelBase Start_of_M_area
  41. //
  42. // This field is used to hold values destined for NTVDMSTATE (at 714)
  43. // Initially, we set it to INITIAL_VDM_TIB_FLAGS just for clarity, since it
  44. // will really only be turned on or off once we look to see if a debugger
  45. // is attached. This way, if you examine it when you first attach with a
  46. // debugger, it will be consistent with the default.
  47. //
  48. ULONG InitialVdmTibFlags = INITIAL_VDM_TIB_FLAGS;
  49. VDM_TRACEINFO TraceInfo;
  50. PVDM_TRACEINFO pVdmTraceInfo = &TraceInfo;
  51. #endif
  52. BOOL bDbgInitCalled = FALSE;
  53. BOOL bDbgDebuggerLoaded = FALSE;
  54. ULONG InitialVdmDbgFlags = 0;
  55. /* DBGInit - DBG Initialiazation routine.
  56. *
  57. * This routine is called during ntvdm initialization from host\src.
  58. * It is responsible for loading ntvdmd.dll, if vdm debugging is required.
  59. */
  60. BOOL DBGInit (VOID)
  61. {
  62. HANDLE hmodDBG;
  63. DWORD dwLen;
  64. // Indicate to VdmDbgAttach that we have gotten far enough into
  65. // the ntvdm boot that memory layout is valid.
  66. bDbgInitCalled = TRUE;
  67. //LATER Decide to load this on a registry switch
  68. if (!bDbgDebuggerLoaded) {
  69. hmodDBG = LoadSystem32Library(L"NTVDMD.DLL");
  70. if ( hmodDBG == (HANDLE)NULL ) {
  71. #if DBG
  72. OutputDebugString("NTVDM: error loading ntvdmd.dll\n");
  73. #endif
  74. return FALSE;
  75. } else {
  76. //
  77. // pfnDbgDispatch is special in that we always want to call it
  78. // even if no debugger is attached.
  79. //
  80. pfnDbgDispatch = (VOID (WINAPI *)(VOID)) GetProcAddress( hmodDBG, "xxxDbgDispatch" );
  81. }
  82. }
  83. return TRUE;
  84. }
  85. /* VdmDbgAttach
  86. *
  87. * This routine is called from NTVDMD.DLL. It is potentially called
  88. * at any time, but specifically we are looking to run some code when:
  89. * 1) the ntvdm has "matured", and
  90. * 2) a debugger is attached
  91. *
  92. * The ntvdm has "matured" when it is initialized sufficiently to determine
  93. * for example where the start of VDM memory is (on risc platforms).
  94. *
  95. */
  96. VOID
  97. VdmDbgAttach(
  98. VOID
  99. )
  100. {
  101. if (bDbgInitCalled) {
  102. HANDLE hmodDBG;
  103. hmodDBG = GetModuleHandle("NTVDMD.DLL");
  104. if ( hmodDBG == (HANDLE)NULL ) {
  105. return;
  106. }
  107. pfnDbgInit = (BOOL (WINAPI *)(ULONG, ULONG, PVOID)) GetProcAddress( hmodDBG, "xxxDbgInit" );
  108. pfnDbgIsDebuggee = (BOOL (WINAPI *)(VOID)) GetProcAddress( hmodDBG, "xxxDbgIsDebuggee" );
  109. pfnDbgDosAppStart = (VOID (WINAPI *)(WORD, WORD)) GetProcAddress( hmodDBG, "xxxDbgDosAppStart" );
  110. pfnDbgSegmentNotice = (VOID (WINAPI *)(WORD, WORD, WORD, WORD, LPSTR, LPSTR, DWORD)) GetProcAddress( hmodDBG, "xxxDbgSegmentNotice" );
  111. pfnDbgTraceEvent = (VOID (WINAPI *)(PVDM_TRACEINFO, WORD, WORD, DWORD)) GetProcAddress( hmodDBG, "xxxDbgTraceEvent" );
  112. pfnDbgFault = (BOOL (WINAPI *)(ULONG)) GetProcAddress( hmodDBG, "xxxDbgFault" );
  113. pfnDbgBPInt = (BOOL (WINAPI *)(VOID)) GetProcAddress( hmodDBG, "xxxDbgBPInt" );
  114. pfnDbgTraceInt = (BOOL (WINAPI *)(VOID)) GetProcAddress( hmodDBG, "xxxDbgTraceInt" );
  115. pfnDbgNotifyNewTask = (VOID (WINAPI *)(LPVOID, UINT)) GetProcAddress( hmodDBG, "xxxDbgNotifyNewTask" );
  116. pfnDbgNotifyRemoteThreadAddress = (VOID (WINAPI *)(LPVOID, DWORD)) GetProcAddress( hmodDBG, "xxxDbgNotifyRemoteThreadAddress" );
  117. pfnDbgNotifyDebugged= (VOID (WINAPI *)(BOOL)) GetProcAddress( hmodDBG, "xxxDbgNotifyDebugged" );
  118. //
  119. // DBGinit has already been called. Do an init, and send
  120. // symbol notifications
  121. //
  122. if (pfnDbgInit &&
  123. (bDbgDebuggerLoaded = (*pfnDbgInit)(IntelBase + FIXED_NTVDMSTATE_LINEAR,
  124. InitialVdmDbgFlags,
  125. &nt_cpu_info))) {
  126. //LATER: send symbol notifications
  127. }
  128. }
  129. }
  130. VOID
  131. DBGNotifyNewTask(
  132. LPVOID lpvNTFrame,
  133. UINT uFrameSize
  134. )
  135. {
  136. if (pfnDbgNotifyNewTask) {
  137. (*pfnDbgNotifyNewTask)(lpvNTFrame, uFrameSize);
  138. }
  139. }
  140. VOID
  141. DBGNotifyRemoteThreadAddress(
  142. LPVOID lpAddress,
  143. DWORD lpBlock
  144. )
  145. {
  146. if (pfnDbgNotifyRemoteThreadAddress) {
  147. (*pfnDbgNotifyRemoteThreadAddress)(lpAddress, lpBlock);
  148. }
  149. }
  150. VOID DBGNotifyDebugged(
  151. BOOL fNewDebugged
  152. )
  153. {
  154. if (pfnDbgNotifyDebugged) {
  155. (*pfnDbgNotifyDebugged)(fNewDebugged);
  156. }
  157. }
  158. BOOL DbgTraceInt(VOID)
  159. {
  160. BOOL bRet = FALSE;
  161. if (pfnDbgTraceInt) {
  162. bRet = (*pfnDbgTraceInt)();
  163. }
  164. return bRet;
  165. }
  166. BOOL DbgFault(ULONG value)
  167. {
  168. BOOL bRet = FALSE;
  169. if (pfnDbgFault) {
  170. bRet = (*pfnDbgFault)(value);
  171. }
  172. return bRet;
  173. }
  174. BOOL
  175. DbgIsDebuggee(
  176. void
  177. )
  178. {
  179. if (pfnDbgIsDebuggee) {
  180. return (*pfnDbgIsDebuggee)();
  181. }
  182. return FALSE;
  183. }
  184. VOID
  185. DbgSegmentNotice(
  186. WORD wType,
  187. WORD wModuleSeg,
  188. WORD wLoadSeg,
  189. WORD wNewSeg,
  190. LPSTR lpModuleName,
  191. LPSTR lpModulePath,
  192. DWORD dwImageLen
  193. )
  194. {
  195. if (pfnDbgSegmentNotice) {
  196. (*pfnDbgSegmentNotice)(wType, wModuleSeg, wLoadSeg, wNewSeg,
  197. lpModuleName, lpModulePath, dwImageLen);
  198. }
  199. }
  200. VOID
  201. DbgDosAppStart(
  202. WORD wCS,
  203. WORD wIP
  204. )
  205. {
  206. if (pfnDbgDosAppStart) {
  207. (*pfnDbgDosAppStart)(wCS, wIP);
  208. }
  209. }
  210. void DBGDispatch()
  211. {
  212. if (pfnDbgDispatch) {
  213. (*pfnDbgDispatch)();
  214. }
  215. }
  216. BOOL DbgBPInt()
  217. {
  218. BOOL bRet = FALSE;
  219. if (pfnDbgBPInt) {
  220. bRet = (*pfnDbgBPInt)();
  221. }
  222. return bRet;
  223. }
  224. VOID
  225. VdmTraceEvent(
  226. USHORT Type,
  227. USHORT wData,
  228. ULONG lData
  229. )
  230. {
  231. if (pfnDbgTraceEvent &&
  232. (*(ULONG *)(IntelBase+FIXED_NTVDMSTATE_LINEAR) & VDM_TRACE_HISTORY)) {
  233. PVDM_TIB VdmTib = NtCurrentTeb()->Vdm;
  234. (*pfnDbgTraceEvent)(&((*VdmTib).TraceInfo), Type, wData, lData);
  235. }
  236. }