ReactOS  0.4.13-dev-249-gcba1a2f
setupldr.c
Go to the documentation of this file.
1 /*
2  * FreeLoader
3  *
4  * Copyright (C) 2009 Aleksey Bragin <aleksey@reactos.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <freeldr.h>
22 #include "winldr.h"
23 
24 #include <ndk/ldrtypes.h>
25 #include <arc/setupblk.h>
26 
27 #include <debug.h>
28 
29 DBG_DEFAULT_CHANNEL(WINDOWS);
30 #define TAG_BOOT_OPTIONS 'pOtB'
31 
32 // TODO: Move to .h
34 
35 static VOID
37 {
38  INFCONTEXT InfContext;
40  LPCSTR AnsiName, OemName, LangName;
41 
42  /* Get ANSI codepage file */
43  if (!InfFindFirstLine(InfHandle, "NLS", "AnsiCodepage", &InfContext))
44  {
45  ERR("Failed to find 'NLS/AnsiCodepage'\n");
46  return;
47  }
48  if (!InfGetDataField(&InfContext, 1, &AnsiName))
49  {
50  ERR("Failed to get load options\n");
51  return;
52  }
53 
54  /* Get OEM codepage file */
55  if (!InfFindFirstLine(InfHandle, "NLS", "OemCodepage", &InfContext))
56  {
57  ERR("Failed to find 'NLS/AnsiCodepage'\n");
58  return;
59  }
60  if (!InfGetDataField(&InfContext, 1, &OemName))
61  {
62  ERR("Failed to get load options\n");
63  return;
64  }
65 
66  if (!InfFindFirstLine(InfHandle, "NLS", "UnicodeCasetable", &InfContext))
67  {
68  ERR("Failed to find 'NLS/AnsiCodepage'\n");
69  return;
70  }
71  if (!InfGetDataField(&InfContext, 1, &LangName))
72  {
73  ERR("Failed to get load options\n");
74  return;
75  }
76 
77  TRACE("NLS data %s %s %s\n", AnsiName, OemName, LangName);
78 
79  Success = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
80  TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
81 
82  /* TODO: Load OEM HAL font */
83  // Value "OemHalFont"
84 }
85 
86 static VOID
87 SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, LPCSTR SearchPath)
88 {
89  INFCONTEXT InfContext, dirContext;
91  LPCSTR Media, DriverName, dirIndex, ImagePath;
92  WCHAR ServiceName[256];
93  WCHAR ImagePathW[256];
94 
95  /* Open inf section */
96  if (!InfFindFirstLine(InfHandle, "SourceDisksFiles", NULL, &InfContext))
97  return;
98 
99  /* Load all listed boot drivers */
100  do
101  {
102  if (InfGetDataField(&InfContext, 7, &Media) &&
103  InfGetDataField(&InfContext, 0, &DriverName) &&
104  InfGetDataField(&InfContext, 13, &dirIndex))
105  {
106  if ((strcmp(Media, "x") == 0) &&
107  InfFindFirstLine(InfHandle, "Directories", dirIndex, &dirContext) &&
108  InfGetDataField(&dirContext, 1, &ImagePath))
109  {
110  /* Convert name to widechar */
111  swprintf(ServiceName, L"%S", DriverName);
112 
113  /* Prepare image path */
114  swprintf(ImagePathW, L"%S", ImagePath);
115  wcscat(ImagePathW, L"\\");
116  wcscat(ImagePathW, ServiceName);
117 
118  /* Remove .sys extension */
119  ServiceName[wcslen(ServiceName) - 4] = 0;
120 
121  /* Add it to the list */
122  Success = WinLdrAddDriverToList(BootDriverListHead,
123  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
124  ImagePathW,
125  ServiceName);
126  if (!Success)
127  {
128  ERR("could not add boot driver %s, %s\n", SearchPath, DriverName);
129  return;
130  }
131  }
132  }
133  } while (InfFindNextLine(&InfContext, &InfContext));
134 }
135 
136 
137 /* SETUP STARTER **************************************************************/
138 
139 VOID
142 {
143  ULONG_PTR SectionId;
144  PCSTR SectionName = OperatingSystem->SystemPartition;
145  CHAR SettingsValue[80];
146  BOOLEAN HasSection;
147  CHAR BootOptions2[256];
148  PCHAR File;
149  CHAR FileName[512];
150  CHAR BootPath[512];
151  LPCSTR LoadOptions;
153  BOOLEAN BootFromFloppy;
155  ULONG i, ErrorLine;
156  HINF InfHandle;
157  INFCONTEXT InfContext;
158  PLOADER_PARAMETER_BLOCK LoaderBlock;
159  PSETUP_LOADER_BLOCK SetupBlock;
160  LPCSTR SystemPath;
161  LPCSTR SourcePaths[] =
162  {
163  "", /* Only for floppy boot */
164 #if defined(_M_IX86)
165  "I386\\",
166 #elif defined(_M_MPPC)
167  "PPC\\",
168 #elif defined(_M_MRX000)
169  "MIPS\\",
170 #endif
171  "reactos\\",
172  NULL
173  };
174 
175  UiDrawStatusText("Setup is loading...");
176 
177  /* Get OS setting value */
178  SettingsValue[0] = ANSI_NULL;
179  IniOpenSection("Operating Systems", &SectionId);
180  IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));
181 
182  /* Open the operating system section specified in the .ini file */
183  HasSection = IniOpenSection(SectionName, &SectionId);
184 
185  UiDrawBackdrop();
186  UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
187 
188  /* Read the system path is set in the .ini file */
189  if (!HasSection ||
190  !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
191  {
192  /*
193  * IMPROVE: I don't want to call MachDiskGetBootPath here as a
194  * default choice because I can call it after (see few lines below).
195  * Also doing the strcpy call as it is done in winldr.c is not
196  * really what we want. Instead I reset BootPath here so that
197  * we can build the full path using the general code from below.
198  */
199  // MachDiskGetBootPath(BootPath, sizeof(BootPath));
200  // strcpy(BootPath, SectionName);
201  BootPath[0] = '\0';
202  }
203 
204  /*
205  * Check whether BootPath is a full path
206  * and if not, create a full boot path.
207  *
208  * See FsOpenFile for the technique used.
209  */
210  if (strrchr(BootPath, ')') == NULL)
211  {
212  /* Temporarily save the boot path */
214 
215  /* This is not a full path. Use the current (i.e. boot) device. */
217 
218  /* Append a path separator if needed */
219  if (FileName[0] != '\\' && FileName[0] != '/')
220  strcat(BootPath, "\\");
221 
222  /* Append the remaining path */
224  }
225 
226  /* Append a backslash if needed */
227  if ((strlen(BootPath) == 0) || BootPath[strlen(BootPath) - 1] != '\\')
228  strcat(BootPath, "\\");
229 
230  /* Read booting options */
231  if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions2, sizeof(BootOptions2)))
232  {
233  /* Get options after the title */
234  PCSTR p = SettingsValue;
235  while (*p == ' ' || *p == '"')
236  p++;
237  while (*p != '\0' && *p != '"')
238  p++;
239  strcpy(BootOptions2, p);
240  TRACE("BootOptions: '%s'\n", BootOptions2);
241  }
242 
243  /* Check if a ramdisk file was given */
244  File = strstr(BootOptions2, "/RDPATH=");
245  if (File)
246  {
247  /* Copy the file name and everything else after it */
248  strcpy(FileName, File + 8);
249 
250  /* Null-terminate */
251  *strstr(FileName, " ") = ANSI_NULL;
252 
253  /* Load the ramdisk */
255  {
256  UiMessageBox("Failed to load RAM disk file %s", FileName);
257  return;
258  }
259  }
260 
261  TRACE("BootPath: '%s'\n", BootPath);
262 
263  /* And check if we booted from floppy */
264  BootFromFloppy = strstr(BootPath, "fdisk") != NULL;
265 
266  /* Open 'txtsetup.sif' from any of source paths */
268  for (i = BootFromFloppy ? 0 : 1; ; i++)
269  {
270  SystemPath = SourcePaths[i];
271  if (!SystemPath)
272  {
273  UiMessageBox("Failed to open txtsetup.sif");
274  return;
275  }
276  strcpy(File, SystemPath);
278  strcat(FileName, "txtsetup.sif");
279  if (InfOpenFile(&InfHandle, FileName, &ErrorLine))
280  {
281  break;
282  }
283  }
284 
285  TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);
286 
287  /* Get Load options - debug and non-debug */
288  if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext))
289  {
290  ERR("Failed to find 'SetupData/OsLoadOptions'\n");
291  return;
292  }
293 
294  if (!InfGetDataField(&InfContext, 1, &LoadOptions))
295  {
296  ERR("Failed to get load options\n");
297  return;
298  }
299 
300 #if DBG
301  /* Get debug load options and use them */
302  if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext))
303  {
304  LPCSTR DbgLoadOptions;
305 
306  if (InfGetDataField(&InfContext, 1, &DbgLoadOptions))
307  LoadOptions = DbgLoadOptions;
308  }
309 #endif
310 
311  /* Copy loadoptions (original string will be freed) */
312  BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS);
313  strcpy(BootOptions, LoadOptions);
314 
315  TRACE("BootOptions: '%s'\n", BootOptions);
316 
317  /* Allocate and minimalist-initialize LPB */
318  AllocateAndInitLPB(&LoaderBlock);
319 
320  /* Allocate and initialize setup loader block */
321  SetupBlock = &WinLdrSystemBlock->SetupBlock;
322  LoaderBlock->SetupLdrBlock = SetupBlock;
323 
324  /* Set textmode setup flag */
325  SetupBlock->Flags = SETUPLDR_TEXT_MODE;
326 
327  /* Load the system hive "setupreg.hiv" for setup */
328  UiDrawBackdrop();
329  UiDrawProgressBarCenter(15, 100, "Loading setup system hive...");
330  Success = WinLdrInitSystemHive(LoaderBlock, BootPath, TRUE);
331  TRACE("Setup SYSTEM hive %s\n", (Success ? "loaded" : "not loaded"));
332  /* Bail out if failure */
333  if (!Success)
334  return;
335 
336  /* Load NLS data, they are in the System32 directory of the installation medium */
338  strcat(FileName, "system32\\");
339  SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);
340 
341  // UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID driver...");
342 
343  /* Get a list of boot drivers */
344  SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath);
345 
346  /* Close the inf file */
347  InfCloseFile(InfHandle);
348 
349  UiDrawStatusText("The Setup program is starting...");
350 
351  /* Load ReactOS Setup */
353  LoaderBlock,
354  BootOptions,
355  BootPath,
356  TRUE);
357 }
signed char * PCHAR
Definition: retypes.h:7
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
BOOLEAN NTAPI RamDiskLoadVirtualFile(IN PCHAR FileName)
Definition: ramdisk.c:121
BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: inffile.c:1125
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
char CHAR
Definition: xmlstorage.h:175
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
char * LPSTR
Definition: xmlstorage.h:182
DBG_DEFAULT_CHANNEL(WINDOWS)
BOOLEAN InfGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PWCHAR *Data)
Definition: infrosget.c:127
#define SearchPath
Definition: winbase.h:3714
static VOID SetupLdrLoadNlsData(PLOADER_PARAMETER_BLOCK LoaderBlock, HINF InfHandle, LPCSTR SearchPath)
Definition: setupldr.c:36
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static VOID SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, LPCSTR SearchPath)
Definition: setupldr.c:87
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define ANSI_NULL
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:347
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR AnsiFileName, IN LPCSTR OemFileName, IN LPCSTR LanguageFileName)
Definition: wlregistry.c:299
BOOLEAN WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, LPWSTR RegistryPath, LPWSTR ImagePath, LPWSTR ServiceName)
Definition: wlregistry.c:747
const char * LPCSTR
Definition: xmlstorage.h:183
USHORT OperatingSystemVersion
Definition: bootmgr.c:35
BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
Definition: inifile.c:147
#define TRACE(s)
Definition: solgame.cpp:4
LPTSTR ServiceName
Definition: ServiceMain.c:15
BOOLEAN IniOpenSection(PCSTR SectionName, ULONG_PTR *SectionId)
Definition: inifile.c:25
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define swprintf(buf, format,...)
Definition: sprintf.c:56
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:276
static const WCHAR L[]
Definition: oid.c:1250
VOID InfCloseFile(HINF InfHandle)
Definition: inffile.c:1046
Definition: typedefs.h:117
VOID UiDrawBackdrop(VOID)
Definition: ui.c:241
SETUP_LOADER_BLOCK SetupBlock
Definition: winldr.h:74
#define ERR(fmt,...)
Definition: debug.h:109
#define TAG_BOOT_OPTIONS
Definition: setupldr.c:30
#define SETUPLDR_TEXT_MODE
Definition: setupblk.h:7
BOOLEAN InfFindFirstLine(HINF InfHandle, PCSTR Section, PCSTR Key, PINFCONTEXT Context)
Definition: inffile.c:1068
BOOLEAN InfOpenFile(PHINF InfHandle, PCSTR FileName, PULONG ErrorLine)
Definition: inffile.c:936
unsigned short USHORT
Definition: pedump.c:61
#define MachDiskGetBootPath(Path, Size)
Definition: machine.h:118
VOID AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
Definition: winldr.c:49
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
VOID LoadAndBootWindowsCommon(USHORT OperatingSystemVersion, PLOADER_PARAMETER_BLOCK LoaderBlock, LPCSTR BootOptions, LPCSTR BootPath, BOOLEAN Setup)
Definition: winldr.c:775
const char * PCSTR
Definition: typedefs.h:51
Definition: File.h:15
GLfloat GLfloat p
Definition: glext.h:8902
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
Definition: wlregistry.c:121
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
char BootPath[0x100]
Definition: mach.c:35
VOID LoadReactOSSetup(IN OperatingSystemItem *OperatingSystem, IN USHORT OperatingSystemVersion)
Definition: setupldr.c:140
VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
Definition: ui.c:373
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:42