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 |