diff --git a/base/system/userinit/livecd.c b/base/system/userinit/livecd.c index eb6b710052b..ad05311bc7c 100644 --- a/base/system/userinit/livecd.c +++ b/base/system/userinit/livecd.c @@ -11,6 +11,8 @@ HWND hList; HWND hLocaleList; BOOL bSpain = FALSE; +WCHAR Installer[MAX_PATH]; + typedef struct _LIVECD_UNATTEND { BOOL bEnabled; @@ -200,7 +202,6 @@ CreateLanguagesList(HWND hwnd, PSTATE pState) (LPARAM)langSel); } - static BOOL GetLayoutName( @@ -267,7 +268,6 @@ GetLayoutName( return FALSE; } - static VOID SetKeyboardLayout( @@ -292,7 +292,6 @@ SetKeyboardLayout( SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDCHANGE); } - static VOID SelectKeyboardForLanguage( @@ -336,7 +335,6 @@ SelectKeyboardForLanguage( TRACE("No match found!\n"); } - static VOID CreateKeyboardLayoutList( @@ -395,7 +393,6 @@ CreateKeyboardLayoutList( RegCloseKey(hKey); } - static VOID InitializeDefaultUserLocale( @@ -543,7 +540,6 @@ CenterWindow(HWND hWnd) SWP_NOSIZE); } - static VOID OnDrawItem( @@ -718,7 +714,6 @@ LocaleDlgProc( return FALSE; } - static INT_PTR CALLBACK @@ -737,8 +732,6 @@ StartDlgProc( { case WM_INITDIALOG: { - WCHAR Installer[MAX_PATH]; - /* Save pointer to the state */ pState = (PSTATE)lParam; SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState); @@ -746,10 +739,9 @@ StartDlgProc( /* Center the dialog window */ CenterWindow(hwndDlg); - /* Check whether we can find the ReactOS installer. If not, - * disable the "Install" button and directly start the LiveCD. */ - *Installer = UNICODE_NULL; - if (!ExpandInstallerPath(L"reactos.exe", Installer, ARRAYSIZE(Installer))) + /* If the ReactOS Installer could not be located, disable + * the "Install" button and directly start the LiveCD. */ + if (!*Installer) EnableWindow(GetDlgItem(hwndDlg, IDC_INSTALL), FALSE); if (pState->Unattend->bEnabled || (*Installer == UNICODE_NULL)) @@ -856,6 +848,132 @@ VOID ParseUnattend(LPCWSTR UnattendInf, LIVECD_UNATTEND* pUnattend) } } + +/** + * @brief + * Expands the path for the ReactOS Installer "reactos.exe". + * See also base/setup/welcome/welcome.c!ExpandInstallerPath() + **/ +static BOOL +ExpandInstallerPath( + _In_ PCWSTR pInstallerName, + _Out_writes_z_(PathSize) PWSTR pInstallerPath, + _In_ SIZE_T PathSize) +{ + SYSTEM_INFO SystemInfo; + SIZE_T cchInstallerNameLen; + PWSTR ptr; + DWORD dwAttribs; + + cchInstallerNameLen = wcslen(pInstallerName); + if (PathSize < cchInstallerNameLen) + { + /* The buffer is not large enough to contain the installer file name */ + *pInstallerPath = UNICODE_NULL; + return FALSE; + } + + /* + * First, try to find the installer using the default drive, under + * the directory whose name corresponds to the currently-running + * CPU architecture. + */ + GetSystemInfo(&SystemInfo); + + *pInstallerPath = UNICODE_NULL; + /* Alternatively one can use SharedUserData->NtSystemRoot */ + GetSystemWindowsDirectoryW(pInstallerPath, PathSize - cchInstallerNameLen - 1); + ptr = wcschr(pInstallerPath, L'\\'); + if (ptr) + *++ptr = UNICODE_NULL; + else + *pInstallerPath = UNICODE_NULL; + + /* Append the corresponding CPU architecture */ + switch (SystemInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_INTEL: + StringCchCatW(pInstallerPath, PathSize, L"I386"); + break; + + case PROCESSOR_ARCHITECTURE_MIPS: + StringCchCatW(pInstallerPath, PathSize, L"MIPS"); + break; + + case PROCESSOR_ARCHITECTURE_ALPHA: + StringCchCatW(pInstallerPath, PathSize, L"ALPHA"); + break; + + case PROCESSOR_ARCHITECTURE_PPC: + StringCchCatW(pInstallerPath, PathSize, L"PPC"); + break; + + case PROCESSOR_ARCHITECTURE_SHX: + StringCchCatW(pInstallerPath, PathSize, L"SHX"); + break; + + case PROCESSOR_ARCHITECTURE_ARM: + StringCchCatW(pInstallerPath, PathSize, L"ARM"); + break; + + case PROCESSOR_ARCHITECTURE_IA64: + StringCchCatW(pInstallerPath, PathSize, L"IA64"); + break; + + case PROCESSOR_ARCHITECTURE_ALPHA64: + StringCchCatW(pInstallerPath, PathSize, L"ALPHA64"); + break; + + case PROCESSOR_ARCHITECTURE_AMD64: + StringCchCatW(pInstallerPath, PathSize, L"AMD64"); + break; + + // case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */ + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture); + SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; + break; + } + + if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN) + StringCchCatW(pInstallerPath, PathSize, L"\\"); + StringCchCatW(pInstallerPath, PathSize, pInstallerName); + + dwAttribs = GetFileAttributesW(pInstallerPath); + if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && + !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) + { + /* We have found the installer */ + return TRUE; + } + + WARN("Couldn't find the installer '%s', trying alternative.\n", debugstr_w(pInstallerPath)); + + /* + * We failed. Try to find the installer from either the current + * ReactOS installation directory, or from our current directory. + */ + *pInstallerPath = UNICODE_NULL; + /* Alternatively one can use SharedUserData->NtSystemRoot */ + if (GetSystemWindowsDirectoryW(pInstallerPath, PathSize - cchInstallerNameLen - 1)) + StringCchCatW(pInstallerPath, PathSize, L"\\"); + StringCchCatW(pInstallerPath, PathSize, pInstallerName); + + dwAttribs = GetFileAttributesW(pInstallerPath); + if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && + !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) + { + /* We have found the installer */ + return TRUE; + } + + /* Installer not found */ + ERR("Couldn't find the installer '%s'\n", debugstr_w(pInstallerPath)); + *pInstallerPath = UNICODE_NULL; + return FALSE; +} + VOID RunLiveCD( PSTATE pState) @@ -863,13 +981,21 @@ RunLiveCD( LIVECD_UNATTEND Unattend = {0}; WCHAR UnattendInf[MAX_PATH]; - InitLogo(&pState->ImageInfo, NULL); + /* Try to locate the ReactOS Installer */ + if (!ExpandInstallerPath(L"reactos.exe", Installer, _countof(Installer))) + *Installer = UNICODE_NULL; + if (*Installer) + TRACE("ReactOS Installer: '%S'\n", Installer); + else + WARN("Could not find the ReactOS Installer\n"); GetWindowsDirectoryW(UnattendInf, _countof(UnattendInf)); wcscat(UnattendInf, L"\\unattend.inf"); ParseUnattend(UnattendInf, &Unattend); pState->Unattend = &Unattend; + InitLogo(&pState->ImageInfo, NULL); + while (pState->NextPage != DONE) { switch (pState->NextPage) diff --git a/base/system/userinit/userinit.c b/base/system/userinit/userinit.c index 84b59eb18ec..3608db9ca02 100644 --- a/base/system/userinit/userinit.c +++ b/base/system/userinit/userinit.c @@ -86,12 +86,11 @@ IsConsoleShell(VOID) LONG rc; BOOL ret = FALSE; - rc = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - REGSTR_PATH_CURRENT_CONTROL_SET, - 0, - KEY_QUERY_VALUE, - &ControlKey); + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + REGSTR_PATH_CURRENT_CONTROL_SET, + 0, + KEY_QUERY_VALUE, + &ControlKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyEx() failed with error %lu\n", rc); @@ -493,142 +492,15 @@ NotifyLogon(VOID) FreeLibrary(hModule); } -/* - * Expands the path for the ReactOS Installer "reactos.exe". - * See also base/setup/welcome/welcome.c!ExpandInstallerPath() - */ -BOOL -ExpandInstallerPath( - IN LPCWSTR lpInstallerName, - OUT LPWSTR lpInstallerPath, - IN SIZE_T PathSize) -{ - SYSTEM_INFO SystemInfo; - SIZE_T cchInstallerNameLen; - PWSTR ptr; - DWORD dwAttribs; - - cchInstallerNameLen = wcslen(lpInstallerName); - if (PathSize < cchInstallerNameLen) - { - /* The buffer is not large enough to contain the installer file name */ - *lpInstallerPath = UNICODE_NULL; - return FALSE; - } - - /* - * First, try to find the installer using the default drive, under - * the directory whose name corresponds to the currently-running - * CPU architecture. - */ - GetSystemInfo(&SystemInfo); - - *lpInstallerPath = UNICODE_NULL; - /* Alternatively one can use SharedUserData->NtSystemRoot */ - GetSystemWindowsDirectoryW(lpInstallerPath, PathSize - cchInstallerNameLen - 1); - ptr = wcschr(lpInstallerPath, L'\\'); - if (ptr) - *++ptr = UNICODE_NULL; - else - *lpInstallerPath = UNICODE_NULL; - - /* Append the corresponding CPU architecture */ - switch (SystemInfo.wProcessorArchitecture) - { - case PROCESSOR_ARCHITECTURE_INTEL: - StringCchCatW(lpInstallerPath, PathSize, L"I386"); - break; - - case PROCESSOR_ARCHITECTURE_MIPS: - StringCchCatW(lpInstallerPath, PathSize, L"MIPS"); - break; - - case PROCESSOR_ARCHITECTURE_ALPHA: - StringCchCatW(lpInstallerPath, PathSize, L"ALPHA"); - break; - - case PROCESSOR_ARCHITECTURE_PPC: - StringCchCatW(lpInstallerPath, PathSize, L"PPC"); - break; - - case PROCESSOR_ARCHITECTURE_SHX: - StringCchCatW(lpInstallerPath, PathSize, L"SHX"); - break; - - case PROCESSOR_ARCHITECTURE_ARM: - StringCchCatW(lpInstallerPath, PathSize, L"ARM"); - break; - - case PROCESSOR_ARCHITECTURE_IA64: - StringCchCatW(lpInstallerPath, PathSize, L"IA64"); - break; - - case PROCESSOR_ARCHITECTURE_ALPHA64: - StringCchCatW(lpInstallerPath, PathSize, L"ALPHA64"); - break; - - case PROCESSOR_ARCHITECTURE_AMD64: - StringCchCatW(lpInstallerPath, PathSize, L"AMD64"); - break; - - // case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */ - case PROCESSOR_ARCHITECTURE_UNKNOWN: - default: - WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture); - SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; - break; - } - - if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN) - StringCchCatW(lpInstallerPath, PathSize, L"\\"); - StringCchCatW(lpInstallerPath, PathSize, lpInstallerName); - - dwAttribs = GetFileAttributesW(lpInstallerPath); - if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && - !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) - { - /* We have found the installer */ - return TRUE; - } - - WARN("Couldn't find the installer '%s', trying alternative.\n", debugstr_w(lpInstallerPath)); - - /* - * We failed. Try to find the installer from either the current - * ReactOS installation directory, or from our current directory. - */ - *lpInstallerPath = UNICODE_NULL; - /* Alternatively one can use SharedUserData->NtSystemRoot */ - if (GetSystemWindowsDirectoryW(lpInstallerPath, PathSize - cchInstallerNameLen - 1)) - StringCchCatW(lpInstallerPath, PathSize, L"\\"); - StringCchCatW(lpInstallerPath, PathSize, lpInstallerName); - - dwAttribs = GetFileAttributesW(lpInstallerPath); - if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && - !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) - { - /* We have found the installer */ - return TRUE; - } - - /* Installer not found */ - ERR("Couldn't find the installer '%s'\n", debugstr_w(lpInstallerPath)); - *lpInstallerPath = UNICODE_NULL; - return FALSE; -} - static BOOL -StartInstaller(IN LPCWSTR lpInstallerName) +StartInstaller(VOID) { - WCHAR Installer[MAX_PATH]; + extern WCHAR Installer[MAX_PATH]; // In livecd.c WCHAR szMsg[RC_STRING_MAX_SIZE]; - if (ExpandInstallerPath(lpInstallerName, Installer, ARRAYSIZE(Installer))) - { - /* We have found the installer */ - if (StartProcess(Installer, NULL)) - return TRUE; - } + /* If we have found the ReactOS Installer, start it */ + if (*Installer && StartProcess(Installer, NULL)) + return TRUE; /* We failed, display an error message and quit */ ERR("Failed to start the installer '%s'\n", debugstr_w(Installer)); @@ -720,7 +592,7 @@ Restart: } case INSTALLER: - Success = StartInstaller(L"reactos.exe"); + Success = StartInstaller(); break; case REBOOT: diff --git a/base/system/userinit/userinit.h b/base/system/userinit/userinit.h index 5c2dc68d852..a73eea6de5f 100644 --- a/base/system/userinit/userinit.h +++ b/base/system/userinit/userinit.h @@ -64,18 +64,6 @@ typedef struct extern HINSTANCE hInstance; -LONG -ReadRegSzKey( - IN HKEY hKey, - IN LPCWSTR pszKey, - OUT LPWSTR *pValue); - -BOOL -ExpandInstallerPath( - IN LPCWSTR lpInstallerName, - OUT LPWSTR lpInstallerPath, - IN SIZE_T PathSize); - BOOL IsMiniNT(VOID);