This is a internal function.\r
\r
@param String UEFI configuration string\r
- @param DevicePath binary of a UEFI device path.\r
+ @param DevicePathData Binary of a UEFI device path.\r
\r
+ @retval EFI_NOT_FOUND The device path is not invalid.\r
@retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.\r
@retval EFI_OUT_OF_RESOURCES Lake of resources to store neccesary structures.\r
@retval EFI_SUCCESS The device path is retrieved and translated to\r
EFI_STATUS\r
GetDevicePath (\r
IN EFI_STRING String,\r
- OUT UINT8 **DevicePath\r
+ OUT UINT8 **DevicePathData\r
)\r
{\r
- UINTN Length;\r
- EFI_STRING PathHdr;\r
- EFI_STRING DevicePathString;\r
- UINT8 *DevicePathBuffer;\r
- CHAR16 TemStr[2];\r
- UINTN Index;\r
- UINT8 DigitUint8;\r
-\r
- if (String == NULL || DevicePath == NULL) {\r
+ UINTN Length;\r
+ EFI_STRING PathHdr;\r
+ UINT8 *DevicePathBuffer;\r
+ CHAR16 TemStr[2];\r
+ UINTN Index;\r
+ UINT8 DigitUint8;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+\r
+ if (String == NULL || DevicePathData == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if (*String == 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
-\r
+ //\r
+ // Check whether path data does exist.\r
+ //\r
String += StrLen (L"PATH=");\r
+ if (*String == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
PathHdr = String;\r
\r
//\r
// of UEFI device path.\r
//\r
for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
- DevicePathString = (EFI_STRING) AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
- if (DevicePathString == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ //\r
+ // Check DevicePath Length\r
+ //\r
+ if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+ return EFI_NOT_FOUND;\r
}\r
- StrnCpy (DevicePathString, PathHdr, Length);\r
- *(DevicePathString + Length) = 0;\r
-\r
+ \r
//\r
// The data in <PathHdr> is encoded as hex UNICODE %02x bytes in the same order\r
// as the device path resides in RAM memory.\r
//\r
DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
if (DevicePathBuffer == NULL) {\r
- FreePool (DevicePathString);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
-\r
+ \r
+ //\r
+ // Convert DevicePath\r
+ //\r
ZeroMem (TemStr, sizeof (TemStr));\r
- for (Index = 0; DevicePathString[Index] != L'\0'; Index ++) {\r
- TemStr[0] = DevicePathString[Index];\r
+ for (Index = 0; Index < Length; Index ++) {\r
+ TemStr[0] = PathHdr[Index];\r
DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
if ((Index & 1) == 0) {\r
DevicePathBuffer [Index/2] = DigitUint8;\r
DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
}\r
}\r
-\r
- FreePool (DevicePathString);\r
\r
- *DevicePath = DevicePathBuffer;\r
+ //\r
+ // Validate DevicePath\r
+ //\r
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DevicePathBuffer;\r
+ while (!IsDevicePathEnd (DevicePath)) {\r
+ if ((DevicePath->Type == 0) || (DevicePath->SubType == 0) || (DevicePathNodeLength (DevicePath) > sizeof (EFI_DEV_PATH))) {\r
+ //\r
+ // Invalid device path\r
+ //\r
+ FreePool (DevicePathBuffer);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
\r
+ //\r
+ // return the device path\r
+ //\r
+ *DevicePathData = DevicePathBuffer;\r
return EFI_SUCCESS;\r
-\r
}\r
\r
/**\r
When Request points to NULL, the default value string \r
for each varstore in form package will be merged into \r
a <MultiConfigAltResp> format string and return.\r
+ @param PointerProgress Optional parameter, it can be be NULL. \r
+ When it is not NULL, if Request is NULL, it returns NULL. \r
+ On return, points to a character in the Request\r
+ string. Points to the string's null terminator if\r
+ request was successful. Points to the most recent\r
+ & before the first failing name / value pair (or\r
+ the beginning of the string if the failure is in\r
+ the first name / value pair) if the request was\r
+ not successful.\r
@retval EFI_SUCCESS The Results string is set to the full request string.\r
And AltCfgResp contains all default value string.\r
@retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.\r
@retval EFI_NOT_FOUND The varstore (Guid and Name) in Request string \r
can't be found in Form package.\r
@retval EFI_NOT_FOUND HiiPackage can't be got on the input HiiHandle.\r
- @retval EFI_INVALID_PARAMETER *Request points to NULL.\r
+ @retval EFI_INVALID_PARAMETER Request points to NULL.\r
\r
**/\r
EFI_STATUS\r
IN HII_DATABASE_RECORD *DataBaseRecord,\r
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
IN OUT EFI_STRING *Request,\r
- IN OUT EFI_STRING *AltCfgResp\r
+ IN OUT EFI_STRING *AltCfgResp,\r
+ OUT EFI_STRING *PointerProgress OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STRING NameStr;\r
EFI_STRING PathStr;\r
EFI_STRING StringPtr;\r
+ EFI_STRING Progress;\r
UINTN Length;\r
UINT8 *TmpBuffer;\r
UINT16 Offset;\r
LIST_ENTRY *LinkDefault;\r
BOOLEAN DataExist;\r
\r
+ if (DataBaseRecord == NULL || DevicePath == NULL || Request == NULL || AltCfgResp == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
//\r
// Initialize the local variables.\r
//\r
ResultSize = 0;\r
PackageSize = 0;\r
DataExist = FALSE;\r
+ Progress = *Request;\r
\r
//\r
// 0. Get Hii Form Package by HiiHandle\r
//\r
StringPtr = NULL;\r
if (*Request != NULL) {\r
- StringPtr = StrStr (*Request, L"&OFFSET=");\r
+ StringPtr = *Request;\r
+ //\r
+ // Jump <ConfigHdr>\r
+ //\r
+ if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"GUID=");\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"&NAME=");\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"&PATH=");\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr ++;\r
+ }\r
+ //\r
+ // Check the following string &OFFSET=\r
+ //\r
+ if (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+ Progress = StringPtr;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ } else if (*StringPtr == L'\0') {\r
+ //\r
+ // No request block is found.\r
+ //\r
+ StringPtr = NULL;\r
+ }\r
}\r
if (StringPtr != NULL) {\r
//\r
while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
//\r
// Skip the OFFSET string\r
- // \r
+ //\r
+ Progress = StringPtr;\r
StringPtr += StrLen (L"&OFFSET=");\r
//\r
// Get Offset\r
// Compute the length of the entire request starting with <ConfigHdr> and a \r
// Null-terminator\r
//\r
- DataExist = FALSE;\r
- Length = StrLen (ConfigHdr) + 1;\r
+ DataExist = FALSE;\r
+ Length = StrLen (ConfigHdr) + 1;\r
\r
for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
//\r
FreePool (HiiFormPackage);\r
}\r
\r
+ if (PointerProgress != NULL) {\r
+ if (*Request == NULL) {\r
+ *PointerProgress = NULL;\r
+ } else if (EFI_ERROR (Status)) {\r
+ *PointerProgress = Progress;\r
+ } else {\r
+ *PointerProgress = *Request + StrLen (*Request);\r
+ }\r
+ }\r
+\r
return Status;\r
}\r
\r
Link = Link->ForwardLink\r
) {\r
Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
- \r
if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
if (CompareMem (\r
// Get the full request string from IFR when HiiPackage is registered to HiiHandle \r
//\r
IfrDataParsedFlag = TRUE;\r
- Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults);\r
+ Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, &AccessProgress);\r
if (EFI_ERROR (Status)) {\r
+ //\r
+ // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
+ // Map it to the progress on <MultiConfigRequest> then return it.\r
+ //\r
+ *Progress = StrStr (StringPtr, AccessProgress);\r
goto Done;\r
}\r
//\r
//\r
// Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
//\r
- if (HiiHandle != NULL) {\r
- if (!IfrDataParsedFlag) {\r
- Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &AccessResults);\r
- } else if (DefaultResults != NULL) {\r
- Status = MergeDefaultString (&AccessResults, DefaultResults);\r
- FreePool (DefaultResults);\r
- DefaultResults = NULL;\r
- }\r
+ if (!IfrDataParsedFlag && HiiHandle != NULL) {\r
+ Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
+\r
FreePool (DevicePath);\r
DevicePath = NULL;\r
- \r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
\r
+ if (DefaultResults != NULL) {\r
+ Status = MergeDefaultString (&AccessResults, DefaultResults);\r
+ ASSERT_EFI_ERROR (Status);\r
+ FreePool (DefaultResults);\r
+ DefaultResults = NULL;\r
+ }\r
+ \r
NextConfigString: \r
if (!FirstElement) {\r
Status = AppendToMultiString (Results, L"&");\r
EFI_STRING AccessResults;\r
EFI_STRING Progress;\r
EFI_STRING StringPtr;\r
+ EFI_STRING ConfigRequest;\r
UINTN Index;\r
EFI_HANDLE *ConfigAccessHandles;\r
UINTN NumberConfigAccessHandles;\r
HII_DATABASE_RECORD *Database;\r
UINT8 *DevicePathPkg;\r
UINT8 *CurrentDevicePath;\r
+ BOOLEAN IfrDataParsedFlag;\r
\r
if (This == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
//\r
// Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
//\r
+ IfrDataParsedFlag = FALSE;\r
Progress = NULL;\r
HiiHandle = NULL;\r
DefaultResults = NULL;\r
Database = NULL;\r
+ ConfigRequest = NULL;\r
DevicePath = DevicePathFromHandle (ConfigAccessHandles[Index]);\r
if (DevicePath != NULL) {\r
for (Link = Private->DatabaseList.ForwardLink;\r
&Progress,\r
&AccessResults\r
);\r
- if (!EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status)) {\r
//\r
// Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
//\r
if (HiiHandle != NULL && DevicePath != NULL) {\r
+ IfrDataParsedFlag = TRUE;\r
+ Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+ //\r
+ // Get the full request string to get the Current setting again.\r
+ //\r
+ if (!EFI_ERROR (Status) && ConfigRequest != NULL) {\r
+ Status = ConfigAccess->ExtractConfig (\r
+ ConfigAccess,\r
+ ConfigRequest,\r
+ &Progress,\r
+ &AccessResults\r
+ );\r
+ FreePool (ConfigRequest);\r
+ } else {\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
+ //\r
+ if (!IfrDataParsedFlag && HiiHandle != NULL && DevicePath != NULL) {\r
StringPtr = StrStr (AccessResults, L"&GUID=");\r
if (StringPtr != NULL) {\r
*StringPtr = 0;\r
}\r
if (StrStr (AccessResults, L"&OFFSET=") != NULL) {\r
- Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults);\r
+ Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
if (StringPtr != NULL) {\r
*StringPtr = L'&';\r