【问题标题】:C# WriteFile() Stops Writing at Sector 242 on USB DrivesC# WriteFile() 在 USB 驱动器的 242 扇区停止写入
【发布时间】:2012-08-18 08:40:57
【问题描述】:

我编写了以下代码,将 0xFF 写入我的 USB 存储设备上的所有字节。出于某种原因,WriteFile() 调用在第 242 扇区开始出错。我在两个单独的 USB 存储设备上完成了此操作,然后在十六进制编辑器中检查了这些设备。扇区 242 似乎是 FAT16 格式化设备上文件分配表的开始和 NTFS 设备上引导区的开始。我确信它在这些确切位置出错并非巧合,但是我不知道如何改变这种行为。当WriteFile 失败时我收到的HRESULT 是-2147024891,即E_ACCESSDENIED。有谁知道是什么导致了这个问题?

注意:如果您要在本地系统上运行此代码,请务必小心,因为我已经硬编码了我的 USB 设备的物理设备 ID。请务必使用您尝试写入的设备更新 deviceId 变量。您不想破坏您的硬盘。

    public enum EMoveMethod : uint
    {
        Begin = 0,
        Current = 1,
        End = 2
    }

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint SetFilePointer([In] SafeFileHandle hFile, [In] long lDistanceToMove, [Out] out int lpDistanceToMoveHigh, [In] EMoveMethod dwMoveMethod);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

    [DllImport("kernel32", SetLastError = true)]
    internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes, int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);

    [DllImport("kernel32.dll", SetLastError = true)]
    internal extern static int WriteFile(SafeFileHandle handle, byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr overlapped_MustBeZero);

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool DeviceIoControl(SafeFileHandle hDevice, uint dwIoControlCode, byte[] lpInBuffer, int nInBufferSize, byte[] lpOutBuffer, int nOutBufferSize, out int lpBytesReturned, IntPtr lpOverlapped);

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool CloseHandle(SafeFileHandle handle);

public void wipeDisk()
{
        const uint OPEN_EXISTING = 3;
        const uint GENERIC_WRITE = (0x40000000);
        const uint FSCTL_LOCK_VOLUME = 0x00090018;
        const uint FSCTL_UNLOCK_VOLUME = 0x0009001c;
        const uint FSCTL_DISMOUNT_VOLUME = 0x00090020;

        bool success = false;
        int intOut;
        string deviceId = @"\\.\PHYSICALDRIVE2";
        long DiskSize = 2056320000;

        SafeFileHandle diskHandle = CreateFile(deviceId, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        if (diskHandle.IsInvalid)
        {
            Console.WriteLine(deviceId + " open error.");
            return;
        }

        Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": opened.");

        success = DeviceIoControl(diskHandle, FSCTL_LOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
        if (!success)
        {
            Console.WriteLine(deviceId + " lock error.");
            CloseHandle(diskHandle);
            return;
        }

        Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": locked.");

        success = DeviceIoControl(diskHandle, FSCTL_DISMOUNT_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
        if (!success)
        {
            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": dismount error.");
            DeviceIoControl(diskHandle, FSCTL_UNLOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
            CloseHandle(diskHandle);
            return;
        }

        Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unmounted.");

        int numBytesPerSector = 512;
        long numTotalSectors = DiskSize / 512;

        byte[] junkBytes = new byte[512];
        for (int x = 0; x < 512; x++)
        {
            junkBytes[x] = 0xFF;
        }

        for (long sectorNum = 0; sectorNum < numTotalSectors; sectorNum++)
        {
            int numBytesWritten = 0;
            int moveToHigh;

            uint rvalsfp = SetFilePointer(diskHandle, sectorNum * numBytesPerSector, out moveToHigh, EMoveMethod.Begin);

            Console.WriteLine("File pointer set " + Marshal.GetHRForLastWin32Error().ToString() + ": " + (sectorNum * numBytesPerSector).ToString());

            int rval = WriteFile(diskHandle, junkBytes, junkBytes.Length, out numBytesWritten, IntPtr.Zero);

            if (numBytesWritten != junkBytes.Length)
            {
                Console.WriteLine("Write error on track " + sectorNum.ToString() + " from " + (sectorNum * numBytesPerSector).ToString() + "-" + moveToHigh.ToString() + " " + Marshal.GetHRForLastWin32Error().ToString() + ": Only " + numBytesWritten.ToString() + "/" + junkBytes.Length.ToString() + " bytes written.");
                break;
            }
            else
            {
                Console.WriteLine("Write success " + Marshal.GetHRForLastWin32Error().ToString() + ": " + numBytesWritten.ToString() + "/" + junkBytes.Length.ToString() + " bytes written.");
            }
        }

        success = DeviceIoControl(diskHandle, FSCTL_UNLOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
        if (success)
        {
            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unlocked.");
        }
        else
        {
            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unlock error: " + Marshal.GetHRForLastWin32Error().ToString());
        }

        success = CloseHandle(diskHandle);
        if (success)
        {
            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": handle closed.");
        }
        else
        {
            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": close handle error: " + Marshal.GetHRForLastWin32Error().ToString());
        }
}

编辑/更新

在使用第三方工具对 USB 设备进行低级别擦除后,我能够使其成功运行。驱动器完全归零后,我能够成功写入设备。似乎 Windows 在识别出有效的 fat 或 ntfs 文件系统以及使用

    const uint FSCTL_LOCK_VOLUME = 0x00090018;
    const uint FSCTL_DISMOUNT_VOLUME = 0x00090020;

DeviceIoControl 配对似乎不会覆盖设备上的锁定窗口。

有谁知道如何在具有有效文件系统的驱动器上使用 DeviceIoControl 在 Windows 中成功锁定可移动 USB 设备?

我已经使用了几个第三方工具来做我想做的事情,并且它们运行良好。我知道这是可能的,但我阅读的所有 MSDN 文档都没有帮助解决问题。

编辑/更新 2

这取自https://web.archive.org/web/20130507212546/http://msdn.microsoft.com/en-us/library/ff551353.aspx

应用程序在发出 DASD I/O 之前需要锁定卷、卸载卷或两者兼而有之。这是 Windows Vista 的新功能,旨在解决潜在的恶意技术。

  1. 文件系统将阻止对磁盘保留部分的所有写操作。在这种情况下,那些保留部分包括 MBR 和两个 FAT 区域。要阻止这些区域,您需要通过发送 FSCTL_LOCK_VOLUME 来锁定卷。您必须在执行实际写入操作的同一卷句柄上发出此结构。如果有打开的文件句柄,此请求可能会失败。在这种情况下,应用程序可以通过发出 FSCTL_DISMOUNT_VOLUME 来强制卸载文件系统。但是,在文件句柄关闭之前,不会真正卸载卷。在此之前,应用程序可以使用当前打开的相同文件句柄继续发出 DASD I/O。

  2. 在文件系统已知的卷空间之外有一个扩展区域,写入操作将被阻止。要允许对该区域进行写操作,您必须在卷句柄上发出 FSCTL_ALLOW_EXTENDED_DASD_IO。

您可以使用 Win32 API 例程 DeviceIoControl 来发出所有以前的 FSCTS。

我相信这正是我们在上面的代码中实现的,但它似乎不能正常工作。我们得到了一个句柄,并且正在锁定和卸载设备,所以我们应该能够正确地写入受保护的区域?

编辑/更新 3

好的,这是当前打开磁盘和卷的顺序.. 锁定、卸载等方法只是按照我们认为错误的顺序工作..

SafeFileHandle volumeHandle = CreateFile("\\.\E:",...);
LockVolume(volumeHandle);
DismountVolume(volumeHandle);
SafeFileHandle diskHandle = CreateFile("\\.\PHYSICALDRIVE1"...);
WriteStuff(diskHandle);
//Fails...
UnlockVolume(volumeHandle);
CloseVolume(volumeHandle);
CloseDisk(diskHandle);

我仍然得到相同的结果,它仅在磁盘被丢弃时才有效。

【问题讨论】:

  • 我知道它没有回答这个问题,但我相信有磁盘实用程序可以将驱动器上的所有位设置为 1 或 0。这是学术/有趣的事情还是有业务需要这样的实用程序吗? PS 赞成这个问题,因为它很有趣,尽管我不知道你将如何解决它。
  • 最终我将使用与此类似的方法将二进制磁盘映像文件“dd”回物理设备。这个特定示例只是用于测试 C# 将二进制数据写入物理设备的能力。我有几个工具可以为我做这件事,但我需要一个 C# 接口来处理我正在处理的代码。
  • 纯粹出于兴趣,我会自己玩一个游戏,如果我有任何事情,请告诉您 - 我有一些 U 盘可以尝试一下。
  • 如果您有病毒扫描程序,它可能会拒绝访问引导扇区。您可以写入超过 242 的任何扇区吗?
  • 它似乎不允许我写入超过 242 的任何扇区。前 241 个扇区的驱动器闪烁,我在十六进制编辑器中验证了所有 241 都填充了 0xFF。 242 有点奇怪……

标签: c# file-io deviceiocontrol


【解决方案1】:

diskdrive 在这里混淆了。

如果您想完全访问 磁盘(这是您使用 \\.\PHYSICALDRIVE 时的情况),您必须锁定所有 已安装的卷,它们基​​本上是您物理磁盘的所有分区(即驱动器

不要在CreateFile("\\.\PHYSICALDRIVE"...) 返回的句柄上使用FSCTL_LOCK_VOLUME,而是使用string.Replace("\\\\.\\{0}:", DriveLetter) 模式获取每个安装的卷(它是驱动器,而不是物理磁盘)的句柄。

您可以使用IOCTL_DISK_GET_DRIVE_LAYOUT 获取给定物理磁盘的已安装卷列表(最终,您需要一个字母列表)。


编辑:

来自MSDN

如果满足以下条件之一,则磁盘句柄上的写入将成功 条件为真:

要写入的扇区不属于 卷的范围。

要写入的扇区属于已安装的扇区 卷,但您已通过以下方式显式锁定或卸载卷 使用 FSCTL_LOCK_VOLUME 或 FSCTL_DISMOUNT_VOLUME。

要成为的行业 写入到没有安装其他文件系统的卷中 比RAW。

所以基本上,你应该做的是:

  • 获取每个卷的句柄
  • 在每个卷上使用FSCTL_LOCK_VOLUME FSCTL_DISMOUNT_VOLUME。如果卷中没有文件被使用(即任何进程都没有打开任何文件的句柄),FSCTL_LOCK_VOLUME 就足够了
  • 获取物理磁盘的句柄
  • 写入物理磁盘
  • 关闭两个手柄。关闭音量手柄将解除锁定。

同时确保您以管理员权限运行您的应用程序(提升的进程)。

【讨论】:

  • 好的,这是有道理的。但是我是否也使用 FSCTL_LOCK_VOLUME 锁定磁盘?我改变了我的代码来处理卷、锁定卷、卸载卷、解锁卷、关闭句柄。然后在磁盘上打开一个句柄,锁定磁盘,卸载磁盘,写入磁盘[失败],解锁磁盘,关闭句柄。
  • @BrandonStout FSCTL_LOCK_VOLUME/FSCTL_DISMOUNT_VOLUME 在卷上应该足够了。然后写入磁盘。然后解锁。在完成写入磁盘之前,不要关闭卷的句柄。关闭手柄将释放锁。
  • 请查看我帖子中的编辑 3,如果您建议的顺序正确,请告诉我。
  • 您的回答帮助我找到了解决方案,尽管我最终不得不以不同的方式解决问题。由于某种原因,我仍然无法写入整个磁盘,直到 FAT 条目仍然只有前 242 个扇区。但是根据您的建议,我想出了一个解决方法。我将在答案中发布我的做法。再次感谢您的帮助!
【解决方案2】:

我猜你正在使用Windows Vista 或更高版本。操作系统将阻止任何直接写入这些扇区的尝试,因此您需要先进行锁定。更多信息在这里:

http://msdn.microsoft.com/en-us/library/ff551353.aspx

也刚刚签到所以提出了这个帖子:

CreateFile: direct write operation to raw disk "Access is denied" - Vista, Win7

那里的调查信息可能会有所帮助,HTH...

【讨论】:

  • 我已经锁定和卸载 USB 设备,如上面的代码中所述。您链接的页面解释了我们已经在做的所有事情,尽管现在我要回去仔细检查我所有的锁定和卸载等。在我 100% 确定这不是问题后,我会和你一起检查。
【解决方案3】:

编辑

我已编辑此答案以反映 ken2k 的建议。

ken2k 的建议确实解决了我遇到的问题。我不确定为什么我之前使用该方法的尝试没有成功,但是我刚刚重新访问/调整了我的代码,并且该方法似乎确实可以正常工作。

以下是我用来解决此问题的步骤:

  • 获取物理磁盘的句柄
  • 获取物理磁盘上每个逻辑驱动器的句柄
  • 锁定物理磁盘上的每个驱动器
  • 卸载物理磁盘上的每个驱动器
  • 锁定物理磁盘(可选)
  • 卸载物理磁盘(可选)
  • 使用物理磁盘句柄将整个物理磁盘归零
  • 解锁每个逻辑驱动器
  • 解锁物理磁盘(仅当您选择锁定磁盘时)
  • 关闭逻辑驱动器句柄
  • 关闭物理磁盘句柄

注意:如果您希望在不终止程序的情况下执行背靠背磁盘操作,并且您已使用 FSCTL_DISMOUNT_VOLUME 功能,则需要使用类似于以下内容的“重新挂载”磁盘:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive");

System.IO.DriveInfo.GetDrives();

当您尝试锁定每个单独的逻辑驱动器时,要将逻辑驱动器 ID 映射到物理磁盘 ID,请使用以下代码将逻辑驱动器标签链接到物理磁盘标签:

    List<string> driveLetters = new List<string>();
    string deviceId = @"\\.\PHYSICALDRIVE1";
    string queryString = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + deviceId + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
    ManagementObjectSearcher diskSearcher = new ManagementObjectSearcher("root\\CIMV2", queryString);
    ManagementObjectCollection diskMoc = diskSearcher.Get();
    foreach (ManagementObject diskMo in diskMoc)
    {
        queryString = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + diskMo["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";
        ManagementObjectSearcher driveSearcher = new ManagementObjectSearcher("root\\CIMV2", queryString);

        ManagementObjectCollection driveMoc = driveSearcher.Get();
        foreach (ManagementObject driveMo in driveMoc)
        {
            driveLetters.Add("\\\\.\\" + driveMo["DeviceID"].ToString());
        }
    }

例如,如果物理磁盘标签为\\.\PHYSICALDRIVE1,并且它包含一个驱动器号为“E”的逻辑驱动器,则上述代码会将\\.\E: 映射到\\.\PHYSICALDRIVE1

根据 ken2k 的建议,此映射也可以使用 IOCTL_DISK_GET_DRIVE_LAYOUT 功能完成。

【讨论】:

  • 很高兴看到您找到了解决方案,但我不明白为什么您在锁定分区后无法写入 FAT 磁盘。老实说,我写了一些我还没有发布的 .Net hex/disk 编辑器软件,我可以使用所描述的方法成功地写入我的磁盘(Windows 7)。我无法复制/粘贴我的代码(目前未知的许可/定价模型),但我所做的与我之前描述的几乎相同。奇怪的是你不能让它工作。
  • 我们最终需要访问的不是单独的逻辑驱动器/分区,我们最终需要能够访问整个物理磁盘以从文件中恢复二进制映像。我认为在某些时候您必须锁定物理磁盘才能执行此操作,而不仅仅是驱动器。
  • 不,这不是必需的。物理磁盘不需要自己锁定。例如,如果没有挂载分区,则对磁盘没有访问限制。这也是您可以从扇区 0 写入扇区 242 的原因:如果该偏移量不是具有文件系统的分区的一部分,或者是锁定的分区的一部分,则可以写入磁盘的任何偏移量。
  • ken2k - 我能够让你的方法起作用,请参阅我上面的编辑。感谢大家的帮助!
【解决方案4】:

对于这个命令,我确实运行并检查了它。 SafeFileHandle diskHandle = CreateFile(deviceId, GENERIC_WRITE, 0/*Here*/ , IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

将 GENERIC_WRITE 参数的第一个零下一个平均更改为 3 FILE_SHARE_READ |FILE_SHARE_WRITE (1|2) 以获得好的结果。 我将其和设备 ID 更改为相同的驱动器名称 \.\f: 用于我的 USB 驱动器名称。最后我用这个代码替换了: SafeFileHandle diskHandle = CreateFile(deviceId, GENERIC_WRITE, 3 , IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); 祝你好运

【讨论】:

【解决方案5】:

我测试跟随代码并且需要修复我的 USB 磁盘以隐藏 rootkit 病毒。所以写下这段代码:

using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace RootKeyremover
{
    public partial class Form1 : Form
    {
        public enum EMoveMethod : uint
        {
            Begin = 0,
            Current = 1,
            End = 2
        }

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint SetFilePointer([In] SafeFileHandle hFile, [In] long lDistanceToMove, [Out] out int lpDistanceToMoveHigh, [In] EMoveMethod dwMoveMethod);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32", SetLastError = true)]
        internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes, int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);

        [DllImport("kernel32.dll", SetLastError = true)]
        internal extern static int WriteFile(SafeFileHandle handle, byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr overlapped_MustBeZero);

        [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
        private static extern bool DeviceIoControl(SafeFileHandle hDevice, uint dwIoControlCode, byte[] lpInBuffer, int nInBufferSize, byte[] lpOutBuffer, int nOutBufferSize, out int lpBytesReturned, IntPtr lpOverlapped);

        [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
        private static extern bool CloseHandle(SafeFileHandle handle);

        public Form1()
        {
            InitializeComponent();
        }

                   
        public void wipeDisk()
        {
            const short FILE_ATTRIBUTE_NORMAL = 0x80;
            const short INVALID_HANDLE_VALUE = -1;
            const uint GENERIC_READ = 0x80000000;
            const uint OPEN_EXISTING = 3;
            const uint GENERIC_WRITE = (0x40000000);
            const uint FSCTL_LOCK_VOLUME = 0x00090018;
            const uint FSCTL_UNLOCK_VOLUME = 0x0009001c;
            const uint FSCTL_DISMOUNT_VOLUME = 0x00090020;

            bool success = false;
            int intOut;
            //@"\\.\PHYSICALDRIVE2"
            string deviceId = @"\\.\" + comboBox1.Text.Substring(0,2);
            long DiskSize = 2056320000;

            SafeFileHandle diskHandle = CreateFile(deviceId, GENERIC_READ | GENERIC_WRITE, 3, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (diskHandle.IsInvalid)
            {
                Console.WriteLine(deviceId + " open error.");
                return;
            }

            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": opened.");

            success = DeviceIoControl(diskHandle, FSCTL_LOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
            if (!success)
            {
                Console.WriteLine(deviceId + " lock error.");
                CloseHandle(diskHandle);
                return;
            }

            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": locked.");

            success = DeviceIoControl(diskHandle, FSCTL_DISMOUNT_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
            if (!success)
            {
                Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": dismount error.");
                DeviceIoControl(diskHandle, FSCTL_UNLOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
                CloseHandle(diskHandle);
                return;
            }

            Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unmounted.");

            int numBytesPerSector = 512;
            long numTotalSectors = DiskSize / 512;

            byte[] junkBytes = new byte[512];

            
            int k =0 ;
            IntPtr l= (IntPtr)0 ;
            SetFilePointer(diskHandle, 0, out k, EMoveMethod.Begin);
            ReadFile(diskHandle, junkBytes, (int)512,out k,l);
            //3e 17e 1f1-1fb
            //for (int x = 0x3e; x < 0x17e; x++)
            //{
            //    junkBytes[x] = 0x00;
            //}
            //for (int x = 0x1f1; x < 0x1fb; x++)
            //{
            //    junkBytes[x] = 0x00;
            //}
            for (int x = 0x1e1; x < 0x1ee; x++)
            {
                junkBytes[x] = 0x00;
            }

            //diskHandle = CreateFile(deviceId, GENERIC_WRITE, 3, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            for (long sectorNum = 0; sectorNum < 1; sectorNum++)
            {
                int numBytesWritten = 0;
                int moveToHigh;

                uint rvalsfp = SetFilePointer(diskHandle, sectorNum * numBytesPerSector, out moveToHigh, EMoveMethod.Begin);

                Console.WriteLine("File pointer set " + Marshal.GetHRForLastWin32Error().ToString() + ": " + (sectorNum * numBytesPerSector).ToString());

                int rval = WriteFile(diskHandle, junkBytes, junkBytes.Length, out numBytesWritten, IntPtr.Zero);

                if (numBytesWritten != junkBytes.Length)
                {
                    Console.WriteLine("Write error on track " + sectorNum.ToString() + " from " + (sectorNum * numBytesPerSector).ToString() + "-" + moveToHigh.ToString() + " " + Marshal.GetHRForLastWin32Error().ToString() + ": Only " + numBytesWritten.ToString() + "/" + junkBytes.Length.ToString() + " bytes written.");
                    break;
                }
                else
                {
                    Console.WriteLine("Write success " + Marshal.GetHRForLastWin32Error().ToString() + ": " + numBytesWritten.ToString() + "/" + junkBytes.Length.ToString() + " bytes written.");
                }
            }

            success = DeviceIoControl(diskHandle, FSCTL_UNLOCK_VOLUME, null, 0, null, 0, out intOut, IntPtr.Zero);
            if (success)
            {
                Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unlocked.");
            }
            else
            {
                Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": unlock error: " + Marshal.GetHRForLastWin32Error().ToString());
            }

            success = CloseHandle(diskHandle);
            if (success)
            {
                Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": handle closed.");
            }
            else
            {
                Console.WriteLine(deviceId + " " + Marshal.GetHRForLastWin32Error().ToString() + ": close handle error: " + Marshal.GetHRForLastWin32Error().ToString());
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            wipeDisk();
            MessageBox.Show("اتمام عملیات پاک سازی");
        }

        private void comboBox1_Click(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                if (drive.DriveType == DriveType.Removable)
                {
                    comboBox1.Items.Add(drive.Name);
                }
            }
            if (comboBox1.Items.Count <= 0)
                button2.Enabled = false;
            else
            {
                button2.Enabled = true;
                comboBox1.SelectedIndex = 0;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1_Click(null, null);

        }
    }
}

【讨论】:

  • **我只是删除消息而不是引导加载程序执行代码
猜你喜欢
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 2014-06-25
  • 2021-12-27
  • 2016-03-10
  • 1970-01-01
相关资源
最近更新 更多