Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shellapi.h> | 8 #include <shellapi.h> |
| 9 #include <shlobj.h> | 9 #include <shlobj.h> |
| 10 #include <time.h> | 10 #include <time.h> |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 // Didn't write all the bytes. | 528 // Didn't write all the bytes. |
| 529 LOG(WARNING) << "wrote" << written << " bytes to " << filename << | 529 LOG(WARNING) << "wrote" << written << " bytes to " << filename << |
| 530 " expected " << size; | 530 " expected " << size; |
| 531 } | 531 } |
| 532 return -1; | 532 return -1; |
| 533 } | 533 } |
| 534 | 534 |
| 535 bool RenameFileAndResetSecurityDescriptor( | 535 bool RenameFileAndResetSecurityDescriptor( |
| 536 const std::wstring& source_file_path, | 536 const std::wstring& source_file_path, |
| 537 const std::wstring& target_file_path) { | 537 const std::wstring& target_file_path) { |
| 538 // The MoveFile API does not reset the security descriptor on the target | 538 // The parameters to SHFileOperation must be terminated with 2 NULL chars. |
| 539 // file. To ensure that the target file gets the correct security descriptor | 539 std::wstring source = source_file_path; |
| 540 // we create the target file initially in the target path, read its security | 540 std::wstring target = target_file_path; |
| 541 // descriptor and stamp this descriptor on the target file after the MoveFile | |
| 542 // API completes. | |
| 543 ScopedHandle temp_file_handle_for_security_desc( | |
| 544 CreateFileW(target_file_path.c_str(), GENERIC_READ | GENERIC_WRITE, | |
| 545 FILE_SHARE_READ, NULL, OPEN_ALWAYS, | |
| 546 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, | |
| 547 NULL)); | |
| 548 if (!temp_file_handle_for_security_desc.IsValid()) | |
| 549 return false; | |
| 550 | 541 |
| 551 // Check how much we should allocate for the security descriptor. | 542 source.append(1, L'\0'); |
| 552 unsigned long security_descriptor_size_in_bytes = 0; | 543 target.append(1, L'\0'); |
| 553 GetFileSecurity(target_file_path.c_str(), DACL_SECURITY_INFORMATION, NULL, 0, | |
| 554 &security_descriptor_size_in_bytes); | |
| 555 if (ERROR_INSUFFICIENT_BUFFER != GetLastError() || | |
| 556 security_descriptor_size_in_bytes == 0) | |
| 557 return false; | |
| 558 | 544 |
| 559 scoped_array<char> security_descriptor( | 545 SHFILEOPSTRUCT move_info = {0}; |
| 560 new char[security_descriptor_size_in_bytes]); | 546 move_info.wFunc = FO_MOVE; |
| 547 move_info.pFrom = source.c_str(); | |
| 548 move_info.pTo = target.c_str(); | |
| 549 move_info.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | | |
| 550 FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS; | |
|
rvargas (doing something else)
2008/10/24 18:00:23
nit: don't we want to use FOF_RENAMEONCOLLISION?
| |
| 561 | 551 |
| 562 if (!GetFileSecurity(target_file_path.c_str(), DACL_SECURITY_INFORMATION, | 552 if (0 != SHFileOperation(&move_info)) |
| 563 security_descriptor.get(), | 553 return false; |
|
amit
2008/10/24 17:45:34
Would be nice to log an error if this fails.
| |
| 564 security_descriptor_size_in_bytes, | 554 |
| 565 &security_descriptor_size_in_bytes)) { | 555 return true; |
| 566 return false; | |
| 567 } | |
| 568 | |
| 569 temp_file_handle_for_security_desc.Set(INVALID_HANDLE_VALUE); | |
| 570 | |
| 571 if (!MoveFileEx(source_file_path.c_str(), target_file_path.c_str(), | |
| 572 MOVEFILE_COPY_ALLOWED)) { | |
| 573 return false; | |
| 574 } | |
| 575 | |
| 576 return !!SetFileSecurity(target_file_path.c_str(), | |
| 577 DACL_SECURITY_INFORMATION, | |
| 578 security_descriptor.get()); | |
| 579 } | 556 } |
| 580 | 557 |
| 581 // Gets the current working directory for the process. | 558 // Gets the current working directory for the process. |
| 582 bool GetCurrentDirectory(std::wstring* dir) { | 559 bool GetCurrentDirectory(std::wstring* dir) { |
| 583 wchar_t system_buffer[MAX_PATH]; | 560 wchar_t system_buffer[MAX_PATH]; |
| 584 system_buffer[0] = 0; | 561 system_buffer[0] = 0; |
| 585 DWORD len = ::GetCurrentDirectory(MAX_PATH, system_buffer); | 562 DWORD len = ::GetCurrentDirectory(MAX_PATH, system_buffer); |
| 586 if (len == 0 || len > MAX_PATH) | 563 if (len == 0 || len > MAX_PATH) |
| 587 return false; | 564 return false; |
| 588 *dir = system_buffer; | 565 *dir = system_buffer; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 // it to pending_paths_ so we scan it after we finish scanning this | 660 // it to pending_paths_ so we scan it after we finish scanning this |
| 684 // directory. | 661 // directory. |
| 685 pending_paths_.push(cur_file); | 662 pending_paths_.push(cur_file); |
| 686 } | 663 } |
| 687 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); | 664 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); |
| 688 } | 665 } |
| 689 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); | 666 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); |
| 690 } | 667 } |
| 691 | 668 |
| 692 } // namespace file_util | 669 } // namespace file_util |
| OLD | NEW |