diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c index 4e2b3fb4c39..e5ef76bbd44 100644 --- a/base/setup/lib/setuplib.c +++ b/base/setup/lib/setuplib.c @@ -235,6 +235,7 @@ InstallSetupInfFile( if (!IniCache) return; +#if 0 /* If you need to put something in this section, do it after the merge with Unattend.inf */ IniSection = IniAddSection(IniCache, L"SetupParams"); if (IniSection) { @@ -243,6 +244,7 @@ InstallSetupInfFile( // L"\"%s\"", L"WinNt5.2"); // IniAddKey(IniSection, L"Version", PathBuffer); } +#endif IniSection = IniAddSection(IniCache, L"Data"); if (IniSection) diff --git a/boot/bootdata/bootcd/unattend.inf b/boot/bootdata/bootcd/unattend.inf index 1ff70f9ddd5..c086ddfcf4e 100644 --- a/boot/bootdata/bootcd/unattend.inf +++ b/boot/bootdata/bootcd/unattend.inf @@ -59,6 +59,15 @@ LocaleID = 409 ; 3 - ReactOS Nano Server (Reserved) InstallationType = 0 +;[GuiUnattended] +; Run a program early in 2nd-stage setup. +;DetachedProgram=%SystemRoot%\system32\cmd.exe +;Arguments="/C echo.Early 2nd-stage setup...&choice>nul /N /T:Y,5" + +;[SetupParams] +; Run a program at the end of 2nd-stage setup. +;UserExecute="cmd.exe /C echo.End of 2nd-stage setup...&choice>nul /N /T:Y,5" + ; Enable this section to automatically launch programs after 3rd boot. ;[GuiRunOnce] ;%SystemRoot%\system32\cmd.exe diff --git a/dll/win32/syssetup/globals.h b/dll/win32/syssetup/globals.h index c6c357222f8..f5bfa683ec3 100644 --- a/dll/win32/syssetup/globals.h +++ b/dll/win32/syssetup/globals.h @@ -73,6 +73,10 @@ HRESULT InstallOptionalComponents( _In_ PITEMSDATA pItemsData); +HRESULT +RunCommandAndWait( + _In_ PWCHAR Command); + /* install */ BOOL @@ -109,6 +113,10 @@ VOID SetAutoAdminLogon(VOID); /* wizard.c */ -VOID InstallWizard (VOID); +VOID +InstallWizard(VOID); + +VOID +GetSetupInfPath(PWSTR szPath, UINT cchMax); /* EOF */ diff --git a/dll/win32/syssetup/install.c b/dll/win32/syssetup/install.c index 84906c6a8d6..9767fb3e68b 100644 --- a/dll/win32/syssetup/install.c +++ b/dll/win32/syssetup/install.c @@ -4,6 +4,7 @@ * PURPOSE: System setup * FILE: dll/win32/syssetup/install.c * PROGRAMER: Eric Kohl + * Whindmar Saksit */ /* INCLUDES *****************************************************************/ @@ -985,6 +986,26 @@ cleanup: return bConsoleBoot; } +static VOID +ProcessDetachedProgram( + _In_ PCWSTR pszInf) +{ + WCHAR szInfApp[MAX_PATH], szInfArg[MAX_PATH * 3]; + WCHAR szCmd[_countof(szInfApp) + _countof(szInfArg)]; + UINT cch; + + if (!GetPrivateProfileStringW(L"GuiUnattended", L"DetachedProgram", L"", szInfApp, _countof(szInfApp), pszInf) || !*szInfApp) + return; + cch = ExpandEnvironmentStrings(szInfApp, szCmd, _countof(szCmd) - 1); + if (GetPrivateProfileStringW(L"GuiUnattended", L"Arguments", L"", szInfArg, _countof(szInfArg), pszInf) && cch) + { + szCmd[cch - 1] = L' '; + szCmd[cch] = UNICODE_NULL; + ExpandEnvironmentStrings(szInfArg, szCmd + cch, _countof(szCmd) - cch); + } + RunCommandAndWait(szCmd); +} + extern VOID EnableVisualTheme( _In_opt_ HWND hwndParent, @@ -1010,8 +1031,7 @@ PreprocessUnattend( { /* See also wizard.c!ProcessSetupInf() * Retrieve the path of the setup INF */ - GetSystemDirectoryW(szPath, _countof(szPath)); - wcscat(szPath, L"\\$winnt$.inf"); + GetSetupInfPath(szPath, _countof(szPath)); } else { @@ -1038,6 +1058,9 @@ PreprocessUnattend( /* Enable the chosen theme, or use the classic theme */ EnableVisualTheme(NULL, bDefaultThemesOff ? NULL : szValue); + + if (IsInstall) + ProcessDetachedProgram(szPath); } static BOOL diff --git a/dll/win32/syssetup/wizard.c b/dll/win32/syssetup/wizard.c index d9d01da88a1..b0f4b646c6b 100644 --- a/dll/win32/syssetup/wizard.c +++ b/dll/win32/syssetup/wizard.c @@ -53,6 +53,13 @@ typedef struct _TIMEZONE_ENTRY extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow); +VOID +GetSetupInfPath(PWSTR szPath, UINT cchMax) +{ + GetSystemDirectoryW(szPath, cchMax); + wcscat(szPath, L"\\$winnt$.inf"); +} + static VOID CenterWindow(HWND hWnd) { @@ -2740,31 +2747,38 @@ ProcessPageDlgProc(HWND hwndDlg, static VOID -SetInstallationCompleted(VOID) +SetInstallationCompleted(IN BOOL Unattended) { HKEY hKey = 0; DWORD InProgress = 0; DWORD InstallDate; - if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, - L"SYSTEM\\Setup", - 0, - KEY_WRITE, - &hKey ) == ERROR_SUCCESS) - { - RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) ); - RegCloseKey( hKey ); - } - - if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, - L"Software\\Microsoft\\Windows NT\\CurrentVersion", - 0, - KEY_WRITE, - &hKey ) == ERROR_SUCCESS) + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", + 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) { InstallDate = (DWORD)time(NULL); - RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) ); - RegCloseKey( hKey ); + RegSetValueExW(hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate)); + RegCloseKey(hKey); + } + + if (Unattended) + { + WCHAR szInf[MAX_PATH]; + WCHAR szInfCmd[MAX_PATH * 4], szCmd[_countof(szInfCmd)]; + + GetSetupInfPath(szInf, _countof(szInf)); + if (GetPrivateProfileStringW(L"SetupParams", L"UserExecute", L"", szInfCmd, _countof(szInfCmd), szInf) && *szInfCmd) + { + *szCmd = UNICODE_NULL; + ExpandEnvironmentStringsW(szInfCmd, szCmd, _countof(szInfCmd)); + RunCommandAndWait(szCmd); + } + } + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) + { + RegSetValueExW(hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress)); + RegCloseKey(hKey); } } @@ -2790,7 +2804,7 @@ FinishDlgProc(HWND hwndDlg, if (SetupData->UnattendSetup) { KillTimer(hwndDlg, 1); - SetInstallationCompleted(); + SetInstallationCompleted(TRUE); PostQuitMessage(0); } @@ -2802,7 +2816,7 @@ FinishDlgProc(HWND hwndDlg, case WM_DESTROY: { - SetInstallationCompleted(); + SetInstallationCompleted(FALSE); PostQuitMessage(0); return TRUE; } @@ -3335,8 +3349,7 @@ ProcessSetupInf( pSetupData->hSetupInf = INVALID_HANDLE_VALUE; /* Retrieve the path of the setup INF */ - GetSystemDirectoryW(szPath, _countof(szPath)); - wcscat(szPath, L"\\$winnt$.inf"); + GetSetupInfPath(szPath, _countof(szPath)); /* Open the setup INF */ pSetupData->hSetupInf = SetupOpenInfFileW(szPath,