// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "mojo/public/cpp/system/message_pipe.h" #include "base/numerics/safe_math.h" namespace mojo { MojoResult WriteMessageRaw(MessagePipeHandle message_pipe, const void* bytes, size_t num_bytes, const MojoHandle* handles, size_t num_handles, MojoWriteMessageFlags flags) { ScopedMessageHandle message_handle; MojoResult rv = CreateMessage(&message_handle); DCHECK_EQ(MOJO_RESULT_OK, rv); MojoAppendMessageDataOptions append_options; append_options.struct_size = sizeof(append_options); append_options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE; void* buffer; uint32_t buffer_size; rv = MojoAppendMessageData(message_handle->value(), base::checked_cast(num_bytes), handles, base::checked_cast(num_handles), &append_options, &buffer, &buffer_size); if (rv != MOJO_RESULT_OK) return MOJO_RESULT_ABORTED; DCHECK(buffer); DCHECK_GE(buffer_size, base::checked_cast(num_bytes)); memcpy(buffer, bytes, num_bytes); MojoWriteMessageOptions write_options; write_options.struct_size = sizeof(write_options); write_options.flags = flags; return MojoWriteMessage(message_pipe.value(), message_handle.release().value(), &write_options); } MojoResult ReadMessageRaw(MessagePipeHandle message_pipe, std::vector* payload, std::vector* handles, MojoReadMessageFlags flags) { ScopedMessageHandle message_handle; MojoResult rv = ReadMessageNew(message_pipe, &message_handle, flags); if (rv != MOJO_RESULT_OK) return rv; rv = MojoSerializeMessage(message_handle->value(), nullptr); if (rv != MOJO_RESULT_OK && rv != MOJO_RESULT_FAILED_PRECONDITION) return MOJO_RESULT_ABORTED; void* buffer = nullptr; uint32_t num_bytes = 0; uint32_t num_handles = 0; rv = MojoGetMessageData(message_handle->value(), nullptr, &buffer, &num_bytes, nullptr, &num_handles); if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) { DCHECK(handles); handles->resize(num_handles); rv = MojoGetMessageData( message_handle->value(), nullptr, &buffer, &num_bytes, reinterpret_cast(handles->data()), &num_handles); } if (num_bytes) { DCHECK(buffer); uint8_t* payload_data = reinterpret_cast(buffer); payload->resize(num_bytes); std::copy(payload_data, payload_data + num_bytes, payload->begin()); } else if (payload) { payload->clear(); } if (handles && !num_handles) handles->clear(); if (rv != MOJO_RESULT_OK) return MOJO_RESULT_ABORTED; return MOJO_RESULT_OK; } } // namespace mojo