Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1505)

Side by Side Diff: utility/cgpt/cgpt_add_modify_delete.c

Issue 2719008: Nearly complete rewrite of cgpt tool. (Closed) Base URL: ssh://git@chromiumos-git//vboot_reference.git
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « utility/cgpt/cgpt.c ('k') | utility/cgpt/cgpt_attribute.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Update GPT attribute bits.
6 */
7 #include <getopt.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "cgpt.h"
11 #include "cgptlib_internal.h"
12 #include "cgpt_tofix.h"
13 #include "utility.h"
14
15 static struct number_range
16 range_127_0 = {127, 0};
17
18 /* Integers to store parsed argument. */
19 static int help, partition, begin_lba, size_lba;
20 static char type[128], unique[128], name[128];
21
22 /* The structure for getopt_long(). When you add/delete any line, please refine
23 * attribute_comments[] and third parameter of getopt_long() too. */
24 static struct option adm_options[] = {
25 {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'},
26 {.name = "partition", .has_arg = required_argument, .flag = 0, .val = 'i'},
27 #if 0//FIXME
28 {.name = "bad", .has_arg = required_argument, .flag = 0, .val = 'b'},
29 {.name = "successful", .has_arg = required_argument, .flag = 0, .val = 's'},
30 {.name = "tries", .has_arg = required_argument, .flag = 0, .val = 't'},
31 {.name = "priority", .has_arg = required_argument, .flag = 0, .val = 'p'},
32 #endif
33 {.name = "type", .has_arg = required_argument, .flag = 0, .val = 't'},
34 {.name = "unique", .has_arg = required_argument, .flag = 0, .val = 'u'},
35 {.name = "begin", .has_arg = required_argument, .flag = 0, .val = 'b'},
36 {.name = "size", .has_arg = required_argument, .flag = 0, .val = 's'},
37 {.name = "name", .has_arg = required_argument, .flag = 0, .val = 'n'},
38 { /* last element, which should be zero. */ }
39 };
40
41 /* Extra information than struct option, please update this structure if you
42 * add/remove any line in attribute_options[]. */
43 static struct option_details adm_options_details[] = {
44 /* help */
45 { .comment = "print this help",
46 .validator = AssignTrue,
47 .valid_range = 0,
48 .parsed = &help},
49 /* partition */
50 { .comment = "partition number (MUST HAVE)",
51 .validator = InNumberRange,
52 .valid_range = &range_127_0,
53 .parsed = &partition},
54 #if 0//FIXME
55 /* bad */
56 { .comment = "mark partition bad",
57 .validator = InNumberRange,
58 .valid_range = &range_1_0,
59 .parsed = &bad},
60 /* successful */
61 { .comment = "mark partition successful",
62 .validator = InNumberRange,
63 .valid_range = &range_1_0,
64 .parsed = &successful},
65 /* tries */
66 { .comment = "tries",
67 .validator = InNumberRange,
68 .valid_range = &range_15_0,
69 .parsed = &tries},
70 /* priority */
71 { .comment = "priority to boot",
72 .validator = InNumberRange,
73 .valid_range = &range_15_0,
74 .parsed = &priority},
75 #endif
76 /* type */
77 { .comment = "Partition Type (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
78 .validator = CopyString,
79 .valid_range = (void*)sizeof(type),
80 .parsed = &type},
81 /* uuid */
82 { .comment = "Partition UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
83 .validator = CopyString,
84 .valid_range = (void*)sizeof(unique),
85 .parsed = &unique},
86 /* start */
87 { .comment = "starting LBA",
88 .validator = InNumberRange,
89 .valid_range = 0,
90 .parsed = &begin_lba},
91 /* end */
92 { .comment = "ending LBA",
93 .validator = InNumberRange,
94 .valid_range = 0,
95 .parsed = &size_lba},
96 /* name */
97 { .comment = "Partition name",
98 .validator = CopyString,
99 .valid_range = (void*)sizeof(name),
100 .parsed = &name},
101 { /* last element, which should be zero. */ }
102 };
103
104 void AdmHelp() {
105 printf("\nUsage: %s {add|delete|modify} [OPTIONS] device_name\n\n", progname);
106 ShowOptions(adm_options, adm_options_details, ARRAY_COUNT(adm_options));
107 PrintTypes();
108 printf("\n");
109 }
110
111 enum {
112 ADD,
113 DELETE,
114 MODIFY,
115 } command;
116
117 /* Parses all options (and validates them), then opens the drive and sets
118 * corresponding bits in GPT entry. */
119 int CgptAdm(int argc, char *argv[]) {
120 struct drive drive;
121 char *cmd;
122 GptEntry *entry;
123 Guid type_guid, unique_guid;
124 int dirty = 0;
125
126 /* I know this is NOT the perfect place to put code to make options[] and
127 * details[] are synced. But this is the best place we have right now since C
128 * preprocessor doesn't know sizeof() for #if directive. */
129 assert(ARRAY_COUNT(adm_options) ==
130 ARRAY_COUNT(adm_options_details));
131
132 cmd = argv[optind - 1];
133 if (!strcmp("add", cmd)) command = ADD;
134 else if (!strcmp("delete", cmd)) command = DELETE;
135 else if (!strcmp("modify", cmd)) command = MODIFY;
136
137 #if 0//FIXME
138 help = partition = bad = successful = tries = priority =
139 #endif
140 help = partition = begin_lba = size_lba = NOT_INITED;
141 type[0] = '\0';
142 unique[0] = '\0';
143 name[0] = '\0';
144
145 if (CGPT_OK != HandleOptions(argc, argv,
146 "hi:t:u:b:s:n:",
147 ARRAY_COUNT(adm_options),
148 adm_options,
149 adm_options_details))
150 return CGPT_FAILED;
151 if (help != NOT_INITED) {
152 AdmHelp();
153 return CGPT_FAILED;
154 }
155
156 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive))
157 return CGPT_FAILED;
158
159 if (CheckValid(&drive) != CGPT_OK) goto error_close;
160
161 if (partition == NOT_INITED) {
162 printf("[ERROR] Please provide partition number with --partition or -i.\n");
163 goto error_close;
164 }
165
166 entry = GetEntry(&drive.gpt, PRIMARY, partition);
167 /* check before really doing something. */
168 switch (command) {
169 case ADD:
170 if (NonZeroGuid(&entry->type)) {
171 printf("[ERROR] partition %d is not free, use '%s modify' instead.\n",
172 partition, progname);
173 goto error_close;
174 }
175 if (type[0] == '\0') {
176 printf("* You must give a type with '--type' or '-t'.\n");
177 PrintTypes();
178 goto error_close;
179 }
180 if (begin_lba == NOT_INITED) {
181 printf("* You didn't give the begin LBA, use '--begin' to specify.\n");
182 goto error_close;
183 }
184 if (size_lba == NOT_INITED) {
185 printf("* You didn't give size, use '--size' to specify.\n");
186 goto error_close;
187 }
188 break;
189 case DELETE:
190 if (!NonZeroGuid(&entry->type)) {
191 printf("[ERROR] partition %d is free already.\n", partition);
192 goto error_close;
193 }
194 break;
195 case MODIFY:
196 if (!NonZeroGuid(&entry->type)) {
197 printf("[ERROR] partition %d is free, use '%s add' first.\n",
198 partition, progname);
199 goto error_close;
200 }
201 break;
202 }
203
204 #if 0 //FIXME
205 if (bad != NOT_INITED)
206 SetBad(&drive.gpt, PRIMARY, partition, bad);
207 if (successful != NOT_INITED)
208 SetSuccessful(&drive.gpt, PRIMARY, partition, successful);
209 if (tries != NOT_INITED)
210 SetTries(&drive.gpt, PRIMARY, partition, tries);
211 if (priority != NOT_INITED)
212 SetPriority(&drive.gpt, PRIMARY, partition, priority);
213 #endif
214 if (type[0]) {
215 if (CGPT_OK != SupportedType(type, &type_guid) &&
216 CGPT_OK != StrToGuid(type, &type_guid)) {
217 printf("[ERROR] You didn't give a valid type [%s]\n", type);
218 goto error_close;
219 }
220 Memcpy(&entry->type, &type_guid, sizeof(Guid));
221 ++dirty;
222 }
223 if (unique[0]) {
224 if (CGPT_OK != StrToGuid(unique, &unique_guid)) {
225 printf("[ERROR] You didn't give a valid UUID [%s]\n", unique);
226 goto error_close;
227 }
228 Memcpy(&entry->unique, &unique_guid, sizeof(Guid));
229 ++dirty;
230 }
231 if (begin_lba != NOT_INITED) {
232 entry->starting_lba = begin_lba;
233 ++dirty;
234 }
235 if (size_lba != NOT_INITED) {
236 entry->ending_lba = entry->starting_lba + size_lba - 1;
237 ++dirty;
238 }
239 if (name[0]) {
240 UTF8ToUTF16((uint8_t*)name, entry->name);
241 ++dirty;
242 }
243
244 if (command == DELETE) {
245 Memcpy(&entry->type, &guid_unused, sizeof(Guid));
246 }
247
248 if (dirty) {
249 uint32_t valid_entries;
250
251 valid_entries = drive.gpt.valid_entries;
252 if ((valid_entries != CheckValidEntries(&drive.gpt)) ||
253 (valid_entries != CheckOverlappedPartition(&drive.gpt))) {
254 printf("\n[ERROR] Your change makes GPT invalid (or worse). "
255 "Please check your arguments.\n\n");
256 drive.gpt.modified = 0; /* DriveClose() won't update hard drive. */
257 goto error_close;
258 }
259
260 /* Claims primary is good, then secondary will be overwritten. */
261 RepairEntries(&drive.gpt, MASK_PRIMARY);
262 RepairHeader(&drive.gpt, MASK_PRIMARY);
263
264 /* Forces headers and entries are modified so that CRC32 will be
265 * re-calculated and headers and entries will be updated to drive. */
266 drive.gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
267 GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
268 UpdateCrc(&drive.gpt);
269 }
270 DriveClose(&drive);
271 return CGPT_OK;
272
273 error_close:
274 DriveClose(&drive);
275 return CGPT_FAILED;
276 }
OLDNEW
« no previous file with comments | « utility/cgpt/cgpt.c ('k') | utility/cgpt/cgpt_attribute.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698