]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Add two new methods to get default value, also add sample code in sample driver.
[mirror_edk2.git] / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
index 947df96b2cb0453bfe7d278c3984cf63539c2787..618aa92dc90abf9935a0f8354abeed193c495343 100644 (file)
@@ -334,6 +334,277 @@ LoadNameValueNames (
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET\r
+  or WIDTH or VALUE.\r
+  <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
+\r
+  This is a internal function.\r
+\r
+  @param  StringPtr              String in <BlockConfig> format and points to the\r
+                                 first character of <Number>.\r
+  @param  Number                 The output value. Caller takes the responsibility\r
+                                 to free memory.\r
+  @param  Len                    Length of the <Number>, in characters.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary\r
+                                 structures.\r
+  @retval EFI_SUCCESS            Value of <Number> is outputted in Number\r
+                                 successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+GetValueOfNumber (\r
+  IN EFI_STRING                    StringPtr,\r
+  OUT UINT8                        **Number,\r
+  OUT UINTN                        *Len\r
+  )\r
+{\r
+  EFI_STRING               TmpPtr;\r
+  UINTN                    Length;\r
+  EFI_STRING               Str;\r
+  UINT8                    *Buf;\r
+  EFI_STATUS               Status;\r
+  UINT8                    DigitUint8;\r
+  UINTN                    Index;\r
+  CHAR16                   TemStr[2];\r
+\r
+  if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Buf = NULL;\r
+\r
+  TmpPtr = StringPtr;\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+  *Len   = StringPtr - TmpPtr;\r
+  Length = *Len + 1;\r
+\r
+  Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (Str == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
+  *(Str + *Len) = L'\0';\r
+\r
+  Length = (Length + 1) / 2;\r
+  Buf = (UINT8 *) AllocateZeroPool (Length);\r
+  if (Buf == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  \r
+  Length = *Len;\r
+  ZeroMem (TemStr, sizeof (TemStr));\r
+  for (Index = 0; Index < Length; Index ++) {\r
+    TemStr[0] = Str[Length - Index - 1];\r
+    DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+    if ((Index & 1) == 0) {\r
+      Buf [Index/2] = DigitUint8;\r
+    } else {\r
+      Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);\r
+    }\r
+  }\r
+\r
+  *Number = Buf;\r
+  Status  = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (Str != NULL) {\r
+    FreePool (Str);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Create altcfg string. \r
+\r
+  @param  Result               The request result string.\r
+  @param  ConfigHdr            The request head info. <ConfigHdr> format.\r
+  @param  Offset               The offset of the parameter int he structure.\r
+  @param  Width                The width of the parameter.\r
+\r
+\r
+  @retval  The string with altcfg info append at the end.\r
+**/\r
+EFI_STRING \r
+CreateAltCfgString (\r
+  IN     EFI_STRING     Result,\r
+  IN     EFI_STRING     ConfigHdr,\r
+  IN     UINTN          Offset,\r
+  IN     UINTN          Width\r
+  )\r
+{\r
+  EFI_STRING StringPtr;\r
+  EFI_STRING TmpStr;\r
+  UINTN      NewLen;\r
+\r
+  NewLen = (((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + StrLen (Result)) * sizeof (CHAR16);\r
+  StringPtr = AllocateZeroPool (NewLen);\r
+  if (StringPtr == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  TmpStr = StringPtr;\r
+  if (Result != NULL) {\r
+    StrCpy (StringPtr, Result);\r
+    StringPtr += StrLen (Result);  \r
+    FreePool (Result);\r
+  }\r
+  \r
+  UnicodeSPrint (\r
+  StringPtr, \r
+  (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+  L"&%s&ALTCFG=%04x", \r
+  ConfigHdr, \r
+  EFI_HII_DEFAULT_CLASS_STANDARD\r
+  );\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  UnicodeSPrint (\r
+    StringPtr, \r
+    (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
+    Offset, \r
+    Width,\r
+    DEFAULT_CLASS_STANDARD_VALUE\r
+    );\r
+  StringPtr += StrLen (StringPtr);  \r
+\r
+  UnicodeSPrint (\r
+  StringPtr, \r
+  (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+  L"&%s&ALTCFG=%04x", \r
+  ConfigHdr, \r
+  EFI_HII_DEFAULT_CLASS_MANUFACTURING\r
+  );\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  UnicodeSPrint (\r
+    StringPtr, \r
+    (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
+    Offset, \r
+    Width,\r
+    DEFAULT_CLASS_MANUFACTURING_VALUE\r
+    );\r
+  StringPtr += StrLen (StringPtr); \r
+\r
+  return TmpStr;\r
+}\r
+\r
+/**\r
+  Check whether need to add the altcfg string. if need to add, add the altcfg \r
+  string.\r
+\r
+  @param  RequestResult              The request result string.\r
+  @param  ConfigRequestHdr           The request head info. <ConfigHdr> format.\r
+\r
+**/\r
+VOID \r
+AppendAltCfgString (\r
+  IN OUT EFI_STRING                       *RequestResult,\r
+  IN     EFI_STRING                       ConfigRequestHdr\r
+  )\r
+{\r
+  EFI_STRING                          StringPtr;\r
+  EFI_STRING                          TmpPtr;\r
+  UINTN                               Length;\r
+  UINT8                               *TmpBuffer;\r
+  UINTN                               Offset;\r
+  UINTN                               Width;\r
+  UINTN                               BlockSize;\r
+  UINTN                               ValueOffset;\r
+  UINTN                               ValueWidth;\r
+  EFI_STATUS                          Status;\r
+\r
+  StringPtr = *RequestResult;\r
+  StringPtr = StrStr (StringPtr, L"OFFSET");\r
+  BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
+  ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);\r
+  ValueWidth  = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);\r
+\r
+  if (StringPtr == NULL) {\r
+    return;\r
+  }\r
+\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {\r
+    //\r
+    // Back up the header of one <BlockName>\r
+    //\r
+    TmpPtr = StringPtr;\r
+\r
+    StringPtr += StrLen (L"OFFSET=");\r
+    //\r
+    // Get Offset\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    Offset = 0;\r
+    CopyMem (\r
+     &Offset,\r
+     TmpBuffer,\r
+     (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
+     );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      return;\r
+    }\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    Width = 0;\r
+    CopyMem (\r
+     &Width,\r
+     TmpBuffer,\r
+     (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
+     );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
+      return;\r
+    }\r
+    StringPtr += StrLen (L"&VALUE=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    StringPtr += Length;\r
+\r
+    //\r
+    // Calculate Value and convert it to hex string.\r
+    //\r
+    if (Offset + Width > BlockSize) {\r
+      return;\r
+    }\r
+\r
+    if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {\r
+      *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, Offset, Width);\r
+           return;\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   This function allows a caller to extract the current configuration for one\r
   or more named elements from the target driver.\r
@@ -429,6 +700,7 @@ ExtractConfig (
     AllocatedRequest = TRUE;\r
     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
     FreePool (ConfigRequestHdr);\r
+    ConfigRequestHdr = NULL;\r
   } else {\r
     //\r
     // Check routing data in <ConfigHdr>.\r
@@ -557,6 +829,8 @@ ExtractConfig (
                                   Results,\r
                                   Progress\r
                                   );\r
+    ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
+    AppendAltCfgString(Results, ConfigRequestHdr);\r
   }\r
 \r
   //\r
@@ -565,6 +839,10 @@ ExtractConfig (
   if (AllocatedRequest) {\r
     FreePool (ConfigRequest);\r
   }\r
+\r
+  if (ConfigRequestHdr != NULL) {\r
+    FreePool (ConfigRequestHdr);\r
+  }\r
   //\r
   // Set Progress string to the original request string.\r
   //\r
@@ -939,6 +1217,34 @@ DriverCallback (
     }\r
     break;\r
 \r
+  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:\r
+    {\r
+      switch (QuestionId) {\r
+      case 0x1240:\r
+        Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;\r
+      break;\r
+\r
+      default:\r
+        Status = EFI_UNSUPPORTED;\r
+      break;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:\r
+    {\r
+      switch (QuestionId) {\r
+      case 0x1240:\r
+        Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;\r
+      break;\r
+\r
+      default:\r
+        Status = EFI_UNSUPPORTED;      \r
+      break;\r
+      }\r
+    }\r
+    break;\r
+\r
   case EFI_BROWSER_ACTION_CHANGING:\r
   {\r
     switch (QuestionId) {\r