| OLD | NEW |
| (Empty) |
| 1 // Copyright 2003-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // File handling routines | |
| 16 // | |
| 17 // encryption is not currently active | |
| 18 // | |
| 19 #ifndef OMAHA_BASE_FILE_H_ | |
| 20 #define OMAHA_BASE_FILE_H_ | |
| 21 | |
| 22 #include <windows.h> | |
| 23 #include <vector> | |
| 24 #include "base/basictypes.h" | |
| 25 #include "omaha/base/scoped_any.h" | |
| 26 #include "omaha/base/store_watcher.h" | |
| 27 | |
| 28 namespace omaha { | |
| 29 | |
| 30 class File { | |
| 31 public: | |
| 32 | |
| 33 File(); | |
| 34 ~File(); | |
| 35 | |
| 36 HRESULT Open(const TCHAR* file_name, bool write, bool async); | |
| 37 HRESULT OpenShareMode(const TCHAR* file_name, | |
| 38 bool write, | |
| 39 bool async, | |
| 40 DWORD share_mode); | |
| 41 | |
| 42 HRESULT Close(); | |
| 43 | |
| 44 static bool Exists(const TCHAR* file_name); | |
| 45 static bool IsDirectory(const TCHAR *file_name); | |
| 46 static HRESULT GetWildcards(const TCHAR* dir, const TCHAR* wildcard, | |
| 47 std::vector<CString>* matching_paths); | |
| 48 // returns S_OK on successful removal or if not existing | |
| 49 static HRESULT Remove(const TCHAR* file_name); | |
| 50 // CopyWildcards doesn't work recursively | |
| 51 static HRESULT CopyWildcards(const TCHAR* from_dir, const TCHAR* to_dir, | |
| 52 const TCHAR* wildcard, | |
| 53 bool replace_existing_files); | |
| 54 static HRESULT CopyTree(const TCHAR* from_dir, const TCHAR* to_dir, | |
| 55 bool replace_existing_files); | |
| 56 // to_dir need not exist | |
| 57 static HRESULT Copy(const TCHAR* from, const TCHAR* to, | |
| 58 bool replace_existing_file); | |
| 59 static HRESULT Move(const TCHAR* from, const TCHAR* to, | |
| 60 bool replace_existing_file); | |
| 61 // DeleteAfterReboot tries to delete the files by either moving them to | |
| 62 // the TEMP directory and deleting them on reboot, or if that fails, by | |
| 63 // trying to delete them in-place on reboot | |
| 64 static HRESULT DeleteAfterReboot(const TCHAR* from); | |
| 65 static HRESULT MoveAfterReboot(const TCHAR* from, const TCHAR* to); | |
| 66 // Remove any moves pending a reboot from the PendingFileRenameOperations | |
| 67 // in the registry. | |
| 68 // The prefix_match boolean controls whether we do an exact match on | |
| 69 // in_directory, or remove all entries with the in_directory prefix. | |
| 70 static HRESULT RemoveFromMovesPendingReboot(const TCHAR* in_directory, | |
| 71 bool prefix_match); | |
| 72 // Did the user try to uninstall a previous install of the same version, | |
| 73 // and we couldn't clean up without a reboot? | |
| 74 // We check if there are any moves pending a reboot from the | |
| 75 // PendingFileRenameOperations in the registry. | |
| 76 // The prefix_match boolean controls whether we do an exact match on | |
| 77 // in_directory, or check all entries with the in_directory prefix. | |
| 78 static bool AreMovesPendingReboot(const TCHAR* in_directory, | |
| 79 bool prefix_match); | |
| 80 | |
| 81 // The GetFileTime function retrieves the date and time that a file was | |
| 82 // created, last accessed, and last modified. The parameters 'created', | |
| 83 // 'accessed', 'modified' can be null if the caller does not require that | |
| 84 // information. All times are utc | |
| 85 // (http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;158588) | |
| 86 // To compare FILETIME values, use CompareFileTime API. | |
| 87 static HRESULT GetFileTime(const TCHAR* file_name, FILETIME* created, | |
| 88 FILETIME* accessed, FILETIME* modified); | |
| 89 | |
| 90 // Sets the file time | |
| 91 static HRESULT SetFileTime(const TCHAR* file_name, | |
| 92 const FILETIME* created, | |
| 93 const FILETIME* accessed, | |
| 94 const FILETIME* modified); | |
| 95 | |
| 96 // sync flushes any pending writes to disk | |
| 97 HRESULT Sync(); | |
| 98 // static HRESULT SyncAllFiles(); | |
| 99 | |
| 100 HRESULT SeekToBegin(); | |
| 101 HRESULT SeekFromBegin(uint32 n); | |
| 102 | |
| 103 HRESULT ReadFromStartOfFile(const uint32 max_len, byte *buf, | |
| 104 uint32 *bytes_read); | |
| 105 HRESULT ReadLineAnsi(uint32 max_len, char *line, uint32 *len); | |
| 106 | |
| 107 // read len bytes, reading 0 bytes is invalid | |
| 108 HRESULT Read(const uint32 len, byte *buf, uint32 *bytes_read); | |
| 109 // read len bytes starting at position n, reading 0 bytes is invalid | |
| 110 HRESULT ReadAt(const uint32 offset, byte *buf, const uint32 len, | |
| 111 const uint32 async_id, uint32 *bytes_read); | |
| 112 | |
| 113 // write len bytes, writing 0 bytes is invalid | |
| 114 HRESULT Write(const byte *buf, const uint32 len, uint32 *bytes_written); | |
| 115 // write len bytes, writing 0 bytes is invalid | |
| 116 HRESULT WriteAt(const uint32 offset, const byte *buf, const uint32 len, | |
| 117 const uint32 async_id, uint32 *bytes_written); | |
| 118 | |
| 119 // write buffer n times | |
| 120 HRESULT WriteN(const byte *buf, const uint32 len, const uint32 n, | |
| 121 uint32 *bytes_written); | |
| 122 | |
| 123 // zeros section of file | |
| 124 HRESULT ClearAt(const uint32 offset, const uint32 len, | |
| 125 uint32 *bytes_written); | |
| 126 | |
| 127 // set length of file | |
| 128 // if new length is greater than current length, new data is undefined | |
| 129 // unless zero_data == true in which case the new data is zeroed. | |
| 130 HRESULT SetLength(const uint32 n, bool zero_data); | |
| 131 HRESULT ExtendInBlocks(const uint32 block_size, uint32 size_needed, | |
| 132 uint32 *new_size, bool clear_new_space); | |
| 133 HRESULT GetLength(uint32 *len); | |
| 134 | |
| 135 // Sets the last write time to the current time | |
| 136 HRESULT Touch(); | |
| 137 | |
| 138 // all the data storage classes contain these functions | |
| 139 // we implemenent them here for consistency | |
| 140 // e.g., so we can do object->GetSizeOnDisk independent of the object type | |
| 141 HRESULT GetSizeOnDisk(uint64 *size_on_disk); | |
| 142 HRESULT GetReloadDiskSpaceNeeded(uint64 *bytes_needed); | |
| 143 HRESULT Reload(uint32 *number_errors); | |
| 144 HRESULT Verify(uint32 *number_errors); | |
| 145 HRESULT Dump(); | |
| 146 | |
| 147 // Gets the size of a file, without opening it [the regular GetFileSize | |
| 148 // requires a file handle, which conflicts if the file is already opened | |
| 149 // and locked] | |
| 150 static HRESULT GetFileSizeUnopen(const TCHAR * filename, | |
| 151 uint32 * out_size); | |
| 152 | |
| 153 // Optimized function that gets the last write time and size | |
| 154 static HRESULT GetLastWriteTimeAndSize(const TCHAR* file_path, | |
| 155 SYSTEMTIME* out_time, | |
| 156 unsigned int* out_size); | |
| 157 | |
| 158 // Returns true if the two files are binary-identical. | |
| 159 static bool AreFilesIdentical(const TCHAR* filename1, | |
| 160 const TCHAR* filename2); | |
| 161 | |
| 162 private: | |
| 163 // See if we have any moves pending a reboot. Return SUCCESS if we do | |
| 164 // not encounter errors (not finding a move is not an error). We need to | |
| 165 // also check the value of *found_ptr for whether we actually found a move. | |
| 166 // On return, *value_multisz_ptr is the value within | |
| 167 // "PendingFileRenameOperations", but with any moves for in_directory | |
| 168 // removed from it. | |
| 169 // The prefix_match boolean controls whether we do an exact match on | |
| 170 // in_directory, or remove all entries with the in_directory prefix. | |
| 171 // NOTE: If the only values found were our own keys, the whole | |
| 172 // PendingFileRenameOperations MULTISZ needs to be deleted. This is | |
| 173 // signified by a returned *value_size_chars_ptr of 0. | |
| 174 static HRESULT GetPendingRenamesValueMinusDir(const TCHAR* in_directory, | |
| 175 bool prefix_match, TCHAR** value_multisz_ptr, DWORD* value_size_chars_ptr, | |
| 176 bool* found_ptr); | |
| 177 | |
| 178 HANDLE handle_; | |
| 179 CString file_name_; | |
| 180 bool read_only_; | |
| 181 bool sync_write_done_; | |
| 182 uint32 pos_; | |
| 183 uint32 encryption_seed_; | |
| 184 uint32 sequence_id_; | |
| 185 enum EncryptionTypes encryption_; | |
| 186 | |
| 187 static const int kMaxFileSize = kint32max; | |
| 188 | |
| 189 DISALLOW_EVIL_CONSTRUCTORS(File); | |
| 190 }; | |
| 191 | |
| 192 // File lock | |
| 193 class FileLock { | |
| 194 public: | |
| 195 // Default constructor | |
| 196 FileLock(); | |
| 197 | |
| 198 // Destructor | |
| 199 ~FileLock(); | |
| 200 | |
| 201 // Lock a single file | |
| 202 HRESULT Lock(const TCHAR* file); | |
| 203 | |
| 204 // Lock multiple files (atomic) | |
| 205 HRESULT Lock(const std::vector<CString>& files); | |
| 206 | |
| 207 // Unlock all | |
| 208 HRESULT Unlock(); | |
| 209 | |
| 210 private: | |
| 211 std::vector<HANDLE> handles_; | |
| 212 | |
| 213 DISALLOW_EVIL_CONSTRUCTORS(FileLock); | |
| 214 }; | |
| 215 | |
| 216 | |
| 217 // Does the common things necessary for watching | |
| 218 // changes in a directory. If there are file change or other watchers, | |
| 219 // there could be a common interface for the three methods to decouple | |
| 220 // the code that is doing the watching from the code that owns the store. | |
| 221 class FileWatcher : public StoreWatcher { | |
| 222 public: | |
| 223 // path_name: the directory to watch | |
| 224 // watch_subtree: watch all subdirectory changes or | |
| 225 // only immediate child values | |
| 226 // notify_filter: See the documentation for FindFirstChangeNotification | |
| 227 FileWatcher(const TCHAR* path_name, bool watch_subtree, DWORD notify_filter); | |
| 228 | |
| 229 // Called to create/reset the event that gets signaled | |
| 230 // any time the store changes. Access the created | |
| 231 // event using change_event(). | |
| 232 virtual HRESULT EnsureEventSetup(); | |
| 233 | |
| 234 // Get the event that is signaled on store changes. | |
| 235 virtual HANDLE change_event() const; | |
| 236 | |
| 237 private: | |
| 238 scoped_hfind_change_notification change_event_; | |
| 239 CString path_name_; | |
| 240 bool watch_subtree_; | |
| 241 DWORD notify_filter_; | |
| 242 | |
| 243 DISALLOW_EVIL_CONSTRUCTORS(FileWatcher); | |
| 244 }; | |
| 245 | |
| 246 } // namespace omaha | |
| 247 | |
| 248 #endif // OMAHA_BASE_FILE_H_ | |
| 249 | |
| OLD | NEW |