
#include <windows.h>
#include <stdio.h>
#include "boot.h"
#include "BootMan.h"

char		MBRBuffer[512];
char		FileName[256];
int		MaxDrive = 0;

int __export __stdcall ReadBootSector(far char *Buffer, char Drive)
{
	return ReadMBR(Buffer, Drive);
}

int __export __stdcall GetPartitionInfo(far char *Buffer, struct _PartInfo_ *SaveBuffer, char Partition)
{
	int	c;

   // Store the boot status
   SaveBuffer->DefBoot = Buffer[PartOffset[Partition]+BOOT_INDICATOR];

	// Store the system ID
	SaveBuffer->Type = Buffer[PartOffset[Partition]+SYSTEM_ID];

   // Find out if we have our boot loader installed already...
   // The boot loader version is stored in the first 50 bytes of the code so
   // that versions won't be intermixed and cause possible problems.
   if (memcmp(Buffer, BootCode, 300) == 0) {
		memcpy(SaveBuffer->BootID, &Buffer[BOOTIDTABLE+(Partition*12)], 11);
   } else {
   	memset(&SaveBuffer->BootID, 0, 11);
   }

	// Find the User friendly system name for this partition
   for(c=0;PartName[c].Type;c++) {
   	if(SaveBuffer->Type == PartName[c].Type)
      	break;
   }
   // Save what we found
   strcpy(SaveBuffer->strType, PartName[c].strName);

   // Are we 'gonna let it be bootable?
   SaveBuffer->CanBoot = PartName[c].CanBoot;

   return TRUE;
}

int __export __stdcall WriteBootInfo(far char MinPartInfo[4][11], char Drive)
{
	int	c;

	// Try and read the desired boot sector
	if (ReadMBR(MBRBuffer, Drive) == FALSE)
      return FALSE;

   // Find out if we have our boot loader installed already...
   if (memcmp(MBRBuffer, BootCode, 300)) {
   	// No, so update the MBR with our code
		memcpy(MBRBuffer, BootCode, sizeof(BootCode));
   }

   // Flag this as a valid partition
   MBRBuffer[510] = 0x55;
   MBRBuffer[511] = 0xaa;

   // Update the Boot Information
	for(c=0;c<4;c++) {
		memcpy(&MBRBuffer[BOOTIDTABLE+(c*12)], &MinPartInfo[c], 11);
   }

   // Check if there is another drive to follow...
   if (Drive < MaxDrive -1)
   	MBRBuffer[BOOTIDTABLE+(4*11)] = 3;

   // Write the new information...
   return WriteMBR(MBRBuffer, Drive);
}

int ReadMBR(far char *Buffer, char Drive)
{
	HANDLE	hDevice;
   DWORD		nBytesRead;

   // Try and read the Master boot record from the specified drive
   sprintf(FileName, "\\\\.\\PhysicalDrive%d", Drive);

   hDevice = CreateFile(FileName, GENERIC_READ,
   	FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
      OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);

   // Exit if failed to open the device
   if(hDevice == NULL)
   	return FALSE;

   // Out internal flag of the maximum number of drives
   if(Drive > MaxDrive)
   	MaxDrive = Drive;

   // Read in the Master Boot Record (512 bytes)
   ReadFile(hDevice, Buffer, 512, &nBytesRead, NULL);

   // Close the Device
   CloseHandle(hDevice);

   if(nBytesRead == 512)
   	return TRUE;

   return FALSE;
}

int WriteMBR(far char *Buffer, char Drive)
{
	HANDLE	hDevice;
   DWORD		nBytesWritten;

   // Try and read the Master boot record from the specified drive
   sprintf(FileName, "\\\\.\\PhysicalDrive%d", Drive);

   hDevice = CreateFile(FileName, GENERIC_WRITE,
   	FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
      OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);

   // Exit if failed to open the device
   if(hDevice == NULL)
   	return FALSE;

   // Read in the Master Boot Record (512 bytes)
   WriteFile(hDevice, Buffer, 512, &nBytesWritten, NULL);

   // Close the Device
   CloseHandle(hDevice);

   if(nBytesWritten == 512)
   	return TRUE;

   return FALSE;
}


