OLD | NEW |
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 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 | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 */ | 4 */ |
5 | 5 |
6 #include "cgptlib.h" | 6 #include "cgptlib.h" |
7 #include <string.h> | 7 #include <string.h> |
8 #include "cgptlib_internal.h" | 8 #include "cgptlib_internal.h" |
9 #include "crc32.h" | 9 #include "crc32.h" |
10 #include "gpt.h" | 10 #include "gpt.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 if (gpt->drive_sectors < (GPT_PMBR_SECTOR + | 51 if (gpt->drive_sectors < (GPT_PMBR_SECTOR + |
52 GPT_HEADER_SECTOR * 2 + | 52 GPT_HEADER_SECTOR * 2 + |
53 GPT_ENTRIES_SECTORS * 2)) | 53 GPT_ENTRIES_SECTORS * 2)) |
54 return GPT_ERROR_INVALID_SECTOR_NUMBER; | 54 return GPT_ERROR_INVALID_SECTOR_NUMBER; |
55 | 55 |
56 return GPT_SUCCESS; | 56 return GPT_SUCCESS; |
57 } | 57 } |
58 | 58 |
59 /* Expects header signature should be GPT_HEADER_SIGNATURE. */ | 59 /* Expects header signature should be GPT_HEADER_SIGNATURE. */ |
60 uint32_t CheckHeaderSignature(GptData *gpt) { | 60 uint32_t CheckHeaderSignature(GptData *gpt) { |
61 uint32_t valid_headers = MASK_BOTH; | |
62 GptHeader *headers[] = { | 61 GptHeader *headers[] = { |
63 (GptHeader*)gpt->primary_header, | 62 (GptHeader*)gpt->primary_header, |
64 (GptHeader*)gpt->secondary_header, | 63 (GptHeader*)gpt->secondary_header, |
65 }; | 64 }; |
66 int i; | 65 int i; |
67 | 66 |
68 for (i = PRIMARY; i <= SECONDARY; ++i) { | 67 for (i = PRIMARY; i <= SECONDARY; ++i) { |
69 if (Memcmp(headers[i]->signature, | 68 if (Memcmp(headers[i]->signature, |
70 GPT_HEADER_SIGNATURE, | 69 GPT_HEADER_SIGNATURE, |
71 GPT_HEADER_SIGNATURE_SIZE)) { | 70 GPT_HEADER_SIGNATURE_SIZE)) { |
72 INVALIDATE_HEADER(valid_headers, i); | 71 INVALIDATE_HEADER(gpt->valid_headers, i); |
73 } | 72 } |
74 } | 73 } |
75 return valid_headers; | 74 return gpt->valid_headers; |
76 } | 75 } |
77 | 76 |
78 /* The header revision should be GPT_HEADER_REVISION. */ | 77 /* The header revision should be GPT_HEADER_REVISION. */ |
79 uint32_t CheckRevision(GptData *gpt) { | 78 uint32_t CheckRevision(GptData *gpt) { |
80 uint32_t valid_headers = MASK_BOTH; | |
81 GptHeader *headers[] = { | 79 GptHeader *headers[] = { |
82 (GptHeader*)gpt->primary_header, | 80 (GptHeader*)gpt->primary_header, |
83 (GptHeader*)gpt->secondary_header, | 81 (GptHeader*)gpt->secondary_header, |
84 }; | 82 }; |
85 int i; | 83 int i; |
86 | 84 |
87 for (i = PRIMARY; i <= SECONDARY; ++i) { | 85 for (i = PRIMARY; i <= SECONDARY; ++i) { |
88 if (headers[i]->revision != GPT_HEADER_REVISION) | 86 if (headers[i]->revision != GPT_HEADER_REVISION) |
89 INVALIDATE_HEADER(valid_headers, i); | 87 INVALIDATE_HEADER(gpt->valid_headers, i); |
90 } | 88 } |
91 return valid_headers; | 89 return gpt->valid_headers; |
92 } | 90 } |
93 | 91 |
94 /* A valid header size should be between MIN_SIZE_OF_HEADER and | 92 /* A valid header size should be between MIN_SIZE_OF_HEADER and |
95 * MAX_SIZE_OF_HEADER. */ | 93 * MAX_SIZE_OF_HEADER. */ |
96 uint32_t CheckSize(GptData *gpt) { | 94 uint32_t CheckSize(GptData *gpt) { |
97 uint32_t valid_headers = MASK_BOTH; | |
98 GptHeader *headers[] = { | 95 GptHeader *headers[] = { |
99 (GptHeader*)gpt->primary_header, | 96 (GptHeader*)gpt->primary_header, |
100 (GptHeader*)gpt->secondary_header, | 97 (GptHeader*)gpt->secondary_header, |
101 }; | 98 }; |
102 int i; | 99 int i; |
103 | 100 |
104 for (i = PRIMARY; i <= SECONDARY; ++i) { | 101 for (i = PRIMARY; i <= SECONDARY; ++i) { |
105 if ((headers[i]->size < MIN_SIZE_OF_HEADER) || | 102 if ((headers[i]->size < MIN_SIZE_OF_HEADER) || |
106 (headers[i]->size > MAX_SIZE_OF_HEADER)) | 103 (headers[i]->size > MAX_SIZE_OF_HEADER)) |
107 INVALIDATE_HEADER(valid_headers, i); | 104 INVALIDATE_HEADER(gpt->valid_headers, i); |
108 } | 105 } |
109 return valid_headers; | 106 return gpt->valid_headers; |
110 } | 107 } |
111 | 108 |
112 /* Reserved and padding fields should be zero. */ | 109 /* Reserved and padding fields should be zero. */ |
113 uint32_t CheckReservedFields(GptData *gpt) { | 110 uint32_t CheckReservedFields(GptData *gpt) { |
114 uint32_t valid_headers = MASK_BOTH; | |
115 GptHeader *headers[] = { | 111 GptHeader *headers[] = { |
116 (GptHeader*)gpt->primary_header, | 112 (GptHeader*)gpt->primary_header, |
117 (GptHeader*)gpt->secondary_header, | 113 (GptHeader*)gpt->secondary_header, |
118 }; | 114 }; |
119 int i; | 115 int i; |
120 | 116 |
121 for (i = PRIMARY; i <= SECONDARY; ++i) { | 117 for (i = PRIMARY; i <= SECONDARY; ++i) { |
122 if (headers[i]->reserved || headers[i]->padding) | 118 if (headers[i]->reserved || headers[i]->padding) |
123 INVALIDATE_HEADER(valid_headers, i); | 119 INVALIDATE_HEADER(gpt->valid_headers, i); |
124 } | 120 } |
125 return valid_headers; | 121 return gpt->valid_headers; |
126 } | 122 } |
127 | 123 |
128 /* my_lba field points to the header itself. | 124 /* my_lba field points to the header itself. |
129 * So that the my_lba of primary header should be 1 (right after PMBR). | 125 * So that the my_lba of primary header should be 1 (right after PMBR). |
130 * The my_lba of secondary header should be the last secotr on drive. */ | 126 * The my_lba of secondary header should be the last secotr on drive. */ |
131 uint32_t CheckMyLba(GptData *gpt) { | 127 uint32_t CheckMyLba(GptData *gpt) { |
132 uint32_t valid_headers = MASK_BOTH; | |
133 GptHeader *primary_header, *secondary_header; | 128 GptHeader *primary_header, *secondary_header; |
134 | 129 |
135 primary_header = (GptHeader*)gpt->primary_header; | 130 primary_header = (GptHeader*)gpt->primary_header; |
136 secondary_header = (GptHeader*)gpt->secondary_header; | 131 secondary_header = (GptHeader*)gpt->secondary_header; |
137 | 132 |
138 if (primary_header->my_lba != GPT_PMBR_SECTOR) /* 2nd sector on drive */ | 133 if (primary_header->my_lba != GPT_PMBR_SECTOR) /* 2nd sector on drive */ |
139 INVALIDATE_HEADER(valid_headers, PRIMARY); | 134 INVALIDATE_HEADER(gpt->valid_headers, PRIMARY); |
140 if (secondary_header->my_lba != (gpt->drive_sectors - 1)) /* last sector */ | 135 if (secondary_header->my_lba != (gpt->drive_sectors - 1)) /* last sector */ |
141 INVALIDATE_HEADER(valid_headers, SECONDARY); | 136 INVALIDATE_HEADER(gpt->valid_headers, SECONDARY); |
142 return valid_headers; | 137 return gpt->valid_headers; |
143 } | 138 } |
144 | 139 |
145 /* SizeOfPartitionEntry must be between MIN_SIZE_OF_ENTRY and | 140 /* SizeOfPartitionEntry must be between MIN_SIZE_OF_ENTRY and |
146 * MAX_SIZE_OF_ENTRY, and a multiple of SIZE_OF_ENTRY_MULTIPLE. */ | 141 * MAX_SIZE_OF_ENTRY, and a multiple of SIZE_OF_ENTRY_MULTIPLE. */ |
147 uint32_t CheckSizeOfPartitionEntry(GptData *gpt) { | 142 uint32_t CheckSizeOfPartitionEntry(GptData *gpt) { |
148 uint32_t valid_headers = MASK_BOTH; | |
149 GptHeader *headers[] = { | 143 GptHeader *headers[] = { |
150 (GptHeader*)gpt->primary_header, | 144 (GptHeader*)gpt->primary_header, |
151 (GptHeader*)gpt->secondary_header, | 145 (GptHeader*)gpt->secondary_header, |
152 }; | 146 }; |
153 int i; | 147 int i; |
154 | 148 |
155 for (i = PRIMARY; i <= SECONDARY; ++i) { | 149 for (i = PRIMARY; i <= SECONDARY; ++i) { |
156 uint32_t size_of_entry = headers[i]->size_of_entry; | 150 uint32_t size_of_entry = headers[i]->size_of_entry; |
157 if ((size_of_entry < MIN_SIZE_OF_ENTRY) || | 151 if ((size_of_entry < MIN_SIZE_OF_ENTRY) || |
158 (size_of_entry > MAX_SIZE_OF_ENTRY) || | 152 (size_of_entry > MAX_SIZE_OF_ENTRY) || |
159 (size_of_entry & (SIZE_OF_ENTRY_MULTIPLE - 1))) | 153 (size_of_entry & (SIZE_OF_ENTRY_MULTIPLE - 1))) |
160 INVALIDATE_HEADER(valid_headers, i); | 154 INVALIDATE_HEADER(gpt->valid_headers, i); |
161 } | 155 } |
162 return valid_headers; | 156 return gpt->valid_headers; |
163 } | 157 } |
164 | 158 |
165 /* number_of_entries must be between MIN_NUMBER_OF_ENTRIES and | 159 /* number_of_entries must be between MIN_NUMBER_OF_ENTRIES and |
166 * MAX_NUMBER_OF_ENTRIES, and size_of_entry * number_of_entries must be | 160 * MAX_NUMBER_OF_ENTRIES, and size_of_entry * number_of_entries must be |
167 * equal to TOTAL_ENTRIES_SIZE. */ | 161 * equal to TOTAL_ENTRIES_SIZE. */ |
168 uint32_t CheckNumberOfEntries(GptData *gpt) { | 162 uint32_t CheckNumberOfEntries(GptData *gpt) { |
169 uint32_t valid_headers = MASK_BOTH; | |
170 GptHeader *headers[] = { | 163 GptHeader *headers[] = { |
171 (GptHeader*)gpt->primary_header, | 164 (GptHeader*)gpt->primary_header, |
172 (GptHeader*)gpt->secondary_header, | 165 (GptHeader*)gpt->secondary_header, |
173 }; | 166 }; |
174 int i; | 167 int i; |
175 | 168 |
176 for (i = PRIMARY; i <= SECONDARY; ++i) { | 169 for (i = PRIMARY; i <= SECONDARY; ++i) { |
177 uint32_t number_of_entries = headers[i]->number_of_entries; | 170 uint32_t number_of_entries = headers[i]->number_of_entries; |
178 if ((number_of_entries < MIN_NUMBER_OF_ENTRIES) || | 171 if ((number_of_entries < MIN_NUMBER_OF_ENTRIES) || |
179 (number_of_entries > MAX_NUMBER_OF_ENTRIES) || | 172 (number_of_entries > MAX_NUMBER_OF_ENTRIES) || |
180 (number_of_entries * headers[i]->size_of_entry != TOTAL_ENTRIES_SIZE)) | 173 (number_of_entries * headers[i]->size_of_entry != TOTAL_ENTRIES_SIZE)) |
181 INVALIDATE_HEADER(valid_headers, i); | 174 INVALIDATE_HEADER(gpt->valid_headers, i); |
182 } | 175 } |
183 return valid_headers; | 176 return gpt->valid_headers; |
184 } | 177 } |
185 | 178 |
186 /* Make sure entries_lba is correct. | 179 /* Make sure entries_lba is correct. |
187 * 2 for primary entries | 180 * 2 for primary entries |
188 * drive_sectors-1-GPT_ENTRIES_SECTORS for secondary entries. */ | 181 * drive_sectors-1-GPT_ENTRIES_SECTORS for secondary entries. */ |
189 uint32_t CheckEntriesLba(GptData *gpt) { | 182 uint32_t CheckEntriesLba(GptData *gpt) { |
190 uint32_t valid_headers = MASK_BOTH; | |
191 GptHeader *primary_header, *secondary_header; | 183 GptHeader *primary_header, *secondary_header; |
192 | 184 |
193 primary_header = (GptHeader*)gpt->primary_header; | 185 primary_header = (GptHeader*)gpt->primary_header; |
194 secondary_header = (GptHeader*)gpt->secondary_header; | 186 secondary_header = (GptHeader*)gpt->secondary_header; |
195 | 187 |
196 /* We assume the primary partition entry table is located at the sector | 188 /* We assume the primary partition entry table is located at the sector |
197 * right after primary partition header. */ | 189 * right after primary partition header. */ |
198 if (primary_header->entries_lba != (GPT_PMBR_SECTOR + GPT_HEADER_SECTOR)) | 190 if (primary_header->entries_lba != (GPT_PMBR_SECTOR + GPT_HEADER_SECTOR)) |
199 INVALIDATE_HEADER(valid_headers, PRIMARY); | 191 INVALIDATE_HEADER(gpt->valid_headers, PRIMARY); |
200 /* We assume the secondary partition entry table is the 32 sectors | 192 /* We assume the secondary partition entry table is the 32 sectors |
201 * right before the secondary partition header. */ | 193 * right before the secondary partition header. */ |
202 if (secondary_header->entries_lba != | 194 if (secondary_header->entries_lba != |
203 (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS)) | 195 (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS)) |
204 INVALIDATE_HEADER(valid_headers, SECONDARY); | 196 INVALIDATE_HEADER(gpt->valid_headers, SECONDARY); |
205 return valid_headers; | 197 return gpt->valid_headers; |
206 } | 198 } |
207 | 199 |
208 /* FirstUsableLBA must be after the end of the primary GPT table array. | 200 /* FirstUsableLBA must be after the end of the primary GPT table array. |
209 * LastUsableLBA must be before the start of the secondary GPT table array. | 201 * LastUsableLBA must be before the start of the secondary GPT table array. |
210 * FirstUsableLBA <= LastUsableLBA. */ | 202 * FirstUsableLBA <= LastUsableLBA. */ |
211 uint32_t CheckValidUsableLbas(GptData *gpt) { | 203 uint32_t CheckValidUsableLbas(GptData *gpt) { |
212 uint32_t valid_headers = MASK_BOTH; | |
213 uint64_t end_of_primary_entries; | 204 uint64_t end_of_primary_entries; |
214 uint64_t start_of_secondary_entries; | 205 uint64_t start_of_secondary_entries; |
215 GptHeader *headers[] = { | 206 GptHeader *headers[] = { |
216 (GptHeader*)gpt->primary_header, | 207 (GptHeader*)gpt->primary_header, |
217 (GptHeader*)gpt->secondary_header, | 208 (GptHeader*)gpt->secondary_header, |
218 }; | 209 }; |
219 int i; | 210 int i; |
220 | 211 |
221 end_of_primary_entries = GPT_PMBR_SECTOR + GPT_HEADER_SECTOR + | 212 end_of_primary_entries = GPT_PMBR_SECTOR + GPT_HEADER_SECTOR + |
222 GPT_ENTRIES_SECTORS; | 213 GPT_ENTRIES_SECTORS; |
223 start_of_secondary_entries = (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS); | 214 start_of_secondary_entries = (gpt->drive_sectors - 1 - GPT_ENTRIES_SECTORS); |
224 | 215 |
225 for (i = PRIMARY; i <= SECONDARY; ++i) { | 216 for (i = PRIMARY; i <= SECONDARY; ++i) { |
226 if (headers[i]->first_usable_lba < end_of_primary_entries) | 217 if (headers[i]->first_usable_lba < end_of_primary_entries) |
227 INVALIDATE_HEADER(valid_headers, i); | 218 INVALIDATE_HEADER(gpt->valid_headers, i); |
228 if (headers[i]->last_usable_lba >= start_of_secondary_entries) | 219 if (headers[i]->last_usable_lba >= start_of_secondary_entries) |
229 INVALIDATE_HEADER(valid_headers, i); | 220 INVALIDATE_HEADER(gpt->valid_headers, i); |
230 if (headers[i]->first_usable_lba > headers[i]->last_usable_lba) | 221 if (headers[i]->first_usable_lba > headers[i]->last_usable_lba) |
231 INVALIDATE_HEADER(valid_headers, i); | 222 INVALIDATE_HEADER(gpt->valid_headers, i); |
232 } | 223 } |
233 | 224 |
234 if (headers[PRIMARY]->first_usable_lba - headers[PRIMARY]->entries_lba < | 225 if (headers[PRIMARY]->first_usable_lba - headers[PRIMARY]->entries_lba < |
235 GPT_ENTRIES_SECTORS) | 226 GPT_ENTRIES_SECTORS) |
236 INVALIDATE_HEADER(valid_headers, PRIMARY); | 227 INVALIDATE_HEADER(gpt->valid_headers, PRIMARY); |
237 if (headers[SECONDARY]->last_usable_lba >= headers[SECONDARY]->entries_lba) | 228 if (headers[SECONDARY]->last_usable_lba >= headers[SECONDARY]->entries_lba) |
238 INVALIDATE_HEADER(valid_headers, SECONDARY); | 229 INVALIDATE_HEADER(gpt->valid_headers, SECONDARY); |
239 | 230 |
240 return valid_headers; | 231 return gpt->valid_headers; |
241 } | 232 } |
242 | 233 |
243 /* Checks header CRC */ | 234 /* Checks header CRC */ |
244 uint32_t CheckHeaderCrc(GptData *gpt) { | 235 uint32_t CheckHeaderCrc(GptData *gpt) { |
245 uint32_t crc32, original_crc32; | 236 uint32_t crc32, original_crc32; |
246 GptHeader *headers[] = { | 237 GptHeader *headers[] = { |
247 (GptHeader*)gpt->primary_header, | 238 (GptHeader*)gpt->primary_header, |
248 (GptHeader*)gpt->secondary_header, | 239 (GptHeader*)gpt->secondary_header, |
249 }; | 240 }; |
250 int i; | 241 int i; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 273 |
283 for (i = PRIMARY; i <= SECONDARY; ++i) { | 274 for (i = PRIMARY; i <= SECONDARY; ++i) { |
284 crc32 = Crc32((const uint8_t *)entries[i], TOTAL_ENTRIES_SIZE); | 275 crc32 = Crc32((const uint8_t *)entries[i], TOTAL_ENTRIES_SIZE); |
285 if (crc32 != entries_crc32) | 276 if (crc32 != entries_crc32) |
286 INVALIDATE_ENTRIES(gpt->valid_entries, i); | 277 INVALIDATE_ENTRIES(gpt->valid_entries, i); |
287 } | 278 } |
288 return gpt->valid_entries; | 279 return gpt->valid_entries; |
289 } | 280 } |
290 | 281 |
291 /* Returns non-zero if the given GUID is non-zero. */ | 282 /* Returns non-zero if the given GUID is non-zero. */ |
292 static int NonZeroGuid(const Guid *guid) { | 283 int NonZeroGuid(const Guid *guid) { |
293 static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; | 284 static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; |
294 return Memcmp(&zero, guid, sizeof(zero)); | 285 return Memcmp(&zero, guid, sizeof(zero)); |
295 } | 286 } |
296 | 287 |
297 /* Checks if entries geometry is valid. | 288 /* Checks if entries geometry is valid. |
298 * All active (non-zero PartitionTypeGUID) partition entries should have: | 289 * All active (non-zero PartitionTypeGUID) partition entries should have: |
299 * entry.StartingLBA >= header.FirstUsableLBA | 290 * entry.StartingLBA >= header.FirstUsableLBA |
300 * entry.EndingLBA <= header.LastUsableLBA | 291 * entry.EndingLBA <= header.LastUsableLBA |
301 * entry.StartingLBA <= entry.EndingLBA | 292 * entry.StartingLBA <= entry.EndingLBA |
302 */ | 293 */ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 (pairs[i].starting <= pairs[i-1].ending)) | 360 (pairs[i].starting <= pairs[i-1].ending)) |
370 return 1; | 361 return 1; |
371 } | 362 } |
372 | 363 |
373 return 0; | 364 return 0; |
374 } | 365 } |
375 | 366 |
376 /* Checks if any two partitions are overlapped in primary and secondary entries. | 367 /* Checks if any two partitions are overlapped in primary and secondary entries. |
377 */ | 368 */ |
378 uint32_t CheckOverlappedPartition(GptData *gpt) { | 369 uint32_t CheckOverlappedPartition(GptData *gpt) { |
379 uint32_t valid_entries = MASK_BOTH; | |
380 GptHeader *headers[] = { | 370 GptHeader *headers[] = { |
381 (GptHeader*)gpt->primary_header, | 371 (GptHeader*)gpt->primary_header, |
382 (GptHeader*)gpt->secondary_header, | 372 (GptHeader*)gpt->secondary_header, |
383 }; | 373 }; |
384 GptEntry *entries[] = { | 374 GptEntry *entries[] = { |
385 (GptEntry*)gpt->primary_entries, | 375 (GptEntry*)gpt->primary_entries, |
386 (GptEntry*)gpt->secondary_entries, | 376 (GptEntry*)gpt->secondary_entries, |
387 }; | 377 }; |
388 int i; | 378 int i; |
389 uint32_t number_of_entries; | 379 uint32_t number_of_entries; |
390 | 380 |
391 if (gpt->valid_headers & MASK_PRIMARY) | 381 if (gpt->valid_headers & MASK_PRIMARY) |
392 number_of_entries = headers[PRIMARY]->number_of_entries; | 382 number_of_entries = headers[PRIMARY]->number_of_entries; |
393 else | 383 else |
394 number_of_entries = headers[SECONDARY]->number_of_entries; | 384 number_of_entries = headers[SECONDARY]->number_of_entries; |
395 | 385 |
396 for (i = PRIMARY; i <= SECONDARY; ++i) { | 386 for (i = PRIMARY; i <= SECONDARY; ++i) { |
397 if (OverlappedEntries(entries[i], number_of_entries)) | 387 if (OverlappedEntries(entries[i], number_of_entries)) |
398 INVALIDATE_ENTRIES(valid_entries, i); | 388 INVALIDATE_ENTRIES(gpt->valid_entries, i); |
399 } | 389 } |
400 return valid_entries; | 390 return gpt->valid_entries; |
401 } | 391 } |
402 | 392 |
403 /* Primary entries and secondary entries should be bitwise identical. | 393 /* Primary entries and secondary entries should be bitwise identical. |
404 * If two entries tables are valid, compare them. If not the same, | 394 * If two entries tables are valid, compare them. If not the same, |
405 * overwrites secondary with primary (primary always has higher priority), | 395 * overwrites secondary with primary (primary always has higher priority), |
406 * and marks secondary as modified. | 396 * and marks secondary as modified. |
407 * If only one is valid, overwrites invalid one. | 397 * If only one is valid, overwrites invalid one. |
408 * If all are invalid, does nothing. | 398 * If all are invalid, does nothing. |
409 * This function returns bit masks for GptData.modified field. | 399 * This function returns bit masks for GptData.modified field. |
410 * Note that CRC is NOT re-computed in this function. | 400 * Note that CRC is NOT re-computed in this function. |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 RepairEntries(gpt, MASK_PRIMARY); | 800 RepairEntries(gpt, MASK_PRIMARY); |
811 /* Actually two entries are dirty now. | 801 /* Actually two entries are dirty now. |
812 * Also two headers are dirty because entries_crc32 has been updated. */ | 802 * Also two headers are dirty because entries_crc32 has been updated. */ |
813 gpt->modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | | 803 gpt->modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | |
814 GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); | 804 GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); |
815 UpdateCrc(gpt); | 805 UpdateCrc(gpt); |
816 } | 806 } |
817 | 807 |
818 return GPT_SUCCESS; | 808 return GPT_SUCCESS; |
819 } | 809 } |
OLD | NEW |