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.

365 lines
10 KiB

  1. // AssertDlg.cpp : Implementation of CCAssertDlg
  2. #include "stdafx.h"
  3. #include "AssertDlg.h"
  4. #include "DebugCore.h"
  5. extern HINSTANCE g_hDll;
  6. //**************************************************************************************************
  7. //
  8. // Global Functions
  9. //
  10. //**************************************************************************************************
  11. //-----------------------------------------------------------------------------
  12. void CopyToClipboard(const char * pszMessage)
  13. {
  14. HANDLE hText;
  15. UINT nStrSize;
  16. char * pszText;
  17. if (OpenClipboard(NULL)) {
  18. nStrSize = (UINT) strlen(pszMessage) +1;
  19. hText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, nStrSize);
  20. if (hText != NULL) {
  21. pszText = (char *) GlobalLock(hText);
  22. if (pszText != NULL) {
  23. strcpy(pszText, pszMessage);
  24. GlobalUnlock(hText);
  25. EmptyClipboard();
  26. if (SetClipboardData(CF_TEXT, hText) != NULL) {
  27. // Data is now owned by the clipboard
  28. hText = NULL;
  29. }
  30. }
  31. if (hText != NULL) {
  32. // Unable to set clipboard data
  33. GlobalFree(hText);
  34. }
  35. }
  36. CloseClipboard();
  37. }
  38. }
  39. //**************************************************************************************************
  40. //
  41. // class CAssertDlg
  42. //
  43. //**************************************************************************************************
  44. BOOL CAssertDlg::s_fInit = FALSE;
  45. //******************************************************************************
  46. //
  47. // CAssertDlg Construction
  48. //
  49. //******************************************************************************
  50. //------------------------------------------------------------------------------
  51. CAssertDlg::CAssertDlg()
  52. {
  53. m_pszExpression = "";
  54. m_pszFileName = "";
  55. m_szLineNum[0] = '\0';
  56. m_hStackData = NULL;
  57. m_cCSEntries = 0;
  58. m_cSkipLevels = 0;
  59. m_fProperShutdown = FALSE;
  60. }
  61. //------------------------------------------------------------------------------
  62. CAssertDlg::~CAssertDlg()
  63. {
  64. }
  65. //******************************************************************************
  66. //
  67. // CAssertDlg Operations
  68. //
  69. //******************************************************************************
  70. //------------------------------------------------------------------------------
  71. INT_PTR
  72. CAssertDlg::ShowDialog(
  73. IN LPCSTR pszType,
  74. IN LPCSTR pszExpression,
  75. IN LPCSTR pszFileName,
  76. IN UINT idxLineNum,
  77. IN HANDLE hStackData,
  78. IN UINT cCSEntries,
  79. IN UINT cSkipLevels)
  80. {
  81. m_pszTitle = pszType;
  82. m_pszExpression = pszExpression;
  83. m_pszFileName = pszFileName;
  84. wsprintf(m_szLineNum, "%d", (int) idxLineNum);
  85. m_hStackData = hStackData;
  86. m_cCSEntries = cCSEntries;
  87. m_cSkipLevels = cSkipLevels;
  88. if (!s_fInit) {
  89. s_fInit = TRUE;
  90. INITCOMMONCONTROLSEX iccs;
  91. iccs.dwSize = sizeof(iccs);
  92. iccs.dwICC = ICC_LISTVIEW_CLASSES;
  93. if (!InitCommonControlsEx(&iccs)) {
  94. return -1;
  95. }
  96. }
  97. INT_PTR nResult = DialogBoxParam(g_hDll, MAKEINTRESOURCE(IDD_Assert), NULL, DlgProc, (LPARAM) this);
  98. if (!m_fProperShutdown) {
  99. nResult = IDC_DEBUG;
  100. }
  101. return nResult;
  102. }
  103. //******************************************************************************
  104. //
  105. // CAssertDlg Message Handlers
  106. //
  107. //******************************************************************************
  108. //------------------------------------------------------------------------------
  109. void inline InsertColumn(HWND hwnd, int idxColumn, TCHAR * pszName, int fmt = LVCFMT_LEFT)
  110. {
  111. _ASSERTE(::IsWindow(hwnd));
  112. LVCOLUMN lvc;
  113. lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
  114. lvc.fmt = fmt;
  115. lvc.iOrder = idxColumn;
  116. lvc.pszText = pszName;
  117. ListView_InsertColumn(hwnd, 0, &lvc);
  118. }
  119. //------------------------------------------------------------------------------
  120. INT_PTR CALLBACK
  121. CAssertDlg::DlgProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  122. {
  123. CAssertDlg * pThis = (CAssertDlg *) GetWindowLongPtr(hwnd, DWLP_USER);
  124. if (pThis == NULL) {
  125. if (nMsg == WM_INITDIALOG) {
  126. SetWindowLongPtr(hwnd, DWLP_USER, lParam);
  127. pThis = (CAssertDlg *) lParam;
  128. pThis->m_hwnd = hwnd;
  129. }
  130. }
  131. BOOL bHandled = FALSE;
  132. if (pThis != NULL) {
  133. LRESULT lRet = 0;
  134. switch (nMsg)
  135. {
  136. case WM_INITDIALOG:
  137. lRet = pThis->OnInitDialog(nMsg, wParam, lParam, bHandled);
  138. break;
  139. case WM_DESTROY:
  140. lRet = pThis->OnDestroy(nMsg, wParam, lParam, bHandled);
  141. break;
  142. case WM_COMMAND:
  143. {
  144. WORD nCode = HIWORD(wParam);
  145. WORD nID = LOWORD(wParam);
  146. HWND hwndC = (HWND) lParam;
  147. if (nCode == BN_CLICKED) {
  148. switch (nID)
  149. {
  150. case IDCANCEL:
  151. case IDC_DEBUG:
  152. case IDC_IGNORE:
  153. lRet = pThis->OnClicked(nCode, nID, hwndC, bHandled);
  154. break;
  155. case IDC_COPY:
  156. lRet = pThis->OnCopy(nCode, nID, hwndC, bHandled);
  157. }
  158. }
  159. }
  160. break;
  161. }
  162. if (bHandled) {
  163. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lRet);
  164. }
  165. }
  166. return bHandled;
  167. }
  168. //------------------------------------------------------------------------------
  169. LRESULT CAssertDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  170. {
  171. UNREFERENCED_PARAMETER(uMsg);
  172. UNREFERENCED_PARAMETER(wParam);
  173. UNREFERENCED_PARAMETER(lParam);
  174. UNREFERENCED_PARAMETER(bHandled);
  175. // CenterWindow();
  176. SetWindowText(m_hwnd, m_pszTitle);
  177. //
  178. // Setup the child windows and fill in all of the values in the dialog.
  179. //
  180. HWND hwndT;
  181. hwndT = GetDlgItem(m_hwnd, IDC_ebcExpression);
  182. SetWindowText(hwndT, m_pszExpression);
  183. hwndT = GetDlgItem(m_hwnd, IDC_ebcFileName);
  184. SetWindowText(hwndT, m_pszFileName);
  185. hwndT = GetDlgItem(m_hwnd, IDC_ebcLineNum);
  186. SetWindowText(hwndT, m_szLineNum);
  187. //
  188. // Display the stack
  189. //
  190. if ((hwndT = GetDlgItem(m_hwnd, IDC_lvcCallStack)) != NULL) {
  191. if (m_hStackData != NULL) {
  192. InsertColumn(hwndT, 0, _T("Address"));
  193. InsertColumn(hwndT, 1, _T("Module"));
  194. InsertColumn(hwndT, 2, _T("Function"));
  195. DWORD * pdwStackData = (DWORD *) ::GlobalLock(m_hStackData);
  196. _ASSERTE(pdwStackData != NULL);
  197. int idxItem = 0;
  198. DUSER_SYMBOL_INFO si;
  199. HANDLE hProcess = ::GetCurrentProcess();
  200. for (UINT nAddress = m_cSkipLevels; nAddress < m_cCSEntries; nAddress++) {
  201. CDebugHelp::ResolveStackItem(hProcess, pdwStackData, nAddress, si);
  202. TCHAR szAddr[20];
  203. wsprintf(szAddr, "0x%p", pdwStackData[nAddress]);
  204. LVITEM item;
  205. item.mask = LVIF_TEXT;
  206. item.pszText = szAddr;
  207. item.iItem = idxItem++;
  208. item.iSubItem = 0;
  209. int idxAdd = ListView_InsertItem(hwndT, &item);
  210. ListView_SetItemText(hwndT, idxAdd, 1, si.szModule);
  211. ListView_SetItemText(hwndT, idxAdd, 2, si.szSymbol);
  212. }
  213. ListView_SetColumnWidth(hwndT, 0, LVSCW_AUTOSIZE);
  214. ListView_SetColumnWidth(hwndT, 1, 130);
  215. ListView_SetColumnWidth(hwndT, 2, 200);
  216. ListView_SetExtendedListViewStyle(hwndT, LVS_EX_FULLROWSELECT);
  217. ::GlobalUnlock(m_hStackData);
  218. } else {
  219. EnableWindow(hwndT, FALSE);
  220. }
  221. }
  222. MessageBeep(MB_ICONHAND);
  223. return TRUE; // let Windows set the focus
  224. }
  225. //------------------------------------------------------------------------------
  226. LRESULT CAssertDlg::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  227. {
  228. UNREFERENCED_PARAMETER(uMsg);
  229. UNREFERENCED_PARAMETER(wParam);
  230. UNREFERENCED_PARAMETER(lParam);
  231. UNREFERENCED_PARAMETER(bHandled);
  232. return 0;
  233. }
  234. //------------------------------------------------------------------------------
  235. LRESULT CAssertDlg::OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  236. {
  237. UNREFERENCED_PARAMETER(wNotifyCode);
  238. UNREFERENCED_PARAMETER(wID);
  239. UNREFERENCED_PARAMETER(hWndCtl);
  240. UNREFERENCED_PARAMETER(bHandled);
  241. m_fProperShutdown = TRUE;
  242. EndDialog(m_hwnd, wID);
  243. return 0;
  244. }
  245. inline void Append(char * & pszCur, const char * pszSrc)
  246. {
  247. _ASSERTE(pszCur != NULL);
  248. _ASSERTE(pszSrc != NULL);
  249. strcpy(pszCur, pszSrc);
  250. pszCur += strlen(pszSrc);
  251. }
  252. //------------------------------------------------------------------------------
  253. LRESULT CAssertDlg::OnCopy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  254. {
  255. UNREFERENCED_PARAMETER(wNotifyCode);
  256. UNREFERENCED_PARAMETER(wID);
  257. UNREFERENCED_PARAMETER(hWndCtl);
  258. UNREFERENCED_PARAMETER(bHandled);
  259. char szBuffer[10000];
  260. szBuffer[0] = '\0';
  261. char * pszCur = szBuffer;
  262. Append(pszCur, "Expression:\r\n");
  263. Append(pszCur, m_pszExpression);
  264. Append(pszCur, "\r\n\r\n");
  265. Append(pszCur, "File: \"");
  266. Append(pszCur, m_pszFileName);
  267. Append(pszCur, "\"\r\nLine: ");
  268. Append(pszCur, m_szLineNum);
  269. Append(pszCur, "\r\n\r\n");
  270. DWORD * pdwStackData = (DWORD *) ::GlobalLock(m_hStackData);
  271. _ASSERTE(pdwStackData != NULL);
  272. Append(pszCur, "Call stack:\r\n");
  273. DUSER_SYMBOL_INFO si;
  274. HANDLE hProcess = ::GetCurrentProcess();
  275. for (UINT nAddress = m_cSkipLevels; nAddress < m_cCSEntries; nAddress++)
  276. {
  277. CDebugHelp::ResolveStackItem(hProcess, pdwStackData, nAddress, si);
  278. TCHAR szAddr[20];
  279. wsprintf(szAddr, "0x%8.8x: ", pdwStackData[nAddress]);
  280. Append(pszCur, szAddr);
  281. Append(pszCur, si.szModule);
  282. Append(pszCur, ", ");
  283. Append(pszCur, si.szSymbol);
  284. Append(pszCur, "\r\n");
  285. }
  286. ::GlobalUnlock(m_hStackData);
  287. CopyToClipboard(szBuffer);
  288. return 0;
  289. }