📄 fdisk.c
字号:
char *output = NULL; int count; output = malloc(MAXSTRINGLENGTH); if (output == NULL) return (ERR_MEMORY); // For each partition entry, check that its starting/ending // cylinder/head/sector values match with its starting logical value // and logical size. In general we expect the logical values are correct. for (count = 0; count < t->numSlices; count ++) { checkSlice = &t->slices[count]; if (!checkSlice->raw.tag) continue; endLogical = ((checkSlice->raw.startLogical + checkSlice->raw.sizeLogical) - 1); expectCylinder = (checkSlice->raw.startLogical / CYLSECTS(t->disk)); if (expectCylinder != checkSlice->raw.geom.startCylinder) { sprintf((output + strlen(output)), "Partition %s starting cylinder " "is %u, should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.startCylinder, expectCylinder); if (fix) { checkSlice->raw.geom.startCylinder = expectCylinder; t->changesPending += 1; } else errors += 1; } expectCylinder = (endLogical / CYLSECTS(t->disk)); if (expectCylinder != checkSlice->raw.geom.endCylinder) { sprintf((output + strlen(output)), "Partition %s ending cylinder " "is %u, should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.endCylinder, expectCylinder); if (fix) { checkSlice->raw.geom.endCylinder = expectCylinder; t->changesPending += 1; } else errors += 1; } expectHead = ((checkSlice->raw.startLogical % CYLSECTS(t->disk)) / t->disk->sectorsPerCylinder); if (expectHead != checkSlice->raw.geom.startHead) { sprintf((output + strlen(output)), "Partition %s starting head is " "%u, should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.startHead, expectHead); if (fix) { checkSlice->raw.geom.startHead = expectHead; t->changesPending += 1; } else errors += 1; } expectHead = ((endLogical % CYLSECTS(t->disk)) / t->disk->sectorsPerCylinder); if (expectHead != checkSlice->raw.geom.endHead) { sprintf((output + strlen(output)), "Partition %s ending head is %u, " "should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.endHead, expectHead); if (fix) { checkSlice->raw.geom.endHead = expectHead; t->changesPending += 1; } else errors += 1; } expectSector = (((checkSlice->raw.startLogical % CYLSECTS(t->disk)) % t->disk->sectorsPerCylinder) + 1); if (expectSector != checkSlice->raw.geom.startSector) { sprintf((output + strlen(output)), "Partition %s starting CHS " "sector is %u, should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.startSector, expectSector); if (fix) { checkSlice->raw.geom.startSector = expectSector; t->changesPending += 1; } else errors += 1; } expectSector = (((endLogical % CYLSECTS(t->disk)) % t->disk->sectorsPerCylinder) + 1); if (expectSector != checkSlice->raw.geom.endSector) { sprintf((output + strlen(output)), "Partition %s ending CHS sector " "is %u, should be %u\n", checkSlice->showSliceName, checkSlice->raw.geom.endSector, expectSector); if (fix) { checkSlice->raw.geom.endSector = expectSector; t->changesPending += 1; } else errors += 1; } } if (errors) { sprintf((output + strlen(output)), "\nFix th%s error%s?", ((errors == 1)? "is" : "ese"), ((errors == 1)? "" : "s")); if (checkTableAsk) { if (yesOrNo(output)) { free(output); return (checkTable(t, 1)); } else // Don't ask about fixing stuff more than once. checkTableAsk = 0; } free(output); return (ERR_INVALID); } else { free(output); return (0); }}static int readPartitionTable(disk *theDisk, partitionTable *t){ // Read the partition table from the physical disk int status = 0; char *fileName = NULL; static char *tmpBackupFileName = NULL; file backupFile; fileStream tmpBackupFile; int count; // Clear stack data bzero(&backupFile, sizeof(file)); bzero(&tmpBackupFile, sizeof(fileStream)); // Clear any existing partition table data bzero(t, sizeof(partitionTable)); t->disk = theDisk; for (count = 0; count < numberDisks; count ++) if (&disks[count] == t->disk) { t->diskNumber = count; break; } // Detect the disk label if (msdosLabel->detect(t->disk) == 1) t->label = msdosLabel; if (t->label) { status = t->label->read(t->disk, t->rawSlices, &t->numRawSlices); if (status < 0) warning("Error %d reading partition table, data may be incorrect.\n" "Proceed with caution.", status); } else { warning("Unknown disk label. Writing changes will create an MS-DOS " "label."); t->label = msdosLabel; } // Any backup partition table saved? Construct the file name fileName = malloc(MAX_PATH_NAME_LENGTH); if (fileName == NULL) return (status = ERR_MEMORY); sprintf(fileName, BACKUP_MBR, t->disk->name); if (!fileFind(fileName, &backupFile)) t->backupAvailable = 1; else t->backupAvailable = 0; free(fileName); if (!readOnly) { // We are not read-only, create a new temporary backup if (tmpBackupName != NULL) { fileDelete(tmpBackupName); tmpBackupName = NULL; } status = fileGetTemp(&backupFile); if (status < 0) { warning("Can't create backup file"); return (status); } if (tmpBackupFileName == NULL) { tmpBackupFileName = malloc(MAX_PATH_NAME_LENGTH); if (tmpBackupFileName == NULL) return (status = ERR_MEMORY); } snprintf(tmpBackupFileName, MAX_PATH_NAME_LENGTH, TEMP_DIR"/%s", backupFile.name); fileClose(&backupFile); status = fileStreamOpen(tmpBackupFileName, OPENMODE_WRITE, &tmpBackupFile); if (status < 0) { warning("Can't open backup file %s", backupFile.name); return (status); } status = fileStreamWrite(&tmpBackupFile, sizeof(int), (char *) &t->numRawSlices); if (status < 0) warning("Error writing backup partition table file"); status = fileStreamWrite(&tmpBackupFile, (t->numRawSlices * sizeof(rawSlice)), (char *) t->rawSlices); if (status < 0) warning("Error writing backup partition table file"); fileStreamClose(&tmpBackupFile); tmpBackupName = tmpBackupFileName; } return (status = 0);}static int writePartitionTable(partitionTable *t){ // Write the partition table to the physical disk int status = 0; char *fileName = NULL; int count1, count2; bzero(t->rawSlices, (DISK_MAX_PARTITIONS * sizeof(rawSlice))); t->numRawSlices = 0; // Copy the 'raw' data from the data slices into the raw slice list. for (count1 = 0; count1 < DISK_MAX_PARTITIONS; count1 ++) for (count2 = 0; count2 < t->numSlices; count2 ++) if (t->slices[count2].raw.tag && (t->slices[count2].raw.order == count1)) { bcopy(&t->slices[count2].raw, &t->rawSlices[count1], sizeof(rawSlice)); t->numRawSlices += 1; break; } // Do a check on the table status = checkTable(t, 0); if ((status < 0) && !yesOrNo("Partition table consistency check failed.\n" "Write anyway?")) return (status); status = t->label->write(t->disk, t->rawSlices); if (status < 0) return (status); // Make the backup file permanent if (tmpBackupName != NULL) { fileName = malloc(MAX_PATH_NAME_LENGTH); if (fileName == NULL) return (status = ERR_MEMORY); // Construct the backup file name snprintf(fileName, MAX_PATH_NAME_LENGTH, BACKUP_MBR, t->disk->name); // Copy the temporary backup file to the backup fileMove(tmpBackupName, fileName); free(fileName); tmpBackupName = NULL; // We now have a proper backup t->backupAvailable = 1; } diskSync(t->disk->name); t->changesPending = 0; return (status = 0);}static void insertSliceAt(partitionTable *t, int sliceNumber){ // Just moves part of the slice list to accommodate an insertion. int count; for (count = t->numSlices; count > sliceNumber; count --) memcpy(&t->slices[count], &t->slices[count - 1], sizeof(slice)); table->numSlices += 1;}static void removeSliceAt(partitionTable *t, int sliceNumber){ // Just moves part of the slice list to accommodate a removal. int count; for (count = (sliceNumber + 1); count < t->numSlices; count ++) memcpy(&t->slices[count - 1], &t->slices[count], sizeof(slice)); table->numSlices -= 1;}static void makeEmptySlice(partitionTable *t, int sliceNumber, unsigned startCylinder, unsigned endCylinder){ // Given a slice entry and a geometry, make a slice for it. slice *emptySlice = &t->slices[sliceNumber]; bzero(emptySlice, sizeof(slice)); emptySlice->raw.startLogical = (startCylinder * CYLSECTS(t->disk)); emptySlice->raw.geom.startCylinder = startCylinder; emptySlice->raw.geom.startHead = ((emptySlice->raw.startLogical % CYLSECTS(t->disk)) / t->disk->sectorsPerCylinder); emptySlice->raw.geom.startSector = (((emptySlice->raw.startLogical % CYLSECTS(t->disk)) % t->disk->sectorsPerCylinder) + 1); emptySlice->raw.sizeLogical = (((endCylinder - startCylinder) + 1) * CYLSECTS(t->disk)); unsigned endLogical = (emptySlice->raw.startLogical + (emptySlice->raw.sizeLogical - 1)); emptySlice->raw.geom.endCylinder = endCylinder; emptySlice->raw.geom.endHead = ((endLogical % CYLSECTS(t->disk)) / t->disk->sectorsPerCylinder); emptySlice->raw.geom.endSector = (((endLogical % CYLSECTS(t->disk)) % t->disk->sectorsPerCylinder) + 1);}static void updateEmptySlices(partitionTable *t){ // Make all the empty slices reflect the actual empty spaces on the disk. int count; // First remove any existing empty slices for (count = 0; count < t->numSlices; count ++) if (!t->slices[count].raw.tag) { removeSliceAt(t, count); count -= 1; } // Now loop through the real slices and insert empty slices where appropriate for (count = 0; count < t->numSlices; count ++) { // Is there empty space between this slice and the previous slice? if ((!count && (t->slices[count].raw.geom.startCylinder > 0)) || (count && (t->slices[count].raw.geom.startCylinder > (t->slices[count - 1].raw.geom.endCylinder + 1)))) { insertSliceAt(t, count); makeEmptySlice(t, count, (count? (t->slices[count - 1] .raw.geom.endCylinder + 1) : 0), (t->slices[count].raw.geom.startCylinder - 1)); count += 1; } } // Is there empty space at the end of the disk? if ((t->numSlices == 0) || (t->slices[t->numSlices - 1].raw.geom.endCylinder < (t->disk->cylinders - 1))) { makeEmptySlice(t, t->numSlices, (t->numSlices? (t->slices[t->numSlices - 1] .raw.geom.endCylinder + 1) : 0), (t->disk->cylinders - 1)); t->numSlices += 1; }}static void getFsInfo(partitionTable *t, int sliceNumber){ slice *slc = &t->slices[sliceNumber]; disk tmpDisk; strcpy(slc->fsType, "unknown"); if (!slc->diskName[0]) return; if (diskGet(slc->diskName, &tmpDisk) < 0) return; slc->opFlags = tmpDisk.opFlags; if (strcmp(tmpDisk.fsType, "unknown")) strncpy(slc->fsType, tmpDisk.fsType, FSTYPE_MAX_NAMELENGTH); return;}static void makeSliceString(disk *theDisk, slice *slc){ int position = 0; partitionType partType; memset(slc->string, ' ', MAX_DESCSTRING_LENGTH); slc->string[MAX_DESCSTRING_LENGTH - 1] = '\0'; if (slc->raw.tag) { // Slice/disk name strcpy(slc->string, slc->showSliceName); slc->string[strlen(slc->string)] = ' '; position += SLICESTRING_DISKFIELD_WIDTH; // Label diskGetPartType(slc->raw.tag, &partType); sprintf((slc->string + position), "%s", partType.description); slc->string[strlen(slc->string)] = ' '; position += SLICESTRING_LABELFIELD_WIDTH; // Filesystem type sprintf((slc->string + position), "%s", slc->fsType); } else { position += SLICESTRING_DISKFIELD_WIDTH; strcpy((slc->string + position), "Empty space"); position += SLICESTRING_LABELFIELD_WIDTH; } slc->string[strlen(slc->string)] = ' '; position += SLICESTRING_FSTYPEFIELD_WIDTH; sprintf((slc->string + position), "%u-%u", slc->raw.geom.startCylinder, slc->raw.geom.endCylinder); slc->string[strlen(slc->string)] = ' '; position += SLICESTRING_CYLSFIELD_WIDTH; sprintf((slc->string + position), "%u", cylsToMb(theDisk, ((slc->raw.geom.endCylinder - slc->raw.geom.startCylinder) + 1))); position += SLICESTRING_SIZEFIELD_WIDTH; if (slc->raw.tag) { slc->string[strlen(slc->string)] = ' '; if (!ISLOGICAL(slc)) sprintf((slc->string + position), "primary"); else sprintf((slc->string + position), "logical"); if (slc->raw.flags & SLICEFLAG_BOOTABLE) strcat(slc->string, "/active"); else strcat(slc->string, " "); }}static void updateSliceList(partitionTable *t){ int count; // Update the empty slices updateEmptySlices(t); // Update the slice strings for (count = 0; count < t->numSlices; count ++) { if (t->slices[count].raw.tag) {#ifdef PARTLOGIC snprintf(t->slices[count].showSliceName, 6, "%d", (t->slices[count].raw.order + 1));#else snprintf(t->slices[count].showSliceName, 6, "%s%c", t->disk->name, ('a' + t->slices[count].raw.order));#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -