From 2b41fc9ef03d28ba54cc64bbda6ccdb1337adf2c Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Mon, 6 Oct 2003 19:22:42 +0000 Subject: [PATCH] 2003-10-06 Casper S. Hornstrup * Makefile: New target uboot for simple unattended setup. * bootdata/unattend.inf.sample: Sample unattended setup script. * subsys/system/usetup/partlist.c (SelectPartition): New function. * subsys/system/usetup/partlist.h (SelectPartition): Prototype. * subsys/system/usetup/usetup.c: Support unattended setup. (IsUnattendedSetup, UnattendDestinationDiskNumber, UnattendDestinationPartitionNumber, UnattendInstallationDirectory): New. (CheckUnattendedSetup, InstallDirectoryPage1): New function. svn path=/trunk/; revision=6258 --- reactos/ChangeLog | 12 ++ reactos/Makefile | 13 +- reactos/bootdata/unattend.inf.sample | 6 + reactos/subsys/system/usetup/partlist.c | 47 ++++- reactos/subsys/system/usetup/partlist.h | 5 +- reactos/subsys/system/usetup/usetup.c | 228 ++++++++++++++++++++---- 6 files changed, 275 insertions(+), 36 deletions(-) create mode 100644 reactos/bootdata/unattend.inf.sample diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 0b8292460ca..5158f79cc95 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,15 @@ +2003-10-06 Casper S. Hornstrup + + * Makefile: New target uboot for simple unattended setup. + * bootdata/unattend.inf.sample: Sample unattended setup script. + * subsys/system/usetup/partlist.c (SelectPartition): New function. + * subsys/system/usetup/partlist.h (SelectPartition): Prototype. + * subsys/system/usetup/usetup.c: Support unattended setup. + (IsUnattendedSetup, UnattendDestinationDiskNumber, + UnattendDestinationPartitionNumber, UnattendInstallationDirectory): + New. + (CheckUnattendedSetup, InstallDirectoryPage1): New function. + 2003-08-30 Filip Navara * tools/cabman/cabinet.cxx (CCabinet::ConvertPath): NULL-terminate diff --git a/reactos/Makefile b/reactos/Makefile index 0a29da3ea2a..b4eedaecb08 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -185,14 +185,23 @@ bootcd_install_before: $(CP) media/nls/c_437.nls $(BOOTCD_DIR)/reactos/c_437.nls $(CP) media/nls/l_intl.nls $(BOOTCD_DIR)/reactos/l_intl.nls -bootcd: all bootcd_directory_layout bootcd_bootstrap_files bootcd_install_before +bootcd_basic: all bootcd_directory_layout bootcd_bootstrap_files bootcd_install_before + +bootcd_makecd: $(CABMAN) /C bootdata/packages/reactos.dff /L $(BOOTCD_DIR)/reactos /I $(CABMAN) /C bootdata/packages/reactos.dff /RC $(BOOTCD_DIR)/reactos/reactos.inf /L $(BOOTCD_DIR)/reactos /N - $(RM) $(BOOTCD_DIR)/reactos/reactos.inf $(TOOLS_PATH)/cdmake/cdmake -v -m -b $(BOOTCD_DIR)/../isoboot.bin $(BOOTCD_DIR) REACTOS ReactOS.iso +ubootcd_unattend: + $(CP) bootdata/unattend.inf $(BOOTCD_DIR)/reactos/unattend.inf + +bootcd: bootcd_basic bootcd_makecd + +ubootcd: bootcd_basic ubootcd_unattend bootcd_makecd + .PHONY: all depends implib clean clean_before install dist freeldr bootcd_directory_layout \ -bootcd_bootstrap_files bootcd +bootcd_bootstrap_files bootcd_install_before bootcd_basic bootcd_makecd ubootcd_unattend bootcd # diff --git a/reactos/bootdata/unattend.inf.sample b/reactos/bootdata/unattend.inf.sample new file mode 100644 index 00000000000..25dfb0071be --- /dev/null +++ b/reactos/bootdata/unattend.inf.sample @@ -0,0 +1,6 @@ +; Install to \Device\Harddisk0\Partition1\ReactOS +[Unattend] +Signature = "$ReactOS$" +DestinationDiskNumber = 0 +DestinationPartitionNumber = 1 +InstallationDirectory=ReactOS \ No newline at end of file diff --git a/reactos/subsys/system/usetup/partlist.c b/reactos/subsys/system/usetup/partlist.c index 47065e6cd09..e87cd63450f 100644 --- a/reactos/subsys/system/usetup/partlist.c +++ b/reactos/subsys/system/usetup/partlist.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: partlist.c,v 1.23 2003/08/29 11:27:16 ekohl Exp $ +/* $Id: partlist.c,v 1.24 2003/10/06 19:22:42 chorns Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/partlist.c @@ -1079,6 +1079,51 @@ DrawPartitionList (PPARTLIST List) } +VOID +SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + ULONG i; + + /* Check for empty disks */ + if (IsListEmpty (&List->DiskListHead)) + return; + + /* Check for first usable entry on next disk */ + Entry1 = List->CurrentDisk->ListEntry.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); + + if (DiskEntry->DiskNumber == DiskNumber) + { + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); + + for (i = 0; i < 4; i++) + { + if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber) + { + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + DrawPartitionList (List); + return; + } + } + Entry2 = Entry2->Flink; + } + return; + } + Entry1 = Entry1->Flink; + } +} + + VOID ScrollDownPartitionList (PPARTLIST List) { diff --git a/reactos/subsys/system/usetup/partlist.h b/reactos/subsys/system/usetup/partlist.h index 8faef8d4042..8d97e47dae7 100644 --- a/reactos/subsys/system/usetup/partlist.h +++ b/reactos/subsys/system/usetup/partlist.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: partlist.h,v 1.21 2003/08/25 11:56:07 ekohl Exp $ +/* $Id: partlist.h,v 1.22 2003/10/06 19:22:42 chorns Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/partlist.h @@ -134,6 +134,9 @@ DestroyPartitionList (PPARTLIST List); VOID DrawPartitionList (PPARTLIST List); +VOID +SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber); + VOID ScrollDownPartitionList (PPARTLIST List); diff --git a/reactos/subsys/system/usetup/usetup.c b/reactos/subsys/system/usetup/usetup.c index 1696fcf47c6..6c989c276d1 100644 --- a/reactos/subsys/system/usetup/usetup.c +++ b/reactos/subsys/system/usetup/usetup.c @@ -89,7 +89,10 @@ typedef struct _COPYCONTEXT HANDLE ProcessHeap; UNICODE_STRING SourceRootPath; - +BOOLEAN IsUnattendedSetup; +LONG UnattendDestinationDiskNumber; +LONG UnattendDestinationPartitionNumber; +WCHAR UnattendInstallationDirectory[MAX_PATH]; /* LOCALS *******************************************************************/ @@ -389,6 +392,119 @@ ConfirmQuit(PINPUT_RECORD Ir) } +VOID +CheckUnattendedSetup() +{ + WCHAR UnattendInfPath[MAX_PATH]; + UNICODE_STRING FileName; + INFCONTEXT Context; + HINF UnattendInf; + ULONG ErrorLine; + NTSTATUS Status; + LONG IntValue; + PWCHAR Value; + + if (DoesFileExist(SourcePath.Buffer, L"unattend.inf") == FALSE) + { + DPRINT("Does not exist: %S\\%S\n", SourcePath.Buffer, L"unattend.inf"); + IsUnattendedSetup = FALSE; + return; + } + + wcscpy(UnattendInfPath, SourcePath.Buffer); + wcscat(UnattendInfPath, L"\\unattend.inf"); + + RtlInitUnicodeString(&FileName, + UnattendInfPath); + + /* Load txtsetup.sif from install media. */ + + Status = InfOpenFile(&UnattendInf, + &FileName, + &ErrorLine); + if (!NT_SUCCESS(Status)) + { + DPRINT("InfOpenFile() failed with status 0x%x\n", Status); + return; + } + + /* Open 'Unattend' section */ + if (!InfFindFirstLine(UnattendInf, L"Unattend", L"Signature", &Context)) + { + DPRINT("InfFindFirstLine() failed for section 'Unattend'\n"); + InfCloseFile(UnattendInf); + return; + } + + /* Get pointer 'Signature' key */ + if (!InfGetData(&Context, NULL, &Value)) + { + DPRINT("InfGetData() failed for key 'Signature'\n"); + InfCloseFile(UnattendInf); + return; + } + + /* Check 'Signature' string */ + if (_wcsicmp(Value, L"$ReactOS$") != 0) + { + DPRINT("Signature not $ReactOS$\n"); + InfCloseFile(UnattendInf); + return; + } + + /* Search for 'DestinationDiskNumber' in the 'Unattend' section */ + if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context)) + { + DPRINT("InfFindFirstLine() failed for key 'DestinationDiskNumber'\n"); + InfCloseFile(UnattendInf); + return; + } + if (!InfGetIntField(&Context, 0, &IntValue)) + { + DPRINT("InfGetIntField() failed for key 'DestinationDiskNumber'\n"); + InfCloseFile(UnattendInf); + return; + } + UnattendDestinationDiskNumber = IntValue; + + /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */ + if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context)) + { + DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n"); + InfCloseFile(UnattendInf); + return; + } + if (!InfGetIntField(&Context, 0, &IntValue)) + { + DPRINT("InfGetIntField() failed for key 'DestinationPartitionNumber'\n"); + InfCloseFile(UnattendInf); + return; + } + UnattendDestinationPartitionNumber = IntValue; + + /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */ + if (!InfFindFirstLine(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context)) + { + DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n"); + InfCloseFile(UnattendInf); + return; + } + /* Get pointer 'InstallationDirectory' key */ + if (!InfGetData(&Context, NULL, &Value)) + { + DPRINT("InfGetData() failed for key 'InstallationDirectory'\n"); + InfCloseFile(UnattendInf); + return; + } + wcscpy(UnattendInstallationDirectory, Value); + + InfCloseFile(UnattendInf); + + IsUnattendedSetup = TRUE; + + DPRINT("Running unattended setup\n"); +} + /* * Start page @@ -549,6 +665,8 @@ StartPage(PINPUT_RECORD Ir) } } + CheckUnattendedSetup(); + return(INTRO_PAGE); } @@ -577,6 +695,11 @@ IntroPage(PINPUT_RECORD Ir) SetStatusText(" ENTER = Continue F3 = Quit"); + if (IsUnattendedSetup) + { + return(INSTALL_INTRO_PAGE); + } + while(TRUE) { ConInKey(Ir); @@ -695,6 +818,11 @@ InstallIntroPage(PINPUT_RECORD Ir) SetStatusText(" ENTER = Continue F3 = Quit"); + if (IsUnattendedSetup) + { + return(SELECT_PARTITION_PAGE); + } + while(TRUE) { ConInKey(Ir); @@ -780,6 +908,14 @@ SelectPartitionPage(PINPUT_RECORD Ir) } } + if (IsUnattendedSetup) + { + SelectPartition(PartitionList, + UnattendDestinationDiskNumber, + UnattendDestinationPartitionNumber); + return(SELECT_FILE_SYSTEM_PAGE); + } + while(TRUE) { /* Update status text */ @@ -1526,6 +1662,11 @@ SelectFileSystemPage (PINPUT_RECORD Ir) SetStatusText (" ENTER = Continue ESC = Cancel F3 = Quit"); + if (IsUnattendedSetup) + { + return(CHECK_FILE_SYSTEM_PAGE); + } + while (TRUE) { ConInKey (Ir); @@ -1738,7 +1879,6 @@ FormatPartitionPage (PINPUT_RECORD Ir) } } - /* Set DestinationRootPath */ RtlFreeUnicodeString (&DestinationRootPath); swprintf (PathBuffer, @@ -1871,6 +2011,11 @@ CheckFileSystemPage(PINPUT_RECORD Ir) DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath); + if (IsUnattendedSetup) + { + return(INSTALL_DIRECTORY_PAGE); + } + while(TRUE) { ConInKey(Ir); @@ -1892,6 +2037,44 @@ CheckFileSystemPage(PINPUT_RECORD Ir) } +static PAGE_NUMBER +InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry) +{ + WCHAR PathBuffer[MAX_PATH]; + + /* Create 'InstallPath' string */ + RtlFreeUnicodeString(&InstallPath); + RtlCreateUnicodeString(&InstallPath, + InstallDir); + + /* Create 'DestinationPath' string */ + RtlFreeUnicodeString(&DestinationPath); + wcscpy(PathBuffer, + DestinationRootPath.Buffer); + if (InstallDir[0] != L'\\') + wcscat(PathBuffer, + L"\\"); + wcscat(PathBuffer, InstallDir); + RtlCreateUnicodeString(&DestinationPath, + PathBuffer); + + /* Create 'DestinationArcPath' */ + RtlFreeUnicodeString(&DestinationArcPath); + swprintf(PathBuffer, + L"multi(0)disk(0)rdisk(%lu)partition(%lu)", + DiskEntry->DiskNumber, + PartEntry->PartInfo[0].PartitionNumber); + if (InstallDir[0] != L'\\') + wcscat(PathBuffer, + L"\\"); + wcscat(PathBuffer, InstallDir); + RtlCreateUnicodeString(&DestinationArcPath, + PathBuffer); + + return(PREPARE_COPY_PAGE); +} + + static PAGE_NUMBER InstallDirectoryPage(PINPUT_RECORD Ir) { @@ -1955,6 +2138,11 @@ InstallDirectoryPage(PINPUT_RECORD Ir) SetStatusText(" ENTER = Continue F3 = Quit"); + if (IsUnattendedSetup) + { + return(InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry)); + } + while(TRUE) { ConInKey(Ir); @@ -1968,36 +2156,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - /* Create 'InstallPath' string */ - RtlFreeUnicodeString(&InstallPath); - RtlCreateUnicodeString(&InstallPath, - InstallDir); - - /* Create 'DestinationPath' string */ - RtlFreeUnicodeString(&DestinationPath); - wcscpy(PathBuffer, - DestinationRootPath.Buffer); - if (InstallDir[0] != L'\\') - wcscat(PathBuffer, - L"\\"); - wcscat(PathBuffer, InstallDir); - RtlCreateUnicodeString(&DestinationPath, - PathBuffer); - - /* Create 'DestinationArcPath' */ - RtlFreeUnicodeString(&DestinationArcPath); - swprintf(PathBuffer, - L"multi(0)disk(0)rdisk(%lu)partition(%lu)", - DiskEntry->DiskNumber, - PartEntry->PartInfo[0].PartitionNumber); - if (InstallDir[0] != L'\\') - wcscat(PathBuffer, - L"\\"); - wcscat(PathBuffer, InstallDir); - RtlCreateUnicodeString(&DestinationArcPath, - PathBuffer); - - return(PREPARE_COPY_PAGE); + return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry)); } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */ { @@ -3233,6 +3392,11 @@ SuccessPage(PINPUT_RECORD Ir) SetStatusText(" ENTER = Reboot computer"); + if (IsUnattendedSetup) + { + return(REBOOT_PAGE); + } + while(TRUE) { ConInKey(Ir);