1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/LSPAnnotator.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,112 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/** 1.9 + * LSPs are evil little bits of code that are allowed to inject into our 1.10 + * networking stack by Windows. Once they have wormed into our process 1.11 + * they gnaw at our innards until we crash. Here we force the buggers 1.12 + * into the light by recording them in our crash information. 1.13 + * We do the enumeration on a thread because I'm concerned about startup perf 1.14 + * on machines with several LSPs. 1.15 + */ 1.16 + 1.17 +#include "nsICrashReporter.h" 1.18 +#include "nsISupportsImpl.h" 1.19 +#include "nsServiceManagerUtils.h" 1.20 +#include "nsThreadUtils.h" 1.21 +#include <windows.h> 1.22 +#include <ws2spi.h> 1.23 + 1.24 +namespace mozilla { 1.25 +namespace crashreporter { 1.26 + 1.27 +class LSPAnnotationGatherer : public nsRunnable 1.28 +{ 1.29 +public: 1.30 + NS_DECL_THREADSAFE_ISUPPORTS 1.31 + NS_DECL_NSIRUNNABLE 1.32 + 1.33 + void Annotate(); 1.34 + nsCString mString; 1.35 + nsCOMPtr<nsIThread> mThread; 1.36 +}; 1.37 + 1.38 +NS_IMPL_ISUPPORTS(LSPAnnotationGatherer, nsIRunnable) 1.39 + 1.40 +void 1.41 +LSPAnnotationGatherer::Annotate() 1.42 +{ 1.43 + nsCOMPtr<nsICrashReporter> cr = 1.44 + do_GetService("@mozilla.org/toolkit/crash-reporter;1"); 1.45 + bool enabled; 1.46 + if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) { 1.47 + cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString); 1.48 + } 1.49 + mThread->Shutdown(); 1.50 +} 1.51 + 1.52 +NS_IMETHODIMP 1.53 +LSPAnnotationGatherer::Run() 1.54 +{ 1.55 + PR_SetCurrentThreadName("LSP Annotator"); 1.56 + 1.57 + mThread = NS_GetCurrentThread(); 1.58 + 1.59 + DWORD size = 0; 1.60 + int err; 1.61 + // Get the size of the buffer we need 1.62 + if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) || 1.63 + err != WSAENOBUFS) { 1.64 + // Er, what? 1.65 + NS_NOTREACHED("WSCEnumProtocols suceeded when it should have failed ..."); 1.66 + return NS_ERROR_FAILURE; 1.67 + } 1.68 + 1.69 + nsAutoArrayPtr<char> byteArray(new char[size]); 1.70 + WSAPROTOCOL_INFOW* providers = 1.71 + reinterpret_cast<WSAPROTOCOL_INFOW*>(byteArray.get()); 1.72 + 1.73 + int n = WSCEnumProtocols(nullptr, providers, &size, &err); 1.74 + if (n == SOCKET_ERROR) { 1.75 + // Lame. We provided the right size buffer; we'll just give up now. 1.76 + NS_WARNING("Could not get LSP list"); 1.77 + return NS_ERROR_FAILURE; 1.78 + } 1.79 + 1.80 + nsCString str; 1.81 + for (int i = 0; i < n; i++) { 1.82 + AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str); 1.83 + str.AppendLiteral(" : "); 1.84 + str.AppendInt(providers[i].iVersion); 1.85 + str.AppendLiteral(" : "); 1.86 + str.AppendInt(providers[i].iSocketType); 1.87 + str.AppendLiteral(" : "); 1.88 + 1.89 + wchar_t path[MAX_PATH]; 1.90 + int dummy; 1.91 + if (!WSCGetProviderPath(&providers[i].ProviderId, path, 1.92 + &dummy, &err)) { 1.93 + AppendUTF16toUTF8(nsDependentString(path), str); 1.94 + } 1.95 + 1.96 + if (i + 1 != n) { 1.97 + str.AppendLiteral(" \n "); 1.98 + } 1.99 + } 1.100 + 1.101 + mString = str; 1.102 + NS_DispatchToMainThread(NS_NewRunnableMethod(this, &LSPAnnotationGatherer::Annotate)); 1.103 + return NS_OK; 1.104 +} 1.105 + 1.106 +void LSPAnnotate() 1.107 +{ 1.108 + nsCOMPtr<nsIThread> thread; 1.109 + nsCOMPtr<nsIRunnable> runnable = 1.110 + do_QueryObject(new LSPAnnotationGatherer()); 1.111 + NS_NewThread(getter_AddRefs(thread), runnable); 1.112 +} 1.113 + 1.114 +} // namespace crashreporter 1.115 +} // namespace mozilla