/// <summary>
        /// Add an object's handle to the list of inherited handles.
        /// </summary>
        /// <param name="obj">The object to add.</param>
        /// <returns>The raw handle value.</returns>
        /// <remarks>Note that this doesn't maintain a reference to the object. It should be kept
        /// alive until the process has been created.</remarks>
        public IntPtr AddInheritedHandle(NtObject obj)
        {
            obj.Inherit = true;
            IntPtr handle = obj.Handle.DangerousGetHandle();

            InheritHandleList.Add(handle);
            return(handle);
        }
        private SafeHGlobalBuffer GetAttributes(DisposableList <IDisposable> resources)
        {
            int count = GetAttributeCount();

            if (count == 0)
            {
                return(SafeHGlobalBuffer.Null);
            }

            var attr_list = resources.AddResource(new SafeProcThreadAttributeListBuffer(count));

            if (ParentProcess != null)
            {
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeParentProcess, ParentProcess.Handle.DangerousGetHandle());
            }

            if (MitigationOptions2 != ProcessMitigationOptions2.None)
            {
                MemoryStream stm    = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(stm);

                writer.Write((ulong)MitigationOptions);
                writer.Write((ulong)MitigationOptions2);
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeMitigationPolicy, stm.ToArray());
            }
            else if (MitigationOptions != ProcessMitigationOptions.None)
            {
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeMitigationPolicy, (ulong)MitigationOptions);
            }

            if (Win32kFilterFlags != Win32kFilterFlags.None)
            {
                Win32kFilterAttribute filter = new Win32kFilterAttribute();
                filter.Flags       = Win32kFilterFlags;
                filter.FilterLevel = Win32kFilterLevel;
                attr_list.AddAttributeBuffer(ProcessAttributes.ProcThreadAttributeWin32kFilter, resources.AddResource(filter.ToBuffer()));
            }

            if ((CreationFlags & CreateProcessFlags.ProtectedProcess) != 0)
            {
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeProtectionLevel, (int)ProtectionLevel);
            }

            if (InheritHandleList.Count > 0)
            {
                int total_size  = IntPtr.Size * InheritHandleList.Count;
                var handle_list = resources.AddResource(new SafeHGlobalBuffer(total_size));
                handle_list.WriteArray(0, InheritHandleList.ToArray(), 0, InheritHandleList.Count);
                attr_list.AddAttributeBuffer(ProcessAttributes.ProcThreadAttributeHandleList, handle_list);
            }

            if (AppContainerSid != null)
            {
                SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES();
                caps.AppContainerSid = resources.AddResource(AppContainerSid.ToSafeBuffer()).DangerousGetHandle();

                if (Capabilities.Count > 0)
                {
                    SidAndAttributes[] cap_sids = new SidAndAttributes[Capabilities.Count];
                    for (int i = 0; i < Capabilities.Count; ++i)
                    {
                        cap_sids[i] = new SidAndAttributes()
                        {
                            Sid        = resources.AddResource(Capabilities[i].ToSafeBuffer()).DangerousGetHandle(),
                            Attributes = GroupAttributes.Enabled
                        };
                    }
                    SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * Capabilities.Count));
                    cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length);
                    caps.Capabilities    = cap_buffer.DangerousGetHandle();
                    caps.CapabilityCount = cap_sids.Length;
                }
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeSecurityCapabilities, caps);
            }

            if (LowPrivilegeAppContainer)
            {
                attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeAllApplicationPackagesPolicy, 1);
            }

            return(attr_list);
        }
        private SafeHGlobalBuffer GetAttributes(DisposableList <IDisposable> resources)
        {
            int count = GetAttributeCount();

            if (count == 0)
            {
                return(SafeHGlobalBuffer.Null);
            }

            var attr_list = resources.AddResource(new SafeProcThreadAttributeListBuffer(count));

            if (ParentProcess != null)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeParentProcess, ParentProcess.Handle.DangerousGetHandle());
            }

            if (MitigationOptions2 != ProcessMitigationOptions2.None)
            {
                MemoryStream stm    = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(stm);

                writer.Write((ulong)MitigationOptions);
                writer.Write((ulong)MitigationOptions2);
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeMitigationPolicy, stm.ToArray());
            }
            else if (MitigationOptions != ProcessMitigationOptions.None)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeMitigationPolicy, (ulong)MitigationOptions);
            }

            if (Win32kFilterFlags != Win32kFilterFlags.None)
            {
                Win32kFilterAttribute filter = new Win32kFilterAttribute
                {
                    Flags       = Win32kFilterFlags,
                    FilterLevel = Win32kFilterLevel
                };
                attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributeWin32kFilter, resources.AddResource(filter.ToBuffer()));
            }

            if ((CreationFlags & CreateProcessFlags.ProtectedProcess) != 0 && ProtectionLevel != ProtectionLevel.None)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeProtectionLevel, (int)ProtectionLevel);
            }

            if (InheritHandleList.Count > 0)
            {
                int total_size  = IntPtr.Size * InheritHandleList.Count;
                var handle_list = resources.AddResource(new SafeHGlobalBuffer(total_size));
                handle_list.WriteArray(0, InheritHandleList.ToArray(), 0, InheritHandleList.Count);
                attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributeHandleList, handle_list);
            }

            if (AppContainerSid != null)
            {
                SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES
                {
                    AppContainerSid = resources.AddResource(AppContainerSid.ToSafeBuffer()).DangerousGetHandle()
                };

                if (Capabilities.Count > 0)
                {
                    SidAndAttributes[] cap_sids = new SidAndAttributes[Capabilities.Count];
                    for (int i = 0; i < Capabilities.Count; ++i)
                    {
                        cap_sids[i] = new SidAndAttributes()
                        {
                            Sid        = resources.AddResource(Capabilities[i].ToSafeBuffer()).DangerousGetHandle(),
                            Attributes = GroupAttributes.Enabled
                        };
                    }
                    SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * Capabilities.Count));
                    cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length);
                    caps.Capabilities    = cap_buffer.DangerousGetHandle();
                    caps.CapabilityCount = cap_sids.Length;
                }
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeSecurityCapabilities, caps);
            }

            if (LowPrivilegeAppContainer)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeAllApplicationPackagesPolicy, 1);
            }

            if (RestrictChildProcessCreation || OverrideChildProcessCreation)
            {
                int flags = RestrictChildProcessCreation ? 1 : 0;
                flags |= OverrideChildProcessCreation ? 2 : 0;

                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeChildProcessPolicy, flags);
            }

            if (DesktopAppBreakaway != ProcessDesktopAppBreakawayFlags.None)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeDesktopAppPolicy, (int)DesktopAppBreakaway);
            }

            if (!string.IsNullOrWhiteSpace(PackageName))
            {
                byte[] str_bytes     = Encoding.Unicode.GetBytes(PackageName);
                var    string_buffer = resources.AddResource(new SafeHGlobalBuffer(str_bytes));
                attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributePackageName, string_buffer);
            }

            if (PseudoConsole != IntPtr.Zero)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributePseudoConsole, PseudoConsole);
            }

            if (!string.IsNullOrEmpty(BnoIsolationPrefix))
            {
                var prefix = new BnoIsolationAttribute()
                {
                    IsolationEnabled = 1, IsolationPrefix = BnoIsolationPrefix
                };
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeBnoIsolation, prefix);
            }

            if (SafeOpenPromptOriginClaim != null)
            {
                var bytes = (byte[])SafeOpenPromptOriginClaim.Clone();
                Array.Resize(ref bytes, 524);
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeSafeOpenPromptOriginClaim, bytes);
            }

            if (ExtendedFlags != ProcessExtendedFlags.None)
            {
                attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeExtendedFlags, (int)ExtendedFlags);
            }

            return(attr_list);
        }