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
390 lines
10 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// Debug engine glue.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999-2002.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
#include "conio.hpp"
|
|
#include "engine.hpp"
|
|
#include "main.hpp"
|
|
|
|
#include "extsfns.h"
|
|
#include "..\..\exts\extdll\crdb.h"
|
|
#include <strsafe.h>
|
|
// To get _open to work
|
|
#include <crt\io.h>
|
|
#include <fcntl.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
|
|
|
|
|
|
PCHAR
|
|
GetLogFileName(
|
|
void
|
|
)
|
|
{
|
|
static CHAR szLogFileName[MAX_PATH+50];
|
|
PCHAR ExeDir;
|
|
|
|
ExeDir = &szLogFileName[0];
|
|
|
|
*ExeDir = 0;
|
|
// Get the directory the debugger executable is in.
|
|
if (!GetModuleFileName(NULL, ExeDir, MAX_PATH))
|
|
{
|
|
// Error. Use the current directory.
|
|
StringCchCopy(ExeDir, sizeof(szLogFileName), ".");
|
|
} else
|
|
{
|
|
// Remove the executable name.
|
|
PCHAR pszTmp = strrchr(ExeDir, '\\');
|
|
if (pszTmp)
|
|
{
|
|
*pszTmp = 0;
|
|
}
|
|
}
|
|
StringCchCat(ExeDir, sizeof(szLogFileName), "\\FailedAddCrash.log");
|
|
return &szLogFileName[0];
|
|
|
|
}
|
|
|
|
HRESULT
|
|
NotifyCallerMQ(
|
|
ULONG SourceId,
|
|
PCHAR szBaseURL,
|
|
PCHAR szGuid,
|
|
PCHAR szMQConnectStr
|
|
)
|
|
{
|
|
HRESULT Hr;
|
|
typedef HRESULT (WINAPI* MQSENDMSGPROC)(LPWSTR, LPWSTR, LPWSTR);
|
|
MQSENDMSGPROC pSendMQMessageText;
|
|
CHAR MQExtPath[MAX_PATH], *pBase;
|
|
HMODULE hMod;
|
|
WCHAR wszGuid[50], wszMQConnectStr[100];
|
|
WCHAR wszMQMessage[300], wszSolnParams[] = L"";
|
|
|
|
|
|
if ((StringCbPrintfW(wszGuid, sizeof(wszGuid), L"%S", szGuid) != S_OK) ||
|
|
(StringCbPrintfW(wszMQConnectStr, sizeof(wszMQConnectStr), L"%S", szMQConnectStr) != S_OK) ||
|
|
(StringCbPrintfW(wszMQMessage, sizeof(wszMQMessage), L"%Ssid=-1&State=0", szBaseURL) != S_OK))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
if (SourceId == CiSrcCER)
|
|
{
|
|
Hr = StringCbPrintfW(wszMQMessage, sizeof(wszMQMessage),
|
|
L"%Ssid=-1&State=0&szSBucket=BAD_DUMPFILE&iSBucket=-1&szGBucket=BAD_DUMPFILE&iGBucket=-1&gsid=-1",
|
|
szBaseURL
|
|
);
|
|
if (FAILED(Hr))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
|
|
if (!GetModuleFileName(NULL, MQExtPath, sizeof(MQExtPath)))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
pBase = strrchr(MQExtPath, '\\');
|
|
if (!pBase)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
*pBase = '\0';
|
|
Hr = StringCchCat(MQExtPath, sizeof(MQExtPath), "\\winext\\mqext.dll");
|
|
if (FAILED(Hr))
|
|
{
|
|
return Hr;
|
|
}
|
|
hMod = LoadLibrary(MQExtPath);
|
|
|
|
if (hMod == NULL)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
if ((pSendMQMessageText = (MQSENDMSGPROC) GetProcAddress(hMod, "_EFN_SendMQMessageText")) != NULL)
|
|
{
|
|
return pSendMQMessageText(wszMQConnectStr, wszGuid, wszMQMessage);
|
|
}
|
|
FreeLibrary(hMod);
|
|
return S_OK;
|
|
}
|
|
|
|
void
|
|
UpdateDbForBadDumpFile(PSTR FilePath)
|
|
{
|
|
HANDLE hFile;
|
|
HMODULE Ext = NULL;
|
|
CHAR ExtCommand[MAX_PATH], *CmdBreak;
|
|
CI_SOURCE Source = CiSrcErClient;
|
|
CRASH_INSTANCE Crash = {0};
|
|
BOOL NoUpdateCustomer = FALSE;
|
|
DBADDCRACHDIRECT FuncAddCrash;
|
|
DEBUG_TRIAGE_FOLLOWUP_INFO UrlInfo;
|
|
CHAR szURL[100];
|
|
EXT_TRIAGE_FOLLOWUP pTriageFollowup;
|
|
CHAR szGuid[50] = {0}, szMQConnectStr[100] = {0};
|
|
PCHAR args;
|
|
|
|
// Load ext.dll
|
|
|
|
Ext = LoadLibrary("winext\\ext.dll");
|
|
if (!Ext)
|
|
{
|
|
ConOut("Cannot load ext.dll.\n");
|
|
}
|
|
|
|
if (!g_InitialCommand)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
StringCchCopy(ExtCommand, sizeof(ExtCommand), g_InitialCommand);
|
|
CmdBreak = strchr(ExtCommand, ';');
|
|
if (CmdBreak)
|
|
{
|
|
*CmdBreak = 0;
|
|
|
|
}
|
|
args = strstr(ExtCommand, "!dbaddcrash");
|
|
if (!args)
|
|
{
|
|
goto error;
|
|
}
|
|
args+=11;
|
|
while (*args)
|
|
{
|
|
if (*args == ' ' || *args == '\t')
|
|
{
|
|
++args;
|
|
continue;
|
|
}
|
|
else if (*args == '-' || *args == '/')
|
|
{
|
|
++args;
|
|
switch (*args)
|
|
{
|
|
case 'g': // GUID identifying this crash, return bucket along with this
|
|
++args;
|
|
while (*args == ' ') ++args;
|
|
if (!sscanf(args,"%50s", szGuid))
|
|
{
|
|
szGuid[0] = 0;
|
|
}
|
|
args+=strlen(szGuid);
|
|
break;
|
|
case 'm':
|
|
if (!strncmp(args, "mail", 4))
|
|
{
|
|
Crash.bSendMail = TRUE;
|
|
args+=4;
|
|
}
|
|
break;
|
|
case 'n':
|
|
if (!strncmp(args, "nocust", 6))
|
|
{
|
|
NoUpdateCustomer = TRUE;
|
|
Crash.bUpdateCustomer = FALSE;
|
|
args+=6;
|
|
}
|
|
break;
|
|
case 'o':
|
|
++args;
|
|
break;
|
|
case 'p':
|
|
{
|
|
CHAR Path[240];
|
|
++args;
|
|
while (*args == ' ') ++args;
|
|
if (!sscanf(args,"%240s", Path))
|
|
{
|
|
Path[0] = 0;
|
|
}
|
|
args+=strlen(Path);
|
|
break;
|
|
}
|
|
case 'r':
|
|
if (!strncmp(args, "retriage", 8))
|
|
{
|
|
Crash.bResetBucket = TRUE;
|
|
args+=8;
|
|
}
|
|
break;
|
|
case 's': // queue connection string to send bucketid back
|
|
if (!strncmp(args, "source", 6))
|
|
{
|
|
args+=6;
|
|
while (*args == ' ') ++args;
|
|
|
|
if (isdigit(*args))
|
|
{
|
|
Source = (CI_SOURCE) atoi(args);
|
|
if (Source > (ULONG) CiSrcMax)
|
|
{
|
|
Source = CiSrcErClient;
|
|
}
|
|
while (isdigit(*args)) ++args;
|
|
}
|
|
} else
|
|
{
|
|
++args;
|
|
while (*args == ' ') ++args;
|
|
if (!sscanf(args,"%100s", szMQConnectStr))
|
|
{
|
|
szMQConnectStr[0] = 0;
|
|
}
|
|
args+=strlen(szMQConnectStr);
|
|
}
|
|
break;
|
|
default:
|
|
++args;
|
|
|
|
while (*args == ' ' || *args == '\t' )
|
|
{
|
|
++args;
|
|
}
|
|
while (*args && *args != '/' && *args != '-')
|
|
{
|
|
++args;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If the dump file was not visible, then we got passed a bad name or
|
|
// the serve ris down - these are errors that need to be reported.
|
|
//
|
|
|
|
hFile = CreateFile(FilePath,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
|
FILE_SHARE_DELETE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
Crash.Bucket = "NO_DUMPFILE";
|
|
Crash.DefaultBucket = "NO_DUMPFILE";
|
|
} else
|
|
{
|
|
Crash.Bucket = "BAD_DUMPFILE";
|
|
Crash.DefaultBucket = "BAD_DUMPFILE";
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
ConOut("Running Extension: '%s'\n", ExtCommand);
|
|
|
|
|
|
FuncAddCrash = (DBADDCRACHDIRECT) GetProcAddress(Ext, "_EFN_DbAddCrashDirect");
|
|
if (!FuncAddCrash)
|
|
{
|
|
ConOut("Cannot find _EFN_DbAddCrashDirect\n");
|
|
goto error;
|
|
}
|
|
|
|
// Build CRASH_INSTANCE
|
|
Crash.CrashTime = -1;
|
|
Crash.UpTime = -1;
|
|
Crash.uCpu = -1;
|
|
Crash.Build = 0;
|
|
Crash.SourceId = Source;
|
|
Crash.Followup = "ignore";
|
|
Crash.Path = g_DumpFilesAnsi[0];
|
|
Crash.FailureType = DEBUG_FLR_KERNEL;
|
|
Crash.StopCode = -1;
|
|
Crash.FaultyDriver = "";
|
|
Crash.MesgGuid = szGuid;
|
|
Crash.MqConnectStr = szMQConnectStr;
|
|
Crash.SolutionId = 79;
|
|
Crash.SolutionType = CiSolFixed;
|
|
|
|
if (Crash.bResetBucket && !NoUpdateCustomer)
|
|
{
|
|
// Update customer info for only for retriage
|
|
Crash.bUpdateCustomer = TRUE;
|
|
}
|
|
//
|
|
// Get the failed dump file name
|
|
//
|
|
|
|
CHAR DumpFileName[MAX_PATH];
|
|
|
|
g_DbgClient4->GetDumpFile(DEBUG_DUMP_FILE_LOAD_FAILED_INDEX,
|
|
DumpFileName, sizeof(DumpFileName),
|
|
NULL, NULL, NULL);
|
|
|
|
Crash.OriginalDumpFileName = DumpFileName;
|
|
|
|
//
|
|
// extract the incident ID from the cab name
|
|
// there are 2 types of filenames we could have to support.
|
|
// The old version is id@*.*
|
|
// The new version is id.*
|
|
//
|
|
|
|
CHAR FileName[MAX_PATH];
|
|
|
|
if (FAILED(FuncAddCrash(&Crash, g_DbgControl3)))
|
|
{
|
|
|
|
error:
|
|
|
|
ConOut("Dump file could not be processed - logged to %s\n", GetLogFileName());
|
|
|
|
szURL[0] = 0;
|
|
pTriageFollowup = (EXT_TRIAGE_FOLLOWUP) GetProcAddress(Ext, "_EFN_GetTriageFollowupFromSymbol");
|
|
if (pTriageFollowup)
|
|
{
|
|
UrlInfo.SizeOfStruct = sizeof(UrlInfo);
|
|
UrlInfo.OwnerName = szURL;
|
|
UrlInfo.OwnerNameSize = sizeof(szURL);
|
|
(*pTriageFollowup)(g_DbgClient, "debugger-params!solutionurl", &UrlInfo);
|
|
}
|
|
if (szURL[0] && szMQConnectStr[0] && szGuid[0])
|
|
{
|
|
NotifyCallerMQ(Source, szURL, szGuid, szMQConnectStr);
|
|
}
|
|
int g_LogFile;
|
|
|
|
g_LogFile = _open(GetLogFileName(), O_APPEND | O_CREAT | O_RDWR,
|
|
S_IREAD | S_IWRITE);
|
|
|
|
if (g_LogFile != -1)
|
|
{
|
|
if (FilePath != NULL)
|
|
{
|
|
_write(g_LogFile, FilePath, strlen(FilePath));
|
|
} else
|
|
{
|
|
_write(g_LogFile, "No File provided", strlen("No File provided"));
|
|
|
|
}
|
|
_write(g_LogFile, "\n", strlen("\n"));
|
|
_close(g_LogFile);
|
|
}
|
|
}
|
|
if (Ext)
|
|
{
|
|
FreeLibrary(Ext);
|
|
}
|
|
}
|