https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bbc4bb2d087310237d3f2…
commit bbc4bb2d087310237d3f21c3c56a73e72a5f17dc
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jan 28 23:47:25 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Nov 6 00:09:16 2018 +0100
[REACTOS] Add features/usability additions.
- Interface the TreeList code and populate it with the list of
discovered disks and partitions. Code is adapted from USETUP.
Also display the names of the disks.
- Display some installation settings summary, before doing the
installation proper.
- Force the user to select a checkbox when (s)he acknowledges that
ReactOS is alpha-quality software and may break on his/her computer
or corrupt his/her data.
- Improve wizard pages transitions and buttons enabling/disabling.
- Press Shift-F10 to start a command-line (as in the 2nd-stage setup
in syssetup.dll).
- Use some explicit UNICODE functions/macros.
---
base/setup/reactos/CMakeLists.txt | 2 +-
base/setup/reactos/drivepage.c | 687 +++++++++++++++++++++++++++++++++-----
base/setup/reactos/reactos.c | 507 +++++++++++++++++++++++-----
base/setup/reactos/reactos.h | 31 +-
4 files changed, 1045 insertions(+), 182 deletions(-)
diff --git a/base/setup/reactos/CMakeLists.txt b/base/setup/reactos/CMakeLists.txt
index 8c58f9e360..75418ede51 100644
--- a/base/setup/reactos/CMakeLists.txt
+++ b/base/setup/reactos/CMakeLists.txt
@@ -20,5 +20,5 @@ add_executable(reactos ${SOURCE} reactos.rc)
set_module_type(reactos win32gui UNICODE)
add_pch(reactos reactos.h SOURCE)
target_link_libraries(reactos uuid setuplib ext2lib vfatlib btrfslib)
-add_importlibs(reactos advapi32 gdi32 user32 comctl32 setupapi msvcrt kernel32 ntdll)
+add_importlibs(reactos advapi32 gdi32 user32 comctl32 shlwapi setupapi msvcrt kernel32
ntdll)
add_cd_file(TARGET reactos DESTINATION reactos NO_CAB FOR bootcd)
diff --git a/base/setup/reactos/drivepage.c b/base/setup/reactos/drivepage.c
index cf79aa3847..1da5771c47 100644
--- a/base/setup/reactos/drivepage.c
+++ b/base/setup/reactos/drivepage.c
@@ -25,17 +25,23 @@
*/
#include "reactos.h"
+#include <shlwapi.h>
+
+// #include <ntdddisk.h>
+#include <ntddstor.h>
+#include <ntddscsi.h>
+
#include "resource.h"
/* GLOBALS ******************************************************************/
#define IDS_LIST_COLUMN_FIRST IDS_PARTITION_NAME
-#define IDS_LIST_COLUMN_LAST IDS_PARTITION_TYPE
+#define IDS_LIST_COLUMN_LAST IDS_PARTITION_STATUS
#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_alignment[MAX_LIST_COLUMNS] = {LVCFMT_LEFT, LVCFMT_LEFT,
LVCFMT_LEFT};
+static const UINT column_ids[MAX_LIST_COLUMNS] = {IDS_LIST_COLUMN_FIRST,
IDS_LIST_COLUMN_FIRST + 1, IDS_LIST_COLUMN_FIRST + 2, IDS_LIST_COLUMN_FIRST + 3};
+static const INT column_widths[MAX_LIST_COLUMNS] = {200, 90, 60, 60};
+static const INT column_alignment[MAX_LIST_COLUMNS] = {LVCFMT_LEFT, LVCFMT_LEFT,
LVCFMT_RIGHT, LVCFMT_RIGHT};
/* FUNCTIONS ****************************************************************/
@@ -59,23 +65,19 @@ MoreOptDlgProc(HWND hwndDlg,
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
CheckDlgButton(hwndDlg, IDC_INSTFREELDR, BST_CHECKED);
- SendMessageW(GetDlgItem(hwndDlg, IDC_PATH),
- WM_SETTEXT,
- (WPARAM)0,
- (LPARAM)pSetupData->USetupData.InstallationDirectory);
+ SetDlgItemTextW(hwndDlg, IDC_PATH,
+ pSetupData->USetupData.InstallationDirectory);
break;
}
case WM_COMMAND:
- switch(LOWORD(wParam))
+ switch (LOWORD(wParam))
{
case IDOK:
{
- SendMessageW(GetDlgItem(hwndDlg, IDC_PATH),
- WM_GETTEXT,
-
(WPARAM)ARRAYSIZE(pSetupData->USetupData.InstallationDirectory),
-
(LPARAM)pSetupData->USetupData.InstallationDirectory);
-
+ GetDlgItemTextW(hwndDlg, IDC_PATH,
+ pSetupData->USetupData.InstallationDirectory,
+
ARRAYSIZE(pSetupData->USetupData.InstallationDirectory));
EndDialog(hwndDlg, IDOK);
return TRUE;
}
@@ -100,9 +102,10 @@ PartitionDlgProc(HWND hwndDlg,
{
case WM_INITDIALOG:
break;
+
case WM_COMMAND:
{
- switch(LOWORD(wParam))
+ switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hwndDlg, IDOK);
@@ -118,38 +121,469 @@ PartitionDlgProc(HWND hwndDlg,
BOOL
-CreateListViewColumns(
+CreateTreeListColumns(
IN HINSTANCE hInstance,
- IN HWND hWndListView,
+ IN HWND hWndTreeList,
IN const UINT* pIDs,
IN const INT* pColsWidth,
IN const INT* pColsAlign,
IN UINT nNumOfColumns)
{
UINT i;
- LVCOLUMN lvC;
+ TLCOLUMN tlC;
WCHAR szText[50];
/* Create the columns */
- lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
- lvC.pszText = szText;
+ tlC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+ tlC.pszText = szText;
/* Load the column labels from the resource file */
for (i = 0; i < nNumOfColumns; i++)
{
- lvC.iSubItem = i;
- lvC.cx = pColsWidth[i];
- lvC.fmt = pColsAlign[i];
+ tlC.iSubItem = i;
+ tlC.cx = pColsWidth[i];
+ tlC.fmt = pColsAlign[i];
LoadStringW(hInstance, pIDs[i], szText, ARRAYSIZE(szText));
- if (ListView_InsertColumn(hWndListView, i, &lvC) == -1)
+ if (TreeList_InsertColumn(hWndTreeList, i, &tlC) == -1)
return FALSE;
}
return TRUE;
}
+// unused
+VOID
+DisplayStuffUsingWin32Setup(HWND hwndDlg)
+{
+ HDEVINFO h;
+ HWND hList;
+ SP_DEVINFO_DATA DevInfoData;
+ DWORD i;
+
+ h = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
+ if (h == INVALID_HANDLE_VALUE)
+ return;
+
+ hList = GetDlgItem(hwndDlg, IDC_PARTITION);
+ DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+ for (i=0; SetupDiEnumDeviceInfo(h, i, &DevInfoData); i++)
+ {
+ DWORD DataT;
+ LPTSTR buffer = NULL;
+ DWORD buffersize = 0;
+
+ while (!SetupDiGetDeviceRegistryProperty(h,
+ &DevInfoData,
+ SPDRP_DEVICEDESC,
+ &DataT,
+ (PBYTE)buffer,
+ buffersize,
+ &buffersize))
+ {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ if (buffer) LocalFree(buffer);
+ buffer = LocalAlloc(LPTR, buffersize * 2);
+ }
+ else
+ {
+ return;
+ }
+ }
+ if (buffer)
+ {
+ SendMessageW(hList, LB_ADDSTRING, (WPARAM)0, (LPARAM)buffer);
+ LocalFree(buffer);
+ }
+ }
+ SetupDiDestroyDeviceInfoList(h);
+}
+
+
+HTLITEM
+TreeListAddItem(IN HWND hTreeList,
+ IN HTLITEM hParent,
+ IN LPWSTR lpText,
+ IN INT iImage,
+ IN INT iSelectedImage,
+ IN LPARAM lParam)
+{
+ TL_INSERTSTRUCTW Insert;
+
+ ZeroMemory(&Insert, sizeof(Insert));
+
+ Insert.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ Insert.hInsertAfter = TVI_LAST;
+ Insert.hParent = hParent;
+ Insert.item.pszText = lpText;
+ Insert.item.iImage = iImage;
+ Insert.item.iSelectedImage = iSelectedImage;
+ Insert.item.lParam = lParam;
+
+ // Insert.item.mask |= TVIF_STATE;
+ // Insert.item.stateMask = TVIS_OVERLAYMASK;
+ // Insert.item.state = INDEXTOOVERLAYMASK(1);
+
+ return TreeList_InsertItem(hTreeList, &Insert);
+}
+
+
+VOID
+GetPartTypeStringFromPartitionType(
+ IN UCHAR partitionType,
+ OUT PCHAR strPartType,
+ IN ULONG cchPartType)
+{
+ /* Determine partition type */
+
+ if (IsContainerPartition(partitionType))
+ {
+ StringCchCopyA(strPartType, cchPartType, "Extended Partition" /*
MUIGetString(STRING_EXTENDED_PARTITION) */);
+ }
+ else if (partitionType == PARTITION_ENTRY_UNUSED)
+ {
+ StringCchCopyA(strPartType, cchPartType, "Unused" /*
MUIGetString(STRING_FORMATUNUSED) */);
+ }
+ else
+ {
+ UINT i;
+
+ /* Do the table lookup */
+ for (i = 0; i < ARRAYSIZE(PartitionTypes); i++)
+ {
+ if (partitionType == PartitionTypes[i].Type)
+ {
+ StringCchCopyA(strPartType, cchPartType, PartitionTypes[i].Description);
+ return;
+ }
+ }
+
+ /* We are here because the partition type is unknown */
+ StringCchCopyA(strPartType, cchPartType, "Unknown" /*
MUIGetString(STRING_FORMATUNKNOWN) */);
+ }
+}
+
+static
+HTLITEM
+PrintPartitionData(
+ IN HWND hWndList,
+ IN PPARTLIST List,
+ IN HTLITEM htiParent,
+ IN PDISKENTRY DiskEntry,
+ IN PPARTENTRY PartEntry)
+{
+ LARGE_INTEGER PartSize;
+ HTLITEM htiPart;
+ CHAR PartTypeString[32];
+ PCHAR PartType = PartTypeString;
+ WCHAR LineBuffer[128];
+
+ /* Volume name */
+ if (PartEntry->IsPartitioned == FALSE)
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_UNPSPACE),
+ L"Unpartitioned space");
+ }
+ else
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDDINFOUNK5),
+ L"%s (%c%c)",
+ *PartEntry->VolumeLabel ? PartEntry->VolumeLabel :
L"Partition",
+ (PartEntry->DriveLetter == 0) ? L'-' :
PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? L'-' :
L':');
+ }
+
+ htiPart = TreeListAddItem(hWndList, htiParent, LineBuffer,
+ 1, 1,
+ (LPARAM)PartEntry);
+
+ /* Determine partition type */
+ *LineBuffer = 0;
+ if (PartEntry->IsPartitioned)
+ {
+ PartTypeString[0] = '\0';
+ if (PartEntry->New == TRUE)
+ {
+ PartType = "New (Unformatted)"; //
MUIGetString(STRING_UNFORMATTED);
+ }
+ else if (PartEntry->IsPartitioned == TRUE)
+ {
+ GetPartTypeStringFromPartitionType(PartEntry->PartitionType,
+ PartTypeString,
+ ARRAYSIZE(PartTypeString));
+ PartType = PartTypeString;
+ }
+
+ if (strcmp(PartType, "Unknown" /* MUIGetString(STRING_FORMATUNKNOWN)
*/) == 0)
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDDINFOUNK5),
+ L"Type 0x%02x",
+ PartEntry->PartitionType);
+ }
+ else
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ L"%S",
+ PartType);
+ }
+ }
+ TreeList_SetItemText(hWndList, htiPart, 1, LineBuffer);
+
+ /* Format the disk size in KBs, MBs, etc... */
+ PartSize.QuadPart = PartEntry->SectorCount.QuadPart *
DiskEntry->BytesPerSector;
+ if (StrFormatByteSizeW(PartSize.QuadPart, LineBuffer, ARRAYSIZE(LineBuffer)) ==
NULL)
+ {
+ /* We failed for whatever reason, do the hardcoded way */
+ PWCHAR Unit;
+
+#if 0
+ if (PartSize.QuadPart >= 10 * GB) /* 10 GB */
+ {
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, GB);
+ // Unit = MUIGetString(STRING_GB);
+ Unit = L"GB";
+ }
+ else
+#endif
+ if (PartSize.QuadPart >= 10 * MB) /* 10 MB */
+ {
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, MB);
+ // Unit = MUIGetString(STRING_MB);
+ Unit = L"MB";
+ }
+ else
+ {
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, KB);
+ // Unit = MUIGetString(STRING_KB);
+ Unit = L"KB";
+ }
+
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ L"%6lu %s",
+ PartSize.u.LowPart,
+ Unit);
+ }
+ TreeList_SetItemText(hWndList, htiPart, 2, LineBuffer);
+
+ /* Volume status */
+ *LineBuffer = 0;
+ if (PartEntry->IsPartitioned)
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDDINFOUNK5),
+ PartEntry->BootIndicator ? L"Active" :
L"");
+ }
+ TreeList_SetItemText(hWndList, htiPart, 3, LineBuffer);
+
+ return htiPart;
+}
+
+static
+VOID
+PrintDiskData(
+ IN HWND hWndList,
+ IN PPARTLIST List,
+ IN PDISKENTRY DiskEntry)
+{
+ BOOL Success;
+ HANDLE hDevice;
+ PCHAR DiskName = NULL;
+ ULONG Length = 0;
+ PPARTENTRY PrimaryPartEntry, LogicalPartEntry;
+ PLIST_ENTRY PrimaryEntry, LogicalEntry;
+ ULARGE_INTEGER DiskSize;
+ HTLITEM htiDisk, htiPart;
+ WCHAR LineBuffer[128];
+ UCHAR outBuf[512];
+
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // L"\\Device\\Harddisk%lu\\Partition%lu",
+ L"\\\\.\\PhysicalDrive%lu",
+ DiskEntry->DiskNumber);
+
+ hDevice = CreateFileW(
+ LineBuffer, // device interface name
+ GENERIC_READ /*| GENERIC_WRITE*/, // dwDesiredAccess
+ FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING, // dwCreationDistribution
+ 0, // dwFlagsAndAttributes
+ NULL // hTemplateFile
+ );
+ if (hDevice != INVALID_HANDLE_VALUE)
+ {
+ STORAGE_PROPERTY_QUERY Query;
+
+ Query.PropertyId = StorageDeviceProperty;
+ Query.QueryType = PropertyStandardQuery;
+
+ Success = DeviceIoControl(hDevice,
+ IOCTL_STORAGE_QUERY_PROPERTY,
+ &Query,
+ sizeof(Query),
+ &outBuf,
+ sizeof(outBuf),
+ &Length,
+ NULL);
+ if (Success)
+ {
+ PSTORAGE_DEVICE_DESCRIPTOR devDesc = (PSTORAGE_DEVICE_DESCRIPTOR)outBuf;
+ if (devDesc->ProductIdOffset)
+ {
+ DiskName = (PCHAR)&outBuf[devDesc->ProductIdOffset];
+ Length -= devDesc->ProductIdOffset;
+ DiskName[min(Length, strlen(DiskName))] = 0;
+ // ( i = devDesc->ProductIdOffset; p[i] != 0 && i < Length;
i++ )
+ }
+ }
+
+ CloseHandle(hDevice);
+ }
+
+ if (DiskName && *DiskName)
+ {
+ if (DiskEntry->DriverName.Length > 0)
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDINFOPARTSELECT_1),
+ L"Harddisk %lu (%S) (Port=%hu, Bus=%hu, Id=%hu) on
%wZ",
+ DiskEntry->DiskNumber,
+ DiskName,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id,
+ &DiskEntry->DriverName);
+ }
+ else
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDINFOPARTSELECT_2),
+ L"Harddisk %lu (%S) (Port=%hu, Bus=%hu, Id=%hu)",
+ DiskEntry->DiskNumber,
+ DiskName,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id);
+ }
+ }
+ else
+ {
+ if (DiskEntry->DriverName.Length > 0)
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDINFOPARTSELECT_1),
+ L"Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on
%wZ",
+ DiskEntry->DiskNumber,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id,
+ &DiskEntry->DriverName);
+ }
+ else
+ {
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ // MUIGetString(STRING_HDINFOPARTSELECT_2),
+ L"Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
+ DiskEntry->DiskNumber,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id);
+ }
+ }
+
+ htiDisk = TreeListAddItem(hWndList, NULL, LineBuffer,
+ 0, 0,
+ (LPARAM)DiskEntry);
+
+ /* Disk type (MBR or GPT) */
+ TreeList_SetItemText(hWndList, htiDisk, 1, DiskEntry->NoMbr ? L"GPT" :
L"MBR");
+
+ /* Format the disk size in KBs, MBs, etc... */
+ DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart *
DiskEntry->BytesPerSector;
+ if (StrFormatByteSizeW(DiskSize.QuadPart, LineBuffer, ARRAYSIZE(LineBuffer)) ==
NULL)
+ {
+ /* We failed for whatever reason, do the hardcoded way */
+ PWCHAR Unit;
+
+ if (DiskSize.QuadPart >= 10 * GB) /* 10 GB */
+ {
+ DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, GB);
+ // Unit = MUIGetString(STRING_GB);
+ Unit = L"GB";
+ }
+ else
+ {
+ DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, MB);
+ if (DiskSize.QuadPart == 0)
+ DiskSize.QuadPart = 1;
+ // Unit = MUIGetString(STRING_MB);
+ Unit = L"MB";
+ }
+
+ StringCchPrintfW(LineBuffer, ARRAYSIZE(LineBuffer),
+ L"%6lu %s",
+ DiskSize.u.LowPart,
+ Unit);
+ }
+ TreeList_SetItemText(hWndList, htiDisk, 2, LineBuffer);
+
+
+ /* Print partition lines */
+ for (PrimaryEntry = DiskEntry->PrimaryPartListHead.Flink;
+ PrimaryEntry != &DiskEntry->PrimaryPartListHead;
+ PrimaryEntry = PrimaryEntry->Flink)
+ {
+ PrimaryPartEntry = CONTAINING_RECORD(PrimaryEntry, PARTENTRY, ListEntry);
+
+ htiPart = PrintPartitionData(hWndList, List, htiDisk,
+ DiskEntry, PrimaryPartEntry);
+
+ if (IsContainerPartition(PrimaryPartEntry->PartitionType))
+ {
+ for (LogicalEntry = DiskEntry->LogicalPartListHead.Flink;
+ LogicalEntry != &DiskEntry->LogicalPartListHead;
+ LogicalEntry = LogicalEntry->Flink)
+ {
+ LogicalPartEntry = CONTAINING_RECORD(LogicalEntry, PARTENTRY,
ListEntry);
+
+ PrintPartitionData(hWndList, List, htiPart,
+ DiskEntry, LogicalPartEntry);
+ }
+
+ /* Expand the extended partition node */
+ TreeList_Expand(hWndList, htiPart, TVE_EXPAND);
+ }
+ }
+
+ /* Expand the disk node */
+ TreeList_Expand(hWndList, htiDisk, TVE_EXPAND);
+}
+
+VOID
+DrawPartitionList(
+ IN HWND hWndList,
+ IN PPARTLIST List)
+{
+ PLIST_ENTRY Entry;
+ PDISKENTRY DiskEntry;
+
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
+ {
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+
+ /* Print disk entry */
+ PrintDiskData(hWndList, List, DiskEntry);
+ }
+}
+
+
INT_PTR
CALLBACK
@@ -160,12 +594,8 @@ DriveDlgProc(
LPARAM lParam)
{
PSETUPDATA pSetupData;
-#if 1
- HDEVINFO h;
HWND hList;
- SP_DEVINFO_DATA DevInfoData;
- DWORD i;
-#endif
+ HIMAGELIST hSmall;
/* Retrieve pointer to the global setup data */
pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
@@ -178,70 +608,70 @@ DriveDlgProc(
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
- CreateListViewColumns(pSetupData->hInstance,
- GetDlgItem(hwndDlg, IDC_PARTITION),
+ /*
+ * Keep the "Next" button disabled. It will be enabled only
+ * when the user selects a valid partition.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+
+ hList = GetDlgItem(hwndDlg, IDC_PARTITION);
+
+ TreeList_SetExtendedStyleEx(hList, TVS_EX_FULLROWMARK, TVS_EX_FULLROWMARK);
+ // TreeList_SetExtendedStyleEx(hList, TVS_EX_FULLROWITEMS,
TVS_EX_FULLROWITEMS);
+
+ CreateTreeListColumns(pSetupData->hInstance,
+ hList,
column_ids,
column_widths,
column_alignment,
MAX_LIST_COLUMNS);
-#if 1
- h = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL,
DIGCF_PRESENT);
- if (h != INVALID_HANDLE_VALUE)
- {
- hList =GetDlgItem(hwndDlg, IDC_PARTITION);
- DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
- for (i=0; SetupDiEnumDeviceInfo(h, i, &DevInfoData); i++)
- {
- DWORD DataT;
- LPTSTR buffer = NULL;
- DWORD buffersize = 0;
-
- while (!SetupDiGetDeviceRegistryProperty(h,
- &DevInfoData,
- SPDRP_DEVICEDESC,
- &DataT,
- (PBYTE)buffer,
- buffersize,
- &buffersize))
- {
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- if (buffer) LocalFree(buffer);
- buffer = LocalAlloc(LPTR, buffersize * 2);
- }
- else
- break;
- }
- if (buffer)
- {
- SendMessageW(hList, LB_ADDSTRING, (WPARAM) 0, (LPARAM) buffer);
- LocalFree(buffer);
- }
- }
- SetupDiDestroyDeviceInfoList(h);
- }
-#endif
+ /* 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_DISKDRIVE)));
+ ImageList_AddIcon(hSmall, LoadIconW(pSetupData->hInstance,
MAKEINTRESOURCEW(IDI_PARTITION)));
+
+ /* Assign the ImageList to the List View */
+ TreeList_SetImageList(hList, hSmall, TVSIL_NORMAL);
+
+ // DisplayStuffUsingWin32Setup(hwndDlg);
+ DrawPartitionList(hList, pSetupData->PartitionList);
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ hList = GetDlgItem(hwndDlg, IDC_PARTITION);
+ hSmall = TreeList_GetImageList(hList, TVSIL_NORMAL);
+ TreeList_SetImageList(hList, NULL, TVSIL_NORMAL);
+ ImageList_Destroy(hSmall);
+ return TRUE;
}
- break;
case WM_COMMAND:
{
- switch(LOWORD(wParam))
+ switch (LOWORD(wParam))
{
case IDC_PARTMOREOPTS:
- DialogBoxParam(pSetupData->hInstance,
- MAKEINTRESOURCE(IDD_BOOTOPTIONS),
- hwndDlg,
- MoreOptDlgProc,
- (LPARAM)pSetupData);
+ DialogBoxParamW(pSetupData->hInstance,
+ MAKEINTRESOURCEW(IDD_BOOTOPTIONS),
+ hwndDlg,
+ MoreOptDlgProc,
+ (LPARAM)pSetupData);
break;
+
case IDC_PARTCREATE:
- DialogBox(pSetupData->hInstance,
- MAKEINTRESOURCE(IDD_PARTITION),
- hwndDlg,
- PartitionDlgProc);
+ DialogBoxW(pSetupData->hInstance,
+ MAKEINTRESOURCEW(IDD_PARTITION),
+ hwndDlg,
+ PartitionDlgProc);
break;
+
case IDC_PARTDELETE:
break;
}
@@ -252,11 +682,83 @@ DriveDlgProc(
{
LPNMHDR lpnm = (LPNMHDR)lParam;
+ // On Vista+ we can use TVN_ITEMCHANGED instead, with NMTVITEMCHANGE*
pointer
+ if (lpnm->idFrom == IDC_PARTITION && lpnm->code ==
TVN_SELCHANGED)
+ {
+ LPNMTREEVIEW pnmv = (LPNMTREEVIEW)lParam;
+
+ // if (pnmv->uChanged & TVIF_STATE) /* The state has changed */
+ if (pnmv->itemNew.mask & TVIF_STATE)
+ {
+ /* The item has been (de)selected */
+ // if (pnmv->uNewState & TVIS_SELECTED)
+ if (pnmv->itemNew.state & TVIS_SELECTED)
+ {
+ HTLITEM hParentItem = TreeList_GetParent(lpnm->hwndFrom,
pnmv->itemNew.hItem);
+ /* May or may not be a PPARTENTRY: this is a PPARTENTRY only when
hParentItem != NULL */
+ PPARTENTRY PartEntry = (PPARTENTRY)pnmv->itemNew.lParam;
+
+ if (!hParentItem || !PartEntry)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PARTCREATE), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PARTDELETE), FALSE);
+ goto DisableWizNext;
+ }
+ else // if (hParentItem && PartEntry)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PARTCREATE),
!PartEntry->IsPartitioned);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PARTDELETE),
PartEntry->IsPartitioned);
+
+ if (PartEntry->IsPartitioned &&
+ !IsContainerPartition(PartEntry->PartitionType) /*
alternatively: PartEntry->PartitionNumber != 0 */ &&
+ // !PartEntry->New &&
+ (PartEntry->FormatState == Preformatted /* ||
PartEntry->FormatState == Formatted */))
+ {
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ }
+ else
+ {
+ goto DisableWizNext;
+ }
+ }
+ }
+ else
+ {
+DisableWizNext:
+ /*
+ * Keep the "Next" button disabled. It will be enabled
only
+ * when the user selects a valid partition.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+ }
+ }
+
+ break;
+ }
+
switch (lpnm->code)
- {
+ {
+#if 0
case PSN_SETACTIVE:
- PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ {
+ /*
+ * Keep the "Next" button disabled. It will be enabled
only
+ * when the user selects a valid partition.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
break;
+ }
+#endif
+
+ case PSN_QUERYINITIALFOCUS:
+ {
+ /* Give the focus on and select the first item */
+ hList = GetDlgItem(hwndDlg, IDC_PARTITION);
+ // TreeList_SetFocusItem(hList, 1, 1);
+ TreeList_SelectItem(hList, 1);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)hList);
+ return TRUE;
+ }
case PSN_QUERYCANCEL:
{
@@ -274,6 +776,28 @@ DriveDlgProc(
return TRUE;
}
+ case PSN_WIZNEXT: /* Set the selected data */
+ {
+ NTSTATUS Status;
+
+ /****/
+ // FIXME: This is my test disk encoding!
+ DISKENTRY DiskEntry;
+ PARTENTRY PartEntry;
+ DiskEntry.DiskNumber = 0;
+ DiskEntry.BiosDiskNumber = 0;
+ PartEntry.PartitionNumber = 1; // 4;
+ /****/
+
+ Status = InitDestinationPaths(&pSetupData->USetupData,
+ NULL, //
pSetupData->USetupData.InstallationDirectory,
+ &DiskEntry, &PartEntry);
+ // TODO: Check Status
+ UNREFERENCED_PARAMETER(Status);
+
+ break;
+ }
+
default:
break;
}
@@ -282,7 +806,6 @@ DriveDlgProc(
default:
break;
-
}
return FALSE;
diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c
index 230eafa38c..55b18a227e 100644
--- a/base/setup/reactos/reactos.c
+++ b/base/setup/reactos/reactos.c
@@ -124,15 +124,15 @@ StartDlgProc(
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
- /* Center the wizard window */
- CenterWindow(GetParent(hwndDlg));
-
/* Set title font */
SendDlgItemMessage(hwndDlg,
IDC_STARTTITLE,
WM_SETFONT,
(WPARAM)pSetupData->hTitleFont,
(LPARAM)TRUE);
+
+ /* Center the wizard window */
+ CenterWindow(GetParent(hwndDlg));
break;
}
@@ -212,6 +212,13 @@ TypeDlgProc(
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
break;
+ case PSN_QUERYINITIALFOCUS:
+ {
+ /* Focus on "Install ReactOS" */
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
(LONG_PTR)GetDlgItem(hwndDlg, IDC_INSTALL));
+ return TRUE;
+ }
+
case PSN_QUERYCANCEL:
{
if (MessageBoxW(GetParent(hwndDlg),
@@ -230,23 +237,40 @@ TypeDlgProc(
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.
+ * Go update only if we have available NT installations
+ * and we choose to do so.
*/
if (pSetupData->NtOsInstallsList &&
- GetNumberOfListEntries(pSetupData->NtOsInstallsList) > 1)
+ GetNumberOfListEntries(pSetupData->NtOsInstallsList) != 0
&&
+ IsDlgButtonChecked(hwndDlg, IDC_UPDATE) == BST_CHECKED)
{
- /* Actually the best would be to dynamically insert the page only
when needed */
- SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT,
IDD_UPDATEREPAIRPAGE);
+ pSetupData->RepairUpdateFlag = TRUE;
+
+ /*
+ * Display the existing NT installations page only
+ * if we have more than one available NT installations.
+ */
+ if (GetNumberOfListEntries(pSetupData->NtOsInstallsList) >
1)
+ {
+ /* pSetupData->CurrentInstallation will be set from within
IDD_UPDATEREPAIRPAGE */
+
+ /* Actually the best would be to dynamically insert the page
only when needed */
+ SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT,
IDD_UPDATEREPAIRPAGE);
+ }
+ else
+ {
+ /* Retrieve the current installation */
+ pSetupData->CurrentInstallation =
+
(PNTOS_INSTALLATION)GetListEntryData(GetCurrentListEntry(pSetupData->NtOsInstallsList));
+
+ SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, IDD_DEVICEPAGE);
+ }
}
else
{
+ pSetupData->CurrentInstallation = NULL;
+ pSetupData->RepairUpdateFlag = FALSE;
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, IDD_DEVICEPAGE);
}
@@ -268,6 +292,39 @@ TypeDlgProc(
+BOOL
+CreateListViewColumns(
+ IN HINSTANCE hInstance,
+ IN HWND hWndListView,
+ IN const UINT* pIDs,
+ IN const INT* pColsWidth,
+ IN const INT* pColsAlign,
+ IN UINT nNumOfColumns)
+{
+ UINT i;
+ LVCOLUMN lvC;
+ WCHAR szText[50];
+
+ /* Create the columns */
+ lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+ lvC.pszText = szText;
+
+ /* Load the column labels from the resource file */
+ for (i = 0; i < nNumOfColumns; i++)
+ {
+ lvC.iSubItem = i;
+ lvC.cx = pColsWidth[i];
+ lvC.fmt = pColsAlign[i];
+
+ LoadStringW(hInstance, pIDs[i], szText, ARRAYSIZE(szText));
+
+ if (ListView_InsertColumn(hWndListView, i, &lvC) == -1)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
typedef VOID
(NTAPI *PGET_ENTRY_DESCRIPTION)(
IN PGENERIC_LIST_ENTRY Entry,
@@ -312,19 +369,17 @@ InitGenericComboList(
SendMessageW(hWndList, CB_SETCURSEL, CurrentEntryIndex, 0);
}
-INT
+PVOID
GetSelectedComboListItem(
IN HWND hWndList)
{
- LRESULT Index;
+ INT Index;
- Index = SendMessageW(hWndList, CB_GETCURSEL, 0, 0);
+ Index = ComboBox_GetCurSel(hWndList);
if (Index == CB_ERR)
- return CB_ERR;
+ return NULL;
- // TODO: Update List->CurrentEntry?
- // return SendMessageW(hWndList, CB_GETITEMDATA, (WPARAM)Index, 0);
- return Index;
+ return (PVOID)ComboBox_GetItemData(hWndList, Index);
}
typedef VOID
@@ -366,9 +421,28 @@ InitGenericListView(
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);
+ ListView_EnsureVisible(hWndList, CurrentEntryIndex, FALSE);
+ ListView_SetItemState(hWndList, CurrentEntryIndex,
+ LVIS_FOCUSED | LVIS_SELECTED,
+ LVIS_FOCUSED | LVIS_SELECTED);
+}
+
+PVOID
+GetSelectedListViewItem(
+ IN HWND hWndList)
+{
+ INT Index;
+ LVITEM item;
+
+ Index = ListView_GetSelectionMark(hWndList);
+ if (Index == LB_ERR)
+ return NULL;
+
+ item.mask = LVIF_PARAM;
+ item.iItem = Index;
+ ListView_GetItem(hWndList, &item);
+
+ return (PVOID)item.lParam;
}
@@ -399,7 +473,7 @@ AddNTOSInstallationItem(
{
/* We have retrieved a partition that is mounted */
StringCchPrintfW(Buffer, cchBufferSize,
- L"%C:%s",
+ L"%c:%s",
PartEntry->DriveLetter,
NtOsInstall->PathComponent);
}
@@ -471,8 +545,16 @@ UpgradeRepairDlgProc(
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
+ /*
+ * Keep the "Next" button disabled. It will be enabled only
+ * when the user selects an installation to upgrade.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+
hList = GetDlgItem(hwndDlg, IDC_NTOSLIST);
+ ListView_SetExtendedListViewStyleEx(hList, LVS_EX_FULLROWSELECT,
LVS_EX_FULLROWSELECT);
+
CreateListViewColumns(pSetupData->hInstance,
hList,
column_ids,
@@ -494,7 +576,6 @@ UpgradeRepairDlgProc(
ListView_SetImageList(hList, hSmall, LVSIL_SMALL);
InitGenericListView(hList, pSetupData->NtOsInstallsList,
AddNTOSInstallationItem);
-
break;
}
@@ -507,15 +588,70 @@ UpgradeRepairDlgProc(
return TRUE;
}
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_SKIPUPGRADE:
+ {
+ /* Skip the upgrade and do the usual new-installation workflow */
+ pSetupData->CurrentInstallation = NULL;
+ pSetupData->RepairUpdateFlag = FALSE;
+ PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_DEVICEPAGE);
+ return TRUE;
+ }
+ }
+ break;
+
case WM_NOTIFY:
{
LPNMHDR lpnm = (LPNMHDR)lParam;
+ if (lpnm->idFrom == IDC_NTOSLIST && lpnm->code ==
LVN_ITEMCHANGED)
+ {
+ LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
+
+ if (pnmv->uChanged & LVIF_STATE) /* The state has changed */
+ {
+ /* The item has been (de)selected */
+ if (pnmv->uNewState & (LVIS_FOCUSED | LVIS_SELECTED))
+ {
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ }
+ else
+ {
+ /*
+ * Keep the "Next" button disabled. It will be enabled
only
+ * when the user selects an installation to upgrade.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+ }
+ }
+
+ break;
+ }
+
switch (lpnm->code)
{
+#if 0
case PSN_SETACTIVE:
- PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ {
+ /*
+ * Keep the "Next" button disabled. It will be enabled
only
+ * when the user selects an installation to upgrade.
+ */
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
break;
+ }
+#endif
+
+ case PSN_QUERYINITIALFOCUS:
+ {
+ /* Give the focus on and select the first item */
+ hList = GetDlgItem(hwndDlg, IDC_NTOSLIST);
+ ListView_SetItemState(hList, 0, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)hList);
+ return TRUE;
+ }
case PSN_QUERYCANCEL:
{
@@ -534,11 +670,31 @@ UpgradeRepairDlgProc(
}
case PSN_WIZNEXT: /* Set the selected data */
- pSetupData->RepairUpdateFlag =
- !(SendMessageW(GetDlgItem(hwndDlg, IDC_INSTALL),
- BM_GETCHECK,
- 0, 0) == BST_CHECKED);
+ {
+ /*
+ * Go update only if we have available NT installations
+ * and we choose to do so.
+ */
+ if (!pSetupData->NtOsInstallsList ||
+ GetNumberOfListEntries(pSetupData->NtOsInstallsList) == 0)
+ {
+ pSetupData->CurrentInstallation = NULL;
+ pSetupData->RepairUpdateFlag = FALSE;
+ break;
+ }
+
+ hList = GetDlgItem(hwndDlg, IDC_NTOSLIST);
+ SetCurrentListEntry(pSetupData->NtOsInstallsList,
+ GetSelectedListViewItem(hList));
+
+ /* Retrieve the current installation */
+ pSetupData->CurrentInstallation =
+
(PNTOS_INSTALLATION)GetListEntryData(GetCurrentListEntry(pSetupData->NtOsInstallsList));
+
+ /* We perform an upgrade */
+ pSetupData->RepairUpdateFlag = TRUE;
return TRUE;
+ }
default:
break;
@@ -599,6 +755,13 @@ DeviceDlgProc(
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
break;
+ case PSN_QUERYINITIALFOCUS:
+ {
+ /* Focus on "Computer" list */
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
(LONG_PTR)GetDlgItem(hwndDlg, IDC_COMPUTER));
+ return TRUE;
+ }
+
case PSN_QUERYCANCEL:
{
if (MessageBoxW(GetParent(hwndDlg),
@@ -618,13 +781,20 @@ DeviceDlgProc(
case PSN_WIZNEXT: /* Set the selected data */
{
hList = GetDlgItem(hwndDlg, IDC_COMPUTER);
- pSetupData->SelectedComputer = GetSelectedComboListItem(hList);
+ SetCurrentListEntry(pSetupData->USetupData.ComputerList,
+ GetSelectedComboListItem(hList));
hList = GetDlgItem(hwndDlg, IDC_DISPLAY);
- pSetupData->SelectedDisplay = GetSelectedComboListItem(hList);
+ SetCurrentListEntry(pSetupData->USetupData.DisplayList,
+ GetSelectedComboListItem(hList));
hList = GetDlgItem(hwndDlg, IDC_KEYBOARD);
- pSetupData->SelectedKeyboard = GetSelectedComboListItem(hList);
+ SetCurrentListEntry(pSetupData->USetupData.KeyboardList,
+ GetSelectedComboListItem(hList));
+
+ // hList = GetDlgItem(hwndDlg, IDC_KEYBOARD_LAYOUT);
+ // SetCurrentListEntry(pSetupData->USetupData.LayoutList,
+ // GetSelectedComboListItem(hList));
return TRUE;
}
@@ -649,6 +819,8 @@ SummaryDlgProc(
IN WPARAM wParam,
IN LPARAM lParam)
{
+ static WCHAR szOrgWizNextBtnText[260]; // TODO: Make it dynamic
+
PSETUPDATA pSetupData;
/* Retrieve pointer to the global setup data */
@@ -657,10 +829,24 @@ SummaryDlgProc(
switch (uMsg)
{
case WM_INITDIALOG:
+ {
/* Save pointer to the global setup data */
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
break;
+ }
+
+ case WM_COMMAND:
+ {
+ if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) ==
IDC_CONFIRM_INSTALL)
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_CONFIRM_INSTALL) == BST_CHECKED)
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ else
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+ }
+ break;
+ }
case WM_NOTIFY:
{
@@ -669,8 +855,92 @@ SummaryDlgProc(
switch (lpnm->code)
{
case PSN_SETACTIVE:
- PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK |
PSWIZB_NEXT);
+ {
+ WCHAR CurrentItemText[256];
+
+ /* Show the current selected settings */
+
+ // FIXME! Localize
+ if (pSetupData->RepairUpdateFlag)
+ {
+ StringCchPrintfW(CurrentItemText, ARRAYSIZE(CurrentItemText),
+ L"Upgrading/Repairing \"%s\" from
\"%s\"",
+
pSetupData->CurrentInstallation->InstallationName,
+
pSetupData->CurrentInstallation->VendorName);
+ }
+ else
+ {
+ StringCchCopyW(CurrentItemText, ARRAYSIZE(CurrentItemText),
+ L"New ReactOS installation");
+ }
+ SetDlgItemTextW(hwndDlg, IDC_INSTALLTYPE, CurrentItemText);
+
+ SetDlgItemTextW(hwndDlg, IDC_INSTALLSOURCE, L"n/a");
+ SetDlgItemTextW(hwndDlg, IDC_ARCHITECTURE, L"n/a");
+
+
GetSettingDescription(GetCurrentListEntry(pSetupData->USetupData.ComputerList),
+ CurrentItemText,
+ ARRAYSIZE(CurrentItemText));
+ SetDlgItemTextW(hwndDlg, IDC_COMPUTER, CurrentItemText);
+
+
GetSettingDescription(GetCurrentListEntry(pSetupData->USetupData.DisplayList),
+ CurrentItemText,
+ ARRAYSIZE(CurrentItemText));
+ SetDlgItemTextW(hwndDlg, IDC_DISPLAY, CurrentItemText);
+
+
GetSettingDescription(GetCurrentListEntry(pSetupData->USetupData.KeyboardList),
+ CurrentItemText,
+ ARRAYSIZE(CurrentItemText));
+ SetDlgItemTextW(hwndDlg, IDC_KEYBOARD, CurrentItemText);
+
+ if (L'C') // FIXME!
+ {
+ StringCchPrintfW(CurrentItemText, ARRAYSIZE(CurrentItemText),
+ L"%c: \x2014 %wZ",
+ L'C', // FIXME!
+
&pSetupData->USetupData.DestinationRootPath);
+ }
+ else
+ {
+ StringCchPrintfW(CurrentItemText, ARRAYSIZE(CurrentItemText),
+ L"%wZ",
+
&pSetupData->USetupData.DestinationRootPath);
+ }
+ SetDlgItemTextW(hwndDlg, IDC_DESTDRIVE, CurrentItemText);
+
+ SetDlgItemTextW(hwndDlg, IDC_PATH,
+ /*pSetupData->USetupData.InstallationDirectory*/
+ pSetupData->USetupData.InstallPath.Buffer);
+
+
+ /* Change the "Next" button text to "Install" */
+ // PropSheet_SetNextText(GetParent(hwndDlg), ...);
+ GetDlgItemTextW(GetParent(hwndDlg), ID_WIZNEXT,
+ szOrgWizNextBtnText,
ARRAYSIZE(szOrgWizNextBtnText));
+ SetDlgItemTextW(GetParent(hwndDlg), ID_WIZNEXT,
L"Install"); // FIXME: Localize!
+
+ /*
+ * Keep the "Next" button disabled. It will be enabled
only
+ * when the user clicks on the installation approval checkbox.
+ */
+ CheckDlgButton(hwndDlg, IDC_CONFIRM_INSTALL, BST_UNCHECKED);
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
break;
+ }
+
+ case PSN_QUERYINITIALFOCUS:
+ {
+ /* Focus on the confirmation check-box */
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
(LONG_PTR)GetDlgItem(hwndDlg, IDC_CONFIRM_INSTALL));
+ return TRUE;
+ }
+
+ case PSN_KILLACTIVE:
+ {
+ /* Restore the original "Next" button text */
+ SetDlgItemTextW(GetParent(hwndDlg), ID_WIZNEXT,
szOrgWizNextBtnText);
+ break;
+ }
case PSN_QUERYCANCEL:
{
@@ -691,8 +961,8 @@ SummaryDlgProc(
default:
break;
}
+ break;
}
- break;
default:
break;
@@ -832,13 +1102,18 @@ PrepareAndDoCopyThread(
/* Retrieve pointer to the global setup data */
pSetupData = (PSETUPDATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
+ /* Get the progress handle */
+ hWndProgress = GetDlgItem(hwndDlg, IDC_PROCESSPROGRESS);
+
+
+ /*
+ * Preparation of the list of files to be copied
+ */
+
/* Set status text */
SetDlgItemTextW(hwndDlg, IDC_ACTIVITY, L"Preparing the list of files to be
copied, please wait...");
SetDlgItemTextW(hwndDlg, IDC_ITEM, L"");
- /* Get the progress handle */
- hWndProgress = GetDlgItem(hwndDlg, IDC_PROCESSPROGRESS);
-
/* Set progress marquee style */
dwStyle = GetWindowLongPtrW(hWndProgress, GWL_STYLE);
SetWindowLongPtrW(hWndProgress, GWL_STYLE, dwStyle | PBS_MARQUEE);
@@ -876,8 +1151,14 @@ PrepareAndDoCopyThread(
/* Restore progress style */
SetWindowLongPtrW(hWndProgress, GWL_STYLE, dwStyle);
+
+ /*
+ * Perform the file copy
+ */
+
/* Set status text */
SetDlgItemTextW(hwndDlg, IDC_ACTIVITY, L"Copying the files...");
+ SetDlgItemTextW(hwndDlg, IDC_ITEM, L"");
/* Create context for the copy process */
CopyContext.pSetupData = pSetupData;
@@ -932,16 +1213,6 @@ ProcessDlgProc(
{
case WM_INITDIALOG:
{
- NTSTATUS Status;
- /****/
- // FIXME: This is my disk encoding!
- DISKENTRY DiskEntry;
- PARTENTRY PartEntry;
- DiskEntry.DiskNumber = 1;
- DiskEntry.BiosDiskNumber = 1;
- PartEntry.PartitionNumber = 4;
- /****/
-
/* Save pointer to the global setup data */
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
@@ -950,10 +1221,6 @@ ProcessDlgProc(
SetDlgItemTextW(hwndDlg, IDC_ACTIVITY, L"");
SetDlgItemTextW(hwndDlg, IDC_ITEM, L"");
- Status = InitDestinationPaths(&pSetupData->USetupData, NULL
/*InstallDir*/, &DiskEntry, &PartEntry);
- // TODO: Check Status
- UNREFERENCED_PARAMETER(Status);
-
break;
}
@@ -1069,11 +1336,11 @@ RestartDlgProc(
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
/* Set title font */
- /*SendDlgItemMessage(hwndDlg,
- IDC_STARTTITLE,
- WM_SETFONT,
- (WPARAM)hTitleFont,
- (LPARAM)TRUE);*/
+ SendDlgItemMessage(hwndDlg,
+ IDC_FINISHTITLE,
+ WM_SETFONT,
+ (WPARAM)pSetupData->hTitleFont,
+ (LPARAM)TRUE);
break;
case WM_TIMER:
@@ -1104,12 +1371,18 @@ RestartDlgProc(
switch (lpnm->code)
{
- case PSN_SETACTIVE: // Only "Finish" for closing the App
+ case PSN_SETACTIVE:
+ {
+ /* Only "Finish" for closing the wizard */
+ ShowWindow(GetDlgItem(GetParent(hwndDlg), IDCANCEL), SW_HIDE);
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
+
+ /* Set up the reboot progress bar */
SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
MAKELPARAM(0, 300));
SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
SetTimer(hwndDlg, 1, 50, NULL);
break;
+ }
default:
break;
@@ -1509,6 +1782,55 @@ Quit:
return Success;
}
+/* Copied from HotkeyThread() in dll/win32/syssetup/install.c */
+static DWORD CALLBACK
+HotkeyThread(LPVOID Parameter)
+{
+ ATOM hotkey;
+ MSG msg;
+
+ DPRINT("HotkeyThread start\n");
+
+ hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey");
+
+ if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10))
+ DPRINT1("RegisterHotKey failed with %lu\n", GetLastError());
+
+ while (GetMessageW(&msg, NULL, 0, 0))
+ {
+ if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam ==
hotkey)
+ {
+ STARTUPINFOW si = { sizeof(si) };
+ PROCESS_INFORMATION pi;
+
+ if (CreateProcessW(L"cmd.exe",
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_NEW_CONSOLE,
+ NULL,
+ NULL,
+ &si,
+ &pi))
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ else
+ {
+ DPRINT1("Failed to launch command prompt: %lu\n",
GetLastError());
+ }
+ }
+ }
+
+ UnregisterHotKey(NULL, hotkey);
+ GlobalDeleteAtom(hotkey);
+
+ DPRINT("HotkeyThread terminate\n");
+ return 0;
+}
+
int WINAPI
_tWinMain(HINSTANCE hInst,
HINSTANCE hPrevInstance,
@@ -1516,6 +1838,7 @@ _tWinMain(HINSTANCE hInst,
int nCmdShow)
{
ULONG Error;
+ HANDLE hHotkeyThread;
INITCOMMONCONTROLSEX iccx;
PROPSHEETHEADER psh;
HPROPSHEETPAGE ahpsp[8];
@@ -1556,6 +1879,8 @@ _tWinMain(HINSTANCE hInst,
if (!LoadSetupData(&SetupData))
goto Quit;
+ hHotkeyThread = CreateThread(NULL, 0, HotkeyThread, NULL, 0, NULL);
+
CheckUnattendedSetup(&SetupData.USetupData);
SetupData.bUnattend = IsUnattendedSetup; // FIXME :-)
@@ -1570,6 +1895,10 @@ _tWinMain(HINSTANCE hInst,
iccx.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_PROGRESS_CLASS;
InitCommonControlsEx(&iccx);
+ /* Register the TreeList control */
+ // RegisterTreeListClass(hInst);
+ TreeListRegister(hInst);
+
/* Create title font */
SetupData.hTitleFont = CreateTitleFont();
@@ -1582,74 +1911,74 @@ _tWinMain(HINSTANCE hInst,
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = StartDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_STARTPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the install type selection page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TYPETITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_TYPESUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_TYPETITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_TYPESUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = TypeDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_TYPEPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_TYPEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the upgrade/repair selection page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TYPETITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_TYPESUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_TYPETITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_TYPESUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = UpgradeRepairDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_UPDATEREPAIRPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_UPDATEREPAIRPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the device settings page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DEVICETITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DEVICESUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_DEVICETITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_DEVICESUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = DeviceDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_DEVICEPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_DEVICEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the install device settings page / boot method / install directory */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DRIVETITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DRIVESUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_DRIVETITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_DRIVESUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = DriveDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_DRIVEPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_DRIVEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the summary page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SUMMARYTITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUMMARYSUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_SUMMARYTITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_SUMMARYSUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = SummaryDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_SUMMARYPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_SUMMARYPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
}
/* Create the installation progress page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
- psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
- psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
+ psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_PROCESSTITLE);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_PROCESSSUBTITLE);
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = ProcessDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_PROCESSPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the finish-and-reboot page */
@@ -1658,7 +1987,7 @@ _tWinMain(HINSTANCE hInst,
psp.hInstance = hInst;
psp.lParam = (LPARAM)&SetupData;
psp.pfnDlgProc = RestartDlgProc;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_RESTARTPAGE);
+ psp.pszTemplate = MAKEINTRESOURCEW(IDD_RESTARTPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the property sheet */
@@ -1669,16 +1998,12 @@ _tWinMain(HINSTANCE hInst,
psh.nPages = nPages;
psh.nStartPage = 0;
psh.phpage = ahpsp;
- psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
- psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
+ psh.pszbmWatermark = MAKEINTRESOURCEW(IDB_WATERMARK);
+ psh.pszbmHeader = MAKEINTRESOURCEW(IDB_HEADER);
/* Display the wizard */
PropertySheet(&psh);
- if (SetupData.hTitleFont)
- DeleteObject(SetupData.hTitleFont);
-
-Quit:
/* Wait for any pending installation */
WaitForSingleObject(SetupData.hInstallThread, INFINITE);
CloseHandle(SetupData.hInstallThread);
@@ -1686,6 +2011,20 @@ Quit:
CloseHandle(SetupData.hHaltInstallEvent);
SetupData.hHaltInstallEvent = NULL;
+ if (SetupData.hTitleFont)
+ DeleteObject(SetupData.hTitleFont);
+
+ /* Unregister the TreeList control */
+ // UnregisterTreeListClass(hInst);
+ TreeListUnregister(hInst);
+
+ if (hHotkeyThread)
+ {
+ PostThreadMessageW(GetThreadId(hHotkeyThread), WM_QUIT, 0, 0);
+ CloseHandle(hHotkeyThread);
+ }
+
+Quit:
/* Setup has finished */
FinishSetup(&SetupData.USetupData);
diff --git a/base/setup/reactos/reactos.h b/base/setup/reactos/reactos.h
index ded1d85f74..23e23afa13 100644
--- a/base/setup/reactos/reactos.h
+++ b/base/setup/reactos/reactos.h
@@ -43,6 +43,19 @@
#include <strsafe.h>
#include <commctrl.h>
+#include <windowsx.h>
+
+/* These are public names and values determined from MFC, and compatible with Windows */
+// Property Sheet control id's (determined with Spy++)
+#define IDC_TAB_CONTROL 0x3020
+#define ID_APPLY_NOW 0x3021
+#define ID_WIZBACK 0x3023
+#define ID_WIZNEXT 0x3024
+#define ID_WIZFINISH 0x3025
+
+
+#include "treelist.h"
+
/**/#include <setupapi.h>/**/
#include <devguid.h>
@@ -123,17 +136,13 @@ typedef struct _SETUPDATA
/* 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
+ LONG FSType; // file system type on partition
+ LONG FormatPart; // type of format the partition
LONG SelectedLangId; // selected language (table index)
- LONG SelectedKBLayout; // selected keyboard layout (table index)
- LONG SelectedComputer; // selected computer type (table index)
- LONG SelectedDisplay; // selected display type (table index)
- LONG SelectedKeyboard; // selected keyboard type (table index)
/* txtsetup.sif data */
- // LONG DefaultLang; // default language (table index)
+ // LONG DefaultLang; // default language (table index)
// LONG DefaultKBLayout; // default keyboard layout (table index)
PCWSTR SelectedLanguageId;
WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList
@@ -147,14 +156,6 @@ extern BOOLEAN IsUnattendedSetup;
extern SETUPDATA SetupData;
-typedef struct _IMGINFO
-{
- HBITMAP hBitmap;
- INT cxSource;
- INT cySource;
-} IMGINFO, *PIMGINFO;
-
-
/*
* Attempts to convert a pure NT file path into a corresponding Win32 path.
* Adapted from GetInstallSourceWin32() in dll/win32/syssetup/wizard.c