Установите для текущего состояния «Только чтение» значение «Да» для диска.C#

Место общения программистов C#
Ответить
Anonymous
 Установите для текущего состояния «Только чтение» значение «Да» для диска.

Сообщение Anonymous »

Я пытался сделать диск доступным только для чтения, и через несколько дней мне это удалось.
Я получил ссылку отсюда и постараюсь добавить больше функций для практических целей!
Я также видел, что некоторые люди вы делаете это из реестра Windows, будет ли это действительным или позже не возникнет проблем?

Код: Выделить всё

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;

const uint IOCTL_DISK_SET_DISK_ATTRIBUTES = 0x0007c0f4;
const ulong DISK_ATTRIBUTE_READ_ONLY = 0x0000000000000002;

[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
);

[StructLayout(LayoutKind.Sequential)]
struct SET_DISK_ATTRIBUTES
{
public uint Version;
[MarshalAs(UnmanagedType.I1)]
public bool Persist;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved1;
public ulong Attributes;
public ulong AttributesMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] Reserved2;
};

public Form1()
{
InitializeComponent();
}

public IntPtr CreateHandle(int diskNumber)
{
string filename = @"\\.\\PhysicalDrive" + diskNumber;
IntPtr handle = CreateFile(
filename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
3, // OPEN_EXISTING
0, // No special flags
IntPtr.Zero
);

if (handle == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
MessageBox.Show("Failed to create handle. Error: " + new Win32Exception(errorCode).Message);
}
return handle;
}

private void SetReadonly(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
MessageBox.Show("Handle is invalid.");
return;
}

var sda = new SET_DISK_ATTRIBUTES
{
Version = (uint)Marshal.SizeOf(),
Persist = true,
AttributesMask = DISK_ATTRIBUTE_READ_ONLY,
Attributes = DISK_ATTRIBUTE_READ_ONLY,
Reserved1 = new byte[3],
Reserved2 = new uint[4]
};

IntPtr ptrQuery = Marshal.AllocHGlobal(Marshal.SizeOf(sda));
try
{
Marshal.StructureToPtr(sda, ptrQuery, false);
uint byteReturned;

// Set the disk to read-only
bool res = DeviceIoControl(handle, IOCTL_DISK_SET_DISK_ATTRIBUTES, ptrQuery, (uint)Marshal.SizeOf(sda), IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
if (!res)
{
MessageBox.Show("Failed to set readonly.  Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
}
finally
{
Marshal.FreeHGlobal(ptrQuery);
}
}

private void DisplayDiskAttributes(int diskNumber,string Msg)
{
MessageBox.Show(Msg);
}

private void button1_Click(object sender, EventArgs e)
{
if (int.TryParse(textBox1.Text.Trim(), out int diskNumber) && diskNumber >= 0)
{
IntPtr handle = CreateHandle(diskNumber);
SetReadonly(handle); // Set to read-only
DisplayDiskAttributes(diskNumber, "Set to Read only succesfuul");
}
else
{
MessageBox.Show("Please enter a valid disk number (e.g., 0, 1, 2).");
}
}
}
}
Когда я использую DiskPart для отображения атрибута, он выглядит следующим образом:
  • Текущее состояние только для чтения: Да
  • Только чтение: Да
  • Загрузочный диск: Нет
  • Диск с файлами подкачки: Нет
  • Диск с файлами гибернации: Нет
  • Диск аварийного дампа: Нет
  • Кластерный диск: Нет
Но я хотел сделать так:
  • Текущий Состояние только для чтения: Да
  • Только для чтения: Нет
  • Загрузочный диск: Нет
  • Диск с файлами подкачки: Нет
  • Диск с файлами гибернации: Нет
  • Диск аварийного дампа: Нет
  • Кластерный диск: нет
Но я не смог найти способ сделать это возможным, потому что структура Set_Disk_Attribute не может этого сделать. это!
Есть ли другой способ?
Извините за плохой текст, я здесь новенький!
Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/790 ... for-a-disk
Ответить

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

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

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

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

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