📄 fdisk.c
字号:
if (typesDialog == NULL) { error("Can't create dialog window"); return (selection = ERR_NOCREATE); } bzero(¶ms, sizeof(componentParameters)); params.gridWidth = 2; params.gridHeight = 1; params.padTop = 5; if (!select) params.padBottom = 5; params.padLeft = 5; params.padRight = 5; params.orientationX = orient_center; params.orientationY = orient_middle; // Make a list for our info typesList = windowNewList(typesDialog, windowlist_textonly, 10, 2, 0, typeListParams, numberTypes, ¶ms); if (select) { params.gridY += 1; params.gridWidth = 1; params.padBottom = 5; params.flags |= (WINDOW_COMPFLAG_FIXEDWIDTH | WINDOW_COMPFLAG_FIXEDHEIGHT); params.orientationX = orient_right; selectButton = windowNewButton(typesDialog, "Select", NULL, ¶ms); params.gridX += 1; params.orientationX = orient_left; cancelButton = windowNewButton(typesDialog, "Cancel", NULL, ¶ms); } windowCenterDialog(window, typesDialog); windowSetVisible(typesDialog, 1); while(1) { // Check for window close if ((windowComponentEventGet(typesDialog, &event) > 0) && (event.type & EVENT_WINDOW_CLOSE)) break; if (select) { // Check for selection if ((windowComponentEventGet(selectButton, &event) > 0) && (event.type & EVENT_MOUSE_LEFTUP)) { windowComponentGetSelected(typesList, &selection); break; } // Check for cancel if ((windowComponentEventGet(cancelButton, &event) > 0) && (event.type & EVENT_MOUSE_LEFTUP)) { selection = ERR_CANCELLED; break; } } multitaskerYield(); } windowDestroy(typesDialog); return (selection);}static void listTypes(void){ int numberTypes = 0; listItemParameters *typeListParams = NULL; int count; numberTypes = getTypeListParams(&typeListParams); if (numberTypes < 0) return; if (graphics) typeListDialog(typeListParams, numberTypes, 0); else { printf("\n%s:\n", PARTTYPES); for (count = 0; count <= (numberTypes / 2); count ++) { printf(" %s", typeListParams[count].text); textSetColumn(30); if ((count + (numberTypes / 2)) < numberTypes) printf(" %s\n", typeListParams[count + (numberTypes / 2)].text); } pause(); } if (typeListParams) free(typeListParams); return;}static int setType(int sliceNumber){ int status = 0; int numberTypes = 0; listItemParameters *typeListParams = NULL; char code[8]; int newTag = 0; partitionType *types; int count; types = diskGetPartTypes(); if (graphics) { numberTypes = getTypeListParams(&typeListParams); if (numberTypes < 0) { status = numberTypes; goto out; } newTag = typeListDialog(typeListParams, numberTypes, 1); free(typeListParams); if (newTag < 0) { status = newTag; goto out; } newTag = types[newTag].code; } else { while(1) { bzero(code, 8); printf("\nEnter the hexadecimal code to set as the type ('L' to list, " "'Q' to quit):\n-> "); status = readLine("0123456789AaBbCcDdEeFfLlQq", code, 8); if (status < 0) goto out; if ((code[0] == 'L') || (code[0] == 'l')) { listTypes(); continue; } if ((code[0] == '\0') || (code[0] == 'Q') || (code[0] == 'q')) { status = ERR_NODATA; goto out; } if (strlen(code) != 2) continue; // Turn it into a number newTag = xtoi(code); // Is it a supported type? for (count = 0; types[count].code != 0; count ++) if (types[count].code == newTag) break; if (types[count].code == 0) { error("Unsupported partition type %x", newTag); status = ERR_INVALID; goto out; } break; } } // Change the value table->slices[sliceNumber].raw.tag = newTag; table->changesPending += 1; // Update the slice list updateSliceList(table); status = 0; out: memoryRelease(types); return (status);}static void doDelete(int sliceNumber){ int order = table->slices[sliceNumber].raw.order; int count; removeSliceAt(table, sliceNumber); // Reduce the order numbers of all slices that occur after the deleted // slice. for (count = 0; count < table->numSlices; count ++) if (table->slices[count].raw.tag && (table->slices[count].raw.order > order)) table->slices[count].raw.order -= 1; // Update the slice list updateSliceList(table);}static void delete(int sliceNumber){ if (table->slices[sliceNumber].raw.flags & SLICEFLAG_BOOTABLE) warning("Deleting active partition. You should set another partition " "active."); doDelete(sliceNumber); if (table->selectedSlice >= table->numSlices) table->selectedSlice = (table->numSlices - 1); table->changesPending += 1;}static sliceType queryPrimaryLogical(objectKey primLogRadio){ sliceType retType = partition_none; int response = -1; if (graphics) { if (windowComponentGetSelected(primLogRadio, &response) < 0) return (retType = partition_none); } else { response = vshCursorMenu("Choose the partition type:", (char *[]){ "primary", "logical" }, 2, 0); if (response < 0) return (retType = partition_none); } switch (response) { case 0: default: retType = partition_primary; break; case 1: retType = partition_logical; break; } return (retType);}static int createSliceOrder(int sliceNumber, sliceType type){ // Given a slice number which currently contains empty space, determine the // correct table order for a new slice which will reside there (and re-order // others, if appropriate). int order = 0; int count1, count2; // Determine the partition table order of this new slice. First, just find // the first empty primary slot, which will be the order number if the new // slice is primary, and will also be the order number if the new slice is // logical but there are no existing logical slices already. for (count1 = 0; count1 < DISK_MAX_PARTITIONS; count1 ++) for (count2 = 0; count2 < table->numSlices; count2 ++) { if (table->slices[count2].raw.tag && !ISLOGICAL(&table->slices[count2]) && (table->slices[count2].raw.order == order)) { order += 1; break; } } if (type == partition_primary) { // Any logical slices will have their order numbers increased. for (count1 = 0; count1 < table->numSlices; count1 ++) if (ISLOGICAL(&table->slices[count1])) table->slices[count1].raw.order += 1; } else if (type == partition_logical) { // Logical slices' order in the table should always correspond with // their on-disk order, so if any previous slice is logical, the new // slice will follow it in the order. if (sliceNumber && ISLOGICAL(&table->slices[sliceNumber - 1])) order = (table->slices[sliceNumber - 1].raw.order + 1); // Otherwise if any following slice is logical, the new slice will // precede it in the order. else if ((sliceNumber < (table->numSlices - 1)) && ISLOGICAL(&table->slices[sliceNumber + 1])) order = table->slices[sliceNumber + 1].raw.order; // Any logical slices that follow this one will have their order // numbers increased. for (count1 = (sliceNumber + 1); count1 < table->numSlices; count1 ++) if (ISLOGICAL(&table->slices[count1])) table->slices[count1].raw.order += 1; } return (order);}static int doCreate(int sliceNumber, sliceType type, unsigned startCylinder, unsigned endCylinder){ // Does the non-interactive work of creating a partition slice *newSlice = &table->slices[sliceNumber]; int count; bzero(newSlice, sizeof(slice)); newSlice->raw.order = createSliceOrder(sliceNumber, type); newSlice->raw.type = type; newSlice->raw.tag = 0x01; newSlice->raw.geom.startCylinder = startCylinder; newSlice->raw.geom.startHead = 0; newSlice->raw.geom.startSector = 1; if (newSlice->raw.geom.startCylinder == 0) { if (type == partition_logical) // Don't write a logical slice on the first cylinder. newSlice->raw.geom.startCylinder += 1; else // Don't write the first track of the first cylinder newSlice->raw.geom.startHead += 1; } if (type == partition_logical) // Don't write the first track of the extended partition newSlice->raw.geom.startHead += 1; newSlice->raw.geom.endCylinder = endCylinder; newSlice->raw.geom.endHead = (table->disk->heads - 1); newSlice->raw.geom.endSector = table->disk->sectorsPerCylinder; newSlice->raw.startLogical = ((newSlice->raw.geom.startCylinder * CYLSECTS(table->disk)) + (newSlice->raw.geom.startHead * table->disk->sectorsPerCylinder)); newSlice->raw.sizeLogical = ((((newSlice->raw.geom.endCylinder - newSlice->raw.geom.startCylinder) + 1) * CYLSECTS(table->disk)) - (newSlice->raw.geom.startHead * table->disk->sectorsPerCylinder)); // Update the slice list updateSliceList(table); // Find our new slice in the list for (count = 0; count < table->numSlices; count ++) if (table->slices[count].raw.geom.startCylinder == startCylinder) { sliceNumber = count; break; } return (sliceNumber);}static void create(int sliceNumber){ // This is the interactive partition creation routine. enum { units_normal, units_mb, units_cylsize } units = units_normal; int status = 0; unsigned minStartCylinder = 0; unsigned maxEndCylinder = 0; sliceType type = partition_none; char startCyl[10]; char endCyl[10]; objectKey createDialog = NULL; objectKey primLogRadio = NULL; objectKey startCylField = NULL; objectKey endCylField = NULL; objectKey okButton = NULL; objectKey cancelButton = NULL; componentParameters params; windowEvent event; unsigned startCylinder = 0; unsigned endCylinder = 0; int newSliceNumber = ERR_NOSUCHENTRY; char tmpChar[160]; int count; minStartCylinder = table->slices[sliceNumber].raw.geom.startCylinder; maxEndCylinder = table->slices[sliceNumber].raw.geom.endCylinder; while (1) { // See if we can create a slice here, and if so, what type? type = table->label->canCreate(table->slices, table->numSlices, sliceNumber); if ((int) type < 0) return; if (graphics) { createDialog = windowNewDialog(window, "Create Partition"); bzero(¶ms, sizeof(componentParameters)); params.gridWidth = 1; params.gridHeight = 1; params.padTop = 5; params.padLeft = 5; params.padRight = 5; params.orientationX = orient_right; params.orientationY = orient_middle; windowNewTextLabel(createDialog, "Partition\ntype:", ¶ms); // A radio to select 'primary' or 'logical' params.gridX = 1; params.orientationX = orient_left; primLogRadio = windowNewRadioButton(createDialog, 2, 1, (char *[]) { "Primary", "Logical" }, 2 , ¶ms); if (type != partition_any) { if (type == partition_logical) windowComponentSetSelected(primLogRadio, 1); windowComponentSetEnabled(primLogRadio, 0); } // Don't create a logical slice on the first cylinder if ((type == partition_logical) && (minStartCylinder == 0)) minStartCylinder = 1; // A label and field for the starting cylinder snprintf(tmpChar, 160, STARTCYL_MESSAGE, minStartCylinder, maxEndCylinder); params.gridX = 0; params.gridY = 1; params.gridWidth = 2; windowNewTextLabel(createDialog, tmpChar, ¶ms); params.gridY = 2; params.flags |= WINDOW_COMPFLAG_HASBORDER; startCylField = windowNewTextField(createDialog, 10, ¶ms); // A label and field for the ending cylinder snprintf(tmpChar, 160, ENDCYL_MESSAGE, minStartCylinder, maxEndCylinder, cylsToMb(table->disk, (maxEndCylinder - minStartCylinder + 1)), (maxEndCylinder - minStartCylinder + 1)); params.gridY = 3; params.flags &= ~WINDOW_COMPFLAG_HASBORDER; windowNewTextLabel(createDialog, tmpChar, ¶ms); params.gridY = 4; params.flags |= WINDOW_COMPFLAG_HASBORDER; endCylField = windowNewTextField(createDialog, 10, ¶ms); // Make 'OK' and 'cancel' buttons params.gridY = 5; params.gridWidth = 1; params.padBottom = 5; params.orientationX = orient_right; params.flags &= ~WINDOW_COMPFLAG_HASBORDER; params.flags |= WINDOW_COMPFLAG_FIXEDWIDTH; okButton = windowNewButton(createDialog, "OK", NULL, ¶ms); params.gridX = 1; params.orientationX = orient_left; cancelButton = windowNewButton(createDialog, "Cancel", NULL, ¶ms); // Make the window visible windowSetResizable(createDialog, 0); windowCenterDialog(window, createDialog); windowSetVisible(createDialog, 1); while(1) { // Check for the OK button if ((windowComponentEventGet(okButton, &event) > 0) && (event.type == EVENT_MOUSE_LEFTUP)) break; // Check for the Cancel button if ((windowComponentEventGet(cancelButton, &event) > 0) && (event.type == EVENT_MOUSE_LEFTUP)) { windowDestroy(createDialog); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -