Force Flush File Cash for a USB Device C#

0

So I have been working on an project, that will search drives, attempting to identify a specific USB device, and if it does find it, will perform an export to this device. On completion of this, I have a dialog that pops up informing the completion of the export to the device, and asks the user if they wish to eject the USB device or not.

Here is a portion of the code to handle the USB device:

public class USBController
{
    const int OPEN_EXISTING = 3;
    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const uint IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;

    [DllImport("kernel32", SetLastError = true)]
    private static extern int CloseHandle(IntPtr handle);

    [DllImport("kernel32", SetLastError = true)]
    private static extern int DeviceIoControl
        (IntPtr deviceHandle, uint ioControlCode,
          IntPtr inBuffer, int inBufferSize,
          IntPtr outBuffer, int outBufferSize,
          ref int bytesReturned, IntPtr overlapped);

    [DllImport("kernel32", SetLastError = true)]
    private static extern IntPtr CreateFile
        (string filename, uint desiredAccess,
          uint shareMode, IntPtr securityAttributes,
          int creationDisposition, int flagsAndAttributes,
          IntPtr templateFile);

    public static bool EjectDrive(char driveLetter, bool displayMessages)
    {
        string path = "\\\\.\\" + driveLetter + ":";

        IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
            IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);


        if ((long)handle == -1)
        {
            int error = Marshal.GetLastWin32Error();
            if (displayMessages)
                MessageBox.Show("Drive may still be in use. Unable to eject drive " + driveLetter + ":\\ \n\nError Code = " + error);

            return false;
        }

        int dummy = 0;

        DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
            IntPtr.Zero, 0, ref dummy, IntPtr.Zero);


        int returnValue = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
            IntPtr.Zero, 0, ref dummy, IntPtr.Zero);

        if (returnValue == 0)
        {
            int error = Marshal.GetLastWin32Error();
            if (displayMessages)
                MessageBox.Show("DeviceIoControl encountered an error. \n\nError Code: " + error);

            return false;
        }


        CloseHandle(handle);
        if (displayMessages)
            MessageBox.Show("OK to remove drive.");

        return true;
    }
public static bool IsReady(char driveLetter)
    {
        DriveInfo[] drives = DriveInfo.GetDrives();

        foreach (DriveInfo drv in drives)
        {
            if (Convert.ToChar(drv.RootDirectory.ToString()[0]) == driveLetter && drv.IsReady)
            {
                return true;
            }
        }
        return false;
    }
}

So everything works, and the code will actually eject a USB device. The issues becomes that the file that is exported is very small, often under 100kb. It seems that the file is sitting in the File Caching system, because after writing the file, I cannot eject the USB drive by code or by the tool in the system tray provided by windows. It says the device is still busy.

Is there a way I can force flush the cache, or another method to get around this issue? My IsReady method seems to more check that the device is available to be accessed, not necessarily ready to be ejected.

Thanks

c#
file
caching
usb
asked on Stack Overflow May 31, 2012 by Sidious911 • edited May 30, 2019 by Bhargav Rao

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0