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 |