4

I'm writing a software to communicate to a recording device that if connected to the pc via USB emulates a mass storage device. Some special features are accessed on that device by communicating on a special sector on that device. To get access on that sector on windows I need to:

  • open a handle to the newly arrived drive
  • fetch the physical drive number via deviceIOControl and IOCTLVolumeGetVolumeDiskExtents
  • Open the physicaldrive found there and read and write to a special sector.

So far so good - everything is working fine but getting the first initial volume handle can take quite long.

what I'm doing is basically this:

var hdl : THandle;
    start, stop, freq : INT64;
begin
     hdl := INVALID_HANDLE_VALUE;

     QueryPerformanceFrequency(freq);
     QueryPerformanceCounter(start);

     fHandle := CreateFile( PChar('\\.\' + fDriveLetter + ':'),
                        GENERIC_READ,
                        FILE_SHARE_WRITE or FILE_SHARE_READ,
                        nil,
                        OPEN_EXISTING,
                        0,
                        0);

     QueryPerformanceCounter(stop);
     OutputDebugString( PChar( Format('Open drive took %.3fms', [(stop - start)/freq*1000]) ));

     if hdl = INVALID_HANDLE_VALUE then
        raise EVolumeError.Create( 'Cannot Open Drive: '+fDriveLetter+#13#10+
                               SysErrorMessage(GetLastError));
end;

This call can take seconds right until the drive arrived.

My guess is that windows first reads the complete FAT which takes long on this little recording device which actually always creates files that reserves the complete disk space (4GB). Anyone has an idea how to speed up that process? I never need to read anything from the file system but rather I need the handle the get information about the underlying physicaldrive number and from there I do my read and write operations.

mrabat
  • 802
  • 7
  • 15
  • According to msdn when accessing volumes one needs to add at least the FILE_SHARE_WRITE flag. msdn: "When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITEflag" – mrabat Sep 11 '17 at 09:43
  • if you want only send `IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS` which defined as `FILE_ANY_ACCESS` - you must open file with `FILE_READ_ATTRIBUTES` maximum or 0 in *dwDesiredAccess*. so change `GENERIC_READ` to 0. this prevent volume from mount and can speed up – RbMm Sep 11 '17 at 09:46
  • my mistake. i confuse sharing flag `FILE_SHARE_WRITE` with access flag - `FILE_WRITE_ACCESS`. really you need try change access flag from `GENERIC_READ` to 0 (`SYNCHRONIZE`) – RbMm Sep 11 '17 at 09:48
  • Ok I'll try that ... In the meantime we changed the cluster size in the recording device and then the waiting time was reduced by a factor of 8 (changing from 4kB to 32kB) – mrabat Sep 11 '17 at 09:59
  • really question here - are your disk device will be mount by file system or not. if you send only `IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS` - you not need filsystem at all - it anyway pass this ioctl to underlining storage device. if big time taken by file system mount process you need avoid this. way to do this - change access flags to minimum. - https://github.com/Zer0Mem0ry/ntoskrnl/blob/master/Io/iomgr/parse.c#L756 – RbMm Sep 11 '17 at 10:04
  • Thanks!! I think using the SYNCHRONIZE flag does the trick (though I don't fully understand the referenze you sent me and ...) . – mrabat Sep 11 '17 at 10:25
  • `SYNCHRONIZE` implicitly was added by `CreateFile` if you not use `FILE_FLAG_OVERLAPPED` flag. reference (windows 2003 source code, which in this point in general actual and for other version) explain that when the device will be not mounted - *caller is opening the device for only read attributes access, then this device will not be mounted. This allows applications to obtain attributes about the device without actually mounting it* - i advice you not mount device for speed up. for do this use 0 or `FILE_READ_ATTRIBUTES` only. – RbMm Sep 11 '17 at 10:31
  • Thank you for your comments - synchronize indeed helped a lot in the initial call to the volume. Nevertheless the next Createfile to the physicalvolume, where I need read and write access for the communication, is then still quite slow (but still it's faster than before). Nevertheless we need to combine both findings - use your suggestion with the synchronized flag and massively increase the cluster size when the device formats the sd card. – mrabat Sep 11 '17 at 12:22

0 Answers0