[SETUPLIB][USETUP] Don't store UI-related display strings in GENERIC_LIST_ENTRY-ies, + other code adaptations.

- Apart from allowing a UI cache variable that may be used when
  displaying GENERIC_LIST_ENTRY-ies, do not store any display strings
  associated to these list entries. They should be instead computed only
  when initializing a list UI (or a combo-box or list control if the
  code is used in Win32 environment).
  For this matter a callback is provided to InitGenericListUi() that
  does the job of computing the displayed string corresponding to a
  given GENERIC_LIST_ENTRY.

- Simplify the calls to InitGenericListUi(), and refactor the
  RestoreGenericListUiState() function.

- Use for-loops for iterating over GENERIC_LIST items.

- Adapt the storage data format for lists of settings items.

- The txtsetup.sif INF format specified in LoadSetupInf() should not be
  INF_STYLE_WIN4 (to be investigated...).
This commit is contained in:
Hermès Bélusca-Maïto 2017-12-29 19:09:56 +01:00
parent 765994c9e3
commit 1f4cb0977a
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
10 changed files with 264 additions and 170 deletions

View file

@ -321,10 +321,8 @@ GetComputerIdentifier(
*/
typedef UCHAR
(NTAPI *PPROCESS_ENTRY_ROUTINE)(
IN PWCHAR KeyName,
IN PWCHAR KeyValue,
OUT PWCHAR DisplayText,
IN SIZE_T DisplayTextSize,
IN PCWSTR KeyName,
IN PCWSTR KeyValue,
OUT PVOID* UserData,
OUT PBOOLEAN Current,
IN PVOID Parameter OPTIONAL);
@ -344,7 +342,6 @@ AddEntriesFromInfSection(
PVOID UserData;
BOOLEAN Current;
UCHAR RetVal;
WCHAR DisplayText[128];
if (!SetupFindFirstLineW(InfFile, SectionName, NULL, pContext))
return -1;
@ -374,8 +371,6 @@ AddEntriesFromInfSection(
Current = FALSE;
RetVal = ProcessEntry(KeyName,
KeyValue,
DisplayText,
sizeof(DisplayText),
&UserData,
&Current,
Parameter);
@ -389,7 +384,7 @@ AddEntriesFromInfSection(
}
else if (RetVal == 1)
{
AppendGenericListEntry(List, DisplayText, UserData, Current);
AppendGenericListEntry(List, UserData, Current);
++TotalCount;
}
// else if (RetVal == 2), skip the entry.
@ -402,29 +397,36 @@ AddEntriesFromInfSection(
static UCHAR
NTAPI
DefaultProcessEntry(
IN PWCHAR KeyName,
IN PWCHAR KeyValue,
OUT PWCHAR DisplayText,
IN SIZE_T DisplayTextSize,
IN PCWSTR KeyName,
IN PCWSTR KeyValue,
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)
PGENENTRY GenEntry;
SIZE_T IdSize, ValueSize;
IdSize = (wcslen(KeyName) + 1) * sizeof(WCHAR);
ValueSize = (wcslen(KeyValue) + 1) * sizeof(WCHAR);
GenEntry = RtlAllocateHeap(ProcessHeap, 0,
sizeof(*GenEntry) + IdSize + ValueSize);
if (GenEntry == NULL)
{
/* Failure, stop enumeration */
DPRINT1("RtlAllocateHeap() failed\n");
return 0;
}
wcscpy((PWCHAR)*UserData, KeyName);
RtlStringCbCopyW(DisplayText, DisplayTextSize, KeyValue);
GenEntry->Id = (PCWSTR)((ULONG_PTR)GenEntry + sizeof(*GenEntry));
GenEntry->Value = (PCWSTR)((ULONG_PTR)GenEntry + sizeof(*GenEntry) + IdSize);
RtlStringCbCopyW((PWSTR)GenEntry->Id, IdSize, KeyName);
RtlStringCbCopyW((PWSTR)GenEntry->Value, ValueSize, KeyValue);
*Current = (CompareKey ? !_wcsicmp(KeyName, CompareKey) : FALSE);
*UserData = GenEntry;
*Current = (CompareKey ? !_wcsicmp(KeyName, CompareKey) : FALSE);
/* Add the entry */
return 1;
@ -765,7 +767,7 @@ ProcessComputerFiles(
}
RtlStringCchPrintfW(SectionName, ARRAYSIZE(SectionName),
L"Files.%s", (PCWSTR)GetListEntryUserData(Entry));
L"Files.%s", ((PGENENTRY)GetListEntryData(Entry))->Id);
*AdditionalSectionName = SectionName;
return TRUE;
@ -797,7 +799,9 @@ ProcessDisplayRegistry(
return FALSE;
}
if (!SetupFindFirstLineW(InfFile, L"Display", (WCHAR*)GetListEntryUserData(Entry), &Context))
if (!SetupFindFirstLineW(InfFile, L"Display",
((PGENENTRY)GetListEntryData(Entry))->Id,
&Context))
{
DPRINT1("SetupFindFirstLineW() failed\n");
return FALSE;
@ -936,7 +940,7 @@ ProcessLocaleRegistry(
IN PGENERIC_LIST List)
{
PGENERIC_LIST_ENTRY Entry;
PWCHAR LanguageId;
PCWSTR LanguageId;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
@ -948,7 +952,7 @@ ProcessLocaleRegistry(
if (Entry == NULL)
return FALSE;
LanguageId = (PWCHAR)GetListEntryUserData(Entry);
LanguageId = ((PGENENTRY)GetListEntryData(Entry))->Id;
if (LanguageId == NULL)
return FALSE;
@ -1086,35 +1090,42 @@ typedef struct _LANG_ENTRY_PARAM
static UCHAR
NTAPI
ProcessLangEntry(
IN PWCHAR KeyName,
IN PWCHAR KeyValue,
OUT PWCHAR DisplayText,
IN SIZE_T DisplayTextSize,
IN PCWSTR KeyName,
IN PCWSTR KeyValue,
OUT PVOID* UserData,
OUT PBOOLEAN Current,
IN PVOID Parameter OPTIONAL)
{
PLANG_ENTRY_PARAM LangEntryParam = (PLANG_ENTRY_PARAM)Parameter;
PGENENTRY GenEntry;
SIZE_T IdSize, ValueSize;
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)
IdSize = (wcslen(KeyName) + 1) * sizeof(WCHAR);
ValueSize = (wcslen(KeyValue) + 1) * sizeof(WCHAR);
GenEntry = RtlAllocateHeap(ProcessHeap, 0,
sizeof(*GenEntry) + IdSize + ValueSize);
if (GenEntry == NULL)
{
/* Failure, stop enumeration */
DPRINT1("RtlAllocateHeap() failed\n");
return 0;
}
wcscpy((PWCHAR)*UserData, KeyName);
RtlStringCbCopyW(DisplayText, DisplayTextSize, KeyValue);
GenEntry->Id = (PCWSTR)((ULONG_PTR)GenEntry + sizeof(*GenEntry));
GenEntry->Value = (PCWSTR)((ULONG_PTR)GenEntry + sizeof(*GenEntry) + IdSize);
RtlStringCbCopyW((PWSTR)GenEntry->Id, IdSize, KeyName);
RtlStringCbCopyW((PWSTR)GenEntry->Value, ValueSize, KeyValue);
*Current = FALSE;
*UserData = GenEntry;
*Current = FALSE;
if (!_wcsicmp(KeyName, LangEntryParam->DefaultLanguage))
DefaultLanguageIndex = LangEntryParam->uIndex;
@ -1168,7 +1179,7 @@ CreateLanguageList(
{
DefaultLanguageIndex = 0;
wcscpy(DefaultLanguage,
(PWSTR)GetListEntryUserData(GetFirstListEntry(List)));
((PGENENTRY)GetListEntryData(GetFirstListEntry(List)))->Id);
}
return List;
@ -1239,7 +1250,7 @@ ProcessKeyboardLayoutRegistry(
IN PCWSTR LanguageId)
{
PGENERIC_LIST_ENTRY Entry;
PWCHAR LayoutId;
PCWSTR LayoutId;
const MUI_LAYOUTS* LayoutsList;
MUI_LAYOUTS NewLayoutsList[20];
ULONG uIndex;
@ -1249,7 +1260,7 @@ ProcessKeyboardLayoutRegistry(
if (Entry == NULL)
return FALSE;
LayoutId = (PWCHAR)GetListEntryUserData(Entry);
LayoutId = ((PGENENTRY)GetListEntryData(Entry))->Id;
if (LayoutId == NULL)
return FALSE;

View file

@ -26,6 +26,13 @@
#pragma once
/* Settings entries with simple 1:1 mapping */
typedef struct _GENENTRY
{
PCWSTR Id;
PCWSTR Value;
} GENENTRY, *PGENENTRY;
PGENERIC_LIST
CreateComputerTypeList(
IN HINF InfFile);

View file

@ -516,7 +516,7 @@ LoadSetupInf(
*SetupInf = SetupOpenInfFileExW(FileNameBuffer,
NULL,
INF_STYLE_WIN4 | INF_STYLE_OLDNT,
/* INF_STYLE_WIN4 | */ INF_STYLE_OLDNT,
pSetupData->LanguageId,
&ErrorLine);

View file

@ -27,9 +27,7 @@ CreateGenericList(VOID)
InitializeListHead(&List->ListHead);
List->NumOfEntries = 0;
List->CurrentEntry = NULL;
List->BackupEntry = NULL;
return List;
}
@ -37,7 +35,7 @@ CreateGenericList(VOID)
VOID
DestroyGenericList(
IN OUT PGENERIC_LIST List,
IN BOOLEAN FreeUserData)
IN BOOLEAN FreeData)
{
PGENERIC_LIST_ENTRY ListEntry;
PLIST_ENTRY Entry;
@ -49,8 +47,8 @@ DestroyGenericList(
ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
/* Release user data */
if (FreeUserData && ListEntry->UserData != NULL)
RtlFreeHeap(ProcessHeap, 0, ListEntry->UserData);
if (FreeData && ListEntry->Data != NULL)
RtlFreeHeap(ProcessHeap, 0, ListEntry->Data);
/* Release list entry */
RtlFreeHeap(ProcessHeap, 0, ListEntry);
@ -63,30 +61,24 @@ DestroyGenericList(
BOOLEAN
AppendGenericListEntry(
IN OUT PGENERIC_LIST List,
IN PCWSTR Text,
IN PVOID UserData,
IN PVOID Data,
IN BOOLEAN Current)
{
PGENERIC_LIST_ENTRY Entry;
SIZE_T TextSize;
TextSize = (wcslen(Text) + 1) * sizeof(WCHAR);
Entry = RtlAllocateHeap(ProcessHeap, 0,
sizeof(GENERIC_LIST_ENTRY) + TextSize);
Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(GENERIC_LIST_ENTRY));
if (Entry == NULL)
return FALSE;
RtlStringCbCopyW(Entry->Text, TextSize, Text);
Entry->List = List;
Entry->UserData = UserData;
Entry->Data = Data;
Entry->UiData = 0;
InsertTailList(&List->ListHead, &Entry->Entry);
List->NumOfEntries++;
++List->NumOfEntries;
if (Current || List->CurrentEntry == NULL)
{
List->CurrentEntry = Entry;
}
return TRUE;
}
@ -112,11 +104,10 @@ PGENERIC_LIST_ENTRY
GetFirstListEntry(
IN PGENERIC_LIST List)
{
PLIST_ENTRY Entry = List->ListHead.Flink;
if (Entry == &List->ListHead)
if (IsListEmpty(&List->ListHead))
return NULL;
return CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
return CONTAINING_RECORD(List->ListHead.Flink, GENERIC_LIST_ENTRY, Entry);
}
PGENERIC_LIST_ENTRY
@ -127,21 +118,22 @@ GetNextListEntry(
if (Next == &Entry->List->ListHead)
return NULL;
return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
}
PVOID
GetListEntryUserData(
GetListEntryData(
IN PGENERIC_LIST_ENTRY Entry)
{
return Entry->UserData;
return Entry->Data;
}
PCWSTR
GetListEntryText(
ULONG_PTR
GetListEntryUiData(
IN PGENERIC_LIST_ENTRY Entry)
{
return Entry->Text;
return Entry->UiData;
}
ULONG
@ -151,30 +143,16 @@ GetNumberOfListEntries(
return List->NumOfEntries;
}
VOID
SaveGenericListState(
IN PGENERIC_LIST List)
{
List->BackupEntry = List->CurrentEntry;
}
VOID
RestoreGenericListState(
IN PGENERIC_LIST List)
{
List->CurrentEntry = List->BackupEntry;
}
BOOLEAN
GenericListHasSingleEntry(
IN PGENERIC_LIST List)
{
if (!IsListEmpty(&List->ListHead) && List->ListHead.Flink == List->ListHead.Blink)
return TRUE;
/* if both list head pointers (which normally point to the first and last list member, respectively)
point to the same entry then it means that there's just a single thing in there, otherwise... false! */
return FALSE;
/*
* If both list head pointers (which normally point to the first and last
* list member, respectively) point to the same entry then it means that
* there is just a single thing in there, otherwise... false!
*/
return (!IsListEmpty(&List->ListHead) && (List->ListHead.Flink == List->ListHead.Blink));
}
/* EOF */

View file

@ -11,19 +11,15 @@ typedef struct _GENERIC_LIST_ENTRY
{
LIST_ENTRY Entry;
struct _GENERIC_LIST* List;
PVOID UserData;
WCHAR Text[1]; // FIXME: UI stuff
PVOID Data;
ULONG_PTR UiData; // Cache variable for any UI list that displays these items
} GENERIC_LIST_ENTRY, *PGENERIC_LIST_ENTRY;
typedef struct _GENERIC_LIST
{
LIST_ENTRY ListHead;
ULONG NumOfEntries;
PGENERIC_LIST_ENTRY CurrentEntry;
PGENERIC_LIST_ENTRY BackupEntry;
} GENERIC_LIST, *PGENERIC_LIST;
@ -33,13 +29,12 @@ CreateGenericList(VOID);
VOID
DestroyGenericList(
IN OUT PGENERIC_LIST List,
IN BOOLEAN FreeUserData);
IN BOOLEAN FreeData);
BOOLEAN
AppendGenericListEntry(
IN OUT PGENERIC_LIST List,
IN PCWSTR Text,
IN PVOID UserData,
IN PVOID Data,
IN BOOLEAN Current);
VOID
@ -60,25 +55,17 @@ GetNextListEntry(
IN PGENERIC_LIST_ENTRY Entry);
PVOID
GetListEntryUserData(
GetListEntryData(
IN PGENERIC_LIST_ENTRY Entry);
PCWSTR
GetListEntryText(
ULONG_PTR
GetListEntryUiData(
IN PGENERIC_LIST_ENTRY Entry);
ULONG
GetNumberOfListEntries(
IN PGENERIC_LIST List);
VOID
SaveGenericListState(
IN PGENERIC_LIST List);
VOID
RestoreGenericListState(
IN PGENERIC_LIST List);
BOOLEAN
GenericListHasSingleEntry(
IN PGENERIC_LIST List);