Когда-то получалось на C++ записать текст в сектор флешки и считать текст из сектора. Код не нашел. Подготовил флешку для экспериментов:
Код:
Секторов в кластере: 2
Байт в секторе: 512
Количество свободных кластеров: 3899937
Всего кластеров: 3948543
Хотел бы на C# сделать то же самое:
Код:
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace CsWinApi
{
class Program
{
static void ShowMes(string strMes)
{
Console.WriteLine(strMes);
Console.WriteLine("\nПрограмма завершила работу. Нажмите любую клавишу\n");
Console.ReadKey();
Environment.Exit(0);
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool GetDiskFreeSpace(string lpRootPathName, out uint lpSectorsPerCluster, out uint lpBytesPerSector,
out uint lpNumberOfFreeClusters, out uint lpTotalNumberOfClusters);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile( [MarshalAs(UnmanagedType.LPTStr)] string filename,
[MarshalAs(UnmanagedType.U4)] FileAccess access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
IntPtr templateFile);
[DllImport("kernel32.dll")]
public static extern bool SetFilePointerEx(
IntPtr hFile, long liDistanceToMove,
out long lpNewFilePointer, uint dwMoveMethod);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool WriteFile( IntPtr hFile, byte[] lpBuffer, UInt32 nNumberOfBytesToWrite,
ref UInt32 lpNumberOfBytesWritten, IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetLastError();
static void Main(string[] args)
{
long nSector = 5;
// Определение параметров флешки
string sDisk = "F:";
uint sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters;
if(GetDiskFreeSpace(sDisk, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters))
{
Console.WriteLine("Секторов в кластере: {0}\nБайт в секторе: {1}\nКоличество свободных кластеров: {2}\nВсего кластеров: {3}",
sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters);
}
else
{
ShowMes("GetDiskFreeSpace - не удалось определить параметры диска");
}
if (nSector*sectorsPerCluster > totalNumberOfClusters)
{
ShowMes("На диске нет сектора с номером " + nSector.ToString());
}
// Получение указателя на флешку
sDisk = "F:";
IntPtr ptr = CreateFile("\\\\.\\" + sDisk, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
if(ptr == IntPtr.Zero) // 0xffffffff
{
ShowMes("Диск не готов для записи");
}
// Установка указателя на нужную позицию
long lpNewFilePointer = 0;
long offset = nSector * (long)bytesPerSector;
if (!SetFilePointerEx(ptr, offset, out lpNewFilePointer, 0))
{
Console.WriteLine(GetLastError());
ShowMes("Не удалось установить указатель на нужную позицию!");
}
// запись строки в сектор
uint RealityWriteCount = 0;
byte[] writeBuffer = Encoding.UTF8.GetBytes("Запись информации в сектор");
if (!WriteFile(ptr, writeBuffer, (uint)writeBuffer.Length, ref RealityWriteCount, IntPtr.Zero))
{
Console.WriteLine(GetLastError());
CloseHandle(ptr);
ShowMes("\nНе удалось записать информацию в сектор " + nSector.ToString());
}
CloseHandle(ptr);
ShowMes("");
} //main
}
}
У меня 2 вопроса:
1. Почему не получается запись в сектор (ошибка 6, не знаю, как в коде вывести содержание ошибки)?
2. как отловить ошибку создания файла. ptr == IntPtr.Zero не работает, я создавал ошибку и значение ptr при ошибки составляло 0xffffffff. Как записать правильно условие ошибки? Проект прикрепил.