OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/crash_upload_list_win.h" |
| 6 |
| 7 #include "base/strings/string_util.h" |
| 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "base/threading/sequenced_worker_pool.h" |
| 11 |
| 12 CrashUploadListWin::CrashUploadListWin( |
| 13 Delegate* delegate, |
| 14 const base::FilePath& upload_log_path, |
| 15 const scoped_refptr<base::SequencedWorkerPool>& worker_pool) |
| 16 : CrashUploadList(delegate, upload_log_path, worker_pool) {} |
| 17 |
| 18 void CrashUploadListWin::LoadUploadList() { |
| 19 std::vector<uint8> buffer(1024); |
| 20 HANDLE event_log = OpenEventLog(NULL, L"Application"); |
| 21 if (event_log) { |
| 22 ClearUploads(); |
| 23 while (true) { |
| 24 DWORD bytes_read; |
| 25 DWORD bytes_needed; |
| 26 BOOL success = |
| 27 ReadEventLog(event_log, |
| 28 EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, |
| 29 0, |
| 30 &buffer[0], |
| 31 buffer.size(), |
| 32 &bytes_read, |
| 33 &bytes_needed); |
| 34 if (success) { |
| 35 DWORD record_offset = 0; |
| 36 // The ReadEventLog() API docs imply, but do not explicitly state that |
| 37 // partial records will not be returned. Use DCHECK() to affirm this. |
| 38 while (record_offset < bytes_read) { |
| 39 DCHECK(record_offset + sizeof(EVENTLOGRECORD) <= bytes_read); |
| 40 EVENTLOGRECORD* record = (EVENTLOGRECORD*)&buffer[record_offset]; |
| 41 DCHECK(record_offset + record->Length <= bytes_read); |
| 42 if (IsPossibleCrashLogRecord(record)) |
| 43 ProcessPossibleCrashLogRecord(record); |
| 44 record_offset += record->Length; |
| 45 } |
| 46 } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { |
| 47 // Resize buffer to the required minimum size. |
| 48 buffer.resize(bytes_needed); |
| 49 } else { |
| 50 // Stop on any other error, including the expected case |
| 51 // of ERROR_HANDLE_EOF. |
| 52 DCHECK(GetLastError() == ERROR_HANDLE_EOF); |
| 53 break; |
| 54 } |
| 55 } |
| 56 CloseEventLog(event_log); |
| 57 } |
| 58 } |
| 59 |
| 60 CrashUploadListWin::~CrashUploadListWin() { |
| 61 } |
| 62 |
| 63 bool CrashUploadListWin::IsPossibleCrashLogRecord( |
| 64 EVENTLOGRECORD* record) const { |
| 65 LPWSTR provider_name = (LPWSTR)((uint8*)record + sizeof(EVENTLOGRECORD)); |
| 66 return !wcscmp(L"Chrome", provider_name) && |
| 67 record->EventType == EVENTLOG_INFORMATION_TYPE && |
| 68 record->NumStrings >= 1; |
| 69 } |
| 70 |
| 71 void CrashUploadListWin::ProcessPossibleCrashLogRecord(EVENTLOGRECORD* record) { |
| 72 // Add the crash if the message matches the expected pattern. |
| 73 const std::wstring pattern_prefix(L"Id="); |
| 74 const std::wstring pattern_suffix(L"."); |
| 75 std::wstring message((LPWSTR)((uint8*)record + record->StringOffset)); |
| 76 size_t start_index = message.find(pattern_prefix); |
| 77 if (start_index != std::wstring::npos) { |
| 78 start_index += pattern_prefix.size(); |
| 79 size_t end_index = message.find(pattern_suffix, start_index); |
| 80 if (end_index != std::wstring::npos) { |
| 81 std::wstring crash_id = |
| 82 message.substr(start_index, end_index - start_index); |
| 83 AppendUploadInfo( |
| 84 UploadInfo(base::SysWideToUTF8(crash_id), |
| 85 base::Time::FromDoubleT(record->TimeGenerated))); |
| 86 } |
| 87 } |
| 88 } |
OLD | NEW |