Exemplo n.º 1
0
        public static SafeFileHandle OpenHandle(string fullPath, bool asDirectory, bool writeMode = false, bool backupMode = false, bool asyncMode = true, int additionalFlags = 0)
        {
            string root = fullPath.Substring(0, Win32PathInternal.GetRootLength(fullPath.AsSpan()));

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

            if (asyncMode)
            {
                additionalFlags |= (int)FileOptions.Asynchronous;
            }

            using (Lfs.EnterDisableMediaInsertionPrompt())
            {
                SafeFileHandle handle = Win32Api.Kernel32.CreateFile(
                    fullPath,
                    writeMode ? Win32Api.Kernel32.GenericOperations.GENERIC_WRITE | Win32Api.Kernel32.GenericOperations.GENERIC_READ : Win32Api.Kernel32.GenericOperations.GENERIC_READ,
                    FileShare.ReadWrite | FileShare.Delete,
                    FileMode.Open,
                    ((asDirectory || backupMode) ? Win32Api.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS : 0) | additionalFlags);

                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 == Win32Api.Errors.ERROR_PATH_NOT_FOUND && fullPath.Equals(Directory.GetDirectoryRoot(fullPath)))
                    {
                        errorCode = Win32Api.Errors.ERROR_ACCESS_DENIED;
                    }

                    throw PalWin32FileStream.GetExceptionForWin32Error(errorCode, fullPath);
                }

                handle._EnsureThreadPoolBindingInitialized();

                return(handle);
            }
        }