Я думаю, что у вас должно получиться - я попробовал это сам, используя образ загрузочной дискеты (смонтированный как виртуальный диск с использованием ImDisk ), и полученный файл в двоичном формате идентичен исходному образу.
Для полноты вот код, который я использовал (в полном объеме):
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace ConsoleApplication1
{
public class Program
{
const int FILE_ATTRIBUTE_SYSTEM = 0x4;
const int FILE_FLAG_SEQUENTIAL_SCAN = 0x8;
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(string fileName, [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess, [MarshalAs(UnmanagedType.U4)] FileShare fileShare, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, int flags, IntPtr template);
[STAThread]
static void Main()
{
using (SafeFileHandle device = CreateFile(@"\\.\E:", FileAccess.Read, FileShare.Write | FileShare.Read | FileShare.Delete, IntPtr.Zero, FileMode.Open, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN, IntPtr.Zero))
{
if (device.IsInvalid)
{
throw new IOException("Unable to access drive. Win32 Error Code " + Marshal.GetLastWin32Error());
}
using (FileStream dest = File.Open("TempFile.bin", FileMode.Create))
{
using (FileStream src = new FileStream(device, FileAccess.Read))
{
src.CopyTo(dest);
}
}
}
}
}
}
Если это не сработает, значит, это означает, что:
- Проблема с исходным изображением.
- Проблема связана с тем, что использует только что записанный образ диска.
- Есть некоторые тонкие различия в работе с конкретным устройством, к которому вы обращаетесь (хотя я не могу понять, что)
Наиболее вероятный виновник - шаг 2. Что именно вы делаете с полученным образом диска?
Обновление: Это написано в комментариях, но для полноты я подумала, что добавлю его в свой ответ - похоже, что происходит то, что содержимое первого раздела диска написано, когда вместо этого требуется содержимое всего диска.
Когда вы смотрите на вторую шестнадцатеричную строку (созданную с помощью примера кода) примерно так: HxD , мы видим это:
ëv.MSDOS5.0..........øò.?.ÿ.?...aÈ..€.)zè!.NO NAME FAT16 ..
........................................................é..´.S3Û
Í.[Ê.<.t.èîÿCëôÃ.No BPB: Can't boot using CHS functions.P°.è¼ÿX
3ÛŽ.ä.ö.Ü..uBö.Ü..u.€>è.€r4SSRP.SUj.‹ôRPŠ.è.¸.BùÍ.ŠìXZ.d.r.€ý.u.
.ŃÒ.û‘.èxÿôëýƒ>...tðRP‹Í÷6..‹ò.Ñ;...v.‹...+Î3Ò÷6..ˆ.é.‹ø‹×QŠÁ.
L.Àæ..Ίê‹.è.´.Í.Ys.€ü.u.IëÞŠÄ.0è.ÿ´.Í.ëÑXZ.ÁƒÒ.+ét.Áá..Ùë”Ã....
úüè..^.î…..‹„ä.ŽØŽÀŽÐ.Ç„|.¯..‰„~.¹..¿..ó.¥.ÿ¬|ÿ¼..û€>è.ÿu.ˆ.è.ƒ.
ä. ¡à.‹.â.½..èéþPRët............Ó ...0€.ÿ.hA.@.ÿ@Z¬...¬.......Uª
Для меня это выглядит как загрузочный сектор раздела FAT16 - наличие строк "MSDOS5.0", "NO NAME" и "FAT16" в начале - это пустая раздача.
Сравните это с выводом первой шестнадцатеричной строки (созданной dd):
3ÀúŽØŽÐ¼.|‰æ.WŽÀûü¿..¹..ó¥ê....RR´A»ªU1É0öùÍ.r..ûUªu.Ñés.fÇ...´B
ë.Z´.Í.ƒá?Q.¶Æ@÷áRPf1Àf™èf.è!.Missing operating system...f`f1Ò».
|fRfP.Sj.j.‰æf÷6ô{Àä.ˆáˆÅ’ö6ø{ˆÆ.áA¸..Š.ú{Í..d.faÃèÄÿ¾¾}¿¾.¹ .ó¥
Ãf`‰å»¾.¹..1ÀSQö.€t.@‰ÞƒÃ.âóHt[y9Y[ŠG.<.t.$.<.u"f‹G.f‹V.f.Ðf!Òu.
f‰Âè¬ÿr.è¶ÿf‹F.è ÿƒÃ.âÌfaÃèb.Multiple active partitions...f‹D.f.
F.f‰D.è0ÿr..>þ}Uª.….ÿ¼ú{Z_.úÿäè..Operating system load error...^
¬´.Š>b.³.Í.<.uñÍ.ôëý......................................Ÿ)..€.
...þ?.?...aÈ..................................................Uª
И мы видим нечто, похожее на главную загрузочную запись . Зачем? Потому что в MBR все первые 440 байтов являются загрузочным кодом, в отличие от загрузочного сектора FAT, который содержит особый блок параметров bios (это выглядит как мусор выше, но если вы поместите это через дизассемблер, вы получите нечто, похожее на действительный 16-битный код).
Кроме того, оба они выглядят как действительные и совершенно разные загрузочные сектора (вместе с сообщениями об ошибках). Нет никакой возможности, чтобы ошибка программирования могла "исказить" одну из них, чтобы она выглядела как другая - просто должно быть, что читается неправильная вещь.
Чтобы получить CreateFile
для возврата диска вместо раздела, похоже, вам просто нужно передать ему другую строку, например, @"\\.\PhysicalDrive0"
открывает первый физический диск.
См: