OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/drive_metrics_provider.h" | 5 #include "components/metrics/drive_metrics_provider.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <ntddscsi.h> | 8 #include <ntddscsi.h> |
9 #include <winioctl.h> | 9 #include <winioctl.h> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/files/file.h" | 12 #include "base/files/file.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
17 | 17 |
| 18 namespace metrics { |
| 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 // Semi-copy of similarly named struct from ata.h in WinDDK. | 22 // Semi-copy of similarly named struct from ata.h in WinDDK. |
21 struct IDENTIFY_DEVICE_DATA { | 23 struct IDENTIFY_DEVICE_DATA { |
22 USHORT UnusedWords[217]; | 24 USHORT UnusedWords[217]; |
23 USHORT NominalMediaRotationRate; | 25 USHORT NominalMediaRotationRate; |
24 USHORT MoreUnusedWords[38]; | 26 USHORT MoreUnusedWords[38]; |
25 }; | 27 }; |
26 COMPILE_ASSERT(sizeof(IDENTIFY_DEVICE_DATA) == 512, IdentifyDeviceDataSize); | 28 COMPILE_ASSERT(sizeof(IDENTIFY_DEVICE_DATA) == 512, IdentifyDeviceDataSize); |
27 | 29 |
(...skipping 19 matching lines...) Expand all Loading... |
47 if (!volume.IsValid()) | 49 if (!volume.IsValid()) |
48 return false; | 50 return false; |
49 | 51 |
50 if (win7_or_higher) { | 52 if (win7_or_higher) { |
51 STORAGE_PROPERTY_QUERY query = {}; | 53 STORAGE_PROPERTY_QUERY query = {}; |
52 query.QueryType = PropertyStandardQuery; | 54 query.QueryType = PropertyStandardQuery; |
53 query.PropertyId = StorageDeviceSeekPenaltyProperty; | 55 query.PropertyId = StorageDeviceSeekPenaltyProperty; |
54 | 56 |
55 DEVICE_SEEK_PENALTY_DESCRIPTOR result; | 57 DEVICE_SEEK_PENALTY_DESCRIPTOR result; |
56 DWORD bytes_returned; | 58 DWORD bytes_returned; |
57 BOOL success = DeviceIoControl(volume.GetPlatformFile(), | 59 BOOL success = DeviceIoControl( |
58 IOCTL_STORAGE_QUERY_PROPERTY, | 60 volume.GetPlatformFile(), IOCTL_STORAGE_QUERY_PROPERTY, &query, |
59 &query, sizeof(query), | 61 sizeof(query), &result, sizeof(result), &bytes_returned, NULL); |
60 &result, sizeof(result), | |
61 &bytes_returned, NULL); | |
62 if (success == FALSE || bytes_returned < sizeof(result)) | 62 if (success == FALSE || bytes_returned < sizeof(result)) |
63 return false; | 63 return false; |
64 | 64 |
65 *has_seek_penalty = result.IncursSeekPenalty != FALSE; | 65 *has_seek_penalty = result.IncursSeekPenalty != FALSE; |
66 } else { | 66 } else { |
67 AtaRequest request = {}; | 67 AtaRequest request = {}; |
68 request.query.AtaFlags = ATA_FLAGS_DATA_IN; | 68 request.query.AtaFlags = ATA_FLAGS_DATA_IN; |
69 request.query.CurrentTaskFile[6] = ID_CMD; | 69 request.query.CurrentTaskFile[6] = ID_CMD; |
70 request.query.DataBufferOffset = sizeof(request.query); | 70 request.query.DataBufferOffset = sizeof(request.query); |
71 request.query.DataTransferLength = sizeof(request.result); | 71 request.query.DataTransferLength = sizeof(request.result); |
72 request.query.Length = sizeof(request.query); | 72 request.query.Length = sizeof(request.query); |
73 request.query.TimeOutValue = 10; | 73 request.query.TimeOutValue = 10; |
74 | 74 |
75 DWORD bytes_returned; | 75 DWORD bytes_returned; |
76 BOOL success = DeviceIoControl(volume.GetPlatformFile(), | 76 BOOL success = DeviceIoControl( |
77 IOCTL_ATA_PASS_THROUGH, | 77 volume.GetPlatformFile(), IOCTL_ATA_PASS_THROUGH, &request, |
78 &request, sizeof(request), | 78 sizeof(request), &request, sizeof(request), &bytes_returned, NULL); |
79 &request, sizeof(request), | |
80 &bytes_returned, NULL); | |
81 if (success == FALSE || bytes_returned < sizeof(request) || | 79 if (success == FALSE || bytes_returned < sizeof(request) || |
82 request.query.CurrentTaskFile[0]) { | 80 request.query.CurrentTaskFile[0]) { |
83 return false; | 81 return false; |
84 } | 82 } |
85 | 83 |
86 *has_seek_penalty = request.result.NominalMediaRotationRate != 1; | 84 *has_seek_penalty = request.result.NominalMediaRotationRate != 1; |
87 } | 85 } |
88 | 86 |
89 return true; | 87 return true; |
90 } | 88 } |
| 89 |
| 90 } // namespace metrics |
OLD | NEW |