This source file includes following definitions.
- GetMachineId
- CreateInstance
#include "chrome/browser/metrics/machine_id_provider.h"
#include <windows.h>
#include <winioctl.h>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/win/scoped_handle.h"
#include "content/public/browser/browser_thread.h"
namespace metrics {
MachineIdProvider::MachineIdProvider() {}
MachineIdProvider::~MachineIdProvider() {}
std::string MachineIdProvider::GetMachineId() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
base::FilePath executable_path;
if (!PathService::Get(base::FILE_EXE, &executable_path)) {
NOTREACHED();
return std::string();
}
std::vector<base::FilePath::StringType> path_components;
executable_path.GetComponents(&path_components);
if (path_components.empty()) {
NOTREACHED();
return std::string();
}
base::FilePath::StringType drive_name = L"\\\\.\\" + path_components[0];
base::win::ScopedHandle drive_handle(CreateFile(
drive_name.c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL));
STORAGE_PROPERTY_QUERY query = {};
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
DWORD bytes_returned;
STORAGE_DESCRIPTOR_HEADER header = {};
BOOL status = DeviceIoControl(drive_handle, IOCTL_STORAGE_QUERY_PROPERTY,
&query, sizeof(STORAGE_PROPERTY_QUERY),
&header, sizeof(STORAGE_DESCRIPTOR_HEADER),
&bytes_returned, NULL);
if (!status)
return std::string();
std::vector<int8> output_buf(header.Size);
status = DeviceIoControl(drive_handle, IOCTL_STORAGE_QUERY_PROPERTY,
&query, sizeof(STORAGE_PROPERTY_QUERY),
&output_buf[0], output_buf.size(),
&bytes_returned, NULL);
if (!status)
return std::string();
const STORAGE_DEVICE_DESCRIPTOR* device_descriptor =
reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(&output_buf[0]);
const DWORD offset = device_descriptor->SerialNumberOffset;
if (offset >= output_buf.size())
return std::string();
const std::vector<int8>::iterator serial_number_begin =
output_buf.begin() + offset;
const std::vector<int8>::iterator null_location =
std::find(serial_number_begin, output_buf.end(), '\0');
if (null_location == output_buf.end())
return std::string();
const char* serial_number =
reinterpret_cast<const char*>(&output_buf[offset]);
return std::string(serial_number);
}
MachineIdProvider* MachineIdProvider::CreateInstance() {
return new MachineIdProvider();
}
}