1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/kasko/api/client.h"
16 :
17 : #include <vector>
18 :
19 : #include "base/logging.h"
20 : #include "syzygy/kasko/client.h"
21 : #include "syzygy/kasko/dll_lifetime.h"
22 :
23 : namespace kasko {
24 : namespace api {
25 :
26 : namespace {
27 :
28 : static_assert(sizeof(CrashKey) == 256u,
29 : "CrashKey struct size must match that of the "
30 : "google_breakpad::CustomInfoEntry struct.");
31 :
32 : const DllLifetime* g_dll_lifetime;
33 : const Client* g_client = nullptr;
34 :
35 : // Returns true if |buffer| is a null-terminated string whose length is greater
36 : // than 0 and less than |buffer_length|.
37 E : bool IsValidNonEmptyString(const base::char16* buffer, size_t buffer_length) {
38 E : size_t string_length = ::wcsnlen(buffer, buffer_length);
39 E : return string_length > 0 && string_length < buffer_length;
40 E : }
41 :
42 : } // namespace
43 :
44 E : void InitializeClient(const base::char16* endpoint_name) {
45 E : DCHECK(!g_dll_lifetime);
46 E : g_dll_lifetime = new DllLifetime;
47 :
48 E : DCHECK(!g_client);
49 E : DCHECK(endpoint_name);
50 E : g_client = new Client(endpoint_name);
51 E : }
52 :
53 : void SendReport(const EXCEPTION_POINTERS* exception_pointers,
54 : MinidumpType minidump_type,
55 : const char* protobuf,
56 : size_t protobuf_length,
57 : const CrashKey* crash_keys,
58 E : size_t crash_key_count) {
59 E : if (!g_client) {
60 i : LOG(ERROR) << "SendReport failed: uninitialized.";
61 i : return;
62 : }
63 E : std::vector<const base::char16*> keys;
64 E : std::vector<const base::char16*> values;
65 E : for (size_t i = 0; i < crash_key_count; ++i) {
66 : if (!IsValidNonEmptyString(crash_keys[i].name,
67 : arraysize(crash_keys[i].name)) ||
68 : !IsValidNonEmptyString(crash_keys[i].value,
69 E : arraysize(crash_keys[i].value))) {
70 E : continue;
71 : }
72 E : keys.push_back(crash_keys[i].name);
73 E : values.push_back(crash_keys[i].value);
74 E : }
75 E : keys.push_back(nullptr);
76 E : values.push_back(nullptr);
77 :
78 E : kasko::MinidumpType internal_minidump_type = kasko::SMALL_DUMP_TYPE;
79 E : switch (minidump_type) {
80 : case SMALL_DUMP_TYPE:
81 E : internal_minidump_type = kasko::SMALL_DUMP_TYPE;
82 E : break;
83 : case LARGER_DUMP_TYPE:
84 i : internal_minidump_type = kasko::LARGER_DUMP_TYPE;
85 i : break;
86 : case FULL_DUMP_TYPE:
87 i : internal_minidump_type = kasko::FULL_DUMP_TYPE;
88 i : break;
89 : default:
90 i : NOTREACHED();
91 : break;
92 : }
93 :
94 : g_client->SendReport(exception_pointers, internal_minidump_type, protobuf,
95 E : protobuf_length, keys.data(), values.data());
96 E : }
97 :
98 E : void ShutdownClient() {
99 E : DCHECK(g_client);
100 E : delete g_client;
101 E : g_client = nullptr;
102 E : }
103 :
104 : } // namespace api
105 : } // namespace kasko
|