loader/gpt.c
EFI_STATUS ReadGptData(REFIT_VOLUME *Volume, GPT_DATA **Data) {
   EFI_STATUS Status = EFI_SUCCESS;
   UINT64     BufferSize;
   UINTN      i;
   GPT_DATA   *GptData = NULL; // Temporary holding storage; transferred to *Data later

   if ((Volume == NULL) || (Data == NULL))
      return EFI_INVALID_PARAMETER;

   // get block i/o
   if ((Status == EFI_SUCCESS) && (Volume->BlockIO == NULL)) {
      Status = refit_call3_wrapper(BS->HandleProtocol, Volume->DeviceHandle, &BlockIoProtocol, (VOID **) &(Volume->BlockIO));
      if (EFI_ERROR(Status)) {
         Volume->BlockIO = NULL;
         Print(L"Warning: Can't get BlockIO protocol in ReadGptData().\n");
         Status = EFI_NOT_READY;
      }
   } // if

   if ((Status == EFI_SUCCESS) && ((!Volume->BlockIO->Media->MediaPresent) || (Volume->BlockIO->Media->LogicalPartition)))
      Status = EFI_NO_MEDIA;

   if (Status == EFI_SUCCESS) {
      GptData = AllocateGptData(); // Note: All but GptData->Entries
      if (GptData == NULL) {
         Status = EFI_OUT_OF_RESOURCES;
      } // if
   } // if

   // Read the MBR and store it in GptData->ProtectiveMBR.
   if (Status == EFI_SUCCESS) {
      Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                   0, sizeof(MBR_RECORD), (VOID*) GptData->ProtectiveMBR);
   }

   // Read the GPT header and store it in GptData->Header.
   if (Status == EFI_SUCCESS) {
      Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                   1, sizeof(GPT_HEADER), GptData->Header);
   }

   // If it looks like a valid protective MBR & GPT header, try to do more with it....
   if (Status == EFI_SUCCESS) {
      if (GptHeaderValid(GptData)) {
         // Load actual GPT table....
         BufferSize = GptData->Header->entry_count * 128;
         GptData->Entries = AllocatePool(BufferSize);
         if (GptData->Entries == NULL)
            Status = EFI_OUT_OF_RESOURCES;

         if (Status == EFI_SUCCESS)
            Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                         GptData->Header->entry_lba, BufferSize, GptData->Entries);

         // Check CRC status of table
         if ((Status == EFI_SUCCESS) && (crc32(0x0, GptData->Entries, BufferSize) != GptData->Header->entry_crc32))
            Status = EFI_CRC_ERROR;

         // Now, ensure that every name is null-terminated....
         if (Status == EFI_SUCCESS) {
            for (i = 0; i < GptData->Header->entry_count; i++)
               GptData->Entries[i].name[35] = '\0';
         } // if
      } else {
         Status = EFI_UNSUPPORTED;
      } // if/else valid header
   } // if header read OK

   if (Status == EFI_SUCCESS) {
      // Everything looks OK, so copy it over
      ClearGptData(*Data);
      *Data = GptData;
   } else {
      ClearGptData(GptData);
   } // if/else

   return Status;
}
// Read GPT data from Volume and store it in *Data. Note that this function
// may be called on a Volume that is not in fact a GPT disk (an MBR disk,
// a partition, etc.), in which case it will return EFI_LOAD_ERROR or some
// other error condition. In this case, *Data will be left alone.
// Note also that this function checks CRCs and does other sanity checks
// on the input data, but does NOT resort to using the backup data if the
// primary data structures are damaged. The intent is that the function
// be very conservative about reading GPT data. Currently (version 0.7.10),
// Next Loader uses the data only to provide access to partition names. This is
// non-critical data, so it's OK to return nothing, but having the program
// hang on reading garbage or return nonsense could be very bad.
Read GPT data from Volume and store it in *Data. Note that this function
may be called on a Volume that is not in fact a GPT disk (an MBR disk,
a partition, etc.), in which case it will return EFI_LOAD_ERROR or some
other error condition. In this case, *Data will be left alone.
Note also that this function checks CRCs and does other sanity checks
on the input data, but does NOT resort to using the backup data if the
primary data structures are damaged. The intent is that the function
be very conservative about reading GPT data. Currently (version 0.7.10),
Next Loader uses the data only to provide access to partition names. This is
non-critical data, so it's OK to return nothing, but having the program
hang on reading garbage or return nonsense could be very bad.
Read GPT data from Volume and store it in * Data . Note that this function may be called on a Volume that is not in fact a GPT disk ( an MBR disk a partition etc . ) in which case it will return EFI_LOAD_ERROR or some other error condition . In this case * Data will be left alone . Note also that this function checks CRCs and does other sanity checks on the input data but does NOT resort to using the backup data if the primary data structures are damaged . The intent is that the function be very conservative about reading GPT data . Currently ( version 0 . 7 . 10 ) Next Loader uses the data only to provide access to partition names . This is non - critical data so it ' s OK to return nothing but having the program hang on reading garbage or return nonsense could be very bad .
EFI_STATUS ReadGptData(REFIT_VOLUME *Volume, GPT_DATA **Data) {
   EFI_STATUS Status = EFI_SUCCESS;
   UINT64     BufferSize;
   UINTN      i;
   GPT_DATA   *GptData = NULL; 
   if ((Volume == NULL) || (Data == NULL))
      return EFI_INVALID_PARAMETER;
   if ((Status == EFI_SUCCESS) && (Volume->BlockIO == NULL)) {
      Status = refit_call3_wrapper(BS->HandleProtocol, Volume->DeviceHandle, &BlockIoProtocol, (VOID **) &(Volume->BlockIO));
      if (EFI_ERROR(Status)) {
         Volume->BlockIO = NULL;
         Print(L"Warning: Can't get BlockIO protocol in ReadGptData().\n");
         Status = EFI_NOT_READY;
      }
   } 
   if ((Status == EFI_SUCCESS) && ((!Volume->BlockIO->Media->MediaPresent) || (Volume->BlockIO->Media->LogicalPartition)))
      Status = EFI_NO_MEDIA;
   if (Status == EFI_SUCCESS) {
      GptData = AllocateGptData(); 
      if (GptData == NULL) {
         Status = EFI_OUT_OF_RESOURCES;
      } 
   } 
   if (Status == EFI_SUCCESS) {
      Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                   0, sizeof(MBR_RECORD), (VOID*) GptData->ProtectiveMBR);
   }
   if (Status == EFI_SUCCESS) {
      Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                   1, sizeof(GPT_HEADER), GptData->Header);
   }
   if (Status == EFI_SUCCESS) {
      if (GptHeaderValid(GptData)) {
         BufferSize = GptData->Header->entry_count * 128;
         GptData->Entries = AllocatePool(BufferSize);
         if (GptData->Entries == NULL)
            Status = EFI_OUT_OF_RESOURCES;
         if (Status == EFI_SUCCESS)
            Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks, Volume->BlockIO, Volume->BlockIO->Media->MediaId,
                                         GptData->Header->entry_lba, BufferSize, GptData->Entries);
         if ((Status == EFI_SUCCESS) && (crc32(0x0, GptData->Entries, BufferSize) != GptData->Header->entry_crc32))
            Status = EFI_CRC_ERROR;
         if (Status == EFI_SUCCESS) {
            for (i = 0; i < GptData->Header->entry_count; i++)
               GptData->Entries[i].name[35] = '\0';
         } 
      } else {
         Status = EFI_UNSUPPORTED;
      } /else valid header
   }  header read OK
   if (Status == EFI_SUCCESS) {
      ClearGptData(*Data);
      *Data = GptData;
   } else {
      ClearGptData(GptData);
   } /else
   return Status;
}
EFI_STATUS ReadGptData ( REFIT_VOLUME * Volume , GPT_DATA * * Data ) { EFI_STATUS Status = EFI_SUCCESS ; UINT64 BufferSize ; UINTN i ; GPT_DATA * GptData = NULL ; if ( ( Volume == NULL ) || ( Data == NULL ) ) return EFI_INVALID_PARAMETER ; if ( ( Status == EFI_SUCCESS ) && ( Volume -> BlockIO == NULL ) ) { Status = refit_call3_wrapper ( BS -> HandleProtocol , Volume -> DeviceHandle , & BlockIoProtocol , ( VOID * * ) & ( Volume -> BlockIO ) ) ; if ( EFI_ERROR ( Status ) ) { Volume -> BlockIO = NULL ; Print ( L" \n " ) ; Status = EFI_NOT_READY ; } } if ( ( Status == EFI_SUCCESS ) && ( ( ! Volume -> BlockIO -> Media -> MediaPresent ) || ( Volume -> BlockIO -> Media -> LogicalPartition ) ) ) Status = EFI_NO_MEDIA ; if ( Status == EFI_SUCCESS ) { GptData = AllocateGptData ( ) ; if ( GptData == NULL ) { Status = EFI_OUT_OF_RESOURCES ; } } if ( Status == EFI_SUCCESS ) { Status = refit_call5_wrapper ( Volume -> BlockIO -> ReadBlocks , Volume -> BlockIO , Volume -> BlockIO -> Media -> MediaId , 0 , sizeof ( MBR_RECORD ) , ( VOID * ) GptData -> ProtectiveMBR ) ; } if ( Status == EFI_SUCCESS ) { Status = refit_call5_wrapper ( Volume -> BlockIO -> ReadBlocks , Volume -> BlockIO , Volume -> BlockIO -> Media -> MediaId , 1 , sizeof ( GPT_HEADER ) , GptData -> Header ) ; } if ( Status == EFI_SUCCESS ) { if ( GptHeaderValid ( GptData ) ) { BufferSize = GptData -> Header -> entry_count * 128 ; GptData -> Entries = AllocatePool ( BufferSize ) ; if ( GptData -> Entries == NULL ) Status = EFI_OUT_OF_RESOURCES ; if ( Status == EFI_SUCCESS ) Status = refit_call5_wrapper ( Volume -> BlockIO -> ReadBlocks , Volume -> BlockIO , Volume -> BlockIO -> Media -> MediaId , GptData -> Header -> entry_lba , BufferSize , GptData -> Entries ) ; if ( ( Status == EFI_SUCCESS ) && ( crc32 ( 0x0 , GptData -> Entries , BufferSize ) != GptData -> Header -> entry_crc32 ) ) Status = EFI_CRC_ERROR ; if ( Status == EFI_SUCCESS ) { for ( i = 0 ; i < GptData -> Header -> entry_count ; i ++ ) GptData -> Entries [ i ] . name [ 35 ] = ' \0 ' ; } } else { Status = EFI_UNSUPPORTED ; } } if ( Status == EFI_SUCCESS ) { ClearGptData ( * Data ) ; * Data = GptData ; } else { ClearGptData ( GptData ) ; } return Status ; }
Read GPT data from Volume and store it in *Data.
Read GPT data from Volume and store it in * Data .
// Temporary holding storage; transferred to *Data later // get block i/o // if // Note: All but GptData->Entries // if // if // Read the MBR and store it in GptData->ProtectiveMBR. // Read the GPT header and store it in GptData->Header. // If it looks like a valid protective MBR & GPT header, try to do more with it.... // Load actual GPT table.... // Check CRC status of table // Now, ensure that every name is null-terminated.... // if // if/else valid header // if header read OK // Everything looks OK, so copy it over // if/else