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

Unified Diff: handler/win/registration_pipe_state.cc

Issue 1301853002: win: Crash handler server (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: oops Created 5 years, 3 months 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
« no previous file with comments | « handler/win/registration_pipe_state.h ('k') | handler/win/registration_pipe_state_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: handler/win/registration_pipe_state.cc
diff --git a/handler/win/registration_pipe_state.cc b/handler/win/registration_pipe_state.cc
deleted file mode 100644
index 08d265f1ce871ff444bc1dfab645788375f13af5..0000000000000000000000000000000000000000
--- a/handler/win/registration_pipe_state.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2015 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "handler/win/registration_pipe_state.h"
-
-#include <string.h>
-
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "util/stdlib/pointer_container.h"
-
-namespace crashpad {
-
-RegistrationPipeState::RegistrationPipeState(
- ScopedFileHANDLE pipe,
- RegistrationServer::Delegate* delegate)
- : request_(),
- response_(),
- completion_handler_(nullptr),
- overlapped_(),
- event_(),
- pipe_(pipe.Pass()),
- waiting_for_close_(false),
- delegate_(delegate),
- get_named_pipe_client_process_id_proc_(nullptr) {
- HMODULE kernel_dll = GetModuleHandle(L"kernel32.dll");
- if (kernel_dll) {
- get_named_pipe_client_process_id_proc_ =
- reinterpret_cast<decltype(GetNamedPipeClientProcessId)*>(
- GetProcAddress(kernel_dll, "GetNamedPipeClientProcessId"));
- }
-}
-
-RegistrationPipeState::~RegistrationPipeState() {
-}
-
-bool RegistrationPipeState::Initialize() {
- DCHECK(!event_.is_valid());
- DCHECK(pipe_.is_valid());
-
- event_.reset(CreateEvent(nullptr, true, false, nullptr));
-
- if (!event_.is_valid()) {
- PLOG(ERROR) << "CreateEvent";
- } else {
- overlapped_.hEvent = event_.get();
- if (IssueConnect())
- return true;
- }
-
- overlapped_.hEvent = nullptr;
- event_.reset();
- pipe_.reset();
- completion_handler_ = nullptr;
-
- return false;
-}
-
-void RegistrationPipeState::Stop() {
- DCHECK(pipe_.is_valid());
- if (!CancelIo(pipe_.get()))
- PLOG(FATAL) << "CancelIo";
-}
-
-bool RegistrationPipeState::OnCompletion() {
- AsyncCompletionHandler completion_handler = completion_handler_;
- completion_handler_ = nullptr;
-
- DWORD bytes_transferred = 0;
- BOOL success = GetOverlappedResult(pipe_.get(),
- &overlapped_,
- &bytes_transferred,
- false); // Do not wait.
- if (!success) {
- // ERROR_BROKEN_PIPE is expected when we are waiting for the client to close
- // the pipe (signaling that they are done reading the response).
- if (!waiting_for_close_ || GetLastError() != ERROR_BROKEN_PIPE)
- PLOG(ERROR) << "GetOverlappedResult";
- }
-
- bool still_running = false;
- if (!ResetEvent(event_.get())) {
- PLOG(ERROR) << "ResetEvent";
- } else if (!completion_handler) {
- NOTREACHED();
- still_running = ResetConnection();
- } else if (!success) {
- still_running = ResetConnection();
- } else {
- still_running = (this->*completion_handler)(bytes_transferred);
- }
-
- if (!still_running) {
- overlapped_.hEvent = nullptr;
- event_.reset();
- pipe_.reset();
- completion_handler_ = nullptr;
- } else {
- DCHECK(completion_handler_);
- }
-
- return still_running;
-}
-
-bool RegistrationPipeState::OnConnectComplete(DWORD /* bytes_transferred */) {
- return IssueRead();
-}
-
-bool RegistrationPipeState::OnReadComplete(DWORD bytes_transferred) {
- if (bytes_transferred != sizeof(request_)) {
- LOG(ERROR) << "Invalid message size: " << bytes_transferred;
- return ResetConnection();
- } else {
- return HandleRequest();
- }
-}
-
-bool RegistrationPipeState::OnWriteComplete(DWORD bytes_transferred) {
- if (bytes_transferred != sizeof(response_)) {
- LOG(ERROR) << "Incomplete write operation. Bytes written: "
- << bytes_transferred;
- }
-
- return IssueWaitForClientClose();
-}
-
-bool RegistrationPipeState::OnWaitForClientCloseComplete(
- DWORD bytes_transferred) {
- LOG(ERROR) << "Unexpected extra data (" << bytes_transferred
- << " bytes) received from client.";
- return ResetConnection();
-}
-
-bool RegistrationPipeState::IssueConnect() {
- if (ConnectNamedPipe(pipe_.get(), &overlapped_)) {
- return OnConnectComplete(0); // bytes_transferred (ignored)
- } else {
- DWORD result = GetLastError();
- if (result == ERROR_PIPE_CONNECTED) {
- return OnConnectComplete(0); // bytes_transferred (ignored)
- } else if (result == ERROR_IO_PENDING) {
- completion_handler_ = &RegistrationPipeState::OnConnectComplete;
- return true;
- } else {
- PLOG(ERROR) << "ConnectNamedPipe";
- return false;
- }
- }
-}
-
-bool RegistrationPipeState::IssueRead() {
- DWORD bytes_read = 0;
- if (ReadFile(pipe_.get(),
- &request_,
- sizeof(request_),
- &bytes_read,
- &overlapped_)) {
- return OnReadComplete(bytes_read);
- } else if (GetLastError() == ERROR_IO_PENDING) {
- completion_handler_ = &RegistrationPipeState::OnReadComplete;
- return true;
- } else {
- PLOG(ERROR) << "ReadFile";
- return ResetConnection();
- }
-}
-
-bool RegistrationPipeState::IssueWrite() {
- DWORD bytes_written = 0;
- if (WriteFile(pipe_.get(),
- &response_,
- sizeof(response_),
- &bytes_written,
- &overlapped_)) {
- return OnWriteComplete(bytes_written);
- } else if (GetLastError() == ERROR_IO_PENDING) {
- completion_handler_ = &RegistrationPipeState::OnWriteComplete;
- return true;
- } else {
- PLOG(ERROR) << "WriteFile";
- return ResetConnection();
- }
-}
-
-bool RegistrationPipeState::IssueWaitForClientClose() {
- // If we invoke DisconnectNamedPipe before the client has read the response
- // the response will never be delivered. Therefore we issue an extra ReadFile
- // operation after writing the response. No data is expected - the operation
- // will be 'completed' when the client closes the pipe.
- waiting_for_close_ = true;
- DWORD bytes_read = 0;
- if (ReadFile(pipe_.get(),
- &request_,
- sizeof(request_),
- &bytes_read,
- &overlapped_)) {
- return OnWaitForClientCloseComplete(bytes_read);
- } else if (GetLastError() == ERROR_IO_PENDING) {
- completion_handler_ = &RegistrationPipeState::OnWaitForClientCloseComplete;
- return true;
- } else {
- PLOG(ERROR) << "ReadFile";
- return ResetConnection();
- }
-}
-
-bool RegistrationPipeState::HandleRequest() {
- if (get_named_pipe_client_process_id_proc_) {
- // On Vista+ we can verify that the client is who they claim to be, thus
- // preventing arbitrary processes from having us duplicate handles into
- // other processes.
- DWORD real_client_process_id = 0;
- if (!get_named_pipe_client_process_id_proc_(pipe_.get(),
- &real_client_process_id)) {
- PLOG(ERROR) << "GetNamedPipeClientProcessId";
- } else if (real_client_process_id != request_.client_process_id) {
- LOG(ERROR) << "Client process ID from request ("
- << request_.client_process_id
- << ") does not match pipe client process ID ("
- << real_client_process_id << ").";
- return ResetConnection();
- }
- }
-
- ScopedKernelHANDLE client_process(
- OpenProcess(PROCESS_ALL_ACCESS, false, request_.client_process_id));
- if (!client_process.is_valid()) {
- if (ImpersonateNamedPipeClient(pipe_.get())) {
- client_process.reset(
- OpenProcess(PROCESS_ALL_ACCESS, false, request_.client_process_id));
- RevertToSelf();
- }
- }
-
- if (!client_process.is_valid()) {
- LOG(ERROR) << "Failed to open client process.";
- return ResetConnection();
- }
-
- memset(&response_, 0, sizeof(response_));
-
- HANDLE request_report_event = nullptr;
- HANDLE report_complete_event = nullptr;
-
- if (!delegate_->RegisterClient(client_process.Pass(),
- request_.crashpad_info_address,
- &request_report_event,
- &report_complete_event)) {
- return ResetConnection();
- }
-
- // A handle has at most 32 significant bits, though its type is void*. Thus we
- // truncate it here. An interesting exception is INVALID_HANDLE_VALUE, which
- // is '-1'. It is still safe to truncate it from 0xFFFFFFFFFFFFFFFF to
- // 0xFFFFFFFF, but a 64-bit client receiving that value must correctly sign
- // extend it.
- response_.request_report_event =
- reinterpret_cast<uint32_t>(request_report_event);
- response_.report_complete_event =
- reinterpret_cast<uint32_t>(report_complete_event);
- return IssueWrite();
-}
-
-bool RegistrationPipeState::ResetConnection() {
- memset(&request_, 0, sizeof(request_));
- waiting_for_close_ = false;
-
- if (!DisconnectNamedPipe(pipe_.get())) {
- PLOG(ERROR) << "DisconnectNamedPipe";
- return false;
- } else {
- return IssueConnect();
- }
-}
-
-} // namespace crashpad
« no previous file with comments | « handler/win/registration_pipe_state.h ('k') | handler/win/registration_pipe_state_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698