2003-10-06 Casper S. Hornstrup <chorns@users.sourceforge.net>
authorCasper Hornstrup <chorns@users.sourceforge.net>
Mon, 6 Oct 2003 19:22:42 +0000 (19:22 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Mon, 6 Oct 2003 19:22:42 +0000 (19:22 +0000)
* 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
reactos/Makefile
reactos/bootdata/unattend.inf.sample [new file with mode: 0644]
reactos/subsys/system/usetup/partlist.c
reactos/subsys/system/usetup/partlist.h
reactos/subsys/system/usetup/usetup.c

index 0b82924..5158f79 100644 (file)
@@ -1,3 +1,15 @@
+2003-10-06  Casper S. Hornstrup  <chorns@users.sourceforge.net>
+
+       * 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  <xnavara@volny.cz>
 
        * tools/cabman/cabinet.cxx (CCabinet::ConvertPath): NULL-terminate
index 0a29da3..b4eedae 100644 (file)
@@ -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 (file)
index 0000000..25dfb00
--- /dev/null
@@ -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
index 47065e6..e87cd63 100644 (file)
@@ -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)
 {
index 8faef8d..8d97e47 100644 (file)
@@ -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);
 
index 1696fcf..6c989c2 100644 (file)
@@ -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);