1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Copyright 2013 The Chromium Authors. All rights reserved.
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// found in the LICENSE file.
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "chrome/browser/profiles/file_path_verifier_win.h"
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <windows.h>
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "base/files/file_path.h"
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "base/files/file_util.h"
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "base/metrics/histogram.h"
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "chrome_elf/create_file/chrome_create_file.h"
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace {
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// This enum is used in UMA histograms and should never be re-ordered.
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum FileVerificationResult {
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_SUCCESS,
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_FILE_NOT_FOUND,
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_INTERNAL_ERROR,
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_FAILED_UNKNOWN,
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_FAILED_SAMEBASE,
23c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian  FILE_VERIFICATION_FAILED_SAMEDIR,
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_SUCCESS_REDIRECT,
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_FAILED_SAMEBASE_REDIRECT,
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FILE_VERIFICATION_FAILED_SAMEDIR_REDIRECT,
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  NUM_FILE_VERIFICATION_RESULTS
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan// Returns a FileVerificationResult based on the state of |file| on disk.
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectFileVerificationResult VerifyFileAtPath(const base::FilePath& file) {
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FileVerificationResult file_verification_result =
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      FILE_VERIFICATION_FAILED_UNKNOWN;
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  base::FilePath normalized_path;
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  int redirect_count_before = ::GetRedirectCount();
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  if (!base::NormalizeFilePath(file, &normalized_path)) {
370db1a8931bb24b4f240c19210e70844af8c1e9ffIliyan Malchev    if (::GetLastError() == ERROR_FILE_NOT_FOUND)
380db1a8931bb24b4f240c19210e70844af8c1e9ffIliyan Malchev      file_verification_result = FILE_VERIFICATION_FILE_NOT_FOUND;
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    else
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      file_verification_result = FILE_VERIFICATION_INTERNAL_ERROR;
415728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan  } else {
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    internal::PathComparisonReason path_comparison_reason =
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        internal::ComparePathsIgnoreCase(file, normalized_path);
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // GetRedirectCount() tracks the number of CreateFile() calls that were
45d4851d74ac9c737acda85f1fdbc028c68f481a36Benny Wong    // redirected. If it has increased then the CreateFile() call made by
465728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan    // base::NormalizeFilePath() was redirected.
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool was_redirected = ::GetRedirectCount() > redirect_count_before;
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (path_comparison_reason) {
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      case internal::PATH_COMPARISON_EQUAL:
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        file_verification_result = was_redirected ?
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            FILE_VERIFICATION_SUCCESS_REDIRECT : FILE_VERIFICATION_SUCCESS;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      case internal::PATH_COMPARISON_FAILED_SAMEBASE:
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        file_verification_result = was_redirected ?
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            FILE_VERIFICATION_FAILED_SAMEBASE_REDIRECT :
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            FILE_VERIFICATION_FAILED_SAMEBASE;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      case internal::PATH_COMPARISON_FAILED_SAMEDIR:
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        file_verification_result = was_redirected ?
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            FILE_VERIFICATION_FAILED_SAMEDIR_REDIRECT :
617b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian            FILE_VERIFICATION_FAILED_SAMEDIR;
627b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian        break;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
647b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian  }
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return file_verification_result;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
677b1905113712281c777b230648d3fbb69ae4f42cMathias Agopian
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}  // namespace
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
705728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajannamespace internal {
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectPathComparisonReason ComparePathsIgnoreCase(const base::FilePath& path1,
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                            const base::FilePath& path2) {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  PathComparisonReason reason = PATH_COMPARISON_FAILED_UNKNOWN;
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  if (base::FilePath::CompareEqualIgnoreCase(path1.value(), path2.value())) {
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    reason = PATH_COMPARISON_EQUAL;
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  } else if (base::FilePath::CompareEqualIgnoreCase(path1.BaseName().value(),
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                                    path2.BaseName().value())) {
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    reason = PATH_COMPARISON_FAILED_SAMEBASE;
815728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan  } else if (base::FilePath::CompareEqualIgnoreCase(path1.DirName().value(),
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                                    path2.DirName().value())) {
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    reason = PATH_COMPARISON_FAILED_SAMEDIR;
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  }
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
865728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan  return reason;
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89d4851d74ac9c737acda85f1fdbc028c68f481a36Benny Wong}  // namespace internal
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid VerifyPreferencesFile(const base::FilePath& pref_file_path) {
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  FileVerificationResult file_verification_result =
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      VerifyFileAtPath(pref_file_path);
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  UMA_HISTOGRAM_ENUMERATION("Stability.FileAtPath.Preferences",
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            file_verification_result,
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            NUM_FILE_VERIFICATION_RESULTS);
975728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan}
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project