| // 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 <windows.h> | 
 | #include <stddef.h> | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "base/command_line.h" | 
 | #include "base/test/multiprocess_test.h" | 
 | #include "base/win/scoped_handle.h" | 
 | #include "base/win/scoped_process_information.h" | 
 | #include "base/win/startup_information.h" | 
 | #include "testing/multiprocess_func_list.h" | 
 |  | 
 | const wchar_t kSectionName[] = L"EventTestSection"; | 
 | const size_t kSectionSize = 4096; | 
 |  | 
 | MULTIPROCESS_TEST_MAIN(FireInheritedEvents) { | 
 |   HANDLE section = ::OpenFileMappingW(PAGE_READWRITE, false, kSectionName); | 
 |   HANDLE* events = reinterpret_cast<HANDLE*>(::MapViewOfFile(section, | 
 |       PAGE_READWRITE, 0, 0, kSectionSize)); | 
 |   // This event should not be valid because it wasn't explicitly inherited. | 
 |   if (::SetEvent(events[1])) | 
 |     return -1; | 
 |   // This event should be valid because it was explicitly inherited. | 
 |   if (!::SetEvent(events[0])) | 
 |     return -1; | 
 |  | 
 |   return 0; | 
 | } | 
 |  | 
 | class StartupInformationTest : public base::MultiProcessTest {}; | 
 |  | 
 | // Verify that only the explicitly specified event is inherited. | 
 | TEST_F(StartupInformationTest, InheritStdOut) { | 
 |   base::win::StartupInformation startup_info; | 
 |  | 
 |   HANDLE section = ::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, | 
 |                                         PAGE_READWRITE, 0, kSectionSize, | 
 |                                         kSectionName); | 
 |   ASSERT_TRUE(section); | 
 |  | 
 |   HANDLE* events = reinterpret_cast<HANDLE*>(::MapViewOfFile(section, | 
 |       FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, kSectionSize)); | 
 |  | 
 |   // Make two inheritable events. | 
 |   SECURITY_ATTRIBUTES security_attributes = { sizeof(security_attributes), | 
 |                                               NULL, true }; | 
 |   events[0] = ::CreateEvent(&security_attributes, false, false, NULL); | 
 |   ASSERT_TRUE(events[0]); | 
 |   events[1] = ::CreateEvent(&security_attributes, false, false, NULL); | 
 |   ASSERT_TRUE(events[1]); | 
 |  | 
 |   ASSERT_TRUE(startup_info.InitializeProcThreadAttributeList(1)); | 
 |   ASSERT_TRUE(startup_info.UpdateProcThreadAttribute( | 
 |       PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &events[0], | 
 |       sizeof(events[0]))); | 
 |  | 
 |   std::wstring cmd_line = | 
 |       MakeCmdLine("FireInheritedEvents").GetCommandLineString(); | 
 |  | 
 |   PROCESS_INFORMATION temp_process_info = {}; | 
 |   ASSERT_TRUE(::CreateProcess(NULL, &cmd_line[0], | 
 |                               NULL, NULL, true, EXTENDED_STARTUPINFO_PRESENT, | 
 |                               NULL, NULL, startup_info.startup_info(), | 
 |                               &temp_process_info)) << ::GetLastError(); | 
 |   base::win::ScopedProcessInformation process_info(temp_process_info); | 
 |  | 
 |   // Only the first event should be signalled | 
 |   EXPECT_EQ(WAIT_OBJECT_0, ::WaitForMultipleObjects(2, events, false, | 
 |                                                     4000)); | 
 | } | 
 |  |