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 : SearchResult FindDiaTable(IDiaSession* dia_session, T** out_table) {
30 : return FindDiaTable(base::win::ScopedComPtr<T>::iid(),
31 : dia_session,
32 E : reinterpret_cast<void**>(out_table));
33 E : }
34 :
35 : template <typename T>
36 E : bool LoadDiaDebugStream(IDiaEnumDebugStreamData* stream, std::vector<T>* list) {
37 E : DCHECK(stream != NULL);
38 E : DCHECK(list != NULL);
39 :
40 E : LONG count = 0;
41 E : HRESULT hr = E_FAIL;
42 E : if (FAILED(hr = stream->get_Count(&count))) {
43 i : LOG(ERROR) << "Failed to get stream count: " << common::LogHr(hr) << ".";
44 i : return false;
45 : }
46 :
47 : // Get the length of the debug stream, and ensure it is the expected size.
48 E : DWORD bytes_read = 0;
49 E : ULONG count_read = 0;
50 E : hr = stream->Next(count, 0, &bytes_read, NULL, &count_read);
51 E : if (FAILED(hr)) {
52 i : LOG(ERROR) << "Unable to get debug stream length: "
53 : << common::LogHr(hr) << ".";
54 i : return false;
55 : }
56 E : DCHECK_EQ(count * sizeof(T), bytes_read);
57 :
58 : // Actually read the stream.
59 E : list->resize(count);
60 E : bytes_read = 0;
61 E : count_read = 0;
62 : hr = stream->Next(count, count * sizeof(T), &bytes_read,
63 : reinterpret_cast<BYTE*>(&list->at(0)),
64 E : &count_read);
65 E : if (FAILED(hr)) {
66 i : LOG(ERROR) << "Unable to read debug stream: " << common::LogHr(hr) << ".";
67 i : return false;
68 : }
69 E : DCHECK_EQ(count * sizeof(T), bytes_read);
70 E : DCHECK_EQ(count, static_cast<LONG>(count_read));
71 :
72 E : return true;
73 E : }
74 :
75 : template <typename T>
76 : SearchResult FindAndLoadDiaDebugStreamByName(const wchar_t* name,
77 : IDiaSession* dia_session,
78 E : std::vector<T>* list) {
79 E : DCHECK(name != NULL);
80 E : DCHECK(dia_session != NULL);
81 E : DCHECK(list != NULL);
82 :
83 E : base::win::ScopedComPtr<IDiaEnumDebugStreamData> debug_stream;
84 : SearchResult search_result =
85 E : FindDiaDebugStream(name, dia_session, debug_stream.Receive());
86 E : if (search_result != kSearchSucceeded)
87 E : return search_result;
88 E : DCHECK(debug_stream.get() != NULL);
89 :
90 : return LoadDiaDebugStream(debug_stream.get(), list) ? kSearchSucceeded :
91 E : kSearchErrored;
92 E : }
93 :
94 : } // namespace pe
95 :
96 : #endif // SYZYGY_PE_DIA_UTIL_INTERNAL_H_
|