| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 
|  | 2 // | 
|  | 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 // you may not use this file except in compliance with the License. | 
|  | 5 // You may obtain a copy of the License at | 
|  | 6 // | 
|  | 7 //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 // | 
|  | 9 // Unless required by applicable law or agreed to in writing, software | 
|  | 10 // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 // See the License for the specific language governing permissions and | 
|  | 13 // limitations under the License. | 
|  | 14 | 
|  | 15 #include "handler/win/registration_test_base.h" | 
|  | 16 | 
|  | 17 #include "base/strings/stringprintf.h" | 
|  | 18 #include "base/strings/utf_string_conversions.h" | 
|  | 19 | 
|  | 20 namespace crashpad { | 
|  | 21 namespace test { | 
|  | 22 | 
|  | 23 RegistrationTestBase::MockDelegate::Entry::Entry( | 
|  | 24     ScopedKernelHANDLE client_process, | 
|  | 25     WinVMAddress crashpad_info_address, | 
|  | 26     uint32_t fake_request_dump_event, | 
|  | 27     uint32_t fake_dump_complete_event) | 
|  | 28     : client_process(client_process.Pass()), | 
|  | 29       crashpad_info_address(crashpad_info_address), | 
|  | 30       fake_request_dump_event(fake_request_dump_event), | 
|  | 31       fake_dump_complete_event(fake_dump_complete_event) { | 
|  | 32 } | 
|  | 33 RegistrationTestBase::MockDelegate::MockDelegate() | 
|  | 34     : started_event_(CreateEvent(nullptr, true, false, nullptr)), | 
|  | 35       registered_processes_(), | 
|  | 36       next_fake_handle_(1), | 
|  | 37       fail_(false) { | 
|  | 38   EXPECT_TRUE(started_event_.is_valid()); | 
|  | 39 } | 
|  | 40 | 
|  | 41 RegistrationTestBase::MockDelegate::~MockDelegate() { | 
|  | 42 } | 
|  | 43 | 
|  | 44 void RegistrationTestBase::MockDelegate::WaitForStart() { | 
|  | 45   DWORD wait_result = WaitForSingleObject(started_event_.get(), INFINITE); | 
|  | 46   if (wait_result == WAIT_FAILED) | 
|  | 47     PLOG(ERROR); | 
|  | 48   ASSERT_EQ(wait_result, WAIT_OBJECT_0); | 
|  | 49 } | 
|  | 50 | 
|  | 51 void RegistrationTestBase::MockDelegate::OnStarted() { | 
|  | 52   EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(started_event_.get(), 0)); | 
|  | 53   SetEvent(started_event_.get()); | 
|  | 54 } | 
|  | 55 | 
|  | 56 bool RegistrationTestBase::MockDelegate::RegisterClient( | 
|  | 57     ScopedKernelHANDLE client_process, | 
|  | 58     WinVMAddress crashpad_info_address, | 
|  | 59     HANDLE* request_dump_event, | 
|  | 60     HANDLE* dump_complete_event) { | 
|  | 61   if (fail_) | 
|  | 62     return false; | 
|  | 63 | 
|  | 64   if (!request_dump_event || !dump_complete_event) { | 
|  | 65     ADD_FAILURE() << "NULL 'out' parameter."; | 
|  | 66     return false; | 
|  | 67   } | 
|  | 68   *request_dump_event = reinterpret_cast<HANDLE>(next_fake_handle_++); | 
|  | 69   *dump_complete_event = reinterpret_cast<HANDLE>(next_fake_handle_++); | 
|  | 70 | 
|  | 71   registered_processes_.push_back( | 
|  | 72       new Entry(client_process.Pass(), | 
|  | 73                 crashpad_info_address, | 
|  | 74                 reinterpret_cast<uint32_t>(*request_dump_event), | 
|  | 75                 reinterpret_cast<uint32_t>(*dump_complete_event))); | 
|  | 76   return true; | 
|  | 77 } | 
|  | 78 | 
|  | 79 RegistrationTestBase::RegistrationTestBase() | 
|  | 80     : pipe_name_( | 
|  | 81           L"\\\\.\\pipe\\registration_server_test_pipe_" + | 
|  | 82           base::UTF8ToUTF16(base::StringPrintf("%08x", GetCurrentProcessId()))), | 
|  | 83       delegate_() { | 
|  | 84 } | 
|  | 85 | 
|  | 86 RegistrationTestBase::~RegistrationTestBase() { | 
|  | 87 } | 
|  | 88 | 
|  | 89 // Returns a pipe handle connected to the RegistrationServer. | 
|  | 90 ScopedFileHANDLE RegistrationTestBase::Connect() { | 
|  | 91   ScopedFileHANDLE pipe; | 
|  | 92   const int kMaxRetries = 5; | 
|  | 93   for (int retries = 0; !pipe.is_valid() && retries < kMaxRetries; ++retries) { | 
|  | 94     if (!WaitNamedPipe(pipe_name_.c_str(), NMPWAIT_WAIT_FOREVER)) | 
|  | 95       break; | 
|  | 96     pipe.reset(CreateFile(pipe_name_.c_str(), | 
|  | 97                           GENERIC_READ | GENERIC_WRITE, | 
|  | 98                           0, | 
|  | 99                           NULL, | 
|  | 100                           OPEN_EXISTING, | 
|  | 101                           SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, | 
|  | 102                           NULL)); | 
|  | 103     if (pipe.is_valid()) { | 
|  | 104       DWORD mode = PIPE_READMODE_MESSAGE; | 
|  | 105       if (!SetNamedPipeHandleState(pipe.get(), | 
|  | 106                                    &mode, | 
|  | 107                                    nullptr,  // don't set maximum bytes | 
|  | 108                                    nullptr)) {  // don't set maximum time | 
|  | 109         pipe.reset(); | 
|  | 110       } | 
|  | 111     } | 
|  | 112   } | 
|  | 113   EXPECT_TRUE(pipe.is_valid()); | 
|  | 114   return pipe.Pass(); | 
|  | 115 } | 
|  | 116 | 
|  | 117 // Sends the provided request and receives a response via the provided pipe. | 
|  | 118 bool RegistrationTestBase::SendRequest(ScopedFileHANDLE pipe, | 
|  | 119                                        const void* request_buffer, | 
|  | 120                                        size_t request_size, | 
|  | 121                                        RegistrationResponse* response) { | 
|  | 122   return WriteRequest(pipe.get(), request_buffer, request_size) && | 
|  | 123          ReadResponse(pipe.get(), response); | 
|  | 124 } | 
|  | 125 | 
|  | 126 bool RegistrationTestBase::WriteRequest(HANDLE pipe, | 
|  | 127                                         const void* request_buffer, | 
|  | 128                                         size_t request_size) { | 
|  | 129   DWORD byte_count = 0; | 
|  | 130   if (!WriteFile(pipe, | 
|  | 131                  request_buffer, | 
|  | 132                  static_cast<DWORD>(request_size), | 
|  | 133                  &byte_count, | 
|  | 134                  nullptr)) { | 
|  | 135     return false; | 
|  | 136   } | 
|  | 137 | 
|  | 138   return byte_count == request_size; | 
|  | 139 } | 
|  | 140 | 
|  | 141 bool RegistrationTestBase::ReadResponse(HANDLE pipe, | 
|  | 142                                         RegistrationResponse* response) { | 
|  | 143   DWORD byte_count = 0; | 
|  | 144   if (!ReadFile(pipe, response, sizeof(*response), &byte_count, nullptr)) | 
|  | 145     return false; | 
|  | 146   return byte_count == sizeof(*response); | 
|  | 147 } | 
|  | 148 | 
|  | 149 // Verifies that the request and response match what was received and sent by | 
|  | 150 // the MockDelegate. | 
|  | 151 void RegistrationTestBase::VerifyRegistration( | 
|  | 152     const MockDelegate::Entry& registered_process, | 
|  | 153     const RegistrationRequest& request, | 
|  | 154     const RegistrationResponse& response) { | 
|  | 155   EXPECT_EQ(request.crashpad_info_address, | 
|  | 156             registered_process.crashpad_info_address); | 
|  | 157   EXPECT_EQ(registered_process.fake_request_dump_event, | 
|  | 158             response.request_report_event); | 
|  | 159   EXPECT_EQ(registered_process.fake_dump_complete_event, | 
|  | 160             response.report_complete_event); | 
|  | 161   EXPECT_EQ(request.client_process_id, | 
|  | 162             GetProcessId(registered_process.client_process.get())); | 
|  | 163 } | 
|  | 164 | 
|  | 165 }  // namespace test | 
|  | 166 }  // namespace crashpad | 
| OLD | NEW | 
|---|