113 lines
4.1 KiB
C#
113 lines
4.1 KiB
C#
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
namespace BootsectorUtils
|
||
|
{
|
||
|
using System;
|
||
|
using System.IO;
|
||
|
|
||
|
/// <summary>
|
||
|
/// VpcFixedDiskInstaller
|
||
|
/// Console utility to install a bootsector onto a VirtualPC FIXED hard disk partition
|
||
|
/// </summary>
|
||
|
class VpcFixedDiskInstaller
|
||
|
{
|
||
|
[STAThread]
|
||
|
static void Main(string[] args)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
if (args.Length != 3)
|
||
|
throw new Exception("Error: The correct argument format is <VHD Name> <Boot Sector File> <partition>");
|
||
|
VpcFixedDiskInstaller i = new VpcFixedDiskInstaller();
|
||
|
i.Install(args[0], args[1], Convert.ToInt32(args[2]));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Console.WriteLine(e.Message);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Install(string VHDName, string BSName, int whichPartition)
|
||
|
{
|
||
|
FileStream HDFile, BSFile, BKFile;
|
||
|
int size = 512;
|
||
|
int skipsize;
|
||
|
byte [] buffer = new Byte[size];
|
||
|
byte [] oldBootSector = new Byte[size];
|
||
|
byte [] newBootSector = new Byte[size];
|
||
|
int bytesread;
|
||
|
int MBRIndex = 446;
|
||
|
int LBA;
|
||
|
string backupFilename = "backup" + System.DateTime.Now.Ticks.ToString() + ".bootsector";
|
||
|
|
||
|
|
||
|
Console.WriteLine("Setting bootsector of disk {0} in HD {1} to contents of file {2} and backing up old bootsector to {3}",
|
||
|
whichPartition, VHDName, BSName, backupFilename);
|
||
|
|
||
|
if (whichPartition>3 || whichPartition < 0)
|
||
|
{
|
||
|
throw new Exception("Error: You must choose a partition between 0 and 3.");
|
||
|
}
|
||
|
|
||
|
HDFile = File.Open(VHDName, FileMode.Open, FileAccess.ReadWrite);
|
||
|
|
||
|
// read the MBR from the VPC HDD file
|
||
|
bytesread=HDFile.Read(buffer, 0, size);
|
||
|
|
||
|
// branch based on partition type
|
||
|
MBRIndex += ((16*whichPartition)+4);
|
||
|
if ((buffer[MBRIndex]!=0x0c) && (buffer[MBRIndex]!=0x0e))
|
||
|
{
|
||
|
throw new Exception("The partition you selected is not FAT32 type 0c or 0e.");
|
||
|
}
|
||
|
|
||
|
LBA = (int) buffer[MBRIndex+7];
|
||
|
LBA = LBA*8 + buffer[MBRIndex+6];
|
||
|
LBA = LBA*8 + buffer[MBRIndex+5];
|
||
|
LBA = LBA*8 + buffer[MBRIndex+4];
|
||
|
|
||
|
// now that we know the location of the boot sector, let's grab it...
|
||
|
HDFile.Seek((LBA)*size, SeekOrigin.Begin);
|
||
|
HDFile.Read(oldBootSector, 0, size);
|
||
|
|
||
|
// read the new BootSector
|
||
|
BSFile = File.Open(BSName, FileMode.Open, FileAccess.Read);
|
||
|
bytesread = BSFile.Read(newBootSector,0,size);
|
||
|
if (bytesread != size)
|
||
|
{
|
||
|
throw new Exception("Error: The boot sector is not big enough.");
|
||
|
}
|
||
|
if (newBootSector[510]!=0x55 || newBootSector[511] != 0xAA)
|
||
|
{
|
||
|
throw new Exception("Error: The boot sector file has an invalid signature.");
|
||
|
}
|
||
|
BSFile.Close();
|
||
|
|
||
|
skipsize = newBootSector[1]+2;
|
||
|
|
||
|
// save the old boot sector:
|
||
|
BKFile = File.OpenWrite(backupFilename);
|
||
|
BKFile.Write(oldBootSector, 0, size);
|
||
|
BKFile.Close();
|
||
|
|
||
|
// generate the new boot sector by copying the BPB and FAT parameters...
|
||
|
for (int i=3;i<skipsize;i++)
|
||
|
{
|
||
|
newBootSector[i] = oldBootSector[i];
|
||
|
}
|
||
|
|
||
|
// point of no return:
|
||
|
// write the new boot sector:
|
||
|
HDFile.Seek((LBA)*size, SeekOrigin.Begin);
|
||
|
HDFile.Write(newBootSector, 0, size);
|
||
|
HDFile.Close();
|
||
|
}
|
||
|
}
|
||
|
}
|