Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
PlatformInvokes.cs680 linesDownload Raw Back to utils
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Diagnostics.CodeAnalysis;5using System.Runtime.InteropServices;6 7using Microsoft.Win32.SafeHandles;8 9namespace System.Management.Automation10{11    internal static class PlatformInvokes12    {13        [StructLayout(LayoutKind.Sequential)]14        internal sealed class FILETIME15        {16            internal uint dwLowDateTime;17            internal uint dwHighDateTime;18 19            internal FILETIME()20            {21                dwLowDateTime = 0;22                dwHighDateTime = 0;23            }24 25            internal FILETIME(long fileTime)26            {27                dwLowDateTime = (uint)fileTime;28                dwHighDateTime = (uint)(fileTime >> 32);29            }30 31            public long ToTicks()32            {33                return ((long)dwHighDateTime << 32) + dwLowDateTime;34            }35        }36 37        [Flags]38        // dwDesiredAccess of CreateFile39        internal enum FileDesiredAccess : uint40        {41            GenericRead = 0x80000000,42            GenericWrite = 0x40000000,43            GenericExecute = 0x20000000,44            GenericAll = 0x10000000,45        }46 47        [Flags]48        // dwShareMode of CreateFile49        internal enum FileShareMode : uint50        {51            None = 0x00000000,52            Read = 0x00000001,53            Write = 0x00000002,54            Delete = 0x00000004,55        }56 57        // dwCreationDisposition of CreateFile58        internal enum FileCreationDisposition : uint59        {60            New = 1,61            CreateAlways = 2,62            OpenExisting = 3,63            OpenAlways = 4,64            TruncateExisting = 5,65        }66 67        [Flags]68        // dwFlagsAndAttributes69        internal enum FileAttributes : uint70        {71            ReadOnly = 0x00000001,72            Hidden = 0x00000002,73            System = 0x00000004,74            Directory = 0x00000010,75            Archive = 0x00000020,76            Normal = 0x00000080,77            Temporary = 0x00000100,78            Offline = 0x00001000,79            NotContentIndexed = 0x00002000,80            Encrypted = 0x00004000,81            Write_Through = 0x80000000,82            Overlapped = 0x40000000,83            NoBuffering = 0x20000000,84            RandomAccess = 0x10000000,85            SequentialScan = 0x08000000,86            DeleteOnClose = 0x04000000,87            BackupSemantics = 0x02000000,88            PosixSemantics = 0x01000000,89            OpenReparsePoint = 0x00200000,90            OpenNoRecall = 0x00100000,91            SessionAware = 0x0080000092        }93 94        [StructLayout(LayoutKind.Sequential)]95        internal sealed class SecurityAttributes96        {97            internal int nLength;98            internal SafeLocalMemHandle lpSecurityDescriptor;99            internal bool bInheritHandle;100 101            internal SecurityAttributes()102            {103                this.nLength = 12;104                this.bInheritHandle = true;105                this.lpSecurityDescriptor = new SafeLocalMemHandle(IntPtr.Zero, true);106            }107        }108 109        internal sealed class SafeLocalMemHandle : SafeHandleZeroOrMinusOneIsInvalid110        {111            // Methods112            internal SafeLocalMemHandle()113                : base(true)114            {115            }116 117            internal SafeLocalMemHandle(IntPtr existingHandle, bool ownsHandle)118                : base(ownsHandle)119            {120                base.SetHandle(existingHandle);121            }122 123            [DllImport(PinvokeDllNames.LocalFreeDllName)]124            private static extern IntPtr LocalFree(IntPtr hMem);125 126            protected override bool ReleaseHandle()127            {128                return (LocalFree(base.handle) == IntPtr.Zero);129            }130        }131 132        /// <summary>133        /// Creates or opens a file, file stream, directory, physical disk, volume, console buffer,134        /// tape drive, communications resource, mailslot, or named pipe. The function returns a135        /// handle that can be used to access the object.136        /// </summary>137        /// <param name="lpFileName">138        /// The name of the object to be created or opened.139        /// In the ANSI version of this function, the name is limited to MAX_PATH characters.140        /// To extend this limit to 32,767 wide characters, call the Unicode version of the141        /// function and prepend "\\?\" to the path. For more information, see Naming a File.142        /// For information on special device names, see Defining an MS-DOS Device Name.143        /// To specify a COM port number greater than 9, use the following syntax: "\\.\COM10".144        /// This syntax works for all port numbers and hardware that allows COM port numbers to be specified.145        /// To create a file stream, specify the name of the file, a colon, and then the name of the146        /// stream. For more information, see File Streams.147        /// </param>148        /// <param name="dwDesiredAccess">149        /// The access to the object, which can be read, write, or both.150        /// You cannot request an access mode that conflicts with the sharing mode that is151        /// specified in an open request that has an open handle.152        /// If this parameter is zero (0), the application can query file and device attributes153        /// without accessing a device. This is useful for an application to determine the size154        /// of a floppy disk drive and the formats it supports without requiring a floppy in a drive.155        /// It can also be used to test for the existence of a file or directory without opening156        /// them for read or write access.157        /// See the "CreateFile desired access" below.158        /// </param>159        /// <param name="dwShareMode">160        /// The sharing mode of an object, which can be read, write, both, or none.161        /// You cannot request a sharing mode that conflicts with the access mode that is specified162        /// in an open request that has an open handle, because that would result in the following163        /// sharing violation: ERROR_SHARING_VIOLATION.164        /// If this parameter is zero (0) and CreateFile succeeds, the object cannot be shared165        /// and cannot be opened again until the handle is closed. For more information, see the166        /// Remarks section of this topic.167        /// The sharing options remain in effect until you close the handle to an object.168        /// To enable a process to share an object while another process has the object open,169        /// use a combination of one or more of the following values to specify the access mode170        /// they can request to open the object.171        /// </param>172        /// <param name="lpSecurityAttributes">173        /// A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not the returned174        /// handle can be inherited by child processes.175        /// If lpSecurityAttributes is NULL, the handle cannot be inherited.176        /// The lpSecurityDescriptor member of the structure specifies a security descriptor177        /// for an object. If lpSecurityAttributes is NULL, the object gets a default security descriptor.178        /// The access control lists (ACL) in the default security descriptor for a file or directory179        /// are inherited from its parent directory.180        /// The target file system must support security on files and directories for this parameter to181        /// have an effect on them, which is indicated when GetVolumeInformation returns FS_PERSISTENT_ACLS.182        /// CreateFile ignores lpSecurityDescriptor when opening an existing file, but continues to183        /// use the other structure members.184        /// </param>185        /// <param name="dwCreationDisposition">186        /// An action to take on files that exist and do not exist.187        /// See "CreateFile creation disposition" below188        /// </param>189        /// <param name="dwFlagsAndAttributes">190        /// The file attributes and flags.191        /// This parameter can include any combination of the file attributes.192        /// All other file attributes override FILE_ATTRIBUTE_NORMAL.193        /// When CreateFile opens a file, it combines the file flags with existing194        /// file attributes, and ignores any supplied file attributes.195        /// </param>196        /// <param name="hTemplateFile">197        /// A handle to a template file with the GENERIC_READ access right.198        /// The template file supplies file attributes and extended attributes for the file that is199        /// being created. This parameter can be NULL.200        /// When opening an existing file, CreateFile ignores the template file.201        /// When opening a new EFS-encrypted file, the file inherits the DACL from its parent directory.202        /// </param>203        /// <returns>204        /// If the function succeeds, the return value is an open handle to a specified file.205        /// If a specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS206        /// or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS, even when the207        /// function succeeds. If a file does not exist before the call, GetLastError returns zero (0).208        /// If the function fails, the return value is INVALID_HANDLE_VALUE.209        /// To get extended error information, call GetLastError.210        /// </returns>211        [DllImport(PinvokeDllNames.CreateFileDllName, SetLastError = true, CharSet = CharSet.Unicode)]212        internal static extern IntPtr CreateFile(213            string lpFileName,214            FileDesiredAccess dwDesiredAccess,215            FileShareMode dwShareMode,216            IntPtr lpSecurityAttributes,217            FileCreationDisposition dwCreationDisposition,218            FileAttributes dwFlagsAndAttributes,219            IntPtr hTemplateFile);220 221        /// <summary>222        /// Closes an open object handle.223        /// </summary>224        /// <param name="handle">225        /// A valid handle to an open object.226        /// </param>227        /// <returns>228        /// If the function succeeds, the return value is nonzero.229        /// If the function fails, the return value is zero. To get extended error information,230        /// call GetLastError.231        /// If the application is running under a debugger, the function will throw an exception232        /// if it receives either a handle value that is not valid or a pseudo-handle value.233        /// This can happen if you close a handle twice, or if you call CloseHandle on a handle234        /// returned by the FindFirstFile function.235        /// </returns>236        [DllImport(PinvokeDllNames.CloseHandleDllName, SetLastError = true)]237        [return: MarshalAs(UnmanagedType.Bool)]238        internal static extern bool CloseHandle(IntPtr handle);239 240        [DllImport(PinvokeDllNames.DosDateTimeToFileTimeDllName, SetLastError = false)]241        [return: MarshalAs(UnmanagedType.Bool)]242        internal static extern bool DosDateTimeToFileTime(243            short wFatDate, // _In_   WORD244            short wFatTime, // _In_   WORD245            FILETIME lpFileTime); // _Out_ LPFILETIME246 247        [DllImport(PinvokeDllNames.LocalFileTimeToFileTimeDllName, SetLastError = false, CharSet = CharSet.Unicode)]248        [return: MarshalAs(UnmanagedType.Bool)]249        internal static extern bool LocalFileTimeToFileTime(250            FILETIME lpLocalFileTime, // _In_   const FILETIME *251            FILETIME lpFileTime); // _Out_ LPFILETIME252 253        [DllImport(PinvokeDllNames.SetFileTimeDllName, SetLastError = false, CharSet = CharSet.Unicode)]254        [return: MarshalAs(UnmanagedType.Bool)]255        internal static extern bool SetFileTime(256            IntPtr hFile, // _In_      HANDLE257            FILETIME lpCreationTime, // _In_opt_ const FILETIME *258            FILETIME lpLastAccessTime, // _In_opt_ const FILETIME *259            FILETIME lpLastWriteTime); // _In_opt_ const FILETIME *260 261        [DllImport(PinvokeDllNames.SetFileAttributesWDllName, SetLastError = false, CharSet = CharSet.Unicode)]262        [return: MarshalAs(UnmanagedType.Bool)]263        internal static extern bool SetFileAttributesW(264            [MarshalAs(UnmanagedType.LPWStr)] string lpFileName, // _In_ LPCTSTR265            FileAttributes dwFileAttributes); // _In_ DWORD266 267        /// <summary>268        /// Enable the privilege specified by the privilegeName. If the specified privilege is already enabled, return true269        /// with the oldPrivilegeState.PrivilegeCount set to 0. Otherwise, enable the specified privilege, and the old privilege270        /// state will be saved in oldPrivilegeState.271        /// </summary>272        /// <param name="privilegeName"></param>273        /// <param name="oldPrivilegeState"></param>274        /// <returns></returns>275        internal static bool EnableTokenPrivilege(string privilegeName, ref TOKEN_PRIVILEGE oldPrivilegeState)276        {277            bool success = false;278            TOKEN_PRIVILEGE newPrivilegeState = new TOKEN_PRIVILEGE();279 280            // Check if the caller has the specified privilege or not281            if (LookupPrivilegeValue(null, privilegeName, ref newPrivilegeState.Privilege.Luid))282            {283                // Get the pseudo handler of the current process284                IntPtr processHandler = GetCurrentProcess();285                if (processHandler != IntPtr.Zero)286                {287                    // Get the handler of the current process's access token288                    IntPtr tokenHandler = IntPtr.Zero;289                    if (OpenProcessToken(processHandler, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandler))290                    {291                        // Check if the specified privilege is already enabled292                        PRIVILEGE_SET requiredPrivilege = new PRIVILEGE_SET();293                        requiredPrivilege.Privilege.Luid = newPrivilegeState.Privilege.Luid;294                        requiredPrivilege.PrivilegeCount = 1;295                        // PRIVILEGE_SET_ALL_NECESSARY is defined as 1296                        requiredPrivilege.Control = 1;297                        bool privilegeEnabled = false;298 299                        if (PrivilegeCheck(tokenHandler, ref requiredPrivilege, out privilegeEnabled) && privilegeEnabled)300                        {301                            // The specified privilege is already enabled302                            oldPrivilegeState.PrivilegeCount = 0;303                            success = true;304                        }305                        else306                        {307                            // The specified privilege is not enabled yet. Enable it.308                            newPrivilegeState.PrivilegeCount = 1;309                            newPrivilegeState.Privilege.Attributes = SE_PRIVILEGE_ENABLED;310                            int bufferSize = Marshal.SizeOf<TOKEN_PRIVILEGE>();311                            int returnSize = 0;312 313                            // enable the specified privilege314                            if (AdjustTokenPrivileges(tokenHandler, false, ref newPrivilegeState, bufferSize, out oldPrivilegeState, ref returnSize))315                            {316                                // AdjustTokenPrivileges returns true does not mean all specified privileges have been successfully enabled317                                int retCode = Marshal.GetLastWin32Error();318                                if (retCode == ERROR_SUCCESS)319                                {320                                    success = true;321                                }322                                else if (retCode == 1300)323                                {324                                    // 1300 - Not all privileges referenced are assigned to the caller. This means the specified privilege is not325                                    // assigned to the current user. For example, suppose the role of current caller is "User", then privilege "SeRemoteShutdownPrivilege"326                                    // is not assigned to the role. In this case, we just return true and leave the call to "Win32Shutdown" to decide327                                    // whether the permission is granted or not.328                                    // Set oldPrivilegeState.PrivilegeCount to 0 to avoid the privilege restore later (PrivilegeCount - how many privileges are modified)329                                    oldPrivilegeState.PrivilegeCount = 0;330                                    success = true;331                                }332                            }333                        }334                    }335 336                    // Close the token handler and the process handler337                    if (tokenHandler != IntPtr.Zero)338                    {339                        CloseHandle(tokenHandler);340                    }341 342                    CloseHandle(processHandler);343                }344            }345 346            return success;347        }348 349        /// <summary>350        /// Restore the previous privilege state.351        /// </summary>352        /// <param name="privilegeName"></param>353        /// <param name="previousPrivilegeState"></param>354        /// <returns></returns>355        internal static bool RestoreTokenPrivilege(string privilegeName, ref TOKEN_PRIVILEGE previousPrivilegeState)356        {357            // The privilege was not changed, do not need to restore it.358            if (previousPrivilegeState.PrivilegeCount == 0)359            {360                return true;361            }362 363            bool success = false;364            TOKEN_PRIVILEGE newState = new TOKEN_PRIVILEGE();365 366            // Check if the caller has the specified privilege or not. If the caller has it, check the LUID specified in previousPrivilegeState367            // to see if the previousPrivilegeState is defined for the same privilege368            if (LookupPrivilegeValue(null, privilegeName, ref newState.Privilege.Luid) &&369                newState.Privilege.Luid.HighPart == previousPrivilegeState.Privilege.Luid.HighPart &&370                newState.Privilege.Luid.LowPart == previousPrivilegeState.Privilege.Luid.LowPart)371            {372                // Get the pseudo handler of the current process373                IntPtr processHandler = GetCurrentProcess();374                if (processHandler != IntPtr.Zero)375                {376                    // Get the handler of the current process's access token377                    IntPtr tokenHandler = IntPtr.Zero;378                    if (OpenProcessToken(processHandler, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandler))379                    {380                        int bufferSize = Marshal.SizeOf<TOKEN_PRIVILEGE>();381                        int returnSize = 0;382 383                        // restore the privilege state back to the previous privilege state384                        if (AdjustTokenPrivileges(tokenHandler, false, ref previousPrivilegeState, bufferSize, out newState, ref returnSize))385                        {386                            if (Marshal.GetLastWin32Error() == ERROR_SUCCESS)387                            {388                                success = true;389                            }390                        }391                    }392 393                    if (tokenHandler != IntPtr.Zero)394                    {395                        CloseHandle(tokenHandler);396                    }397 398                    CloseHandle(processHandler);399                }400            }401 402            return success;403        }404 405        /// <summary>406        /// The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent407        /// the specified privilege name.408        /// </summary>409        /// <param name="lpSystemName"></param>410        /// <param name="lpName"></param>411        /// <param name="lpLuid"></param>412        /// <returns></returns>413        [DllImport(PinvokeDllNames.LookupPrivilegeValueDllName, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]414        [return: MarshalAs(UnmanagedType.Bool)]415        internal static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref LUID lpLuid);416 417        /// <summary>418        /// The PrivilegeCheck function determines whether a specified privilege is enabled in an access token.419        /// </summary>420        /// <param name="tokenHandler"></param>421        /// <param name="requiredPrivileges"></param>422        /// <param name="pfResult"></param>423        /// <returns></returns>424        [DllImport(PinvokeDllNames.PrivilegeCheckDllName, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]425        [return: MarshalAs(UnmanagedType.Bool)]426        internal static extern bool PrivilegeCheck(IntPtr tokenHandler, ref PRIVILEGE_SET requiredPrivileges, out bool pfResult);427 428        /// <summary>429        /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in430        /// an access token requires TOKEN_ADJUST_PRIVILEGES access. The TOKEN_ADJUST_PRIVILEGES and TOKEN_QUERY accesses are gained when calling431        /// the OpenProcessToken function.432        /// </summary>433        /// <param name="tokenHandler"></param>434        /// <param name="disableAllPrivilege"></param>435        /// <param name="newPrivilegeState"></param>436        /// <param name="bufferLength"></param>437        /// <param name="previousPrivilegeState"></param>438        /// <param name="returnLength"></param>439        /// <returns></returns>440        [DllImport(PinvokeDllNames.AdjustTokenPrivilegesDllName, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]441        [return: MarshalAs(UnmanagedType.Bool)]442        internal static extern bool AdjustTokenPrivileges(IntPtr tokenHandler, bool disableAllPrivilege,443                                                          ref TOKEN_PRIVILEGE newPrivilegeState, int bufferLength,444                                                          out TOKEN_PRIVILEGE previousPrivilegeState,445                                                          ref int returnLength);446 447        [StructLayout(LayoutKind.Sequential)]448        internal struct TOKEN_PRIVILEGE449        {450            internal uint PrivilegeCount;451            internal LUID_AND_ATTRIBUTES Privilege;452        }453 454        [StructLayout(LayoutKind.Sequential)]455        internal struct LUID456        {457            internal uint LowPart;458            internal uint HighPart;459        }460 461        [StructLayout(LayoutKind.Sequential)]462        internal struct LUID_AND_ATTRIBUTES463        {464            internal LUID Luid;465            internal uint Attributes;466        }467 468        [StructLayout(LayoutKind.Sequential)]469        internal struct PRIVILEGE_SET470        {471            internal uint PrivilegeCount;472            internal uint Control;473            internal LUID_AND_ATTRIBUTES Privilege;474        }475 476        /// <summary>477        /// Get the pseudo handler of the current process.478        /// </summary>479        /// <returns></returns>480        [DllImport(PinvokeDllNames.GetCurrentProcessDllName)]481        internal static extern IntPtr GetCurrentProcess();482 483        /// <summary>484        /// Retrieves the current process token.485        /// This function exists just for backward compatibility. It is preferred to use the other override that takes 'SafeHandle' as parameter.486        /// </summary>487        /// <param name="processHandle">Process handle.</param>488        /// <param name="desiredAccess">Token access.</param>489        /// <param name="tokenHandle">Process token.</param>490        /// <returns>The current process token.</returns>491        [DllImport(PinvokeDllNames.OpenProcessTokenDllName, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]492        [return: MarshalAs(UnmanagedType.Bool)]493        internal static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);494 495        /// <summary>496        /// Required to enable or disable the privileges in an access token.497        /// </summary>498        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;499 500        /// <summary>501        /// Required to query an access token.502        /// </summary>503        internal const int TOKEN_QUERY = 0x00000008;504 505        /// <summary>506        /// Combines all possible access rights for a token.507        /// </summary>508        internal const int TOKEN_ALL_ACCESS = 0x001f01ff;509 510        internal const uint SE_PRIVILEGE_DISABLED = 0x00000000;511        internal const uint SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;512        internal const uint SE_PRIVILEGE_ENABLED = 0x00000002;513        internal const uint SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;514 515        internal const int ERROR_SUCCESS = 0x0;516 517        #region CreateProcess for SSH Remoting518 519#if !UNIX520 521        // Fields522        internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);523        internal static readonly UInt32 GENERIC_READ = 0x80000000;524        internal static readonly UInt32 GENERIC_WRITE = 0x40000000;525        internal static readonly UInt32 FILE_ATTRIBUTE_NORMAL = 0x80000000;526        internal static readonly UInt32 CREATE_ALWAYS = 2;527        internal static readonly UInt32 FILE_SHARE_WRITE = 0x00000002;528        internal static readonly UInt32 FILE_SHARE_READ = 0x00000001;529        internal static readonly UInt32 OF_READWRITE = 0x00000002;530        internal static readonly UInt32 OPEN_EXISTING = 3;531 532        [StructLayout(LayoutKind.Sequential)]533        internal sealed class PROCESS_INFORMATION534        {535            public IntPtr hProcess;536            public IntPtr hThread;537            public int dwProcessId;538            public int dwThreadId;539 540            public PROCESS_INFORMATION()541            {542                this.hProcess = IntPtr.Zero;543                this.hThread = IntPtr.Zero;544            }545 546            /// <summary>547            /// Dispose.548            /// </summary>549            public void Dispose()550            {551                Dispose(true);552            }553 554            /// <summary>555            /// Dispose.556            /// </summary>557            /// <param name="disposing"></param>558            private void Dispose(bool disposing)559            {560                if (disposing)561                {562                    if (this.hProcess != IntPtr.Zero)563                    {564                        CloseHandle(this.hProcess);565                        this.hProcess = IntPtr.Zero;566                    }567 568                    if (this.hThread != IntPtr.Zero)569                    {570                        CloseHandle(this.hThread);571                        this.hThread = IntPtr.Zero;572                    }573                }574            }575        }576 577        [StructLayout(LayoutKind.Sequential)]578        internal sealed class STARTUPINFO579        {580            public int cb;581            public IntPtr lpReserved;582            public IntPtr lpDesktop;583            public IntPtr lpTitle;584            public int dwX;585            public int dwY;586            public int dwXSize;587            public int dwYSize;588            public int dwXCountChars;589            public int dwYCountChars;590            public int dwFillAttribute;591            public int dwFlags;592            public short wShowWindow;593            public short cbReserved2;594            public IntPtr lpReserved2;595            public SafeFileHandle hStdInput;596            public SafeFileHandle hStdOutput;597            public SafeFileHandle hStdError;598 599            public STARTUPINFO()600            {601                this.lpReserved = IntPtr.Zero;602                this.lpDesktop = IntPtr.Zero;603                this.lpTitle = IntPtr.Zero;604                this.lpReserved2 = IntPtr.Zero;605                this.hStdInput = new SafeFileHandle(IntPtr.Zero, false);606                this.hStdOutput = new SafeFileHandle(IntPtr.Zero, false);607                this.hStdError = new SafeFileHandle(IntPtr.Zero, false);608                this.cb = Marshal.SizeOf(this);609            }610 611            public void Dispose(bool disposing)612            {613                if (disposing)614                {615                    if ((this.hStdInput != null) && !this.hStdInput.IsInvalid)616                    {617                        this.hStdInput.Dispose();618                        this.hStdInput = null;619                    }620 621                    if ((this.hStdOutput != null) && !this.hStdOutput.IsInvalid)622                    {623                        this.hStdOutput.Dispose();624                        this.hStdOutput = null;625                    }626 627                    if ((this.hStdError != null) && !this.hStdError.IsInvalid)628                    {629                        this.hStdError.Dispose();630                        this.hStdError = null;631                    }632                }633            }634 635            public void Dispose()636            {637                Dispose(true);638            }639        }640 641        [StructLayout(LayoutKind.Sequential)]642        internal sealed class SECURITY_ATTRIBUTES643        {644            public int nLength;645            public SafeLocalMemHandle lpSecurityDescriptor;646            public bool bInheritHandle;647 648            public SECURITY_ATTRIBUTES()649            {650                this.nLength = 12;651                this.bInheritHandle = true;652                this.lpSecurityDescriptor = new SafeLocalMemHandle(IntPtr.Zero, true);653            }654        }655 656        [DllImport(PinvokeDllNames.CreateProcessDllName, CharSet = CharSet.Unicode, SetLastError = true)]657        [return: MarshalAs(UnmanagedType.Bool)]658        internal static extern bool CreateProcess(659            [MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName,660            [MarshalAs(UnmanagedType.LPWStr)] string lpCommandLine,661            SECURITY_ATTRIBUTES lpProcessAttributes,662            SECURITY_ATTRIBUTES lpThreadAttributes,663            bool bInheritHandles,664            int dwCreationFlags,665            IntPtr lpEnvironment,666            [MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory,667            STARTUPINFO lpStartupInfo,668            PROCESS_INFORMATION lpProcessInformation);669 670        [DllImport(PinvokeDllNames.ResumeThreadDllName, CharSet = CharSet.Unicode, SetLastError = true)]671        public static extern uint ResumeThread(IntPtr threadHandle);672 673        internal static readonly uint RESUME_THREAD_FAILED = System.UInt32.MaxValue; // (DWORD)-1674 675#endif676 677        #endregion678    }679}680