Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4348)

Unified Diff: chrome/browser/extensions/api/messaging/native_message_process_host_win.cc

Issue 10918255: The Windows portion of Native Messagaing (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/messaging/native_message_process_host_win.cc
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host_win.cc b/chrome/browser/extensions/api/messaging/native_message_process_host_win.cc
index a9a6819f67ba595aaadfcb8c101f7814d29761f3..e89ccc1624426d82882af664c3dd8722e7973f95 100644
--- a/chrome/browser/extensions/api/messaging/native_message_process_host_win.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host_win.cc
@@ -12,31 +12,138 @@
#include "base/process_util.h"
#include "content/public/browser/browser_thread.h"
+namespace {
+
+void AddToOverlappedOffset(OVERLAPPED* overlapped, uint32 to_add) {
+ uint64 full_offset =
+ static_cast<uint64>(overlapped->OffsetHigh) << 32 | overlapped->Offset;
+ full_offset += to_add;
+ overlapped->Offset = full_offset & 0x00000000ffffffff;
+ overlapped->OffsetHigh = full_offset >> 32;
+}
+
+} // namespace
+
namespace extensions {
+void NativeMessageProcessHost::ReadNowForTesting() {
+}
+
void NativeMessageProcessHost::OnIOCompleted(
MessageLoopForIO::IOContext* context,
DWORD bytes_transfered,
DWORD error) {
- NOTREACHED();
+ if (error != 0) {
+ if (native_process_handle_ != base::kNullProcessHandle &&
+ base::GetTerminationStatus(native_process_handle_, NULL) !=
+ base::TERMINATION_STATUS_STILL_RUNNING) {
+ // Notify the message service that the channel should close.
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&Client::CloseChannel, weak_client_ui_,
+ destination_port_, true));
+ }
+ return;
+ }
+
+ if (context == read_context_.get()) {
+ switch (read_state) {
+ case READ_STATE_INVALID:
+ // This could be the case on destruction.
+ return;
+ case READ_STATE_WAITING_FOR_META: {
+ AddToOverlappedOffset(&read_context_->overlapped, bytes_transfered);
+
+ MessageType type;
+ uint32 message_length = 0;
+ if (!VerifyMessageMetaData(pending_message_meta_data_, &type,
+ &message_length)) {
+ return;
+ }
+ pending_message_.resize(message_length, '\0');
+ // Try to read the full message.
+ read_state = READ_STATE_WAITING_FOR_MESSAGE;
+ ::ReadFile(read_file_, &(pending_message_)[0], message_length, NULL,
+ &read_context_->overlapped);
+ return;
+ }
+ case READ_STATE_WAITING_FOR_MESSAGE:
+ AddToOverlappedOffset(&read_context_->overlapped, bytes_transfered);
+
+ // Verify that the entire message was read.
+ if (bytes_transfered != pending_message_.size()) {
+ LOG(ERROR) << "Could not read entire message.";
+ return;
+ }
+ // Send the current message
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_,
+ destination_port_, pending_message_));
+ // Do not try to read another message if this is only a
+ // sendNativeMessage().
+ if (is_send_message_) {
+ read_state = READ_STATE_INVALID;
+ } else {
+ // Start the read for the next message.
+ read_state = READ_STATE_WAITING_FOR_META;
+ ::ReadFile(read_file_, &pending_message_meta_data_, 8, NULL,
+ &read_context_->overlapped);
+ }
+ return;
+ default:
+ NOTREACHED();
+ return;
+ }
+ } else {
+ DCHECK(context == write_context_.get());
+ }
}
void NativeMessageProcessHost::InitIO() {
- NOTREACHED();
+ read_context_.reset(new MessageLoopForIO::IOContext());
+ write_context_.reset(new MessageLoopForIO::IOContext());
+
+ memset(&read_context_->overlapped, 0, sizeof(read_context_->overlapped));
+ memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped));
+
+ read_context_->handler = this;
+ write_context_->handler = this;
+
+ MessageLoopForIO::current()->RegisterIOHandler(read_file_, this);
+
+ // Make a request for the type and length of the first message.
+ read_state = READ_STATE_WAITING_FOR_META;
+ ::ReadFile(read_file_, &pending_message_meta_data_, 8, NULL,
+ &read_context_->overlapped);
+}
+
+void NativeMessageProcessHost::StopIO() {
+ read_state = READ_STATE_INVALID;
+
+ MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this);
+
+ read_context_->handler = NULL;
+ write_context_->handler = NULL;
+
+ read_context_.reset();
+ write_context_.reset();
+
+ // Because of the asynchronous IO, ::CloseHandle() may return a non-zero
+ // status. This is expected, but will trigger a CHECK in
+ // ScopedHandle::Close(). To circumvent this, we will take ownership of the
+ // raw handle and close it manually.
+ ::CloseHandle(scoped_read_file_.Take());
+ ::CloseHandle(scoped_write_file_.Take());
}
bool NativeMessageProcessHost::WriteData(FileHandle file,
const char* data,
size_t bytes_to_write) {
- NOTREACHED();
- return false;
-}
+ DWORD bytes_written = 0;
+ ::SetLastError(0);
+ BOOL result = ::WriteFile(file, data, bytes_to_write, &bytes_written,
+ &write_context_->overlapped);
-bool NativeMessageProcessHost::ReadData(FileHandle file,
- char* data,
- size_t bytes_to_read) {
- NOTREACHED();
- return false;
+ return result || ::GetLastError() == ERROR_IO_PENDING;
}
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698