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

Mounting an ISO image that exists on a drive mounted as a network drive. #1076

Open
2 of 5 tasks
onexzero opened this issue Mar 11, 2022 · 19 comments
Open
2 of 5 tasks

Comments

@onexzero
Copy link

onexzero commented Mar 11, 2022

Feature request can skip this form. Bug report must complete it. Check List must be 100% match or it will be automatically closed without further discussion. Please remove this line.

Environment

  • Windows version:
  • Processor architecture:
  • Dokany version:
  • Library type (Dokany/FUSE):

Check List

  • I checked my issue doesn't exist yet
  • My issue is valid with mirror default sample and not specific to my user-mode driver implementation
  • I can always reproduce the issue with the provided description below.
  • I have updated Dokany to the latest version and have reboot my computer after.
  • I tested one of the last snapshot from appveyor CI

Description

Is there a way to mount an iso image on a mounted drive with the /n switch?
I have already read #855.

Logs

Please attach in separate files: mirror output, library logs and kernel logs.
In case of BSOD, please attach minidump or dump analyze output.

@Liryna
Copy link
Member

Liryna commented Mar 12, 2022

Is mounting an ISO from a network share possible by default on Windows ?
What issue are you facing ?

@onexzero
Copy link
Author

Yes It works well with network share. When i click iso image on my drive i got "Sorry, threre was a problem mounting the file.". On dokan mirror sample with /o switch it works well, but /o switch not work with /n switch. When i run mirror with /n same error poped up but image mounted and works but not on my drive.
ImageMount

@Liryna
Copy link
Member

Liryna commented Mar 12, 2022

Oh I see. It would be useful to use Procmon here and find out if there is a request that fails but should succeed that can explain the error.

Regarding mount manager and network manager, it is still a feature that would be nice to have indeed!

@onexzero
Copy link
Author

I've already checked it on procmon, but I haven't found anything special. It's not an important problem right now, so I'll have to research it again when I have time. Thanks for reply.

@Liryna
Copy link
Member

Liryna commented Mar 19, 2022

@onexzero were you able to get more information here ?

@onexzero
Copy link
Author

I haven't had time to dig more yet.

@onexzero
Copy link
Author

PS Z:\test> dir

Directory: Z:\test

Mode LastWriteTime Length Name


------ 3/21/2022 12:20 PM 375390208 android.iso

PS Z:\test>
PS Z:\test> Mount-DiskImage -StorageType ISO -ImagePath "Z:\test\android.iso"
Mount-DiskImage : The parameter is incorrect.
At line:1 char:1

  • Mount-DiskImage -StorageType ISO -ImagePath "Z:\test\android.iso"
  •   + CategoryInfo          : InvalidArgument: (MSFT_DiskImage:ROOT/Microsoft/.../MSFT_DiskImage) [Mount-DiskImage], C
     imException
      + FullyQualifiedErrorId : HRESULT 0x80070057,Mount-DiskImage
    
    

PS Z:\test>

As you can see, the ISO file exists in the path, but the mount fails. It also fails in windows explorer.
However, in 3rd party utilities such as WinCDEmu, it mounts successfully.

Looking at the Procmon log, the PATH part is a bit strange.

\localhost\개인문서함\localhost\개인문서함\test\android.iso
UNCName("\localhost\개인문서함") repeated twice.
And we can see INVALID_PARAMETER (<-- this not returned from me).
But It is uncertain that INVALID_PARAMETER caused above mount error - "The parameter is incorrect.".

When I try to mount with Powershell, I don't see any special user mode calls.

If I run my driver without the /n switch and mount it from powershell, it seems to work normally, so it seems to be related to the /n switch. Google doesn't have much information about this either.

mountlog.zip

@Liryna
Copy link
Member

Liryna commented Mar 21, 2022

That looks to be the same issue as #973. The UNC path is provided somewhere by the network provider or the driver when it should not and create this dup UNC path.
It would be great if someone could take a look at it!

@onexzero
Copy link
Author

I'm trying to figure it out, but I don't have much time.

@onexzero
Copy link
Author

It has been confirmed that the issue of including UNCName twice in the path is not related to NP. This problem is probably driver related. From what I've figured out so far, ISO mount and abnormal path problems are seen as different problems.

@onexzero
Copy link
Author

onexzero commented Mar 23, 2022

#973 fix
replace FillNameInformation function of /sys/fileinfo.c

NTSTATUS FillNameInformation(__in PREQUEST_CONTEXT RequestContext,
                             __in PDokanFCB Fcb,
                             __in PFILE_NAME_INFORMATION NameInfo) {
  PUNICODE_STRING fileName = &Fcb->FileName;
  PCHAR dest = (PCHAR)&NameInfo->FileName;
  NameInfo->FileNameLength = fileName->Length;

  BOOLEAN isNetworkDevice = (RequestContext->Dcb->VolumeDeviceType ==
                             FILE_DEVICE_NETWORK_FILE_SYSTEM);
  if (isNetworkDevice) {
    PUNICODE_STRING devicePath = RequestContext->Dcb->UNCName->Length
                                     ? RequestContext->Dcb->UNCName
                                     : RequestContext->Dcb->DiskDeviceName;
  
    if (!(fileName->Length > 0 && wcsstr(fileName->Buffer, devicePath->Buffer) == fileName->Buffer)) {

        NameInfo->FileNameLength += devicePath->Length;

        if (!AppendVarSizeOutputString(RequestContext->Irp, dest, devicePath,
            /*UpdateInformationOnFailure=*/FALSE,
            /*FillSpaceWithPartialString=*/TRUE)) {
            return STATUS_BUFFER_OVERFLOW;
        }
        dest += devicePath->Length;
    }
  }

  if (!AppendVarSizeOutputString(RequestContext->Irp, dest, fileName,
                                 /*UpdateInformationOnFailure=*/FALSE,
                                 /*FillSpaceWithPartialString=*/TRUE)) {
    return STATUS_BUFFER_OVERFLOW;
  }
  return STATUS_SUCCESS;
}

@onexzero
Copy link
Author

onexzero commented Mar 23, 2022

And to eliminate unnecessary calls
in /dokan/fileinfo.c

VOID DispatchQueryInformation(PDOKAN_IO_EVENT IoEvent) {
  BY_HANDLE_FILE_INFORMATION byHandleFileInfo;
  NTSTATUS status = STATUS_INVALID_PARAMETER;

  DbgPrint(
      "###GetFileInfo file handle = 0x%p, eventID = %04d, event Info = 0x%p\n",
      IoEvent->DokanOpenInfo,
      IoEvent->DokanOpenInfo != NULL ? IoEvent->DokanOpenInfo->EventId : -1,
      IoEvent);

  CheckFileName(IoEvent->EventContext->Operation.File.FileName);

  CreateDispatchCommon(IoEvent,
                       IoEvent->EventContext->Operation.File.BufferLength,
                       /*UseExtraMemoryPool=*/FALSE,
                       /*ClearNonPoolBuffer=*/TRUE);
  if (IoEvent->EventContext->Operation.File.FileInformationClass ==
      FileRemoteProtocolInformation)
      status = STATUS_NOT_IMPLEMENTED;
  else if (IoEvent->EventContext->Operation.File.FileInformationClass ==
      FileStreamInformation) {
    DbgPrint("FileStreamInformation\n");
    // https://msdn.microsoft.com/en-us/library/windows/hardware/ff540364(v=vs.85).aspx
    if (IoEvent->EventContext->Operation.File.BufferLength <
        sizeof(FILE_STREAM_INFORMATION)) {

      status = STATUS_BUFFER_TOO_SMALL;
    } else if (IoEvent->DokanInstance->DokanOperations->FindStreams) {

      status = IoEvent->DokanInstance->DokanOperations->FindStreams(
          IoEvent->EventContext->Operation.File.FileName,
          DokanFillFindStreamData, IoEvent, &IoEvent->DokanFileInfo);
      DokanEndDispatchFindStreams(IoEvent, status);
    } else {
      status = STATUS_NOT_IMPLEMENTED;
    }
  } else if (IoEvent->DokanInstance->DokanOperations->GetFileInformation) {

    ZeroMemory(&byHandleFileInfo, sizeof(BY_HANDLE_FILE_INFORMATION));
    status = IoEvent->DokanInstance->DokanOperations->GetFileInformation(
        IoEvent->EventContext->Operation.File.FileName, &byHandleFileInfo,
        &IoEvent->DokanFileInfo);
    DokanEndDispatchGetFileInformation(IoEvent, &byHandleFileInfo, status);
  } else {

    status = STATUS_NOT_IMPLEMENTED;
  }
}

But image mount still fails with "The requested operation could not be completed due to a file system limitation"
For CIFS(SMB) drives this is well supported.
But In dokan I don't know why..

@Liryna
Copy link
Member

Liryna commented Mar 23, 2022

Thanks @onexzero for the patches.
Regarding #1076 (comment) I actually believe we should NOT have the UNC in the Fcb->FileName from start. If we get a CreateFile with the UNC we should not copy it in our Fcb here https://github.com/dokan-dev/dokany/blob/master/sys/create.c#L608-L627
Would you agree ? Can you try see if it fix the issue here ?

#1076 (comment)
The diff is skipping calls for FileRemoteProtocolInformation ? That might be a good idea! We should event just skip it from the Kernel. I don't see how we could support it at all.

@onexzero
Copy link
Author

It will probably have the same effect. I haven't tested it, but it seems to be a more fundamental solution.

@onexzero
Copy link
Author

I also tried to implement FileRemoteProtocolInformation, but it didn't seem like a generalizable part.

@onexzero
Copy link
Author

onexzero commented Mar 24, 2022

Another thing I want to say about path notation is that it would be better to conform to the UNC notation. So it looks like we need one more leading "\" in unc-path.
ex) \Host\Share\PathToFile -> \\Host\Share\PathToFile

@Liryna
Copy link
Member

Liryna commented Mar 24, 2022

Another thing I want to say about path notation is that it would be better to conform to the UNC notation. So it looks like we need one more leading "" in unc-path.
ex) \Host\Share\PathToFile -> \Host\Share\PathToFile

The single \ is made in purpose. It is the Windows kernel format we are using.

@onexzero
Copy link
Author

onexzero commented Mar 24, 2022

All right. But usually use UNC format for network drives.

@Liryna
Copy link
Member

Liryna commented Mar 28, 2022

Can confirm the iso is mount without issue on non network storage with mount manager option, with an error but still mount without the mount manager option and the same previous error without being mount on network storage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants