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.

390 lines
10 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Debug engine glue.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "pch.cpp"
  9. #pragma hdrstop
  10. #include "conio.hpp"
  11. #include "engine.hpp"
  12. #include "main.hpp"
  13. #include "extsfns.h"
  14. #include "..\..\exts\extdll\crdb.h"
  15. #include <strsafe.h>
  16. // To get _open to work
  17. #include <crt\io.h>
  18. #include <fcntl.h>
  19. #include <sys\types.h>
  20. #include <sys\stat.h>
  21. PCHAR
  22. GetLogFileName(
  23. void
  24. )
  25. {
  26. static CHAR szLogFileName[MAX_PATH+50];
  27. PCHAR ExeDir;
  28. ExeDir = &szLogFileName[0];
  29. *ExeDir = 0;
  30. // Get the directory the debugger executable is in.
  31. if (!GetModuleFileName(NULL, ExeDir, MAX_PATH))
  32. {
  33. // Error. Use the current directory.
  34. StringCchCopy(ExeDir, sizeof(szLogFileName), ".");
  35. } else
  36. {
  37. // Remove the executable name.
  38. PCHAR pszTmp = strrchr(ExeDir, '\\');
  39. if (pszTmp)
  40. {
  41. *pszTmp = 0;
  42. }
  43. }
  44. StringCchCat(ExeDir, sizeof(szLogFileName), "\\FailedAddCrash.log");
  45. return &szLogFileName[0];
  46. }
  47. HRESULT
  48. NotifyCallerMQ(
  49. ULONG SourceId,
  50. PCHAR szBaseURL,
  51. PCHAR szGuid,
  52. PCHAR szMQConnectStr
  53. )
  54. {
  55. HRESULT Hr;
  56. typedef HRESULT (WINAPI* MQSENDMSGPROC)(LPWSTR, LPWSTR, LPWSTR);
  57. MQSENDMSGPROC pSendMQMessageText;
  58. CHAR MQExtPath[MAX_PATH], *pBase;
  59. HMODULE hMod;
  60. WCHAR wszGuid[50], wszMQConnectStr[100];
  61. WCHAR wszMQMessage[300], wszSolnParams[] = L"";
  62. if ((StringCbPrintfW(wszGuid, sizeof(wszGuid), L"%S", szGuid) != S_OK) ||
  63. (StringCbPrintfW(wszMQConnectStr, sizeof(wszMQConnectStr), L"%S", szMQConnectStr) != S_OK) ||
  64. (StringCbPrintfW(wszMQMessage, sizeof(wszMQMessage), L"%Ssid=-1&State=0", szBaseURL) != S_OK))
  65. {
  66. return E_FAIL;
  67. }
  68. if (SourceId == CiSrcCER)
  69. {
  70. Hr = StringCbPrintfW(wszMQMessage, sizeof(wszMQMessage),
  71. L"%Ssid=-1&State=0&szSBucket=BAD_DUMPFILE&iSBucket=-1&szGBucket=BAD_DUMPFILE&iGBucket=-1&gsid=-1",
  72. szBaseURL
  73. );
  74. if (FAILED(Hr))
  75. {
  76. return E_FAIL;
  77. }
  78. }
  79. if (!GetModuleFileName(NULL, MQExtPath, sizeof(MQExtPath)))
  80. {
  81. return E_FAIL;
  82. }
  83. pBase = strrchr(MQExtPath, '\\');
  84. if (!pBase)
  85. {
  86. return E_FAIL;
  87. }
  88. *pBase = '\0';
  89. Hr = StringCchCat(MQExtPath, sizeof(MQExtPath), "\\winext\\mqext.dll");
  90. if (FAILED(Hr))
  91. {
  92. return Hr;
  93. }
  94. hMod = LoadLibrary(MQExtPath);
  95. if (hMod == NULL)
  96. {
  97. return E_FAIL;
  98. }
  99. if ((pSendMQMessageText = (MQSENDMSGPROC) GetProcAddress(hMod, "_EFN_SendMQMessageText")) != NULL)
  100. {
  101. return pSendMQMessageText(wszMQConnectStr, wszGuid, wszMQMessage);
  102. }
  103. FreeLibrary(hMod);
  104. return S_OK;
  105. }
  106. void
  107. UpdateDbForBadDumpFile(PSTR FilePath)
  108. {
  109. HANDLE hFile;
  110. HMODULE Ext = NULL;
  111. CHAR ExtCommand[MAX_PATH], *CmdBreak;
  112. CI_SOURCE Source = CiSrcErClient;
  113. CRASH_INSTANCE Crash = {0};
  114. BOOL NoUpdateCustomer = FALSE;
  115. DBADDCRACHDIRECT FuncAddCrash;
  116. DEBUG_TRIAGE_FOLLOWUP_INFO UrlInfo;
  117. CHAR szURL[100];
  118. EXT_TRIAGE_FOLLOWUP pTriageFollowup;
  119. CHAR szGuid[50] = {0}, szMQConnectStr[100] = {0};
  120. PCHAR args;
  121. // Load ext.dll
  122. Ext = LoadLibrary("winext\\ext.dll");
  123. if (!Ext)
  124. {
  125. ConOut("Cannot load ext.dll.\n");
  126. }
  127. if (!g_InitialCommand)
  128. {
  129. goto error;
  130. }
  131. StringCchCopy(ExtCommand, sizeof(ExtCommand), g_InitialCommand);
  132. CmdBreak = strchr(ExtCommand, ';');
  133. if (CmdBreak)
  134. {
  135. *CmdBreak = 0;
  136. }
  137. args = strstr(ExtCommand, "!dbaddcrash");
  138. if (!args)
  139. {
  140. goto error;
  141. }
  142. args+=11;
  143. while (*args)
  144. {
  145. if (*args == ' ' || *args == '\t')
  146. {
  147. ++args;
  148. continue;
  149. }
  150. else if (*args == '-' || *args == '/')
  151. {
  152. ++args;
  153. switch (*args)
  154. {
  155. case 'g': // GUID identifying this crash, return bucket along with this
  156. ++args;
  157. while (*args == ' ') ++args;
  158. if (!sscanf(args,"%50s", szGuid))
  159. {
  160. szGuid[0] = 0;
  161. }
  162. args+=strlen(szGuid);
  163. break;
  164. case 'm':
  165. if (!strncmp(args, "mail", 4))
  166. {
  167. Crash.bSendMail = TRUE;
  168. args+=4;
  169. }
  170. break;
  171. case 'n':
  172. if (!strncmp(args, "nocust", 6))
  173. {
  174. NoUpdateCustomer = TRUE;
  175. Crash.bUpdateCustomer = FALSE;
  176. args+=6;
  177. }
  178. break;
  179. case 'o':
  180. ++args;
  181. break;
  182. case 'p':
  183. {
  184. CHAR Path[240];
  185. ++args;
  186. while (*args == ' ') ++args;
  187. if (!sscanf(args,"%240s", Path))
  188. {
  189. Path[0] = 0;
  190. }
  191. args+=strlen(Path);
  192. break;
  193. }
  194. case 'r':
  195. if (!strncmp(args, "retriage", 8))
  196. {
  197. Crash.bResetBucket = TRUE;
  198. args+=8;
  199. }
  200. break;
  201. case 's': // queue connection string to send bucketid back
  202. if (!strncmp(args, "source", 6))
  203. {
  204. args+=6;
  205. while (*args == ' ') ++args;
  206. if (isdigit(*args))
  207. {
  208. Source = (CI_SOURCE) atoi(args);
  209. if (Source > (ULONG) CiSrcMax)
  210. {
  211. Source = CiSrcErClient;
  212. }
  213. while (isdigit(*args)) ++args;
  214. }
  215. } else
  216. {
  217. ++args;
  218. while (*args == ' ') ++args;
  219. if (!sscanf(args,"%100s", szMQConnectStr))
  220. {
  221. szMQConnectStr[0] = 0;
  222. }
  223. args+=strlen(szMQConnectStr);
  224. }
  225. break;
  226. default:
  227. ++args;
  228. while (*args == ' ' || *args == '\t' )
  229. {
  230. ++args;
  231. }
  232. while (*args && *args != '/' && *args != '-')
  233. {
  234. ++args;
  235. }
  236. break;
  237. }
  238. }
  239. else
  240. {
  241. break;
  242. }
  243. }
  244. //
  245. // If the dump file was not visible, then we got passed a bad name or
  246. // the serve ris down - these are errors that need to be reported.
  247. //
  248. hFile = CreateFile(FilePath,
  249. GENERIC_READ,
  250. FILE_SHARE_READ | FILE_SHARE_WRITE |
  251. FILE_SHARE_DELETE,
  252. NULL,
  253. OPEN_EXISTING,
  254. FILE_ATTRIBUTE_NORMAL,
  255. NULL);
  256. if (hFile == INVALID_HANDLE_VALUE)
  257. {
  258. Crash.Bucket = "NO_DUMPFILE";
  259. Crash.DefaultBucket = "NO_DUMPFILE";
  260. } else
  261. {
  262. Crash.Bucket = "BAD_DUMPFILE";
  263. Crash.DefaultBucket = "BAD_DUMPFILE";
  264. }
  265. CloseHandle(hFile);
  266. ConOut("Running Extension: '%s'\n", ExtCommand);
  267. FuncAddCrash = (DBADDCRACHDIRECT) GetProcAddress(Ext, "_EFN_DbAddCrashDirect");
  268. if (!FuncAddCrash)
  269. {
  270. ConOut("Cannot find _EFN_DbAddCrashDirect\n");
  271. goto error;
  272. }
  273. // Build CRASH_INSTANCE
  274. Crash.CrashTime = -1;
  275. Crash.UpTime = -1;
  276. Crash.uCpu = -1;
  277. Crash.Build = 0;
  278. Crash.SourceId = Source;
  279. Crash.Followup = "ignore";
  280. Crash.Path = g_DumpFilesAnsi[0];
  281. Crash.FailureType = DEBUG_FLR_KERNEL;
  282. Crash.StopCode = -1;
  283. Crash.FaultyDriver = "";
  284. Crash.MesgGuid = szGuid;
  285. Crash.MqConnectStr = szMQConnectStr;
  286. Crash.SolutionId = 79;
  287. Crash.SolutionType = CiSolFixed;
  288. if (Crash.bResetBucket && !NoUpdateCustomer)
  289. {
  290. // Update customer info for only for retriage
  291. Crash.bUpdateCustomer = TRUE;
  292. }
  293. //
  294. // Get the failed dump file name
  295. //
  296. CHAR DumpFileName[MAX_PATH];
  297. g_DbgClient4->GetDumpFile(DEBUG_DUMP_FILE_LOAD_FAILED_INDEX,
  298. DumpFileName, sizeof(DumpFileName),
  299. NULL, NULL, NULL);
  300. Crash.OriginalDumpFileName = DumpFileName;
  301. //
  302. // extract the incident ID from the cab name
  303. // there are 2 types of filenames we could have to support.
  304. // The old version is id@*.*
  305. // The new version is id.*
  306. //
  307. CHAR FileName[MAX_PATH];
  308. if (FAILED(FuncAddCrash(&Crash, g_DbgControl3)))
  309. {
  310. error:
  311. ConOut("Dump file could not be processed - logged to %s\n", GetLogFileName());
  312. szURL[0] = 0;
  313. pTriageFollowup = (EXT_TRIAGE_FOLLOWUP) GetProcAddress(Ext, "_EFN_GetTriageFollowupFromSymbol");
  314. if (pTriageFollowup)
  315. {
  316. UrlInfo.SizeOfStruct = sizeof(UrlInfo);
  317. UrlInfo.OwnerName = szURL;
  318. UrlInfo.OwnerNameSize = sizeof(szURL);
  319. (*pTriageFollowup)(g_DbgClient, "debugger-params!solutionurl", &UrlInfo);
  320. }
  321. if (szURL[0] && szMQConnectStr[0] && szGuid[0])
  322. {
  323. NotifyCallerMQ(Source, szURL, szGuid, szMQConnectStr);
  324. }
  325. int g_LogFile;
  326. g_LogFile = _open(GetLogFileName(), O_APPEND | O_CREAT | O_RDWR,
  327. S_IREAD | S_IWRITE);
  328. if (g_LogFile != -1)
  329. {
  330. if (FilePath != NULL)
  331. {
  332. _write(g_LogFile, FilePath, strlen(FilePath));
  333. } else
  334. {
  335. _write(g_LogFile, "No File provided", strlen("No File provided"));
  336. }
  337. _write(g_LogFile, "\n", strlen("\n"));
  338. _close(g_LogFile);
  339. }
  340. }
  341. if (Ext)
  342. {
  343. FreeLibrary(Ext);
  344. }
  345. }