https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8f2c4f7a6dfed20dc8874…
commit 8f2c4f7a6dfed20dc887471b20a40528653edfa2
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Aug 28 14:01:30 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Oct 27 18:13:45 2018 +0200
[USETUP] Add an AddEntriesFromInfSection() helper that enumerates the entries of a
given INF section, and adds these into a (user-allocated) GENERIC_LIST after some
pre-processing.
This helper is inspired by the reactos/reactos.c!LoadGenEntry() function.
Use this helper in the different Create*List() functions.
svn path=/branches/setup_improvements/; revision=75700
---
base/setup/usetup/settings.c | 405 +++++++++++++++++++++++--------------------
1 file changed, 216 insertions(+), 189 deletions(-)
diff --git a/base/setup/usetup/settings.c b/base/setup/usetup/settings.c
index 2866c53b18..c36f5eff89 100644
--- a/base/setup/usetup/settings.c
+++ b/base/setup/usetup/settings.c
@@ -307,16 +307,132 @@ GetComputerIdentifier(
}
+/*
+ * Return values:
+ * 0x00: Failure, stop the enumeration;
+ * 0x01: Add the entry and continue the enumeration;
+ * 0x02: Skip the entry but continue the enumeration.
+ */
+typedef UCHAR
+(NTAPI *PPROCESS_ENTRY_ROUTINE)(
+ IN PWCHAR KeyName,
+ IN PWCHAR KeyValue,
+ IN PCHAR DisplayText,
+ IN SIZE_T DisplayTextSize,
+ OUT PVOID* UserData,
+ OUT PBOOLEAN Current,
+ IN PVOID Parameter OPTIONAL);
+
+LONG
+AddEntriesFromInfSection(
+ IN OUT PGENERIC_LIST List,
+ IN HINF InfFile,
+ IN PCWSTR SectionName,
+ IN PINFCONTEXT pContext,
+ IN PPROCESS_ENTRY_ROUTINE ProcessEntry,
+ IN PVOID Parameter OPTIONAL)
+{
+ LONG TotalCount = 0;
+ PWCHAR KeyName;
+ PWCHAR KeyValue;
+ PVOID UserData;
+ BOOLEAN Current;
+ UCHAR RetVal;
+ CHAR DisplayText[128];
+
+ if (!SetupFindFirstLineW(InfFile, SectionName, NULL, pContext))
+ return -1;
+
+ do
+ {
+ /*
+ * NOTE: Do not use INF_GetData() as it expects INF entries of exactly
+ * two fields ("key = value"); however we expect to be able to deal
with
+ * entries having more than two fields, the only requirement being that
+ * the second field (field number 1) contains the field description.
+ */
+ if (!INF_GetDataField(pContext, 0, &KeyName))
+ {
+ DPRINT("INF_GetDataField() failed\n");
+ return -1;
+ }
+
+ if (!INF_GetDataField(pContext, 1, &KeyValue))
+ {
+ DPRINT("INF_GetDataField() failed\n");
+ INF_FreeData(KeyName);
+ return -1;
+ }
+
+ UserData = NULL;
+ Current = FALSE;
+ RetVal = ProcessEntry(KeyName,
+ KeyValue,
+ DisplayText,
+ sizeof(DisplayText),
+ &UserData,
+ &Current,
+ Parameter);
+ INF_FreeData(KeyName);
+ INF_FreeData(KeyValue);
+
+ if (RetVal == 0)
+ {
+ DPRINT("ProcessEntry() failed\n");
+ return -1;
+ }
+ else if (RetVal == 1)
+ {
+ AppendGenericListEntry(List, DisplayText, UserData, Current);
+ ++TotalCount;
+ }
+ // else if (RetVal == 2), skip the entry.
+
+ } while (SetupFindNextLine(pContext, pContext));
+
+ return TotalCount;
+}
+
+static UCHAR
+NTAPI
+DefaultProcessEntry(
+ IN PWCHAR KeyName,
+ IN PWCHAR KeyValue,
+ IN PCHAR DisplayText,
+ IN SIZE_T DisplayTextSize,
+ OUT PVOID* UserData,
+ OUT PBOOLEAN Current,
+ IN PVOID Parameter OPTIONAL)
+{
+ PWSTR CompareKey = (PWSTR)Parameter;
+
+ *UserData = RtlAllocateHeap(ProcessHeap, 0,
+ (wcslen(KeyName) + 1) * sizeof(WCHAR));
+ if (*UserData == NULL)
+ {
+ /* Failure, stop enumeration */
+ DPRINT1("RtlAllocateHeap() failed\n");
+ return 0;
+ }
+
+ wcscpy((PWCHAR)*UserData, KeyName);
+ sprintf(DisplayText, "%S", KeyValue);
+
+ *Current = (CompareKey ? !_wcsicmp(KeyName, CompareKey) : FALSE);
+
+ /* Add the entry */
+ return 1;
+}
+
+
PGENERIC_LIST
CreateComputerTypeList(
HINF InfFile)
{
- CHAR Buffer[128];
PGENERIC_LIST List;
INFCONTEXT Context;
PWCHAR KeyName;
PWCHAR KeyValue;
- PWCHAR UserData;
WCHAR ComputerIdentifier[128];
WCHAR ComputerKey[32];
@@ -369,39 +485,17 @@ CreateComputerTypeList(
if (List == NULL)
return NULL;
- if (!SetupFindFirstLineW(InfFile, L"Computer", NULL, &Context))
+ if (AddEntriesFromInfSection(List,
+ InfFile,
+ L"Computer",
+ &Context,
+ DefaultProcessEntry,
+ ComputerKey) == -1)
{
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}
- do
- {
- if (!INF_GetData(&Context, &KeyName, &KeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT("INF_GetData() failed\n");
- break;
- }
-
- UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
- 0,
- (wcslen(KeyName) + 1) * sizeof(WCHAR));
- if (UserData == NULL)
- {
- /* FIXME: Handle error! */
- }
-
- wcscpy(UserData, KeyName);
- INF_FreeData(KeyName);
-
- sprintf(Buffer, "%S", KeyValue);
- INF_FreeData(KeyValue);
-
- AppendGenericListEntry(List, Buffer, UserData,
- _wcsicmp(UserData, ComputerKey) ? FALSE : TRUE);
- } while (SetupFindNextLine(&Context, &Context));
-
return List;
}
@@ -533,9 +627,9 @@ GetDisplayIdentifier(
DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);
BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR),
IdentifierLength);
- RtlCopyMemory (Identifier,
- ValueInfo->Data,
- BufferLength * sizeof(WCHAR));
+ RtlCopyMemory(Identifier,
+ ValueInfo->Data,
+ BufferLength * sizeof(WCHAR));
Identifier[BufferLength] = 0;
RtlFreeHeap(RtlGetProcessHeap(),
@@ -571,12 +665,10 @@ PGENERIC_LIST
CreateDisplayDriverList(
HINF InfFile)
{
- CHAR Buffer[128];
PGENERIC_LIST List;
INFCONTEXT Context;
PWCHAR KeyName;
PWCHAR KeyValue;
- PWCHAR UserData;
WCHAR DisplayIdentifier[128];
WCHAR DisplayKey[32];
@@ -629,49 +721,17 @@ CreateDisplayDriverList(
if (List == NULL)
return NULL;
- if (!SetupFindFirstLineW(InfFile, L"Display", NULL, &Context))
+ if (AddEntriesFromInfSection(List,
+ InfFile,
+ L"Display",
+ &Context,
+ DefaultProcessEntry,
+ DisplayKey) == -1)
{
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}
- do
- {
- if (!INF_GetDataField(&Context, 0, &KeyName))
- {
- DPRINT1("INF_GetDataField() failed\n");
- break;
- }
-
- if (!INF_GetDataField(&Context, 1, &KeyValue))
- {
- DPRINT1("INF_GetDataField() failed\n");
- INF_FreeData(KeyName);
- break;
- }
-
- UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
- 0,
- (wcslen(KeyName) + 1) * sizeof(WCHAR));
- if (UserData == NULL)
- {
- DPRINT1("RtlAllocateHeap() failed\n");
- DestroyGenericList(List, TRUE);
- INF_FreeData(KeyValue);
- INF_FreeData(KeyName);
- return NULL;
- }
-
- wcscpy(UserData, KeyName);
- INF_FreeData(KeyName);
-
- sprintf(Buffer, "%S", KeyValue);
- INF_FreeData(KeyValue);
-
- AppendGenericListEntry(List, Buffer, UserData,
- _wcsicmp(UserData, DisplayKey) ? FALSE : TRUE);
- } while (SetupFindNextLine(&Context, &Context));
-
#if 0
AppendGenericListEntry(List, "Other display driver", NULL, TRUE);
#endif
@@ -981,46 +1041,24 @@ PGENERIC_LIST
CreateKeyboardDriverList(
HINF InfFile)
{
- CHAR Buffer[128];
PGENERIC_LIST List;
INFCONTEXT Context;
- PWCHAR KeyName;
- PWCHAR KeyValue;
- PWCHAR UserData;
List = CreateGenericList();
if (List == NULL)
return NULL;
- if (!SetupFindFirstLineW(InfFile, L"Keyboard", NULL, &Context))
+ if (AddEntriesFromInfSection(List,
+ InfFile,
+ L"Keyboard",
+ &Context,
+ DefaultProcessEntry,
+ NULL) == -1)
{
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}
- do
- {
- if (!INF_GetData(&Context, &KeyName, &KeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT("INF_GetData() failed\n");
- break;
- }
-
- UserData = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (wcslen(KeyName) + 1) * sizeof(WCHAR));
- if (UserData == NULL)
- {
- /* FIXME: Handle error! */
- }
-
- wcscpy(UserData, KeyName);
-
- sprintf(Buffer, "%S", KeyValue);
- AppendGenericListEntry(List, Buffer, UserData, FALSE);
- } while (SetupFindNextLine(&Context, &Context));
-
return List;
}
@@ -1030,18 +1068,67 @@ GetDefaultLanguageIndex(VOID)
return DefaultLanguageIndex;
}
+typedef struct _LANG_ENTRY_PARAM
+{
+ ULONG uIndex;
+ PWCHAR DefaultLanguage;
+} LANG_ENTRY_PARAM, *PLANG_ENTRY_PARAM;
+
+static UCHAR
+NTAPI
+ProcessLangEntry(
+ IN PWCHAR KeyName,
+ IN PWCHAR KeyValue,
+ IN PCHAR DisplayText,
+ IN SIZE_T DisplayTextSize,
+ OUT PVOID* UserData,
+ OUT PBOOLEAN Current,
+ IN PVOID Parameter OPTIONAL)
+{
+ PLANG_ENTRY_PARAM LangEntryParam = (PLANG_ENTRY_PARAM)Parameter;
+
+ if (!IsLanguageAvailable(KeyName))
+ {
+ /* The specified language is unavailable, skip the entry */
+ return 2;
+ }
+
+ *UserData = RtlAllocateHeap(ProcessHeap, 0,
+ (wcslen(KeyName) + 1) * sizeof(WCHAR));
+ if (*UserData == NULL)
+ {
+ /* Failure, stop enumeration */
+ DPRINT1("RtlAllocateHeap() failed\n");
+ return 0;
+ }
+
+ wcscpy((PWCHAR)*UserData, KeyName);
+ sprintf(DisplayText, "%S", KeyValue);
+
+ *Current = FALSE;
+
+ if (!_wcsicmp(KeyName, LangEntryParam->DefaultLanguage))
+ DefaultLanguageIndex = LangEntryParam->uIndex;
+
+ LangEntryParam->uIndex++;
+
+ /* Add the entry */
+ return 1;
+}
+
PGENERIC_LIST
CreateLanguageList(
HINF InfFile,
WCHAR *DefaultLanguage)
{
- CHAR Buffer[128];
PGENERIC_LIST List;
INFCONTEXT Context;
- PWCHAR KeyName;
PWCHAR KeyValue;
- PWCHAR UserData = NULL;
- ULONG uIndex = 0;
+
+ LANG_ENTRY_PARAM LangEntryParam;
+
+ LangEntryParam.uIndex = 0;
+ LangEntryParam.DefaultLanguage = DefaultLanguage;
/* Get default language id */
if (!SetupFindFirstLineW(InfFile, L"NLS", L"DefaultLanguage",
&Context))
@@ -1051,58 +1138,29 @@ CreateLanguageList(
return NULL;
wcscpy(DefaultLanguage, KeyValue);
-
SelectedLanguageId = KeyValue;
List = CreateGenericList();
if (List == NULL)
return NULL;
- if (!SetupFindFirstLineW(InfFile, L"Language", NULL, &Context))
+ if (AddEntriesFromInfSection(List,
+ InfFile,
+ L"Language",
+ &Context,
+ ProcessLangEntry,
+ &LangEntryParam) == -1)
{
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}
- do
- {
- if (!INF_GetData(&Context, &KeyName, &KeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT("INF_GetData() failed\n");
- break;
- }
-
- if (IsLanguageAvailable(KeyName))
- {
-
- UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap,
- 0,
- (wcslen(KeyName) + 1) * sizeof(WCHAR));
- if (UserData == NULL)
- {
- /* FIXME: Handle error! */
- }
-
- wcscpy(UserData, KeyName);
-
- if (!_wcsicmp(KeyName, DefaultLanguage))
- DefaultLanguageIndex = uIndex;
-
- sprintf(Buffer, "%S", KeyValue);
- AppendGenericListEntry(List,
- Buffer,
- UserData,
- FALSE);
- uIndex++;
- }
- } while (SetupFindNextLine(&Context, &Context));
-
/* Only one language available, make it the default one */
- if (uIndex == 1 && UserData != NULL)
+ if (LangEntryParam.uIndex == 1)
{
DefaultLanguageIndex = 0;
- wcscpy(DefaultLanguage, UserData);
+ wcscpy(DefaultLanguage,
+ (PWSTR)GetListEntryUserData(GetFirstListEntry(List)));
}
return List;
@@ -1113,15 +1171,11 @@ CreateKeyboardLayoutList(
HINF InfFile,
WCHAR *DefaultKBLayout)
{
- CHAR Buffer[128];
PGENERIC_LIST List;
INFCONTEXT Context;
- PWCHAR KeyName;
PWCHAR KeyValue;
- PWCHAR UserData;
const MUI_LAYOUTS * LayoutsList;
ULONG uIndex = 0;
- BOOL KeyboardLayoutsFound = FALSE;
/* Get default layout id */
if (!SetupFindFirstLineW(InfFile, L"NLS", L"DefaultLayout",
&Context))
@@ -1140,55 +1194,28 @@ CreateKeyboardLayoutList(
do
{
- if (!SetupFindFirstLineW(InfFile, L"KeyboardLayout", NULL,
&Context))
+ // NOTE: See
https://svn.reactos.org/svn/reactos?view=revision&revision=68354
+ if (AddEntriesFromInfSection(List,
+ InfFile,
+ L"KeyboardLayout",
+ &Context,
+ DefaultProcessEntry,
+ DefaultKBLayout) == -1)
{
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}
- do
- {
- if (!INF_GetData(&Context, &KeyName, &KeyValue))
- {
- /* FIXME: Handle error! */
- DPRINT("INF_GetData() failed\n");
- DestroyGenericList(List, FALSE);
- return NULL;
- }
-
- {
- UserData = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (wcslen(KeyName) + 1) *
sizeof(WCHAR));
- if (UserData == NULL)
- {
- /* FIXME: Handle error! */
- DPRINT("RtlAllocateHeap() failed\n");
- DestroyGenericList(List, FALSE);
- return NULL;
- }
-
- wcscpy(UserData, KeyName);
-
- sprintf(Buffer, "%S", KeyValue);
- AppendGenericListEntry(List,
- Buffer,
- UserData,
- _wcsicmp(KeyName, DefaultKBLayout) ? FALSE :
TRUE);
- KeyboardLayoutsFound = TRUE;
- }
-
- } while (SetupFindNextLine(&Context, &Context));
-
uIndex++;
} while (LayoutsList[uIndex].LangID != NULL);
+ /* Check whether some keyboard layouts have been found */
/* FIXME: Handle this case */
- if (!KeyboardLayoutsFound)
+ if (GetNumberOfListEntries(List) == 0)
{
DPRINT1("No keyboard layouts have been found\n");
- DestroyGenericList(List, FALSE);
+ DestroyGenericList(List, TRUE);
return NULL;
}