OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 FileStream *Win32Filesystem::OpenFile(const Pathname &filename, | 65 FileStream *Win32Filesystem::OpenFile(const Pathname &filename, |
66 const std::string &mode) { | 66 const std::string &mode) { |
67 FileStream *fs = new FileStream(); | 67 FileStream *fs = new FileStream(); |
68 if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { | 68 if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { |
69 delete fs; | 69 delete fs; |
70 fs = NULL; | 70 fs = NULL; |
71 } | 71 } |
72 return fs; | 72 return fs; |
73 } | 73 } |
74 | 74 |
75 bool Win32Filesystem::CreatePrivateFile(const Pathname &filename) { | |
76 // To make the file private to the current user, we first must construct a | |
77 // SECURITY_DESCRIPTOR specifying an ACL. This code is mostly based upon | |
78 // http://msdn.microsoft.com/en-us/library/ms707085%28VS.85%29.aspx | |
79 | |
80 // Get the current process token. | |
81 HANDLE process_token = INVALID_HANDLE_VALUE; | |
82 if (!::OpenProcessToken(::GetCurrentProcess(), | |
83 TOKEN_QUERY, | |
84 &process_token)) { | |
85 LOG_ERR(LS_ERROR) << "OpenProcessToken() failed"; | |
86 return false; | |
87 } | |
88 | |
89 // Get the size of its TOKEN_USER structure. Return value is not checked | |
90 // because we expect it to fail. | |
91 DWORD token_user_size = 0; | |
92 (void)::GetTokenInformation(process_token, | |
93 TokenUser, | |
94 NULL, | |
95 0, | |
96 &token_user_size); | |
97 | |
98 // Get the TOKEN_USER structure. | |
99 std::unique_ptr<char[]> token_user_bytes(new char[token_user_size]); | |
100 PTOKEN_USER token_user = reinterpret_cast<PTOKEN_USER>( | |
101 token_user_bytes.get()); | |
102 memset(token_user, 0, token_user_size); | |
103 BOOL success = ::GetTokenInformation(process_token, | |
104 TokenUser, | |
105 token_user, | |
106 token_user_size, | |
107 &token_user_size); | |
108 // We're now done with this. | |
109 ::CloseHandle(process_token); | |
110 if (!success) { | |
111 LOG_ERR(LS_ERROR) << "GetTokenInformation() failed"; | |
112 return false; | |
113 } | |
114 | |
115 if (!IsValidSid(token_user->User.Sid)) { | |
116 LOG_ERR(LS_ERROR) << "Current process has invalid user SID"; | |
117 return false; | |
118 } | |
119 | |
120 // Compute size needed for an ACL that allows access to just this user. | |
121 int acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + | |
122 GetLengthSid(token_user->User.Sid); | |
123 | |
124 // Allocate it. | |
125 std::unique_ptr<char[]> acl_bytes(new char[acl_size]); | |
126 PACL acl = reinterpret_cast<PACL>(acl_bytes.get()); | |
127 memset(acl, 0, acl_size); | |
128 if (!::InitializeAcl(acl, acl_size, ACL_REVISION)) { | |
129 LOG_ERR(LS_ERROR) << "InitializeAcl() failed"; | |
130 return false; | |
131 } | |
132 | |
133 // Allow access to only the current user. | |
134 if (!::AddAccessAllowedAce(acl, | |
135 ACL_REVISION, | |
136 GENERIC_READ | GENERIC_WRITE | STANDARD_RIGHTS_ALL, | |
137 token_user->User.Sid)) { | |
138 LOG_ERR(LS_ERROR) << "AddAccessAllowedAce() failed"; | |
139 return false; | |
140 } | |
141 | |
142 // Now make the security descriptor. | |
143 SECURITY_DESCRIPTOR security_descriptor; | |
144 if (!::InitializeSecurityDescriptor(&security_descriptor, | |
145 SECURITY_DESCRIPTOR_REVISION)) { | |
146 LOG_ERR(LS_ERROR) << "InitializeSecurityDescriptor() failed"; | |
147 return false; | |
148 } | |
149 | |
150 // Put the ACL in it. | |
151 if (!::SetSecurityDescriptorDacl(&security_descriptor, | |
152 TRUE, | |
153 acl, | |
154 FALSE)) { | |
155 LOG_ERR(LS_ERROR) << "SetSecurityDescriptorDacl() failed"; | |
156 return false; | |
157 } | |
158 | |
159 // Finally create the file. | |
160 SECURITY_ATTRIBUTES security_attributes; | |
161 security_attributes.nLength = sizeof(security_attributes); | |
162 security_attributes.lpSecurityDescriptor = &security_descriptor; | |
163 security_attributes.bInheritHandle = FALSE; | |
164 HANDLE handle = ::CreateFile( | |
165 ToUtf16(filename.pathname()).c_str(), | |
166 GENERIC_READ | GENERIC_WRITE, | |
167 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, | |
168 &security_attributes, | |
169 CREATE_NEW, | |
170 0, | |
171 NULL); | |
172 if (INVALID_HANDLE_VALUE == handle) { | |
173 LOG_ERR(LS_ERROR) << "CreateFile() failed"; | |
174 return false; | |
175 } | |
176 if (!::CloseHandle(handle)) { | |
177 LOG_ERR(LS_ERROR) << "CloseFile() failed"; | |
178 // Continue. | |
179 } | |
180 return true; | |
181 } | |
182 | |
183 bool Win32Filesystem::DeleteFile(const Pathname &filename) { | 75 bool Win32Filesystem::DeleteFile(const Pathname &filename) { |
184 LOG(LS_INFO) << "Deleting file " << filename.pathname(); | 76 LOG(LS_INFO) << "Deleting file " << filename.pathname(); |
185 if (!IsFile(filename)) { | 77 if (!IsFile(filename)) { |
186 ASSERT(IsFile(filename)); | 78 ASSERT(IsFile(filename)); |
187 return false; | 79 return false; |
188 } | 80 } |
189 return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0; | 81 return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0; |
190 } | 82 } |
191 | 83 |
192 bool Win32Filesystem::DeleteEmptyFolder(const Pathname &folder) { | 84 bool Win32Filesystem::DeleteEmptyFolder(const Pathname &folder) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 if (!IsFile(old_path)) { | 126 if (!IsFile(old_path)) { |
235 ASSERT(IsFile(old_path)); | 127 ASSERT(IsFile(old_path)); |
236 return false; | 128 return false; |
237 } | 129 } |
238 LOG(LS_INFO) << "Moving " << old_path.pathname() | 130 LOG(LS_INFO) << "Moving " << old_path.pathname() |
239 << " to " << new_path.pathname(); | 131 << " to " << new_path.pathname(); |
240 return ::MoveFile(ToUtf16(old_path.pathname()).c_str(), | 132 return ::MoveFile(ToUtf16(old_path.pathname()).c_str(), |
241 ToUtf16(new_path.pathname()).c_str()) != 0; | 133 ToUtf16(new_path.pathname()).c_str()) != 0; |
242 } | 134 } |
243 | 135 |
244 bool Win32Filesystem::MoveFolder(const Pathname &old_path, | |
245 const Pathname &new_path) { | |
246 if (!IsFolder(old_path)) { | |
247 ASSERT(IsFolder(old_path)); | |
248 return false; | |
249 } | |
250 LOG(LS_INFO) << "Moving " << old_path.pathname() | |
251 << " to " << new_path.pathname(); | |
252 if (::MoveFile(ToUtf16(old_path.pathname()).c_str(), | |
253 ToUtf16(new_path.pathname()).c_str()) == 0) { | |
254 if (::GetLastError() != ERROR_NOT_SAME_DEVICE) { | |
255 LOG_GLE(LS_ERROR) << "Failed to move file"; | |
256 return false; | |
257 } | |
258 if (!CopyFolder(old_path, new_path)) | |
259 return false; | |
260 if (!DeleteFolderAndContents(old_path)) | |
261 return false; | |
262 } | |
263 return true; | |
264 } | |
265 | |
266 bool Win32Filesystem::IsFolder(const Pathname &path) { | 136 bool Win32Filesystem::IsFolder(const Pathname &path) { |
267 WIN32_FILE_ATTRIBUTE_DATA data = {0}; | 137 WIN32_FILE_ATTRIBUTE_DATA data = {0}; |
268 if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), | 138 if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(), |
269 GetFileExInfoStandard, &data)) | 139 GetFileExInfoStandard, &data)) |
270 return false; | 140 return false; |
271 return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == | 141 return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == |
272 FILE_ATTRIBUTE_DIRECTORY; | 142 FILE_ATTRIBUTE_DIRECTORY; |
273 } | 143 } |
274 | 144 |
275 bool Win32Filesystem::IsFile(const Pathname &path) { | 145 bool Win32Filesystem::IsFile(const Pathname &path) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 (PULARGE_INTEGER)free_bytes, | 286 (PULARGE_INTEGER)free_bytes, |
417 (PULARGE_INTEGER)&total_number_of_bytes, | 287 (PULARGE_INTEGER)&total_number_of_bytes, |
418 (PULARGE_INTEGER)&total_number_of_free_bytes)) { | 288 (PULARGE_INTEGER)&total_number_of_free_bytes)) { |
419 return true; | 289 return true; |
420 } else { | 290 } else { |
421 LOG(LS_VERBOSE) << "GetDiskFreeSpaceEx returns error."; | 291 LOG(LS_VERBOSE) << "GetDiskFreeSpaceEx returns error."; |
422 return false; | 292 return false; |
423 } | 293 } |
424 } | 294 } |
425 | 295 |
426 Pathname Win32Filesystem::GetCurrentDirectory() { | |
427 Pathname cwd; | |
428 int path_len = 0; | |
429 std::unique_ptr<wchar_t[]> path; | |
430 do { | |
431 int needed = ::GetCurrentDirectory(path_len, path.get()); | |
432 if (needed == 0) { | |
433 // Error. | |
434 LOG_GLE(LS_ERROR) << "::GetCurrentDirectory() failed"; | |
435 return cwd; // returns empty pathname | |
436 } | |
437 if (needed <= path_len) { | |
438 // It wrote successfully. | |
439 break; | |
440 } | |
441 // Else need to re-alloc for "needed". | |
442 path.reset(new wchar_t[needed]); | |
443 path_len = needed; | |
444 } while (true); | |
445 cwd.SetFolder(ToUtf8(path.get())); | |
446 return cwd; | |
447 } | |
448 | |
449 // TODO: Consider overriding DeleteFolderAndContents for speed and potentially | |
450 // better OS integration (recycle bin?) | |
451 /* | |
452 std::wstring temp_path16 = ToUtf16(temp_path.pathname()); | |
453 temp_path16.append(1, '*'); | |
454 temp_path16.append(1, '\0'); | |
455 | |
456 SHFILEOPSTRUCT file_op = { 0 }; | |
457 file_op.wFunc = FO_DELETE; | |
458 file_op.pFrom = temp_path16.c_str(); | |
459 file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; | |
460 return (0 == SHFileOperation(&file_op)); | |
461 */ | |
462 | |
463 } // namespace rtc | 296 } // namespace rtc |
OLD | NEW |