asio::error_code win_iocp_file_service::open()

in demo_example/asio/asio/detail/impl/win_iocp_file_service.ipp [51:118]


asio::error_code win_iocp_file_service::open(
    win_iocp_file_service::implementation_type& impl,
    const char* path, file_base::flags open_flags,
    asio::error_code& ec)
{
  if (is_open(impl))
  {
    ec = asio::error::already_open;
    return ec;
  }

  DWORD access = 0;
  if ((open_flags & file_base::read_only) != 0)
    access = GENERIC_READ;
  else if ((open_flags & file_base::write_only) != 0)
    access = GENERIC_WRITE;
  else if ((open_flags & file_base::read_write) != 0)
    access = GENERIC_READ | GENERIC_WRITE;

  DWORD disposition = 0;
  if ((open_flags & file_base::create) != 0)
  {
    if ((open_flags & file_base::exclusive) != 0)
      disposition = CREATE_NEW;
    else
      disposition = OPEN_ALWAYS;
  }
  else
  {
    if ((open_flags & file_base::truncate) != 0)
      disposition = TRUNCATE_EXISTING;
    else
      disposition = OPEN_EXISTING;
  }

  DWORD flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
  if (impl.is_stream_)
    flags |= FILE_FLAG_SEQUENTIAL_SCAN;
  else
    flags |= FILE_FLAG_RANDOM_ACCESS;

  HANDLE handle = ::CreateFileA(path, access, 0, 0, disposition, flags, 0);
  if (handle != INVALID_HANDLE_VALUE)
  {
    if (disposition == OPEN_ALWAYS && (open_flags & file_base::truncate) != 0)
    {
      if (!::SetEndOfFile(handle))
      {
        DWORD last_error = ::GetLastError();
        ::CloseHandle(handle);
        ec.assign(last_error, asio::error::get_system_category());
        return ec;
      }
    }

    handle_service_.assign(impl, handle, ec);
    if (ec)
      ::CloseHandle(handle);
    impl.offset_ = 0;
    return ec;
  }
  else
  {
    DWORD last_error = ::GetLastError();
    ec.assign(last_error, asio::error::get_system_category());
    return ec;
  }
}