1 /** @file
2   Parse the INI configuration file and pass the information to the recovery driver
3   so that the driver can perform recovery accordingly.
4 
5   Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #include "RecoveryModuleLoadPei.h"
12 #include <Library/IniParsingLib.h>
13 #include <Library/PrintLib.h>
14 
15 #define MAX_LINE_LENGTH           512
16 
17 /**
18   Parse Config data file to get the updated data array.
19 
20   @param[in]      DataBuffer      Config raw file buffer.
21   @param[in]      BufferSize      Size of raw buffer.
22   @param[in, out] ConfigHeader    Pointer to the config header.
23   @param[in, out] RecoveryArray   Pointer to the config of recovery data.
24 
25   @retval EFI_NOT_FOUND         No config data is found.
26   @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
27   @retval EFI_SUCCESS           Parse the config file successfully.
28 
29 **/
30 EFI_STATUS
ParseRecoveryDataFile(IN UINT8 * DataBuffer,IN UINTN BufferSize,IN OUT CONFIG_HEADER * ConfigHeader,IN OUT RECOVERY_CONFIG_DATA ** RecoveryArray)31 ParseRecoveryDataFile (
32   IN      UINT8                         *DataBuffer,
33   IN      UINTN                         BufferSize,
34   IN OUT  CONFIG_HEADER                 *ConfigHeader,
35   IN OUT  RECOVERY_CONFIG_DATA          **RecoveryArray
36   )
37 {
38   EFI_STATUS                            Status;
39   CHAR8                                 *SectionName;
40   CHAR8                                 Entry[MAX_LINE_LENGTH];
41   UINTN                                 Num;
42   UINTN                                 Index;
43   EFI_GUID                              FileGuid;
44   VOID                                  *Context;
45 
46   //
47   // First process the data buffer and get all sections and entries
48   //
49   Context = OpenIniFile(DataBuffer, BufferSize);
50   if (Context == NULL) {
51     return EFI_INVALID_PARAMETER;
52   }
53 
54   //
55   // Now get NumOfUpdate
56   //
57   Status = GetDecimalUintnFromDataFile(
58              Context,
59              "Head",
60              "NumOfRecovery",
61              &Num
62              );
63   if (EFI_ERROR(Status) || (Num == 0)) {
64     DEBUG((DEBUG_ERROR, "NumOfRecovery not found\n"));
65     CloseIniFile(Context);
66     return EFI_NOT_FOUND;
67   }
68 
69   ConfigHeader->NumOfRecovery = Num;
70   *RecoveryArray = AllocateZeroPool ((sizeof (RECOVERY_CONFIG_DATA) * Num));
71   if (*RecoveryArray == NULL) {
72     CloseIniFile(Context);
73     return EFI_OUT_OF_RESOURCES;
74   }
75 
76   for (Index = 0 ; Index < ConfigHeader->NumOfRecovery; Index++) {
77     //
78     // Get the section name of each update
79     //
80     AsciiStrCpyS (Entry, MAX_LINE_LENGTH, "Recovery");
81     AsciiValueToStringS (
82       Entry + AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
83       MAX_LINE_LENGTH - AsciiStrnLenS (Entry, MAX_LINE_LENGTH),
84       0,
85       Index,
86       0
87       );
88     Status = GetStringFromDataFile(
89                Context,
90                "Head",
91                Entry,
92                &SectionName
93                );
94     if (EFI_ERROR(Status) || (SectionName == NULL)) {
95       DEBUG((DEBUG_ERROR, "[%d] %a not found\n", Index, Entry));
96       CloseIniFile(Context);
97       return EFI_NOT_FOUND;
98     }
99 
100     //
101     // The section name of this update has been found.
102     // Now looks for all the config data of this update
103     //
104 
105     //
106     // FileGuid
107     //
108     Status = GetGuidFromDataFile(
109                Context,
110                SectionName,
111                "FileGuid",
112                &FileGuid
113                );
114     if (EFI_ERROR(Status)) {
115       CloseIniFile(Context);
116       DEBUG((DEBUG_ERROR, "[%d] FileGuid not found\n", Index));
117       return EFI_NOT_FOUND;
118     }
119 
120     CopyGuid(&((*RecoveryArray)[Index].FileGuid), &FileGuid);
121 
122     //
123     // Length
124     //
125     Status = GetHexUintnFromDataFile(
126                Context,
127                SectionName,
128                "Length",
129                &Num
130                );
131     if (EFI_ERROR(Status)) {
132       CloseIniFile(Context);
133       DEBUG((DEBUG_ERROR, "[%d] Length not found\n", Index));
134       return EFI_NOT_FOUND;
135     }
136     (*RecoveryArray)[Index].Length = Num;
137 
138     //
139     // ImageOffset
140     //
141     Status = GetHexUintnFromDataFile(
142                Context,
143                SectionName,
144                "ImageOffset",
145                &Num
146                );
147     if (EFI_ERROR(Status)) {
148       CloseIniFile(Context);
149       DEBUG((DEBUG_ERROR, "[%d] ImageOffset not found\n", Index));
150       return EFI_NOT_FOUND;
151     }
152     (*RecoveryArray)[Index].ImageOffset = Num;
153   }
154 
155   //
156   // Now all configuration data got. Free those temporary buffers
157   //
158   CloseIniFile(Context);
159 
160   return EFI_SUCCESS;
161 }
162 
163