mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1240315: Add startup crash report annotation for AppInit_DLLs; r=jimm
This commit is contained in:
parent
32b718d585
commit
898a717959
@ -159,6 +159,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include <comdef.h>
|
||||
#include <wbemidl.h>
|
||||
#include "WinUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
@ -3330,6 +3331,15 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
||||
IsSignalHandlingBroken() ? NS_LITERAL_CSTRING("1")
|
||||
: NS_LITERAL_CSTRING("0"));
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsAutoString appInitDLLs;
|
||||
if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AppInitDLLs"),
|
||||
NS_ConvertUTF16toUTF8(appInitDLLs));
|
||||
}
|
||||
#endif
|
||||
|
||||
CrashReporter::SetRestartArgs(gArgc, gArgv);
|
||||
|
||||
// annotate other data (user id etc)
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsIThread.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#ifdef NS_ENABLE_TSF
|
||||
@ -55,6 +56,8 @@
|
||||
#include "TSFTextStore.h"
|
||||
#endif // #ifdef NS_ENABLE_TSF
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
PRLogModuleInfo* gWindowsLog = nullptr;
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
@ -1901,5 +1904,165 @@ WinUtils::ResolveMovedUsersFolder(std::wstring& aPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
WinUtils::SanitizePath(const wchar_t* aInputPath, nsAString& aOutput)
|
||||
{
|
||||
aOutput.Truncate();
|
||||
wchar_t buffer[MAX_PATH + 1] = {0};
|
||||
if (!PathCanonicalizeW(buffer, aInputPath)) {
|
||||
return false;
|
||||
}
|
||||
wchar_t longBuffer[MAX_PATH + 1] = {0};
|
||||
DWORD longResult = GetLongPathNameW(buffer, longBuffer, MAX_PATH);
|
||||
if (longResult == 0 || longResult > MAX_PATH - 1) {
|
||||
return false;
|
||||
}
|
||||
aOutput.SetLength(MAX_PATH + 1);
|
||||
if (!PathUnExpandEnvStringsW(longBuffer, aOutput.BeginWriting(), MAX_PATH)) {
|
||||
return false;
|
||||
}
|
||||
// Truncate to correct length
|
||||
aOutput.Truncate(wcslen(aOutput.BeginReading()));
|
||||
MOZ_ASSERT(aOutput.Length() <= MAX_PATH);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function provides an array of (system path, substitution) pairs that are
|
||||
* considered to be acceptable with respect to privacy, for the purposes of
|
||||
* submitting within telemetry or crash reports.
|
||||
*
|
||||
* The substitution string's void flag may be set. If it is, no subsitution is
|
||||
* necessary. Otherwise, the consumer should replace the system path with the
|
||||
* substitution.
|
||||
*
|
||||
* @see GetAppInitDLLs for an example of its usage.
|
||||
*/
|
||||
/* static */
|
||||
void
|
||||
WinUtils::GetWhitelistedPaths(
|
||||
nsTArray<mozilla::Pair<nsString,nsDependentString>>& aOutput)
|
||||
{
|
||||
aOutput.Clear();
|
||||
aOutput.AppendElement(mozilla::MakePair(
|
||||
nsString(NS_LITERAL_STRING("%ProgramFiles%")),
|
||||
nsDependentString()));
|
||||
// When no substitution is required, set the void flag
|
||||
aOutput.LastElement().second().SetIsVoid(true);
|
||||
wchar_t tmpPath[MAX_PATH + 1] = {0};
|
||||
if (GetTempPath(MAX_PATH, tmpPath)) {
|
||||
// GetTempPath's result always ends with a backslash, which we don't want
|
||||
uint32_t tmpPathLen = wcslen(tmpPath);
|
||||
if (tmpPathLen) {
|
||||
tmpPath[tmpPathLen - 1] = 0;
|
||||
}
|
||||
nsAutoString cleanTmpPath;
|
||||
if (SanitizePath(tmpPath, cleanTmpPath)) {
|
||||
aOutput.AppendElement(mozilla::MakePair(nsString(cleanTmpPath),
|
||||
nsDependentString(L"%TEMP%")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is located here (as opposed to nsSystemInfo or elsewhere)
|
||||
* because we need to gather this information as early as possible during
|
||||
* startup.
|
||||
*/
|
||||
/* static */
|
||||
bool
|
||||
WinUtils::GetAppInitDLLs(nsAString& aOutput)
|
||||
{
|
||||
aOutput.Truncate();
|
||||
HKEY hkey = NULL;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
|
||||
0, KEY_QUERY_VALUE, &hkey)) {
|
||||
return false;
|
||||
}
|
||||
nsAutoRegKey key(hkey);
|
||||
LONG status;
|
||||
if (IsVistaOrLater()) {
|
||||
const wchar_t kLoadAppInitDLLs[] = L"LoadAppInit_DLLs";
|
||||
DWORD loadAppInitDLLs = 0;
|
||||
DWORD loadAppInitDLLsLen = sizeof(loadAppInitDLLs);
|
||||
status = RegQueryValueExW(hkey, kLoadAppInitDLLs, nullptr,
|
||||
nullptr, (LPBYTE)&loadAppInitDLLs,
|
||||
&loadAppInitDLLsLen);
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
if (!loadAppInitDLLs) {
|
||||
// If loadAppInitDLLs is zero then AppInit_DLLs is disabled.
|
||||
// In this case we'll return true along with an empty output string.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DWORD numBytes = 0;
|
||||
const wchar_t kAppInitDLLs[] = L"AppInit_DLLs";
|
||||
// Query for required buffer size
|
||||
status = RegQueryValueExW(hkey, kAppInitDLLs, nullptr, nullptr, nullptr,
|
||||
&numBytes);
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
// Allocate the buffer and query for the actual data
|
||||
mozilla::UniquePtr<wchar_t[]> data =
|
||||
mozilla::MakeUnique<wchar_t[]>(numBytes / sizeof(wchar_t));
|
||||
status = RegQueryValueExW(hkey, kAppInitDLLs, nullptr,
|
||||
nullptr, (LPBYTE)data.get(), &numBytes);
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
nsTArray<mozilla::Pair<nsString,nsDependentString>> whitelistedPaths;
|
||||
GetWhitelistedPaths(whitelistedPaths);
|
||||
// For each token, split up the filename components and then check the
|
||||
// name of the file.
|
||||
const wchar_t kDelimiters[] = L", ";
|
||||
wchar_t* tokenContext = nullptr;
|
||||
wchar_t* token = wcstok_s(data.get(), kDelimiters, &tokenContext);
|
||||
while (token) {
|
||||
nsAutoString cleanPath;
|
||||
// Since these paths are short paths originating from the registry, we need
|
||||
// to canonicalize them, lengthen them, and sanitize them before we can
|
||||
// check them against the whitelist
|
||||
if (SanitizePath(token, cleanPath)) {
|
||||
bool needsStrip = true;
|
||||
for (uint32_t i = 0; i < whitelistedPaths.Length(); ++i) {
|
||||
const nsString& testPath = whitelistedPaths[i].first();
|
||||
const nsDependentString& substitution = whitelistedPaths[i].second();
|
||||
if (StringBeginsWith(cleanPath, testPath,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
if (!substitution.IsVoid()) {
|
||||
cleanPath.Replace(0, testPath.Length(), substitution);
|
||||
}
|
||||
// Whitelisted paths may be used as-is provided that they have been
|
||||
// previously sanitized.
|
||||
needsStrip = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!aOutput.IsEmpty()) {
|
||||
aOutput += L";";
|
||||
}
|
||||
// For non-whitelisted paths, we strip the path component and just leave
|
||||
// the filename.
|
||||
if (needsStrip) {
|
||||
// nsLocalFile doesn't like non-absolute paths. Since these paths might
|
||||
// contain environment variables instead of roots, we can't use it.
|
||||
wchar_t tmpPath[MAX_PATH + 1] = {0};
|
||||
wcsncpy(tmpPath, cleanPath.get(), cleanPath.Length());
|
||||
PathStripPath(tmpPath);
|
||||
aOutput += tmpPath;
|
||||
} else {
|
||||
aOutput += cleanPath;
|
||||
}
|
||||
}
|
||||
token = wcstok_s(nullptr, kDelimiters, &tokenContext);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
@ -445,6 +445,18 @@ public:
|
||||
|
||||
static bool ShouldHideScrollbars();
|
||||
|
||||
/**
|
||||
* This function normalizes the input path, converts short filenames to long
|
||||
* filenames, and substitutes environment variables for system paths.
|
||||
* The resulting output string length is guaranteed to be <= MAX_PATH.
|
||||
*/
|
||||
static bool SanitizePath(const wchar_t* aInputPath, nsAString& aOutput);
|
||||
|
||||
/**
|
||||
* Retrieve a semicolon-delimited list of DLL files derived from AppInit_DLLs
|
||||
*/
|
||||
static bool GetAppInitDLLs(nsAString& aOutput);
|
||||
|
||||
private:
|
||||
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath,
|
||||
IBindCtx *pbc,
|
||||
@ -456,6 +468,9 @@ private:
|
||||
HANDLE hToken,
|
||||
PWSTR *ppszPath);
|
||||
static SHGetKnownFolderPathPtr sGetKnownFolderPath;
|
||||
|
||||
static void GetWhitelistedPaths(
|
||||
nsTArray<mozilla::Pair<nsString,nsDependentString>>& aOutput);
|
||||
};
|
||||
|
||||
#ifdef MOZ_PLACES
|
||||
|
Loading…
Reference in New Issue
Block a user