示例#1
0
        public override void CopyFile(string sourceFullPath, string destFullPath, bool overwrite)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
            int errorCode = Interop.mincore.CopyFile(sourceFullPath, destFullPath, !overwrite);

            if (errorCode != Interop.mincore.Errors.ERROR_SUCCESS)
            {
                String fileName = destFullPath;

                if (errorCode != Interop.mincore.Errors.ERROR_FILE_EXISTS)
                {
                    // For a number of error codes (sharing violation, path
                    // not found, etc) we don't know if the problem was with
                    // the source or dest file.  Try reading the source file.
                    using (SafeFileHandle handle = Interop.mincore.UnsafeCreateFile(sourceFullPath, Win32FileStream.GENERIC_READ, FileShare.Read, ref secAttrs, FileMode.Open, 0, IntPtr.Zero))
                    {
                        if (handle.IsInvalid)
                        {
                            fileName = sourceFullPath;
                        }
                    }

                    if (errorCode == Interop.mincore.Errors.ERROR_ACCESS_DENIED)
                    {
                        if (DirectoryExists(destFullPath))
                        {
                            throw new IOException(SR.Format(SR.Arg_FileIsDirectory_Name, destFullPath), Interop.mincore.Errors.ERROR_ACCESS_DENIED);
                        }
                    }
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode, fileName);
            }
        }
        private static SafeMemoryMappedFileHandle CreateCore(
            FileStream fileStream, string mapName, HandleInheritability inheritability,
            MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity)
        {
            SafeFileHandle fileHandle = fileStream != null ? fileStream.SafeFileHandle : null;

            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability);


            SafeMemoryMappedFileHandle handle = fileHandle != null?
                                                Interop.CreateFileMapping(fileHandle, ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName) :
                                                    Interop.CreateFileMapping(INVALID_HANDLE_VALUE, ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName);

            int errorCode = Marshal.GetLastWin32Error();

            if (!handle.IsInvalid)
            {
                if (errorCode == Interop.mincore.Errors.ERROR_ALREADY_EXISTS)
                {
                    handle.Dispose();
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }
            }
            else // handle.IsInvalid
            {
                handle.Dispose();
                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            return(handle);
        }
        private static SafeMemoryMappedFileHandle CreateCore(
            SafeFileHandle fileHandle, string mapName, HandleInheritability inheritability,
            MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability);

            // split the long into two ints
            int capacityLow  = unchecked ((int)(capacity & 0x00000000FFFFFFFFL));
            int capacityHigh = unchecked ((int)(capacity >> 32));

            SafeMemoryMappedFileHandle handle = fileHandle != null?
                                                Interop.mincore.CreateFileMapping(fileHandle, ref secAttrs, GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName) :
                                                    Interop.mincore.CreateFileMapping(INVALID_HANDLE_VALUE, ref secAttrs, GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName);

            int errorCode = Marshal.GetLastWin32Error();

            if (!handle.IsInvalid)
            {
                if (errorCode == Interop.mincore.Errors.ERROR_ALREADY_EXISTS)
                {
                    handle.Dispose();
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }
            }
            else if (handle.IsInvalid)
            {
                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            return(handle);
        }
示例#4
0
 internal static SafeFileHandle UnsafeCreateFile(
     string lpFileName,
     int dwDesiredAccess,
     FileShare dwShareMode,
     ref Interop.mincore.SECURITY_ATTRIBUTES securityAttrs,
     FileMode dwCreationDisposition,
     int dwFlagsAndAttributes,
     IntPtr hTemplateFile)
 {
     return(CreateFile(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile));
 }
示例#5
0
 internal static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
 {
     Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
     if ((inheritability & HandleInheritability.Inheritable) != 0)
     {
         secAttrs                = new Interop.mincore.SECURITY_ATTRIBUTES();
         secAttrs.nLength        = (uint)Marshal.SizeOf(secAttrs);
         secAttrs.bInheritHandle = true;
     }
     return(secAttrs);
 }
 private unsafe static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
 {
     Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
     if ((inheritability & HandleInheritability.Inheritable) != 0)
     {
         secAttrs                = new Interop.mincore.SECURITY_ATTRIBUTES();
         secAttrs.nLength        = (uint)sizeof(Interop.mincore.SECURITY_ATTRIBUTES);
         secAttrs.bInheritHandle = Interop.BOOL.TRUE;
     }
     return(secAttrs);
 }
示例#7
0
        // Using synchronous Anonymous pipes for process input/output redirection means we would end up
        // wasting a worker threadpool thread per pipe instance. Overlapped pipe IO is desirable, since
        // it will take advantage of the NT IO completion port infrastructure. But we can't really use
        // Overlapped I/O for process input/output as it would break Console apps (managed Console class
        // methods such as WriteLine as well as native CRT functions like printf) which are making an
        // assumption that the console standard handles (obtained via GetStdHandle()) are opened
        // for synchronous I/O and hence they can work fine with ReadFile/WriteFile synchronously!
        private void CreatePipe(out SafeFileHandle parentHandle, out SafeFileHandle childHandle, bool parentInputs)
        {
            Interop.mincore.SECURITY_ATTRIBUTES securityAttributesParent = new Interop.mincore.SECURITY_ATTRIBUTES();
            securityAttributesParent.bInheritHandle = Interop.BOOL.TRUE;

            SafeFileHandle hTmp = null;

            try
            {
                if (parentInputs)
                {
                    CreatePipeWithSecurityAttributes(out childHandle, out hTmp, ref securityAttributesParent, 0);
                }
                else
                {
                    CreatePipeWithSecurityAttributes(out hTmp,
                                                     out childHandle,
                                                     ref securityAttributesParent,
                                                     0);
                }
                // Duplicate the parent handle to be non-inheritable so that the child process
                // doesn't have access. This is done for correctness sake, exact reason is unclear.
                // One potential theory is that child process can do something brain dead like
                // closing the parent end of the pipe and there by getting into a blocking situation
                // as parent will not be draining the pipe at the other end anymore.
                SafeProcessHandle currentProcHandle = Interop.mincore.GetCurrentProcess();
                if (!Interop.mincore.DuplicateHandle(currentProcHandle,
                                                     hTmp,
                                                     currentProcHandle,
                                                     out parentHandle,
                                                     0,
                                                     false,
                                                     Interop.mincore.HandleOptions.DUPLICATE_SAME_ACCESS))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                if (hTmp != null && !hTmp.IsInvalid)
                {
                    hTmp.Dispose();
                }
            }
        }
        private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize)
        {
            Debug.Assert(direction != PipeDirection.InOut, "Anonymous pipe direction shouldn't be InOut");
            Debug.Assert(bufferSize >= 0, "bufferSize is negative");

            bool           bSuccess;
            SafePipeHandle serverHandle;
            SafePipeHandle newServerHandle;

            // Create the two pipe handles that make up the anonymous pipe.
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability);
            if (direction == PipeDirection.In)
            {
                bSuccess = Interop.mincore.CreatePipe(out serverHandle, out _clientHandle, ref secAttrs, bufferSize);
            }
            else
            {
                bSuccess = Interop.mincore.CreatePipe(out _clientHandle, out serverHandle, ref secAttrs, bufferSize);
            }

            if (!bSuccess)
            {
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

            // Duplicate the server handle to make it not inheritable.  Note: We need to do this so that the child
            // process doesn't end up getting another copy of the server handle.  If it were to get a copy, the
            // OS wouldn't be able to inform the child that the server has closed its handle because it will see
            // that there is still one server handle that is open.
            bSuccess = Interop.mincore.DuplicateHandle(Interop.mincore.GetCurrentProcess(), serverHandle, Interop.mincore.GetCurrentProcess(),
                                                       out newServerHandle, 0, false, Interop.mincore.HandleOptions.DUPLICATE_SAME_ACCESS);

            if (!bSuccess)
            {
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

            // Close the inheritable server handle.
            serverHandle.Dispose();

            InitializeHandle(newServerHandle, false, false);

            State = PipeState.Connected;
        }
示例#9
0
        private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
                            PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize,
                            HandleInheritability inheritability)
        {
            Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty");
            Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction");
            Debug.Assert(inBufferSize >= 0, "inBufferSize is negative");
            Debug.Assert(outBufferSize >= 0, "outBufferSize is negative");
            Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid");
            Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range");

            string fullPipeName = Path.GetFullPath(@"\\.\pipe\" + pipeName);

            // Make sure the pipe name isn't one of our reserved names for anonymous pipes.
            if (String.Equals(fullPipeName, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentOutOfRangeException(nameof(pipeName), SR.ArgumentOutOfRange_AnonymousReserved);
            }


            int openMode = ((int)direction) |
                           (maxNumberOfServerInstances == 1 ? Interop.mincore.FileOperations.FILE_FLAG_FIRST_PIPE_INSTANCE : 0) |
                           (int)options;

            // We automatically set the ReadMode to match the TransmissionMode.
            int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1;

            // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254).
            if (maxNumberOfServerInstances == MaxAllowedServerInstances)
            {
                maxNumberOfServerInstances = 255;
            }

            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability);
            SafePipeHandle handle = Interop.mincore.CreateNamedPipe(fullPipeName, openMode, pipeModes,
                                                                    maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs);

            if (handle.IsInvalid)
            {
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

            InitializeHandle(handle, false, (options & PipeOptions.Asynchronous) != 0);
        }
示例#10
0
        private unsafe RegistryKey CreateSubKeyInternalCore(string subkey, bool writable, RegistryOptions registryOptions)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
            int disposition = 0;

            // By default, the new key will be writable.
            SafeRegistryHandle result = null;
            int ret = Interop.mincore.RegCreateKeyEx(_hkey,
                                                     subkey,
                                                     0,
                                                     null,
                                                     (int)registryOptions /* specifies if the key is volatile */,
                                                     (int)GetRegistryKeyRights(writable) | (int)_regView,
                                                     ref secAttrs,
                                                     out result,
                                                     out disposition);

            if (ret == 0 && !result.IsInvalid)
            {
                RegistryKey key = new RegistryKey(result, writable, false, _remoteKey, false, _regView);
                if (subkey.Length == 0)
                {
                    key._keyName = _keyName;
                }
                else
                {
                    key._keyName = _keyName + "\\" + subkey;
                }
                return(key);
            }
            else if (ret != 0)                             // syscall failed, ret is an error code.
            {
                Win32Error(ret, _keyName + "\\" + subkey); // Access denied?
            }

            Debug.Fail("Unexpected code path in RegistryKey::CreateSubKey");
            return(null);
        }
示例#11
0
        [System.Security.SecurityCritical]  // auto-generated
        internal static SafeFileHandle SafeCreateFile(
            String lpFileName,
            int dwDesiredAccess,
            System.IO.FileShare dwShareMode,
            ref Interop.mincore.SECURITY_ATTRIBUTES securityAttrs,
            FileMode dwCreationDisposition,
            int dwFlagsAndAttributes,
            IntPtr hTemplateFile)
        {
            SafeFileHandle handle = UnsafeCreateFile(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

            if (!handle.IsInvalid)
            {
                int fileType = Interop.mincore.GetFileType(handle);
                if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
                {
                    handle.Dispose();
                    throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
                }
            }

            return(handle);
        }
示例#12
0
    private static unsafe SafeFileHandle CreateFile(
        string lpFileName,
        int dwDesiredAccess,
        System.IO.FileShare dwShareMode,
        ref Interop.mincore.SECURITY_ATTRIBUTES securityAttrs,
        System.IO.FileMode dwCreationDisposition,
        int dwFlagsAndAttributes,
        IntPtr hTemplateFile)
    {
        Interop.mincore.CREATEFILE2_EXTENDED_PARAMETERS parameters;
        parameters.dwSize = (uint)Marshal.SizeOf <Interop.mincore.CREATEFILE2_EXTENDED_PARAMETERS>();

        parameters.dwFileAttributes   = (uint)dwFlagsAndAttributes & 0x0000FFFF;
        parameters.dwSecurityQosFlags = (uint)dwFlagsAndAttributes & 0x000F0000;
        parameters.dwFileFlags        = (uint)dwFlagsAndAttributes & 0xFFF00000;

        parameters.hTemplateFile = hTemplateFile;
        fixed(Interop.mincore.SECURITY_ATTRIBUTES *lpSecurityAttributes = &securityAttrs)
        {
            parameters.lpSecurityAttributes = (IntPtr)lpSecurityAttributes;
            return(Interop.mincore.CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ref parameters));
        }
    }
示例#13
0
        private static SafeFileHandle OpenHandle(string fullPath, bool asDirectory)
        {
            String root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath));

            if (root == fullPath && root[1] == Path.VolumeSeparatorChar)
            {
                // intentionally not fullpath, most upstack public APIs expose this as path.
                throw new ArgumentException(SR.Arg_PathIsVolume, "path");
            }

            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
            SafeFileHandle handle = Interop.mincore.SafeCreateFile(
                fullPath,
                (int)Interop.mincore.GenericOperations.GENERIC_WRITE,
                FileShare.ReadWrite | FileShare.Delete,
                ref secAttrs,
                FileMode.Open,
                asDirectory ? (int)Interop.mincore.FileOperations.FILE_FLAG_BACKUP_SEMANTICS : (int)FileOptions.None,
                IntPtr.Zero
                );

            if (handle.IsInvalid)
            {
                int errorCode = Marshal.GetLastWin32Error();

                // NT5 oddity - when trying to open "C:\" as a File,
                // we usually get ERROR_PATH_NOT_FOUND from the OS.  We should
                // probably be consistent w/ every other directory.
                if (!asDirectory && errorCode == Interop.mincore.Errors.ERROR_PATH_NOT_FOUND && fullPath.Equals(Directory.GetDirectoryRoot(fullPath)))
                {
                    errorCode = Interop.mincore.Errors.ERROR_ACCESS_DENIED;
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath);
            }
            return(handle);
        }
示例#14
0
        private static SafeMemoryMappedFileHandle CreateCore(
            FileStream fileStream, string mapName, HandleInheritability inheritability,
            MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity)
        {
            SafeFileHandle fileHandle = fileStream != null ? fileStream.SafeFileHandle : null;

            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability);

            // split the long into two ints
            int capacityLow  = unchecked ((int)(capacity & 0x00000000FFFFFFFFL));
            int capacityHigh = unchecked ((int)(capacity >> 32));

            SafeMemoryMappedFileHandle handle = fileHandle != null?
                                                Interop.mincore.CreateFileMapping(fileHandle, ref secAttrs, GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName) :
                                                    Interop.mincore.CreateFileMapping(INVALID_HANDLE_VALUE, ref secAttrs, GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName);

            int errorCode = Marshal.GetLastWin32Error();

            if (!handle.IsInvalid)
            {
                // If the object exists before the function call, the function
                // returns a handle to the existing object (with its current size,
                // not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
                if (errorCode == Interop.mincore.Errors.ERROR_ALREADY_EXISTS)
                {
                    handle.Dispose();
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }
            }
            else   // handle.IsInvalid
            {
                handle.Dispose();
                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            return(handle);
        }
示例#15
0
 internal static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
 {
     Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
     if ((inheritability & HandleInheritability.Inheritable) != 0)
     {
         secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
         secAttrs.nLength = (uint)Marshal.SizeOf(secAttrs);
         secAttrs.bInheritHandle = true;
     }
     return secAttrs;
 }
示例#16
0
        private static SafeMemoryMappedFileHandle CreateOrOpenCore(
            string mapName, HandleInheritability inheritability, MemoryMappedFileAccess access,
            MemoryMappedFileOptions options, long capacity)
        {
            /// Try to open the file if it exists -- this requires a bit more work. Loop until we can
            /// either create or open a memory mapped file up to a timeout. CreateFileMapping may fail
            /// if the file exists and we have non-null security attributes, in which case we need to
            /// use OpenFileMapping.  But, there exists a race condition because the memory mapped file
            /// may have closed between the two calls -- hence the loop.
            ///
            /// The retry/timeout logic increases the wait time each pass through the loop and times
            /// out in approximately 1.4 minutes. If after retrying, a MMF handle still hasn't been opened,
            /// throw an InvalidOperationException.

            Debug.Assert(access != MemoryMappedFileAccess.Write, "Callers requesting write access shouldn't try to create a mmf");

            SafeMemoryMappedFileHandle handle = null;

            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability);

            // split the long into two ints
            int capacityLow  = unchecked ((int)(capacity & 0x00000000FFFFFFFFL));
            int capacityHigh = unchecked ((int)(capacity >> 32));

            int waitRetries = 14;   //((2^13)-1)*10ms == approximately 1.4mins
            int waitSleep   = 0;

            // keep looping until we've exhausted retries or break as soon we get valid handle
            while (waitRetries > 0)
            {
                // try to create
                handle = Interop.mincore.CreateFileMapping(INVALID_HANDLE_VALUE, ref secAttrs,
                                                           GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName);

                if (!handle.IsInvalid)
                {
                    break;
                }
                else
                {
                    handle.Dispose();
                    int createErrorCode = Marshal.GetLastWin32Error();
                    if (createErrorCode != Interop.mincore.Errors.ERROR_ACCESS_DENIED)
                    {
                        throw Win32Marshal.GetExceptionForWin32Error(createErrorCode);
                    }
                }

                // try to open
                handle = Interop.mincore.OpenFileMapping(GetFileMapAccess(access), (inheritability &
                                                                                    HandleInheritability.Inheritable) != 0, mapName);

                // valid handle
                if (!handle.IsInvalid)
                {
                    break;
                }
                // didn't get valid handle; have to retry
                else
                {
                    handle.Dispose();
                    int openErrorCode = Marshal.GetLastWin32Error();
                    if (openErrorCode != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND)
                    {
                        throw Win32Marshal.GetExceptionForWin32Error(openErrorCode);
                    }

                    // increase wait time
                    --waitRetries;
                    if (waitSleep == 0)
                    {
                        waitSleep = 10;
                    }
                    else
                    {
                        ThreadSleep(waitSleep);
                        waitSleep *= 2;
                    }
                }
            }

            // finished retrying but couldn't create or open
            if (handle == null || handle.IsInvalid)
            {
                throw new InvalidOperationException(SR.InvalidOperation_CantCreateFileMapping);
            }

            return(handle);
        }
示例#17
0
        /// <summary>Starts the process using the supplied start info.</summary>
        /// <param name="startInfo">The start info with which to start the process.</param>
        private bool StartCore(ProcessStartInfo startInfo)
        {
            // See knowledge base article Q190351 for an explanation of the following code.  Noteworthy tricky points:
            //    * The handles are duplicated as non-inheritable before they are passed to CreateProcess so
            //      that the child process can not close them
            //    * CreateProcess allows you to redirect all or none of the standard IO handles, so we use
            //      GetStdHandle for the handles that are not being redirected

            StringBuilder commandLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments);

            Interop.mincore.STARTUPINFO         startupInfo     = new Interop.mincore.STARTUPINFO();
            Interop.mincore.PROCESS_INFORMATION processInfo     = new Interop.mincore.PROCESS_INFORMATION();
            Interop.mincore.SECURITY_ATTRIBUTES unused_SecAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
            SafeProcessHandle procSH   = new SafeProcessHandle();
            SafeThreadHandle  threadSH = new SafeThreadHandle();
            bool retVal;
            int  errorCode = 0;
            // handles used in parent process
            SafeFileHandle standardInputWritePipeHandle = null;
            SafeFileHandle standardOutputReadPipeHandle = null;
            SafeFileHandle standardErrorReadPipeHandle  = null;
            GCHandle       environmentHandle            = new GCHandle();

            lock (s_createProcessLock)
            {
                try
                {
                    // set up the streams
                    if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError)
                    {
                        if (startInfo.RedirectStandardInput)
                        {
                            CreatePipe(out standardInputWritePipeHandle, out startupInfo.hStdInput, true);
                        }
                        else
                        {
                            startupInfo.hStdInput = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_INPUT_HANDLE), false);
                        }

                        if (startInfo.RedirectStandardOutput)
                        {
                            CreatePipe(out standardOutputReadPipeHandle, out startupInfo.hStdOutput, false);
                        }
                        else
                        {
                            startupInfo.hStdOutput = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_OUTPUT_HANDLE), false);
                        }

                        if (startInfo.RedirectStandardError)
                        {
                            CreatePipe(out standardErrorReadPipeHandle, out startupInfo.hStdError, false);
                        }
                        else
                        {
                            startupInfo.hStdError = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_ERROR_HANDLE), false);
                        }

                        startupInfo.dwFlags = Interop.mincore.StartupInfoOptions.STARTF_USESTDHANDLES;
                    }

                    // set up the creation flags parameter
                    int creationFlags = 0;
                    if (startInfo.CreateNoWindow)
                    {
                        creationFlags |= Interop.mincore.StartupInfoOptions.CREATE_NO_WINDOW;
                    }

                    // set up the environment block parameter
                    IntPtr environmentPtr = (IntPtr)0;
                    if (startInfo._environmentVariables != null)
                    {
                        creationFlags |= Interop.mincore.StartupInfoOptions.CREATE_UNICODE_ENVIRONMENT;
                        byte[] environmentBytes = EnvironmentVariablesToByteArray(startInfo._environmentVariables);
                        environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned);
                        environmentPtr    = environmentHandle.AddrOfPinnedObject();
                    }
                    string workingDirectory = startInfo.WorkingDirectory;
                    if (workingDirectory == string.Empty)
                    {
                        workingDirectory = Directory.GetCurrentDirectory();
                    }

                    if (startInfo.UserName.Length != 0)
                    {
                        Interop.mincore.LogonFlags logonFlags = (Interop.mincore.LogonFlags) 0;
                        if (startInfo.LoadUserProfile)
                        {
                            logonFlags = Interop.mincore.LogonFlags.LOGON_WITH_PROFILE;
                        }


                        try { }
                        finally
                        {
                            retVal = Interop.mincore.CreateProcessWithLogonW(
                                startInfo.UserName,
                                startInfo.Domain,
                                startInfo.PasswordInClearText,
                                logonFlags,
                                null,                // we don't need this since all the info is in commandLine
                                commandLine,
                                creationFlags,
                                environmentPtr,
                                workingDirectory,
                                startupInfo,            // pointer to STARTUPINFO
                                processInfo             // pointer to PROCESS_INFORMATION
                                );
                            if (!retVal)
                            {
                                errorCode = Marshal.GetLastWin32Error();
                            }
                            if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE)
                            {
                                procSH.InitialSetHandle(processInfo.hProcess);
                            }
                            if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE)
                            {
                                threadSH.InitialSetHandle(processInfo.hThread);
                            }
                        }
                        if (!retVal)
                        {
                            if (errorCode == Interop.mincore.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.mincore.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH)
                            {
                                throw new Win32Exception(errorCode, SR.InvalidApplication);
                            }

                            throw new Win32Exception(errorCode);
                        }
                    }
                    else
                    {
                        try { }
                        finally
                        {
                            retVal = Interop.mincore.CreateProcess(
                                null,                // we don't need this since all the info is in commandLine
                                commandLine,         // pointer to the command line string
                                ref unused_SecAttrs, // address to process security attributes, we don't need to inherit the handle
                                ref unused_SecAttrs, // address to thread security attributes.
                                true,                // handle inheritance flag
                                creationFlags,       // creation flags
                                environmentPtr,      // pointer to new environment block
                                workingDirectory,    // pointer to current directory name
                                startupInfo,         // pointer to STARTUPINFO
                                processInfo          // pointer to PROCESS_INFORMATION
                                );
                            if (!retVal)
                            {
                                errorCode = Marshal.GetLastWin32Error();
                            }
                            if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE)
                            {
                                procSH.InitialSetHandle(processInfo.hProcess);
                            }
                            if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE)
                            {
                                threadSH.InitialSetHandle(processInfo.hThread);
                            }
                        }
                        if (!retVal)
                        {
                            if (errorCode == Interop.mincore.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.mincore.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH)
                            {
                                throw new Win32Exception(errorCode, SR.InvalidApplication);
                            }

                            throw new Win32Exception(errorCode);
                        }
                    }
                }
                finally
                {
                    // free environment block
                    if (environmentHandle.IsAllocated)
                    {
                        environmentHandle.Free();
                    }

                    startupInfo.Dispose();
                }
            }

            if (startInfo.RedirectStandardInput)
            {
                Encoding enc = GetEncoding((int)Interop.mincore.GetConsoleCP());
                _standardInput           = new StreamWriter(new FileStream(standardInputWritePipeHandle, FileAccess.Write, 4096, false), enc, 4096);
                _standardInput.AutoFlush = true;
            }
            if (startInfo.RedirectStandardOutput)
            {
                Encoding enc = startInfo.StandardOutputEncoding ?? GetEncoding((int)Interop.mincore.GetConsoleOutputCP());
                _standardOutput = new StreamReader(new FileStream(standardOutputReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096);
            }
            if (startInfo.RedirectStandardError)
            {
                Encoding enc = startInfo.StandardErrorEncoding ?? GetEncoding((int)Interop.mincore.GetConsoleOutputCP());
                _standardError = new StreamReader(new FileStream(standardErrorReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096);
            }

            bool ret = false;

            if (!procSH.IsInvalid)
            {
                SetProcessHandle(procSH);
                SetProcessId((int)processInfo.dwProcessId);
                threadSH.Dispose();
                ret = true;
            }

            return(ret);
        }
示例#18
0
        private static void CreatePipeWithSecurityAttributes(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, ref Interop.mincore.SECURITY_ATTRIBUTES lpPipeAttributes, int nSize)
        {
            bool ret = Interop.mincore.CreatePipe(out hReadPipe, out hWritePipe, ref lpPipeAttributes, nSize);

            if (!ret || hReadPipe.IsInvalid || hWritePipe.IsInvalid)
            {
                throw new Win32Exception();
            }
        }
示例#19
0
        private bool TryConnect(int timeout, CancellationToken cancellationToken)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(_inheritability);

            int _pipeFlags = (int)_pipeOptions;

            if (_impersonationLevel != TokenImpersonationLevel.None)
            {
                _pipeFlags |= Interop.mincore.SecurityOptions.SECURITY_SQOS_PRESENT;
                _pipeFlags |= (((int)_impersonationLevel - 1) << 16);
            }

            if (!Interop.mincore.WaitNamedPipe(_normalizedPipePath, timeout))
            {
                int errorCode = Marshal.GetLastWin32Error();

                // Server is not yet created
                if (errorCode == Interop.mincore.Errors.ERROR_FILE_NOT_FOUND)
                {
                    return(false);
                }

                // The timeout has expired.
                if (errorCode == Interop.mincore.Errors.ERROR_SUCCESS)
                {
                    if (cancellationToken.CanBeCanceled)
                    {
                        // It may not be real timeout.
                        return(false);
                    }
                    throw new TimeoutException();
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            // Pipe server should be free.  Let's try to connect to it.
            int access = 0;

            if ((PipeDirection.In & _direction) != 0)
            {
                access |= Interop.mincore.GenericOperations.GENERIC_READ;
            }
            if ((PipeDirection.Out & _direction) != 0)
            {
                access |= Interop.mincore.GenericOperations.GENERIC_WRITE;
            }
            SafePipeHandle handle = Interop.mincore.CreateNamedPipeClient(_normalizedPipePath,
                                                                          access,        // read and write access
                                                                          0,             // sharing: none
                                                                          ref secAttrs,  // security attributes
                                                                          FileMode.Open, // open existing
                                                                          _pipeFlags,    // impersonation flags
                                                                          IntPtr.Zero);  // template file: null

            if (handle.IsInvalid)
            {
                int errorCode = Marshal.GetLastWin32Error();

                // Handle the possible race condition of someone else connecting to the server
                // between our calls to WaitNamedPipe & CreateFile.
                if (errorCode == Interop.mincore.Errors.ERROR_PIPE_BUSY)
                {
                    return(false);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            // Success!
            InitializeHandle(handle, false, (_pipeOptions & PipeOptions.Asynchronous) != 0);
            State = PipeState.Connected;

            return(true);
        }
示例#20
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        private unsafe static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
            if ((share & FileShare.Inheritable) != 0)
            {
                secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (uint)sizeof(Interop.mincore.SECURITY_ATTRIBUTES);

                secAttrs.bInheritHandle = Interop.BOOL.TRUE;
            }
            return secAttrs;
        }
示例#21
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        private static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
            if ((share & FileShare.Inheritable) != 0)
            {
                secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (uint)Marshal.SizeOf(secAttrs);

                secAttrs.bInheritHandle = true;
            }
            return secAttrs;
        }
示例#22
0
        /// <summary>Starts the process using the supplied start info.</summary>
        /// <param name="startInfo">The start info with which to start the process.</param>
        private bool StartCore(ProcessStartInfo startInfo)
        {
            // See knowledge base article Q190351 for an explanation of the following code.  Noteworthy tricky points:
            //    * The handles are duplicated as non-inheritable before they are passed to CreateProcess so
            //      that the child process can not close them
            //    * CreateProcess allows you to redirect all or none of the standard IO handles, so we use
            //      GetStdHandle for the handles that are not being redirected

            StringBuilder commandLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments);

            Interop.mincore.STARTUPINFO startupInfo = new Interop.mincore.STARTUPINFO();
            Interop.mincore.PROCESS_INFORMATION processInfo = new Interop.mincore.PROCESS_INFORMATION();
            Interop.mincore.SECURITY_ATTRIBUTES unused_SecAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
            SafeProcessHandle procSH = new SafeProcessHandle();
            SafeThreadHandle threadSH = new SafeThreadHandle();
            bool retVal;
            int errorCode = 0;
            // handles used in parent process
            SafeFileHandle standardInputWritePipeHandle = null;
            SafeFileHandle standardOutputReadPipeHandle = null;
            SafeFileHandle standardErrorReadPipeHandle = null;
            GCHandle environmentHandle = new GCHandle();
            lock (s_createProcessLock)
            {
                try
                {
                    // set up the streams
                    if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError)
                    {
                        if (startInfo.RedirectStandardInput)
                        {
                            CreatePipe(out standardInputWritePipeHandle, out startupInfo.hStdInput, true);
                        }
                        else
                        {
                            startupInfo.hStdInput = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_INPUT_HANDLE), false);
                        }

                        if (startInfo.RedirectStandardOutput)
                        {
                            CreatePipe(out standardOutputReadPipeHandle, out startupInfo.hStdOutput, false);
                        }
                        else
                        {
                            startupInfo.hStdOutput = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_OUTPUT_HANDLE), false);
                        }

                        if (startInfo.RedirectStandardError)
                        {
                            CreatePipe(out standardErrorReadPipeHandle, out startupInfo.hStdError, false);
                        }
                        else
                        {
                            startupInfo.hStdError = new SafeFileHandle(Interop.mincore.GetStdHandle(Interop.mincore.HandleTypes.STD_ERROR_HANDLE), false);
                        }

                        startupInfo.dwFlags = Interop.mincore.StartupInfoOptions.STARTF_USESTDHANDLES;
                    }

                    // set up the creation flags paramater
                    int creationFlags = 0;
                    if (startInfo.CreateNoWindow) creationFlags |= Interop.mincore.StartupInfoOptions.CREATE_NO_WINDOW;

                    // set up the environment block parameter
                    IntPtr environmentPtr = (IntPtr)0;
                    if (startInfo._environmentVariables != null)
                    {
                        creationFlags |= Interop.mincore.StartupInfoOptions.CREATE_UNICODE_ENVIRONMENT;
                        byte[] environmentBytes = EnvironmentVariablesToByteArray(startInfo._environmentVariables);
                        environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned);
                        environmentPtr = environmentHandle.AddrOfPinnedObject();
                    }
                    string workingDirectory = startInfo.WorkingDirectory;
                    if (workingDirectory == string.Empty)
                        workingDirectory = Directory.GetCurrentDirectory();

                    if (startInfo.UserName.Length != 0)
                    {
                        Interop.mincore.LogonFlags logonFlags = (Interop.mincore.LogonFlags)0;
                        if (startInfo.LoadUserProfile)
                        {
                            logonFlags = Interop.mincore.LogonFlags.LOGON_WITH_PROFILE;
                        }


                        try { }
                        finally
                        {
                            retVal = Interop.mincore.CreateProcessWithLogonW(
                                    startInfo.UserName,
                                    startInfo.Domain,
                                    startInfo.PasswordInClearText,
                                    logonFlags,
                                    null,            // we don't need this since all the info is in commandLine
                                    commandLine,
                                    creationFlags,
                                    environmentPtr,
                                    workingDirectory,
                                    startupInfo,        // pointer to STARTUPINFO
                                    processInfo         // pointer to PROCESS_INFORMATION
                                );
                            if (!retVal)
                                errorCode = Marshal.GetLastWin32Error();
                            if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE)
                                procSH.InitialSetHandle(processInfo.hProcess);
                            if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE)
                                threadSH.InitialSetHandle(processInfo.hThread);
                        }
                        if (!retVal)
                        {
                            if (errorCode == Interop.mincore.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.mincore.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH)
                                throw new Win32Exception(errorCode, SR.InvalidApplication);

                            throw new Win32Exception(errorCode);
                        }
                    }
                    else
                    {
                        try { }
                        finally
                        {
                            retVal = Interop.mincore.CreateProcess(
                                    null,                // we don't need this since all the info is in commandLine
                                    commandLine,         // pointer to the command line string
                                    ref unused_SecAttrs, // address to process security attributes, we don't need to inheriat the handle
                                    ref unused_SecAttrs, // address to thread security attributes.
                                    true,                // handle inheritance flag
                                    creationFlags,       // creation flags
                                    environmentPtr,      // pointer to new environment block
                                    workingDirectory,    // pointer to current directory name
                                    startupInfo,         // pointer to STARTUPINFO
                                    processInfo      // pointer to PROCESS_INFORMATION
                                );
                            if (!retVal)
                                errorCode = Marshal.GetLastWin32Error();
                            if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE)
                                procSH.InitialSetHandle(processInfo.hProcess);
                            if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE)
                                threadSH.InitialSetHandle(processInfo.hThread);
                        }
                        if (!retVal)
                        {
                            if (errorCode == Interop.mincore.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.mincore.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH)
                                throw new Win32Exception(errorCode, SR.InvalidApplication);

                            throw new Win32Exception(errorCode);
                        }
                    }
                }
                finally
                {
                    // free environment block
                    if (environmentHandle.IsAllocated)
                    {
                        environmentHandle.Free();
                    }

                    startupInfo.Dispose();
                }
            }

            if (startInfo.RedirectStandardInput)
            {
                Encoding enc = GetEncoding((int)Interop.mincore.GetConsoleCP());
                _standardInput = new StreamWriter(new FileStream(standardInputWritePipeHandle, FileAccess.Write, 4096, false), enc, 4096);
                _standardInput.AutoFlush = true;
            }
            if (startInfo.RedirectStandardOutput)
            {
                Encoding enc = startInfo.StandardOutputEncoding ?? GetEncoding((int)Interop.mincore.GetConsoleOutputCP());
                _standardOutput = new StreamReader(new FileStream(standardOutputReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096);
            }
            if (startInfo.RedirectStandardError)
            {
                Encoding enc = startInfo.StandardErrorEncoding ?? GetEncoding((int)Interop.mincore.GetConsoleOutputCP());
                _standardError = new StreamReader(new FileStream(standardErrorReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096);
            }

            bool ret = false;
            if (!procSH.IsInvalid)
            {
                SetProcessHandle(procSH);
                SetProcessId((int)processInfo.dwProcessId);
                threadSH.Dispose();
                ret = true;
            }

            return ret;
        }
示例#23
0
        // Using synchronous Anonymous pipes for process input/output redirection means we would end up 
        // wasting a worker threadpool thread per pipe instance. Overlapped pipe IO is desirable, since 
        // it will take advantage of the NT IO completion port infrastructure. But we can't really use 
        // Overlapped I/O for process input/output as it would break Console apps (managed Console class 
        // methods such as WriteLine as well as native CRT functions like printf) which are making an
        // assumption that the console standard handles (obtained via GetStdHandle()) are opened
        // for synchronous I/O and hence they can work fine with ReadFile/WriteFile synchronously!
        private void CreatePipe(out SafeFileHandle parentHandle, out SafeFileHandle childHandle, bool parentInputs)
        {
            Interop.mincore.SECURITY_ATTRIBUTES securityAttributesParent = new Interop.mincore.SECURITY_ATTRIBUTES();
            securityAttributesParent.bInheritHandle = true;

            SafeFileHandle hTmp = null;
            try
            {
                if (parentInputs)
                {
                    CreatePipeWithSecurityAttributes(out childHandle, out hTmp, ref securityAttributesParent, 0);
                }
                else
                {
                    CreatePipeWithSecurityAttributes(out hTmp,
                                                          out childHandle,
                                                          ref securityAttributesParent,
                                                          0);
                }
                // Duplicate the parent handle to be non-inheritable so that the child process 
                // doesn't have access. This is done for correctness sake, exact reason is unclear.
                // One potential theory is that child process can do something brain dead like 
                // closing the parent end of the pipe and there by getting into a blocking situation
                // as parent will not be draining the pipe at the other end anymore. 
                SafeProcessHandle currentProcHandle = Interop.mincore.GetCurrentProcess();
                if (!Interop.mincore.DuplicateHandle(currentProcHandle,
                                                     hTmp,
                                                     currentProcHandle,
                                                     out parentHandle,
                                                     0,
                                                     false,
                                                     Interop.mincore.HandleOptions.DUPLICATE_SAME_ACCESS))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                if (hTmp != null && !hTmp.IsInvalid)
                {
                    hTmp.Dispose();
                }
            }
        }
示例#24
0
        public override void CreateDirectory(string fullPath)
        {
            if (PathInternal.IsDirectoryTooLong(fullPath))
            {
                throw new PathTooLongException(SR.IO_PathTooLong);
            }

            // We can save a bunch of work if the directory we want to create already exists.  This also
            // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the
            // final path is accessable and the directory already exists.  For example, consider trying
            // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo
            // and c:\Foo\Bar.  In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar
            // and fail to due so, causing an exception to be thrown.  This is not what we want.
            if (DirectoryExists(fullPath))
            {
                return;
            }

            List <string> stackDir = new List <string>();

            // Attempt to figure out which directories don't exist, and only
            // create the ones we need.  Note that InternalExists may fail due
            // to Win32 ACL's preventing us from seeing a directory, and this
            // isn't threadsafe.

            bool somepathexists = false;

            int length = fullPath.Length;

            // We need to trim the trailing slash or the code will try to create 2 directories of the same name.
            if (length >= 2 && PathHelpers.EndsInDirectorySeparator(fullPath))
            {
                length--;
            }

            int lengthRoot = PathInternal.GetRootLength(fullPath);

            if (length > lengthRoot)
            {
                // Special case root (fullpath = X:\\)
                int i = length - 1;
                while (i >= lengthRoot && !somepathexists)
                {
                    String dir = fullPath.Substring(0, i + 1);

                    if (!DirectoryExists(dir)) // Create only the ones missing
                    {
                        stackDir.Add(dir);
                    }
                    else
                    {
                        somepathexists = true;
                    }

                    while (i > lengthRoot && !PathInternal.IsDirectorySeparator(fullPath[i]))
                    {
                        i--;
                    }
                    i--;
                }
            }

            int count = stackDir.Count;

            // If we were passed a DirectorySecurity, convert it to a security
            // descriptor and set it in he call to CreateDirectory.
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);

            bool   r           = true;
            int    firstError  = 0;
            String errorString = fullPath;

            // If all the security checks succeeded create all the directories
            while (stackDir.Count > 0)
            {
                String name = stackDir[stackDir.Count - 1];
                stackDir.RemoveAt(stackDir.Count - 1);

                r = Interop.mincore.CreateDirectory(name, ref secAttrs);
                if (!r && (firstError == 0))
                {
                    int currentError = Marshal.GetLastWin32Error();
                    // While we tried to avoid creating directories that don't
                    // exist above, there are at least two cases that will
                    // cause us to see ERROR_ALREADY_EXISTS here.  InternalExists
                    // can fail because we didn't have permission to the
                    // directory.  Secondly, another thread or process could
                    // create the directory between the time we check and the
                    // time we try using the directory.  Thirdly, it could
                    // fail because the target does exist, but is a file.
                    if (currentError != Interop.mincore.Errors.ERROR_ALREADY_EXISTS)
                    {
                        firstError = currentError;
                    }
                    else
                    {
                        // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw.
                        if (File.InternalExists(name) || (!DirectoryExists(name, out currentError) && currentError == Interop.mincore.Errors.ERROR_ACCESS_DENIED))
                        {
                            firstError  = currentError;
                            errorString = name;
                        }
                    }
                }
            }

            // We need this check to mask OS differences
            // Handle CreateDirectory("X:\\") when X: doesn't exist. Similarly for n/w paths.
            if ((count == 0) && !somepathexists)
            {
                String root = Directory.InternalGetDirectoryRoot(fullPath);
                if (!DirectoryExists(root))
                {
                    throw Win32Marshal.GetExceptionForWin32Error(Interop.mincore.Errors.ERROR_PATH_NOT_FOUND, root);
                }
                return;
            }

            // Only throw an exception if creating the exact directory we
            // wanted failed to work correctly.
            if (!r && (firstError != 0))
            {
                throw Win32Marshal.GetExceptionForWin32Error(firstError, errorString);
            }
        }
 internal unsafe static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
 {
     Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
     if ((inheritability & HandleInheritability.Inheritable) != 0)
     {
         secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
         secAttrs.nLength = (uint)sizeof(Interop.mincore.SECURITY_ATTRIBUTES);
         secAttrs.bInheritHandle = Interop.BOOL.TRUE;
     }
     return secAttrs;
 }