⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msdos.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 2 页
字号:
////  Visopsys//  Copyright (C) 1998-2007 J. Andrew McLaughlin// //  This program is free software; you can redistribute it and/or modify it//  under the terms of the GNU General Public License as published by the Free//  Software Foundation; either version 2 of the License, or (at your option)//  any later version.// //  This program is distributed in the hope that it will be useful, but//  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY//  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License//  for more details.//  //  You should have received a copy of the GNU General Public License along//  with this program; if not, write to the Free Software Foundation, Inc.,//  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.////  msdos.c//// This code does operations specific to MSDOS-labelled disks.#include "fdisk.h"#include "msdos.h"#include <errno.h>#include <stdlib.h>#include <sys/api.h>static inline int checkSignature(unsigned char *sectorData){  // Returns 1 if the buffer contains an MSDOS signature.  if ((sectorData[510] != (unsigned char) 0x55) ||      (sectorData[511] != (unsigned char) 0xAA))    // No signature.  Return 0.    return (0);  else    // We'll say this has an MSDOS signature.    return (1);}static int readTable(const disk *theDisk, unsigned sector,		     unsigned extendedStart, rawSlice *slices, int *numSlices){  // This function (recursively) reads partition table sectors and populates  // the array of raw slices.  int status = 0;  unsigned char *sectorData = NULL;  int maxEntries = DISK_MAX_PRIMARY_PARTITIONS;  msdosTable *table = NULL;  int count;  sectorData = malloc(theDisk->sectorSize);  if (sectorData == NULL)    return (status = ERR_MEMORY);  // Read the specified sector.  status = diskReadSectors(theDisk->name, sector, 1, sectorData);  if (status < 0)    {      error("Couldn't read partition table sector %u", sector);      free(sectorData);      return (status);    }  if (!checkSignature(sectorData))    {      error("Table at %u has no signature", sector);      free(sectorData);      return (status = ERR_INVALID);    }  // Set the pointer to the start of partition records in the table  table = (msdosTable *) (sectorData + 0x01BE);  // If this is not the first partition table, the maximum number of entries  // is 2.  if (sector)    maxEntries = 2;  // Loop through the partition entries and create slices for them.  for (count = 0; count < maxEntries; count ++)    {      // If this is an entry for an extended partition, skip it for the moment.      if (PARTITION_TYPEID_IS_EXTD(table->entries[count].tag))	continue;      // If the tag is NULL, and we are in the primary table, we have to      // leave an empty slice.  Otherwise, we are finished.      if (!table->entries[count].tag)	{	  if (!sector)	    {	      bzero(&slices[*numSlices], sizeof(rawSlice));	      *numSlices += 1;	      continue;	    }	  else	    break;	}      // Assign the data fields in the appropriate slice      slices[*numSlices].order = *numSlices;      if (sector)	slices[*numSlices].type = partition_logical;      else	slices[*numSlices].type = partition_primary;      if (table->entries[count].driveActive >> 7)	slices[*numSlices].flags = SLICEFLAG_BOOTABLE;      // The MSDOS partition tag.      slices[*numSlices].tag = table->entries[count].tag;      // The logical (LBA) start sector and number of sectors.      slices[*numSlices].startLogical =	(table->entries[count].startLogical + sector);      slices[*numSlices].sizeLogical = table->entries[count].sizeLogical;      // Get the (alleged) partition geometry.      // Start cylinder.      slices[*numSlices].geom.startCylinder =	(unsigned) table->entries[count].startCyl;      slices[*numSlices].geom.startCylinder |=	(((unsigned) table->entries[count].startCylSect & 0xC0) << 2);      // Start head.      slices[*numSlices].geom.startHead =	(unsigned) table->entries[count].startHead;      // Start sector.      slices[*numSlices].geom.startSector =	(unsigned) (table->entries[count].startCylSect & 0x3F);      // End cylinder.      slices[*numSlices].geom.endCylinder = 	(unsigned) table->entries[count].endCyl;      slices[*numSlices].geom.endCylinder |=	(((unsigned) table->entries[count].endCylSect & 0xC0) << 2);      // End head.      slices[*numSlices].geom.endHead =	(unsigned) table->entries[count].endHead;      // End sector.      slices[*numSlices].geom.endSector =	(unsigned) (table->entries[count].endCylSect & 0x3F);      // Now, check whether the start and end CHS values seem correct.      // If they are 'maxed out' and don't correspond with the LBA values,      // recalculate them.      if ((slices[*numSlices].geom.startCylinder == 1023) ||	  (slices[*numSlices].geom.endCylinder == 1023))	{	  if (slices[*numSlices].geom.startCylinder == 1023)	    slices[*numSlices].geom.startCylinder =	      (slices[*numSlices].startLogical / CYLSECTS(theDisk));	  if (slices[*numSlices].geom.endCylinder == 1023)	    slices[*numSlices].geom.endCylinder =	      ((slices[*numSlices].startLogical +		(slices[*numSlices].sizeLogical - 1)) / CYLSECTS(theDisk));	}      *numSlices += 1;    }  // Remove any 'trailing' empty slices  while (*numSlices && !slices[*numSlices - 1].tag)    *numSlices -= 1;  // Loop through the entries one more time, looking for extended entries  // (we skipped them, above).  for (count = 0; count < maxEntries; count ++)    if (PARTITION_TYPEID_IS_EXTD(table->entries[count].tag))      {	// This is an extended entry.  Recurse for it.	if (sector)	  status =	    readTable(theDisk, (table->entries[count].startLogical +				extendedStart), extendedStart, slices,		      numSlices);	else	  status =	    readTable(theDisk, table->entries[count].startLogical,		      table->entries[count].startLogical, slices, numSlices);	break;      }  free(sectorData);  return (status);}static void calcExtendedSize(rawSlice *extSlice, rawSlice *slices){  // Given an array of slices beginning with a logical slice, calculate the  // size of the extended partition to contain the logical slice and all  // following logical slices.  int count;  extSlice->sizeLogical = 0;  for (count = 0; (slices[count].tag &&		   (slices[count].type == partition_logical)); count ++)    {      extSlice->sizeLogical += slices[count].sizeLogical;      extSlice->geom.endCylinder = slices[count].geom.endCylinder;      extSlice->geom.endHead = slices[count].geom.endHead;      extSlice->geom.endSector = slices[count].geom.endSector;    }}static void formatTableEntry(rawSlice *origRaw, msdosEntry *entry){  rawSlice raw;  // Make a copy of the entry in case we modify it.  memcpy(&raw, origRaw, sizeof(rawSlice));  // Check whether our start or end cylinder values exceed the legal  // maximum of 1023.  If so, set them to 1023.  raw.geom.startCylinder = min(raw.geom.startCylinder, 1023);  raw.geom.endCylinder = min(raw.geom.endCylinder, 1023);  if (raw.flags & SLICEFLAG_BOOTABLE)    entry->driveActive = 0x80;  entry->startHead = (unsigned char) raw.geom.startHead;  entry->startCylSect = (unsigned char)    (((raw.geom.startCylinder & 0x300) >> 2) | (raw.geom.startSector & 0x3F));  entry->startCyl = (unsigned char) (raw.geom.startCylinder & 0x0FF);  entry->tag = raw.tag;  entry->endHead = (unsigned char) raw.geom.endHead;  entry->endCylSect = (unsigned char)    (((raw.geom.endCylinder & 0x300) >> 2) | (raw.geom.endSector & 0x3F));  entry->endCyl = (unsigned char) (raw.geom.endCylinder & 0x0FF);  entry->startLogical = raw.startLogical;  entry->sizeLogical = raw.sizeLogical;}static int writeTable(const disk *theDisk, unsigned sector,		      unsigned extendedStart, rawSlice *slices){  // This function (recursively) writes partition table sectors from the  // array of slices.  int status = 0;  unsigned char *sectorData = NULL;  int maxEntries = DISK_MAX_PRIMARY_PARTITIONS;  msdosTable *table = NULL;  int numEntries = 0;  rawSlice tmpSlice;  int count;  sectorData = malloc(theDisk->sectorSize);  if (sectorData == NULL)    return (status = ERR_MEMORY);  // Read the specified sector.  status = diskReadSectors(theDisk->name, sector, 1, sectorData);  if (status < 0)    {      error("Couldn't read partition table sector %u", sector);      goto out;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -