\r
--*/\r
\r
+#define MAX_STRING_LEN 200\r
+static BOOLEAN mFeaturerSwitch = TRUE;\r
+static BOOLEAN mResetRequired = FALSE;\r
extern UINT16 gPlatformBootTimeOutDefault;\r
\r
UINT16\r
return Buffer;\r
}\r
\r
+VOID\r
+BdsLibSafeFreePool (\r
+ IN VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free pool safely.\r
+\r
+Arguments:\r
+ \r
+ Buffer - The allocated pool entry to free\r
+\r
+Returns:\r
+\r
+ Pointer of the buffer allocated.\r
+\r
+--*/\r
+{\r
+ if (Buffer != NULL) {\r
+ gBS->FreePool (Buffer);\r
+ Buffer = NULL;\r
+ }\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Single\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete the instance in Multi which matches partly with Single instance\r
+\r
+Arguments:\r
+\r
+ Multi - A pointer to a multi-instance device path data structure.\r
+\r
+ Single - A pointer to a single-instance device path data structure.\r
+\r
+Returns:\r
+\r
+ This function will remove the device path instances in Multi which partly \r
+ match with the Single, and return the result device path. If there is no\r
+ remaining device path as a result, this function will return NULL.\r
+\r
+--*/\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINTN InstanceSize;\r
+ UINTN SingleDpSize; \r
+ UINTN Size; \r
+ \r
+ NewDevicePath = NULL;\r
+ TempNewDevicePath = NULL;\r
+\r
+ if (Multi == NULL || Single == NULL) {\r
+ return Multi;\r
+ }\r
+ \r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+\r
+ while (Instance != NULL) {\r
+\r
+ Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; \r
+ \r
+ if ((CompareMem (Instance, Single, Size) != 0)) {\r
+ //\r
+ // Append the device path instance which does not match with Single\r
+ //\r
+ TempNewDevicePath = NewDevicePath;\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
+ BdsLibSafeFreePool(TempNewDevicePath);\r
+ }\r
+ BdsLibSafeFreePool(Instance);\r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+ }\r
+ \r
+ return NewDevicePath;\r
+}\r
+\r
BOOLEAN\r
BdsLibMatchDevicePaths (\r
IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
\r
DevicePath = Multi;\r
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
- Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
\r
//\r
// Search for the match of 'Single' in 'Multi'\r
// If the single device path is found in multiple device paths,\r
// return success\r
//\r
- if (Size == 0) {\r
- return FALSE;\r
- }\r
-\r
if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
+ gBS->FreePool (DevicePathInst);\r
return TRUE;\r
}\r
\r
gBS->FreePool (DevicePathInst);\r
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
- Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
}\r
\r
return FALSE;\r
\r
return Status;\r
}\r
+\r
+//\r
+// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.\r
+// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if \r
+// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.\r
+//\r
+\r
+VOID\r
+EnableResetReminderFeature (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Enable the setup browser reset reminder feature.\r
+ This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.\r
+\r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ mFeaturerSwitch = TRUE;\r
+} \r
+\r
+VOID\r
+DisableResetReminderFeature (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Disable the setup browser reset reminder feature.\r
+ This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.\r
+ \r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ mFeaturerSwitch = FALSE;\r
+} \r
+\r
+VOID\r
+EnableResetRequired (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Record the info that a reset is required.\r
+ A module boolean variable is used to record whether a reset is required. \r
+ \r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ mResetRequired = TRUE;\r
+} \r
+\r
+VOID\r
+DisableResetRequired (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Record the info that no reset is required.\r
+ A module boolean variable is used to record whether a reset is required. \r
+\r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ mResetRequired = FALSE;\r
+} \r
+\r
+BOOLEAN\r
+IsResetReminderFeatureEnable (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Check whether platform policy enable the reset reminder feature. The default is enabled.\r
+\r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ return mFeaturerSwitch;\r
+}\r
+\r
+BOOLEAN\r
+IsResetRequired (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Check if user changed any option setting which needs a system reset to be effective.\r
+ \r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ return mResetRequired;\r
+}\r
+\r
+VOID\r
+SetupResetReminder (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Check whether a reset is needed, and finish the reset reminder feature.\r
+ If a reset is needed, Popup a menu to notice user, and finish the feature \r
+ according to the user selection.\r
+\r
+Arguments:\r
+\r
+ VOID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FORM_BROWSER_PROTOCOL *Browser;\r
+ EFI_INPUT_KEY Key; \r
+ CHAR16 *StringBuffer1;\r
+ CHAR16 *StringBuffer2; \r
+\r
+\r
+ //\r
+ //check any reset required change is applied? if yes, reset system\r
+ //\r
+ if (IsResetReminderFeatureEnable ()) {\r
+ if (IsResetRequired ()) {\r
+ \r
+ Status = gBS->LocateProtocol (\r
+ &gEfiFormBrowserProtocolGuid,\r
+ NULL,\r
+ &Browser\r
+ ); \r
+ \r
+ StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
+ ASSERT (StringBuffer1 != NULL);\r
+ StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
+ ASSERT (StringBuffer2 != NULL); \r
+ StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? ");\r
+ StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)"); \r
+ //\r
+ // Popup a menu to notice user\r
+ // \r
+ do {\r
+ Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2);\r
+ } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); \r
+ \r
+ gBS->FreePool (StringBuffer1); \r
+ gBS->FreePool (StringBuffer2); \r
+ //\r
+ // If the user hits the YES Response key, reset\r
+ //\r
+ if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {\r
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+ }\r
+ gST->ConOut->ClearScreen (gST->ConOut);\r
+ } \r
+ } \r
+} \r
+\r
+EFI_STATUS\r
+BdsLibGetHiiHandles (\r
+ IN EFI_HII_PROTOCOL *Hii,\r
+ IN OUT UINT16 *HandleBufferLength,\r
+ OUT EFI_HII_HANDLE **HiiHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determines the handles that are currently active in the database.\r
+ It's the caller's responsibility to free handle buffer.\r
+\r
+Arguments:\r
+\r
+ This - A pointer to the EFI_HII_PROTOCOL instance.\r
+ HandleBufferLength - On input, a pointer to the length of the handle buffer. On output, \r
+ the length of the handle buffer that is required for the handles found.\r
+ HiiHandleBuffer - Pointer to an array of EFI_HII_PROTOCOL instances returned.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Get an array of EFI_HII_PROTOCOL instances successfully.\r
+ EFI_INVALID_PARAMETER - Hii is NULL.\r
+ EFI_NOT_FOUND - Database not found.\r
+ \r
+--*/\r
+{\r
+ UINT16 TempBufferLength;\r
+ EFI_STATUS Status;\r
+ \r
+ TempBufferLength = 0;\r
+ \r
+ //\r
+ // Try to find the actual buffer size for HiiHandle Buffer.\r
+ //\r
+ Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);\r
+ \r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ *HiiHandleBuffer = AllocateZeroPool (TempBufferLength);\r
+ Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);\r
+ //\r
+ // we should not fail here.\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ \r
+ *HandleBufferLength = TempBufferLength;\r
+ \r
+ return Status;\r
+ \r
+}\r