1 : // Copyright 2011 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 : // Contains implementation details for the various templated functions declared
16 : // in dia_util.h. Not meant to be included directly.
17 :
18 : #ifndef SYZYGY_PE_DIA_UTIL_INTERNAL_H_
19 : #define SYZYGY_PE_DIA_UTIL_INTERNAL_H_
20 :
21 : #include "base/logging.h"
22 : #include "base/win/scoped_bstr.h"
23 : #include "base/win/scoped_comptr.h"
24 : #include "syzygy/common/com_utils.h"
25 :
26 : namespace pe {
27 :
28 : template <typename T>
29 E : bool CreateDiaObject(T** created_object, const CLSID& class_id) {
30 E : return internal::CreateDiaObject(reinterpret_cast<void**>(created_object),
31 : class_id,
32 : __uuidof(T));
33 E : }
34 :
35 : template <typename T>
36 E : SearchResult FindDiaTable(IDiaSession* dia_session, T** out_table) {
37 E : return FindDiaTable(base::win::ScopedComPtr<T>::iid(),
38 : dia_session,
39 : reinterpret_cast<void**>(out_table));
40 E : }
41 :
42 : template <typename T>
43 E : bool LoadDiaDebugStream(IDiaEnumDebugStreamData* stream, std::vector<T>* list) {
44 E : DCHECK(stream != NULL);
45 E : DCHECK(list != NULL);
46 :
47 E : LONG count = 0;
48 E : HRESULT hr = E_FAIL;
49 E : if (FAILED(hr = stream->get_Count(&count))) {
50 i : LOG(ERROR) << "Failed to get stream count: " << common::LogHr(hr) << ".";
51 i : return false;
52 : }
53 :
54 : // Get the length of the debug stream, and ensure it is the expected size.
55 E : DWORD bytes_read = 0;
56 E : ULONG count_read = 0;
57 E : hr = stream->Next(count, 0, &bytes_read, NULL, &count_read);
58 E : if (FAILED(hr)) {
59 i : LOG(ERROR) << "Unable to get debug stream length: "
60 : << common::LogHr(hr) << ".";
61 i : return false;
62 : }
63 E : DCHECK_EQ(count * sizeof(T), bytes_read);
64 :
65 : // Actually read the stream.
66 E : list->resize(count);
67 E : bytes_read = 0;
68 E : count_read = 0;
69 E : hr = stream->Next(count, count * sizeof(T), &bytes_read,
70 : reinterpret_cast<BYTE*>(&list->at(0)),
71 : &count_read);
72 E : if (FAILED(hr)) {
73 i : LOG(ERROR) << "Unable to read debug stream: " << common::LogHr(hr) << ".";
74 i : return false;
75 : }
76 E : DCHECK_EQ(count * sizeof(T), bytes_read);
77 E : DCHECK_EQ(count, static_cast<LONG>(count_read));
78 :
79 E : return true;
80 E : }
81 :
82 : template <typename T>
83 : SearchResult FindAndLoadDiaDebugStreamByName(const wchar_t* name,
84 : IDiaSession* dia_session,
85 E : std::vector<T>* list) {
86 E : DCHECK(name != NULL);
87 E : DCHECK(dia_session != NULL);
88 E : DCHECK(list != NULL);
89 :
90 E : base::win::ScopedComPtr<IDiaEnumDebugStreamData> debug_stream;
91 : SearchResult search_result =
92 E : FindDiaDebugStream(name, dia_session, debug_stream.Receive());
93 E : if (search_result != kSearchSucceeded)
94 E : return search_result;
95 E : DCHECK(debug_stream.get() != NULL);
96 :
97 E : return LoadDiaDebugStream(debug_stream.get(), list) ? kSearchSucceeded :
98 : kSearchErrored;
99 E : }
100 :
101 : } // namespace pe
102 :
103 : #endif // SYZYGY_PE_DIA_UTIL_INTERNAL_H_
|