📄 gpt.c
字号:
int status = 0; gptEntry *entries = NULL; // Get the memory entries = malloc(header->numPartEntries * header->partEntryBytes); if (entries == NULL) { printf("Can't get memory for a GPT entry array\n"); return (entries = NULL); } // Seek to the start of the partition entries status = (int) lseek64(fd, (header->partEntriesLBA * 512), SEEK_SET); if (status == -1) { printf("Can't seek device to entries\n"); free(entries); return (entries = NULL); } // Read the data status = read(fd, entries, (header->numPartEntries * header->partEntryBytes)); if (status < (header->numPartEntries * header->partEntryBytes)) { printf("Can't read device\n"); free(entries); return (entries = NULL); } return (entries);}static int gptWriteEntries(int fd, gptHeader *header, gptEntry *entries){ // Given a file descriptor for the open disk, and GPT header and entries // pointers, write the partition entries to disk. int status = 0; // Seek to the start of the partition entries status = (int) lseek64(fd, (header->partEntriesLBA * 512), SEEK_SET); if (status == -1) { printf("Can't seek device\n"); return (-1); } // Write the data status = (int) write(fd, entries, (header->partEntryBytes * header->numPartEntries)); if (status != (header->partEntryBytes * header->numPartEntries)) { printf("Can't write device\n"); return (-1); } // Update the entries checksum in the header header->partEntriesCRC32 = gptEntriesChecksum(entries, (header->partEntryBytes * header->numPartEntries)); return (0);}static inline int gptEntryUsed(gptEntry *entry){ // A GPT entry is empty if the partition type GIUD is all zeros if (memcmp(&entry->partTypeGUID, &GUID_UNUSED, sizeof(gptGuid))) return (1); else return (0);}static int gptGetPart(char *fullpath, struct diskent *ent, int *maxp){ // Given a *full path* disk name, get the partition info from a // GPT-labelled disk int status = 0; int fd = 0; gptHeader *header = NULL; gptEntry *entries = NULL; int count; // Open the disk device fd = open(fullpath, O_RDWR); if (fd == -1) { printf("Can't open device %s\n", fullpath); return (-1); } // Read the header header = gptGetHeader(fd); if (!header) { close(fd); return (-1); } // Read the partition entries entries = gptGetEntries(fd, header); close(fd); if (!entries) { free(header); return (-1); } // Fill in the partition entries for (count = 0; ((count < MAX_PARTITIONS) && (count < header->numPartEntries)); count ++) { if (gptEntryUsed(&entries[count])) { ent->part[count + 1].part_num = (count + 1); ent->part[count + 1].part_start = entries[count].startingLBA; ent->part[count + 1].part_size = (entries[count].endingLBA - entries[count].startingLBA + 1); ent->part[count + 1].part_tag = gpt_map_guid_to_tag(&entries[count] .partTypeGUID); memcpy(&(ent->part[count + 1].part_type_guid), &entries[count].partTypeGUID, sizeof(gptGuid)); memcpy(&(ent->part[count + 1].part_guid), &entries[count].partGUID, sizeof(gptGuid)); ent->part[count + 1].part_flags = entries[count].attributes; memcpy(ent->part[count + 1].part_name, entries[count].partName, 72); printf("%d: start %llu end %llu attrib %llx %s", count, entries[count].startingLBA, entries[count].endingLBA, entries[count].attributes, entries[count].partName); printGUID(&entries[count].partTypeGUID); printf("\n"); } } free(header); free(entries); return (0);}static int gptFindEntry(gptHeader *header, gptEntry *entries, unsigned long long start, unsigned long long size){ // Given an array of GPT partition entries, try to locate one with the // supplied start and size values. If found, return the index of the // entry. Otherwise, return -1 int count; for (count = 0; count < header->numPartEntries; count ++) { if (gptEntryUsed(&entries[count]) && (entries[count].startingLBA == start) && (entries[count].endingLBA == (start + size - 1))) return (count); } // Not found return (-1);}static int gptWritePart(char *fullpath, struct diskent *ent, int flag){ // Given a *full path* disk name pointing to a GPT-labelled disk, write a // new partition scheme to disk. int status = 0; int fd = 0; gptHeader *header = NULL; gptEntry *orig_entries = NULL; gptEntry *entries = NULL; int count; // Open the disk device fd = open(fullpath, O_RDWR); if (fd == -1) { printf("Can't open device %s\n", fullpath); return (-1); } // Read the header header = gptGetHeader(fd); if (!header) { close(fd); return (-1); } // Read the existing partition entries orig_entries = gptGetEntries(fd, header); if (!orig_entries) { free(header); close(fd); return (-1); } // Get some memory to hold our array of new entries entries = calloc(header->numPartEntries, header->partEntryBytes); if (!entries) { free(header); free(orig_entries); close(fd); return (-1); } // Loop for each partition for (count = 1; ((count <= MAX_PARTITIONS) && (count <= header->numPartEntries)); count ++) { if (ent->part[count].part_size) { // Is there already a matching entry? int old_index = gptFindEntry(header, orig_entries, ent->part[count].part_start, ent->part[count].part_size); if (old_index >= 0) { // A matching entry already exists (i.e. one with the same start // and end positions). Because our system would cause all kinds // of information to be lost, we copy the existing entry first, // and then overwrite the fields we've been provided. memcpy(&entries[count - 1], &orig_entries[old_index], header->partEntryBytes); } else { memcpy(&entries[count - 1].partGUID, &GUID_EXT2, sizeof(gptGuid)); entries[count - 1].attributes = 0; //entries[count - 1].partName[72]; } entries[count - 1].startingLBA = ent->part[count].part_start; entries[count - 1].endingLBA = (ent->part[count].part_start + (ent->part[count].part_size - 1)); memcpy(&entries[count - 1].partTypeGUID, gpt_map_tag_to_guid(ent->part[count].part_tag), sizeof(gptGuid)); // Make sure the start and end are legal if ((entries[count - 1].startingLBA < header->firstUsableLBA) || (entries[count - 1].endingLBA > header->lastUsableLBA)) { printf("Partition parameters (%llu->%llu) are outside legal range " "(%llu->%llu)", entries[count - 1].startingLBA, entries[count - 1].endingLBA, header->firstUsableLBA, header->lastUsableLBA); continue; } printf("Wrote entry %d %llu-%llu\n", (count - 1), entries[count - 1].startingLBA, entries[count - 1].endingLBA); } else printf("Entry %d size %llu\n", (count - 1), ent->part[count].part_size); } // Write out the entries status = gptWriteEntries(fd, header, entries); if (status) printf("Error %d writing GPT entries\n", status); // Write out the header status = gptWriteHeader(fd, header); if (status) printf("Error %d writing GPT header\n", status); // Just to make sure, partition information updated on the disk. fsync(fd); sleep(1); // Have the kernel re-read the partitions. ioctl(fd, BLKRRPART); close(fd); free(header); free(orig_entries); free(entries); return (status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -