<commit_before>﻿using PInvokeWrap;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Microsoft.Win32;

namespace HelperFunctions
{
    public static class Helpers
    {
        public const string HKLM = @"HKEY_LOCAL_MACHINE\";
        public const string REGISTRY_SERVICES_KEY =
            @"SYSTEM\CurrentControlSet\Services\";

        public static void Reboot()
        {
            Trace.WriteLine("OK - shutting down");
            AcquireSystemPrivilege(AdvApi32.SE_SHUTDOWN_NAME);

            if (WinVersion.GetMajorVersion() >= 5 &&
                WinVersion.GetMajorVersion() < 6)
            {
                User32.ExitWindowsEx(
                    User32.ExitFlags.EWX_REBOOT |
                    User32.ExitFlags.EWX_FORCE,
                    0
                );
            }
            else
            {
                AdvApi32.InitiateSystemShutdownEx(
                    "", "", 0, true, true,
                    AdvApi32.ShtdnReason.MAJOR_OTHER |
                    AdvApi32.ShtdnReason.MINOR_ENVIRONMENT |
                    AdvApi32.ShtdnReason.FLAG_PLANNED
                );
            }
        }

        public static void AcquireSystemPrivilege(string name)
        {
            AdvApi32.TOKEN_PRIVILEGES tkp;
            IntPtr token;

            tkp.Privileges = new AdvApi32.LUID_AND_ATTRIBUTES[1];
            AdvApi32.LookupPrivilegeValue(
                IntPtr.Zero,
                name,
                out tkp.Privileges[0].Luid
            );

            tkp.PrivilegeCount = 1;

            tkp.Privileges[0].Attributes = (uint)AdvApi32.Se_Privilege.ENABLED;

            if (!AdvApi32.OpenProcessToken(
                    Process.GetCurrentProcess().Handle,
                    (uint)(AdvApi32.Token.ADJUST_PRIVILEGES |
                           AdvApi32.Token.QUERY),
                    out token))
            {
                Win32Error.Set("OpenProcessToken");
                throw new Exception(Win32Error.GetFullErrMsg());
            }

            if (!AdvApi32.AdjustTokenPrivileges(
                    token,
                    false,
                    ref tkp,
                    0,
                    IntPtr.Zero,
                    IntPtr.Zero))
            {
                Win32Error.Set("AdjustTokenPrivileges");
                throw new Exception(Win32Error.GetFullErrMsg());
            }
        }

        public static void InstallCertificate(string cerPath)
        {
            X509Certificate2 cert = new X509Certificate2(cerPath);

            X509Store store = new X509Store(
                StoreName.TrustedPublisher,
                StoreLocation.LocalMachine
            );

            Trace.WriteLine(
                "Installing cerificate: \'" + Path.GetFileName(cerPath) + "\'"
            );

            store.Open(OpenFlags.ReadWrite);
            store.Add(cert);
            store.Close();

            Trace.WriteLine("Certificate installed");
        }

        public static int BitIdxFromFlag(uint flag)
        {
            if (flag == 0)
            {
                throw new Exception("\'flag\' is empty");
            }
            else if ((flag & (flag - 1)) != 0)
            // If this is true, 'flag' is not a power of 2,
            // and hence, has more than one bit set
            {
                throw new Exception("\'flag\' has more than one bits set");
            }

            return (int)Math.Log((double)flag, 2.0);
        }

        public enum ExpandedServiceStartMode : uint {
            // Contains service start modes for drivers and user services
            Boot        = 0,
            System      = 1,
            Automatic   = 2,
            Manual      = 3, //User Services
            Demand      = 3, //Drivers
            Disabled    = 4,
        }

        public static bool ChangeServiceStartMode(
            string serviceName,
            ExpandedServiceStartMode mode)
        {
            Trace.WriteLine(
                "Changing Start Mode of service: \'" + serviceName + "\'"
            );

            IntPtr scManagerHandle = AdvApi32.OpenSCManager(
                null,
                null,
                AdvApi32.SC_MANAGER_ALL_ACCESS
            );

            if (scManagerHandle == IntPtr.Zero)
            {
                Trace.WriteLine("Open Service Manager Error");
                return false;
            }

            IntPtr serviceHandle = AdvApi32.OpenService(
                scManagerHandle,
                serviceName,
                AdvApi32.SERVICE_QUERY_CONFIG |
                    AdvApi32.SERVICE_CHANGE_CONFIG
            );

            if (serviceHandle == IntPtr.Zero)
            {
                Trace.WriteLine("Open Service Error");
                return false;
            }

            if (!AdvApi32.ChangeServiceConfig(
                    serviceHandle,
                    AdvApi32.SERVICE_NO_CHANGE,
                    (uint)mode,
                    AdvApi32.SERVICE_NO_CHANGE,
                    null,
                    null,
                    IntPtr.Zero,
                    null,
                    null,
                    null,
                    null))
            {
                Win32Error.Set("ChangeServiceConfig");
                Trace.WriteLine(Win32Error.GetFullErrMsg());
                return false;
            }

            AdvApi32.CloseServiceHandle(serviceHandle);
            AdvApi32.CloseServiceHandle(scManagerHandle);

            Trace.WriteLine(
                "Start Mode successfully changed to: \'" +
                mode.ToString() + "\'"
            );

            return true;
        }


        public static void EnsureBootStartServicesStartAtBoot()
        // This is a function which at first glance appears pointless
        // It runs through all of our services registry entries, and
        // if it finds they are boot start, it changes their start mode
        // to be boot start.
        // The Reason:  If we move xenbus to be non-boot start,
        // then reinstall the same version of xenbus, it will become boot
        // start.  But other boot start drivers hanging off it seem to become
        // forgotten by Windows.  This function reminds Windows about them.<commit_msg>CP-14538:  Ensure drivers set to bootstart start at boot time<commit_after>﻿using PInvokeWrap;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Microsoft.Win32;

namespace HelperFunctions
{
    public static class Helpers
    {
        public const string HKLM = @"HKEY_LOCAL_MACHINE\";
        public const string REGISTRY_SERVICES_KEY =
            @"SYSTEM\CurrentControlSet\Services\";

        public static void Reboot()
        {
            Trace.WriteLine("OK - shutting down");
            AcquireSystemPrivilege(AdvApi32.SE_SHUTDOWN_NAME);

            if (WinVersion.GetMajorVersion() >= 5 &&
                WinVersion.GetMajorVersion() < 6)
            {
                User32.ExitWindowsEx(
                    User32.ExitFlags.EWX_REBOOT |
                    User32.ExitFlags.EWX_FORCE,
                    0
                );
            }
            else
            {
                AdvApi32.InitiateSystemShutdownEx(
                    "", "", 0, true, true,
                    AdvApi32.ShtdnReason.MAJOR_OTHER |
                    AdvApi32.ShtdnReason.MINOR_ENVIRONMENT |
                    AdvApi32.ShtdnReason.FLAG_PLANNED
                );
            }
        }

        public static void AcquireSystemPrivilege(string name)
        {
            AdvApi32.TOKEN_PRIVILEGES tkp;
            IntPtr token;

            tkp.Privileges = new AdvApi32.LUID_AND_ATTRIBUTES[1];
            AdvApi32.LookupPrivilegeValue(
                IntPtr.Zero,
                name,
                out tkp.Privileges[0].Luid
            );

            tkp.PrivilegeCount = 1;

            tkp.Privileges[0].Attributes = (uint)AdvApi32.Se_Privilege.ENABLED;

            if (!AdvApi32.OpenProcessToken(
                    Process.GetCurrentProcess().Handle,
                    (uint)(AdvApi32.Token.ADJUST_PRIVILEGES |
                           AdvApi32.Token.QUERY),
                    out token))
            {
                Win32Error.Set("OpenProcessToken");
                throw new Exception(Win32Error.GetFullErrMsg());
            }

            if (!AdvApi32.AdjustTokenPrivileges(
                    token,
                    false,
                    ref tkp,
                    0,
                    IntPtr.Zero,
                    IntPtr.Zero))
            {
                Win32Error.Set("AdjustTokenPrivileges");
                throw new Exception(Win32Error.GetFullErrMsg());
            }
        }

        public static void InstallCertificate(string cerPath)
        {
            X509Certificate2 cert = new X509Certificate2(cerPath);

            X509Store store = new X509Store(
                StoreName.TrustedPublisher,
                StoreLocation.LocalMachine
            );

            Trace.WriteLine(
                "Installing cerificate: \'" + Path.GetFileName(cerPath) + "\'"
            );

            store.Open(OpenFlags.ReadWrite);
            store.Add(cert);
            store.Close();

            Trace.WriteLine("Certificate installed");
        }

        public static int BitIdxFromFlag(uint flag)
        {
            if (flag == 0)
            {
                throw new Exception("\'flag\' is empty");
            }
            else if ((flag & (flag - 1)) != 0)
            // If this is true, 'flag' is not a power of 2,
            // and hence, has more than one bit set
            {
                throw new Exception("\'flag\' has more than one bits set");
            }

            return (int)Math.Log((double)flag, 2.0);
        }

        public enum ExpandedServiceStartMode : uint {
            // Contains service start modes for drivers and user services
            Boot        = 0,
            System      = 1,
            Automatic   = 2,
            Manual      = 3, //User Services
            Demand      = 3, //Drivers
            Disabled    = 4,
        }

        public static bool ChangeServiceStartMode(
            string serviceName,
            ExpandedServiceStartMode mode)
        {
            Trace.WriteLine(
                "Changing Start Mode of service: \'" + serviceName + "\'"
            );

            IntPtr scManagerHandle = AdvApi32.OpenSCManager(
                null,
                null,
                AdvApi32.SC_MANAGER_ALL_ACCESS
            );

            if (scManagerHandle == IntPtr.Zero)
            {
                Trace.WriteLine("Open Service Manager Error");
                return false;
            }

            IntPtr serviceHandle = AdvApi32.OpenService(
                scManagerHandle,
                serviceName,
                AdvApi32.SERVICE_QUERY_CONFIG |
                    AdvApi32.SERVICE_CHANGE_CONFIG
            );

            if (serviceHandle == IntPtr.Zero)
            {
                Trace.WriteLine("Open Service Error");
                return false;
            }

            if (!AdvApi32.ChangeServiceConfig(
                    serviceHandle,
                    AdvApi32.SERVICE_NO_CHANGE,
                    (uint)mode,
                    AdvApi32.SERVICE_NO_CHANGE,
                    null,
                    null,
                    IntPtr.Zero,
                    null,
                    null,
                    null,
                    null))
            {
                Win32Error.Set("ChangeServiceConfig");
                Trace.WriteLine(Win32Error.GetFullErrMsg());
                return false;
            }

            AdvApi32.CloseServiceHandle(serviceHandle);
            AdvApi32.CloseServiceHandle(scManagerHandle);

            Trace.WriteLine(
                "Start Mode successfully changed to: \'" +
                mode.ToString() + "\'"
            );

            return true;
        }

        public static void EnsureBootStartServicesStartAtBoot()
        // This is a function which at first glance appears pointless
        // It runs through all of our services registry entries, and
        // if it finds they are boot start, it changes their start mode
        // to be boot start.
        // The Reason:  If we move xenbus to be non-boot start,
        // then reinstall the same version of xenbus, it will become boot
        // start.  But other boot start drivers hanging off it seem to become
        // forgotten by Windows.  This function reminds Windows about them.
{'fraction_non_alphanumeric': 0.07631111454390979, 'fraction_numerical': 0.016451687649648567, 'mean_word_length': 1.2880367556105319, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2244443', 'n_tokens_mistral': 3447, 'n_tokens_neox': 3136, 'n_words': 734}