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 |