dokan-dev / dokany

User mode file system library for windows with FUSE Wrapper
http://dokan-dev.github.io
5.2k stars 661 forks source link

Certain context menu options missing #1132

Closed GeorgeSmithHwk closed 1 year ago

GeorgeSmithHwk commented 1 year ago

Environment

Check List

Description

Hi guys. I've recently discovered an issue with the Windows Explorer Context Menu when accessing mounted drives using Dokany. The issue is that certain context menu options that exist when accessing a path via the Windows filesystem do not appear when accessing the same path using the mounted filesystem. In my example, the 7Zip and KDiff3 options do not appear when using the mounted filesystem path. Mounted drive example: image

Windows Filesystem example: image

Note that in the Windows Filesystem example, there are options for 7Zip and KDiff3. What I find strange about this is that other context menu items such as the "Open with Code" for Visual Studio Code works across both methods (Although this may be because Visual Studio Code is developed like Microsoft, so this may have some impact?).

Our usage of Dokany appears to be what is expected as described by the documentation, we return STATUS_NOT_IMPLEMENTED for the GetFileSecurity callback which as described in the documentation "let dokan library build a sddl of the current process user with authenticate user rights for context menu"

Any help or suggestions would be greatly appreciated, thanks in advance :)

Liryna commented 1 year ago

Hi @GeorgeSmithHwk ,

That's interesting. Have you been able to reproduce the issue with the mirror sample using the mount manager option /o ? If not, it would be interesting to look at their code and find the requirements for the entry to show. Maybe it is even possible to have their logs.

GeorgeSmithHwk commented 1 year ago

Hi @Liryna,

Thanks for getting back to me :) So I tried with the mirror using the command .\mirror.exe /r C:\Users /l M: /n \myfs\myfs1 and I could see the context menu options when accessing the UNC path \\myfs\myfs1, so I suppose this would indicate that it is indeed an issue with our implementation. Would you have any suggestions of where in our usage of the API to look or potential logs that may indicate the issue? Thanks

Liryna commented 1 year ago

The best might be to use Procmon and analyse the query happening when doing a right click on a file. I would expect the process to spy to be explorer. Compare on native NTFS and your FS the requests.

Is your type of filesystem NTFS or have your personalized it ? Try with NTFS

GeorgeSmithHwk commented 1 year ago

Ok sounds good, I will give this a try next week when I have access to our codebase and compare the requests. I'll have to double check about the filesystem, pretty sure it's NTFS. If not I'll try using NTFS. Thanks

GeorgeSmithHwk commented 1 year ago

Hi @Liryna,

So I've been investigating this further today and have made some progress, although something still isn't quite right.

Something I noticed when running the mirror was that without launching the .exe as admin, we get this warning in the console: PS C:\Program Files\Dokan\Dokan Library-2.0.4\sample\mirror> .\mirror.exe /r C:\Users /l M: /n /u \myfs\myfs1 [Mirror] Failed to add security privilege to process => GetFileSecurity/SetFileSecurity may not work properly => Please restart mirror sample with administrator rights to fix it

The GetFileSecurity method appears to be the method that "builds" the context menu options as explained earlier, so I modified our impl to be ran as admin which I can confirm by looking at the process in task manager: image

Unfortunately, this alone hasn't solved our issue. Even running our Dokan impl as admin, no KDiff or 7Zip options appear in the context menu.

Comparing the ProcMon operations between the native NTFS and our FS impl shows that we do seem to be doing stuff partly correct, both native and our FS make some operations pertaining to KDiff3 which presumably is what is causing the KDiff3 option to appear in the context menu. Remote FS example: image Native example: image

I then looked at the Mirror.c file and noticed that in your mirror impl, the MirrorGetFileSecurity function does a lot more logic than we do in ours. Currently, our GetFileSecurity method looks like this:

NTSTATUS DOKAN_CALLBACK OnGetFileSecurity(
    LPCWSTR path,
    PSECURITY_INFORMATION securityInfo,
    PSECURITY_DESCRIPTOR securityDescriptor,
    ULONG bufferLength,
    PULONG lengthNeeded,
    PDOKAN_FILE_INFO pFileInfo)
{
    MARKER;

    const auto oObjects = getObjects(path, pFileInfo);

    if (!oObjects)
    {
        processNoSuchFile("GetFileSecurity", std::filesystem::path(path).string());
        return STATUS_NO_SUCH_FILE;
    }

    processUnimplemented(oObjects->id, "GetFileSecurity", oObjects->path);
    return STATUS_NOT_IMPLEMENTED;
}

I even tried modifying our method so that it immediately returns STATUS_NOT_IMPLEMENTED in an attempt to get Dokan to "build a sddl of the current process user with authenticate user rights for context menu", but this has no affect.

Could it be that the docs are somewhat incorrect and that there's more required to this operation than just returning STATUS_NOT_IMPLEMENTED ?

Thanks again for your continued support on this issue

GeorgeSmithHwk commented 1 year ago

Just to follow this up, the call to processUnimplemented in our implementation is purely for logging purposes, no business logic takes place

Liryna commented 1 year ago

The problem when running with admin rights is that the Dokan get default security information built when status not implemented, will have the admin information. See https://github.com/dokan-dev/dokany/commit/548eea55f578c5dcb1f2ed6b69154b1592468b87

Therefore the running user for the context menu will not have the security information for him returned.

If you really want to run as administrator, you might want to implement the same logic on your side but get the user permission to make the context menu happy.

Liryna commented 1 year ago

Closing for inactivity