Я работаю над реализацией функции безопасного извлечения на C#, которая использует импорт из C++ через пространство имен System.Runtime.InteropServices.
Хотя функция работает должным образом для USB-устройств хранения данных он не работает с устройствами SCSI.
Я заметил, что эти более крупные диски можно извлечь только с помощью встроенной функции «Безопасное извлечение устройства и извлечение носителя». », которая, похоже, не имеет соответствующего API и не позволяет передавать аргументы.
Есть ли способ программно включить безопасное извлечение флэш-накопителей большего размера?
Изменить. Мне действительно нужна функция для извлечения устройств SCSI. Когда я вызываю DeviceIOControl, функция с такими аргументами, как IOCTL_STORAGE_EJECT_MEDIA и IOCTL_STORAGE_MEDIA_REMOVAL, тоже завершается сбоем
Кроме того, я увидел, что моя политика устройств SCSI по умолчанию определена как более высокая производительность, и, похоже, мне нужно изменить их политику на быстрое удаление, чтобы разрешить извлечение за пределы специального приложения win10/11. Но я не могу перейти к политике в соответствии с «Настройки устройства». Что мне делать?
фрагмент кода:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace USBRemoval
{
internal class USBMagic
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
byte[] lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
private IntPtr handle = IntPtr.Zero;
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int FSCTL_LOCK_VOLUME = 0x00090018;
const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;
///
/// Constructor for the USBEject class
///
/// This should be the drive letter. Format: F:/, C:/..
public static IntPtr USBEject(string driveLetter)
{
string filename = @"\\.\" + driveLetter[0] + ":";
return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
}
public static bool Eject(IntPtr handle)
{
bool result = false;
if (LockVolume(handle) && DismountVolume(handle))
{
PreventRemovalOfVolume(handle, false);
result = AutoEjectVolume(handle);
}
CloseHandle(handle);
return result;
}
private static bool LockVolume(IntPtr handle)
{
uint byteReturned;
for (int i = 0; i < 10; i++)
{
if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
{
return true;
}
Thread.Sleep(500);
}
return false;
}
private static bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
{
byte[] buf = new byte[1];
uint retVal;
buf[0] = (prevent) ? (byte)1 : (byte)0;
return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
}
private static bool DismountVolume(IntPtr handle)
{
uint byteReturned;
return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
}
private static bool AutoEjectVolume(IntPtr handle)
{
uint byteReturned;
return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
}
private bool CloseVolume(IntPtr handle)
{
return CloseHandle(handle);
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... isk-drives
Невозможно безопасно извлечь диски SCSI. ⇐ C#
Место общения программистов C#
1729000526
Anonymous
Я работаю над реализацией функции безопасного извлечения на C#, которая использует импорт из C++ через пространство имен System.Runtime.InteropServices.
Хотя функция работает должным образом для USB-устройств хранения данных он не работает с устройствами SCSI.
Я заметил, что эти более крупные диски можно извлечь только с помощью встроенной функции «Безопасное извлечение устройства и извлечение носителя». », которая, похоже, не имеет соответствующего API и не позволяет передавать аргументы.
Есть ли способ программно включить безопасное извлечение флэш-накопителей большего размера?
Изменить. Мне действительно нужна функция для извлечения устройств SCSI. Когда я вызываю DeviceIOControl, функция с такими аргументами, как IOCTL_STORAGE_EJECT_MEDIA и IOCTL_STORAGE_MEDIA_REMOVAL, тоже завершается сбоем
Кроме того, я увидел, что моя политика устройств SCSI по умолчанию определена как более высокая производительность, и, похоже, мне нужно изменить их политику на быстрое удаление, чтобы разрешить извлечение за пределы специального приложения win10/11. Но я не могу перейти к политике в соответствии с «Настройки устройства». Что мне делать?
фрагмент кода:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace USBRemoval
{
internal class USBMagic
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
byte[] lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
private IntPtr handle = IntPtr.Zero;
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int FSCTL_LOCK_VOLUME = 0x00090018;
const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;
///
/// Constructor for the USBEject class
///
/// This should be the drive letter. Format: F:/, C:/..
public static IntPtr USBEject(string driveLetter)
{
string filename = @"\\.\" + driveLetter[0] + ":";
return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
}
public static bool Eject(IntPtr handle)
{
bool result = false;
if (LockVolume(handle) && DismountVolume(handle))
{
PreventRemovalOfVolume(handle, false);
result = AutoEjectVolume(handle);
}
CloseHandle(handle);
return result;
}
private static bool LockVolume(IntPtr handle)
{
uint byteReturned;
for (int i = 0; i < 10; i++)
{
if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
{
return true;
}
Thread.Sleep(500);
}
return false;
}
private static bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
{
byte[] buf = new byte[1];
uint retVal;
buf[0] = (prevent) ? (byte)1 : (byte)0;
return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
}
private static bool DismountVolume(IntPtr handle)
{
uint byteReturned;
return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
}
private static bool AutoEjectVolume(IntPtr handle)
{
uint byteReturned;
return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
}
private bool CloseVolume(IntPtr handle)
{
return CloseHandle(handle);
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79086923/cant-safely-eject-scsi-disk-drives[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия