Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows NtDll.cs requires FILE_FLAG_BACKUP_SEMANTICS for directories #7

Closed
domsleee opened this issue Jul 5, 2023 · 3 comments
Closed

Comments

@domsleee
Copy link

domsleee commented Jul 5, 2023

Current behaviour

GetLockingProcessInfos with LockManagerFeatures.UseLowLevelApi does not work if the path is a directory on windows.
The simplest example is getting the locks of a directory that is the working directory of a cmd/powershell window.

Environment info

Windows 10 x64 on .NET 7

Possible solution

I've found this line from the documentation:
https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea

Flag Meaning
FILE_FLAG_BACKUP_SEMANTICS
0x02000000
You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file handle. For more information, see the Remarks section.

And then later in the same docs:

To open a directory using CreateFile, specify the FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFlagsAndAttributes. Appropriate security checks still apply when this flag is used without SE_BACKUP_NAME and SE_RESTORE_NAME privileges.

So I think we should be using this flag if the path is a directory 👍

Other notes

I would be interested to know how this compares to the approach mentioned by @KirillOsenkov in #6. The only case I can think of is that it would also be able to find locks on children of the directory, whereas this approach would not. Finding the lock of a child of a directory seems to be outside the scope of this library though.

Additionally, Restart Manager seems to not support finding locks on directories. Seems like another problem, but I thought I would mention it here.

I am interested in fixing it here because I'm currently using my fork of LockCheck in https://github.com/domsleee/ForceOps. For directories, I am currently just using NtDll (with UseLowLevelApi).

@KirillOsenkov
Copy link
Contributor

I added a snippet into my fork, something along these lines:

        public static IEnumerable<ProcessInformation> GetProcessesWithCurrentDirectory(string directory)
        {
            if (string.IsNullOrWhiteSpace(directory))
            {
                return Array.Empty<ProcessInformation>();
            }

            var list = new List<ProcessInformation>();

            var processes = ProcessInformation.GetProcesses();
            foreach (var process in processes)
            {
                if (process.CurrentDirectory is string currentDirectory)
                {
                    if (currentDirectory.StartsWith(directory, StringComparison.OrdinalIgnoreCase))
                    {
                        list.Add(process);
                    }
                }
            }

            return list;
        }

@KirillOsenkov
Copy link
Contributor

And here's a sample of getting the current directory for any given process:
https://github.com/KirillOsenkov/Misc/blob/cf1b6ece2be91459bb301f65eac5b10e2f398562/GetProcessCurrentDirectory.cs#L16

@cklutz
Copy link
Owner

cklutz commented Oct 9, 2024

I'm closing this for now due to the features added in #13. Might reopen and reconsider when the original idea ("FILE_FLAG_BACKUP_SEMANTICS") should provide more / better functionality than what @KirillOsenkov suggested in #6 and above in a comment.

@cklutz cklutz closed this as completed Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants