Skip to content

Commit 064dd8f

Browse files
committed
[USERINIT] Locate and cache early the path to the ReactOS installer when starting in livecd mode
- Move `ExpandInstallerPath()` from userinit.c to livecd.c, and update its SAL2 annotations and Doxygen comment. - Make `StartInstaller()` directly use the cached ReactOS installer path. - This avoids invoking yet again `ExpandInstallerPath()` when trying to locate the installer also for the aim of determining whether to disable the "Install" button.
1 parent d524789 commit 064dd8f

3 files changed

Lines changed: 151 additions & 165 deletions

File tree

‎base/system/userinit/livecd.c‎

Lines changed: 140 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ HWND hList;
1111
HWND hLocaleList;
1212
BOOL bSpain = FALSE;
1313

14+
WCHAR Installer[MAX_PATH];
15+
1416
typedef struct _LIVECD_UNATTEND
1517
{
1618
BOOL bEnabled;
@@ -200,7 +202,6 @@ CreateLanguagesList(HWND hwnd, PSTATE pState)
200202
(LPARAM)langSel);
201203
}
202204

203-
204205
static
205206
BOOL
206207
GetLayoutName(
@@ -267,7 +268,6 @@ GetLayoutName(
267268
return FALSE;
268269
}
269270

270-
271271
static
272272
VOID
273273
SetKeyboardLayout(
@@ -292,7 +292,6 @@ SetKeyboardLayout(
292292
SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDCHANGE);
293293
}
294294

295-
296295
static
297296
VOID
298297
SelectKeyboardForLanguage(
@@ -336,7 +335,6 @@ SelectKeyboardForLanguage(
336335
TRACE("No match found!\n");
337336
}
338337

339-
340338
static
341339
VOID
342340
CreateKeyboardLayoutList(
@@ -395,7 +393,6 @@ CreateKeyboardLayoutList(
395393
RegCloseKey(hKey);
396394
}
397395

398-
399396
static
400397
VOID
401398
InitializeDefaultUserLocale(
@@ -543,7 +540,6 @@ CenterWindow(HWND hWnd)
543540
SWP_NOSIZE);
544541
}
545542

546-
547543
static
548544
VOID
549545
OnDrawItem(
@@ -718,7 +714,6 @@ LocaleDlgProc(
718714
return FALSE;
719715
}
720716

721-
722717
static
723718
INT_PTR
724719
CALLBACK
@@ -737,19 +732,16 @@ StartDlgProc(
737732
{
738733
case WM_INITDIALOG:
739734
{
740-
WCHAR Installer[MAX_PATH];
741-
742735
/* Save pointer to the state */
743736
pState = (PSTATE)lParam;
744737
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState);
745738

746739
/* Center the dialog window */
747740
CenterWindow(hwndDlg);
748741

749-
/* Check whether we can find the ReactOS installer. If not,
750-
* disable the "Install" button and directly start the LiveCD. */
751-
*Installer = UNICODE_NULL;
752-
if (!ExpandInstallerPath(L"reactos.exe", Installer, ARRAYSIZE(Installer)))
742+
/* If the ReactOS Installer could not be located, disable
743+
* the "Install" button and directly start the LiveCD. */
744+
if (!*Installer)
753745
EnableWindow(GetDlgItem(hwndDlg, IDC_INSTALL), FALSE);
754746

755747
if (pState->Unattend->bEnabled || (*Installer == UNICODE_NULL))
@@ -856,20 +848,154 @@ VOID ParseUnattend(LPCWSTR UnattendInf, LIVECD_UNATTEND* pUnattend)
856848
}
857849
}
858850

851+
852+
/**
853+
* @brief
854+
* Expands the path for the ReactOS Installer "reactos.exe".
855+
* See also base/setup/welcome/welcome.c!ExpandInstallerPath()
856+
**/
857+
static BOOL
858+
ExpandInstallerPath(
859+
_In_ PCWSTR pInstallerName,
860+
_Out_writes_z_(PathSize) PWSTR pInstallerPath,
861+
_In_ SIZE_T PathSize)
862+
{
863+
SYSTEM_INFO SystemInfo;
864+
SIZE_T cchInstallerNameLen;
865+
PWSTR ptr;
866+
DWORD dwAttribs;
867+
868+
cchInstallerNameLen = wcslen(pInstallerName);
869+
if (PathSize < cchInstallerNameLen)
870+
{
871+
/* The buffer is not large enough to contain the installer file name */
872+
*pInstallerPath = UNICODE_NULL;
873+
return FALSE;
874+
}
875+
876+
/*
877+
* First, try to find the installer using the default drive, under
878+
* the directory whose name corresponds to the currently-running
879+
* CPU architecture.
880+
*/
881+
GetSystemInfo(&SystemInfo);
882+
883+
*pInstallerPath = UNICODE_NULL;
884+
/* Alternatively one can use SharedUserData->NtSystemRoot */
885+
GetSystemWindowsDirectoryW(pInstallerPath, PathSize - cchInstallerNameLen - 1);
886+
ptr = wcschr(pInstallerPath, L'\\');
887+
if (ptr)
888+
*++ptr = UNICODE_NULL;
889+
else
890+
*pInstallerPath = UNICODE_NULL;
891+
892+
/* Append the corresponding CPU architecture */
893+
switch (SystemInfo.wProcessorArchitecture)
894+
{
895+
case PROCESSOR_ARCHITECTURE_INTEL:
896+
StringCchCatW(pInstallerPath, PathSize, L"I386");
897+
break;
898+
899+
case PROCESSOR_ARCHITECTURE_MIPS:
900+
StringCchCatW(pInstallerPath, PathSize, L"MIPS");
901+
break;
902+
903+
case PROCESSOR_ARCHITECTURE_ALPHA:
904+
StringCchCatW(pInstallerPath, PathSize, L"ALPHA");
905+
break;
906+
907+
case PROCESSOR_ARCHITECTURE_PPC:
908+
StringCchCatW(pInstallerPath, PathSize, L"PPC");
909+
break;
910+
911+
case PROCESSOR_ARCHITECTURE_SHX:
912+
StringCchCatW(pInstallerPath, PathSize, L"SHX");
913+
break;
914+
915+
case PROCESSOR_ARCHITECTURE_ARM:
916+
StringCchCatW(pInstallerPath, PathSize, L"ARM");
917+
break;
918+
919+
case PROCESSOR_ARCHITECTURE_IA64:
920+
StringCchCatW(pInstallerPath, PathSize, L"IA64");
921+
break;
922+
923+
case PROCESSOR_ARCHITECTURE_ALPHA64:
924+
StringCchCatW(pInstallerPath, PathSize, L"ALPHA64");
925+
break;
926+
927+
case PROCESSOR_ARCHITECTURE_AMD64:
928+
StringCchCatW(pInstallerPath, PathSize, L"AMD64");
929+
break;
930+
931+
// case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */
932+
case PROCESSOR_ARCHITECTURE_UNKNOWN:
933+
default:
934+
WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture);
935+
SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN;
936+
break;
937+
}
938+
939+
if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN)
940+
StringCchCatW(pInstallerPath, PathSize, L"\\");
941+
StringCchCatW(pInstallerPath, PathSize, pInstallerName);
942+
943+
dwAttribs = GetFileAttributesW(pInstallerPath);
944+
if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
945+
!(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
946+
{
947+
/* We have found the installer */
948+
return TRUE;
949+
}
950+
951+
WARN("Couldn't find the installer '%s', trying alternative.\n", debugstr_w(pInstallerPath));
952+
953+
/*
954+
* We failed. Try to find the installer from either the current
955+
* ReactOS installation directory, or from our current directory.
956+
*/
957+
*pInstallerPath = UNICODE_NULL;
958+
/* Alternatively one can use SharedUserData->NtSystemRoot */
959+
if (GetSystemWindowsDirectoryW(pInstallerPath, PathSize - cchInstallerNameLen - 1))
960+
StringCchCatW(pInstallerPath, PathSize, L"\\");
961+
StringCchCatW(pInstallerPath, PathSize, pInstallerName);
962+
963+
dwAttribs = GetFileAttributesW(pInstallerPath);
964+
if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
965+
!(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
966+
{
967+
/* We have found the installer */
968+
return TRUE;
969+
}
970+
971+
/* Installer not found */
972+
ERR("Couldn't find the installer '%s'\n", debugstr_w(pInstallerPath));
973+
*pInstallerPath = UNICODE_NULL;
974+
return FALSE;
975+
}
976+
859977
VOID
860978
RunLiveCD(
861979
PSTATE pState)
862980
{
863981
LIVECD_UNATTEND Unattend = {0};
864982
WCHAR UnattendInf[MAX_PATH];
865983

866-
InitLogo(&pState->ImageInfo, NULL);
984+
/* Try to locate the ReactOS Installer */
985+
if (!ExpandInstallerPath(L"reactos.exe", Installer, _countof(Installer)))
986+
*Installer = UNICODE_NULL;
987+
if (*Installer)
988+
TRACE("ReactOS Installer: '%S'\n", Installer);
989+
else
990+
WARN("Could not find the ReactOS Installer\n");
867991

868992
GetWindowsDirectoryW(UnattendInf, _countof(UnattendInf));
869993
wcscat(UnattendInf, L"\\unattend.inf");
870994
ParseUnattend(UnattendInf, &Unattend);
871995
pState->Unattend = &Unattend;
872996

997+
InitLogo(&pState->ImageInfo, NULL);
998+
873999
while (pState->NextPage != DONE)
8741000
{
8751001
switch (pState->NextPage)

0 commit comments

Comments
 (0)