public static void SetAttributes(string fullPath, FileAttributes attributes)
 {
     if (!Win32Api.Kernel32.SetFileAttributes(fullPath, (int)attributes))
     {
         int errorCode = Marshal.GetLastWin32Error();
         if (errorCode == Win32Api.Errors.ERROR_INVALID_PARAMETER)
         {
             throw new ArgumentException(nameof(attributes));
         }
         throw PalWin32FileStream.GetExceptionForWin32Error(errorCode, fullPath);
     }
 }
        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);
                }

                if (((FileOptions)additionalFlags).Bit(FileOptions.Asynchronous))
                {
                    handle._SetAsync(true);
                    ThreadPool.BindHandle(handle);
                }
                else
                {
                    handle._SetAsync(false);
                }

                return(handle);
            }
        }
        public static FileAttributes GetAttributes(string fullPath, bool backupMode = false)
        {
            int flags = backupMode ? Win32Api.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS : 0;

            Win32Api.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Api.Kernel32.WIN32_FILE_ATTRIBUTE_DATA();
            int errorCode = FillAttributeInfo(fullPath, ref data, returnErrorOnNotFound: true);

            if (errorCode != 0)
            {
                throw PalWin32FileStream.GetExceptionForWin32Error(errorCode, fullPath);
            }

            return((FileAttributes)data.dwFileAttributes);
        }
 public static Exception GetWin32ErrorException(int?errorCode = null, string?argument = null)
 => PalWin32FileStream.GetExceptionForWin32Error(errorCode ?? Marshal.GetLastWin32Error(), argument);