| Index: sandbox/win/src/ipc_unittest.cc | 
| diff --git a/sandbox/win/src/ipc_unittest.cc b/sandbox/win/src/ipc_unittest.cc | 
| deleted file mode 100644 | 
| index c41720da36a3237703058601cddb3ce348fa62de..0000000000000000000000000000000000000000 | 
| --- a/sandbox/win/src/ipc_unittest.cc | 
| +++ /dev/null | 
| @@ -1,632 +0,0 @@ | 
| -// Copyright (c) 2012 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 <stddef.h> | 
| -#include <stdint.h> | 
| - | 
| -#include "sandbox/win/src/crosscall_client.h" | 
| -#include "sandbox/win/src/crosscall_server.h" | 
| -#include "sandbox/win/src/sharedmem_ipc_client.h" | 
| -#include "sandbox/win/src/sharedmem_ipc_server.h" | 
| -#include "testing/gtest/include/gtest/gtest.h" | 
| - | 
| -namespace sandbox { | 
| - | 
| -// Helper function to make the fake shared memory with some | 
| -// basic elements initialized. | 
| -IPCControl* MakeChannels(size_t channel_size, size_t total_shared_size, | 
| -                         size_t* base_start) { | 
| -  // Allocate memory | 
| -  char* mem = new char[total_shared_size]; | 
| -  memset(mem, 0, total_shared_size); | 
| -  // Calculate how many channels we can fit in the shared memory. | 
| -  total_shared_size -= offsetof(IPCControl, channels); | 
| -  size_t channel_count = | 
| -    total_shared_size / (sizeof(ChannelControl) + channel_size); | 
| -  // Calculate the start of the first channel. | 
| -  *base_start = (sizeof(ChannelControl)* channel_count) + | 
| -    offsetof(IPCControl, channels); | 
| -  // Setup client structure. | 
| -  IPCControl* client_control = reinterpret_cast<IPCControl*>(mem); | 
| -  client_control->channels_count = channel_count; | 
| -  return client_control; | 
| -} | 
| - | 
| -enum TestFixMode { | 
| -  FIX_NO_EVENTS, | 
| -  FIX_PONG_READY, | 
| -  FIX_PONG_NOT_READY | 
| -}; | 
| - | 
| -void FixChannels(IPCControl* client_control, size_t base_start, | 
| -                 size_t channel_size, TestFixMode mode) { | 
| -  for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 
| -    ChannelControl& channel = client_control->channels[ix]; | 
| -    channel.channel_base = base_start; | 
| -    channel.state = kFreeChannel; | 
| -    if (mode != FIX_NO_EVENTS) { | 
| -      BOOL signaled = (FIX_PONG_READY == mode)? TRUE : FALSE; | 
| -      channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL); | 
| -      channel.pong_event = ::CreateEventW(NULL, FALSE, signaled, NULL); | 
| -    } | 
| -    base_start += channel_size; | 
| -  } | 
| -} | 
| - | 
| -void CloseChannelEvents(IPCControl* client_control) { | 
| -  for (size_t ix = 0; ix != client_control->channels_count; ++ix) { | 
| -    ChannelControl& channel = client_control->channels[ix]; | 
| -    ::CloseHandle(channel.ping_event); | 
| -    ::CloseHandle(channel.pong_event); | 
| -  } | 
| -} | 
| - | 
| -TEST(IPCTest, ChannelMaker) { | 
| -  // Test that our testing rig is computing offsets properly. We should have | 
| -  // 5 channnels and the offset to the first channel is 108 bytes in 32 bits | 
| -  // and 216 in 64 bits. | 
| -  size_t channel_start = 0; | 
| -  IPCControl* client_control = MakeChannels(12 * 64, 4096, &channel_start); | 
| -  ASSERT_TRUE(NULL != client_control); | 
| -  EXPECT_EQ(5u, client_control->channels_count); | 
| -#if defined(_WIN64) | 
| -  EXPECT_EQ(216u, channel_start); | 
| -#else | 
| -  EXPECT_EQ(108u, channel_start); | 
| -#endif | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -TEST(IPCTest, ClientLockUnlock) { | 
| -  // Make 7 channels of kIPCChannelSize (1kb) each. Test that we lock and | 
| -  // unlock channels properly. | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(kIPCChannelSize, 4096 * 2, &base_start); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_NO_EVENTS); | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  // Test that we lock the first 3 channels in sequence. | 
| -  void* buff0 = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  void* buff1 = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff1); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  void* buff2 = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[2].channel_base == buff2); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  // Test that we unlock and re-lock the right channel. | 
| -  client.FreeBuffer(buff1); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  void* buff2b = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff2b); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  client.FreeBuffer(buff0); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[2].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[3].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[4].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[5].state); | 
| - | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -TEST(IPCTest, CrossCallStrPacking) { | 
| -  // This test tries the CrossCall object with null and non-null string | 
| -  // combination of parameters, integer types and verifies that the unpacker | 
| -  // can read them properly. | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(kIPCChannelSize, 4096 * 4, &base_start); | 
| -  client_control->server_alive = HANDLE(1); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  CrossCallReturn answer; | 
| -  uint32_t tag1 = 666; | 
| -  const wchar_t *text = L"98765 - 43210"; | 
| -  base::string16 copied_text; | 
| -  CrossCallParamsEx* actual_params; | 
| - | 
| -  CrossCall(client, tag1, text, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(1u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag1, actual_params->GetTag()); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text)); | 
| -  EXPECT_STREQ(text, copied_text.c_str()); | 
| - | 
| -  // Check with an empty string. | 
| -  uint32_t tag2 = 777; | 
| -  const wchar_t* null_text = NULL; | 
| -  CrossCall(client, tag2, null_text, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(1u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag2, actual_params->GetTag()); | 
| -  uint32_t param_size = 1; | 
| -  ArgType type = INVALID_TYPE; | 
| -  void* param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); | 
| -  EXPECT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0u, param_size); | 
| -  EXPECT_EQ(WCHAR_TYPE, type); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text)); | 
| - | 
| -  uint32_t tag3 = 888; | 
| -  param_size = 1; | 
| -  copied_text.clear(); | 
| - | 
| -  // Check with an empty string and a non-empty string. | 
| -  CrossCall(client, tag3, null_text, text, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(2u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag3, actual_params->GetTag()); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); | 
| -  EXPECT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0u, param_size); | 
| -  EXPECT_EQ(WCHAR_TYPE, type); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text)); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(1, &copied_text)); | 
| -  EXPECT_STREQ(text, copied_text.c_str()); | 
| - | 
| -  param_size = 1; | 
| -  base::string16 copied_text_p0, copied_text_p2; | 
| - | 
| -  const wchar_t *text2 = L"AeFG"; | 
| -  CrossCall(client, tag1, text2, null_text, text, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(3u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag1, actual_params->GetTag()); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text_p0)); | 
| -  EXPECT_STREQ(text2, copied_text_p0.c_str()); | 
| -  EXPECT_TRUE(actual_params->GetParameterStr(2, &copied_text_p2)); | 
| -  EXPECT_STREQ(text, copied_text_p2.c_str()); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); | 
| -  EXPECT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0u, param_size); | 
| -  EXPECT_EQ(WCHAR_TYPE, type); | 
| - | 
| -  CloseChannelEvents(client_control); | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -TEST(IPCTest, CrossCallIntPacking) { | 
| -  // Check handling for regular 32 bit integers used in Windows. | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(kIPCChannelSize, 4096 * 4, &base_start); | 
| -  client_control->server_alive = HANDLE(1); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); | 
| - | 
| -  uint32_t tag1 = 999; | 
| -  uint32_t tag2 = 111; | 
| -  const wchar_t *text = L"godzilla"; | 
| -  CrossCallParamsEx* actual_params; | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  CrossCallReturn answer; | 
| -  DWORD dw = 0xE6578; | 
| -  CrossCall(client, tag2, dw, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(1u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag2, actual_params->GetTag()); | 
| -  ArgType type = INVALID_TYPE; | 
| -  uint32_t param_size = 1; | 
| -  void* param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); | 
| -  ASSERT_EQ(sizeof(dw), param_size); | 
| -  EXPECT_EQ(UINT32_TYPE, type); | 
| -  ASSERT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0, memcmp(&dw, param_addr, param_size)); | 
| - | 
| -  // Check handling for windows HANDLES. | 
| -  HANDLE h = HANDLE(0x70000500); | 
| -  CrossCall(client, tag1, text, h, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(2u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag1, actual_params->GetTag()); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); | 
| -  ASSERT_EQ(sizeof(h), param_size); | 
| -  EXPECT_EQ(VOIDPTR_TYPE, type); | 
| -  ASSERT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); | 
| - | 
| -  // Check combination of 32 and 64 bits. | 
| -  CrossCall(client, tag2, h, dw, h, &answer); | 
| -  actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); | 
| -  EXPECT_EQ(3u, actual_params->GetParamsCount()); | 
| -  EXPECT_EQ(tag2, actual_params->GetTag()); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); | 
| -  ASSERT_EQ(sizeof(h), param_size); | 
| -  EXPECT_EQ(VOIDPTR_TYPE, type); | 
| -  ASSERT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(1, ¶m_size, &type); | 
| -  ASSERT_EQ(sizeof(dw), param_size); | 
| -  EXPECT_EQ(UINT32_TYPE, type); | 
| -  ASSERT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0, memcmp(&dw, param_addr, param_size)); | 
| -  type = INVALID_TYPE; | 
| -  param_addr = actual_params->GetRawParameter(2, ¶m_size, &type); | 
| -  ASSERT_EQ(sizeof(h), param_size); | 
| -  EXPECT_EQ(VOIDPTR_TYPE, type); | 
| -  ASSERT_TRUE(NULL != param_addr); | 
| -  EXPECT_EQ(0, memcmp(&h, param_addr, param_size)); | 
| - | 
| -  CloseChannelEvents(client_control); | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -TEST(IPCTest, CrossCallValidation) { | 
| -  // First a sanity test with a well formed parameter object. | 
| -  unsigned long value = 124816; | 
| -  const uint32_t kTag = 33; | 
| -  const uint32_t kBufferSize = 256; | 
| -  ActualCallParams<1, kBufferSize> params_1(kTag); | 
| -  params_1.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); | 
| -  void* buffer = const_cast<void*>(params_1.GetBuffer()); | 
| - | 
| -  uint32_t out_size = 0; | 
| -  CrossCallParamsEx* ccp = 0; | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, params_1.GetSize(), | 
| -                                            &out_size); | 
| -  ASSERT_TRUE(NULL != ccp); | 
| -  EXPECT_TRUE(ccp->GetBuffer() != buffer); | 
| -  EXPECT_EQ(kTag, ccp->GetTag()); | 
| -  EXPECT_EQ(1u, ccp->GetParamsCount()); | 
| -  delete[] (reinterpret_cast<char*>(ccp)); | 
| - | 
| -  // Test that we handle integer overflow on the number of params | 
| -  // correctly. We use a test-only ctor for ActualCallParams that | 
| -  // allows to create malformed cross-call buffers. | 
| -  const int32_t kPtrDiffSz = sizeof(ptrdiff_t); | 
| -  for (int32_t ix = -1; ix != 3; ++ix) { | 
| -    uint32_t fake_num_params = (UINT32_MAX / kPtrDiffSz) + ix; | 
| -    ActualCallParams<1, kBufferSize> params_2(kTag, fake_num_params); | 
| -    params_2.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); | 
| -    buffer = const_cast<void*>(params_2.GetBuffer()); | 
| - | 
| -    EXPECT_TRUE(NULL != buffer); | 
| -    ccp = CrossCallParamsEx::CreateFromBuffer(buffer, params_1.GetSize(), | 
| -                                              &out_size); | 
| -    // If the buffer is malformed the return is NULL. | 
| -    EXPECT_TRUE(NULL == ccp); | 
| -  } | 
| - | 
| -  ActualCallParams<1, kBufferSize> params_3(kTag, 1); | 
| -  params_3.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); | 
| -  buffer = const_cast<void*>(params_3.GetBuffer()); | 
| -  EXPECT_TRUE(NULL != buffer); | 
| - | 
| -  uint32_t correct_size = params_3.OverrideSize(1); | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); | 
| -  EXPECT_TRUE(NULL == ccp); | 
| - | 
| -  // The correct_size is 8 bytes aligned. | 
| -  params_3.OverrideSize(correct_size - 7); | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); | 
| -  EXPECT_TRUE(NULL == ccp); | 
| - | 
| -  params_3.OverrideSize(correct_size); | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); | 
| -  EXPECT_TRUE(NULL != ccp); | 
| - | 
| -  // Make sure that two parameters work as expected. | 
| -  ActualCallParams<2, kBufferSize> params_4(kTag, 2); | 
| -  params_4.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); | 
| -  params_4.CopyParamIn(1, buffer, sizeof(buffer), false, VOIDPTR_TYPE); | 
| -  buffer = const_cast<void*>(params_4.GetBuffer()); | 
| -  EXPECT_TRUE(NULL != buffer); | 
| - | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); | 
| -  EXPECT_TRUE(NULL != ccp); | 
| - | 
| -#if defined(_WIN64) | 
| -  correct_size = params_4.OverrideSize(1); | 
| -  params_4.OverrideSize(correct_size - 1); | 
| -  ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); | 
| -  EXPECT_TRUE(NULL == ccp); | 
| -#endif | 
| -} | 
| - | 
| -// This structure is passed to the mock server threads to simulate | 
| -// the server side IPC so it has the required kernel objects. | 
| -struct ServerEvents { | 
| -  HANDLE ping; | 
| -  HANDLE pong; | 
| -  volatile LONG* state; | 
| -  HANDLE mutex; | 
| -}; | 
| - | 
| -// This is the server thread that quicky answers an IPC and exits. | 
| -DWORD WINAPI QuickResponseServer(PVOID param) { | 
| -  ServerEvents* events = reinterpret_cast<ServerEvents*>(param); | 
| -  DWORD wait_result = 0; | 
| -  wait_result = ::WaitForSingleObject(events->ping, INFINITE); | 
| -  ::InterlockedExchange(events->state, kAckChannel); | 
| -  ::SetEvent(events->pong); | 
| -  return wait_result; | 
| -} | 
| - | 
| -class CrossCallParamsMock : public CrossCallParams { | 
| - public: | 
| -  CrossCallParamsMock(uint32_t tag, uint32_t params_count) | 
| -      : CrossCallParams(tag, params_count) {} | 
| -}; | 
| - | 
| -void FakeOkAnswerInChannel(void* channel) { | 
| -  CrossCallReturn* answer = reinterpret_cast<CrossCallReturn*>(channel); | 
| -  answer->call_outcome = SBOX_ALL_OK; | 
| -} | 
| - | 
| -// Create two threads that will quickly answer IPCs; the first one | 
| -// using channel 1 (channel 0 is busy) and one using channel 0. No time-out | 
| -// should occur. | 
| -TEST(IPCTest, ClientFastServer) { | 
| -  const size_t channel_size = kIPCChannelSize; | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(channel_size, 4096 * 2, &base_start); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY); | 
| -  client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  ServerEvents events = {0}; | 
| -  events.ping = client_control->channels[1].ping_event; | 
| -  events.pong = client_control->channels[1].pong_event; | 
| -  events.state = &client_control->channels[1].state; | 
| - | 
| -  HANDLE t1 = ::CreateThread(NULL, 0, QuickResponseServer, &events, 0, NULL); | 
| -  ASSERT_TRUE(NULL != t1); | 
| -  ::CloseHandle(t1); | 
| - | 
| -  void* buff0 = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| - | 
| -  void* buff1 = client.GetBuffer(); | 
| -  EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff1); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| - | 
| -  EXPECT_EQ(0u, client_control->channels[1].ipc_tag); | 
| - | 
| -  uint32_t tag = 7654; | 
| -  CrossCallReturn answer; | 
| -  CrossCallParamsMock* params1 = new(buff1) CrossCallParamsMock(tag, 1); | 
| -  FakeOkAnswerInChannel(buff1); | 
| - | 
| -  ResultCode result = client.DoCall(params1, &answer); | 
| -  if (SBOX_ERROR_CHANNEL_ERROR != result) | 
| -    client.FreeBuffer(buff1); | 
| - | 
| -  EXPECT_TRUE(SBOX_ALL_OK == result); | 
| -  EXPECT_EQ(tag, client_control->channels[1].ipc_tag); | 
| -  EXPECT_EQ(kBusyChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| - | 
| -  HANDLE t2 = ::CreateThread(NULL, 0, QuickResponseServer, &events, 0, NULL); | 
| -  ASSERT_TRUE(NULL != t2); | 
| -  ::CloseHandle(t2); | 
| - | 
| -  client.FreeBuffer(buff0); | 
| -  events.ping = client_control->channels[0].ping_event; | 
| -  events.pong = client_control->channels[0].pong_event; | 
| -  events.state = &client_control->channels[0].state; | 
| - | 
| -  tag = 4567; | 
| -  CrossCallParamsMock* params2 = new(buff0) CrossCallParamsMock(tag, 1); | 
| -  FakeOkAnswerInChannel(buff0); | 
| - | 
| -  result = client.DoCall(params2, &answer); | 
| -  if (SBOX_ERROR_CHANNEL_ERROR != result) | 
| -    client.FreeBuffer(buff0); | 
| - | 
| -  EXPECT_TRUE(SBOX_ALL_OK == result); | 
| -  EXPECT_EQ(tag, client_control->channels[0].ipc_tag); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[1].state); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[2].state); | 
| - | 
| -  CloseChannelEvents(client_control); | 
| -  ::CloseHandle(client_control->server_alive); | 
| - | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -// This is the server thread that very slowly answers an IPC and exits. Note | 
| -// that the pong event needs to be signaled twice. | 
| -DWORD WINAPI SlowResponseServer(PVOID param) { | 
| -  ServerEvents* events = reinterpret_cast<ServerEvents*>(param); | 
| -  DWORD wait_result = 0; | 
| -  wait_result = ::WaitForSingleObject(events->ping, INFINITE); | 
| -  ::Sleep(kIPCWaitTimeOut1 + kIPCWaitTimeOut2 + 200); | 
| -  ::InterlockedExchange(events->state, kAckChannel); | 
| -  ::SetEvent(events->pong); | 
| -  return wait_result; | 
| -} | 
| - | 
| -// This thread's job is to keep the mutex locked. | 
| -DWORD WINAPI MainServerThread(PVOID param) { | 
| -  ServerEvents* events = reinterpret_cast<ServerEvents*>(param); | 
| -  DWORD wait_result = 0; | 
| -  wait_result = ::WaitForSingleObject(events->mutex, INFINITE); | 
| -  Sleep(kIPCWaitTimeOut1 * 20); | 
| -  return wait_result; | 
| -} | 
| - | 
| -// Creates a server thread that answers the IPC so slow that is guaranteed to | 
| -// trigger the time-out code path in the client. A second thread is created | 
| -// to hold locked the server_alive mutex: this signals the client that the | 
| -// server is not dead and it retries the wait. | 
| -TEST(IPCTest, ClientSlowServer) { | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(kIPCChannelSize, 4096*2, &base_start); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY); | 
| -  client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL); | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  ServerEvents events = {0}; | 
| -  events.ping = client_control->channels[0].ping_event; | 
| -  events.pong = client_control->channels[0].pong_event; | 
| -  events.state = &client_control->channels[0].state; | 
| - | 
| -  HANDLE t1 = ::CreateThread(NULL, 0, SlowResponseServer, &events, 0, NULL); | 
| -  ASSERT_TRUE(NULL != t1); | 
| -  ::CloseHandle(t1); | 
| - | 
| -  ServerEvents events2 = {0}; | 
| -  events2.pong = events.pong; | 
| -  events2.mutex = client_control->server_alive; | 
| - | 
| -  HANDLE t2 = ::CreateThread(NULL, 0, MainServerThread, &events2, 0, NULL); | 
| -  ASSERT_TRUE(NULL != t2); | 
| -  ::CloseHandle(t2); | 
| - | 
| -  ::Sleep(1); | 
| - | 
| -  void* buff0 = client.GetBuffer(); | 
| -  uint32_t tag = 4321; | 
| -  CrossCallReturn answer; | 
| -  CrossCallParamsMock* params1 = new(buff0) CrossCallParamsMock(tag, 1); | 
| -  FakeOkAnswerInChannel(buff0); | 
| - | 
| -  ResultCode result = client.DoCall(params1, &answer); | 
| -  if (SBOX_ERROR_CHANNEL_ERROR != result) | 
| -    client.FreeBuffer(buff0); | 
| - | 
| -  EXPECT_TRUE(SBOX_ALL_OK == result); | 
| -  EXPECT_EQ(tag, client_control->channels[0].ipc_tag); | 
| -  EXPECT_EQ(kFreeChannel, client_control->channels[0].state); | 
| - | 
| -  CloseChannelEvents(client_control); | 
| -  ::CloseHandle(client_control->server_alive); | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -// This test-only IPC dispatcher has two handlers with the same signature | 
| -// but only CallOneHandler should be used. | 
| -class UnitTestIPCDispatcher : public Dispatcher { | 
| - public: | 
| -  enum { | 
| -    CALL_ONE_TAG = 78, | 
| -    CALL_TWO_TAG = 87 | 
| -  }; | 
| - | 
| -  UnitTestIPCDispatcher(); | 
| -  ~UnitTestIPCDispatcher() override{}; | 
| - | 
| -  bool SetupService(InterceptionManager* manager, int service) override { | 
| -    return true; | 
| -  } | 
| - | 
| - private: | 
| -  bool CallOneHandler(IPCInfo* ipc, HANDLE p1, uint32_t p2) { | 
| -    ipc->return_info.extended[0].handle = p1; | 
| -    ipc->return_info.extended[1].unsigned_int = p2; | 
| -    return true; | 
| -  } | 
| - | 
| -  bool CallTwoHandler(IPCInfo* ipc, HANDLE p1, uint32_t p2) { return true; } | 
| -}; | 
| - | 
| -UnitTestIPCDispatcher::UnitTestIPCDispatcher() { | 
| -  static const IPCCall call_one = {{CALL_ONE_TAG, {VOIDPTR_TYPE, UINT32_TYPE}}, | 
| -                                   reinterpret_cast<CallbackGeneric>( | 
| -                                       &UnitTestIPCDispatcher::CallOneHandler)}; | 
| -  static const IPCCall call_two = {{CALL_TWO_TAG, {VOIDPTR_TYPE, UINT32_TYPE}}, | 
| -                                   reinterpret_cast<CallbackGeneric>( | 
| -                                       &UnitTestIPCDispatcher::CallTwoHandler)}; | 
| -  ipc_calls_.push_back(call_one); | 
| -  ipc_calls_.push_back(call_two); | 
| -} | 
| - | 
| -// This test does most of the shared memory IPC client-server roundtrip | 
| -// and tests the packing, unpacking and call dispatching. | 
| -TEST(IPCTest, SharedMemServerTests) { | 
| -  size_t base_start = 0; | 
| -  IPCControl* client_control = | 
| -      MakeChannels(kIPCChannelSize, 4096, &base_start); | 
| -  client_control->server_alive = HANDLE(1); | 
| -  FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); | 
| - | 
| -  char* mem = reinterpret_cast<char*>(client_control); | 
| -  SharedMemIPCClient client(mem); | 
| - | 
| -  CrossCallReturn answer; | 
| -  HANDLE bar = HANDLE(191919); | 
| -  DWORD foo = 6767676; | 
| -  CrossCall(client, UnitTestIPCDispatcher::CALL_ONE_TAG, bar, foo, &answer); | 
| -  void* buff = client.GetBuffer(); | 
| -  ASSERT_TRUE(NULL != buff); | 
| - | 
| -  UnitTestIPCDispatcher dispatcher; | 
| -  // Since we are directly calling InvokeCallback, most of this structure | 
| -  // can be set to NULL. | 
| -  sandbox::SharedMemIPCServer::ServerControl srv_control = {}; | 
| -  srv_control.channel_size = kIPCChannelSize; | 
| -  srv_control.shared_base = reinterpret_cast<char*>(client_control); | 
| -  srv_control.dispatcher = &dispatcher; | 
| - | 
| -  sandbox::CrossCallReturn call_return = {0}; | 
| -  EXPECT_TRUE(SharedMemIPCServer::InvokeCallback(&srv_control, buff, | 
| -                                                 &call_return)); | 
| -  EXPECT_EQ(SBOX_ALL_OK, call_return.call_outcome); | 
| -  EXPECT_TRUE(bar == call_return.extended[0].handle); | 
| -  EXPECT_EQ(foo, call_return.extended[1].unsigned_int); | 
| - | 
| -  CloseChannelEvents(client_control); | 
| -  delete[] reinterpret_cast<char*>(client_control); | 
| -} | 
| - | 
| -}  // namespace sandbox | 
|  |