Невозможно безопасно извлечь диски SCSI.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Невозможно безопасно извлечь диски SCSI.

Сообщение 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);
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... isk-drives
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Невозможно безопасно извлечь диски SCSI.
    Anonymous » » в форуме C#
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Невозможно безопасно извлечь большие диски программно — Win 10 и 11
    Anonymous » » в форуме C#
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Невозможно безопасно извлечь большие диски программно — Win 10 и 11
    Anonymous » » в форуме C#
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Невозможно безопасно извлечь большие диски
    Anonymous » » в форуме C#
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Не удается настроить контроллер PCI-X SCSI RAID [закрыто]
    Anonymous » » в форуме Linux
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»