[SETUPLIB][USETUP] Don't store UI-related display strings in GENERIC_LIST_ENTRY-ies...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 29 Dec 2017 18:09:56 +0000 (19:09 +0100)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 27 Oct 2018 23:32:15 +0000 (01:32 +0200)
- 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...).

base/setup/lib/settings.c
base/setup/lib/settings.h
base/setup/lib/setuplib.c
base/setup/lib/utils/genlist.c
base/setup/lib/utils/genlist.h
base/setup/usetup/console.c
base/setup/usetup/genlist.c
base/setup/usetup/genlist.h
base/setup/usetup/usetup.c
base/setup/usetup/usetup.h

index 060c671..f0a5200 100644 (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;
 
index ce66383..9c46123 100644 (file)
 
 #pragma once
 
+/* Settings entries with simple 1:1 mapping */
+typedef struct _GENENTRY
+{
+    PCWSTR Id;
+    PCWSTR Value;
+} GENENTRY, *PGENENTRY;
+
 PGENERIC_LIST
 CreateComputerTypeList(
     IN HINF InfFile);
index 2d9a6bb..aba1533 100644 (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);
 
index 209da60..a322914 100644 (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 */
index ca8696d..5d145a4 100644 (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);
index 14a0564..ec73f38 100644 (file)
@@ -417,7 +417,7 @@ WriteConsoleOutputCharacterW(
 
     UnicodeString.Length = nLength * sizeof(WCHAR);
     UnicodeString.MaximumLength = nLength * sizeof(WCHAR);
-    UnicodeString.Buffer = (LPWSTR)lpCharacter;
+    UnicodeString.Buffer = (PWSTR)lpCharacter;
 
     OemLength = RtlUnicodeStringToOemSize(&UnicodeString);
 
index d0b7a63..8e8baff 100644 (file)
 VOID
 InitGenericListUi(
     IN OUT PGENERIC_LIST_UI ListUi,
-    IN PGENERIC_LIST List)
+    IN PGENERIC_LIST List,
+    IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc)
 {
     ListUi->List = List;
     ListUi->FirstShown = NULL;
     ListUi->LastShown = NULL;
+    ListUi->BackupEntry = NULL;
+
+    ListUi->GetEntryDescriptionProc = GetEntryDescriptionProc;
 
     ListUi->Left = 0;
     ListUi->Top = 0;
@@ -49,6 +53,16 @@ InitGenericListUi(
     ListUi->Redraw = TRUE;
 
     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
@@ -159,7 +173,13 @@ DrawListEntries(
             break;
         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,
                                    (List->CurrentEntry == ListEntry) ?
@@ -329,6 +349,26 @@ DrawGenericList(
     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
 ScrollDownGenericList(
     IN PGENERIC_LIST_UI ListUi)
@@ -493,7 +533,13 @@ GenericListKeyPress(
 
     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) &&
          (List->CurrentEntry->Entry.Flink != &List->ListHead))
@@ -501,7 +547,13 @@ GenericListKeyPress(
         ScrollDownGenericList(ListUi);
         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))
             goto End;
@@ -514,7 +566,13 @@ GenericListKeyPress(
 
     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))
         {
index 5e85800..80aa867 100644 (file)
 
 // #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
 {
     PGENERIC_LIST List;
 
     PLIST_ENTRY FirstShown;
     PLIST_ENTRY LastShown;
+    PGENERIC_LIST_ENTRY BackupEntry;
+
+    PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc;
 
     SHORT Left;
     SHORT Top;
@@ -48,7 +57,12 @@ typedef struct _GENERIC_LIST_UI
 VOID
 InitGenericListUi(
     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
 DrawGenericList(
@@ -58,6 +72,13 @@ DrawGenericList(
     IN SHORT Right,
     IN SHORT Bottom);
 
+VOID
+DrawGenericListCurrentItem(
+    IN PGENERIC_LIST List,
+    IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc,
+    IN SHORT Left,
+    IN SHORT Top);
+
 VOID
 ScrollDownGenericList(
     IN PGENERIC_LIST_UI ListUi);
index 35d83ab..99ea1c8 100644 (file)
@@ -56,7 +56,7 @@ static WCHAR DestinationDriveLetter;
 
 /* OTHER Stuff *****/
 
-PWCHAR SelectedLanguageId;
+PCWSTR SelectedLanguageId;
 static WCHAR DefaultLanguage[20];   // Copy of string inside LanguageList
 static WCHAR DefaultKBLayout[20];   // Copy of string inside KeyboardList
 
@@ -414,25 +414,63 @@ UpdateKBLayout(VOID)
         }
     }
 
-    ListEntry = GetFirstListEntry(LayoutList);
-
     /* Search for default layout (if provided) */
     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);
                 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.
  *
@@ -449,7 +487,7 @@ static PAGE_NUMBER
 LanguagePage(PINPUT_RECORD Ir)
 {
     GENERIC_LIST_UI ListUi;
-    PWCHAR NewLanguageId;
+    PCWSTR NewLanguageId;
     BOOL RefreshPage = FALSE;
 
     /* Initialize the computer settings list */
@@ -478,10 +516,9 @@ LanguagePage(PINPUT_RECORD Ir)
         return WELCOME_PAGE;
     }
 
-    InitGenericListUi(&ListUi, LanguageList);
+    InitGenericListUi(&ListUi, LanguageList, GetSettingDescription);
     DrawGenericList(&ListUi,
-                    2,
-                    18,
+                    2, 18,
                     xScreen - 3,
                     yScreen - 3);
 
@@ -527,7 +564,11 @@ LanguagePage(PINPUT_RECORD Ir)
         }
         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);
 
@@ -550,7 +591,11 @@ LanguagePage(PINPUT_RECORD Ir)
 
         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))
             {
@@ -603,6 +648,7 @@ SetupStartPage(PINPUT_RECORD Ir)
     NTSTATUS Status;
     ULONG Error;
     PGENERIC_LIST_ENTRY ListEntry;
+    PCWSTR LocaleId;
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
@@ -640,6 +686,8 @@ SetupStartPage(PINPUT_RECORD Ir)
     if (IsUnattendedSetup)
     {
         // TODO: Read options from inf
+        /* Load the hardware, language and keyboard layout lists */
+
         ComputerList = CreateComputerTypeList(SetupInf);
         DisplayList = CreateDisplayDriverList(SetupInf);
         KeyboardList = CreateKeyboardDriverList(SetupInf);
@@ -648,37 +696,35 @@ SetupStartPage(PINPUT_RECORD Ir)
 
         /* new part */
         SelectedLanguageId = DefaultLanguage;
-        wcscpy(SelectedLanguageId, USetupData.LocaleID);
+        wcscpy(DefaultLanguage, USetupData.LocaleID);
         USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
 
         LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout);
 
         /* first we hack LanguageList */
-        ListEntry = GetFirstListEntry(LanguageList);
-        while (ListEntry != NULL)
+        for (ListEntry = GetFirstListEntry(LanguageList); ListEntry;
+             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);
                 break;
             }
-
-            ListEntry = GetNextListEntry(ListEntry);
         }
 
         /* now LayoutList */
-        ListEntry = GetFirstListEntry(LayoutList);
-        while (ListEntry != NULL)
+        for (ListEntry = GetFirstListEntry(LayoutList); ListEntry;
+             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);
                 break;
             }
-
-            ListEntry = GetNextListEntry(ListEntry);
         }
 
         SetConsoleCodePage();
@@ -862,14 +908,12 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
 
     MUIDisplayPage(UPGRADE_REPAIR_PAGE);
 
-    InitGenericListUi(&ListUi, NtOsInstallsList);
+    InitGenericListUi(&ListUi, NtOsInstallsList, GetNTOSInstallationName);
     DrawGenericList(&ListUi,
                     2, 23,
                     xScreen - 3,
                     yScreen - 3);
 
-    SaveGenericListState(NtOsInstallsList);
-
     // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
     while (TRUE)
     {
@@ -901,7 +945,7 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
             }
             case VK_ESCAPE: /* ESC */
             {
-                RestoreGenericListState(NtOsInstallsList);
+                RestoreGenericListUiState(&ListUi);
                 // return nextPage;    // prevPage;
 
                 // return INSTALL_INTRO_PAGE;
@@ -917,7 +961,12 @@ UpgradeRepairPage(PINPUT_RECORD Ir)
             if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U')  /* U */
             {
                 /* 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",
                         CurrentInstallation->InstallationName, CurrentInstallation->DiskNumber, CurrentInstallation->PartitionNumber);
 
@@ -1090,7 +1139,6 @@ static PAGE_NUMBER
 DeviceSettingsPage(PINPUT_RECORD Ir)
 {
     static ULONG Line = 16;
-    CHAR CurrentItemText[256];
 
     /* Initialize the computer settings list */
     if (ComputerList == NULL)
@@ -1145,14 +1193,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
 
     MUIDisplayPage(DEVICE_SETTINGS_PAGE);
 
-    sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(ComputerList)));
-    CONSOLE_SetTextXY(25, 11, CurrentItemText);
-    sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(DisplayList)));
-    CONSOLE_SetTextXY(25, 12, CurrentItemText);
-    sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(KeyboardList)));
-    CONSOLE_SetTextXY(25, 13, CurrentItemText);
-    sprintf(CurrentItemText, "%S", GetListEntryText(GetCurrentListEntry(LayoutList)));
-    CONSOLE_SetTextXY(25, 14, CurrentItemText);
+    DrawGenericListCurrentItem(ComputerList, GetSettingDescription, 25, 11);
+    DrawGenericListCurrentItem(DisplayList , GetSettingDescription, 25, 12);
+    DrawGenericListCurrentItem(KeyboardList, GetSettingDescription, 25, 13);
+    DrawGenericListCurrentItem(LayoutList  , GetSettingDescription, 25, 14);
 
     CONSOLE_InvertTextXY(24, Line, 48, 1);
 
@@ -1263,7 +1307,7 @@ HandleGenericList(PGENERIC_LIST_UI ListUi,
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE))  /* ESC */
         {
-            RestoreGenericListState(ListUi->List);
+            RestoreGenericListUiState(ListUi);
             return nextPage;    // Use some "prevPage;" instead?
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
@@ -1295,15 +1339,12 @@ ComputerSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(COMPUTER_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, ComputerList);
+    InitGenericListUi(&ListUi, ComputerList, GetSettingDescription);
     DrawGenericList(&ListUi,
-                    2,
-                    18,
+                    2, 18,
                     xScreen - 3,
                     yScreen - 3);
 
-    SaveGenericListState(ComputerList);
-
     return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
 }
 
@@ -1324,15 +1365,12 @@ DisplaySettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(DISPLAY_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, DisplayList);
+    InitGenericListUi(&ListUi, DisplayList, GetSettingDescription);
     DrawGenericList(&ListUi,
-                    2,
-                    18,
+                    2, 18,
                     xScreen - 3,
                     yScreen - 3);
 
-    SaveGenericListState(DisplayList);
-
     return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
 }
 
@@ -1353,15 +1391,12 @@ KeyboardSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(KEYBOARD_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, KeyboardList);
+    InitGenericListUi(&ListUi, KeyboardList, GetSettingDescription);
     DrawGenericList(&ListUi,
-                    2,
-                    18,
+                    2, 18,
                     xScreen - 3,
                     yScreen - 3);
 
-    SaveGenericListState(KeyboardList);
-
     return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
 }
 
@@ -1382,15 +1417,12 @@ LayoutSettingsPage(PINPUT_RECORD Ir)
     GENERIC_LIST_UI ListUi;
     MUIDisplayPage(LAYOUT_SETTINGS_PAGE);
 
-    InitGenericListUi(&ListUi, LayoutList);
+    InitGenericListUi(&ListUi, LayoutList, GetSettingDescription);
     DrawGenericList(&ListUi,
-                    2,
-                    18,
+                    2, 18,
                     xScreen - 3,
                     yScreen - 3);
 
-    SaveGenericListState(LayoutList);
-
     return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
 }
 
index 61971f1..572defa 100644 (file)
@@ -72,7 +72,7 @@
 
 extern HANDLE ProcessHeap;
 extern BOOLEAN IsUnattendedSetup;
-extern PWCHAR SelectedLanguageId;
+extern PCWSTR SelectedLanguageId;
 
 typedef enum _PAGE_NUMBER
 {