Chromium Code Reviews| Index: chrome/browser/crash_upload_list_win.cc |
| diff --git a/chrome/browser/crash_upload_list_win.cc b/chrome/browser/crash_upload_list_win.cc |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..8baf91a5ea6e2a05fb8e8f7d397ca6aefbbce77f |
| --- /dev/null |
| +++ b/chrome/browser/crash_upload_list_win.cc |
| @@ -0,0 +1,79 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/crash_upload_list_win.h" |
| + |
| +#include "base/stringprintf.h" |
| +#include "base/string_util.h" |
| +#include "base/sys_string_conversions.h" |
| + |
| +CrashUploadListWin::CrashUploadListWin(Delegate* delegate) |
| + : CrashUploadList(delegate) {} |
| + |
| +void CrashUploadListWin::LoadCrashList() { |
| + std::vector<uint8> buffer(1024); |
| + HANDLE event_log = OpenEventLog(NULL, L"Application"); |
| + if (event_log) { |
| + while (true) { |
| + DWORD bytes_read; |
| + DWORD bytes_needed; |
| + BOOL success = |
| + ReadEventLog(event_log, |
| + EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, |
| + 0, |
| + &buffer[0], |
| + buffer.size(), |
| + &bytes_read, |
| + &bytes_needed); |
| + if (success) { |
| + DWORD record_offset = 0; |
| + while (record_offset + sizeof(EVENTLOGRECORD) <= bytes_read) { |
| + EVENTLOGRECORD* record = (EVENTLOGRECORD*)&buffer[record_offset]; |
| + // Records are variable length, so check that record->Length fits |
| + // within bytes_read before using the record. |
| + if (record_offset + record->Length > bytes_read) |
| + break; |
|
MAD
2011/04/01 14:28:20
OK, now we won't read beyond bytes_read, but if a
Alexei Svitkine (slow)
2011/04/01 15:01:23
Done.
|
| + if (IsPossibleCrashLogRecord(record)) |
| + ProcessPossibleCrashLogRecord(record); |
| + record_offset += record->Length; |
| + } |
| + } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { |
| + // Resize buffer to the required minimum size. |
| + buffer.resize(bytes_needed); |
| + } else { |
| + // Stop on any other error, including the expected case |
| + // of ERROR_HANDLE_EOF. |
| + DCHECK(GetLastError() == ERROR_HANDLE_EOF); |
| + break; |
| + } |
| + } |
| + CloseEventLog(event_log); |
| + } |
| +} |
| + |
| +bool CrashUploadListWin::IsPossibleCrashLogRecord( |
| + EVENTLOGRECORD* record) const { |
| + LPWSTR provider_name = (LPWSTR)((uint8*)record + sizeof(EVENTLOGRECORD)); |
| + return !wcscmp(L"Chrome", provider_name) && |
| + record->EventType == EVENTLOG_INFORMATION_TYPE && |
| + record->NumStrings >= 1; |
| +} |
| + |
| +void CrashUploadListWin::ProcessPossibleCrashLogRecord(EVENTLOGRECORD* record) { |
| + // Add the crash if the message matches the expected pattern. |
| + const std::wstring pattern_prefix(L"Id="); |
| + const std::wstring pattern_suffix(L"."); |
| + std::wstring message((LPWSTR)((uint8*)record + record->StringOffset)); |
| + size_t start_index = message.find(pattern_prefix); |
| + if (start_index != std::wstring::npos && |
| + EndsWith(message, pattern_suffix, false)) { |
|
MAD
2011/04/01 14:28:20
You are still assuming that the id=XXX. will be at
Alexei Svitkine (slow)
2011/04/01 15:01:23
Done.
|
| + size_t end_index = message.size() - pattern_suffix.size(); |
| + start_index += pattern_prefix.size(); |
| + std::wstring crash_id = |
| + message.substr(start_index, end_index - start_index); |
| + crashes().push_back( |
| + CrashInfo(base::SysWideToUTF8(crash_id), |
| + base::Time::FromDoubleT(record->TimeGenerated))); |
| + } |
| +} |