OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-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 <vector> | |
6 #include <windows.h> | |
7 | |
8 #include "chrome/test/test_file_util.h" | |
9 | |
10 #include "base/file_util.h" | |
11 #include "chrome/common/win_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 |