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

View file

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

View file

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

View file

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

View file

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

View file

@ -417,7 +417,7 @@ WriteConsoleOutputCharacterW(
UnicodeString.Length = nLength * sizeof(WCHAR); UnicodeString.Length = nLength * sizeof(WCHAR);
UnicodeString.MaximumLength = nLength * sizeof(WCHAR); UnicodeString.MaximumLength = nLength * sizeof(WCHAR);
UnicodeString.Buffer = (LPWSTR)lpCharacter; UnicodeString.Buffer = (PWSTR)lpCharacter;
OemLength = RtlUnicodeStringToOemSize(&UnicodeString); OemLength = RtlUnicodeStringToOemSize(&UnicodeString);

View file

@ -36,11 +36,15 @@
VOID VOID
InitGenericListUi( InitGenericListUi(
IN OUT PGENERIC_LIST_UI ListUi, IN OUT PGENERIC_LIST_UI ListUi,
IN PGENERIC_LIST List) IN PGENERIC_LIST List,
IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc)
{ {
ListUi->List = List; ListUi->List = List;
ListUi->FirstShown = NULL; ListUi->FirstShown = NULL;
ListUi->LastShown = NULL; ListUi->LastShown = NULL;
ListUi->BackupEntry = NULL;
ListUi->GetEntryDescriptionProc = GetEntryDescriptionProc;
ListUi->Left = 0; ListUi->Left = 0;
ListUi->Top = 0; ListUi->Top = 0;
@ -49,6 +53,16 @@ InitGenericListUi(
ListUi->Redraw = TRUE; ListUi->Redraw = TRUE;
ListUi->CurrentItemText[0] = ANSI_NULL; ListUi->CurrentItemText[0] = ANSI_NULL;
/* SaveGenericListUiState(ListUi); */
ListUi->BackupEntry = ListUi->List->CurrentEntry;
}
VOID
RestoreGenericListUiState(
IN PGENERIC_LIST_UI ListUi)
{
ListUi->List->CurrentEntry = ListUi->BackupEntry;
} }
static static
@ -159,7 +173,13 @@ DrawListEntries(
break; break;
ListUi->LastShown = Entry; ListUi->LastShown = Entry;
sprintf(ListUi->CurrentItemText, "%S", ListEntry->Text); ListUi->CurrentItemText[0] = ANSI_NULL;
if (ListUi->GetEntryDescriptionProc)
{
ListUi->GetEntryDescriptionProc(ListEntry,
ListUi->CurrentItemText,
ARRAYSIZE(ListUi->CurrentItemText));
}
FillConsoleOutputAttribute(StdOutput, FillConsoleOutputAttribute(StdOutput,
(List->CurrentEntry == ListEntry) ? (List->CurrentEntry == ListEntry) ?
@ -329,6 +349,26 @@ DrawGenericList(
DrawScrollBarGenericList(ListUi); DrawScrollBarGenericList(ListUi);
} }
VOID
DrawGenericListCurrentItem(
IN PGENERIC_LIST List,
IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc,
IN SHORT Left,
IN SHORT Top)
{
//
// FIXME: That stuff crashes when the list is empty!!
//
CHAR CurrentItemText[256];
if (GetEntryDescriptionProc)
{
GetEntryDescriptionProc(GetCurrentListEntry(List),
CurrentItemText,
ARRAYSIZE(CurrentItemText));
CONSOLE_SetTextXY(Left, Top, CurrentItemText);
}
}
VOID VOID
ScrollDownGenericList( ScrollDownGenericList(
IN PGENERIC_LIST_UI ListUi) IN PGENERIC_LIST_UI ListUi)
@ -493,7 +533,13 @@ GenericListKeyPress(
ListUi->Redraw = FALSE; ListUi->Redraw = FALSE;
sprintf(ListUi->CurrentItemText, "%S", ListEntry->Text); ListUi->CurrentItemText[0] = ANSI_NULL;
if (ListUi->GetEntryDescriptionProc)
{
ListUi->GetEntryDescriptionProc(ListEntry,
ListUi->CurrentItemText,
ARRAYSIZE(ListUi->CurrentItemText));
}
if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar) && if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar) &&
(List->CurrentEntry->Entry.Flink != &List->ListHead)) (List->CurrentEntry->Entry.Flink != &List->ListHead))
@ -501,7 +547,13 @@ GenericListKeyPress(
ScrollDownGenericList(ListUi); ScrollDownGenericList(ListUi);
ListEntry = List->CurrentEntry; ListEntry = List->CurrentEntry;
sprintf(ListUi->CurrentItemText, "%S", ListEntry->Text); ListUi->CurrentItemText[0] = ANSI_NULL;
if (ListUi->GetEntryDescriptionProc)
{
ListUi->GetEntryDescriptionProc(ListEntry,
ListUi->CurrentItemText,
ARRAYSIZE(ListUi->CurrentItemText));
}
if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar)) if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar))
goto End; goto End;
@ -514,7 +566,13 @@ GenericListKeyPress(
for (;;) for (;;)
{ {
sprintf(ListUi->CurrentItemText, "%S", ListEntry->Text); ListUi->CurrentItemText[0] = ANSI_NULL;
if (ListUi->GetEntryDescriptionProc)
{
ListUi->GetEntryDescriptionProc(ListEntry,
ListUi->CurrentItemText,
ARRAYSIZE(ListUi->CurrentItemText));
}
if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar)) if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar))
{ {

View file

@ -28,12 +28,21 @@
// #include "../lib/utils/genlist.h" // #include "../lib/utils/genlist.h"
typedef NTSTATUS
(NTAPI *PGET_ENTRY_DESCRIPTION)(
IN PGENERIC_LIST_ENTRY Entry,
OUT PSTR Buffer,
IN SIZE_T cchBufferSize);
typedef struct _GENERIC_LIST_UI typedef struct _GENERIC_LIST_UI
{ {
PGENERIC_LIST List; PGENERIC_LIST List;
PLIST_ENTRY FirstShown; PLIST_ENTRY FirstShown;
PLIST_ENTRY LastShown; PLIST_ENTRY LastShown;
PGENERIC_LIST_ENTRY BackupEntry;
PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc;
SHORT Left; SHORT Left;
SHORT Top; SHORT Top;
@ -48,7 +57,12 @@ typedef struct _GENERIC_LIST_UI
VOID VOID
InitGenericListUi( InitGenericListUi(
IN OUT PGENERIC_LIST_UI ListUi, IN OUT PGENERIC_LIST_UI ListUi,
IN PGENERIC_LIST List); IN PGENERIC_LIST List,
IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc);
VOID
RestoreGenericListUiState(
IN PGENERIC_LIST_UI ListUi);
VOID VOID
DrawGenericList( DrawGenericList(
@ -58,6 +72,13 @@ DrawGenericList(
IN SHORT Right, IN SHORT Right,
IN SHORT Bottom); IN SHORT Bottom);
VOID
DrawGenericListCurrentItem(
IN PGENERIC_LIST List,
IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc,
IN SHORT Left,
IN SHORT Top);
VOID VOID
ScrollDownGenericList( ScrollDownGenericList(
IN PGENERIC_LIST_UI ListUi); IN PGENERIC_LIST_UI ListUi);

View file

@ -56,7 +56,7 @@ static WCHAR DestinationDriveLetter;
/* OTHER Stuff *****/ /* OTHER Stuff *****/
PWCHAR SelectedLanguageId; PCWSTR SelectedLanguageId;
static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList
static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList
@ -414,25 +414,63 @@ UpdateKBLayout(VOID)
} }
} }
ListEntry = GetFirstListEntry(LayoutList);
/* Search for default layout (if provided) */ /* Search for default layout (if provided) */
if (pszNewLayout != NULL) if (pszNewLayout != NULL)
{ {
while (ListEntry != NULL) for (ListEntry = GetFirstListEntry(LayoutList); ListEntry;
ListEntry = GetNextListEntry(ListEntry))
{ {
if (!wcscmp(pszNewLayout, GetListEntryUserData(ListEntry))) if (!wcscmp(pszNewLayout, ((PGENENTRY)GetListEntryData(ListEntry))->Id))
{ {
SetCurrentListEntry(LayoutList, ListEntry); SetCurrentListEntry(LayoutList, ListEntry);
break; break;
} }
ListEntry = GetNextListEntry(ListEntry);
} }
} }
} }
static NTSTATUS
NTAPI
GetSettingDescription(
IN PGENERIC_LIST_ENTRY Entry,
OUT PSTR Buffer,
IN SIZE_T cchBufferSize)
{
return RtlStringCchPrintfA(Buffer, cchBufferSize, "%S",
((PGENENTRY)GetListEntryData(Entry))->Value);
}
static NTSTATUS
NTAPI
GetNTOSInstallationName(
IN PGENERIC_LIST_ENTRY Entry,
OUT PSTR Buffer,
IN SIZE_T cchBufferSize)
{
PNTOS_INSTALLATION NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry);
PPARTENTRY PartEntry = NtOsInstall->PartEntry;
if (PartEntry && PartEntry->DriveLetter)
{
/* We have retrieved a partition that is mounted */
return RtlStringCchPrintfA(Buffer, cchBufferSize,
"%c:%S \"%S\"",
PartEntry->DriveLetter,
NtOsInstall->PathComponent,
NtOsInstall->InstallationName);
}
else
{
/* We failed somewhere, just show the NT path */
return RtlStringCchPrintfA(Buffer, cchBufferSize,
"%wZ \"%S\"",
&NtOsInstall->SystemNtPath,
NtOsInstall->InstallationName);
}
}
/* /*
* Displays the LanguagePage. * Displays the LanguagePage.
* *
@ -449,7 +487,7 @@ static PAGE_NUMBER
LanguagePage(PINPUT_RECORD Ir) LanguagePage(PINPUT_RECORD Ir)
{ {
GENERIC_LIST_UI ListUi; GENERIC_LIST_UI ListUi;
PWCHAR NewLanguageId; PCWSTR NewLanguageId;
BOOL RefreshPage = FALSE; BOOL RefreshPage = FALSE;
/* Initialize the computer settings list */ /* Initialize the computer settings list */
@ -478,10 +516,9 @@ LanguagePage(PINPUT_RECORD Ir)
return WELCOME_PAGE; return WELCOME_PAGE;
} }
InitGenericListUi(&ListUi, LanguageList); InitGenericListUi(&ListUi, LanguageList, GetSettingDescription);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 2, 18,
18,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
@ -527,7 +564,11 @@ LanguagePage(PINPUT_RECORD Ir)
} }
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{ {
SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList)); //
// FIXME: That stuff crashes when the list is empty!!
//
SelectedLanguageId =
((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id;
USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
@ -550,7 +591,11 @@ LanguagePage(PINPUT_RECORD Ir)
if (RefreshPage) if (RefreshPage)
{ {
NewLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList)); //
// FIXME: That stuff crashes when the list is empty!!
//
NewLanguageId =
((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id;
if (wcscmp(SelectedLanguageId, NewLanguageId)) if (wcscmp(SelectedLanguageId, NewLanguageId))
{ {
@ -603,6 +648,7 @@ SetupStartPage(PINPUT_RECORD Ir)
NTSTATUS Status; NTSTATUS Status;
ULONG Error; ULONG Error;
PGENERIC_LIST_ENTRY ListEntry; PGENERIC_LIST_ENTRY ListEntry;
PCWSTR LocaleId;
CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
@ -640,6 +686,8 @@ SetupStartPage(PINPUT_RECORD Ir)
if (IsUnattendedSetup) if (IsUnattendedSetup)
{ {
// TODO: Read options from inf // TODO: Read options from inf
/* Load the hardware, language and keyboard layout lists */
ComputerList = CreateComputerTypeList(SetupInf); ComputerList = CreateComputerTypeList(SetupInf);
DisplayList = CreateDisplayDriverList(SetupInf); DisplayList = CreateDisplayDriverList(SetupInf);
KeyboardList = CreateKeyboardDriverList(SetupInf); KeyboardList = CreateKeyboardDriverList(SetupInf);
@ -648,37 +696,35 @@ SetupStartPage(PINPUT_RECORD Ir)
/* new part */ /* new part */
SelectedLanguageId = DefaultLanguage; SelectedLanguageId = DefaultLanguage;
wcscpy(SelectedLanguageId, USetupData.LocaleID); wcscpy(DefaultLanguage, USetupData.LocaleID);
USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout); LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout);
/* first we hack LanguageList */ /* first we hack LanguageList */
ListEntry = GetFirstListEntry(LanguageList); for (ListEntry = GetFirstListEntry(LanguageList); ListEntry;
while (ListEntry != NULL) ListEntry = GetNextListEntry(ListEntry))
{ {
if (!wcsicmp(USetupData.LocaleID, GetListEntryUserData(ListEntry))) LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
if (!wcsicmp(USetupData.LocaleID, LocaleId))
{ {
DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry)); DPRINT("found %S in LanguageList\n", LocaleId);
SetCurrentListEntry(LanguageList, ListEntry); SetCurrentListEntry(LanguageList, ListEntry);
break; break;
} }
ListEntry = GetNextListEntry(ListEntry);
} }
/* now LayoutList */ /* now LayoutList */
ListEntry = GetFirstListEntry(LayoutList); for (ListEntry = GetFirstListEntry(LayoutList); ListEntry;
while (ListEntry != NULL) ListEntry = GetNextListEntry(ListEntry))
{ {
if (!wcsicmp(USetupData.LocaleID, GetListEntryUserData(ListEntry))) LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id;
if (!wcsicmp(USetupData.LocaleID, LocaleId))
{ {
DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry)); DPRINT("found %S in LayoutList\n", LocaleId);
SetCurrentListEntry(LayoutList, ListEntry); SetCurrentListEntry(LayoutList, ListEntry);
break; break;
} }
ListEntry = GetNextListEntry(ListEntry);
} }
SetConsoleCodePage(); SetConsoleCodePage();
@ -862,14 +908,12 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
MUIDisplayPage(UPGRADE_REPAIR_PAGE); MUIDisplayPage(UPGRADE_REPAIR_PAGE);
InitGenericListUi(&ListUi, NtOsInstallsList); InitGenericListUi(&ListUi, NtOsInstallsList, GetNTOSInstallationName);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 23, 2, 23,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
SaveGenericListState(NtOsInstallsList);
// return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
while (TRUE) while (TRUE)
{ {
@ -901,7 +945,7 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
} }
case VK_ESCAPE: /* ESC */ case VK_ESCAPE: /* ESC */
{ {
RestoreGenericListState(NtOsInstallsList); RestoreGenericListUiState(&ListUi);
// return nextPage; // prevPage; // return nextPage; // prevPage;
// return INSTALL_INTRO_PAGE; // return INSTALL_INTRO_PAGE;
@ -917,7 +961,12 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */ if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
{ {
/* Retrieve the current installation */ /* Retrieve the current installation */
CurrentInstallation = (PNTOS_INSTALLATION)GetListEntryUserData(GetCurrentListEntry(NtOsInstallsList)); //
// FIXME: That stuff crashes when the list is empty!!
//
CurrentInstallation =
(PNTOS_INSTALLATION)GetListEntryData(GetCurrentListEntry(NtOsInstallsList));
DPRINT1("Selected installation for repair: \"%S\" ; DiskNumber = %d , PartitionNumber = %d\n", DPRINT1("Selected installation for repair: \"%S\" ; DiskNumber = %d , PartitionNumber = %d\n",
CurrentInstallation->InstallationName, CurrentInstallation->DiskNumber, CurrentInstallation->PartitionNumber); CurrentInstallation->InstallationName, CurrentInstallation->DiskNumber, CurrentInstallation->PartitionNumber);
@ -1090,7 +1139,6 @@ static PAGE_NUMBER
DeviceSettingsPage(PINPUT_RECORD Ir) DeviceSettingsPage(PINPUT_RECORD Ir)
{ {
static ULONG Line = 16; static ULONG Line = 16;
CHAR CurrentItemText[256];
/* Initialize the computer settings list */ /* Initialize the computer settings list */
if (ComputerList == NULL) if (ComputerList == NULL)
@ -1145,14 +1193,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
MUIDisplayPage(DEVICE_SETTINGS_PAGE); MUIDisplayPage(DEVICE_SETTINGS_PAGE);
sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(ComputerList))); DrawGenericListCurrentItem(ComputerList, GetSettingDescription, 25, 11);
CONSOLE_SetTextXY(25, 11, CurrentItemText); DrawGenericListCurrentItem(DisplayList , GetSettingDescription, 25, 12);
sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(DisplayList))); DrawGenericListCurrentItem(KeyboardList, GetSettingDescription, 25, 13);
CONSOLE_SetTextXY(25, 12, CurrentItemText); DrawGenericListCurrentItem(LayoutList , GetSettingDescription, 25, 14);
sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(KeyboardList)));
CONSOLE_SetTextXY(25, 13, CurrentItemText);
sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(LayoutList)));
CONSOLE_SetTextXY(25, 14, CurrentItemText);
CONSOLE_InvertTextXY(24, Line, 48, 1); CONSOLE_InvertTextXY(24, Line, 48, 1);
@ -1263,7 +1307,7 @@ HandleGenericList(PGENERIC_LIST_UI ListUi,
else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
(Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */ (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
{ {
RestoreGenericListState(ListUi->List); RestoreGenericListUiState(ListUi);
return nextPage; // Use some "prevPage;" instead? return nextPage; // Use some "prevPage;" instead?
} }
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
@ -1295,15 +1339,12 @@ ComputerSettingsPage(PINPUT_RECORD Ir)
GENERIC_LIST_UI ListUi; GENERIC_LIST_UI ListUi;
MUIDisplayPage(COMPUTER_SETTINGS_PAGE); MUIDisplayPage(COMPUTER_SETTINGS_PAGE);
InitGenericListUi(&ListUi, ComputerList); InitGenericListUi(&ListUi, ComputerList, GetSettingDescription);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 2, 18,
18,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
SaveGenericListState(ComputerList);
return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
} }
@ -1324,15 +1365,12 @@ DisplaySettingsPage(PINPUT_RECORD Ir)
GENERIC_LIST_UI ListUi; GENERIC_LIST_UI ListUi;
MUIDisplayPage(DISPLAY_SETTINGS_PAGE); MUIDisplayPage(DISPLAY_SETTINGS_PAGE);
InitGenericListUi(&ListUi, DisplayList); InitGenericListUi(&ListUi, DisplayList, GetSettingDescription);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 2, 18,
18,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
SaveGenericListState(DisplayList);
return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
} }
@ -1353,15 +1391,12 @@ KeyboardSettingsPage(PINPUT_RECORD Ir)
GENERIC_LIST_UI ListUi; GENERIC_LIST_UI ListUi;
MUIDisplayPage(KEYBOARD_SETTINGS_PAGE); MUIDisplayPage(KEYBOARD_SETTINGS_PAGE);
InitGenericListUi(&ListUi, KeyboardList); InitGenericListUi(&ListUi, KeyboardList, GetSettingDescription);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 2, 18,
18,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
SaveGenericListState(KeyboardList);
return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
} }
@ -1382,15 +1417,12 @@ LayoutSettingsPage(PINPUT_RECORD Ir)
GENERIC_LIST_UI ListUi; GENERIC_LIST_UI ListUi;
MUIDisplayPage(LAYOUT_SETTINGS_PAGE); MUIDisplayPage(LAYOUT_SETTINGS_PAGE);
InitGenericListUi(&ListUi, LayoutList); InitGenericListUi(&ListUi, LayoutList, GetSettingDescription);
DrawGenericList(&ListUi, DrawGenericList(&ListUi,
2, 2, 18,
18,
xScreen - 3, xScreen - 3,
yScreen - 3); yScreen - 3);
SaveGenericListState(LayoutList);
return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
} }

View file

@ -72,7 +72,7 @@
extern HANDLE ProcessHeap; extern HANDLE ProcessHeap;
extern BOOLEAN IsUnattendedSetup; extern BOOLEAN IsUnattendedSetup;
extern PWCHAR SelectedLanguageId; extern PCWSTR SelectedLanguageId;
typedef enum _PAGE_NUMBER typedef enum _PAGE_NUMBER
{ {