📄 fdisk.c
字号:
getFsInfo(t, count); } makeSliceString(t->disk, &t->slices[count]); }}static void makeSliceList(partitionTable *t){ // This function populates the list of slices using the 'raw' slices list // in the partitionTable structure. rawSlice *raw = NULL; int firstPartition = -1; unsigned firstSector = -1; int count1, count2; bzero(t->slices, (MAX_SLICES * sizeof(slice))); t->numSlices = 0; // Loop through all the raw partitions and put them in our list for (count1 = 0; count1 < t->numRawSlices; count1 ++) { firstPartition = -1; firstSector = 0xFFFFFFFF; for (count2 = 0; count2 < t->numRawSlices; count2 ++) { raw = &t->rawSlices[count2]; // If we have already processed this one, continue if (t->numSlices && (raw->startLogical <= t->slices[t->numSlices - 1].raw.startLogical)) continue; if (raw->startLogical < firstSector) { firstSector = raw->startLogical; firstPartition = count2; } } if (firstPartition < 0) break; raw = &t->rawSlices[firstPartition]; // Now add a slice for the current partition memcpy(&t->slices[t->numSlices].raw, raw, sizeof(rawSlice)); snprintf(t->slices[t->numSlices].diskName, 6, "%s%c", t->disk->name, ('a' + t->slices[t->numSlices].raw.order)); t->numSlices += 1; } updateSliceList(t);}static int selectDisk(disk *theDisk){ int status = 0; char tmpChar[80]; if (table->changesPending) { sprintf(tmpChar, "Discard changes to disk %s?", table->disk->name); if (!yesOrNo(tmpChar)) { if (graphics) // Re-select the old disk in the list windowComponentSetSelected(diskList, table->diskNumber); return (status = 0); } table->changesPending = 0; } // Check for geometry. The way things are currently implemented, we need // some of these values to be non-zero. if (!theDisk->cylinders || !theDisk->heads || !theDisk->sectorsPerCylinder || !theDisk->sectorSize) { error("Disk \"%s\" is missing geometry information.", theDisk->name); return (status = ERR_NOTIMPLEMENTED); } status = readPartitionTable(theDisk, table); if (status < 0) return (status); if (graphics) windowComponentSetSelected(diskList, table->diskNumber); // Make the slice list makeSliceList(table); table->selectedSlice = 0; return (status = 0);}static int queryDisk(void){ int status; char *diskStrings[DISK_MAXDEVICES]; int count; for (count = 0; count < numberDisks; count ++) diskStrings[count] = diskListParams[count].text; status = vshCursorMenu("Please choose the disk on which to operate:", diskStrings, numberDisks, table->diskNumber); if (status < 0) return (status); status = selectDisk(&disks[status]); if (table->disk == NULL) status = ERR_INVALID; return (status);}static void drawDiagram(void){ // Draw a picture of the disk layout on our 'canvas' component int needPixels = 0; int xCoord = 0; windowDrawParameters params; static color colors[DISK_MAX_PARTITIONS + 1] = { { 0, 255, 255 }, // 0 = Yellow { 255, 0, 0 }, // 1 = Blue { 0, 255, 0 }, // 2 = Green { 0, 0, 255 }, // 3 = Red { 255, 0, 255 }, // 4 = Purple { 0, 196, 255 }, // 5 = Orange // These standard shades can fill out the rest. COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_BROWN, COLOR_LIGHTBLUE, COLOR_LIGHTGREEN, COLOR_LIGHTCYAN, COLOR_LIGHTRED, // This one is for extended partitions { 255, 196, 178 } }; color *extendedColor = NULL; int count1, count2; // Clear our drawing parameters bzero(¶ms, sizeof(windowDrawParameters)); // Some basic drawing values for slice rectangles params.operation = draw_rect; params.mode = draw_normal; params.xCoord1 = 0; params.yCoord1 = 0; params.width = canvasWidth; params.height = canvasHeight; params.thickness = 1; params.fill = 1; // Draw a white background params.foreground.red = 255; params.foreground.green = 255; params.foreground.blue = 255; windowComponentSetData(canvas, ¶ms, 1); // Set the pixel widths of all the slices for (count1 = 0; count1 < table->numSlices; count1 ++) table->slices[count1].pixelWidth = ((((table->slices[count1].raw.geom.endCylinder - table->slices[count1].raw.geom.startCylinder) + 1) * canvasWidth) / table->disk->cylinders); // Now, we want to make sure each slice has a width of at least MIN_WIDTH, // so that it is visible. If we need to, we steal the pixels from any // adjacent slices. #define MIN_WIDTH 15 for (count1 = 0; count1 < table->numSlices; count1 ++) if (table->slices[count1].pixelWidth < MIN_WIDTH) { needPixels = (MIN_WIDTH - table->slices[count1].pixelWidth); while (needPixels) for (count2 = 0; count2 < table->numSlices; count2 ++) if ((count2 != count1) && (table->slices[count2].pixelWidth > MIN_WIDTH)) { table->slices[count1].pixelWidth += 1; table->slices[count2].pixelWidth -= 1; needPixels -= 1; if (!needPixels) break; } } for (count1 = 0; count1 < table->numSlices; count1 ++) { table->slices[count1].pixelX = xCoord; params.mode = draw_normal; params.xCoord1 = table->slices[count1].pixelX; params.yCoord1 = 0; params.width = table->slices[count1].pixelWidth; params.height = canvasHeight; params.fill = 1; if (table->slices[count1].raw.tag) { if (ISLOGICAL(&table->slices[count1])) extendedColor = &colors[DISK_MAX_PARTITIONS]; else extendedColor = NULL; } if (extendedColor != NULL) { if ((table->slices[count1].raw.tag) || ((count1 < (table->numSlices - 1)) && ISLOGICAL(&table->slices[count1 + 1]))) { memcpy(¶ms.foreground, extendedColor, sizeof(color)); windowComponentSetData(canvas, ¶ms, 1); } } // If it is a used slice, we draw a filled rectangle on the canvas to // represent the slice. if (table->slices[count1].raw.tag) { table->slices[count1].color = &colors[table->slices[count1].raw.order]; memcpy(¶ms.foreground, table->slices[count1].color, sizeof(color)); if (ISLOGICAL(&table->slices[count1])) { params.xCoord1 += 3; params.yCoord1 += 3; params.width -= 6; params.height -= 6; } windowComponentSetData(canvas, ¶ms, 1); } // If this is the selected slice, draw a border inside it if (count1 == table->selectedSlice) { params.mode = draw_xor; params.foreground.red = 200; params.foreground.green = 200; params.foreground.blue = 200; params.xCoord1 += 2; params.yCoord1 += 2; params.width -= 4; params.height -= 4; params.fill = 0; windowComponentSetData(canvas, ¶ms, 1); } xCoord += table->slices[count1].pixelWidth; }}static void printBanner(void){ textScreenClear(); printf("%s\nCopyright (C) 1998-2007 J. Andrew McLaughlin\n", programName);}static void display(void){ listItemParameters *sliceListParams = NULL; char lineString[SLICESTRING_LENGTH + 2]; int slc = 0; int isDefrag = 0; int isHide = 0; textAttrs attrs; int count; if (graphics) { // Re-populate our slice list component sliceListParams = malloc(table->numSlices * sizeof(listItemParameters)); if (sliceListParams == NULL) return; for (count = 0; count < table->numSlices; count ++) strncpy(sliceListParams[count].text, table->slices[count].string, WINDOW_MAX_LABEL_LENGTH); windowComponentSetSelected(sliceList, 0); windowComponentSetData(sliceList, sliceListParams, table->numSlices); free(sliceListParams); windowComponentSetSelected(sliceList, table->selectedSlice); drawDiagram(); // Depending on which slice type is selected (i.e. partition vs. empty // space) we enable/disable button choices if (table->slices[table->selectedSlice].raw.tag) { // It's a partition if (table->slices[table->selectedSlice].opFlags & FS_OP_DEFRAG) isDefrag = 1; if (PARTITION_TYPEID_IS_HIDEABLE(table->slices[table->selectedSlice] .raw.tag) || PARTITION_TYPEID_IS_HIDDEN(table->slices[table->selectedSlice] .raw.tag)) isHide = 1; windowComponentSetEnabled(partMenuContents.items[PARTMENU_COPY] .key, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_PASTE] .key, 0); windowComponentSetEnabled(setActiveButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_SETACTIVE] .key, 1); windowComponentSetEnabled(deleteButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_DELETE] .key, 1); windowComponentSetEnabled(formatButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_FORMAT] .key, 1); windowComponentSetEnabled(defragButton, isDefrag); windowComponentSetEnabled(partMenuContents.items[PARTMENU_DEFRAG] .key, isDefrag); windowComponentSetEnabled(resizeButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_RESIZE] .key, 1); windowComponentSetEnabled(hideButton, isHide); windowComponentSetEnabled(partMenuContents.items[PARTMENU_HIDE] .key, isHide); windowComponentSetEnabled(moveButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_MOVE] .key, 1); windowComponentSetEnabled(newButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_CREATE] .key, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_SETTYPE] .key, 1); } else { // It's empty space windowComponentSetEnabled(partMenuContents.items[PARTMENU_COPY] .key, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_PASTE] .key, clipboardSliceValid); windowComponentSetEnabled(setActiveButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_SETACTIVE] .key, 0); windowComponentSetEnabled(deleteButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_DELETE] .key, 0); windowComponentSetEnabled(formatButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_FORMAT] .key, 0); windowComponentSetEnabled(defragButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_DEFRAG] .key, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_RESIZE] .key, 0); windowComponentSetEnabled(hideButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_HIDE] .key, 0); windowComponentSetEnabled(moveButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_MOVE] .key, 0); windowComponentSetEnabled(newButton, 1); windowComponentSetEnabled(partMenuContents.items[PARTMENU_CREATE] .key, 1); windowComponentSetEnabled(resizeButton, 0); windowComponentSetEnabled(partMenuContents.items[PARTMENU_SETTYPE] .key, 0); } // Other buttons enabled/disabled... windowComponentSetEnabled(deleteAllButton, table->numRawSlices); windowComponentSetEnabled(partMenuContents.items[PARTMENU_DELETEALL] .key, table->numRawSlices); windowComponentSetEnabled(fileMenuContents.items[FILEMENU_RESTOREBACKUP] .key, table->backupAvailable); windowComponentSetEnabled(undoButton, table->changesPending); windowComponentSetEnabled(fileMenuContents.items[FILEMENU_UNDO] .key, table->changesPending); windowComponentSetEnabled(writeButton, table->changesPending); windowComponentSetEnabled(fileMenuContents.items[FILEMENU_WRITE] .key, table->changesPending); } else { printBanner(); bzero(&attrs, sizeof(textAttrs)); bzero(lineString, (SLICESTRING_LENGTH + 2)); for (count = 0; count <= SLICESTRING_LENGTH; count ++) lineString[count] = 196; printf("\n%s\n\n %s\n %s\n", diskListParams[table->diskNumber].text, sliceListHeader, lineString); // Print info about the slices for (slc = 0; slc < table->numSlices; slc ++) { printf(" "); if (slc == table->selectedSlice) attrs.flags = TEXT_ATTRS_REVERSE; else attrs.flags = 0; textPrintAttrs(&attrs, " "); textPrintAttrs(&attrs, table->slices[slc].string); for (count = strlen(table->slices[slc].string); count < SLICESTRING_LENGTH; count ++) textPrintAttrs(&attrs, " "); printf("\n"); } printf(" %s\n", lineString); }}static void setActive(int sliceNumber){ // Toggle the 'bootable' flag of the supplied slice number, and if necessary // clear the flag of any existing bootable slice. int count; // Loop through the slices for (count = 0; count < table->numSlices; count ++) if (table->slices[count].raw.tag) { if (count == sliceNumber) { if (table->slices[count].raw.flags & SLICEFLAG_BOOTABLE) // Clear the bootable flag table->slices[count].raw.flags &= ~SLICEFLAG_BOOTABLE; else // Set the bootable flag table->slices[count].raw.flags |= SLICEFLAG_BOOTABLE; } else table->slices[count].raw.flags &= ~SLICEFLAG_BOOTABLE; } table->changesPending += 1; // Update the slice list updateSliceList(table);}static int getTypeListParams(listItemParameters **typeListParams){ // Get the list of supported partition types as an array of // listItemParameters structures partitionType *types = NULL; int numberTypes = 0; int count; // Get the list of types types = diskGetPartTypes(); if (types == NULL) return (numberTypes = ERR_NODATA); for (count = 0; (types[count].code != 0); count ++) numberTypes += 1; // Make an array of list item parameters *typeListParams = malloc(numberTypes * sizeof(listItemParameters)); if (*typeListParams == NULL) { numberTypes = ERR_MEMORY; goto out; } for (count = 0; count < numberTypes; count ++) snprintf((*typeListParams)[count].text, WINDOW_MAX_LABEL_LENGTH, "%02x %s", types[count].code, types[count].description); out: memoryRelease(types); return (numberTypes);}static int typeListDialog(listItemParameters *typeListParams, int numberTypes, int select){ int selection = 0; objectKey typesDialog = NULL; objectKey typesList = NULL; objectKey selectButton = NULL; objectKey cancelButton = NULL; componentParameters params; windowEvent event; // Create a new window, not a modal dialog typesDialog = windowNewDialog(window, PARTTYPES);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -