Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Запись в сектор флешки и чтение информации из сектора (http://forum.oszone.net/showthread.php?t=347823)

tumanovalex 31-01-2021 19:29 2948173

Запись в сектор флешки и чтение информации из сектора
 
Когда-то получалось на 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. Как записать правильно условие ошибки? Проект прикрепил.


Время: 09:13.

Время: 09:13.
© OSzone.net 2001-