From 1f4cb0977a324859f8d4ba0e27a0a63cae8f96aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Fri, 29 Dec 2017 19:09:56 +0100 Subject: [PATCH] [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...). --- base/setup/lib/settings.c | 81 +++++++++-------- base/setup/lib/settings.h | 7 ++ base/setup/lib/setuplib.c | 2 +- base/setup/lib/utils/genlist.c | 68 +++++---------- base/setup/lib/utils/genlist.h | 27 ++---- base/setup/usetup/console.c | 2 +- base/setup/usetup/genlist.c | 68 +++++++++++++-- base/setup/usetup/genlist.h | 23 ++++- base/setup/usetup/usetup.c | 154 ++++++++++++++++++++------------- base/setup/usetup/usetup.h | 2 +- 10 files changed, 264 insertions(+), 170 deletions(-) diff --git a/base/setup/lib/settings.c b/base/setup/lib/settings.c index 060c671b411..f0a5200fe91 100644 --- a/base/setup/lib/settings.c +++ b/base/setup/lib/settings.c @@ -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; diff --git a/base/setup/lib/settings.h b/base/setup/lib/settings.h index ce66383aba7..9c46123e434 100644 --- a/base/setup/lib/settings.h +++ b/base/setup/lib/settings.h @@ -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); diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c index 2d9a6bba809..aba1533ceb9 100644 --- a/base/setup/lib/setuplib.c +++ b/base/setup/lib/setuplib.c @@ -516,7 +516,7 @@ LoadSetupInf( *SetupInf = SetupOpenInfFileExW(FileNameBuffer, NULL, - INF_STYLE_WIN4 | INF_STYLE_OLDNT, + /* INF_STYLE_WIN4 | */ INF_STYLE_OLDNT, pSetupData->LanguageId, &ErrorLine); diff --git a/base/setup/lib/utils/genlist.c b/base/setup/lib/utils/genlist.c index 209da600589..a322914cd8f 100644 --- a/base/setup/lib/utils/genlist.c +++ b/base/setup/lib/utils/genlist.c @@ -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 */ diff --git a/base/setup/lib/utils/genlist.h b/base/setup/lib/utils/genlist.h index ca8696d9570..5d145a4c464 100644 --- a/base/setup/lib/utils/genlist.h +++ b/base/setup/lib/utils/genlist.h @@ -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); diff --git a/base/setup/usetup/console.c b/base/setup/usetup/console.c index 14a0564c6b5..ec73f382216 100644 --- a/base/setup/usetup/console.c +++ b/base/setup/usetup/console.c @@ -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); diff --git a/base/setup/usetup/genlist.c b/base/setup/usetup/genlist.c index d0b7a638750..8e8baffacda 100644 --- a/base/setup/usetup/genlist.c +++ b/base/setup/usetup/genlist.c @@ -36,11 +36,15 @@ 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)) { diff --git a/base/setup/usetup/genlist.h b/base/setup/usetup/genlist.h index 5e85800fd63..80aa86786ac 100644 --- a/base/setup/usetup/genlist.h +++ b/base/setup/usetup/genlist.h @@ -28,12 +28,21 @@ // #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); diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 35d83ab2a5a..99ea1c8d6bd 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -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); } diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h index 61971f1432b..572defaae16 100644 --- a/base/setup/usetup/usetup.h +++ b/base/setup/usetup/usetup.h @@ -72,7 +72,7 @@ extern HANDLE ProcessHeap; extern BOOLEAN IsUnattendedSetup; -extern PWCHAR SelectedLanguageId; +extern PCWSTR SelectedLanguageId; typedef enum _PAGE_NUMBER {