📄 msdos.c
字号:
} // Set the pointer to the start of partition records in the table table = (msdosTable *) (sectorData + 0x01BE); // Clear it. bzero(table, sizeof(msdosTable)); // 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 < DISK_MAX_PARTITIONS) && (numEntries < maxEntries)); count ++) { // Empty slot? if (!slices[count].tag) { // If we are in the primary table, continue. Otherwise, we are // finished. if (!sector) { numEntries += 1; continue; } else break; } // Make a copy of the slice in case we need to change values memcpy(&tmpSlice, &slices[count], sizeof(rawSlice)); // If the current slice is logical, and this is not the first entry // of an extended table, we need to create an extended entry for it // instead, and recurse. if ((tmpSlice.type == partition_logical) && (!sector || count)) { // Create an extended entry to correspond to the logical entry // -- which we will to create in the next call. tmpSlice.tag = 0x0F; // Adjust the size to accommodate the logical slice and all following // logical slices calcExtendedSize(&tmpSlice, &slices[count]); // The extended partition should start on the cylinder boundary, and // the logical partition should start one 'track' after that. if (!tmpSlice.geom.startHead) { error("Logical partition cannot start on a cylinder boundary"); status = ERR_ALIGN; goto out; } tmpSlice.startLogical -= theDisk->sectorsPerCylinder; tmpSlice.sizeLogical += theDisk->sectorsPerCylinder; tmpSlice.geom.startHead = 0; // If this is an extended table, re-adjust the starting logical // starting sector value to reflect a position relative to the start // of the extended partition. if (sector) tmpSlice.startLogical -= extendedStart; // Fill out the table entry formatTableEntry(&tmpSlice, &table->entries[numEntries]); if (sector) status = writeTable(theDisk, (table->entries[numEntries].startLogical + extendedStart), extendedStart, &slices[count]); else status = writeTable(theDisk, table->entries[numEntries].startLogical, table->entries[numEntries].startLogical, &slices[count]); // If we are in the main table, skip to the end of all the logical // slices. If we're not in the main table, we are finished. if (!sector) { while ((count < (DISK_MAX_PARTITIONS - 1)) && (slices[count + 1].type == partition_logical)) count += 1; } else break; } else { // If this is an extended table, re-adjust the starting logical // starting sector value to reflect a position relative to the start // of the extended partition. if (sector) tmpSlice.startLogical -= sector; // Fill out the table entry formatTableEntry(&tmpSlice, &table->entries[numEntries]); } numEntries += 1; } // Make sure it has a valid signature sectorData[510] = (unsigned char) 0x55; sectorData[511] = (unsigned char) 0xAA; // Write back the sector. status = diskWriteSectors(theDisk->name, sector, 1, sectorData); if (status < 0) error("Couldn't write partition table sector %u", sector); out: free(sectorData); return (status);}static int detect(const disk *theDisk){ // Checks for the presense of an MSDOS disk label. int status = 0; unsigned char *sectorData = NULL; sectorData = malloc(theDisk->sectorSize); if (sectorData == NULL) return (status = ERR_MEMORY); // Read the first sector of the device status = diskReadSectors(theDisk->name, 0, 1, sectorData); if (status < 0) { free(sectorData); return (status); } // Is this a valid partition table? Make sure the signature is at the end. status = checkSignature(sectorData); free(sectorData); if (status == 1) // Call this an MSDOS label. return (status); else // Not an MSDOS label return (status = 0);}static int read(const disk *theDisk, rawSlice *slices, int *numSlices){ // Recursively read the partition tables, starting with the MBR in sector // zero. *numSlices = 0; return (readTable(theDisk, 0, 0, slices, numSlices));}static int write(const disk *theDisk, rawSlice *slices){ // Recursively write the partition tables, starting with the MBR in sector // zero. return (writeTable(theDisk, 0, 0, slices));}static sliceType canCreate(slice *slices, int numSlices, int sliceNumber){ // This will return a sliceType enumeration if, given a slice number // representing free space, a partition can be created there. If not, it // returns error. Otherwise it returns the enumeration representing the // type that can be created: primary, logical, or 'any'. sliceType returnType = partition_any; int numPrimary = 0; int numLogical = 0; int count; // Gather a bit of information for (count = 0; count < numSlices; count ++) if (slices[count].raw.tag) { if (ISLOGICAL(&slices[count])) numLogical += 1; else numPrimary += 1; } if (numLogical) { // There are existing logical partitions. // Logical partitions use up one primary slot for all of them. numPrimary += 1; // If this will be the first slice, and the second is not logical, // then allow only primary. if ((sliceNumber == 0) && !ISLOGICAL(&slices[sliceNumber + 1])) returnType = partition_primary; // If this will be the last slice, and the previous is not logical, // then only allow primary. else if ((sliceNumber == (numSlices - 1)) && !ISLOGICAL(&slices[sliceNumber - 1])) returnType = partition_primary; // If this will be between two slices, and neither is logical, then // only allow primary. else if (((sliceNumber > 0) && !ISLOGICAL(&slices[sliceNumber - 1])) && ((sliceNumber < (numSlices - 1)) && !ISLOGICAL(&slices[sliceNumber + 1]))) returnType = partition_primary; // If this will be between two logical slices, then only allow logical. else if (((sliceNumber > 0) && ISLOGICAL(&slices[sliceNumber - 1])) && ((sliceNumber < (numSlices - 1)) && ISLOGICAL(&slices[sliceNumber + 1]))) returnType = partition_logical; } // If we don't have to do logical, check whether the main table is full if ((returnType != partition_logical) && (numPrimary >= DISK_MAX_PRIMARY_PARTITIONS)) { // If logical is possible, then logical it will be if (numLogical && (returnType == partition_any)) returnType = partition_logical; else // Can't do logical, and the main table is full of entries returnType = ERR_NOFREE; } // Can't create a logical partition solely on cylinder 0 if ((slices[sliceNumber].raw.geom.startCylinder == 0) && (slices[sliceNumber].raw.geom.endCylinder == 0)) { if ((returnType == partition_any) || (returnType == partition_primary)) returnType = partition_primary; else returnType = ERR_NOFREE; } if ((int) returnType == ERR_NOFREE) // The partition table is full of entries, in its current // configuration. error("The partition table is full of primary partitions. Use " "more\nlogical partitions in order to create more."); return (returnType);}diskLabel msdosLabel = { label_msdos, // type (LABELFLAG_PRIMARYPARTS | LABELFLAG_LOGICALPARTS), // flags // Functions &detect, &read, &write, &canCreate};diskLabel *getLabelMsdos(void){ // Called at initialization, returns a pointer to the disk label structure. return (&msdosLabel);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -