startup_information_unittest.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/win/startup_information.h"
  5. #include <windows.h>
  6. #include <stddef.h>
  7. #include "base/files/file_path.h"
  8. #include "base/path_service.h"
  9. #include "base/strings/string_util.h"
  10. #include "base/win/scoped_handle.h"
  11. #include "base/win/scoped_process_information.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace {
  14. class ScopedProcessTerminator {
  15. public:
  16. explicit ScopedProcessTerminator(const PROCESS_INFORMATION& process_info)
  17. : process_info_(process_info) {}
  18. ScopedProcessTerminator(const ScopedProcessTerminator&) = delete;
  19. ScopedProcessTerminator& operator=(const ScopedProcessTerminator&) = delete;
  20. ~ScopedProcessTerminator() {
  21. if (process_info_.IsValid())
  22. ::TerminateProcess(process_info_.process_handle(), 0);
  23. }
  24. private:
  25. base::win::ScopedProcessInformation process_info_;
  26. };
  27. base::win::ScopedHandle CreateInheritedHandle() {
  28. HANDLE handle;
  29. if (!::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentProcess(),
  30. ::GetCurrentProcess(), &handle,
  31. PROCESS_QUERY_LIMITED_INFORMATION, TRUE, 0)) {
  32. return base::win::ScopedHandle();
  33. }
  34. return base::win::ScopedHandle(handle);
  35. }
  36. bool CheckInheritedHandle(HANDLE process, HANDLE check_handle) {
  37. HANDLE temp_handle;
  38. if (!::DuplicateHandle(process, check_handle, ::GetCurrentProcess(),
  39. &temp_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
  40. return false;
  41. }
  42. base::win::ScopedHandle dup_handle(temp_handle);
  43. return ::GetProcessId(temp_handle) == ::GetCurrentProcessId();
  44. }
  45. } // namespace
  46. // Verify that only the explicitly specified process handle is inherited.
  47. TEST(StartupInformationTest, InheritStdOut) {
  48. base::win::ScopedHandle handle_0 = CreateInheritedHandle();
  49. ASSERT_TRUE(handle_0.is_valid());
  50. base::win::ScopedHandle handle_1 = CreateInheritedHandle();
  51. ASSERT_TRUE(handle_1.is_valid());
  52. ASSERT_NE(handle_0.get(), handle_1.get());
  53. base::win::StartupInformation startup_info;
  54. ASSERT_TRUE(startup_info.InitializeProcThreadAttributeList(1));
  55. HANDLE inherit_process = handle_0.get();
  56. ASSERT_TRUE(startup_info.UpdateProcThreadAttribute(
  57. PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &inherit_process,
  58. sizeof(inherit_process)));
  59. base::FilePath exe_path;
  60. ASSERT_TRUE(base::PathService::Get(base::FILE_EXE, &exe_path));
  61. WCHAR cmd_line[] = L"dummy";
  62. PROCESS_INFORMATION temp_process_info = {};
  63. ASSERT_TRUE(::CreateProcess(
  64. exe_path.value().c_str(), cmd_line, nullptr, nullptr, TRUE,
  65. EXTENDED_STARTUPINFO_PRESENT | CREATE_SUSPENDED, nullptr, nullptr,
  66. startup_info.startup_info(), &temp_process_info))
  67. << ::GetLastError();
  68. ScopedProcessTerminator process(temp_process_info);
  69. EXPECT_TRUE(CheckInheritedHandle(temp_process_info.hProcess, handle_0.get()));
  70. EXPECT_FALSE(
  71. CheckInheritedHandle(temp_process_info.hProcess, handle_1.get()));
  72. }