From 4bf9f6fa4ac1ddf3be0c6ab0f6fbec5037efe258 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:37:28 +0100 Subject: [PATCH] [SETUP:REACTOS] Populate the list of existing installations. - In the 1st-stage GUI setup, display the list of existing discovered NTOS installations, with its name, installation path and vendor name, and an associated icon. --- base/setup/reactos/drivepage.c | 3 + base/setup/reactos/reactos.c | 605 +++++++++++++++------------ base/setup/reactos/reactos.h | 42 +- base/setup/reactos/reactos.rc | 4 +- base/setup/reactos/res/README.txt | 12 + base/setup/reactos/res/roslogo.ico | Bin 0 -> 10134 bytes base/setup/reactos/res/roslogo_2.ico | Bin 0 -> 10134 bytes base/setup/reactos/res/winlogo.ico | Bin 0 -> 10134 bytes base/setup/reactos/resource.h | 5 +- 9 files changed, 376 insertions(+), 295 deletions(-) create mode 100644 base/setup/reactos/res/README.txt create mode 100644 base/setup/reactos/res/roslogo.ico create mode 100644 base/setup/reactos/res/roslogo_2.ico create mode 100644 base/setup/reactos/res/winlogo.ico diff --git a/base/setup/reactos/drivepage.c b/base/setup/reactos/drivepage.c index 5130a2983c5..b8bc07f3ced 100644 --- a/base/setup/reactos/drivepage.c +++ b/base/setup/reactos/drivepage.c @@ -29,6 +29,9 @@ /* GLOBALS ******************************************************************/ +#define IDS_LIST_COLUMN_FIRST IDS_PARTITION_NAME +#define IDS_LIST_COLUMN_LAST IDS_PARTITION_TYPE + #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1) static const UINT column_ids[MAX_LIST_COLUMNS] = {IDS_LIST_COLUMN_FIRST, IDS_LIST_COLUMN_FIRST + 1, IDS_LIST_COLUMN_FIRST + 2}; static const INT column_widths[MAX_LIST_COLUMNS] = {200, 150, 150}; diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c index 23c659c3d58..7bc0581b9c7 100644 --- a/base/setup/reactos/reactos.c +++ b/base/setup/reactos/reactos.c @@ -39,8 +39,6 @@ SETUPDATA SetupData; /* FUNCTIONS ****************************************************************/ -LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context); - static VOID CenterWindow(HWND hWnd) { @@ -112,14 +110,14 @@ StartDlgProc( PSETUPDATA pSetupData; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); /* Center the wizard window */ CenterWindow(GetParent(hwndDlg)); @@ -166,22 +164,37 @@ TypeDlgProc( PSETUPDATA pSetupData; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: + { /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); /* Check the 'install' radio button */ CheckDlgButton(hwndDlg, IDC_INSTALL, BST_CHECKED); - /* Disable the 'update' radio button and text */ - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATETEXT), FALSE); + /* + * Enable the 'update' radio button and text only if we have + * available NT installations, otherwise disable them. + */ + if (pSetupData->NtOsInstallsList && + GetNumberOfListEntries(pSetupData->NtOsInstallsList) != 0) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATETEXT), TRUE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATETEXT), FALSE); + } + break; + } case WM_NOTIFY: { @@ -194,20 +207,38 @@ TypeDlgProc( break; case PSN_QUERYCANCEL: - SetWindowLongPtr(hwndDlg, - DWLP_MSGRESULT, - MessageBox(GetParent(hwndDlg), - pSetupData->szAbortMessage, - pSetupData->szAbortTitle, - MB_YESNO | MB_ICONQUESTION) != IDYES); + SetWindowLongPtrW(hwndDlg, + DWLP_MSGRESULT, + MessageBoxW(GetParent(hwndDlg), + pSetupData->szAbortMessage, + pSetupData->szAbortTitle, + MB_YESNO | MB_ICONQUESTION) != IDYES); return TRUE; - case PSN_WIZNEXT: // set the selected data - pSetupData->RepairUpdateFlag = !(SendMessage(GetDlgItem(hwndDlg, IDC_INSTALL), - BM_GETCHECK, - (WPARAM) 0, - (LPARAM) 0) == BST_CHECKED); + case PSN_WIZNEXT: /* Set the selected data */ + { + pSetupData->RepairUpdateFlag = + !(SendMessageW(GetDlgItem(hwndDlg, IDC_INSTALL), + BM_GETCHECK, + 0, 0) == BST_CHECKED); + + /* + * Display the existing NT installations page only + * if we have more than one available NT installations. + */ + if (pSetupData->NtOsInstallsList && + GetNumberOfListEntries(pSetupData->NtOsInstallsList) > 1) + { + /* Actually the best would be to dynamically insert the page only when needed */ + SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, IDD_UPDATEREPAIRPAGE); + } + else + { + SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, IDD_DEVICEPAGE); + } + return TRUE; + } default: break; @@ -222,9 +253,187 @@ TypeDlgProc( return FALSE; } + + +typedef VOID +(NTAPI *PGET_ENTRY_DESCRIPTION)( + IN PGENERIC_LIST_ENTRY Entry, + OUT PWSTR Buffer, + IN SIZE_T cchBufferSize); + +VOID +InitGenericComboList( + IN HWND hWndList, + IN PGENERIC_LIST List, + IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc) +{ + INT Index, CurrentEntryIndex = 0; + PGENERIC_LIST_ENTRY ListEntry; + PLIST_ENTRY Entry; + WCHAR CurrentItemText[256]; + + for (Entry = List->ListHead.Flink; + Entry != &List->ListHead; + Entry = Entry->Flink) + { + ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry); + + if (GetEntryDescriptionProc) + { + GetEntryDescriptionProc(ListEntry, + CurrentItemText, + ARRAYSIZE(CurrentItemText)); + Index = SendMessageW(hWndList, CB_ADDSTRING, 0, (LPARAM)CurrentItemText); + } + else + { + Index = SendMessageW(hWndList, CB_ADDSTRING, 0, (LPARAM)L"n/a"); + } + + if (ListEntry == List->CurrentEntry) + CurrentEntryIndex = Index; + + SendMessageW(hWndList, CB_SETITEMDATA, Index, (LPARAM)ListEntry); + } + + SendMessageW(hWndList, CB_SETCURSEL, CurrentEntryIndex, 0); +} + +INT +GetSelectedComboListItem( + IN HWND hWndList) +{ + LRESULT Index; + + Index = SendMessageW(hWndList, CB_GETCURSEL, 0, 0); + if (Index == CB_ERR) + return CB_ERR; + + // TODO: Update List->CurrentEntry? + // return SendMessageW(hWndList, CB_GETITEMDATA, (WPARAM)Index, 0); + return Index; +} + +typedef VOID +(NTAPI *PADD_ENTRY_ITEM)( + IN HWND hWndList, + IN LVITEM* plvItem, + IN PGENERIC_LIST_ENTRY Entry, + IN OUT PWSTR Buffer, + IN SIZE_T cchBufferSize); + +VOID +InitGenericListView( + IN HWND hWndList, + IN PGENERIC_LIST List, + IN PADD_ENTRY_ITEM AddEntryItemProc) +{ + INT CurrentEntryIndex = 0; + LVITEM lvItem; + PGENERIC_LIST_ENTRY ListEntry; + PLIST_ENTRY Entry; + WCHAR CurrentItemText[256]; + + for (Entry = List->ListHead.Flink; + Entry != &List->ListHead; + Entry = Entry->Flink) + { + ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry); + + if (!AddEntryItemProc) + continue; + + AddEntryItemProc(hWndList, + &lvItem, + ListEntry, + CurrentItemText, + ARRAYSIZE(CurrentItemText)); + + if (ListEntry == List->CurrentEntry) + CurrentEntryIndex = lvItem.iItem; + } + + SendMessageW(hWndList, LVM_ENSUREVISIBLE, CurrentEntryIndex, FALSE); + ListView_SetItemState(hWndList, CurrentEntryIndex, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(hWndList, CurrentEntryIndex, LVIS_FOCUSED, LVIS_FOCUSED); +} + + +static VOID +NTAPI +GetSettingDescription( + IN PGENERIC_LIST_ENTRY Entry, + OUT PWSTR Buffer, + IN SIZE_T cchBufferSize) +{ + StringCchCopyW(Buffer, cchBufferSize, + ((PGENENTRY)GetListEntryData(Entry))->Value); +} + +static VOID +NTAPI +AddNTOSInstallationItem( + IN HWND hWndList, + IN LVITEM* plvItem, + IN PGENERIC_LIST_ENTRY Entry, + IN OUT PWSTR Buffer, // SystemRootPath + 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 */ + StringCchPrintfW(Buffer, cchBufferSize, + L"%C:%s", + PartEntry->DriveLetter, + NtOsInstall->PathComponent); + } + else + { + /* We failed somewhere, just show the NT path */ + StringCchPrintfW(Buffer, cchBufferSize, + L"%wZ", + &NtOsInstall->SystemNtPath); + } + + plvItem->mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; + plvItem->iItem = 0; + plvItem->iSubItem = 0; + plvItem->lParam = (LPARAM)Entry; + plvItem->pszText = NtOsInstall->InstallationName; + + /* Associate vendor icon */ + if (FindSubStrI(NtOsInstall->VendorName, VENDOR_REACTOS)) + { + plvItem->mask |= LVIF_IMAGE; + plvItem->iImage = 0; + } + else if (FindSubStrI(NtOsInstall->VendorName, VENDOR_MICROSOFT)) + { + plvItem->mask |= LVIF_IMAGE; + plvItem->iImage = 1; + } + + plvItem->iItem = SendMessageW(hWndList, LVM_INSERTITEMW, 0, (LPARAM)plvItem); + + plvItem->iSubItem = 1; + plvItem->pszText = Buffer; // SystemRootPath; + SendMessageW(hWndList, LVM_SETITEMTEXTW, plvItem->iItem, (LPARAM)plvItem); + + plvItem->iSubItem = 2; + plvItem->pszText = NtOsInstall->VendorName; + SendMessageW(hWndList, LVM_SETITEMTEXTW, plvItem->iItem, (LPARAM)plvItem); +} + + +#define IDS_LIST_COLUMN_FIRST IDS_INSTALLATION_NAME +#define IDS_LIST_COLUMN_LAST IDS_INSTALLATION_VENDOR + #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1) static const UINT column_ids[MAX_LIST_COLUMNS] = {IDS_LIST_COLUMN_FIRST, IDS_LIST_COLUMN_FIRST + 1, IDS_LIST_COLUMN_FIRST + 2}; -static const INT column_widths[MAX_LIST_COLUMNS] = {200, 150, 150}; +static const INT column_widths[MAX_LIST_COLUMNS] = {200, 150, 100}; static const INT column_alignment[MAX_LIST_COLUMNS] = {LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT}; static INT_PTR CALLBACK @@ -236,9 +445,10 @@ UpgradeRepairDlgProc( { PSETUPDATA pSetupData; HWND hList; + HIMAGELIST hSmall; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWL_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { @@ -246,9 +456,9 @@ UpgradeRepairDlgProc( { /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtrW(hwndDlg, GWL_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); - hList = GetDlgItem(hwndDlg, IDC_LIST1); + hList = GetDlgItem(hwndDlg, IDC_NTOSLIST); CreateListViewColumns(pSetupData->hInstance, hList, @@ -257,9 +467,33 @@ UpgradeRepairDlgProc( column_alignment, MAX_LIST_COLUMNS); + /* Create the ImageList */ + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_COLOR32 | ILC_MASK, // ILC_COLOR24 + 1, 1); + + /* Add event type icons to the ImageList */ + ImageList_AddIcon(hSmall, LoadIconW(pSetupData->hInstance, MAKEINTRESOURCEW(IDI_ROSICON))); + ImageList_AddIcon(hSmall, LoadIconW(pSetupData->hInstance, MAKEINTRESOURCEW(IDI_WINICON))); + + /* Assign the ImageList to the List View */ + ListView_SetImageList(hList, hSmall, LVSIL_SMALL); + + InitGenericListView(hList, pSetupData->NtOsInstallsList, AddNTOSInstallationItem); + break; } + case WM_DESTROY: + { + hList = GetDlgItem(hwndDlg, IDC_NTOSLIST); + hSmall = ListView_GetImageList(hList, LVSIL_SMALL); + ListView_SetImageList(hList, NULL, LVSIL_SMALL); + ImageList_Destroy(hSmall); + return TRUE; + } + case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; @@ -272,18 +506,18 @@ UpgradeRepairDlgProc( case PSN_QUERYCANCEL: SetWindowLongPtrW(hwndDlg, - DWL_MSGRESULT, - MessageBox(GetParent(hwndDlg), - pSetupData->szAbortMessage, - pSetupData->szAbortTitle, - MB_YESNO | MB_ICONQUESTION) != IDYES); + DWLP_MSGRESULT, + MessageBoxW(GetParent(hwndDlg), + pSetupData->szAbortMessage, + pSetupData->szAbortTitle, + MB_YESNO | MB_ICONQUESTION) != IDYES); return TRUE; - case PSN_WIZNEXT: // set the selected data - pSetupData->RepairUpdateFlag = !(SendMessageW(GetDlgItem(hwndDlg, IDC_INSTALL), - BM_GETCHECK, - (WPARAM) 0, - (LPARAM) 0) == BST_CHECKED); + case PSN_WIZNEXT: /* Set the selected data */ + pSetupData->RepairUpdateFlag = + !(SendMessageW(GetDlgItem(hwndDlg, IDC_INSTALL), + BM_GETCHECK, + 0, 0) == BST_CHECKED); return TRUE; default: @@ -307,47 +541,33 @@ DeviceDlgProc( IN LPARAM lParam) { PSETUPDATA pSetupData; - LONG i; - LRESULT tindex; HWND hList; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: + { /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); hList = GetDlgItem(hwndDlg, IDC_COMPUTER); - - for (i=0; i < pSetupData->CompCount; i++) - { - tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) pSetupData->pComputers[i].Value); - SendMessage(hList, CB_SETITEMDATA, tindex, i); - } - SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default + InitGenericComboList(hList, pSetupData->ComputerList, GetSettingDescription); hList = GetDlgItem(hwndDlg, IDC_DISPLAY); - - for (i=0; i < pSetupData->DispCount; i++) - { - tindex = SendMessage(hList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) pSetupData->pDisplays[i].Value); - SendMessage(hList, CB_SETITEMDATA, tindex, i); - } - SendMessage(hList, CB_SETCURSEL, 0, 0); // set first as default + InitGenericComboList(hList, pSetupData->DisplayList, GetSettingDescription); hList = GetDlgItem(hwndDlg, IDC_KEYBOARD); + InitGenericComboList(hList, pSetupData->KeyboardList, GetSettingDescription); + + // hList = GetDlgItem(hwndDlg, IDC_KEYBOARD_LAYOUT); + // InitGenericComboList(hList, pSetupData->LayoutList, GetSettingDescription); - for (i=0; i < pSetupData->KeybCount; i++) - { - tindex = SendMessage(hList,CB_ADDSTRING,(WPARAM)0,(LPARAM)pSetupData->pKeyboards[i].Value); - SendMessage(hList,CB_SETITEMDATA,tindex,i); - } - SendMessage(hList,CB_SETCURSEL,0,0); // set first as default break; + } case WM_NOTIFY: { @@ -360,48 +580,25 @@ DeviceDlgProc( break; case PSN_QUERYCANCEL: - SetWindowLongPtr(hwndDlg, - DWLP_MSGRESULT, - MessageBox(GetParent(hwndDlg), - pSetupData->szAbortMessage, - pSetupData->szAbortTitle, - MB_YESNO | MB_ICONQUESTION) != IDYES); + SetWindowLongPtrW(hwndDlg, + DWLP_MSGRESULT, + MessageBoxW(GetParent(hwndDlg), + pSetupData->szAbortMessage, + pSetupData->szAbortTitle, + MB_YESNO | MB_ICONQUESTION) != IDYES); return TRUE; - case PSN_WIZNEXT: // set the selected data + case PSN_WIZNEXT: /* Set the selected data */ { - hList = GetDlgItem(hwndDlg, IDC_COMPUTER); - - tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); - if (tindex != CB_ERR) - { - pSetupData->SelectedComputer = SendMessage(hList, - CB_GETITEMDATA, - (WPARAM) tindex, - (LPARAM) 0); - } + hList = GetDlgItem(hwndDlg, IDC_COMPUTER); + pSetupData->SelectedComputer = GetSelectedComboListItem(hList); hList = GetDlgItem(hwndDlg, IDC_DISPLAY); + pSetupData->SelectedDisplay = GetSelectedComboListItem(hList); - tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); - if (tindex != CB_ERR) - { - pSetupData->SelectedDisplay = SendMessage(hList, - CB_GETITEMDATA, - (WPARAM) tindex, - (LPARAM) 0); - } + hList = GetDlgItem(hwndDlg, IDC_KEYBOARD); + pSetupData->SelectedKeyboard = GetSelectedComboListItem(hList); - hList =GetDlgItem(hwndDlg, IDC_KEYBOARD); - - tindex = SendMessage(hList, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); - if (tindex != CB_ERR) - { - pSetupData->SelectedKeyboard = SendMessage(hList, - CB_GETITEMDATA, - (WPARAM) tindex, - (LPARAM) 0); - } return TRUE; } @@ -428,14 +625,14 @@ SummaryDlgProc( PSETUPDATA pSetupData; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); break; case WM_NOTIFY: @@ -444,18 +641,19 @@ SummaryDlgProc( switch (lpnm->code) { - case PSN_SETACTIVE: + case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); break; case PSN_QUERYCANCEL: - SetWindowLongPtr(hwndDlg, - DWLP_MSGRESULT, - MessageBox(GetParent(hwndDlg), - pSetupData->szAbortMessage, - pSetupData->szAbortTitle, - MB_YESNO | MB_ICONQUESTION) != IDYES); + SetWindowLongPtrW(hwndDlg, + DWLP_MSGRESULT, + MessageBoxW(GetParent(hwndDlg), + pSetupData->szAbortMessage, + pSetupData->szAbortTitle, + MB_YESNO | MB_ICONQUESTION) != IDYES); return TRUE; + default: break; } @@ -479,14 +677,14 @@ ProcessDlgProc( PSETUPDATA pSetupData; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); break; case WM_NOTIFY: @@ -501,13 +699,14 @@ ProcessDlgProc( // PropSheet_SetWizButtons(GetParent(hwndDlg), 0 ); break; case PSN_QUERYCANCEL: - SetWindowLongPtr(hwndDlg, - DWLP_MSGRESULT, - MessageBox(GetParent(hwndDlg), - pSetupData->szAbortMessage, - pSetupData->szAbortTitle, - MB_YESNO | MB_ICONQUESTION) != IDYES); + SetWindowLongPtrW(hwndDlg, + DWLP_MSGRESULT, + MessageBoxW(GetParent(hwndDlg), + pSetupData->szAbortMessage, + pSetupData->szAbortTitle, + MB_YESNO | MB_ICONQUESTION) != IDYES); return TRUE; + default: break; } @@ -532,14 +731,14 @@ RestartDlgProc( PSETUPDATA pSetupData; /* Retrieve pointer to the global setup data */ - pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: /* Save pointer to the global setup data */ pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); /* Set title font */ /*SendDlgItemMessage(hwndDlg, @@ -555,7 +754,7 @@ RestartDlgProc( HWND hWndProgress; hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS); - Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0); + Position = SendMessageW(hWndProgress, PBM_GETPOS, 0, 0); if (Position == 300) { KillTimer(hwndDlg, 1); @@ -563,7 +762,7 @@ RestartDlgProc( } else { - SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0); + SendMessageW(hWndProgress, PBM_SETPOS, Position + 1, 0); } return TRUE; } @@ -602,78 +801,34 @@ BOOL LoadSetupData( IN OUT PSETUPDATA pSetupData) { BOOL ret = TRUE; - INFCONTEXT InfContext; - TCHAR tmp[10]; - //TCHAR szValue[MAX_PATH]; - DWORD LineLength; - LONG Count; - - // get language list - pSetupData->LangCount = SetupGetLineCount(pSetupData->SetupInf, _T("Language")); - if (pSetupData->LangCount > 0) - { - pSetupData->pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * pSetupData->LangCount); - if (pSetupData->pLanguages == NULL) - { - ret = FALSE; - goto done; - } + // INFCONTEXT InfContext; + // TCHAR tmp[10]; + // DWORD LineLength; + // LONG Count; - Count = 0; - if (SetupFindFirstLine(pSetupData->SetupInf, _T("Language"), NULL, &InfContext)) - { - do - { - SetupGetStringField(&InfContext, - 0, - pSetupData->pLanguages[Count].LangId, - sizeof(pSetupData->pLanguages[Count].LangId) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(&InfContext, - 1, - pSetupData->pLanguages[Count].LangName, - sizeof(pSetupData->pLanguages[Count].LangName) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < pSetupData->LangCount); - } - } + /* Load the hardware, language and keyboard layout lists */ - // get keyboard layout list - pSetupData->KbLayoutCount = SetupGetLineCount(pSetupData->SetupInf, _T("KeyboardLayout")); - if (pSetupData->KbLayoutCount > 0) - { - pSetupData->pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * pSetupData->KbLayoutCount); - if (pSetupData->pKbLayouts == NULL) - { - ret = FALSE; - goto done; - } + pSetupData->ComputerList = CreateComputerTypeList(pSetupData->SetupInf); + pSetupData->DisplayList = CreateDisplayDriverList(pSetupData->SetupInf); + pSetupData->KeyboardList = CreateKeyboardDriverList(pSetupData->SetupInf); - Count = 0; - if (SetupFindFirstLine(pSetupData->SetupInf, _T("KeyboardLayout"), NULL, &InfContext)) - { - do - { - SetupGetStringField(&InfContext, - 0, - pSetupData->pKbLayouts[Count].LayoutId, - sizeof(pSetupData->pKbLayouts[Count].LayoutId) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(&InfContext, - 1, - pSetupData->pKbLayouts[Count].LayoutName, - sizeof(pSetupData->pKbLayouts[Count].LayoutName) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < pSetupData->KbLayoutCount); - } - } + pSetupData->LanguageList = CreateLanguageList(pSetupData->SetupInf, pSetupData->DefaultLanguage); + + pSetupData->PartitionList = CreatePartitionList(); + + pSetupData->NtOsInstallsList = CreateNTOSInstallationsList(pSetupData->PartitionList); + if (!pSetupData->NtOsInstallsList) + DPRINT1("Failed to get a list of NTOS installations; continue installation...\n"); + + + /* new part */ + pSetupData->SelectedLanguageId = pSetupData->DefaultLanguage; + wcscpy(pSetupData->DefaultLanguage, pSetupData->USetupData.LocaleID); + pSetupData->USetupData.LanguageId = (LANGID)(wcstol(pSetupData->SelectedLanguageId, NULL, 16) & 0xFFFF); + + pSetupData->LayoutList = CreateKeyboardLayoutList(pSetupData->SetupInf, pSetupData->SelectedLanguageId, pSetupData->DefaultKBLayout); +#if 0 // get default for keyboard and language pSetupData->DefaultKBLayout = -1; pSetupData->DefaultLang = -1; @@ -681,7 +836,7 @@ BOOL LoadSetupData( // TODO: get defaults from underlaying running system if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLayout"), &InfContext)) { - SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength); + SetupGetStringField(&InfContext, 1, tmp, ARRAYSIZE(tmp), &LineLength); for (Count = 0; Count < pSetupData->KbLayoutCount; Count++) { if (_tcscmp(tmp, pSetupData->pKbLayouts[Count].LayoutId) == 0) @@ -694,7 +849,7 @@ BOOL LoadSetupData( if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLanguage"), &InfContext)) { - SetupGetStringField(&InfContext, 1, tmp, sizeof(tmp) / sizeof(TCHAR), &LineLength); + SetupGetStringField(&InfContext, 1, tmp, ARRAYSIZE(tmp), &LineLength); for (Count = 0; Count < pSetupData->LangCount; Count++) { if (_tcscmp(tmp, pSetupData->pLanguages[Count].LangId) == 0) @@ -704,82 +859,11 @@ BOOL LoadSetupData( } } } - - // get computers list - pSetupData->CompCount = LoadGenentry(pSetupData->SetupInf,_T("Computer"),&pSetupData->pComputers,&InfContext); - - // get display list - pSetupData->DispCount = LoadGenentry(pSetupData->SetupInf,_T("Display"),&pSetupData->pDisplays,&InfContext); - - // get keyboard list - pSetupData->KeybCount = LoadGenentry(pSetupData->SetupInf, _T("Keyboard"),&pSetupData->pKeyboards,&InfContext); - - // get install directory - if (SetupFindFirstLine(pSetupData->SetupInf, _T("SetupData"), _T("DefaultPath"), &InfContext)) - { - SetupGetStringField(&InfContext, - 1, - pSetupData->USetupData.InstallationDirectory, - sizeof(pSetupData->USetupData.InstallationDirectory) / sizeof(TCHAR), - &LineLength); - } - -done: - if (ret == FALSE) - { - if (pSetupData->pKbLayouts != NULL) - { - HeapFree(GetProcessHeap(), 0, pSetupData->pKbLayouts); - pSetupData->pKbLayouts = NULL; - } - - if (pSetupData->pLanguages != NULL) - { - HeapFree(GetProcessHeap(), 0, pSetupData->pLanguages); - pSetupData->pLanguages = NULL; - } - } +#endif return ret; } -LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY *gen,PINFCONTEXT context) -{ - LONG TotalCount; - DWORD LineLength; - - TotalCount = SetupGetLineCount(hinf, name); - if (TotalCount > 0) - { - *gen = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * TotalCount); - if (*gen != NULL) - { - if (SetupFindFirstLine(hinf, name, NULL, context)) - { - LONG Count = 0; - do - { - SetupGetStringField(context, - 0, - (*gen)[Count].Id, - sizeof((*gen)[Count].Id) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(context, - 1, - (*gen)[Count].Value, - sizeof((*gen)[Count].Value) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(context, context) && Count < TotalCount); - } - } - else return 0; - } - return TotalCount; -} - /* * Attempts to convert a pure NT file path into a corresponding Win32 path. * Adapted from GetInstallSourceWin32() in dll/win32/syssetup/wizard.c @@ -866,6 +950,7 @@ _tWinMain(HINSTANCE hInst, { NTSTATUS Status; ULONG Error; + INITCOMMONCONTROLSEX iccx; PROPSHEETHEADER psh; HPROPSHEETPAGE ahpsp[8]; PROPSHEETPAGE psp = {0}; @@ -920,9 +1005,17 @@ _tWinMain(HINSTANCE hInst, CheckUnattendedSetup(&SetupData.USetupData); SetupData.bUnattend = IsUnattendedSetup; + /* Cache commonly-used strings */ LoadStringW(hInst, IDS_ABORTSETUP, SetupData.szAbortMessage, ARRAYSIZE(SetupData.szAbortMessage)); LoadStringW(hInst, IDS_ABORTSETUP2, SetupData.szAbortTitle, ARRAYSIZE(SetupData.szAbortTitle)); + /* Whenever any of the common controls are used in your app, + * you must call InitCommonControlsEx() to register the classes + * for those controls. */ + iccx.dwSize = sizeof(iccx); + iccx.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES /* | ICC_PROGRESS_CLASS */; + InitCommonControlsEx(&iccx); + /* Create title font */ SetupData.hTitleFont = CreateTitleFont(); diff --git a/base/setup/reactos/reactos.h b/base/setup/reactos/reactos.h index a27eea12a46..760b62708ab 100644 --- a/base/setup/reactos/reactos.h +++ b/base/setup/reactos/reactos.h @@ -40,10 +40,11 @@ #include #include +#include + #include /**/#include /**/ #include -// #include #define NTOS_MODE_USER #include // For CM_DISK stuff @@ -56,26 +57,14 @@ #include <../lib/setuplib.h> // #include "errorcode.h" - -typedef struct _LANG -{ - TCHAR LangId[9]; - TCHAR LangName[128]; -} LANG, *PLANG; - +#if 0 typedef struct _KBLAYOUT { TCHAR LayoutId[9]; TCHAR LayoutName[128]; TCHAR DllName[128]; } KBLAYOUT, *PKBLAYOUT; - -// generic entries with simple 1:1 mapping -typedef struct _GENENTRY -{ - TCHAR Id[24]; - TCHAR Value[128]; -} GENENTRY, *PGENENTRY; +#endif typedef struct _SETUPDATA @@ -92,7 +81,7 @@ typedef struct _SETUPDATA USETUP_DATA USetupData; HINF SetupInf; - // Settings + /* Settings */ LONG DestPartSize; // if partition doesn't exist, size of partition LONG FSType; // file system type on partition LONG FormatPart; // type of format the partition @@ -106,26 +95,10 @@ typedef struct _SETUPDATA BOOLEAN RepairUpdateFlag; // flag for update/repair an installed reactos - // txtsetup.sif data -#if 1 - LONG DefaultLang; // default language (table index) - PLANG pLanguages; - LONG LangCount; - LONG DefaultKBLayout; // default keyboard layout (table index) - PKBLAYOUT pKbLayouts; - LONG KbLayoutCount; - PGENENTRY pComputers; - LONG CompCount; - PGENENTRY pDisplays; - LONG DispCount; - PGENENTRY pKeyboards; - LONG KeybCount; - -#else - + /* txtsetup.sif data */ // LONG DefaultLang; // default language (table index) // LONG DefaultKBLayout; // default keyboard layout (table index) - PWCHAR SelectedLanguageId; + PCWSTR SelectedLanguageId; WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList @@ -138,7 +111,6 @@ typedef struct _SETUPDATA PPARTLIST PartitionList; PNTOS_INSTALLATION CurrentInstallation; PGENERIC_LIST NtOsInstallsList; -#endif } SETUPDATA, *PSETUPDATA; diff --git a/base/setup/reactos/reactos.rc b/base/setup/reactos/reactos.rc index e20f4a6ab04..a1f7ac5eabe 100644 --- a/base/setup/reactos/reactos.rc +++ b/base/setup/reactos/reactos.rc @@ -12,7 +12,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* Icons */ -IDI_MAIN ICON "res/setup.ico" +IDI_MAIN ICON "res/setup.ico" +IDI_ROSICON ICON "res/roslogo.ico" +IDI_WINICON ICON "res/winlogo.ico" /* Bitmaps */ IDB_WATERMARK BITMAP "res/watermark.bmp" diff --git a/base/setup/reactos/res/README.txt b/base/setup/reactos/res/README.txt new file mode 100644 index 00000000000..54c0b111c49 --- /dev/null +++ b/base/setup/reactos/res/README.txt @@ -0,0 +1,12 @@ + +roslogo.ico +----------- +(C) 2018 ReactOS Team & Contributors +Distributed under CC-BY-SA 4.0 International License Terms. + +winlogo.ico +----------- +Adapted from the WinTango IconPack, by 'heebijeebi' +See http://heebijeebi.deviantart.com and http://wintango.blogspot.com/ +Distributed under CC-BY-SA 3.0 International License Terms. +Slightly modified by Hermès Bélusca-Maïto. diff --git a/base/setup/reactos/res/roslogo.ico b/base/setup/reactos/res/roslogo.ico new file mode 100644 index 0000000000000000000000000000000000000000..d2f5b8630851f7272e71dfbb3661a0fc5c7cf224 GIT binary patch literal 10134 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 aVdJ3+prKQw@&SEq44BW!z%T)AeGC9Xa6SS6 literal 0 HcmV?d00001 diff --git a/base/setup/reactos/res/roslogo_2.ico b/base/setup/reactos/res/roslogo_2.ico new file mode 100644 index 0000000000000000000000000000000000000000..2d73e1eba748ebe8688fa325521ecf519a2a799e GIT binary patch literal 10134 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 K96B^?3>5&*lnp`v literal 0 HcmV?d00001 diff --git a/base/setup/reactos/res/winlogo.ico b/base/setup/reactos/res/winlogo.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab8632d566dbf08460a351dc6874052298f29187 GIT binary patch literal 10134 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