Index: base/test/test_file_util_win.cc |
diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc |
deleted file mode 100644 |
index 5496a5574ce6a88d4359bf7c85e35975f6dc7368..0000000000000000000000000000000000000000 |
--- a/base/test/test_file_util_win.cc |
+++ /dev/null |
@@ -1,282 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "base/test/test_file_util.h" |
- |
-#include <windows.h> |
-#include <aclapi.h> |
-#include <shlwapi.h> |
- |
-#include <vector> |
- |
-#include "base/files/file_path.h" |
-#include "base/files/file_util.h" |
-#include "base/logging.h" |
-#include "base/strings/string_split.h" |
-#include "base/threading/platform_thread.h" |
-#include "base/win/scoped_handle.h" |
- |
-namespace base { |
- |
-static const ptrdiff_t kOneMB = 1024 * 1024; |
- |
-namespace { |
- |
-struct PermissionInfo { |
- PSECURITY_DESCRIPTOR security_descriptor; |
- ACL dacl; |
-}; |
- |
-// Deny |permission| on the file |path|, for the current user. |
-bool DenyFilePermission(const FilePath& path, DWORD permission) { |
- PACL old_dacl; |
- PSECURITY_DESCRIPTOR security_descriptor; |
- if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()), |
- SE_FILE_OBJECT, |
- DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, |
- NULL, &security_descriptor) != ERROR_SUCCESS) { |
- return false; |
- } |
- |
- EXPLICIT_ACCESS change; |
- change.grfAccessPermissions = permission; |
- change.grfAccessMode = DENY_ACCESS; |
- change.grfInheritance = 0; |
- change.Trustee.pMultipleTrustee = NULL; |
- change.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; |
- change.Trustee.TrusteeForm = TRUSTEE_IS_NAME; |
- change.Trustee.TrusteeType = TRUSTEE_IS_USER; |
- change.Trustee.ptstrName = const_cast<wchar_t*>(L"CURRENT_USER"); |
- |
- PACL new_dacl; |
- if (SetEntriesInAcl(1, &change, old_dacl, &new_dacl) != ERROR_SUCCESS) { |
- LocalFree(security_descriptor); |
- return false; |
- } |
- |
- DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()), |
- SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, |
- NULL, NULL, new_dacl, NULL); |
- LocalFree(security_descriptor); |
- LocalFree(new_dacl); |
- |
- return rc == ERROR_SUCCESS; |
-} |
- |
-// Gets a blob indicating the permission information for |path|. |
-// |length| is the length of the blob. Zero on failure. |
-// Returns the blob pointer, or NULL on failure. |
-void* GetPermissionInfo(const FilePath& path, size_t* length) { |
- DCHECK(length != NULL); |
- *length = 0; |
- PACL dacl = NULL; |
- PSECURITY_DESCRIPTOR security_descriptor; |
- if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()), |
- SE_FILE_OBJECT, |
- DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, |
- NULL, &security_descriptor) != ERROR_SUCCESS) { |
- return NULL; |
- } |
- DCHECK(dacl != NULL); |
- |
- *length = sizeof(PSECURITY_DESCRIPTOR) + dacl->AclSize; |
- PermissionInfo* info = reinterpret_cast<PermissionInfo*>(new char[*length]); |
- info->security_descriptor = security_descriptor; |
- memcpy(&info->dacl, dacl, dacl->AclSize); |
- |
- return info; |
-} |
- |
-// Restores the permission information for |path|, given the blob retrieved |
-// using |GetPermissionInfo()|. |
-// |info| is the pointer to the blob. |
-// |length| is the length of the blob. |
-// Either |info| or |length| may be NULL/0, in which case nothing happens. |
-bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) { |
- if (!info || !length) |
- return false; |
- |
- PermissionInfo* perm = reinterpret_cast<PermissionInfo*>(info); |
- |
- DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()), |
- SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, |
- NULL, NULL, &perm->dacl, NULL); |
- LocalFree(perm->security_descriptor); |
- |
- char* char_array = reinterpret_cast<char*>(info); |
- delete [] char_array; |
- |
- return rc == ERROR_SUCCESS; |
-} |
- |
-} // namespace |
- |
-bool DieFileDie(const FilePath& file, bool recurse) { |
- // It turns out that to not induce flakiness a long timeout is needed. |
- const int kIterations = 25; |
- const TimeDelta kTimeout = TimeDelta::FromSeconds(10) / kIterations; |
- |
- if (!PathExists(file)) |
- return true; |
- |
- // Sometimes Delete fails, so try a few more times. Divide the timeout |
- // into short chunks, so that if a try succeeds, we won't delay the test |
- // for too long. |
- for (int i = 0; i < kIterations; ++i) { |
- if (DeleteFile(file, recurse)) |
- return true; |
- PlatformThread::Sleep(kTimeout); |
- } |
- return false; |
-} |
- |
-bool EvictFileFromSystemCache(const FilePath& file) { |
- // Request exclusive access to the file and overwrite it with no buffering. |
- base::win::ScopedHandle file_handle( |
- CreateFile(file.value().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, |
- OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL)); |
- if (!file_handle.IsValid()) |
- return false; |
- |
- // Get some attributes to restore later. |
- BY_HANDLE_FILE_INFORMATION bhi = {0}; |
- CHECK(::GetFileInformationByHandle(file_handle.Get(), &bhi)); |
- |
- // Execute in chunks. It could be optimized. We want to do few of these since |
- // these operations will be slow without the cache. |
- |
- // Allocate a buffer for the reads and the writes. |
- char* buffer = reinterpret_cast<char*>(VirtualAlloc(NULL, |
- kOneMB, |
- MEM_COMMIT | MEM_RESERVE, |
- PAGE_READWRITE)); |
- |
- // If the file size isn't a multiple of kOneMB, we'll need special |
- // processing. |
- bool file_is_aligned = true; |
- int total_bytes = 0; |
- DWORD bytes_read, bytes_written; |
- for (;;) { |
- bytes_read = 0; |
- ::ReadFile(file_handle.Get(), buffer, kOneMB, &bytes_read, NULL); |
- if (bytes_read == 0) |
- break; |
- |
- if (bytes_read < kOneMB) { |
- // Zero out the remaining part of the buffer. |
- // WriteFile will fail if we provide a buffer size that isn't a |
- // sector multiple, so we'll have to write the entire buffer with |
- // padded zeros and then use SetEndOfFile to truncate the file. |
- ZeroMemory(buffer + bytes_read, kOneMB - bytes_read); |
- file_is_aligned = false; |
- } |
- |
- // Move back to the position we just read from. |
- // Note that SetFilePointer will also fail if total_bytes isn't sector |
- // aligned, but that shouldn't happen here. |
- DCHECK_EQ(total_bytes % kOneMB, 0); |
- SetFilePointer(file_handle.Get(), total_bytes, NULL, FILE_BEGIN); |
- if (!::WriteFile(file_handle.Get(), buffer, kOneMB, &bytes_written, NULL) || |
- bytes_written != kOneMB) { |
- BOOL freed = VirtualFree(buffer, 0, MEM_RELEASE); |
- DCHECK(freed); |
- NOTREACHED(); |
- return false; |
- } |
- |
- total_bytes += bytes_read; |
- |
- // If this is false, then we just processed the last portion of the file. |
- if (!file_is_aligned) |
- break; |
- } |
- |
- BOOL freed = VirtualFree(buffer, 0, MEM_RELEASE); |
- DCHECK(freed); |
- |
- if (!file_is_aligned) { |
- // The size of the file isn't a multiple of 1 MB, so we'll have |
- // to open the file again, this time without the FILE_FLAG_NO_BUFFERING |
- // flag and use SetEndOfFile to mark EOF. |
- file_handle.Set(NULL); |
- file_handle.Set(CreateFile(file.value().c_str(), GENERIC_WRITE, 0, NULL, |
- OPEN_EXISTING, 0, NULL)); |
- CHECK_NE(SetFilePointer(file_handle.Get(), total_bytes, NULL, FILE_BEGIN), |
- INVALID_SET_FILE_POINTER); |
- CHECK(::SetEndOfFile(file_handle.Get())); |
- } |
- |
- // Restore the file attributes. |
- CHECK(::SetFileTime(file_handle.Get(), &bhi.ftCreationTime, |
- &bhi.ftLastAccessTime, &bhi.ftLastWriteTime)); |
- |
- return true; |
-} |
- |
-// Checks if the volume supports Alternate Data Streams. This is required for |
-// the Zone Identifier implementation. |
-bool VolumeSupportsADS(const FilePath& path) { |
- wchar_t drive[MAX_PATH] = {0}; |
- wcscpy_s(drive, MAX_PATH, path.value().c_str()); |
- |
- if (!PathStripToRootW(drive)) |
- return false; |
- |
- DWORD fs_flags = 0; |
- if (!GetVolumeInformationW(drive, NULL, 0, 0, NULL, &fs_flags, NULL, 0)) |
- return false; |
- |
- if (fs_flags & FILE_NAMED_STREAMS) |
- return true; |
- |
- return false; |
-} |
- |
-// Return whether the ZoneIdentifier is correctly set to "Internet" (3) |
-// Only returns a valid result when called from same process as the |
-// one that (was supposed to have) set the zone identifier. |
-bool HasInternetZoneIdentifier(const FilePath& full_path) { |
- FilePath zone_path(full_path.value() + L":Zone.Identifier"); |
- std::string zone_path_contents; |
- if (!ReadFileToString(zone_path, &zone_path_contents)) |
- return false; |
- |
- std::vector<std::string> lines; |
- // This call also trims whitespaces, including carriage-returns (\r). |
- SplitString(zone_path_contents, '\n', &lines); |
- |
- switch (lines.size()) { |
- case 3: |
- // optional empty line at end of file: |
- if (!lines[2].empty()) |
- return false; |
- // fall through: |
- case 2: |
- return lines[0] == "[ZoneTransfer]" && lines[1] == "ZoneId=3"; |
- default: |
- return false; |
- } |
-} |
- |
-bool MakeFileUnreadable(const FilePath& path) { |
- return DenyFilePermission(path, GENERIC_READ); |
-} |
- |
-bool MakeFileUnwritable(const FilePath& path) { |
- return DenyFilePermission(path, GENERIC_WRITE); |
-} |
- |
-FilePermissionRestorer::FilePermissionRestorer(const FilePath& path) |
- : path_(path), info_(NULL), length_(0) { |
- info_ = GetPermissionInfo(path_, &length_); |
- DCHECK(info_ != NULL); |
- DCHECK_NE(0u, length_); |
-} |
- |
-FilePermissionRestorer::~FilePermissionRestorer() { |
- if (!RestorePermissionInfo(path_, info_, length_)) |
- NOTREACHED(); |
-} |
- |
-} // namespace base |