blob: ec6a07633abcfb4cd31f0075f5cad8d1ce9b6fdd [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "syzygy/refinery/symbols/symbol_provider_util.h"
#include <string>
#include "base/environment.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "syzygy/pe/find.h"
namespace refinery {
namespace {
// TODO(manzagop): this probably exists somewhere?
bool GetEnvVar(const char* name, base::string16* value) {
DCHECK(name != NULL);
DCHECK(value != NULL);
value->clear();
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (env.get() == NULL) {
LOG(ERROR) << "base::Environment::Create returned NULL.";
return false;
}
// If this fails, the environment variable simply does not exist.
std::string var;
if (!env->GetVar(name, &var))
return true;
if (!base::UTF8ToUTF16(var.c_str(), var.size(), value)) {
LOG(ERROR) << "base::UTF8ToUTF16(\"" << var << "\" failed.";
return false;
}
return true;
}
} // namespace
bool GetPdbPath(const pe::PEFile::Signature& signature,
base::FilePath* pdb_path) {
DCHECK(pdb_path);
// Get the module's path.
base::string16 symbol_paths;
GetEnvVar("_NT_SYMBOL_PATH", &symbol_paths);
base::FilePath module_local_path;
if (!pe::FindModuleBySignature(signature, symbol_paths, &module_local_path) ||
module_local_path.empty()) {
LOG(ERROR) << "Failed to find module (name, size, timestamp): "
<< signature.path << ", " << signature.module_size << ", "
<< signature.module_time_date_stamp;
return false;
}
// Get the pdb's path.
if (!pe::FindPdbForModule(module_local_path, symbol_paths, pdb_path) ||
pdb_path->empty()) {
LOG(ERROR) << "Failed to find pdb for module " << signature.path;
return false;
}
return true;
}
} // namespace refinery