[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.
This commit is contained in:
Hermès Bélusca-Maïto 2018-01-28 23:47:25 +01:00
parent a531843245
commit bbc4bb2d08
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 1044 additions and 181 deletions

View file

@ -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)

View file

@ -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;
/* Create the ImageList */
hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_COLOR32 | ILC_MASK, // ILC_COLOR24
1, 1);
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
/* 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;

View file

@ -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);

View file

@ -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