file_win32 opens for read-only in shared mode:

fix #786

Without this change the second opening of an
already opened file fails with:

  "The process cannot access the file because it
  is being used by another process"
This commit is contained in:
Nils Gladitz
2017-09-20 23:39:56 +02:00
committed by Vinnie Falco
parent 5a7b8b23db
commit c81558e38b
2 changed files with 43 additions and 37 deletions

View File

@@ -1,5 +1,7 @@
Version 118: Version 118:
* file_win32 opens for read-only in shared mode
HTTP: HTTP:
* Fix writing header into std::ostream * Fix writing header into std::ostream

View File

@@ -120,9 +120,10 @@ open(char const* path, file_mode mode, error_code& ec)
boost::detail::winapi::CloseHandle(h_); boost::detail::winapi::CloseHandle(h_);
h_ = boost::detail::winapi::INVALID_HANDLE_VALUE_; h_ = boost::detail::winapi::INVALID_HANDLE_VALUE_;
} }
boost::detail::winapi::DWORD_ dw1 = 0; boost::detail::winapi::DWORD_ share_mode = 0;
boost::detail::winapi::DWORD_ dw2 = 0; boost::detail::winapi::DWORD_ desired_access = 0;
boost::detail::winapi::DWORD_ dw3 = 0; boost::detail::winapi::DWORD_ creation_disposition = 0;
boost::detail::winapi::DWORD_ flags_and_attributes = 0;
/* /*
| When the file... | When the file...
This argument: | Exists Does not exist This argument: | Exists Does not exist
@@ -137,66 +138,69 @@ open(char const* path, file_mode mode, error_code& ec)
{ {
default: default:
case file_mode::read: case file_mode::read:
dw1 = boost::detail::winapi::GENERIC_READ_; desired_access = boost::detail::winapi::GENERIC_READ_;
dw2 = boost::detail::winapi::OPEN_EXISTING_; share_mode = boost::detail::winapi::FILE_SHARE_READ_;
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS creation_disposition = boost::detail::winapi::OPEN_EXISTING_;
flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
break; break;
case file_mode::scan: case file_mode::scan:
dw1 = boost::detail::winapi::GENERIC_READ_; desired_access = boost::detail::winapi::GENERIC_READ_;
dw2 = boost::detail::winapi::OPEN_EXISTING_; share_mode = boost::detail::winapi::FILE_SHARE_READ_;
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN creation_disposition = boost::detail::winapi::OPEN_EXISTING_;
flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
break; break;
case file_mode::write: case file_mode::write:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::CREATE_ALWAYS_; creation_disposition = boost::detail::winapi::CREATE_ALWAYS_;
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
break; break;
case file_mode::write_new: case file_mode::write_new:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::CREATE_NEW_; creation_disposition = boost::detail::winapi::CREATE_NEW_;
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
break; break;
case file_mode::write_existing: case file_mode::write_existing:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::OPEN_EXISTING_; creation_disposition = boost::detail::winapi::OPEN_EXISTING_;
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
break; break;
case file_mode::append: case file_mode::append:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::CREATE_ALWAYS_;
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN creation_disposition = boost::detail::winapi::CREATE_ALWAYS_;
flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
break; break;
case file_mode::append_new: case file_mode::append_new:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::CREATE_NEW_; creation_disposition = boost::detail::winapi::CREATE_NEW_;
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
break; break;
case file_mode::append_existing: case file_mode::append_existing:
dw1 = boost::detail::winapi::GENERIC_READ_ | desired_access = boost::detail::winapi::GENERIC_READ_ |
boost::detail::winapi::GENERIC_WRITE_; boost::detail::winapi::GENERIC_WRITE_;
dw2 = boost::detail::winapi::OPEN_EXISTING_; creation_disposition = boost::detail::winapi::OPEN_EXISTING_;
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
break; break;
} }
h_ = ::CreateFileA( h_ = ::CreateFileA(
path, path,
dw1, desired_access,
0, share_mode,
NULL, NULL,
dw2, creation_disposition,
dw3, flags_and_attributes,
NULL); NULL);
if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_) if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_)
ec.assign(boost::detail::winapi::GetLastError(), ec.assign(boost::detail::winapi::GetLastError(),