|
Work perfectly on win7 and win10. Great job, one class, one method to call.
|
|
|
|
|
Hi Gina,
I am using .net framework and .net5 is used and i am simply attach this class and call using a line which is
bool remove = RemoveDriveTools.RemoveDrive("H:");
then, the below highlighted line exception has thrown.
static long GetDrivesDevInstByDeviceNumber(long DeviceNumber, DriveType DriveType, string dosDeviceName)
{
bool IsFloppy = dosDeviceName.Contains("\\Floppy");
Guid guid;
switch (DriveType)
{
case DriveType.DRIVE_REMOVABLE:
if (IsFloppy) guid = new Guid(GUID_DEVINTERFACE_FLOPPY);
else guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_FIXED:
guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_CDROM:
guid = new Guid(GUID_DEVINTERFACE_CDROM);
break;
default:
return 0;
}
IntPtr hDevInfo = SetupDiGetClassDevs(ref guid, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo.ToInt32() == INVALID_HANDLE_VALUE) throw new Win32Exception(Marshal.GetLastWin32Error());
int dwIndex = 0;
Please provide guide to resolve this gina.
Execption is
System.OverflowException: 'Arithmetic operation resulted in an overflow.'
|
|
|
|
|
This works perfect, just one comment, in Visual Studio 2012 I had to select one CPU option, I selected x86 (32 bits), if you use Any CPU, maybe you find some problems.
Best regards my friend.
|
|
|
|
|
I had received error messages when running this under X64:
Eine nicht behandelte Ausnahme des Typs "System.ComponentModel.Win32Exception" ist in RemoveDriveByLetter.exe aufgetreten.
Zusätzliche Informationen: Der angegebene Benutzerpuffer ist für den angeforderten Vorgang nicht zulässig
I did modify the code based on comments from here Eject USB disks using C#[^]
which did solve the problem for me.
I hope the code below helps somebodyelse encountering similar issues:
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.ComponentModel;
namespace RemoveDriveByLetter
{
public class RemoveDriveTools
{
[StructLayout(LayoutKind.Sequential)]
struct STORAGE_DEVICE_NUMBER
{
public int DeviceType;
public int DeviceNumber;
public int PartitionNumber;
};
enum DriveType : uint
{
DRIVE_UNKNOWN = 0,
DRIVE_NO_ROOT_DIR = 1,
DRIVE_REMOVABLE = 2,
DRIVE_FIXED = 3,
DRIVE_REMOTE = 4,
DRIVE_CDROM = 5,
DRIVE_RAMDISK = 6
}
const string GUID_DEVINTERFACE_VOLUME = "53f5630d-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_DISK = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_FLOPPY = "53f56311-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_CDROM = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
const int INVALID_HANDLE_VALUE = -1;
const int GENERIC_READ = unchecked((int)0x80000000);
const int GENERIC_WRITE = unchecked((int)0x40000000);
const int FILE_SHARE_READ = unchecked((int)0x00000001);
const int FILE_SHARE_WRITE = unchecked((int)0x00000002);
const int OPEN_EXISTING = unchecked((int)3);
const int FSCTL_LOCK_VOLUME = unchecked((int)0x00090018);
const int FSCTL_DISMOUNT_VOLUME = unchecked((int)0x00090020);
const int IOCTL_STORAGE_EJECT_MEDIA = unchecked((int)0x002D4808);
const int IOCTL_STORAGE_MEDIA_REMOVAL = unchecked((int)0x002D4804);
const int IOCTL_STORAGE_GET_DEVICE_NUMBER = unchecked((int)0x002D1080);
const int ERROR_NO_MORE_ITEMS = 259;
const int ERROR_INSUFFICIENT_BUFFER = 122;
const int ERROR_INVALID_DATA = 13;
[DllImport("kernel32.dll")]
static extern DriveType GetDriveType([MarshalAs(UnmanagedType.LPStr)] string lpRootPathName);
[DllImport("kernel32.dll")]
static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
int dwDesiredAccess,
int dwShareMode,
IntPtr lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool DeviceIoControl(
IntPtr hDevice,
int dwIoControlCode,
IntPtr lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped);
const int DIGCF_PRESENT = (0x00000002);
const int DIGCF_DEVICEINTERFACE = (0x00000010);
[StructLayout(LayoutKind.Sequential)]
class SP_DEVINFO_DATA
{
public int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
public Guid classGuid = Guid.Empty;
public int devInst = 0;
public IntPtr reserved = IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public short devicePath;
}
[StructLayout(LayoutKind.Sequential)]
class SP_DEVICE_INTERFACE_DATA
{
public int cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
public Guid interfaceClassGuid = Guid.Empty;
public int flags = 0;
public IntPtr reserved = IntPtr.Zero;
}
[DllImport("setupapi.dll")]
static extern IntPtr SetupDiGetClassDevs(
ref Guid classGuid,
int enumerator,
IntPtr hwndParent,
int flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInterfaces(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
ref Guid interfaceClassGuid,
int memberIndex,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInterfaceDetail(
IntPtr deviceInfoSet,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
int deviceInterfaceDetailDataSize,
ref int requiredSize,
SP_DEVINFO_DATA deviceInfoData);
[DllImport("setupapi.dll")]
static extern uint SetupDiDestroyDeviceInfoList(
IntPtr deviceInfoSet);
[DllImport("setupapi.dll")]
static extern int CM_Get_Parent(
ref int pdnDevInst,
int dnDevInst,
int ulFlags);
[DllImport("setupapi.dll")]
static extern int CM_Request_Device_Eject(
int dnDevInst,
out PNP_VETO_TYPE pVetoType,
StringBuilder pszVetoName,
int ulNameLength,
int ulFlags);
[DllImport("setupapi.dll", EntryPoint = "CM_Request_Device_Eject")]
static extern int CM_Request_Device_Eject_NoUi(
int dnDevInst,
IntPtr pVetoType,
StringBuilder pszVetoName,
int ulNameLength,
int ulFlags);
enum PNP_VETO_TYPE
{
Ok,
TypeUnknown,
LegacyDevice,
PendingClose,
WindowsApp,
WindowsService,
OutstandingOpen,
Device,
Driver,
IllegalDeviceRequest,
InsufficientPower,
NonDisableable,
LegacyDriver,
InsufficientRights
}
public static bool RemoveDrive(string driveCharWithColon)
{
IntPtr hVolume = CreateFile(@"\\.\" + driveCharWithColon, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hVolume.ToInt32() == -1) return false;
long DeviceNumber = GetDeviceNumber(hVolume);
if (DeviceNumber == -1) return false;
string rootPath = driveCharWithColon + "\\";
DriveType driveType = GetDriveType(rootPath);
StringBuilder pathInformation = new StringBuilder(250);
uint res = QueryDosDevice(driveCharWithColon, pathInformation, 250);
if (res == 0) return false;
long DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, driveType, pathInformation.ToString());
if (DevInst == 0) return false;
int DevInstParent = 0;
CM_Get_Parent(ref DevInstParent, (int)DevInst, 0);
for (int tries = 1; tries <= 3; tries++)
{
int r = CM_Request_Device_Eject_NoUi(DevInstParent, IntPtr.Zero, null, 0, 0);
if (r == 0) return true;
Thread.Sleep(500);
}
return false;
}
static long GetDeviceNumber(IntPtr handle)
{
long DeviceNumber = -1;
int size = 0x400;
IntPtr buffer = Marshal.AllocHGlobal(size);
int bytesReturned = 0;
try
{
DeviceIoControl(handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, buffer, size, out bytesReturned, IntPtr.Zero);
}
finally
{
CloseHandle(handle);
}
if (bytesReturned > 0)
{
STORAGE_DEVICE_NUMBER sdn = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(buffer, typeof(STORAGE_DEVICE_NUMBER));
DeviceNumber = sdn.DeviceNumber;
}
Marshal.FreeHGlobal(buffer);
return DeviceNumber;
}
static long GetDrivesDevInstByDeviceNumber(long DeviceNumber, DriveType DriveType, string dosDeviceName)
{
bool IsFloppy = dosDeviceName.Contains("\\Floppy");
Guid guid;
switch (DriveType)
{
case DriveType.DRIVE_REMOVABLE:
if (IsFloppy) guid = new Guid(GUID_DEVINTERFACE_FLOPPY);
else guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_FIXED:
guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_CDROM:
guid = new Guid(GUID_DEVINTERFACE_CDROM);
break;
default:
return 0;
}
IntPtr hDevInfo = SetupDiGetClassDevs(ref guid, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo.ToInt32() == INVALID_HANDLE_VALUE) throw new Win32Exception(Marshal.GetLastWin32Error());
int dwIndex = 0;
while (true)
{
SP_DEVICE_INTERFACE_DATA interfaceData = new SP_DEVICE_INTERFACE_DATA();
if (!SetupDiEnumDeviceInterfaces(hDevInfo, null, ref guid, dwIndex, interfaceData))
{
int error = Marshal.GetLastWin32Error();
if (error != ERROR_NO_MORE_ITEMS) throw new Win32Exception(error);
break;
}
SP_DEVINFO_DATA devData = new SP_DEVINFO_DATA();
int size = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, interfaceData, IntPtr.Zero, 0, ref size, devData))
{
int error = Marshal.GetLastWin32Error();
if (error != ERROR_INSUFFICIENT_BUFFER) throw new Win32Exception(error);
}
IntPtr buffer = Marshal.AllocHGlobal(size);
SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
if(IntPtr.Size == 8)
detailData.cbSize = 8;
else
detailData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
Marshal.StructureToPtr(detailData, buffer, false);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, interfaceData, buffer, size, ref size, devData))
{
Marshal.FreeHGlobal(buffer);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
IntPtr pDevicePath = (IntPtr)((int)buffer + Marshal.SizeOf(typeof(int)));
string devicePath = Marshal.PtrToStringAuto(pDevicePath);
Marshal.FreeHGlobal(buffer);
IntPtr hDrive = CreateFile(devicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hDrive.ToInt32() != INVALID_HANDLE_VALUE)
{
long driveDeviceNumber = GetDeviceNumber(hDrive);
if (DeviceNumber == driveDeviceNumber)
{
SetupDiDestroyDeviceInfoList(hDevInfo);
return devData.devInst;
}
}
dwIndex++;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
static void Test()
{
bool ok = RemoveDrive("H:");
}
}
}
modified 15-Dec-14 14:05pm.
|
|
|
|
|
Hi there, I found this post and probably is too late to contribute on it but Im going to post my answer anyway so it might help someone else.
We needed exactly something like this but working for x64 architectures, the solution posted in the thread for x64 wasn´t really working (it threw an Overflow exception in the toInt16() casting a couple of times) so here is the modified code that works for both arquitectures:
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.ComponentModel;
namespace RemoveDriveByLetter
{
public static class RemoveDriveTools
{
[StructLayout(LayoutKind.Sequential)]
struct STORAGE_DEVICE_NUMBER
{
public int DeviceType;
public int DeviceNumber;
public int PartitionNumber;
};
enum DriveType : uint
{
DRIVE_UNKNOWN = 0,
DRIVE_NO_ROOT_DIR = 1,
DRIVE_REMOVABLE = 2,
DRIVE_FIXED = 3,
DRIVE_REMOTE = 4,
DRIVE_CDROM = 5,
DRIVE_RAMDISK = 6
}
const string GUID_DEVINTERFACE_VOLUME = "53f5630d-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_DISK = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_FLOPPY = "53f56311-b6bf-11d0-94f2-00a0c91efb8b";
const string GUID_DEVINTERFACE_CDROM = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
const int INVALID_HANDLE_VALUE = -1;
const int GENERIC_READ = unchecked((int)0x80000000);
const int GENERIC_WRITE = unchecked((int)0x40000000);
const int FILE_SHARE_READ = unchecked((int)0x00000001);
const int FILE_SHARE_WRITE = unchecked((int)0x00000002);
const int OPEN_EXISTING = unchecked((int)3);
const int FSCTL_LOCK_VOLUME = unchecked((int)0x00090018);
const int FSCTL_DISMOUNT_VOLUME = unchecked((int)0x00090020);
const int IOCTL_STORAGE_EJECT_MEDIA = unchecked((int)0x002D4808);
const int IOCTL_STORAGE_MEDIA_REMOVAL = unchecked((int)0x002D4804);
const int IOCTL_STORAGE_GET_DEVICE_NUMBER = unchecked((int)0x002D1080);
const int ERROR_NO_MORE_ITEMS = 259;
const int ERROR_INSUFFICIENT_BUFFER = 122;
const int ERROR_INVALID_DATA = 13;
[DllImport("kernel32.dll")]
static extern DriveType GetDriveType([MarshalAs(UnmanagedType.LPStr)] string lpRootPathName);
[DllImport("kernel32.dll")]
static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
int dwDesiredAccess,
int dwShareMode,
IntPtr lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool DeviceIoControl(
IntPtr hDevice,
int dwIoControlCode,
IntPtr lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped);
const int DIGCF_PRESENT = (0x00000002);
const int DIGCF_DEVICEINTERFACE = (0x00000010);
[StructLayout(LayoutKind.Sequential)]
class SP_DEVINFO_DATA
{
public int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
public Guid classGuid = Guid.Empty;
public int devInst = 0;
public IntPtr reserved = IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
public short devicePath;
}
[StructLayout(LayoutKind.Sequential)]
class SP_DEVICE_INTERFACE_DATA
{
public int cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
public Guid interfaceClassGuid = Guid.Empty;
public int flags = 0;
public IntPtr reserved = IntPtr.Zero;
}
[DllImport("setupapi.dll")]
static extern IntPtr SetupDiGetClassDevs(
ref Guid classGuid,
int enumerator,
IntPtr hwndParent,
int flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInterfaces(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
ref Guid interfaceClassGuid,
int memberIndex,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInterfaceDetail(
IntPtr deviceInfoSet,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
int deviceInterfaceDetailDataSize,
ref int requiredSize,
SP_DEVINFO_DATA deviceInfoData);
[DllImport("setupapi.dll")]
static extern uint SetupDiDestroyDeviceInfoList(
IntPtr deviceInfoSet);
[DllImport("setupapi.dll")]
static extern int CM_Get_Parent(
ref int pdnDevInst,
int dnDevInst,
int ulFlags);
[DllImport("setupapi.dll")]
static extern int CM_Request_Device_Eject(
int dnDevInst,
out PNP_VETO_TYPE pVetoType,
StringBuilder pszVetoName,
int ulNameLength,
int ulFlags);
[DllImport("setupapi.dll", EntryPoint = "CM_Request_Device_Eject")]
static extern int CM_Request_Device_Eject_NoUi(
int dnDevInst,
IntPtr pVetoType,
StringBuilder pszVetoName,
int ulNameLength,
int ulFlags);
enum PNP_VETO_TYPE
{
Ok,
TypeUnknown,
LegacyDevice,
PendingClose,
WindowsApp,
WindowsService,
OutstandingOpen,
Device,
Driver,
IllegalDeviceRequest,
InsufficientPower,
NonDisableable,
LegacyDriver,
InsufficientRights
}
public static bool RemoveDrive(string driveCharWithColon)
{
IntPtr hVolume = CreateFile(@"\\.\" + driveCharWithColon, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hVolume.ToInt32() == -1) return false;
long DeviceNumber = GetDeviceNumber(hVolume);
if (DeviceNumber == -1) return false;
string rootPath = driveCharWithColon + "\\";
DriveType driveType = GetDriveType(rootPath);
StringBuilder pathInformation = new StringBuilder(250);
uint res = QueryDosDevice(driveCharWithColon, pathInformation, 250);
if (res == 0) return false;
long DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, driveType, pathInformation.ToString());
if (DevInst == 0) return false;
int DevInstParent = 0;
CM_Get_Parent(ref DevInstParent, (int)DevInst, 0);
for (int tries = 1; tries <= 3; tries++)
{
int r = CM_Request_Device_Eject_NoUi(DevInstParent, IntPtr.Zero, null, 0, 0);
if (r == 0) return true;
Thread.Sleep(500);
}
return false;
}
static long GetDeviceNumber(IntPtr handle)
{
long DeviceNumber = -1;
int size = 0x400;
IntPtr buffer = Marshal.AllocHGlobal(size);
int bytesReturned = 0;
try
{
DeviceIoControl(handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, buffer, size, out bytesReturned, IntPtr.Zero);
}
finally
{
CloseHandle(handle);
}
if (bytesReturned > 0)
{
STORAGE_DEVICE_NUMBER sdn = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(buffer, typeof(STORAGE_DEVICE_NUMBER));
DeviceNumber = sdn.DeviceNumber;
}
Marshal.FreeHGlobal(buffer);
return DeviceNumber;
}
static long GetDrivesDevInstByDeviceNumber(long DeviceNumber, DriveType DriveType, string dosDeviceName)
{
bool IsFloppy = dosDeviceName.Contains("\\Floppy");
Guid guid;
switch (DriveType)
{
case DriveType.DRIVE_REMOVABLE:
if (IsFloppy) guid = new Guid(GUID_DEVINTERFACE_FLOPPY);
else guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_FIXED:
guid = new Guid(GUID_DEVINTERFACE_DISK);
break;
case DriveType.DRIVE_CDROM:
guid = new Guid(GUID_DEVINTERFACE_CDROM);
break;
default:
return 0;
}
IntPtr hDevInfo = SetupDiGetClassDevs(ref guid, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo.ToInt64() == INVALID_HANDLE_VALUE) throw new Win32Exception(Marshal.GetLastWin32Error());
int dwIndex = 0;
while (true)
{
SP_DEVICE_INTERFACE_DATA interfaceData = new SP_DEVICE_INTERFACE_DATA();
if (!SetupDiEnumDeviceInterfaces(hDevInfo, null, ref guid, dwIndex, interfaceData))
{
int error = Marshal.GetLastWin32Error();
if (error != ERROR_NO_MORE_ITEMS) throw new Win32Exception(error);
break;
}
SP_DEVINFO_DATA devData = new SP_DEVINFO_DATA();
int size = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, interfaceData, IntPtr.Zero, 0, ref size, devData))
{
int error = Marshal.GetLastWin32Error();
if (error != ERROR_INSUFFICIENT_BUFFER) throw new Win32Exception(error);
}
IntPtr buffer = Marshal.AllocHGlobal(size);
SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
if (IntPtr.Size == 8)
detailData.cbSize = 8;
else
detailData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
Marshal.StructureToPtr(detailData, buffer, false);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, interfaceData, buffer, size, ref size, devData))
{
Marshal.FreeHGlobal(buffer);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
IntPtr pDevicePath = (IntPtr)((Int64)buffer + Marshal.SizeOf(typeof(int)));
string devicePath = Marshal.PtrToStringAuto(pDevicePath);
Marshal.FreeHGlobal(buffer);
IntPtr hDrive = CreateFile(devicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hDrive.ToInt64() != INVALID_HANDLE_VALUE)
{
long driveDeviceNumber = GetDeviceNumber(hDrive);
if (DeviceNumber == driveDeviceNumber)
{
SetupDiDestroyDeviceInfoList(hDevInfo);
return devData.devInst;
}
}
dwIndex++;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;<pre lang="c#"><pre lang="c#">
}
static void Test()
{
bool ok = RemoveDrive("H:");
}
}
}
|
|
|
|
|
When I remove the USB, "Windows8" In does not display in a pop-up.
Please tell me the reason.
|
|
|
|
|
Yes, Windows just doesn't show that anymore.
|
|
|
|
|
Thank you, you saved my day! This was very helpful!
Also, maybe you know how to tell this method to wait untill device is free to eject?
|
|
|
|
|
Where does the resulting "Ok" value come from? I cannot find the specification of this and the
PNP_VetoTypeUnknown is already 0.
Thx in advance
Ruud
|
|
|
|
|
It would very nice if someone could explain this behaviour
|
|
|
|
|
Thank you very much~~~
|
|
|
|
|
Looks like CloseHandle didn't work in net 4.0. It throw SEHException. Some similar discussion founded here http://stackoverflow.com/questions/9867334/why-is-the-handling-of-exceptions-from-closehandle-different-between-net-4-and et-4-and
|
|
|
|
|
I use this code also in .NET 4.0 (x86) on different OS (XP, W7 32/64, W8 64).
I can now reproduce the exception only with the debugger attached. It works correct without debugger. I figured out that CloseHandle was called twice (first inside GetDeviceNumber(..)).
Remove the two second CloseHandle and it will also work with debugger attached.
static long GetDrivesDevInstByDeviceNumber( long ....
.....
IntPtr hDrive = CreateFile( devicePath, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero );
if ( hDrive.ToInt32( ) != INVALID_HANDLE_VALUE )
{
long driveDeviceNumber = GetDeviceNumber( hDrive );
if ( DeviceNumber == driveDeviceNumber )
{
CloseHandle( hDrive );
SetupDiDestroyDeviceInfoList( hDevInfo );
return devData.devInst;
}
CloseHandle( hDrive );
}
dwIndex++;
|
|
|
|
|
Using Hungarian notation in C# and not following the naming convention of variables?
|
|
|
|
|
|
Thank you and you have my 5 !
There is always hope ..!
|
|
|
|
|