1e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 24bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * Use of this source code is governed by a BSD-style license that can be 34bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * found in the LICENSE file. 44bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo */ 54bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 6f510973497a430c1bb41d9b7e996d02fb7f7179eAlex Deymo#include <errno.h> 737f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#include <string.h> 83dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 9534723a6519267461855441279b321e6fc1e4e90Albert Chaulk#include "../cgpt/cgpt.h" 100dce41c2ece9020d5ac9bb68c9772432fac85e64Louis Yung-Chieh Lo#include "cgptlib_internal.h" 113dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#include "cgptlib_test.h" 1249fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo#include "crc32.h" 13b31ddcec6a826986cd215725bf4defbc6021fe6bLouis Yung-Chieh Lo#include "crc32_test.h" 1437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#include "gpt.h" 153ecaf776d82d29573be083b2e5c6ddc5b9f49c70vbendeb#include "test_common.h" 16534723a6519267461855441279b321e6fc1e4e90Albert Chaulk#define _STUB_IMPLEMENTATION_ 1737f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#include "utility.h" 1837f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 19e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 20e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Testing partition layout (sector_bytes=512) 2137f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 2237f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * LBA Size Usage 23b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo * --------------------------------------------------------- 2437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 0 1 PMBR 2537f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 1 1 primary partition header 2637f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 2 32 primary partition entries (128B * 128) 27b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo * 34 100 kernel A (index: 0) 28b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo * 134 100 root A (index: 1) 29b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo * 234 100 root B (index: 2) 30b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo * 334 100 kernel B (index: 3) 3137f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 434 32 secondary partition entries 3237f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 466 1 secondary partition header 3337f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * 467 3437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo */ 35b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo#define KERNEL_A 0 363dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#define KERNEL_B 1 373dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#define ROOTFS_A 2 383dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#define ROOTFS_B 3 393dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#define KERNEL_X 2 /* Overload ROOTFS_A, for some GetNext tests */ 403dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#define KERNEL_Y 3 /* Overload ROOTFS_B, for some GetNext tests */ 41b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 4237f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#define DEFAULT_SECTOR_SIZE 512 4337f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#define MAX_SECTOR_SIZE 4096 4437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#define DEFAULT_DRIVE_SECTORS 467 45f3f7fca07fbcb6bb9655a71257f09c71b0a1458dDan Ehrenberg#define TOTAL_ENTRIES_SIZE (MAX_NUMBER_OF_ENTRIES * sizeof(GptEntry)) /* 16384 */ 4649fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo#define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ 4737f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 483dcf9dce04301d6d735f265652625fffb6758430Randall Spanglerstatic const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; 493dcf9dce04301d6d735f265652625fffb6758430Randall Spanglerstatic const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; 503dcf9dce04301d6d735f265652625fffb6758430Randall Spanglerstatic const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; 513dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 52534723a6519267461855441279b321e6fc1e4e90Albert Chaulk// cgpt_common.c requires these be defined if linked in. 53534723a6519267461855441279b321e6fc1e4e90Albert Chaulkconst char *progname = "CGPT-TEST"; 54534723a6519267461855441279b321e6fc1e4e90Albert Chaulkconst char *command = "TEST"; 55534723a6519267461855441279b321e6fc1e4e90Albert Chaulk 56e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 57e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Copy a random-for-this-program-only Guid into the dest. The num parameter 58aa8eda4f97f43a51bfec4fc096635565617a89e0Bill Richardson * completely determines the Guid. 59aa8eda4f97f43a51bfec4fc096635565617a89e0Bill Richardson */ 60e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void SetGuid(void *dest, uint32_t num) 61e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 62e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Guid g = {{{num,0xd450,0x44bc,0xa6,0x93, 63e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0xb8,0xac,0x75,0x5f,0xcd,0x48}}}}; 64e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(dest, &g, sizeof(Guid)); 65aa8eda4f97f43a51bfec4fc096635565617a89e0Bill Richardson} 663dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 67e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 68e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Given a GptData pointer, first re-calculate entries CRC32 value, then reset 69e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * header CRC32 value to 0, and calculate header CRC32 value. Both primary and 70e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * secondary are updated. 71e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 72e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void RefreshCrc32(GptData *gpt) 73e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 74e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *header, *header2; 75e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *entries, *entries2; 76e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 77e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header = (GptHeader *)gpt->primary_header; 78e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries = (GptEntry *)gpt->primary_entries; 79e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2 = (GptHeader *)gpt->secondary_header; 80e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries2 = (GptEntry *)gpt->secondary_entries; 81e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 82e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->entries_crc32 = 83e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Crc32((uint8_t *)entries, 84e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->number_of_entries * header->size_of_entry); 85e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->header_crc32 = 0; 86e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->header_crc32 = Crc32((uint8_t *)header, header->size); 87e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->entries_crc32 = 88e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Crc32((uint8_t *)entries2, 89e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->number_of_entries * header2->size_of_entry); 90e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->header_crc32 = 0; 91e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->header_crc32 = Crc32((uint8_t *)header2, header2->size); 9249fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 9349fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 94e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void ZeroHeaders(GptData *gpt) 95e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 96e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(gpt->primary_header, 0, MAX_SECTOR_SIZE); 97e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(gpt->secondary_header, 0, MAX_SECTOR_SIZE); 9849fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 9949fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 100e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void ZeroEntries(GptData *gpt) 101e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 102e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(gpt->primary_entries, 0, PARTITION_ENTRIES_SIZE); 103e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(gpt->secondary_entries, 0, PARTITION_ENTRIES_SIZE); 10449fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 10549fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 106e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void ZeroHeadersEntries(GptData *gpt) 107e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 108e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ZeroHeaders(gpt); 109e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ZeroEntries(gpt); 11037f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo} 11137f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 112e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 113e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Return a pointer to a static GptData instance (no free is required). 11437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo * All fields are zero except 4 pointers linking to header and entries. 115e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * All content of headers and entries are zero. 116e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 117e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic GptData *GetEmptyGptData(void) 118e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 119e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler static GptData gpt; 120e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler static uint8_t primary_header[MAX_SECTOR_SIZE]; 121e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler static uint8_t primary_entries[PARTITION_ENTRIES_SIZE]; 122e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler static uint8_t secondary_header[MAX_SECTOR_SIZE]; 123e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler static uint8_t secondary_entries[PARTITION_ENTRIES_SIZE]; 124e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 125e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(&gpt, 0, sizeof(gpt)); 126e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt.primary_header = primary_header; 127e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt.primary_entries = primary_entries; 128e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt.secondary_header = secondary_header; 129e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt.secondary_entries = secondary_entries; 130e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ZeroHeadersEntries(&gpt); 131e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 132e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Initialize GptData internal states. */ 133e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt.current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; 134e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 135e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return &gpt; 13637f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo} 13737f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 138e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 139e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Fill in most of fields and creates the layout described in the top of this 14049fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo * file. Before calling this function, primary/secondary header/entries must 14149fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo * have been pointed to the buffer, say, a gpt returned from GetEmptyGptData(). 14249fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo * This function returns a good (valid) copy of GPT layout described in top of 143e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * this file. 144e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 145e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void BuildTestGptData(GptData *gpt) 146e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 147e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *header, *header2; 148e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *entries, *entries2; 149e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; 150e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Guid chromeos_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; 151e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 152e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->sector_bytes = DEFAULT_SECTOR_SIZE; 153b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->streaming_drive_sectors = 154b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors = DEFAULT_DRIVE_SECTORS; 155e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; 156e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->valid_headers = MASK_BOTH; 157e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->valid_entries = MASK_BOTH; 158e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->modified = 0; 159e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 160e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Build primary */ 161e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header = (GptHeader *)gpt->primary_header; 162e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries = (GptEntry *)gpt->primary_entries; 163e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(header->signature, GPT_HEADER_SIGNATURE, 164e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler sizeof(GPT_HEADER_SIGNATURE)); 165e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->revision = GPT_HEADER_REVISION; 166e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->size = sizeof(GptHeader); 167e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->reserved_zero = 0; 168e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->my_lba = 1; 169e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->alternate_lba = DEFAULT_DRIVE_SECTORS - 1; 170e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->first_usable_lba = 34; 171e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ 172e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->entries_lba = 2; 173e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* 512B / 128B * 32sectors = 128 entries */ 174e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->number_of_entries = 128; 175e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header->size_of_entry = 128; /* bytes */ 176e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); 177e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&entries[0].unique, 0); 178e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[0].starting_lba = 34; 179e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[0].ending_lba = 133; 180e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); 181e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&entries[1].unique, 1); 182e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[1].starting_lba = 134; 183e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[1].ending_lba = 232; 184e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); 185e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&entries[2].unique, 2); 186e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[2].starting_lba = 234; 187e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[2].ending_lba = 331; 188e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); 189e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&entries[3].unique, 3); 190e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[3].starting_lba = 334; 191e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries[3].ending_lba = 430; 192e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 193e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Build secondary */ 194e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2 = (GptHeader *)gpt->secondary_header; 195e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler entries2 = (GptEntry *)gpt->secondary_entries; 196e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(header2, header, sizeof(GptHeader)); 197e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE); 198e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ 199e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->alternate_lba = 1; 200e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler header2->entries_lba = DEFAULT_DRIVE_SECTORS - 1 - 32; /* 434 */ 201e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 202e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 20337f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo} 20437f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 205e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 206e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Test if the structures are the expected size; if this fails, struct packing 207e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * is not working properly. 208e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 209e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int StructSizeTest(void) 210e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 21181d0996901387619cc782ca258fcb4a9f3f591e7Randall Spangler 212e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GUID_EXPECTED_SIZE == sizeof(Guid)); 213e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPTHEADER_EXPECTED_SIZE == sizeof(GptHeader)); 214e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPTENTRY_EXPECTED_SIZE == sizeof(GptEntry)); 215e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 21681d0996901387619cc782ca258fcb4a9f3f591e7Randall Spangler} 21781d0996901387619cc782ca258fcb4a9f3f591e7Randall Spangler 21881d0996901387619cc782ca258fcb4a9f3f591e7Randall Spangler 219e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if the default structure returned by BuildTestGptData() is good. */ 220e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int TestBuildTestGptData(void) 221e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 222e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt; 2233dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 224e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt = GetEmptyGptData(); 225e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 226e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptInit(gpt)); 2270bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->sector_bytes = 0; 2280bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GPT_ERROR_INVALID_SECTOR_SIZE == GptInit(gpt)); 229e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 23049fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 23149fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 232e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 233e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Test if wrong sector_bytes or drive_sectors is detected by GptInit(). 234e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Currently we only support 512 bytes per sector. In the future, we may 235e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * support other sizes. A too small drive_sectors should be rejected by 236e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * GptInit(). 237e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 238e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int ParameterTests(void) 239e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 240e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt; 241e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 242e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t sector_bytes; 243e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t drive_sectors; 244e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int expected_retval; 245e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 246e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {512, DEFAULT_DRIVE_SECTORS, GPT_SUCCESS}, 247e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {520, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, 248e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {512, 0, GPT_ERROR_INVALID_SECTOR_NUMBER}, 249f3f7fca07fbcb6bb9655a71257f09c71b0a1458dDan Ehrenberg {512, 10, GPT_ERROR_INVALID_SECTOR_NUMBER}, 25088458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen {512, GPT_PMBR_SECTORS + GPT_HEADER_SECTORS * 2 + 2513200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen TOTAL_ENTRIES_SIZE / DEFAULT_SECTOR_SIZE * 2, GPT_SUCCESS}, 252e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, 253e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 254e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 255e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 256e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt = GetEmptyGptData(); 257e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 258e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 259e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->sector_bytes = cases[i].sector_bytes; 260b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->streaming_drive_sectors = 261b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors = cases[i].drive_sectors; 262e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(cases[i].expected_retval == CheckParameters(gpt)); 263e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 264e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 265e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 26649fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 26749fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 268e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if header CRC in two copies are calculated. */ 269e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int HeaderCrcTest(void) 270e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 271e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 272e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 2733dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 274e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 275e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(HeaderCrc(h1) == h1->header_crc32); 2763dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 277e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* CRC covers first byte of header */ 278e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 279e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[0] ^= 0xa5; 280e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(HeaderCrc(h1) != h1->header_crc32); 2813dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 282e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* CRC covers last byte of header */ 283e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 284e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[h1->size - 1] ^= 0x5a; 285e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(HeaderCrc(h1) != h1->header_crc32); 2863dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 287e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* CRC only covers header */ 288e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 289e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[h1->size] ^= 0x5a; 290e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(HeaderCrc(h1) == h1->header_crc32); 2913dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 292e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 2933dcf9dce04301d6d735f265652625fffb6758430Randall Spangler} 2943dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 2950bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler/* Test if header-same comparison works. */ 2960bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spanglerstatic int HeaderSameTest(void) 2970bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler{ 2980bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptData *gpt = GetEmptyGptData(); 2990bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 3000bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 3010bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptHeader h3; 3020bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3030bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(0 == HeaderFieldsSame(h1, h2)); 3040bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3050bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3060bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.signature[0] ^= 0xba; 3070bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3080bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3090bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3100bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.revision++; 3110bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3120bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3130bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3140bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.size++; 3150bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3160bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3170bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3180bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.reserved_zero++; 3190bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3200bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3210bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3220bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.first_usable_lba++; 3230bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3240bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3250bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3260bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.last_usable_lba++; 3270bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3280bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3290bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3300bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.disk_uuid.u.raw[0] ^= 0xba; 3310bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3320bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3330bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3340bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.number_of_entries++; 3350bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3360bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3370bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3380bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.size_of_entry++; 3390bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3400bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3410bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&h3, h2, sizeof(h3)); 3420bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler h3.entries_crc32++; 3430bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(1 == HeaderFieldsSame(h1, &h3)); 3440bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 3450bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler return TEST_OK; 3460bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler} 3470bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 348e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if signature ("EFI PART") is checked. */ 349e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int SignatureTest(void) 350e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 351e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 352e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 353e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 354e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 355e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 356b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(NULL, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 3570bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 358e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < 8; ++i) { 359e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 360e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->signature[i] ^= 0xff; 361e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->signature[i] ^= 0xff; 362e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 363b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 364b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 365e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 366e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 367e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 36849fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 36949fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 370e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 371e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * The revision we currently support is GPT_HEADER_REVISION. If the revision 372e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * in header is not that, we expect the header is invalid. 373e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 374e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int RevisionTest(void) 375e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 376e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 377e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 378e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 379e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 380e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 381e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 382e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t value_to_test; 383e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int expect_rv; 384e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 385e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0x01000000, 1}, 386e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0x00010000, 0}, /* GPT_HEADER_REVISION */ 387e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0x00000100, 1}, 388e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0x00000001, 1}, 389e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {0x23010456, 1}, 390e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 391e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 392e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 393e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 394e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->revision = cases[i].value_to_test; 395e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->revision = cases[i].value_to_test; 396e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 397e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 398b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 399e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 400b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 401e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 402e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 403e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 40449fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 40549fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 406e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int SizeTest(void) 407e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 408e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 409e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 410e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 411e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 412e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 413e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 414e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t value_to_test; 415e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int expect_rv; 416e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 417e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {91, 1}, 418e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {92, 0}, 419e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {93, 0}, 420e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {511, 0}, 421e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {512, 0}, 422e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {513, 1}, 423e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 424e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 425e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 426e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 427e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->size = cases[i].value_to_test; 428e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->size = cases[i].value_to_test; 429e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 430e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 431b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 432e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 433b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 434e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 435e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 436e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 43749fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 43849fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 439e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if CRC is checked. */ 440e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int CrcFieldTest(void) 441e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 442e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 443e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 444e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 445e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 446e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 447e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Modify a field that the header verification doesn't care about */ 448e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->entries_crc32++; 449e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->entries_crc32++; 450b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 451b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 452e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Refresh the CRC; should pass now */ 453e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 454b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 455b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 456e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 457e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 4583dcf9dce04301d6d735f265652625fffb6758430Randall Spangler} 4593dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 460e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if reserved fields are checked. We'll try non-zero values to test. */ 461e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int ReservedFieldsTest(void) 462e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 463e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 464e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 465e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 4663dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 467e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 468e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->reserved_zero ^= 0x12345678; /* whatever random */ 469e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->reserved_zero ^= 0x12345678; /* whatever random */ 470e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 471b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 472b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 47337f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 4743dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#ifdef PADDING_CHECKED 475e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* TODO: padding check is currently disabled */ 476e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 477e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->padding[12] ^= 0x34; /* whatever random */ 478e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->padding[56] ^= 0x78; /* whatever random */ 479e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 480b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 481b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 4823dcf9dce04301d6d735f265652625fffb6758430Randall Spangler#endif 48337f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 484e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 48537f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo} 48637f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo 487e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 488e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Technically, any size which is 2^N where N > 6 should work, but our 489e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * library only supports one size. 490e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 491e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int SizeOfPartitionEntryTest(void) { 492e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 493e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 494e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 495e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 496e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 497e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 498e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t value_to_test; 499e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int expect_rv; 500e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 501e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {127, 1}, 502e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {128, 0}, 503e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {129, 1}, 504e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {256, 1}, 505e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {512, 1}, 506e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 507e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 508e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Check size of entryes */ 509e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 510e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 511e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->size_of_entry = cases[i].value_to_test; 512e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->size_of_entry = cases[i].value_to_test; 513e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->number_of_entries = TOTAL_ENTRIES_SIZE / 514e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].value_to_test; 515e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->number_of_entries = TOTAL_ENTRIES_SIZE / 516e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].value_to_test; 517e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 518e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 519b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 520e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 521b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 522e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].expect_rv); 523e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 524e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 525e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 5264bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 5274bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 528e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 529e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Technically, any size which is 2^N where N > 6 should work, but our library 530e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * only supports one size. 531e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 532e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int NumberOfPartitionEntriesTest(void) 533e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 534e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 535e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 536e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 537e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 538e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 539e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->number_of_entries--; 540e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->number_of_entries /= 2; 5413200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen /* Because we halved h2 entries, its entries_lba is going to change. */ 5423200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen h2->entries_lba = h2->my_lba - CalculateEntriesSectors(h2); 543e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 544b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 545b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 5466ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen /* But it's okay to have less if the GPT structs are stored elsewhere. */ 547b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 548b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 549e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 550e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 5514bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 5524bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 55349fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 554e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if myLBA field is checked (1 for primary, last for secondary). */ 555e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int MyLbaTest(void) 556e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 557e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 558e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 559e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 560e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 561e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* myLBA depends on primary vs secondary flag */ 562e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 563b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 564b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 565e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 566e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 567e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->my_lba--; 568e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->my_lba--; 569e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 570b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 571b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 572e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 573e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 574e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->my_lba = 2; 575e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->my_lba--; 576e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 577b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 578b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 579e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 580e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* We should ignore the alternate_lba field entirely */ 581e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 582e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->alternate_lba++; 583e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->alternate_lba++; 584e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 585b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 586b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 587e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 588e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 589e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->alternate_lba--; 590e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->alternate_lba--; 591e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 592b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 593b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 594e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 595e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 596e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->entries_lba++; 597e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->entries_lba++; 598e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 599a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen /* 600a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen * We support a padding between primary GPT header and its entries. So 601a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen * this still passes. 602a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen */ 603b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 604a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen /* 605a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen * But the secondary table should fail because it would overlap the 606a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen * header, which is now lying after its entry array. 607a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen */ 608b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 609e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 610e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 611e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->entries_lba--; 612e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->entries_lba--; 613e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 614b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 615b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); 616e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 617e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 6184bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 6194bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 620e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if FirstUsableLBA and LastUsableLBA are checked. 6214bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * FirstUsableLBA must be after the end of the primary GPT table array. 6224bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * LastUsableLBA must be before the start of the secondary GPT table array. 6236ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen * FirstUsableLBA <= LastUsableLBA. 6246ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen * Also see CheckHeaderOffDevice() test. */ 625e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int FirstUsableLbaAndLastUsableLbaTest(void) 626e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 627e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 628e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 629e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h2 = (GptHeader *)gpt->secondary_header; 630e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 631e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 632e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 633e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t primary_entries_lba; 634e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t primary_first_usable_lba; 635e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t primary_last_usable_lba; 636e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t secondary_first_usable_lba; 637e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t secondary_last_usable_lba; 638e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t secondary_entries_lba; 639e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int primary_rv; 640e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int secondary_rv; 641e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 642e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 34, 433, 34, 433, 434, 0, 0}, 643e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 34, 432, 34, 430, 434, 0, 0}, 644e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 33, 433, 33, 433, 434, 1, 1}, 645e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 34, 434, 34, 433, 434, 1, 0}, 646e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 34, 433, 34, 434, 434, 0, 1}, 647e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 35, 433, 35, 433, 434, 0, 0}, 648e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 433, 433, 433, 433, 434, 0, 0}, 649e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 434, 433, 434, 434, 434, 1, 1}, 650e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 433, 34, 34, 433, 434, 1, 0}, 651e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {2, 34, 433, 433, 34, 434, 0, 1}, 652e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 653e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 654e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 655e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 656e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->entries_lba = cases[i].primary_entries_lba; 657e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->first_usable_lba = cases[i].primary_first_usable_lba; 658e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->last_usable_lba = cases[i].primary_last_usable_lba; 659e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->entries_lba = cases[i].secondary_entries_lba; 660e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->first_usable_lba = cases[i].secondary_first_usable_lba; 661e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h2->last_usable_lba = cases[i].secondary_last_usable_lba; 662e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 663e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 664b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 665e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].primary_rv); 666b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0) == 667e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler cases[i].secondary_rv); 668e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 669e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 670e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 6714bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 6724bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 673e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 674e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Test if PartitionEntryArrayCRC32 is checked. PartitionEntryArrayCRC32 must 675e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * be calculated over SizeOfPartitionEntry * NumberOfPartitionEntries bytes. 6764bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo */ 677e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int EntriesCrcTest(void) 678e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 679e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 680e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 681e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 682e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e2 = (GptEntry *)(gpt->secondary_entries); 683e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 684e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Modify first byte of primary entries, and expect the CRC is wrong. */ 685e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 686e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == CheckEntries(e1, h1)); 687e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == CheckEntries(e2, h1)); 688e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_entries[0] ^= 0xa5; /* just XOR a non-zero value */ 689e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[TOTAL_ENTRIES_SIZE-1] ^= 0x5a; 690e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_CRC_CORRUPTED == CheckEntries(e1, h1)); 691e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_CRC_CORRUPTED == CheckEntries(e2, h1)); 692e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 693e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 69449fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo} 69549fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo 696e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 697e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Test if partition geometry is checked. 6984bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * All active (non-zero PartitionTypeGUID) partition entries should have: 6994bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * entry.StartingLBA >= header.FirstUsableLBA 7004bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * entry.EndingLBA <= header.LastUsableLBA 7014bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo * entry.StartingLBA <= entry.EndingLBA 7024bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo */ 703e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int ValidEntryTest(void) 704e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 705e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 706e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 707e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 708e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 709e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* error case: entry.StartingLBA < header.FirstUsableLBA */ 710e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 711e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e1[0].starting_lba = h1->first_usable_lba - 1; 712e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 713e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); 714e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 715e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* error case: entry.EndingLBA > header.LastUsableLBA */ 716e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 717e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e1[2].ending_lba = h1->last_usable_lba + 1; 718e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 719e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); 720e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 721e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* error case: entry.StartingLBA > entry.EndingLBA */ 722e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 723e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e1[3].starting_lba = e1[3].ending_lba + 1; 724e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 725e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); 726e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 727e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* case: non active entry should be ignored. */ 728e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 729e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(&e1[1].type, 0, sizeof(e1[1].type)); 730e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e1[1].starting_lba = e1[1].ending_lba + 1; 731e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 732e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == CheckEntries(e1, h1)); 733e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 734e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 7354bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 7364bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 737e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test if overlapped partition tables can be detected. */ 738e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int OverlappedPartitionTest(void) { 739e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 740e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h = (GptHeader *)gpt->primary_header; 741e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e = (GptEntry *)gpt->primary_entries; 742e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i, j; 743e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 744e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 745e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int overlapped; 746e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 747e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int active; 748e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t starting_lba; 749e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t ending_lba; 750e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } entries[16]; /* enough for testing. */ 751e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 752e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{0, 100, 199}}}, 753e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{1, 100, 199}}}, 754e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{1, 100, 150}, {1, 200, 250}, {1, 300, 350}}}, 755e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 756e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 299}, {1, 100, 199}, {1, 100, 100}}}, 757e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_END_LBA_OVERLAP, 758e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 299}, {1, 100, 199}, {1, 299, 299}}}, 759e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{1, 300, 399}, {1, 200, 299}, {1, 100, 199}}}, 760e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_END_LBA_OVERLAP, 761e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 100, 199}, {1, 199, 299}, {1, 299, 399}}}, 762e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 763e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 100, 199}, {1, 200, 299}, {1, 75, 399}}}, 764e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 765e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 100, 199}, {1, 75, 250}, {1, 200, 299}}}, 766e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_END_LBA_OVERLAP, 767e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 75, 150}, {1, 100, 199}, {1, 200, 299}}}, 768e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 769e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 299}, {1, 100, 199}, {1, 300, 399}, {1, 100, 399}}}, 770e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, 771e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 299}, {1, 100, 199}, {1, 300, 399}, {0, 100, 399}}}, 772e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 773e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 300}, {1, 100, 200}, {1, 100, 400}, {1, 300, 400}}}, 774e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 775e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{0, 200, 300}, {1, 100, 200}, {1, 100, 400}, {1, 300, 400}}}, 776e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, 777e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 300}, {1, 100, 199}, {0, 100, 400}, {0, 300, 400}}}, 778e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_END_LBA_OVERLAP, 779e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 200, 299}, {1, 100, 199}, {1, 199, 199}}}, 780e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{1, 200, 299}, {0, 100, 199}, {1, 199, 199}}}, 781e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{1, 200, 299}, {1, 100, 199}, {0, 199, 199}}}, 782e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_START_LBA_OVERLAP, 783e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 199, 199}, {1, 200, 200}, {1, 201, 201}, {1, 202, 202}, 784e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {1, 203, 203}, {1, 204, 204}, {1, 205, 205}, {1, 206, 206}, 785e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {1, 207, 207}, {1, 208, 208}, {1, 199, 199}}}, 786e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, 787e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {{1, 199, 199}, {1, 200, 200}, {1, 201, 201}, {1, 202, 202}, 788e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {1, 203, 203}, {1, 204, 204}, {1, 205, 205}, {1, 206, 206}, 789e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {1, 207, 207}, {1, 208, 208}, {0, 199, 199}}}, 790e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 791e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 792e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 793e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 794e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ZeroEntries(gpt); 795e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { 796e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler if (!cases[i].entries[j].starting_lba) 797e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler break; 798e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 7995c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk if (cases[i].entries[j].active) { 800e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); 8015c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk } 802e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&e[j].unique, j); 803e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e[j].starting_lba = cases[i].entries[j].starting_lba; 804e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e[j].ending_lba = cases[i].entries[j].ending_lba; 805e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 806e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 807e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 808e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(cases[i].overlapped == CheckEntries(e, h)); 809e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 810e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 8114bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 8124bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo 8133dcf9dce04301d6d735f265652625fffb6758430Randall Spangler/* Test both sanity checking and repair. */ 814e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int SanityCheckTest(void) 815e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 816e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 817e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h1 = (GptHeader *)gpt->primary_header; 8180bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptEntry *e1 = (GptEntry *)gpt->primary_entries; 8190bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler uint8_t *tempptr; 820e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 821e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Unmodified test data is completely sane */ 822e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 823e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 824e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 825e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 826e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Repair doesn't damage it */ 827e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 828e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 829e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 830e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 831e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->modified); 832e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 8330bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler /* Invalid sector size should fail */ 8340bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler BuildTestGptData(gpt); 8350bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->sector_bytes = 1024; 8360bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GPT_ERROR_INVALID_SECTOR_SIZE == GptSanityCheck(gpt)); 8370bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 838e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Modify headers */ 839e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 840e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[0]++; 841e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_header[0]++; 842e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_INVALID_HEADERS == GptSanityCheck(gpt)); 843e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->valid_headers); 844e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->valid_entries); 845e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Repair can't fix completely busted headers */ 846e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 847e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_INVALID_HEADERS == GptSanityCheck(gpt)); 848e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->valid_headers); 849e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->valid_entries); 850e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->modified); 851e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 852e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 853e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[0]++; 854e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 855e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_headers); 856e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 857e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 858e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 859e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 860e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 861e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_MODIFIED_HEADER1 == gpt->modified); 862e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 863e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 864e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_header[0]++; 865e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 866e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_headers); 867e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 868e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 869e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 870e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 871e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 872e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_MODIFIED_HEADER2 == gpt->modified); 873e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 874e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* 875e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Modify header1 and update its CRC. Since header2 is now different 876e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * than header1, it'll be the one considered invalid. 877e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 878e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 879e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler h1->size++; 880e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 881e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 882e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_headers); 883e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 884e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 885e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 886e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 887e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 888e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_MODIFIED_HEADER2 == gpt->modified); 889e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 890e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Modify entries */ 891e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 892e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_entries[0]++; 893e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[0]++; 894e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_INVALID_ENTRIES == GptSanityCheck(gpt)); 895e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 896e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_NONE == gpt->valid_entries); 897e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Repair can't fix both copies of entries being bad, either. */ 898e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 899e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_INVALID_ENTRIES == GptSanityCheck(gpt)); 900e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 901e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_NONE == gpt->valid_entries); 902e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->modified); 903e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 904e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 905e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_entries[0]++; 906e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 907e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 908e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_entries); 909e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 910e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 911e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 912e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 913e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_MODIFIED_ENTRIES1 == gpt->modified); 914e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 915e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 916e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[0]++; 917e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 918e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 919e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_entries); 920e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 921e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 922e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 923e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 924e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); 925e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 9260bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler /* 9270bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler * Modify entries and recompute CRCs, then make both primary and 9280bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler * secondary entry pointers use the secondary data. The primary 9290bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler * header will have the wrong entries CRC, so we should fall back 9300bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler * to the secondary header. 9310bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler */ 9320bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler BuildTestGptData(gpt); 9330bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler e1->starting_lba++; 9340bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler RefreshCrc32(gpt); 9350bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler tempptr = gpt->primary_entries; 9360bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->primary_entries = gpt->secondary_entries; 9370bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 9380bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_headers); 9390bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 9400bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->primary_entries = tempptr; 9410bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 942e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Modify both header and entries */ 943e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 944e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[0]++; 945e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_entries[0]++; 946e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 947e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_headers); 948e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_entries); 949e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 950e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 951e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 952e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 953e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified); 954e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 955e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 956e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_header[0]++; 957e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[0]++; 958e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 959e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_headers); 960e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_entries); 961e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 962e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 963e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 964e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 965e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified); 966e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 967e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Test cross-correction (h1+e2, h2+e1) */ 968e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 969e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_header[0]++; 970e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[0]++; 971e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 972e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_headers); 973e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_entries); 974e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 975e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 976e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 977e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 978e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES2) == gpt->modified); 979e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 980e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 981e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_header[0]++; 982e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->primary_entries[0]++; 983e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 984e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_headers); 985e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_SECONDARY == gpt->valid_entries); 986e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 987e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 988e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 989e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 990e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES1) == gpt->modified); 991e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 992e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* 993e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Test mismatched pairs (h1+e1 valid, h2+e2 valid but different. This 994e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * simulates a partial update of the drive. 995e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 996e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 997e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->secondary_entries[0]++; 998e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 999e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 1000e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_headers); 1001e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_PRIMARY == gpt->valid_entries); 1002e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptRepair(gpt); 1003e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 1004e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_headers); 1005e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(MASK_BOTH == gpt->valid_entries); 1006e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified); 1007e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 10085ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen /* Test unloaded entry array. */ 10095ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt = GetEmptyGptData(); 10105ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen BuildTestGptData(gpt); 10115ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt->primary_entries = NULL; 10125ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 10135ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(MASK_SECONDARY == gpt->valid_entries); 10145ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt = GetEmptyGptData(); 10155ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen BuildTestGptData(gpt); 10165ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt->secondary_entries = NULL; 10175ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 10185ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(MASK_PRIMARY == gpt->valid_entries); 10195ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen 10205ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen /* Test unloaded header. */ 10215ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt = GetEmptyGptData(); 10225ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen BuildTestGptData(gpt); 10235ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt->primary_header = NULL; 10245ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 10255ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(MASK_SECONDARY == gpt->valid_headers); 10265ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt = GetEmptyGptData(); 10275ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen BuildTestGptData(gpt); 10285ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen gpt->secondary_header = NULL; 10295ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); 10305ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen EXPECT(MASK_PRIMARY == gpt->valid_headers); 10315ce8325f4ac4662d0daef63878c85462a8e59ff4Nam T. Nguyen 1032e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1033b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1034b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1035e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int EntryAttributeGetSetTest(void) 1036e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1037e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1038e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e = (GptEntry *)(gpt->primary_entries); 1039e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1040e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0x0000000000000000ULL; 1041e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntrySuccessful(e, 1); 1042e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0x0100000000000000ULL == e->attrs.whole); 1043e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e)); 1044e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; 1045e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntrySuccessful(e, 0); 1046e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0xFEFFFFFFFFFFFFFFULL == e->attrs.whole); 1047e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e)); 1048e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1049e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0x0000000000000000ULL; 1050e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryTries(e, 15); 1051e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(15 == GetEntryTries(e)); 1052e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0x00F0000000000000ULL == e->attrs.whole); 1053e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; 1054e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryTries(e, 0); 1055e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0xFF0FFFFFFFFFFFFFULL == e->attrs.whole); 1056e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e)); 1057e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1058e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0x0000000000000000ULL; 1059e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryPriority(e, 15); 1060e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0x000F000000000000ULL == e->attrs.whole); 1061e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(15 == GetEntryPriority(e)); 1062e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; 1063e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryPriority(e, 0); 1064e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole); 1065e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryPriority(e)); 1066e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1067e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; 1068e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e)); 1069e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(15 == GetEntryPriority(e)); 1070e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(15 == GetEntryTries(e)); 1071e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1072e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e->attrs.whole = 0x0123000000000000ULL; 1073e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e)); 1074e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryTries(e)); 1075e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(3 == GetEntryPriority(e)); 1076e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1077e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1078b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1079b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1080e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int EntryTypeTest(void) 1081e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1082e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1083e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e = (GptEntry *)(gpt->primary_entries); 10843dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 1085e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&e->type, &guid_zero, sizeof(Guid)); 1086e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == IsUnusedEntry(e)); 1087e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == IsKernelEntry(e)); 10883dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 1089e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&e->type, &guid_kernel, sizeof(Guid)); 1090e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == IsUnusedEntry(e)); 1091e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == IsKernelEntry(e)); 10923dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 1093e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&e->type, &guid_rootfs, sizeof(Guid)); 1094e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == IsUnusedEntry(e)); 1095e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == IsKernelEntry(e)); 10963dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 1097e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1098b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1099b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 11003dcf9dce04301d6d735f265652625fffb6758430Randall Spangler/* Make an entry unused by clearing its type. */ 1101e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void FreeEntry(GptEntry *e) 1102e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1103e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memset(&e->type, 0, sizeof(Guid)); 11043dcf9dce04301d6d735f265652625fffb6758430Randall Spangler} 11053dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 11063dcf9dce04301d6d735f265652625fffb6758430Randall Spangler/* Set up an entry. */ 1107e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic void FillEntry(GptEntry *e, int is_kernel, 1108e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int priority, int successful, int tries) 1109e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1110e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler Memcpy(&e->type, (is_kernel ? &guid_kernel : &guid_zero), sizeof(Guid)); 1111e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryPriority(e, priority); 1112e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntrySuccessful(e, successful); 1113e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryTries(e, tries); 11143dcf9dce04301d6d735f265652625fffb6758430Randall Spangler} 11153dcf9dce04301d6d735f265652625fffb6758430Randall Spangler 1116e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 1117e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Invalidate all kernel entries and expect GptNextKernelEntry() cannot find 11183dcf9dce04301d6d735f265652625fffb6758430Randall Spangler * any usable kernel entry. 1119b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo */ 1120e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int NoValidKernelEntryTest(void) 1121e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1122e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1123e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 1124e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1125e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1126e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetEntryPriority(e1 + KERNEL_A, 0); 1127e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FreeEntry(e1 + KERNEL_B); 1128e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1129e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_NO_VALID_KERNEL == 1130e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptNextKernelEntry(gpt, NULL, NULL)); 1131e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1132e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1133b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1134b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1135e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int GetNextNormalTest(void) 1136e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1137e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1138e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 1139e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t start, size; 1140e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1141e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Normal case - both kernels successful */ 1142e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1143e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_A, 1, 2, 1, 0); 1144e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_B, 1, 2, 1, 0); 1145e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1146e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptInit(gpt); 1147e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1148e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1149e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_A == gpt->current_kernel); 1150e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(34 == start); 1151e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(100 == size); 1152e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1153e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1154e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_B == gpt->current_kernel); 1155e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(134 == start); 1156e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(99 == size); 1157e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1158e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_NO_VALID_KERNEL == 1159e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptNextKernelEntry(gpt, &start, &size)); 1160e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(-1 == gpt->current_kernel); 1161e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1162e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Call as many times as you want; you won't get another kernel... */ 1163e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_NO_VALID_KERNEL == 1164e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptNextKernelEntry(gpt, &start, &size)); 1165e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(-1 == gpt->current_kernel); 1166e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1167e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1168b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1169b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1170e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int GetNextPrioTest(void) 1171e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1172e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1173e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 1174e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t start, size; 1175e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1176e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Priority 3, 4, 0, 4 - should boot order B, Y, A */ 1177e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1178e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_A, 1, 3, 1, 0); 1179e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_B, 1, 4, 1, 0); 1180e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_X, 1, 0, 1, 0); 1181e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_Y, 1, 4, 1, 0); 1182e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1183e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptInit(gpt); 1184e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1185e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1186e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_B == gpt->current_kernel); 1187e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1188e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_Y == gpt->current_kernel); 1189e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1190e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_A == gpt->current_kernel); 1191e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_NO_VALID_KERNEL == 1192e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptNextKernelEntry(gpt, &start, &size)); 1193e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1194e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1195b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1196b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1197e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int GetNextTriesTest(void) 1198e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1199e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1200e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e1 = (GptEntry *)(gpt->primary_entries); 1201e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t start, size; 1202e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1203e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Tries=nonzero is attempted just like success, but tries=0 isn't */ 1204e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1205e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_A, 1, 2, 1, 0); 1206e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_B, 1, 3, 0, 0); 1207e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_X, 1, 4, 0, 1); 1208e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e1 + KERNEL_Y, 1, 0, 0, 5); 1209e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1210e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptInit(gpt); 1211e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1212e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1213e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_X == gpt->current_kernel); 1214e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1215e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_A == gpt->current_kernel); 1216e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_NO_VALID_KERNEL == 1217e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptNextKernelEntry(gpt, &start, &size)); 1218e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1219e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1220b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1221b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1222e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int GptUpdateTest(void) 1223e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1224e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1225e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e = (GptEntry *)(gpt->primary_entries); 1226e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e2 = (GptEntry *)(gpt->secondary_entries); 1227e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t start, size; 1228e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1229e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Tries=nonzero is attempted just like success, but tries=0 isn't */ 1230e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1231e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e + KERNEL_A, 1, 4, 1, 0); 1232e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e + KERNEL_B, 1, 3, 0, 2); 1233e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler FillEntry(e + KERNEL_X, 1, 2, 0, 2); 1234e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1235e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptInit(gpt); 1236e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->modified = 0; /* Nothing modified yet */ 1237e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1238e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Successful kernel */ 1239e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1240e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_A == gpt->current_kernel); 1241e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e + KERNEL_A)); 1242e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(4 == GetEntryPriority(e + KERNEL_A)); 1243e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e + KERNEL_A)); 1244e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e2 + KERNEL_A)); 1245e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(4 == GetEntryPriority(e2 + KERNEL_A)); 1246e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e2 + KERNEL_A)); 1247e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Trying successful kernel changes nothing */ 1248e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_TRY)); 1249e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e + KERNEL_A)); 1250e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(4 == GetEntryPriority(e + KERNEL_A)); 1251e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e + KERNEL_A)); 1252e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->modified); 1253e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Marking it bad also does not update it. */ 1254e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_BAD)); 1255e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntrySuccessful(e + KERNEL_A)); 1256e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(4 == GetEntryPriority(e + KERNEL_A)); 1257e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e + KERNEL_A)); 1258e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == gpt->modified); 1259e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1260e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Kernel with tries */ 1261e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1262e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_B == gpt->current_kernel); 1263e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e + KERNEL_B)); 1264e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(3 == GetEntryPriority(e + KERNEL_B)); 1265e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryTries(e + KERNEL_B)); 1266e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Marking it bad clears it */ 1267e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_BAD)); 1268e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e + KERNEL_B)); 1269e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryPriority(e + KERNEL_B)); 1270e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e + KERNEL_B)); 1271e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Which affects both copies of the partition entries */ 1272e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e2 + KERNEL_B)); 1273e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryPriority(e2 + KERNEL_B)); 1274e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e2 + KERNEL_B)); 1275e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* And that's caused the GPT to need updating */ 1276e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0x0F == gpt->modified); 1277e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1278e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Another kernel with tries */ 1279e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size)); 1280e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(KERNEL_X == gpt->current_kernel); 1281e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e + KERNEL_X)); 1282e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryPriority(e + KERNEL_X)); 1283e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryTries(e + KERNEL_X)); 1284e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Trying it uses up a try */ 1285e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_TRY)); 1286e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e + KERNEL_X)); 1287e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryPriority(e + KERNEL_X)); 1288e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntryTries(e + KERNEL_X)); 1289e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e2 + KERNEL_X)); 1290e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(2 == GetEntryPriority(e2 + KERNEL_X)); 1291e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(1 == GetEntryTries(e2 + KERNEL_X)); 1292e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* Trying it again marks it inactive */ 1293e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_SUCCESS == GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_TRY)); 1294e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntrySuccessful(e + KERNEL_X)); 1295e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryPriority(e + KERNEL_X)); 1296e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(0 == GetEntryTries(e + KERNEL_X)); 1297e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 12980bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler /* Can't update if entry isn't a kernel, or there isn't an entry */ 12990bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Memcpy(&e[KERNEL_X].type, &guid_rootfs, sizeof(guid_rootfs)); 13000bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == 13010bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_BAD)); 13020bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; 13030bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == 13040bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptUpdateKernelEntry(gpt, GPT_UPDATE_ENTRY_BAD)); 13050bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 13060bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 1307e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 13083dcf9dce04301d6d735f265652625fffb6758430Randall Spangler} 1309b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1310e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* 1311e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * Give an invalid kernel type, and expect GptUpdateKernelEntry() returns 1312e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler * GPT_ERROR_INVALID_UPDATE_TYPE. 1313e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler */ 1314e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int UpdateInvalidKernelTypeTest(void) 1315e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1316e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1317e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1318e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1319e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ 1320e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler gpt->current_kernel = 0; 1321e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler /* any invalid update_type value */ 1322e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == 1323e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptUpdateKernelEntry(gpt, 99)); 1324e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1325e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1326b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo} 1327b17db3c4b9e7051e51af72bfd404d3d243b44f5cLouis Yung-Chieh Lo 1328e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler/* Test duplicate UniqueGuids can be detected. */ 1329e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerstatic int DuplicateUniqueGuidTest(void) 1330e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1331e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptData *gpt = GetEmptyGptData(); 1332e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptHeader *h = (GptHeader *)gpt->primary_header; 1333e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler GptEntry *e = (GptEntry *)gpt->primary_entries; 1334e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i, j; 1335e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1336e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 1337e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int duplicate; 1338e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 1339e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t starting_lba; 1340e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint64_t ending_lba; 1341e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t type_guid; 1342e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler uint32_t unique_guid; 1343e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } entries[16]; /* enough for testing. */ 1344e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } cases[] = { 1345e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{100, 109, 1, 1}, 1346e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {110, 119, 2, 2}, 1347e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {120, 129, 3, 3}, 1348e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {130, 139, 4, 4}, 1349e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }}, 1350e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_SUCCESS, {{100, 109, 1, 1}, 1351e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {110, 119, 1, 2}, 1352e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {120, 129, 2, 3}, 1353e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {130, 139, 2, 4}, 1354e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }}, 1355e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_DUP_GUID, {{100, 109, 1, 1}, 1356e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {110, 119, 2, 2}, 1357e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {120, 129, 3, 1}, 1358e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {130, 139, 4, 4}, 1359e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }}, 1360e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {GPT_ERROR_DUP_GUID, {{100, 109, 1, 1}, 1361e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {110, 119, 1, 2}, 1362e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {120, 129, 2, 3}, 1363e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler {130, 139, 2, 2}, 1364e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }}, 1365e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 1366e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1367e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < ARRAY_SIZE(cases); ++i) { 1368e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler BuildTestGptData(gpt); 1369e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ZeroEntries(gpt); 1370e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { 1371e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler if (!cases[i].entries[j].starting_lba) 1372e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler break; 1373e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1374e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e[j].starting_lba = cases[i].entries[j].starting_lba; 1375e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler e[j].ending_lba = cases[i].entries[j].ending_lba; 1376e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&e[j].type, cases[i].entries[j].type_guid); 1377e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler SetGuid(&e[j].unique, cases[i].entries[j].unique_guid); 1378e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1379e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler RefreshCrc32(gpt); 1380e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1381e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler EXPECT(cases[i].duplicate == CheckEntries(e, h)); 1382e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1383e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1384e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return TEST_OK; 1385aa8eda4f97f43a51bfec4fc096635565617a89e0Bill Richardson} 1386aa8eda4f97f43a51bfec4fc096635565617a89e0Bill Richardson 13870bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler/* Test getting the current kernel GUID */ 13880bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spanglerstatic int GetKernelGuidTest(void) 13890bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler{ 13900bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptData *gpt = GetEmptyGptData(); 13910bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GptEntry *e = (GptEntry *)gpt->primary_entries; 13920bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler Guid g; 13930bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 13940bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler BuildTestGptData(gpt); 13950bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->current_kernel = 0; 13960bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GetCurrentKernelUniqueGuid(gpt, &g); 13970bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(!Memcmp(&g, &e[0].unique, sizeof(Guid))); 13980bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler gpt->current_kernel = 1; 13990bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler GetCurrentKernelUniqueGuid(gpt, &g); 14000bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(!Memcmp(&g, &e[1].unique, sizeof(Guid))); 14010bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14020bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler return TEST_OK; 14030bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler} 14040bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14050bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler/* Test getting GPT error text strings */ 14060bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spanglerstatic int ErrorTextTest(void) 14070bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler{ 14080bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler int i; 14090bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14100bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler /* Known errors are not unknown */ 14110bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler for (i = 0; i < GPT_ERROR_COUNT; i++) { 14120bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(GptErrorText(i)); 14130bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(strcmp(GptErrorText(i), "Unknown")); 14140bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler } 14150bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14160bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler /* But other error values are */ 14170bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler EXPECT(!strcmp(GptErrorText(GPT_ERROR_COUNT), "Unknown")); 14180bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14190bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler return TEST_OK; 14200bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler} 14210bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler 14226ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyenstatic int CheckHeaderOffDevice() 14236ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen{ 14246ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen GptData* gpt = GetEmptyGptData(); 14256ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen BuildTestGptData(gpt); 14266ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14276ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen GptHeader* primary_header = (GptHeader*)gpt->primary_header; 14286ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen primary_header->first_usable_lba = 0; 14296ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 14306ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // GPT is stored on the same device so first usable lba should not 14316ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // start at 0. 1432b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(primary_header, 0, gpt->streaming_drive_sectors, 1433b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, 0)); 14346ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // But off device, it is okay to accept this GPT header. 1435b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(primary_header, 0, gpt->streaming_drive_sectors, 1436b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14376ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14386ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen BuildTestGptData(gpt); 14396ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen primary_header->number_of_entries = 100; 14406ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 14416ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // Normally, number of entries is 128. So this should fail. 1442b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(primary_header, 0, gpt->streaming_drive_sectors, 1443b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, 0)); 14446ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // But off device, it is okay. 1445b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(primary_header, 0, gpt->streaming_drive_sectors, 1446b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14476ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14486ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen primary_header->number_of_entries = MIN_NUMBER_OF_ENTRIES - 1; 14496ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 14506ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // However, too few entries is not good. 1451b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(primary_header, 0, gpt->streaming_drive_sectors, 1452b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14536ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14546ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen // Repeat for secondary header. 14556ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen BuildTestGptData(gpt); 14566ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen GptHeader* secondary_header = (GptHeader*)gpt->secondary_header; 14576ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen secondary_header->first_usable_lba = 0; 14586ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 1459b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, 1460b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, 0)); 1461b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, 1462b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14636ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14646ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen BuildTestGptData(gpt); 14656ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen secondary_header->number_of_entries = 100; 14663200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen /* Because we change number of entries, we need to also update entrie_lba. */ 14673200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen secondary_header->entries_lba = secondary_header->my_lba - 14683200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen CalculateEntriesSectors(secondary_header); 14696ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 1470b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, 1471b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, 0)); 1472b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(0 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, 1473b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14746ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14756ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen secondary_header->number_of_entries = MIN_NUMBER_OF_ENTRIES - 1; 14766ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen RefreshCrc32(gpt); 1477b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg EXPECT(1 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, 1478b3d38f5c620da89662deb1a08971c5025d6c1132Dan Ehrenberg gpt->gpt_drive_sectors, GPT_FLAG_EXTERNAL)); 14796ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 14806ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen return TEST_OK; 14816ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen} 14826ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen 1483e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spanglerint main(int argc, char *argv[]) 1484e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler{ 1485e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int i; 1486e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int error_count = 0; 1487e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler struct { 1488e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler char *name; 1489e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler test_func fp; 1490e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler int retval; 1491e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } test_cases[] = { 1492e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(StructSizeTest), }, 1493e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(TestBuildTestGptData), }, 1494e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(ParameterTests), }, 1495e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(HeaderCrcTest), }, 14960bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler { TEST_CASE(HeaderSameTest), }, 1497e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(SignatureTest), }, 1498e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(RevisionTest), }, 1499e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(SizeTest), }, 1500e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(CrcFieldTest), }, 1501e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(ReservedFieldsTest), }, 1502e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(SizeOfPartitionEntryTest), }, 1503e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(NumberOfPartitionEntriesTest), }, 1504e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(MyLbaTest), }, 1505e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(FirstUsableLbaAndLastUsableLbaTest), }, 1506e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(EntriesCrcTest), }, 1507e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(ValidEntryTest), }, 1508e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(OverlappedPartitionTest), }, 1509e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(SanityCheckTest), }, 1510e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(NoValidKernelEntryTest), }, 1511e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(EntryAttributeGetSetTest), }, 1512e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(EntryTypeTest), }, 1513e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(GetNextNormalTest), }, 1514e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(GetNextPrioTest), }, 1515e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(GetNextTriesTest), }, 1516e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(GptUpdateTest), }, 1517e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(UpdateInvalidKernelTypeTest), }, 1518e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(DuplicateUniqueGuidTest), }, 1519e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler { TEST_CASE(TestCrc32TestVectors), }, 15200bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler { TEST_CASE(GetKernelGuidTest), }, 15210bda13f5154afc8068e7d2d4563ff20b152f1c87Randall Spangler { TEST_CASE(ErrorTextTest), }, 15226ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen { TEST_CASE(CheckHeaderOffDevice), }, 1523e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler }; 1524e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1525e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { 1526e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf("Running %s() ...\n", test_cases[i].name); 1527e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler test_cases[i].retval = test_cases[i].fp(); 1528e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler if (test_cases[i].retval) { 1529e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf(COL_RED "[ERROR]\n\n" COL_STOP); 1530e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler ++error_count; 1531e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } else { 1532e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf(COL_GREEN "[PASS]\n\n" COL_STOP); 1533e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1534e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1535e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1536e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler if (error_count) { 1537e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf("\n------------------------------------------------\n"); 1538e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf(COL_RED "The following %d test cases are failed:\n" 1539e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler COL_STOP, error_count); 1540e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { 1541e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler if (test_cases[i].retval) 1542e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler printf(" %s()\n", test_cases[i].name); 1543e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1544e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler } 1545e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler 1546e9213a7c133681d6f565adbf218bafa7a3115c22Randall Spangler return error_count ? 1 : 0; 15474bbf21e47663914d355941ff61fcbf262b4085acLouis Yung-Chieh Lo} 1548