1// Copyright (c) 2011 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 "net/disk_cache/cache_util.h" 6 7#include <windows.h> 8 9#include "base/file_util.h" 10#include "base/logging.h" 11#include "base/message_loop.h" 12#include "base/win/scoped_handle.h" 13 14namespace { 15 16// Deletes all the files on path that match search_name pattern. 17void DeleteFiles(const wchar_t* path, const wchar_t* search_name) { 18 std::wstring name(path); 19 file_util::AppendToPath(&name, search_name); 20 21 WIN32_FIND_DATA data; 22 HANDLE handle = FindFirstFile(name.c_str(), &data); 23 if (handle == INVALID_HANDLE_VALUE) 24 return; 25 26 std::wstring adjusted_path(path); 27 adjusted_path += L'\\'; 28 do { 29 if (data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY || 30 data.dwFileAttributes == FILE_ATTRIBUTE_REPARSE_POINT) 31 continue; 32 std::wstring current(adjusted_path); 33 current += data.cFileName; 34 DeleteFile(current.c_str()); 35 } while (FindNextFile(handle, &data)); 36 37 FindClose(handle); 38} 39 40} // namespace 41 42namespace disk_cache { 43 44bool MoveCache(const FilePath& from_path, const FilePath& to_path) { 45 // I don't want to use the shell version of move because if something goes 46 // wrong, that version will attempt to move file by file and fail at the end. 47 if (!MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), 0)) { 48 LOG(ERROR) << "Unable to move the cache: " << GetLastError(); 49 return false; 50 } 51 return true; 52} 53 54void DeleteCache(const FilePath& path, bool remove_folder) { 55 DeleteFiles(path.value().c_str(), L"*"); 56 if (remove_folder) 57 RemoveDirectory(path.value().c_str()); 58} 59 60bool DeleteCacheFile(const FilePath& name) { 61 // We do a simple delete, without ever falling back to SHFileOperation, as the 62 // version from base does. 63 if (!DeleteFile(name.value().c_str())) { 64 // There is an error, but we share delete access so let's see if there is a 65 // file to open. Note that this code assumes that we have a handle to the 66 // file at all times (even now), so nobody can have a handle that prevents 67 // us from opening the file again (unless it was deleted). 68 DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 69 DWORD access = SYNCHRONIZE; 70 base::win::ScopedHandle file(CreateFile( 71 name.value().c_str(), access, sharing, NULL, OPEN_EXISTING, 0, NULL)); 72 if (file.IsValid()) 73 return false; 74 75 // Most likely there is no file to open... and that's what we wanted. 76 } 77 return true; 78} 79 80} // namespace disk_cache 81