OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/test_file_util.h" |
| 6 |
| 7 #include <windows.h> |
| 8 |
| 9 #include <vector> |
| 10 |
| 11 #include "base/file_util.h" |
| 12 |
| 13 namespace file_util { |
| 14 |
| 15 bool EvictFileFromSystemCache(const wchar_t* file) { |
| 16 // Request exclusive access to the file and overwrite it with no buffering. |
| 17 win_util::ScopedHandle hfile( |
| 18 CreateFile(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, |
| 19 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, |
| 20 NULL)); |
| 21 if (!hfile) |
| 22 return false; |
| 23 |
| 24 // Execute in chunks. It could be optimized. We want to do few of these since |
| 25 // these opterations will be slow without the cache. |
| 26 char buffer[4096]; |
| 27 int total_bytes = 0; |
| 28 DWORD bytes_read; |
| 29 for (;;) { |
| 30 bytes_read = 0; |
| 31 ReadFile(hfile, buffer, sizeof(buffer), &bytes_read, NULL); |
| 32 if (bytes_read == 0) |
| 33 break; |
| 34 |
| 35 SetFilePointer(hfile, total_bytes, 0, FILE_BEGIN); |
| 36 if (!WriteFile(hfile, buffer, bytes_read, &bytes_read, NULL)) |
| 37 return false; |
| 38 total_bytes += bytes_read; |
| 39 } |
| 40 return true; |
| 41 } |
| 42 |
| 43 // Like CopyFileNoCache but recursively copies all files and subdirectories |
| 44 // in the given input directory to the output directory. |
| 45 bool CopyRecursiveDirNoCache(const std::wstring& source_dir, |
| 46 const std::wstring& dest_dir) { |
| 47 // Try to create the directory if it doesn't already exist. |
| 48 if (!CreateDirectory(dest_dir)) { |
| 49 if (GetLastError() != ERROR_ALREADY_EXISTS) |
| 50 return false; |
| 51 } |
| 52 |
| 53 std::vector<std::wstring> files_copied; |
| 54 |
| 55 std::wstring src(source_dir); |
| 56 file_util::AppendToPath(&src, L"*"); |
| 57 |
| 58 WIN32_FIND_DATA fd; |
| 59 HANDLE fh = FindFirstFile(src.c_str(), &fd); |
| 60 if (fh == INVALID_HANDLE_VALUE) |
| 61 return false; |
| 62 |
| 63 do { |
| 64 std::wstring cur_file(fd.cFileName); |
| 65 if (cur_file == L"." || cur_file == L"..") |
| 66 continue; // Skip these special entries. |
| 67 |
| 68 std::wstring cur_source_path(source_dir); |
| 69 file_util::AppendToPath(&cur_source_path, cur_file); |
| 70 |
| 71 std::wstring cur_dest_path(dest_dir); |
| 72 file_util::AppendToPath(&cur_dest_path, cur_file); |
| 73 |
| 74 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
| 75 // Recursively copy a subdirectory. We stripped "." and ".." already. |
| 76 if (!CopyRecursiveDirNoCache(cur_source_path, cur_dest_path)) { |
| 77 FindClose(fh); |
| 78 return false; |
| 79 } |
| 80 } else { |
| 81 // Copy the file. |
| 82 if (!::CopyFile(cur_source_path.c_str(), cur_dest_path.c_str(), false)) { |
| 83 FindClose(fh); |
| 84 return false; |
| 85 } |
| 86 |
| 87 // We don't check for errors from this function, often, we are copying |
| 88 // files that are in the repository, and they will have read-only set. |
| 89 // This will prevent us from evicting from the cache, but these don't |
| 90 // matter anyway. |
| 91 EvictFileFromSystemCache(cur_dest_path.c_str()); |
| 92 } |
| 93 } while (FindNextFile(fh, &fd)); |
| 94 |
| 95 FindClose(fh); |
| 96 return true; |
| 97 } |
| 98 |
| 99 } // namespace file_util |
| 100 |
OLD | NEW |