ReactOS 0.4.16-dev-297-gc569aee
setuplib.c File Reference
#include "precomp.h"
#include "filesup.h"
#include "infsupp.h"
#include "inicache.h"
#include "setuplib.h"
#include <debug.h>
Include dependency graph for setuplib.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define IS_PATH_SEPARATOR(c)   ((c) == L'\\' || (c) == L'/')
 

Functions

VOID CheckUnattendedSetup (IN OUT PUSETUP_DATA pSetupData)
 
VOID InstallSetupInfFile (IN OUT PUSETUP_DATA pSetupData)
 
NTSTATUS GetSourcePaths (_Out_ PUNICODE_STRING SourcePath, _Out_ PUNICODE_STRING SourceRootPath, _Out_ PUNICODE_STRING SourceRootDir)
 Determine the installation source path and isolate its useful path components (root path and source sub-directory).
 
ERROR_NUMBER LoadSetupInf (IN OUT PUSETUP_DATA pSetupData)
 
BOOLEAN InitSystemPartition (_In_ PPARTLIST PartitionList, _In_ PPARTENTRY InstallPartition, _Out_ PPARTENTRY *pSystemPartition, _In_opt_ PFSVOL_CALLBACK FsVolCallback, _In_opt_ PVOID Context)
 Find or set the active system partition.
 
BOOLEAN IsValidInstallDirectory (_In_ PCWSTR InstallDir)
 Verify whether the given directory is suitable for ReactOS installation. Each path component must be a valid 8.3 name.
 
NTSTATUS InitDestinationPaths (_Inout_ PUSETUP_DATA pSetupData, _In_ PCWSTR InstallationDir, _In_ PVOLENTRY Volume)
 
ERROR_NUMBER InitializeSetup (IN OUT PUSETUP_DATA pSetupData, IN ULONG InitPhase)
 
VOID FinishSetup (IN OUT PUSETUP_DATA pSetupData)
 
ERROR_NUMBER UpdateRegistry (IN OUT PUSETUP_DATA pSetupData, IN BOOLEAN RepairUpdateFlag, IN PPARTLIST PartitionList, IN WCHAR DestinationDriveLetter, IN PCWSTR SelectedLanguageId, IN PREGISTRY_STATUS_ROUTINE StatusRoutine OPTIONAL, IN PFONTSUBSTSETTINGS SubstSettings OPTIONAL)
 

Macro Definition Documentation

â—† IS_PATH_SEPARATOR

#define IS_PATH_SEPARATOR (   c)    ((c) == L'\\' || (c) == L'/')

Definition at line 763 of file setuplib.c.

â—† NDEBUG

#define NDEBUG

Definition at line 19 of file setuplib.c.

Function Documentation

â—† CheckUnattendedSetup()

VOID CheckUnattendedSetup ( IN OUT PUSETUP_DATA  pSetupData)

Definition at line 28 of file setuplib.c.

30{
32 HINF UnattendInf;
33 UINT ErrorLine;
34 INT IntValue;
36 WCHAR UnattendInfPath[MAX_PATH];
37
38 CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
39 pSetupData->SourcePath.Buffer, L"unattend.inf");
40
41 DPRINT("UnattendInf path: '%S'\n", UnattendInfPath);
42
43 if (DoesFileExist(NULL, UnattendInfPath) == FALSE)
44 {
45 DPRINT("Does not exist: %S\n", UnattendInfPath);
46 return;
47 }
48
49 /* Load 'unattend.inf' from installation media */
50 UnattendInf = SpInfOpenInfFile(UnattendInfPath,
51 NULL,
53 pSetupData->LanguageId,
54 &ErrorLine);
55 if (UnattendInf == INVALID_HANDLE_VALUE)
56 {
57 DPRINT("SpInfOpenInfFile() failed\n");
58 return;
59 }
60
61 /* Open 'Unattend' section */
62 if (!SpInfFindFirstLine(UnattendInf, L"Unattend", L"Signature", &Context))
63 {
64 DPRINT("SpInfFindFirstLine() failed for section 'Unattend'\n");
65 goto Quit;
66 }
67
68 /* Get pointer 'Signature' key */
69 if (!INF_GetData(&Context, NULL, &Value))
70 {
71 DPRINT("INF_GetData() failed for key 'Signature'\n");
72 goto Quit;
73 }
74
75 /* Check 'Signature' string */
76 if (_wcsicmp(Value, L"$ReactOS$") != 0)
77 {
78 DPRINT("Signature not $ReactOS$\n");
80 goto Quit;
81 }
82
84
85 /* Check if Unattend setup is enabled */
86 if (!SpInfFindFirstLine(UnattendInf, L"Unattend", L"UnattendSetupEnabled", &Context))
87 {
88 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
89 goto Quit;
90 }
91
92 if (!INF_GetData(&Context, NULL, &Value))
93 {
94 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
95 goto Quit;
96 }
97
98 if (_wcsicmp(Value, L"yes") != 0)
99 {
100 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
102 goto Quit;
103 }
104
106
107 /* Search for 'DestinationDiskNumber' */
108 if (!SpInfFindFirstLine(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context))
109 {
110 DPRINT("SpInfFindFirstLine() failed for key 'DestinationDiskNumber'\n");
111 goto Quit;
112 }
113
114 if (!SpInfGetIntField(&Context, 1, &IntValue))
115 {
116 DPRINT("SpInfGetIntField() failed for key 'DestinationDiskNumber'\n");
117 goto Quit;
118 }
119
120 pSetupData->DestinationDiskNumber = (LONG)IntValue;
121
122 /* Search for 'DestinationPartitionNumber' */
123 if (!SpInfFindFirstLine(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
124 {
125 DPRINT("SpInfFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
126 goto Quit;
127 }
128
129 if (!SpInfGetIntField(&Context, 1, &IntValue))
130 {
131 DPRINT("SpInfGetIntField() failed for key 'DestinationPartitionNumber'\n");
132 goto Quit;
133 }
134
135 pSetupData->DestinationPartitionNumber = (LONG)IntValue;
136
137 /* Search for 'InstallationDirectory' (optional) */
138 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"InstallationDirectory", &Context))
139 {
140 if (INF_GetData(&Context, NULL, &Value))
141 {
142 RtlStringCchCopyW(pSetupData->InstallationDirectory,
143 ARRAYSIZE(pSetupData->InstallationDirectory),
144 Value);
146 }
147 else
148 {
149 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
150 }
151 }
152
154 DPRINT("Running unattended setup\n");
155
156 /* Search for 'BootLoaderLocation' (optional) */
157 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"BootLoaderLocation", &Context))
158 {
159 if (SpInfGetIntField(&Context, 1, &IntValue))
160 pSetupData->BootLoaderLocation = IntValue;
161 }
162
163 /* Search for 'FormatPartition' (optional) */
164 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"FormatPartition", &Context))
165 {
166 if (SpInfGetIntField(&Context, 1, &IntValue))
167 pSetupData->FormatPartition = IntValue;
168 }
169
170 /* Search for 'AutoPartition' (optional) */
171 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"AutoPartition", &Context))
172 {
173 if (SpInfGetIntField(&Context, 1, &IntValue))
174 pSetupData->AutoPartition = IntValue;
175 }
176
177 /* Search for 'LocaleID' (optional) */
178 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"LocaleID", &Context))
179 {
180 if (INF_GetData(&Context, NULL, &Value))
181 {
182 LONG Id = wcstol(Value, NULL, 16);
183 RtlStringCchPrintfW(pSetupData->LocaleID,
184 ARRAYSIZE(pSetupData->LocaleID),
185 L"%08lx", Id);
187 }
188 }
189
190 /* Search for 'FsType' (optional) */
191 if (SpInfFindFirstLine(UnattendInf, L"Unattend", L"FsType", &Context))
192 {
193 if (SpInfGetIntField(&Context, 1, &IntValue))
194 pSetupData->FsType = IntValue;
195 }
196
197Quit:
198 SpInfCloseInfFile(UnattendInf);
199}
DWORD Id
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:664
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:83
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define INF_STYLE_OLDNT
Definition: infsupp.h:37
pSpInfGetIntField SpInfGetIntField
Definition: infsupp.c:91
pSpInfFindFirstLine SpInfFindFirstLine
Definition: infsupp.c:87
FORCEINLINE VOID INF_FreeData(IN PCWSTR InfData)
Definition: infsupp.h:157
pSpInfOpenInfFile SpInfOpenInfFile
Definition: infsupp.c:95
pSpInfCloseInfFile SpInfCloseInfFile
Definition: infsupp.c:86
BOOLEAN INF_GetData(IN PINFCONTEXT Context, OUT PCWSTR *Key, OUT PCWSTR *Data)
Definition: infsupp.c:90
unsigned int UINT
Definition: ndis.h:50
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOLEAN IsUnattendedSetup
Definition: reactos.c:41
#define DPRINT
Definition: sndvol32.h:73
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by _tWinMain(), and SetupStartPage().

â—† FinishSetup()

VOID FinishSetup ( IN OUT PUSETUP_DATA  pSetupData)

Definition at line 1096 of file setuplib.c.

1098{
1099 /* Destroy the computer settings list */
1100 if (pSetupData->ComputerList != NULL)
1101 {
1102 DestroyGenericList(pSetupData->ComputerList, TRUE);
1103 pSetupData->ComputerList = NULL;
1104 }
1105
1106 /* Destroy the display settings list */
1107 if (pSetupData->DisplayList != NULL)
1108 {
1109 DestroyGenericList(pSetupData->DisplayList, TRUE);
1110 pSetupData->DisplayList = NULL;
1111 }
1112
1113 /* Destroy the keyboard settings list */
1114 if (pSetupData->KeyboardList != NULL)
1115 {
1116 DestroyGenericList(pSetupData->KeyboardList, TRUE);
1117 pSetupData->KeyboardList = NULL;
1118 }
1119
1120 /* Destroy the keyboard layout list */
1121 if (pSetupData->LayoutList != NULL)
1122 {
1123 DestroyGenericList(pSetupData->LayoutList, TRUE);
1124 pSetupData->LayoutList = NULL;
1125 }
1126
1127 /* Destroy the languages list */
1128 if (pSetupData->LanguageList != NULL)
1129 {
1130 DestroyGenericList(pSetupData->LanguageList, FALSE);
1131 pSetupData->LanguageList = NULL;
1132 }
1133
1134 /* Close the Setup INF */
1135 SpInfCloseInfFile(pSetupData->SetupInf);
1136}
VOID DestroyGenericList(IN OUT PGENERIC_LIST List, IN BOOLEAN FreeData)
Definition: genlist.c:36

Referenced by _tWinMain(), and RunUSetup().

â—† GetSourcePaths()

NTSTATUS GetSourcePaths ( _Out_ PUNICODE_STRING  SourcePath,
_Out_ PUNICODE_STRING  SourceRootPath,
_Out_ PUNICODE_STRING  SourceRootDir 
)

Determine the installation source path and isolate its useful path components (root path and source sub-directory).

The installation source path is based either on the installer's image file path, or on the \SystemRoot full path.

In case the \SystemRoot full path prefixes the image file path, use the resolved \SystemRoot as the installation source path. Otherwise, use the image file path.

The returned strings are allocated with RtlCreateUnicodeString(), and need to be freed with RtlFreeUnicodeString() after being used.

Example of output: SourcePath: '\Device\CdRom0\I386' SourceRootPath: '\Device\CdRom0' SourceRootDir: '\I386'

Definition at line 402 of file setuplib.c.

406{
409 PWCHAR Ptr;
410 HANDLE LinkHandle;
413 struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ImageFileBuffer;
414 PUNICODE_STRING InstallSourcePath = &ImageFileBuffer.Name;
415 struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } SystemRootBuffer;
416 PUNICODE_STRING SystemRootPath = &SystemRootBuffer.Name;
417 const UNICODE_STRING SystemRoot = RTL_CONSTANT_STRING(L"\\SystemRoot");
418
419 /* Retrieve the installer's full image file path */
420 RtlInitEmptyUnicodeString(InstallSourcePath,
421 ImageFileBuffer.Buffer,
422 sizeof(ImageFileBuffer.Buffer));
423 BufferSize = sizeof(ImageFileBuffer);
426 InstallSourcePath,
428 NULL);
429 // STATUS_INFO_LENGTH_MISMATCH or STATUS_BUFFER_TOO_SMALL ?
430 if (!NT_SUCCESS(Status))
431 return Status;
432 ASSERT(InstallSourcePath->Length < InstallSourcePath->MaximumLength);
433
434 /* Go to the beginning of the path component, stop at the separator */
435 Ptr = ImageFileBuffer.Buffer + (InstallSourcePath->Length / sizeof(WCHAR));
436 while ((Ptr > ImageFileBuffer.Buffer) && (*Ptr != OBJ_NAME_PATH_SEPARATOR))
437 --Ptr;
438 /* Strip the trailing file name (at the separator or beginning of buffer)
439 * and manually NULL-terminate */
440 InstallSourcePath->Length = (ULONG_PTR)Ptr - (ULONG_PTR)ImageFileBuffer.Buffer;
441 InstallSourcePath->Buffer[InstallSourcePath->Length / sizeof(WCHAR)] = UNICODE_NULL;
442
443
444 /*
445 * Now, resolve the \SystemRoot symlink target full path.
446 *
447 * The symlink target path resolution requires reparsing, because it
448 * can reference other symlinks. This is what happens, for example when
449 * booting the installation from a removable hard-disk. We can have:
450 *
451 * \SystemRoot ---> \Device\Harddisk1\Partition1\ReactOS
452 * and: \Device\Harddisk1\Partition1 ---> \Device\HarddiskVolume2
453 * etc.
454 * and we wish to resolve \SystemRoot to: \Device\HarddiskVolume2\ReactOS
455 *
456 * We then verify whether it prefixes the image file path obtained
457 * from the step above, which is a fully reparsed path.
458 *
459 * - Using NtOpenSymbolicLinkObject(SYMBOLIC_LINK_QUERY) followed by
460 * NtQuerySymbolicLinkObject() would only resolve the first symlink
461 * but not the others (\Device\Harddisk1\Partition1 left as is).
462 *
463 * - Since \SystemRoot has to point to a directory, we try opening
464 * the directory itself: NtOpenFile(..., FILE_DIRECTORY_FILE).
465 *
466 * - A call to NtQueryInformationFile(FileNameInformation) alone on
467 * the obtained handle would only retrieve the FS directory name,
468 * i.e. \ReactOS , but not the whole NT path.
469 *
470 * - We therefore use NtQueryObject(), which allows retrieving the
471 * full resolved NT path (device name + FS directory name).
472 */
473
477 NULL,
478 NULL);
479
480 RtlInitEmptyUnicodeString(SystemRootPath,
481 SystemRootBuffer.Buffer,
482 sizeof(SystemRootBuffer.Buffer));
483
484 Status = NtOpenFile(&LinkHandle,
490 /*| FILE_OPEN_FOR_BACKUP_INTENT*/);
491 if (NT_SUCCESS(Status))
492 {
493 /* Resolve the path and close its handle */
494 Status = NtQueryObject(LinkHandle,
496 &SystemRootBuffer,
497 sizeof(SystemRootBuffer),
498 &BufferSize);
499 NtClose(LinkHandle);
500 }
501 /* If any of the calls above failed, try to naively resolve the symlink */
502 if (!NT_SUCCESS(Status))
503 {
504 RtlInitEmptyUnicodeString(SystemRootPath,
505 SystemRootBuffer.Buffer,
506 sizeof(SystemRootBuffer.Buffer));
507
508 Status = NtOpenSymbolicLinkObject(&LinkHandle,
511 if (NT_SUCCESS(Status))
512 {
513 /* Resolve the link and close its handle */
515 SystemRootPath,
516 &BufferSize);
517 NtClose(LinkHandle);
518 }
519 }
520 ASSERT(SystemRootPath->Length < SystemRootPath->MaximumLength);
521
522 /*
523 * If the resolved \SystemRoot is a prefix of the image file path,
524 * use \SystemRoot instead as the installation source path.
525 *
526 * If opening the \SystemRoot link failed (usually due to wrong
527 * access rights), do not consider this as a fatal error, and
528 * use the image file path as the installation source path.
529 */
530 if (NT_SUCCESS(Status) && RtlPrefixUnicodeString(SystemRootPath, InstallSourcePath, TRUE))
531 InstallSourcePath = SystemRootPath;
532
533
534 /*
535 * Retrieve the different source path components.
536 */
537 RtlCreateUnicodeString(SourcePath, InstallSourcePath->Buffer);
538
539 /* Isolate and strip the trailing (source root) directory */
540 Ptr = wcsrchr(InstallSourcePath->Buffer, OBJ_NAME_PATH_SEPARATOR);
541 if (Ptr)
542 {
543 RtlCreateUnicodeString(SourceRootDir, Ptr);
544 *Ptr = UNICODE_NULL;
545 }
546 else
547 {
548 RtlCreateUnicodeString(SourceRootDir, L"");
549 }
550
551 RtlCreateUnicodeString(SourceRootPath, InstallSourcePath->Buffer);
552
553 return STATUS_SUCCESS;
554}
@ ObjectNameInformation
Definition: DriverTester.h:55
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
Definition: bufpool.h:45
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define BufferSize
Definition: mmc.h:75
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static const WCHAR SystemRoot[]
Definition: reg.c:38
#define wcsrchr
Definition: compat.h:16
#define FILE_SHARE_READ
Definition: compat.h:136
#define ULONG_PTR
Definition: config.h:101
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ ProcessImageFileName
Definition: winternl.h:397
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define NtCurrentProcess()
Definition: nt_native.h:1657
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define UNICODE_NULL
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_SUCCESS
Definition: shellext.h:65
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by InitializeSetup().

â—† InitDestinationPaths()

NTSTATUS InitDestinationPaths ( _Inout_ PUSETUP_DATA  pSetupData,
_In_ PCWSTR  InstallationDir,
_In_ PVOLENTRY  Volume 
)

Equivalent of 'NTOS_INSTALLATION::SystemArcPath'

Equivalent of 'NTOS_INSTALLATION::SystemNtPath'

Equivalent of 'NTOS_INSTALLATION::PathComponent'

Definition at line 855 of file setuplib.c.

859{
861 PPARTENTRY PartEntry = Volume->PartEntry;
862 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
864
865 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
866
867 /* Create 'pSetupData->DestinationRootPath' string */
868 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
869 Status = RtlStringCchPrintfW(PathBuffer, _countof(PathBuffer),
870 L"%s\\", Volume->Info.DeviceName);
871 if (!NT_SUCCESS(Status))
872 {
873 DPRINT1("RtlStringCchPrintfW() failed with status 0x%08lx\n", Status);
874 return Status;
875 }
876
877 Status = RtlCreateUnicodeString(&pSetupData->DestinationRootPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
878
879 if (!NT_SUCCESS(Status))
880 {
881 DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
882 return Status;
883 }
884
885 DPRINT("DestinationRootPath: %wZ\n", &pSetupData->DestinationRootPath);
886
887 // FIXME! Which variable to choose?
888 if (!InstallationDir)
889 InstallationDir = pSetupData->InstallationDirectory;
890
892 /* Create 'pSetupData->DestinationArcPath' */
893 RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
894
895 if (DiskEntry->MediaType == FixedMedia)
896 {
897 if (DiskEntry->BiosFound)
898 {
899#if 1
900 Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
901 L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
902 DiskEntry->HwFixedDiskNumber,
903 PartEntry->OnDiskPartitionNumber);
904#else
905 Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
906 L"multi(%lu)disk(%lu)rdisk(%lu)partition(%lu)\\",
907 DiskEntry->HwAdapterNumber,
908 DiskEntry->HwControllerNumber,
909 DiskEntry->HwFixedDiskNumber,
910 PartEntry->OnDiskPartitionNumber);
911#endif
912 DPRINT1("Fixed disk found by BIOS, using MULTI ARC path '%S'\n", PathBuffer);
913 }
914 else
915 {
916 Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
917 L"scsi(%u)disk(%u)rdisk(%u)partition(%lu)\\",
918 DiskEntry->Port,
919 DiskEntry->Bus,
920 DiskEntry->Id,
921 PartEntry->OnDiskPartitionNumber);
922 DPRINT1("Fixed disk not found by BIOS, using SCSI ARC path '%S'\n", PathBuffer);
923 }
924 }
925 else // if (DiskEntry->MediaType == RemovableMedia)
926 {
927#if 1
928 Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
929 L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\",
930 0, 1);
931 DPRINT1("Removable disk, using MULTI ARC path '%S'\n", PathBuffer);
932#else
933 Status = RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
934 L"signature(%08x)disk(%u)rdisk(%u)partition(%lu)\\",
935 DiskEntry->LayoutBuffer->Signature,
936 DiskEntry->Bus,
937 DiskEntry->Id,
938 PartEntry->OnDiskPartitionNumber);
939 DPRINT1("Removable disk, using SIGNATURE ARC path '%S'\n", PathBuffer);
940#endif
941 }
942
943 if (!NT_SUCCESS(Status))
944 {
945 DPRINT1("RtlStringCchPrintfW() failed with status 0x%08lx\n", Status);
946 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
947 return Status;
948 }
949
950 Status = ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallationDir);
951
952 if (!NT_SUCCESS(Status))
953 {
954 DPRINT1("ConcatPaths() failed with status 0x%08lx\n", Status);
955 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
956 return Status;
957 }
958
959 Status = RtlCreateUnicodeString(&pSetupData->DestinationArcPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
960
961 if (!NT_SUCCESS(Status))
962 {
963 DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
964 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
965 return Status;
966 }
967
969 /* Create 'pSetupData->DestinationPath' string */
970 RtlFreeUnicodeString(&pSetupData->DestinationPath);
971 Status = CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
972 pSetupData->DestinationRootPath.Buffer, InstallationDir);
973
974 if (!NT_SUCCESS(Status))
975 {
976 DPRINT1("CombinePaths() failed with status 0x%08lx\n", Status);
977 RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
978 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
979 return Status;
980 }
981
982 Status = RtlCreateUnicodeString(&pSetupData->DestinationPath, PathBuffer) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
983
984 if (!NT_SUCCESS(Status))
985 {
986 DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
987 RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
988 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
989 return Status;
990 }
991
993 // FIXME: This is only temporary!! Must be removed later!
994 Status = RtlCreateUnicodeString(&pSetupData->InstallPath, InstallationDir) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
995
996 if (!NT_SUCCESS(Status))
997 {
998 DPRINT1("RtlCreateUnicodeString() failed with status 0x%08lx\n", Status);
999 RtlFreeUnicodeString(&pSetupData->DestinationPath);
1000 RtlFreeUnicodeString(&pSetupData->DestinationArcPath);
1001 RtlFreeUnicodeString(&pSetupData->DestinationRootPath);
1002 return Status;
1003 }
1004
1005 return STATUS_SUCCESS;
1006}
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:642
UNICODE_STRING Volume
Definition: fltkernel.h:1172
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define RTL_NUMBER_OF_FIELD(type, field)
Definition: ntbasedef.h:711
@ FixedMedia
Definition: ntdddisk.h:383
#define _countof(array)
Definition: sndvol32.h:70
ULONG HwAdapterNumber
Definition: partlist.h:121
ULONG HwControllerNumber
Definition: partlist.h:122
BOOLEAN BiosFound
Definition: partlist.h:120
USHORT Bus
Definition: partlist.h:132
USHORT Id
Definition: partlist.h:133
USHORT Port
Definition: partlist.h:131
MEDIA_TYPE MediaType
Definition: partlist.h:106
ULONG HwFixedDiskNumber
Definition: partlist.h:124
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:143
BOOLEAN IsPartitioned
Definition: partlist.h:82
struct _DISKENTRY * DiskEntry
Definition: partlist.h:66
ULONG OnDiskPartitionNumber
Definition: partlist.h:74
ULONG PartitionNumber
Definition: partlist.h:75
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

Referenced by InstallDirectoryPage(), and PrepareAndDoCopyThread().

â—† InitializeSetup()

ERROR_NUMBER InitializeSetup ( IN OUT PUSETUP_DATA  pSetupData,
IN ULONG  InitPhase 
)

Definition at line 1010 of file setuplib.c.

1013{
1014 if (InitPhase == 0)
1015 {
1016 RtlZeroMemory(pSetupData, sizeof(*pSetupData));
1017
1018 /* Initialize error handling */
1019 pSetupData->LastErrorNumber = ERROR_SUCCESS;
1020 pSetupData->ErrorRoutine = NULL;
1021
1022 /* Initialize global unicode strings */
1023 RtlInitUnicodeString(&pSetupData->SourcePath, NULL);
1024 RtlInitUnicodeString(&pSetupData->SourceRootPath, NULL);
1025 RtlInitUnicodeString(&pSetupData->SourceRootDir, NULL);
1026 RtlInitUnicodeString(&pSetupData->DestinationArcPath, NULL);
1027 RtlInitUnicodeString(&pSetupData->DestinationPath, NULL);
1028 RtlInitUnicodeString(&pSetupData->DestinationRootPath, NULL);
1029 RtlInitUnicodeString(&pSetupData->SystemRootPath, NULL);
1030
1031 // FIXME: This is only temporary!! Must be removed later!
1032 /***/RtlInitUnicodeString(&pSetupData->InstallPath, NULL);/***/
1033
1034 //
1035 // TODO: Load and start SetupDD, and ask it for the information
1036 //
1037
1038 return ERROR_SUCCESS;
1039 }
1040 else
1041 if (InitPhase == 1)
1042 {
1045
1046 /* Get the source path and source root path */
1047 Status = GetSourcePaths(&pSetupData->SourcePath,
1048 &pSetupData->SourceRootPath,
1049 &pSetupData->SourceRootDir);
1050 if (!NT_SUCCESS(Status))
1051 {
1052 DPRINT1("GetSourcePaths() failed (Status 0x%08lx)\n", Status);
1053 return ERROR_NO_SOURCE_DRIVE;
1054 }
1055 DPRINT1("SourcePath (1): '%wZ'\n", &pSetupData->SourcePath);
1056 DPRINT1("SourceRootPath (1): '%wZ'\n", &pSetupData->SourceRootPath);
1057 DPRINT1("SourceRootDir (1): '%wZ'\n", &pSetupData->SourceRootDir);
1058
1059 /* Set up default values */
1060 pSetupData->DestinationDiskNumber = 0;
1061 pSetupData->DestinationPartitionNumber = 1;
1062 pSetupData->BootLoaderLocation = 2; // Default to "System partition"
1063 pSetupData->FormatPartition = 0;
1064 pSetupData->AutoPartition = 0;
1065 pSetupData->FsType = 0;
1066
1067 /* Load 'txtsetup.sif' from the installation media */
1068 Error = LoadSetupInf(pSetupData);
1069 if (Error != ERROR_SUCCESS)
1070 {
1071 DPRINT1("LoadSetupInf() failed (Error 0x%lx)\n", Error);
1072 return Error;
1073 }
1074 DPRINT1("SourcePath (2): '%wZ'\n", &pSetupData->SourcePath);
1075 DPRINT1("SourceRootPath (2): '%wZ'\n", &pSetupData->SourceRootPath);
1076 DPRINT1("SourceRootDir (2): '%wZ'\n", &pSetupData->SourceRootDir);
1077
1078 /* Retrieve the target machine architecture type */
1079 // FIXME: This should be determined at runtime!!
1080 // FIXME: Allow for (pre-)installing on an architecture
1081 // different from the current one?
1082#if defined(SARCH_XBOX)
1083 pSetupData->ArchType = ARCH_Xbox;
1084// #elif defined(SARCH_PC98)
1085#else // TODO: Arc, UEFI
1086 pSetupData->ArchType = (IsNEC_98 ? ARCH_NEC98x86 : ARCH_PcAT);
1087#endif
1088
1089 return ERROR_SUCCESS;
1090 }
1091
1092 return ERROR_SUCCESS;
1093}
BOOL Error
Definition: chkdsk.c:66
#define ERROR_SUCCESS
Definition: deptool.c:10
enum _ERROR_NUMBER ERROR_NUMBER
@ ERROR_NO_SOURCE_DRIVE
Definition: errorcode.h:23
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ERROR_NUMBER LoadSetupInf(IN OUT PUSETUP_DATA pSetupData)
Definition: setuplib.c:557
NTSTATUS GetSourcePaths(_Out_ PUNICODE_STRING SourcePath, _Out_ PUNICODE_STRING SourceRootPath, _Out_ PUNICODE_STRING SourceRootDir)
Determine the installation source path and isolate its useful path components (root path and source s...
Definition: setuplib.c:402
@ ARCH_NEC98x86
Definition: setuplib.h:47
@ ARCH_PcAT
Definition: setuplib.h:46
@ ARCH_Xbox
Definition: setuplib.h:48
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IsNEC_98
Definition: ketypes.h:911

Referenced by _tWinMain(), RunUSetup(), and SetupStartPage().

â—† InitSystemPartition()

BOOLEAN InitSystemPartition ( _In_ PPARTLIST  PartitionList,
_In_ PPARTENTRY  InstallPartition,
_Out_ PPARTENTRY pSystemPartition,
_In_opt_ PFSVOL_CALLBACK  FsVolCallback,
_In_opt_ PVOID  Context 
)

Find or set the active system partition.

Definition at line 672 of file setuplib.c.

678{
681 PPARTENTRY OldActivePart;
682
683 /*
684 * If we install on a fixed disk, try to find a supported system
685 * partition on the system. Otherwise if we install on a removable disk
686 * use the install partition as the system partition.
687 */
688 if (InstallPartition->DiskEntry->MediaType == FixedMedia)
689 {
691 FALSE,
694 /* Use the original system partition as the old active partition hint */
695 OldActivePart = PartitionList->SystemPartition;
696
699 {
700 DPRINT1("We are using a different system partition!!\n");
701
705 0);
706 if (Result != FSVOL_DOIT)
707 return FALSE;
708 }
709 }
710 else // if (InstallPartition->DiskEntry->MediaType == RemovableMedia)
711 {
713 /* Don't specify any old active partition hint */
714 OldActivePart = NULL;
715 }
716
717 if (!SystemPartition)
718 {
722 0);
723 return FALSE;
724 }
725
726 *pSystemPartition = SystemPartition;
727
728 /*
729 * If the system partition can be created in some
730 * non-partitioned space, create it now.
731 */
733 {
734 /* Automatically create the partition; it will be
735 * formatted later with default parameters */
736 // FIXME: Don't use the whole empty space, but a minimal size
737 // specified from the TXTSETUP.SIF or unattended setup.
740 0ULL,
741 0);
743 }
744
745 /* Set it as such */
747 {
748 DPRINT1("SetActivePartition(0x%p) failed?!\n", SystemPartition);
749 ASSERT(FALSE);
750 }
751
752 /*
753 * In all cases, whether or not we are going to perform a formatting,
754 * we must perform a filesystem check of the system partition.
755 */
758
759 return TRUE;
760}
static FSVOL_OP CALLBACK FsVolCallback(_In_opt_ PVOID Context, _In_ FSVOLNOTIFY FormatStatus, _In_ ULONG_PTR Param1, _In_ ULONG_PTR Param2)
Definition: reactos.c:1252
PPARTENTRY InstallPartition
Definition: reactos.c:45
PPARTENTRY SystemPartition
Definition: reactos.c:50
#define ULL(a, b)
Definition: format_msg.c:27
@ FSVOLNOTIFY_PARTITIONERROR
Definition: fsutil.h:142
@ ChangeSystemPartition
Definition: fsutil.h:149
enum _FSVOL_OP FSVOL_OP
@ FSVOL_DOIT
Definition: fsutil.h:159
BOOLEAN CreatePartition(_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:2903
BOOLEAN SetActivePartition(IN PPARTLIST List, IN PPARTENTRY PartEntry, IN PPARTENTRY OldActivePart OPTIONAL)
Definition: partlist.c:3518
PPARTENTRY FindSupportedSystemPartition(IN PPARTLIST List, IN BOOLEAN ForceSelect, IN PDISKENTRY AlternativeDisk OPTIONAL, IN PPARTENTRY AlternativePart OPTIONAL)
Definition: partlist.c:3218
#define ERROR_SYSTEM_PARTITION_NOT_FOUND
Definition: setuplib.h:182
PVOLENTRY Volume
Definition: partlist.h:95
PPARTENTRY SystemPartition
Definition: partlist.h:181
BOOLEAN NeedsCheck
Definition: partlist.h:51
static PPARTLIST PartitionList
Definition: usetup.c:75
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by PrepareAndDoCopyThread(), and StartPartitionOperationsPage().

â—† InstallSetupInfFile()

VOID InstallSetupInfFile ( IN OUT PUSETUP_DATA  pSetupData)

Definition at line 202 of file setuplib.c.

204{
206 PINICACHE IniCache;
207
208#if 0 // HACK FIXME!
209 PINICACHE UnattendCache;
211#else
212 // WCHAR CrLf[] = {L'\r', L'\n'};
213 CHAR CrLf[] = {'\r', '\n'};
214 HANDLE FileHandle, UnattendFileHandle, SectionHandle;
217 PVOID ViewBase;
221#endif
222
223 PINI_SECTION IniSection;
224 WCHAR PathBuffer[MAX_PATH];
225 WCHAR UnattendInfPath[MAX_PATH];
226
227 /* Create a $winnt$.inf file with default entries */
228 IniCache = IniCacheCreate();
229 if (!IniCache)
230 return;
231
232 IniSection = IniAddSection(IniCache, L"SetupParams");
233 if (IniSection)
234 {
235 /* Key "skipmissingfiles" */
236 // RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
237 // L"\"%s\"", L"WinNt5.2");
238 // IniAddKey(IniSection, L"Version", PathBuffer);
239 }
240
241 IniSection = IniAddSection(IniCache, L"Data");
242 if (IniSection)
243 {
244 RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
245 L"\"%s\"", IsUnattendedSetup ? L"yes" : L"no");
246 IniAddKey(IniSection, L"UnattendedInstall", PathBuffer);
247
248 // "floppylessbootpath" (yes/no)
249
250 RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
251 L"\"%s\"", L"winnt");
252 IniAddKey(IniSection, L"ProductType", PathBuffer);
253
254 RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
255 L"\"%s\\\"", pSetupData->SourceRootPath.Buffer);
256 IniAddKey(IniSection, L"SourcePath", PathBuffer);
257
258 // "floppyless" ("0")
259 }
260
261#if 0
262
263 /* TODO: Append the standard unattend.inf file */
264 CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
265 pSetupData->SourcePath.Buffer, L"unattend.inf");
266 if (DoesFileExist(NULL, UnattendInfPath) == FALSE)
267 {
268 DPRINT("Does not exist: %S\n", UnattendInfPath);
269 goto Quit;
270 }
271
272 Status = IniCacheLoad(&UnattendCache, UnattendInfPath, FALSE);
273 if (!NT_SUCCESS(Status))
274 {
275 DPRINT1("Cannot load %S as an INI file!\n", UnattendInfPath);
276 goto Quit;
277 }
278
279 IniCacheDestroy(UnattendCache);
280
281Quit:
282 CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
283 pSetupData->DestinationPath.Buffer, L"System32\\$winnt$.inf");
284 IniCacheSave(IniCache, PathBuffer);
285 IniCacheDestroy(IniCache);
286
287#else
288
289 CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
290 pSetupData->DestinationPath.Buffer, L"System32\\$winnt$.inf");
291 IniCacheSave(IniCache, PathBuffer);
292 IniCacheDestroy(IniCache);
293
294 /* TODO: Append the standard unattend.inf file */
295 CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
296 pSetupData->SourcePath.Buffer, L"unattend.inf");
297 if (DoesFileExist(NULL, UnattendInfPath) == FALSE)
298 {
299 DPRINT("Does not exist: %S\n", UnattendInfPath);
300 return;
301 }
302
303 RtlInitUnicodeString(&FileName, PathBuffer);
305 &FileName,
307 NULL,
308 NULL);
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("Cannot load %S as an INI file!\n", PathBuffer);
318 return;
319 }
320
321 /* Query the file size */
324 &FileInfo,
325 sizeof(FileInfo),
327 if (!NT_SUCCESS(Status))
328 {
329 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
330 FileInfo.EndOfFile.QuadPart = 0ULL;
331 }
332
334 UnattendInfPath,
335 &UnattendFileHandle,
336 &FileSize,
337 &SectionHandle,
338 &ViewBase,
339 FALSE);
340 if (!NT_SUCCESS(Status))
341 {
342 DPRINT1("Cannot load %S !\n", UnattendInfPath);
344 return;
345 }
346
347 /* Write to the INI file */
348
349 /* "\r\n" */
351 NULL,
352 NULL,
353 NULL,
355 (PVOID)CrLf,
356 sizeof(CrLf),
357 &FileInfo.EndOfFile,
358 NULL);
359
361 NULL,
362 NULL,
363 NULL,
365 ViewBase,
366 FileSize,
367 NULL,
368 NULL);
369 if (!NT_SUCCESS(Status))
370 {
371 DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
372 }
373
374 /* Finally, unmap and close the file */
375 UnMapAndCloseFile(UnattendFileHandle, SectionHandle, ViewBase);
376
378#endif
379}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
struct _FileName FileName
Definition: fatprocs.h:897
NTSTATUS OpenAndMapFile(_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathNameToFile, _Out_opt_ PHANDLE FileHandle, _Out_opt_ PULONG FileSize, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Opens and maps a file in memory.
Definition: filesup.c:879
#define UnMapAndCloseFile(FileHandle, SectionHandle, BaseAddress)
Definition: filesup.h:121
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define OBJ_OPENIF
Definition: winternl.h:229
VOID IniCacheDestroy(_In_ PINICACHE Cache)
Definition: inicache.c:699
NTSTATUS IniCacheLoad(PINICACHE *Cache, PWCHAR FileName, BOOLEAN String)
Definition: inicache.c:655
PINI_SECTION IniAddSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:838
NTSTATUS IniCacheSave(PINICACHE Cache, PWCHAR FileName)
Definition: inicache.c:1038
PINICACHE IniCacheCreate(VOID)
Definition: inicache.c:919
PINI_KEYWORD IniAddKey(_In_ PINI_SECTION Section, _In_ PCWSTR Name, _In_ PCWSTR Data)
Definition: inicache.c:883
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FileStandardInformation
Definition: propsheet.cpp:61
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656
char CHAR
Definition: xmlstorage.h:175

Referenced by FileCopyPage(), and PrepareAndDoCopyThread().

â—† IsValidInstallDirectory()

BOOLEAN IsValidInstallDirectory ( _In_ PCWSTR  InstallDir)

Verify whether the given directory is suitable for ReactOS installation. Each path component must be a valid 8.3 name.

Definition at line 771 of file setuplib.c.

773{
774 PCWCH p;
775
776 /* As with the NT installer, fail if the path is empty or "\\" */
777 p = InstallDir;
778 if (!*p || (IS_PATH_SEPARATOR(*p) && !*(p + 1)))
779 return FALSE;
780
781 /* The path must contain only valid characters */
782 for (p = InstallDir; *p; ++p)
783 {
785 return FALSE;
786 }
787
788 /*
789 * Loop over each path component and verify that each is a valid 8.3 name.
790 */
791 for (p = InstallDir; *p;)
792 {
793 PCWSTR Path;
796 BOOLEAN IsNameLegal, SpacesInName;
797
798 /* Skip any first separator */
799 if (IS_PATH_SEPARATOR(*p))
800 ++p;
801
802 /* Now skip past the path component until we reach the next separator */
803 Path = p;
804 while (*p && !IS_PATH_SEPARATOR(*p))
805 ++p;
806 if (p == Path)
807 {
808 /* Succeed if nothing else follows this separator; otherwise
809 * it's a separator and consecutive ones are not supported */
810 return (!*p);
811 }
812
813 /* Calculate the path component length */
814 Length = p - Path;
815
816 /* As with the NT installer, fail for '.' and '..';
817 * RtlIsNameLegalDOS8Dot3() would succeed otherwise */
818 if ((Length == 1 && *Path == '.') || (Length == 2 && *Path == '.' && *(Path + 1) == '.'))
819 return FALSE;
820
821 /* As with the NT installer, allow _only ONE trailing_ dot in
822 * the path component (but not 2 or more), by reducing Length
823 * in that case; RtlIsNameLegalDOS8Dot3() would fail otherwise */
824 if (Length > 1 && *(p - 2) != L'.' && *(p - 1) == L'.')
825 --Length;
826
827 if (Length == 0)
828 return FALSE;
829
830 /* Verify that the path component is a valid 8.3 name */
831 // if (Length > 8+1+3)
832 // return FALSE;
833 Name.Length = Name.MaximumLength = (USHORT)(Length * sizeof(WCHAR));
834 Name.Buffer = (PWCHAR)Path;
835 SpacesInName = FALSE;
836 IsNameLegal = RtlIsNameLegalDOS8Dot3(&Name, NULL, &SpacesInName);
837
838 /* If it isn't legal or contain spaces, fail */
839 if (!IsNameLegal || SpacesInName)
840 {
841 DPRINT("'%wZ' is %s 8.3 filename %s spaces\n",
842 &Name,
843 (IsNameLegal ? "a valid" : "an invalid"),
844 (SpacesInName ? "with" : "without"));
845 return FALSE;
846 }
847 /* Go to the next path component */
848 }
849
850 return TRUE;
851}
unsigned char BOOLEAN
PRTL_UNICODE_STRING_BUFFER Path
struct NameRec_ * Name
Definition: cdprocs.h:460
GLfloat GLfloat p
Definition: glext.h:8902
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
CONST WCHAR * PCWCH
Definition: ntbasedef.h:419
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define IS_PATH_SEPARATOR(c)
Definition: setuplib.c:763
#define IS_VALID_INSTALL_PATH_CHAR(c)
Defines the class of characters valid for the installation directory.
Definition: setuplib.h:199
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by InstallDirectoryPage(), MoreOptDlgProc(), and START_TEST().

â—† LoadSetupInf()

ERROR_NUMBER LoadSetupInf ( IN OUT PUSETUP_DATA  pSetupData)

Definition at line 557 of file setuplib.c.

559{
561 UINT ErrorLine;
562 INT IntValue;
565
567 pSetupData->SourcePath.Buffer, L"txtsetup.sif");
568
569 DPRINT("SetupInf path: '%S'\n", FileNameBuffer);
570
571 pSetupData->SetupInf =
573 NULL,
575 pSetupData->LanguageId,
576 &ErrorLine);
577 if (pSetupData->SetupInf == INVALID_HANDLE_VALUE)
579
580 /* Open 'Version' section */
581 if (!SpInfFindFirstLine(pSetupData->SetupInf, L"Version", L"Signature", &Context))
583
584 /* Get pointer 'Signature' key */
585 if (!INF_GetData(&Context, NULL, &Value))
587
588 /* Check 'Signature' string */
589 if (_wcsicmp(Value, L"$ReactOS$") != 0 &&
590 _wcsicmp(Value, L"$Windows NT$") != 0)
591 {
594 }
595
597
598 /* Open 'DiskSpaceRequirements' section */
599 if (!SpInfFindFirstLine(pSetupData->SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context))
601
602 pSetupData->RequiredPartitionDiskSpace = ~0;
603
604 /* Get the 'FreeSysPartDiskSpace' value */
605 if (!SpInfGetIntField(&Context, 1, &IntValue))
607
608 pSetupData->RequiredPartitionDiskSpace = (ULONG)IntValue;
609
610 //
611 // Support "SetupSourceDevice" and "SetupSourcePath" in txtsetup.sif
612 // See CORE-9023
613 // Support for that should also be added in setupldr.
614 //
615
616 /* Update the Setup Source paths */
617 if (SpInfFindFirstLine(pSetupData->SetupInf, L"SetupData", L"SetupSourceDevice", &Context))
618 {
619 /*
620 * Get optional pointer 'SetupSourceDevice' key, its presence
621 * will dictate whether we also need 'SetupSourcePath'.
622 */
623 if (INF_GetData(&Context, NULL, &Value))
624 {
625 /* Free the old source root path string and create the new one */
626 RtlFreeUnicodeString(&pSetupData->SourceRootPath);
627 RtlCreateUnicodeString(&pSetupData->SourceRootPath, Value);
629
630 if (!SpInfFindFirstLine(pSetupData->SetupInf, L"SetupData", L"SetupSourcePath", &Context))
631 {
632 /* The 'SetupSourcePath' value is mandatory! */
634 }
635
636 /* Get pointer 'SetupSourcePath' key */
637 if (!INF_GetData(&Context, NULL, &Value))
638 {
639 /* The 'SetupSourcePath' value is mandatory! */
641 }
642
643 /* Free the old source path string and create the new one */
644 RtlFreeUnicodeString(&pSetupData->SourceRootDir);
645 RtlCreateUnicodeString(&pSetupData->SourceRootDir, Value);
647 }
648 }
649
650 /* Search for 'DefaultPath' in the 'SetupData' section */
651 pSetupData->InstallationDirectory[0] = 0;
652 if (SpInfFindFirstLine(pSetupData->SetupInf, L"SetupData", L"DefaultPath", &Context))
653 {
654 /* Get pointer 'DefaultPath' key */
655 if (!INF_GetData(&Context, NULL, &Value))
657
658 RtlStringCchCopyW(pSetupData->InstallationDirectory,
659 ARRAYSIZE(pSetupData->InstallationDirectory),
660 Value);
661
663 }
664
665 return ERROR_SUCCESS;
666}
WCHAR FileNameBuffer[MAX_PATH]
Definition: framewnd.c:225
@ ERROR_SIGNATURE_TXTSETUPSIF
Definition: errorcode.h:26
@ ERROR_CORRUPT_TXTSETUPSIF
Definition: errorcode.h:25
@ ERROR_LOAD_TXTSETUPSIF
Definition: errorcode.h:24
#define INF_STYLE_WIN4
Definition: infsupp.h:41

Referenced by InitializeSetup().

â—† UpdateRegistry()

ERROR_NUMBER UpdateRegistry ( IN OUT PUSETUP_DATA  pSetupData,
IN BOOLEAN  RepairUpdateFlag,
IN PPARTLIST  PartitionList,
IN WCHAR  DestinationDriveLetter,
IN PCWSTR  SelectedLanguageId,
IN PREGISTRY_STATUS_ROUTINE StatusRoutine  OPTIONAL,
IN PFONTSUBSTSETTINGS SubstSettings  OPTIONAL 
)

Definition at line 1146 of file setuplib.c.

1154{
1155 ERROR_NUMBER ErrorNumber;
1157 INFCONTEXT InfContext;
1158 PCWSTR Action;
1159 PCWSTR File;
1160 PCWSTR Section;
1162 BOOLEAN ShouldRepairRegistry = FALSE;
1164
1165 if (RepairUpdateFlag)
1166 {
1167 DPRINT1("TODO: Updating / repairing the registry is not completely implemented yet!\n");
1168
1169 /* Verify the registry hives and check whether we need to update or repair any of them */
1170 Status = VerifyRegistryHives(&pSetupData->DestinationPath, &ShouldRepairRegistry);
1171 if (!NT_SUCCESS(Status))
1172 {
1173 DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status);
1174 ShouldRepairRegistry = FALSE;
1175 }
1176 if (!ShouldRepairRegistry)
1177 DPRINT1("No need to repair the registry\n");
1178 }
1179
1180DoUpdate:
1181 ErrorNumber = ERROR_SUCCESS;
1182
1183 /* Update the registry */
1185
1186 /* Initialize the registry and setup the registry hives */
1187 Status = RegInitializeRegistry(&pSetupData->DestinationPath);
1188 if (!NT_SUCCESS(Status))
1189 {
1190 DPRINT1("RegInitializeRegistry() failed\n");
1191 /********** HACK!!!!!!!!!!! **********/
1193 {
1194 /* The hack was called, return its corresponding error */
1196 }
1197 else
1198 /*************************************/
1199 {
1200 /* Something else failed */
1201 return ERROR_CREATE_HIVE;
1202 }
1203 }
1204
1205 if (!RepairUpdateFlag || ShouldRepairRegistry)
1206 {
1207 /*
1208 * We fully setup the hives, in case we are doing a fresh installation
1209 * (RepairUpdateFlag == FALSE), or in case we are doing an update
1210 * (RepairUpdateFlag == TRUE) BUT we have some registry hives to
1211 * "repair" (aka. recreate: ShouldRepairRegistry == TRUE).
1212 */
1213
1214 Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Fresh", NULL, &InfContext); // Windows-compatible
1215 if (!Success)
1216 Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Install", NULL, &InfContext); // ReactOS-specific
1217
1218 if (!Success)
1219 {
1220 DPRINT1("SpInfFindFirstLine() failed\n");
1221 ErrorNumber = ERROR_FIND_REGISTRY;
1222 goto Cleanup;
1223 }
1224 }
1225 else // if (RepairUpdateFlag && !ShouldRepairRegistry)
1226 {
1227 /*
1228 * In case we are doing an update (RepairUpdateFlag == TRUE) and
1229 * NO registry hives need a repair (ShouldRepairRegistry == FALSE),
1230 * we only update the hives.
1231 */
1232
1233 Success = SpInfFindFirstLine(pSetupData->SetupInf, L"HiveInfs.Upgrade", NULL, &InfContext);
1234 if (!Success)
1235 {
1236 /* Nothing to do for update! */
1237 DPRINT1("No update needed for the registry!\n");
1238 goto Cleanup;
1239 }
1240 }
1241
1242 do
1243 {
1244 INF_GetDataField(&InfContext, 0, &Action);
1245 INF_GetDataField(&InfContext, 1, &File);
1246 INF_GetDataField(&InfContext, 2, &Section);
1247
1248 DPRINT("Action: %S File: %S Section %S\n", Action, File, Section);
1249
1250 if (Action == NULL)
1251 {
1254 INF_FreeData(Section);
1255 break; // Hackfix
1256 }
1257
1258 if (!_wcsicmp(Action, L"AddReg"))
1259 Delete = FALSE;
1260 else if (!_wcsicmp(Action, L"DelReg"))
1261 Delete = TRUE;
1262 else
1263 {
1264 DPRINT1("Unrecognized registry INF action '%S'\n", Action);
1267 INF_FreeData(Section);
1268 continue;
1269 }
1270
1272
1274
1275 if (!ImportRegistryFile(pSetupData->SourcePath.Buffer,
1276 File, Section,
1277 pSetupData->LanguageId, Delete))
1278 {
1279 DPRINT1("Importing %S failed\n", File);
1281 INF_FreeData(Section);
1282 ErrorNumber = ERROR_IMPORT_HIVE;
1283 goto Cleanup;
1284 }
1285 } while (SpInfFindNextLine(&InfContext, &InfContext));
1286
1287 if (!RepairUpdateFlag || ShouldRepairRegistry)
1288 {
1289 /* See the explanation for this test above */
1290
1292 PCWSTR LanguageId; // LocaleID;
1293
1294 Entry = GetCurrentListEntry(pSetupData->DisplayList);
1295 ASSERT(Entry);
1296 pSetupData->DisplayType = ((PGENENTRY)GetListEntryData(Entry))->Id;
1297 ASSERT(pSetupData->DisplayType);
1298
1299 /* Update display registry settings */
1301 if (!ProcessDisplayRegistry(pSetupData->SetupInf, pSetupData->DisplayType))
1302 {
1303 ErrorNumber = ERROR_UPDATE_DISPLAY_SETTINGS;
1304 goto Cleanup;
1305 }
1306
1307 Entry = GetCurrentListEntry(pSetupData->LanguageList);
1308 ASSERT(Entry);
1309 LanguageId = ((PGENENTRY)GetListEntryData(Entry))->Id;
1310 ASSERT(LanguageId);
1311
1312 /* Set the locale */
1314 if (!ProcessLocaleRegistry(/*pSetupData->*/LanguageId))
1315 {
1316 ErrorNumber = ERROR_UPDATE_LOCALESETTINGS;
1317 goto Cleanup;
1318 }
1319
1320 /* Add the keyboard layouts for the given language (without user override) */
1323 {
1324 ErrorNumber = ERROR_ADDING_KBLAYOUTS;
1325 goto Cleanup;
1326 }
1327
1328 if (!IsUnattendedSetup)
1329 {
1330 Entry = GetCurrentListEntry(pSetupData->LayoutList);
1331 ASSERT(Entry);
1332 pSetupData->LayoutId = ((PGENENTRY)GetListEntryData(Entry))->Id;
1333 ASSERT(pSetupData->LayoutId);
1334
1335 /* Update keyboard layout settings with user-overridden values */
1336 // FIXME: Wouldn't it be better to do it all at once
1337 // with the AddKeyboardLayouts() step?
1339 if (!ProcessKeyboardLayoutRegistry(pSetupData->LayoutId, SelectedLanguageId))
1340 {
1341 ErrorNumber = ERROR_UPDATE_KBSETTINGS;
1342 goto Cleanup;
1343 }
1344 }
1345
1346 /* Set GeoID */
1348 {
1349 ErrorNumber = ERROR_UPDATE_GEOID;
1350 goto Cleanup;
1351 }
1352
1353 /* Add codepage information to registry */
1356 {
1357 ErrorNumber = ERROR_ADDING_CODEPAGE;
1358 goto Cleanup;
1359 }
1360
1361 /* Set the default pagefile entry */
1362 SetDefaultPagefile(DestinationDriveLetter);
1363
1364 /* Update the mounted devices list */
1365 // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
1367 }
1368
1369#ifdef __REACTOS__
1370 if (SubstSettings)
1371 {
1372 /* HACK */
1373 DoRegistryFontFixup(SubstSettings, wcstoul(SelectedLanguageId, NULL, 16));
1374 }
1375#endif
1376
1377Cleanup:
1378 //
1379 // TODO: Unload all the registry stuff, perform cleanup,
1380 // and copy the created hive files into .sav files.
1381 //
1382 RegCleanupRegistry(&pSetupData->DestinationPath);
1383
1384 /*
1385 * Check whether we were in update/repair mode but we were actually
1386 * repairing the registry hives. If so, we have finished repairing them,
1387 * and we now reset the flag and run the proper registry update.
1388 * Otherwise we have finished the registry update!
1389 */
1390 if (RepairUpdateFlag && ShouldRepairRegistry)
1391 {
1392 ShouldRepairRegistry = FALSE;
1393 goto DoUpdate;
1394 }
1395
1396 return ErrorNumber;
1397}
static BOOL ImportRegistryFile(HWND hWnd)
Definition: framewnd.c:439
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
VOID RegCleanupRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:997
NTSTATUS RegInitializeRegistry(IN PUNICODE_STRING NtSystemRoot)
Definition: registry.c:679
NTSTATUS VerifyRegistryHives(IN PUNICODE_STRING NtSystemRoot, OUT PBOOLEAN ShouldRepairRegistry)
Definition: registry.c:603
BOOLEAN SetDefaultPagefile(_In_ WCHAR Drive)
Definition: settings.c:1370
BOOLEAN ProcessKeyboardLayoutRegistry(_In_ PCWSTR pszLayoutId, _In_ PCWSTR LanguageId)
Definition: settings.c:1267
BOOLEAN ProcessDisplayRegistry(_In_ HINF InfFile, _In_ PCWSTR DisplayType)
Definition: settings.c:806
BOOLEAN SetGeoID(_In_ GEOID GeoId)
Definition: settings.c:1320
BOOLEAN ProcessLocaleRegistry(_In_ PCWSTR LanguageId)
Definition: settings.c:969
struct _GENENTRY * PGENENTRY
Definition: File.h:16
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static const WCHAR Cleanup[]
Definition: register.c:80
@ ERROR_ADDING_CODEPAGE
Definition: errorcode.h:52
@ ERROR_UPDATE_GEOID
Definition: errorcode.h:55
@ ERROR_IMPORT_HIVE
Definition: errorcode.h:39
@ ERROR_FIND_REGISTRY
Definition: errorcode.h:40
@ ERROR_UPDATE_LOCALESETTINGS
Definition: errorcode.h:53
@ ERROR_INITIALIZE_REGISTRY
Definition: errorcode.h:42
@ ERROR_CREATE_HIVE
Definition: errorcode.h:41
@ ERROR_ADDING_KBLAYOUTS
Definition: errorcode.h:54
@ ERROR_UPDATE_DISPLAY_SETTINGS
Definition: errorcode.h:38
@ ERROR_UPDATE_KBSETTINGS
Definition: errorcode.h:37
@ Success
Definition: eventcreate.c:712
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
pSpInfFindNextLine SpInfFindNextLine
Definition: infsupp.c:88
GEOID MUIGetGeoID(IN PCWSTR LanguageId)
Definition: mui.c:104
BOOLEAN AddCodePage(IN PCWSTR LanguageId)
Definition: mui.c:534
BOOLEAN AddKeyboardLayouts(IN PCWSTR LanguageId)
Definition: mui.c:362
BOOLEAN INF_GetDataField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PCWSTR *Data)
Definition: infsupp.c:42
PGENERIC_LIST_ENTRY GetCurrentListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:97
PVOID GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)
Definition: genlist.c:126
static const char const char const char PIMAGEHLP_STATUS_ROUTINE StatusRoutine
Definition: image.c:35
BOOLEAN SetMountedDeviceValues(_In_ PPARTLIST List)
Definition: partlist.c:3867
@ KeybLayouts
Definition: setuplib.h:230
@ DisplaySettingsUpdate
Definition: setuplib.h:228
@ CodePageInfoUpdate
Definition: setuplib.h:232
@ LocaleSettingsUpdate
Definition: setuplib.h:229
@ RegHiveUpdate
Definition: setuplib.h:226
@ ImportRegHive
Definition: setuplib.h:227
@ KeybSettingsUpdate
Definition: setuplib.h:231
base of all file and directory entries
Definition: entries.h:83
Definition: genlist.h:11
BOOL DoRegistryFontFixup(PFONTSUBSTSETTINGS pSettings, LANGID LangID)
static BOOLEAN RepairUpdateFlag
Definition: usetup.c:72
PCWSTR SelectedLanguageId
Definition: usetup.c:68
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510

Referenced by PrepareAndDoCopyThread(), and RegistryPage().