text: // Copyright 2020 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.
  
  #ifndef SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_
  #define SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_
  
  #include <Windows.h>
  
  #include <vector>
  
  #include "base/memory/scoped_refptr.h"
  #include "base/win/startup_information.h"
  #include "base/win/windows_version.h"
  #include "sandbox/win/src/app_container_profile_base.h"
  #include "sandbox/win/src/process_mitigations.h"
  #include "sandbox/win/src/security_capabilities.h"
  
  namespace sandbox {
  using base::win::StartupInformation;
  
  // Wraps base::win::StartupInformation and allows some querying of what is
  // set. This is specialized for the dance between
  // BrokerServices::SpawnTarget() and TargetProcess::Create().
  class StartupInformationHelper {
   public:
    StartupInformationHelper();
    ~StartupInformationHelper();
  
    // Adds flags to the |dwFlags| field.
    void UpdateFlags(DWORD flags);
    // Sets |lpDesktop|. If |desktop| is empty, sets as nullptr.
    void SetDesktop(std::wstring desktop);
    // Creates PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY based on |flags|.
    void SetMitigations(MitigationFlags flags);
    // Creates PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY if |restrict| is true.
    void SetRestrictChildProcessCreation(bool restrict);
    // Sets stdout and stderr handles. Also allows these to be inherited into
    // the child process. Should be called once only.
    void SetStdHandles(HANDLE stdout_handle, HANDLE stderr_handle);
    // Ignores duplicate or invalid handles.
    void AddInheritedHandle(HANDLE handle);
    // Create PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES and
    //        PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY
    // based on |profile|. |profile| should be valid.
    void SetAppContainerProfile(scoped_refptr<AppContainerProfileBase> profile);
    // Creates PROC_THREAD_ATTRIBUTE_JOB_LIST with |job_handle|. Not valid before
    // Windows 10.
    void AddJobToAssociate(HANDLE job_handle);
  
    // Will one or more jobs be associated via the wrapped StartupInformation.
    bool HasJobsToAssociate() { return !job_handle_list_.empty(); }
    // Have handles been provided for secure inheritance?
    bool ShouldInheritHandles() { return inherit_handles_; }
  
    // Compiles fields into PROC_THREAD_ attributes and populates startup
    // information. Must be called before GetStartupInformation().
    bool BuildStartupInformation();
  
    // Gets wrapped object, valid once BuildStartupInformation() has been called.
    base::win::StartupInformation* GetStartupInformation() {
      return &startup_info_;
    }
  
   private:
    void operator=(const StartupInformationHelper&) = delete;
    StartupInformationHelper(const StartupInformationHelper&) = delete;
  
    int CountAttributes();
  
    // Fields that are not passed into CreateProcessAsUserW().
    scoped_refptr<AppContainerProfileBase> app_container_profile_ = nullptr;
    bool restrict_child_process_creation_ = false;
    HANDLE stdout_handle_ = INVALID_HANDLE_VALUE;
    HANDLE stderr_handle_ = INVALID_HANDLE_VALUE;
    bool inherit_handles_ = false;
    size_t mitigations_size_ = 0;
  
    // startup_info_.startup_info() is passed to CreateProcessAsUserW().
    StartupInformation startup_info_;
  
    // These need to have the same lifetime as startup_info_.startup_info();
    std::wstring desktop_;
    DWORD64 mitigations_[2];
    DWORD child_process_creation_;
    DWORD all_applications_package_policy_;
    std::vector<HANDLE> inherited_handle_list_;
    std::vector<HANDLE> job_handle_list_;
    std::unique_ptr<SecurityCapabilities> security_capabilities_ = nullptr;
  };
  }  // namespace sandbox
  
  #endif  // SANDBOX_WIN_SRC_STARTUP_INFORMATION_HELPER_H_
  