mirror of https://github.com/acidanthera/audk.git
Retire original HII APIs: IfrLibExtractDefault and ConstructConfigAltResp, which are replaced by HiiSetToDefaults API.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8319 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
b347c1bceb
commit
1f1cb2f216
|
@ -328,55 +328,6 @@ HiiValidateSettings (
|
|||
IN CONST EFI_STRING Request OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Allocates and returns a Null-terminated Unicode <ConfigAltResp> string.
|
||||
|
||||
If Guid is NULL, then ASSERT().
|
||||
If Name is NULL, then ASSERT().
|
||||
If BlockNameArray is NULL, then ASSERT().
|
||||
|
||||
@param[in] Guid GUID of the buffer storage.
|
||||
@param[in] Name Name of the buffer storage.
|
||||
@param[in] DriverHandle The DriverHandle that support a Device Path
|
||||
Protocol.
|
||||
@param[in] BufferStorage Content of the buffer storage.
|
||||
@param[in] BufferStorageSize Length in bytes of the buffer storage.
|
||||
@param[in] BlockNameArray Array generated by VFR compiler. This array
|
||||
contains a UINT32 value that is the length
|
||||
of BlockNameArray in bytes, followed by pairs
|
||||
of 16-bit values that are the offset and length
|
||||
values used to contruct a <ConfigRequest> string.
|
||||
@param[in] ... A variable argument list that contains pairs of 16-bit
|
||||
ALTCFG identifiers and pointers to DefaultValueArrays.
|
||||
The variable argument list is terminated by a NULL
|
||||
DefaultValueArray pointer. A DefaultValueArray
|
||||
contains a UINT32 value that is the length, in bytes,
|
||||
of the DefaultValueArray. The UINT32 length value
|
||||
is followed by a series of records that contain
|
||||
a 16-bit WIDTH value followed by a byte array with
|
||||
WIDTH entries. The records must be parsed from
|
||||
beginning to end until the UINT32 length limit
|
||||
is reached.
|
||||
|
||||
@retval NULL There are not enough resources to process the request.
|
||||
@retval NULL A <ConfigResp> could not be retrieved from the Config
|
||||
Routing Protocol.
|
||||
@retval Other A pointer to the Null-terminate Unicode <ConfigAltResp>
|
||||
string.
|
||||
|
||||
**/
|
||||
EFI_STRING
|
||||
EFIAPI
|
||||
HiiConstructConfigAltResp (
|
||||
IN CONST EFI_GUID *Guid,
|
||||
IN CONST CHAR16 *Name,
|
||||
IN EFI_HANDLE DriverHandle,
|
||||
IN CONST VOID *BufferStorage,
|
||||
IN UINTN BufferStorageSize,
|
||||
IN CONST VOID *BlockNameArray,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
Determines if the routing data specified by GUID and NAME match a <ConfigHdr>.
|
||||
|
||||
|
@ -990,32 +941,4 @@ HiiUpdateForm (
|
|||
IN VOID *EndOpcodeHandle OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Configure the buffer accrording to ConfigBody strings in the format of
|
||||
<Length:4 bytes>, <Offset: 2 bytes>, <Width:2 bytes>, <Data:n bytes>.
|
||||
This ConfigBody strings is generated by EDKII UEFI VfrCompiler for the default
|
||||
values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000
|
||||
constructed following this rule:
|
||||
"Vfr" + varstore.name + "Default" + defaultstore.attributes.
|
||||
Check the generated C file in Output for details.
|
||||
|
||||
@param Buffer the start address of buffer.
|
||||
@param BufferSize the size of buffer.
|
||||
@param Number the number of the ConfigBody strings.
|
||||
@param ... the ConfigBody strings
|
||||
|
||||
@retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
|
||||
@retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
|
||||
@retval EFI_SUCCESS Operation successful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HiiIfrLibExtractDefault(
|
||||
IN VOID *Buffer,
|
||||
IN UINTN *BufferSize,
|
||||
UINTN Number,
|
||||
...
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1843,11 +1843,20 @@ InternalHiiIfrValueAction (
|
|||
(ActionType == ACTION_SET_DEFAUTL_VALUE) ? &DefaultName:NULL, // it can be NULL to get the current setting.
|
||||
&ConfigResp
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// The required setting can't be found. So, it is not required to be validated and set.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto NextConfigAltResp;
|
||||
}
|
||||
//
|
||||
// Only the ConfigHdr is found. Not any block data is found. No data is required to be validated and set.
|
||||
//
|
||||
if (StrStr (ConfigResp, L"&OFFSET=") == NULL) {
|
||||
goto NextConfigAltResp;
|
||||
}
|
||||
|
||||
//
|
||||
// 4. Set the default configuration information or Validate current setting by parse IFR code.
|
||||
|
@ -1878,10 +1887,10 @@ NextConfigAltResp:
|
|||
HiiPackageList = NULL;
|
||||
}
|
||||
|
||||
if (ConfigResp != NULL) {
|
||||
FreePool (ConfigResp);
|
||||
ConfigResp = NULL;
|
||||
}
|
||||
if (ConfigResp != NULL) {
|
||||
FreePool (ConfigResp);
|
||||
ConfigResp = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Free the allocated buffer.
|
||||
|
@ -2035,299 +2044,6 @@ HiiSetToDefaults (
|
|||
return InternalHiiIfrValueAction (Request, DefaultId, ACTION_SET_DEFAUTL_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and returns a Null-terminated Unicode <ConfigAltResp> string.
|
||||
|
||||
If Guid is NULL, then ASSERT().
|
||||
If Name is NULL, then ASSERT().
|
||||
If BlockNameArray is NULL, then ASSERT().
|
||||
|
||||
@param[in] Guid GUID of the buffer storage.
|
||||
@param[in] Name Name of the buffer storage.
|
||||
@param[in] DriverHandle The DriverHandle that support a Device Path
|
||||
Protocol.
|
||||
@param[in] BufferStorage Content of the buffer storage.
|
||||
@param[in] BufferStorageSize Length in bytes of the buffer storage.
|
||||
@param[in] BlockNameArray Array generated by VFR compiler. This array
|
||||
contains a UINT32 value that is the length
|
||||
of BlockNameArray in bytes, followed by pairs
|
||||
of 16-bit values that are the offset and length
|
||||
values used to contruct a <ConfigRequest> string.
|
||||
@param[in] ... A variable argument list that contains pairs of 16-bit
|
||||
ALTCFG identifiers and pointers to DefaultValueArrays.
|
||||
The variable argument list is terminated by a NULL
|
||||
DefaultValueArray pointer. A DefaultValueArray
|
||||
contains a UINT32 value that is the length, in bytes,
|
||||
of the DefaultValueArray. The UINT32 length value
|
||||
is followed by a series of records that contain
|
||||
a 16-bit WIDTH value followed by a byte array with
|
||||
WIDTH entries. The records must be parsed from
|
||||
beginning to end until the UINT32 length limit
|
||||
is reached.
|
||||
|
||||
@retval NULL There are not enough resources to process the request.
|
||||
@retval NULL A <ConfigResp> could not be retrieved from the Config
|
||||
Routing Protocol.
|
||||
@retval Other A pointer to the Null-terminate Unicode <ConfigAltResp>
|
||||
string.
|
||||
|
||||
**/
|
||||
EFI_STRING
|
||||
EFIAPI
|
||||
HiiConstructConfigAltResp (
|
||||
IN CONST EFI_GUID *Guid,
|
||||
IN CONST CHAR16 *Name,
|
||||
IN EFI_HANDLE DriverHandle,
|
||||
IN CONST VOID *BufferStorage,
|
||||
IN UINTN BufferStorageSize,
|
||||
IN CONST VOID *BlockNameArray,
|
||||
...
|
||||
)
|
||||
{
|
||||
UINTN Length;
|
||||
CHAR16 *String;
|
||||
CHAR16 *ConfigHdr;
|
||||
UINT8 *Buffer;
|
||||
UINT8 *BufferEnd;
|
||||
CHAR16 *ConfigRequest;
|
||||
EFI_STRING ConfigResp;
|
||||
EFI_STRING ConfigAltResp;
|
||||
VA_LIST Args;
|
||||
UINTN AltCfgId;
|
||||
UINT16 Width;
|
||||
UINT16 OffsetValue;
|
||||
UINT16 WidthValue;
|
||||
|
||||
ASSERT (Guid != NULL);
|
||||
ASSERT (Name != NULL);
|
||||
ASSERT (BlockNameArray != NULL);
|
||||
|
||||
//
|
||||
// Initialize local variables
|
||||
//
|
||||
ConfigHdr = NULL;
|
||||
ConfigRequest = NULL;
|
||||
ConfigResp = NULL;
|
||||
|
||||
//
|
||||
// Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
|
||||
//
|
||||
ConfigHdr = HiiConstructConfigHdr (Guid, Name, DriverHandle);
|
||||
if (ConfigHdr == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute the length of the entire request starting with <ConfigHdr> and a
|
||||
// Null-terminator
|
||||
//
|
||||
Length = StrLen (ConfigHdr) + 1;
|
||||
|
||||
//
|
||||
// Determine the size <BlockName> Offset/Width pairs
|
||||
//
|
||||
Buffer = (UINT8 *)BlockNameArray;
|
||||
BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer);
|
||||
Buffer += sizeof (UINT32);
|
||||
|
||||
//
|
||||
// Add <BlockName> length that is composed of one or more Offset/Width pairs
|
||||
//
|
||||
// <BlockName> ::= &OFFSET=1234&WIDTH=1234
|
||||
// | 8 | 4 | 7 | 4 |
|
||||
//
|
||||
Length += (((BufferEnd - Buffer) / (sizeof (UINT16) + sizeof (UINT16))) * (8 + 4 + 7 + 4));
|
||||
|
||||
//
|
||||
// Allocate buffer for the entire <ConfigRequest>
|
||||
//
|
||||
ConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));
|
||||
if (ConfigRequest == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
String = ConfigRequest;
|
||||
|
||||
//
|
||||
// Start with <ConfigHdr>
|
||||
//
|
||||
StrCpy (String, ConfigHdr);
|
||||
String += StrLen (String);
|
||||
|
||||
//
|
||||
// Loop through all the Offset/Width pairs and append them to ConfigRequest
|
||||
//
|
||||
while (Buffer < BufferEnd) {
|
||||
//
|
||||
// Append &OFFSET=XXXX&WIDTH=YYYY
|
||||
//
|
||||
OffsetValue = ReadUnaligned16 ((UINT16 *)Buffer);
|
||||
WidthValue = ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16)));
|
||||
UnicodeSPrint (
|
||||
String,
|
||||
(8 + 4 + 7 + 4) * sizeof (CHAR16),
|
||||
L"&OFFSET=%04X&WIDTH=%04X",
|
||||
OffsetValue,
|
||||
WidthValue
|
||||
);
|
||||
|
||||
String += StrLen (String);
|
||||
Buffer += (sizeof (UINT16) + sizeof (UINT16));
|
||||
}
|
||||
|
||||
//
|
||||
// Get the <ConfigResp>
|
||||
//
|
||||
ConfigResp = InternalHiiBlockToConfig (ConfigRequest, BufferStorage, BufferStorageSize);
|
||||
if (ConfigResp == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute the length of the entire response starting with <ConfigResp> and a
|
||||
// Null-terminator
|
||||
//
|
||||
Length = StrLen (ConfigResp) + 1;
|
||||
|
||||
//
|
||||
// Add the length associated with each pair of variable argument parameters
|
||||
//
|
||||
VA_START (Args, BlockNameArray);
|
||||
while (TRUE) {
|
||||
AltCfgId = VA_ARG (Args, UINTN);
|
||||
Buffer = VA_ARG (Args, UINT8 *);
|
||||
if (Buffer == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Add length for "&<ConfigHdr>&ALTCFG=XXXX"
|
||||
// |1| StrLen (ConfigHdr) | 8 | 4 |
|
||||
//
|
||||
Length += (1 + StrLen (ConfigHdr) + 8 + 4);
|
||||
|
||||
BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer);
|
||||
Buffer += sizeof (UINT32);
|
||||
while (Buffer < BufferEnd) {
|
||||
//
|
||||
// Extract Width field
|
||||
//
|
||||
Width = ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16)));
|
||||
|
||||
//
|
||||
// Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
|
||||
// | 8 | 4 | 7 | 4 | 7 | Width * 2 |
|
||||
//
|
||||
Length += (8 + 4 + 7 + 4 + 7 + Width * 2);
|
||||
|
||||
//
|
||||
// Update Buffer to the next record
|
||||
//
|
||||
Buffer += (sizeof (UINT16) + sizeof (UINT16) + Width);
|
||||
}
|
||||
}
|
||||
VA_END (Args);
|
||||
|
||||
//
|
||||
// Allocate a buffer for the entire response
|
||||
//
|
||||
ConfigAltResp = AllocateZeroPool (Length * sizeof (CHAR16));
|
||||
if (ConfigAltResp == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
String = ConfigAltResp;
|
||||
|
||||
//
|
||||
// Add <ConfigResp>
|
||||
//
|
||||
StrCpy (String, ConfigResp);
|
||||
String += StrLen (String);
|
||||
|
||||
//
|
||||
// Add <AltResp> for each pair of variable argument parameters
|
||||
//
|
||||
VA_START (Args, BlockNameArray);
|
||||
while (TRUE) {
|
||||
AltCfgId = VA_ARG (Args, UINTN);
|
||||
Buffer = VA_ARG (Args, UINT8 *);
|
||||
if (Buffer == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX"
|
||||
// |1| StrLen (ConfigHdr) | 8 | 4 |
|
||||
//
|
||||
UnicodeSPrint (
|
||||
String,
|
||||
(1 + StrLen (ConfigHdr) + 8 + 4) * sizeof (CHAR16),
|
||||
L"&%s&ALTCFG=%04X",
|
||||
ConfigHdr,
|
||||
AltCfgId
|
||||
);
|
||||
String += StrLen (String);
|
||||
|
||||
//
|
||||
// Add <ConfigBody> ::= <ConfigElement>*
|
||||
//
|
||||
BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer);
|
||||
Buffer += sizeof (UINT32);
|
||||
while (Buffer < BufferEnd) {
|
||||
//
|
||||
// Extract Width field
|
||||
//
|
||||
Width = ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16)));
|
||||
|
||||
//
|
||||
// Add <BlockConfig>
|
||||
//
|
||||
UnicodeSPrint (
|
||||
String,
|
||||
(8 + 4 + 7 + 4 + 7 + Width * 2) * sizeof (CHAR16),
|
||||
L"&OFFSET=%04X&WIDTH=%04X&VALUE=",
|
||||
ReadUnaligned16 ((UINT16 *)Buffer),
|
||||
Width
|
||||
);
|
||||
String += StrLen (String);
|
||||
|
||||
//
|
||||
// Update Buffer to point to the value in the current record
|
||||
//
|
||||
Buffer += (sizeof (UINT16) + sizeof (UINT16));
|
||||
|
||||
//
|
||||
// Convert Value to a hex string in "%x" format
|
||||
// NOTE: This is in the opposite byte that GUID and PATH use
|
||||
//
|
||||
for (; Width > 0; Width--) {
|
||||
String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, Buffer[Width - 1], 2);
|
||||
}
|
||||
//
|
||||
// Update Buffer to the next record
|
||||
//
|
||||
Buffer += Width;
|
||||
}
|
||||
}
|
||||
VA_END (Args);
|
||||
|
||||
//
|
||||
// Convert all hex digits in range [A-F] in the configuration header to [a-f]
|
||||
//
|
||||
return InternalHiiLowerConfigString (ConfigAltResp);
|
||||
|
||||
Exit:
|
||||
if (ConfigHdr != NULL) {
|
||||
FreePool (ConfigHdr);
|
||||
}
|
||||
if (ConfigRequest != NULL) {
|
||||
FreePool (ConfigRequest);
|
||||
}
|
||||
if (ConfigResp != NULL) {
|
||||
FreePool (ConfigResp);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Determines if two values in config strings match.
|
||||
|
||||
|
@ -3859,78 +3575,3 @@ Finish:
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Configure the buffer accrording to ConfigBody strings in the format of
|
||||
<Length:4 bytes>, <Offset: 2 bytes>, <Width:2 bytes>, <Data:n bytes>.
|
||||
This ConfigBody strings is generated by UEFI VfrCompiler for the default
|
||||
values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000
|
||||
constructed following this rule:
|
||||
"Vfr" + varstore.name + "Default" + defaultstore.attributes.
|
||||
Check the generated C file in Output for details.
|
||||
|
||||
@param Buffer The start address of buffer.
|
||||
@param BufferSize The size of buffer.
|
||||
@param Number The number of the strings.
|
||||
@param ... Variable argument list for default value in <AltResp> format
|
||||
generated by the tool.
|
||||
|
||||
@retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
|
||||
@retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
|
||||
@retval EFI_SUCCESS Operation successful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HiiIfrLibExtractDefault(
|
||||
IN VOID *Buffer,
|
||||
IN UINTN *BufferSize,
|
||||
UINTN Number,
|
||||
...
|
||||
)
|
||||
{
|
||||
VA_LIST Args;
|
||||
UINTN Index;
|
||||
UINT32 TotalLen;
|
||||
UINT8 *BufCfgArray;
|
||||
UINT8 *BufferPos;
|
||||
UINT16 Offset;
|
||||
UINT16 Width;
|
||||
UINT8 *Value;
|
||||
|
||||
if ((Buffer == NULL) || (BufferSize == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Offset = 0;
|
||||
Width = 0;
|
||||
Value = NULL;
|
||||
|
||||
VA_START (Args, Number);
|
||||
for (Index = 0; Index < Number; Index++) {
|
||||
BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);
|
||||
TotalLen = ReadUnaligned32 ((UINT32 *)BufCfgArray);
|
||||
BufferPos = BufCfgArray + sizeof (UINT32);
|
||||
|
||||
while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {
|
||||
Offset = ReadUnaligned16 ((UINT16 *)BufferPos);
|
||||
BufferPos += sizeof (UINT16);
|
||||
Width = ReadUnaligned16 ((UINT16 *)BufferPos);
|
||||
BufferPos += sizeof (UINT16);
|
||||
Value = BufferPos;
|
||||
BufferPos += Width;
|
||||
|
||||
if ((UINTN)(Offset + Width) > *BufferSize) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
CopyMem ((UINT8 *)Buffer + Offset, Value, Width);
|
||||
}
|
||||
}
|
||||
VA_END (Args);
|
||||
|
||||
*BufferSize = (UINTN)Offset;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,7 @@ ExtractConfig (
|
|||
|
||||
if (Request == NULL) {
|
||||
FreePool (ConfigRequest);
|
||||
*Progress = NULL;
|
||||
*Progress = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
|
|
@ -873,9 +873,10 @@ ParseIfrData (
|
|||
LengthString = StrLen (GuidStr);
|
||||
LengthString = LengthString + StrLen (NameStr) + 1;
|
||||
TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
|
||||
if (TempStr == NULL) {
|
||||
FreePool (GuidStr);
|
||||
FreePool (NameStr);
|
||||
FreePool (GuidStr);
|
||||
FreePool (NameStr);
|
||||
if (TempStr == NULL) {
|
||||
FreePool (VarStoreName);
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
@ -899,8 +900,6 @@ ParseIfrData (
|
|||
// Free alllocated temp string.
|
||||
//
|
||||
FreePool (TempStr);
|
||||
FreePool (GuidStr);
|
||||
FreePool (NameStr);
|
||||
break;
|
||||
|
||||
case EFI_IFR_DEFAULTSTORE_OP:
|
||||
|
@ -2211,13 +2210,13 @@ HiiConfigRoutingExtractConfig (
|
|||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
//
|
||||
// Not any request block is found.
|
||||
//
|
||||
if (StrStr (ConfigRequest, L"&OFFSET=") == NULL) {
|
||||
//
|
||||
// Not any request block is found.
|
||||
//
|
||||
if (StrStr (ConfigRequest, L"&OFFSET=") == NULL) {
|
||||
AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
|
||||
goto NextConfigString;
|
||||
}
|
||||
goto NextConfigString;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2307,7 +2306,7 @@ NextConfigString:
|
|||
Done:
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (*Results);
|
||||
*Results = NULL;
|
||||
*Results = NULL;
|
||||
}
|
||||
|
||||
if (ConfigRequest != NULL) {
|
||||
|
@ -2964,8 +2963,8 @@ HiiBlockToConfig (
|
|||
|
||||
Exit:
|
||||
if (*Config != NULL) {
|
||||
FreePool (*Config);
|
||||
*Config = NULL;
|
||||
FreePool (*Config);
|
||||
*Config = NULL;
|
||||
}
|
||||
if (ValueStr != NULL) {
|
||||
FreePool (ValueStr);
|
||||
|
|
Loading…
Reference in New Issue