Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: base/test/test_file_util_win.cc

Issue 2061593002: Fix crash when switching to a profile that cannot be opened (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bug-614753-fix
Patch Set: Respond to nits, fix tests Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/test/test_file_util.h" 5 #include "base/test/test_file_util.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <aclapi.h> 8 #include <aclapi.h>
9 #include <shlwapi.h> 9 #include <shlwapi.h>
10 #include <stddef.h> 10 #include <stddef.h>
11 11
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
18 #include "base/threading/platform_thread.h" 18 #include "base/threading/platform_thread.h"
19 #include "base/win/scoped_handle.h" 19 #include "base/win/scoped_handle.h"
20 20
21 namespace base { 21 namespace base {
22 22
23 namespace { 23 namespace {
24 24
25 struct PermissionInfo { 25 struct PermissionInfo {
26 PSECURITY_DESCRIPTOR security_descriptor; 26 PSECURITY_DESCRIPTOR security_descriptor;
27 ACL dacl; 27 ACL dacl;
28 }; 28 };
29 29
30 // Deny |permission| on the file |path|, for the current user.
31 bool DenyFilePermission(const FilePath& path, DWORD permission) {
32 PACL old_dacl;
33 PSECURITY_DESCRIPTOR security_descriptor;
34 if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
35 SE_FILE_OBJECT,
36 DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl,
37 NULL, &security_descriptor) != ERROR_SUCCESS) {
38 return false;
39 }
40
41 EXPLICIT_ACCESS change;
42 change.grfAccessPermissions = permission;
43 change.grfAccessMode = DENY_ACCESS;
44 change.grfInheritance = 0;
45 change.Trustee.pMultipleTrustee = NULL;
46 change.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
47 change.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
48 change.Trustee.TrusteeType = TRUSTEE_IS_USER;
49 change.Trustee.ptstrName = const_cast<wchar_t*>(L"CURRENT_USER");
50
51 PACL new_dacl;
52 if (SetEntriesInAcl(1, &change, old_dacl, &new_dacl) != ERROR_SUCCESS) {
53 LocalFree(security_descriptor);
54 return false;
55 }
56
57 DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
58 SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
59 NULL, NULL, new_dacl, NULL);
60 LocalFree(security_descriptor);
61 LocalFree(new_dacl);
62
63 return rc == ERROR_SUCCESS;
64 }
65
66 // Gets a blob indicating the permission information for |path|. 30 // Gets a blob indicating the permission information for |path|.
67 // |length| is the length of the blob. Zero on failure. 31 // |length| is the length of the blob. Zero on failure.
68 // Returns the blob pointer, or NULL on failure. 32 // Returns the blob pointer, or NULL on failure.
69 void* GetPermissionInfo(const FilePath& path, size_t* length) { 33 void* GetPermissionInfo(const FilePath& path, size_t* length) {
70 DCHECK(length != NULL); 34 DCHECK(length != NULL);
71 *length = 0; 35 *length = 0;
72 PACL dacl = NULL; 36 PACL dacl = NULL;
73 PSECURITY_DESCRIPTOR security_descriptor; 37 PSECURITY_DESCRIPTOR security_descriptor;
74 if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()), 38 if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
75 SE_FILE_OBJECT, 39 SE_FILE_OBJECT,
(...skipping 28 matching lines...) Expand all
104 LocalFree(perm->security_descriptor); 68 LocalFree(perm->security_descriptor);
105 69
106 char* char_array = reinterpret_cast<char*>(info); 70 char* char_array = reinterpret_cast<char*>(info);
107 delete [] char_array; 71 delete [] char_array;
108 72
109 return rc == ERROR_SUCCESS; 73 return rc == ERROR_SUCCESS;
110 } 74 }
111 75
112 } // namespace 76 } // namespace
113 77
78 // Deny |permission| on the file |path|, for the current user.
Peter Kasting 2016/06/16 07:02:10 Nit: Definition order in .cc file must match decla
WC Leung 2016/07/04 18:45:37 Acknowledged.
79 bool DenyFilePermission(const FilePath& path, DWORD permission) {
80 PACL old_dacl;
81 PSECURITY_DESCRIPTOR security_descriptor;
82 if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
Peter Kasting 2016/06/16 07:02:10 My comments about const_cast stand (3 places). In
WC Leung 2016/07/04 18:45:37 Thanks a lot. I'll use wcsncpy() because - wcscpy(
83 SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr,
84 nullptr, &old_dacl, nullptr,
85 &security_descriptor) != ERROR_SUCCESS) {
86 return false;
87 }
88
89 EXPLICIT_ACCESS new_access = {
90 permission,
91 DENY_ACCESS,
92 0,
93 {nullptr, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER,
94 const_cast<wchar_t*>(L"CURRENT_USER")}};
95
96 PACL new_dacl;
97 if (SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl) != ERROR_SUCCESS) {
98 LocalFree(security_descriptor);
Peter Kasting 2016/06/16 07:02:10 I assume you decided to investigate the scoping ob
WC Leung 2016/06/16 10:04:10 Yes.
WC Leung 2016/06/20 16:54:08 Created issue 621559 to track this.
99 return false;
100 }
101
102 DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
103 SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
104 nullptr, nullptr, new_dacl, nullptr);
105 LocalFree(security_descriptor);
106 LocalFree(new_dacl);
107
108 return rc == ERROR_SUCCESS;
109 }
110
114 bool DieFileDie(const FilePath& file, bool recurse) { 111 bool DieFileDie(const FilePath& file, bool recurse) {
115 // It turns out that to not induce flakiness a long timeout is needed. 112 // It turns out that to not induce flakiness a long timeout is needed.
116 const int kIterations = 25; 113 const int kIterations = 25;
117 const TimeDelta kTimeout = TimeDelta::FromSeconds(10) / kIterations; 114 const TimeDelta kTimeout = TimeDelta::FromSeconds(10) / kIterations;
118 115
119 if (!PathExists(file)) 116 if (!PathExists(file))
120 return true; 117 return true;
121 118
122 // Sometimes Delete fails, so try a few more times. Divide the timeout 119 // Sometimes Delete fails, so try a few more times. Divide the timeout
123 // into short chunks, so that if a try succeeds, we won't delay the test 120 // into short chunks, so that if a try succeeds, we won't delay the test
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 DCHECK(info_ != NULL); 203 DCHECK(info_ != NULL);
207 DCHECK_NE(0u, length_); 204 DCHECK_NE(0u, length_);
208 } 205 }
209 206
210 FilePermissionRestorer::~FilePermissionRestorer() { 207 FilePermissionRestorer::~FilePermissionRestorer() {
211 if (!RestorePermissionInfo(path_, info_, length_)) 208 if (!RestorePermissionInfo(path_, info_, length_))
212 NOTREACHED(); 209 NOTREACHED();
213 } 210 }
214 211
215 } // namespace base 212 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698