2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: System setup
5 * FILE: dll/win32/syssetup/install.c
9 /* INCLUDES *****************************************************************/
24 #include <ndk/cmfuncs.h>
30 CMP_WaitNoPendingInstallEvents(DWORD dwTimeout
);
33 SetupStartService(LPCWSTR lpServiceName
, BOOL bWait
);
35 /* GLOBALS ******************************************************************/
37 HINF hSysSetupInf
= INVALID_HANDLE_VALUE
;
40 /* FUNCTIONS ****************************************************************/
43 FatalError(char *pszFmt
,...)
49 vsprintf(szBuffer
, pszFmt
, ap
);
52 LogItem(NULL
, L
"Failed");
54 strcat(szBuffer
, "\nRebooting now!");
74 HRESULT hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellLink
, (LPVOID
*)&psl
);
78 hr
= IShellLinkW_SetPath(psl
, pszCmd
);
81 hr
= IShellLinkW_SetArguments(psl
, pszArg
);
84 hr
= IShellLinkW_SetWorkingDirectory(psl
, pszDir
);
87 hr
= IShellLinkW_SetIconLocation(psl
, pszIconPath
, iIconNr
);
90 hr
= IShellLinkW_SetDescription(psl
, pszComment
);
92 hr
= IShellLinkW_QueryInterface(psl
, &IID_IPersistFile
, (LPVOID
*)&ppf
);
96 hr
= IPersistFile_Save(ppf
, pszLinkPath
, TRUE
);
97 IPersistFile_Release(ppf
);
100 IShellLinkW_Release(psl
);
112 LPCWSTR pszDescription
,
114 LPCWSTR pszWorkingDir
)
119 WCHAR szPath
[MAX_PATH
];
120 WCHAR szWorkingDirBuf
[MAX_PATH
];
122 /* If no working directory is provided, try to compute a default one */
123 if (pszWorkingDir
== NULL
|| pszWorkingDir
[0] == L
'\0')
125 if (ExpandEnvironmentStringsW(pszCommand
, szPath
, ARRAYSIZE(szPath
)) == 0)
126 wcscpy(szPath
, pszCommand
);
128 dwLen
= GetFullPathNameW(szPath
,
129 ARRAYSIZE(szWorkingDirBuf
),
132 if (dwLen
!= 0 && dwLen
<= ARRAYSIZE(szWorkingDirBuf
))
134 /* Since those should only be called with (.exe) files,
135 lpFilePart has not to be NULL */
136 ASSERT(lpFilePart
!= NULL
);
138 /* We're only interested in the path. Cut the file name off.
139 Also remove the trailing backslash unless the working directory
140 is only going to be a drive, i.e. C:\ */
141 *(lpFilePart
--) = L
'\0';
142 if (!(lpFilePart
- szWorkingDirBuf
== 2 &&
143 szWorkingDirBuf
[1] == L
':' && szWorkingDirBuf
[2] == L
'\\'))
147 pszWorkingDir
= szWorkingDirBuf
;
151 /* If we failed to compute a working directory, just do not use one */
152 if (pszWorkingDir
&& pszWorkingDir
[0] == L
'\0')
153 pszWorkingDir
= NULL
;
155 /* Build the shortcut file name */
156 wcscpy(szPath
, pszFolder
);
157 Ptr
= PathAddBackslash(szPath
);
158 wcscpy(Ptr
, pszName
);
160 /* Create the shortcut */
161 return SUCCEEDED(CreateShellLink(szPath
,
165 /* Special value to indicate no icon */
166 (iIconNr
!= -1 ? pszCommand
: NULL
),
172 static BOOL
CreateShortcutsFromSection(HINF hinf
, LPWSTR pszSection
, LPCWSTR pszFolder
)
177 WCHAR szCommand
[MAX_PATH
];
178 WCHAR szName
[MAX_PATH
];
179 WCHAR szDescription
[MAX_PATH
];
180 WCHAR szDirectory
[MAX_PATH
];
182 if (!SetupFindFirstLine(hinf
, pszSection
, NULL
, &Context
))
187 dwFieldCount
= SetupGetFieldCount(&Context
);
188 if (dwFieldCount
< 3)
191 if (!SetupGetStringFieldW(&Context
, 1, szCommand
, ARRAYSIZE(szCommand
), NULL
))
194 if (!SetupGetStringFieldW(&Context
, 2, szName
, ARRAYSIZE(szName
), NULL
))
197 if (!SetupGetStringFieldW(&Context
, 3, szDescription
, ARRAYSIZE(szDescription
), NULL
))
200 if (dwFieldCount
< 4 || !SetupGetIntField(&Context
, 4, &iIconNr
))
201 iIconNr
= -1; /* Special value to indicate no icon */
203 if (dwFieldCount
< 5 || !SetupGetStringFieldW(&Context
, 5, szDirectory
, ARRAYSIZE(szDirectory
), NULL
))
204 szDirectory
[0] = L
'\0';
206 wcscat(szName
, L
".lnk");
208 CreateShortcut(pszFolder
, szName
, szCommand
, szDescription
, iIconNr
, szDirectory
);
210 } while (SetupFindNextLine(&Context
, &Context
));
215 static BOOL
CreateShortcuts(HINF hinf
, LPCWSTR szSection
)
218 WCHAR szPath
[MAX_PATH
];
219 WCHAR szFolder
[MAX_PATH
];
220 WCHAR szFolderSection
[MAX_PATH
];
225 if (!SetupFindFirstLine(hinf
, szSection
, NULL
, &Context
))
230 if (SetupGetFieldCount(&Context
) < 2)
233 if (!SetupGetStringFieldW(&Context
, 0, szFolderSection
, ARRAYSIZE(szFolderSection
), NULL
))
236 if (!SetupGetIntField(&Context
, 1, &csidl
))
239 if (!SetupGetStringFieldW(&Context
, 2, szFolder
, ARRAYSIZE(szFolder
), NULL
))
242 if (FAILED(SHGetFolderPathAndSubDirW(NULL
, csidl
|CSIDL_FLAG_CREATE
, (HANDLE
)-1, SHGFP_TYPE_DEFAULT
, szFolder
, szPath
)))
245 CreateShortcutsFromSection(hinf
, szFolderSection
, szPath
);
247 } while (SetupFindNextLine(&Context
, &Context
));
258 WCHAR szTempDir
[MAX_PATH
];
259 WCHAR szBuffer
[MAX_PATH
];
263 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
264 L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
267 &hKey
) != ERROR_SUCCESS
)
269 FatalError("Error: %lu\n", GetLastError());
274 dwLength
= sizeof(szBuffer
);
275 if (RegQueryValueExW(hKey
,
280 &dwLength
) != ERROR_SUCCESS
)
282 FatalError("Error: %lu\n", GetLastError());
287 if (!ExpandEnvironmentStringsW(szBuffer
, szTempDir
, ARRAYSIZE(szTempDir
)))
289 FatalError("Error: %lu\n", GetLastError());
293 /* Create profiles directory */
294 if (!CreateDirectoryW(szTempDir
, NULL
))
296 if (GetLastError() != ERROR_ALREADY_EXISTS
)
298 FatalError("Error: %lu\n", GetLastError());
308 InstallSysSetupInfDevices(VOID
)
310 INFCONTEXT InfContext
;
311 WCHAR szLineBuffer
[256];
314 if (!SetupFindFirstLineW(hSysSetupInf
,
315 L
"DeviceInfsToInstall",
324 if (!SetupGetStringFieldW(&InfContext
,
327 ARRAYSIZE(szLineBuffer
),
333 if (!SetupDiInstallClassW(NULL
, szLineBuffer
, DI_QUIETINSTALL
, NULL
))
338 while (SetupFindNextLine(&InfContext
, &InfContext
));
344 InstallSysSetupInfComponents(VOID
)
346 INFCONTEXT InfContext
;
347 WCHAR szNameBuffer
[256];
348 WCHAR szSectionBuffer
[256];
349 HINF hComponentInf
= INVALID_HANDLE_VALUE
;
351 if (!SetupFindFirstLineW(hSysSetupInf
,
356 DPRINT("No Inf.Always section found\n");
362 if (!SetupGetStringFieldW(&InfContext
,
363 1, // Get the component name
365 ARRAYSIZE(szNameBuffer
),
368 FatalError("Error while trying to get component name \n");
372 if (!SetupGetStringFieldW(&InfContext
,
373 2, // Get the component install section
375 ARRAYSIZE(szSectionBuffer
),
378 FatalError("Error while trying to get component install section \n");
382 DPRINT("Trying to execute install section '%S' from '%S' \n", szSectionBuffer
, szNameBuffer
);
384 hComponentInf
= SetupOpenInfFileW(szNameBuffer
,
389 if (hComponentInf
== INVALID_HANDLE_VALUE
)
391 FatalError("SetupOpenInfFileW() failed to open '%S' (Error: %lu)\n", szNameBuffer
, GetLastError());
395 if (!SetupInstallFromInfSectionW(NULL
,
402 SetupDefaultQueueCallbackW
,
407 FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer
, GetLastError());
408 SetupCloseInfFile(hComponentInf
);
412 SetupCloseInfFile(hComponentInf
);
414 while (SetupFindNextLine(&InfContext
, &InfContext
));
423 RegisterTypeLibraries(HINF hinf
, LPCWSTR szSection
)
425 INFCONTEXT InfContext
;
427 WCHAR szName
[MAX_PATH
];
428 WCHAR szPath
[MAX_PATH
];
434 /* Begin iterating the entries in the inf section */
435 res
= SetupFindFirstLine(hinf
, szSection
, NULL
, &InfContext
);
436 if (!res
) return FALSE
;
440 /* Get the name of the current type library */
441 if (!SetupGetStringFieldW(&InfContext
, 1, szName
, ARRAYSIZE(szName
), NULL
))
443 FatalError("SetupGetStringFieldW failed\n");
447 if (!SetupGetIntField(&InfContext
, 2, &csidl
))
448 csidl
= CSIDL_SYSTEM
;
450 hret
= SHGetFolderPathW(NULL
, csidl
, NULL
, 0, szPath
);
453 FatalError("SHGetFolderPathW failed hret=0x%lx\n", hret
);
457 p
= PathAddBackslash(szPath
);
460 hmod
= LoadLibraryW(szName
);
463 FatalError("LoadLibraryW failed\n");
467 __wine_register_resources(hmod
);
469 } while (SetupFindNextLine(&InfContext
, &InfContext
));
475 EnableUserModePnpManager(VOID
)
477 SC_HANDLE hSCManager
= NULL
;
478 SC_HANDLE hService
= NULL
;
481 hSCManager
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
482 if (hSCManager
== NULL
)
484 DPRINT1("Unable to open the service control manager.\n");
485 DPRINT1("Last Error %d\n", GetLastError());
489 hService
= OpenServiceW(hSCManager
,
491 SERVICE_CHANGE_CONFIG
| SERVICE_START
);
492 if (hService
== NULL
)
494 DPRINT1("Unable to open PlugPlay service\n");
498 bRet
= ChangeServiceConfigW(hService
,
503 NULL
, NULL
, NULL
, NULL
);
506 DPRINT1("Unable to change the service configuration\n");
510 bRet
= StartServiceW(hService
, 0, NULL
);
511 if (!bRet
&& (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING
))
513 DPRINT1("Unable to start service\n");
520 if (hService
!= NULL
)
521 CloseServiceHandle(hService
);
522 if (hSCManager
!= NULL
)
523 CloseServiceHandle(hSCManager
);
527 static INT_PTR CALLBACK
528 StatusMessageWindowProc(
534 UNREFERENCED_PARAMETER(wParam
);
542 if (!LoadStringW(hDllInstance
, IDS_STATUS_INSTALL_DEV
, szMsg
, ARRAYSIZE(szMsg
)))
544 SetDlgItemTextW(hwndDlg
, IDC_STATUSLABEL
, szMsg
);
552 ShowStatusMessageThread(
553 IN LPVOID lpParameter
)
557 UNREFERENCED_PARAMETER(lpParameter
);
559 hWnd
= CreateDialogParam(hDllInstance
,
560 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG
),
562 StatusMessageWindowProc
,
567 ShowWindow(hWnd
, SW_SHOW
);
569 hItem
= GetDlgItem(hWnd
, IDC_STATUSPROGRESS
);
572 PostMessage(hItem
, PBM_SETMARQUEE
, TRUE
, 40);
575 /* Message loop for the Status window */
576 while (GetMessage(&Msg
, NULL
, 0, 0))
578 TranslateMessage(&Msg
);
579 DispatchMessage(&Msg
);
599 return ERROR_INVALID_PARAMETER
;
602 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
603 if (rc
!= ERROR_SUCCESS
)
605 if (dwType
!= REG_SZ
)
606 return ERROR_FILE_NOT_FOUND
;
607 pwszValue
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
609 return ERROR_NOT_ENOUGH_MEMORY
;
610 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)pwszValue
, &cbData
);
611 if (rc
!= ERROR_SUCCESS
)
613 HeapFree(GetProcessHeap(), 0, pwszValue
);
616 /* NULL-terminate the string */
617 pwszValue
[cbData
/ sizeof(WCHAR
)] = '\0';
620 return ERROR_SUCCESS
;
626 HKEY hControlKey
= NULL
;
627 LPWSTR pwszSystemStartOptions
= NULL
;
628 LPWSTR pwszCurrentOption
, pwszNextOption
; /* Pointers into SystemStartOptions */
629 BOOL bConsoleBoot
= FALSE
;
632 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
633 L
"SYSTEM\\CurrentControlSet\\Control",
637 if (rc
!= ERROR_SUCCESS
)
640 rc
= ReadRegSzKey(hControlKey
, L
"SystemStartOptions", &pwszSystemStartOptions
);
641 if (rc
!= ERROR_SUCCESS
)
644 /* Check for CONSOLE switch in SystemStartOptions */
645 pwszCurrentOption
= pwszSystemStartOptions
;
646 while (pwszCurrentOption
)
648 pwszNextOption
= wcschr(pwszCurrentOption
, L
' ');
650 *pwszNextOption
= L
'\0';
651 if (wcsicmp(pwszCurrentOption
, L
"CONSOLE") == 0)
653 DPRINT("Found %S. Switching to console boot\n", pwszCurrentOption
);
657 pwszCurrentOption
= pwszNextOption
? pwszNextOption
+ 1 : NULL
;
661 if (hControlKey
!= NULL
)
662 RegCloseKey(hControlKey
);
663 if (pwszSystemStartOptions
)
664 HeapFree(GetProcessHeap(), 0, pwszSystemStartOptions
);
671 HANDLE hThread
= NULL
;
672 BOOL bResult
= FALSE
;
674 hSysSetupInf
= SetupOpenInfFileW(L
"syssetup.inf",
678 if (hSysSetupInf
== INVALID_HANDLE_VALUE
)
680 FatalError("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
684 if (!InstallSysSetupInfDevices())
686 FatalError("InstallSysSetupInfDevices() failed!\n");
690 if(!InstallSysSetupInfComponents())
692 FatalError("InstallSysSetupInfComponents() failed!\n");
696 if (!IsConsoleBoot())
698 hThread
= CreateThread(NULL
,
700 ShowStatusMessageThread
,
706 if (!EnableUserModePnpManager())
708 FatalError("EnableUserModePnpManager() failed!\n");
712 if (CMP_WaitNoPendingInstallEvents(INFINITE
) != WAIT_OBJECT_0
)
714 FatalError("CMP_WaitNoPendingInstallEvents() failed!\n");
722 if (bResult
== FALSE
)
724 SetupCloseInfFile(hSysSetupInf
);
729 PostThreadMessage(GetThreadId(hThread
), WM_QUIT
, 0, 0);
730 WaitForSingleObject(hThread
, INFINITE
);
731 CloseHandle(hThread
);
737 /* Install a section of a .inf file
738 * Returns TRUE if success, FALSE if failure. Error code can
739 * be retrieved with GetLastError()
746 IN LPCWSTR InfSection OPTIONAL
,
747 IN LPCWSTR InfService OPTIONAL
)
749 WCHAR Buffer
[MAX_PATH
];
750 HINF hInf
= INVALID_HANDLE_VALUE
;
752 PVOID Context
= NULL
;
755 /* Get Windows directory */
756 BufferSize
= ARRAYSIZE(Buffer
) - 5 - wcslen(InfFile
);
757 if (GetWindowsDirectoryW(Buffer
, BufferSize
) > BufferSize
)
759 /* Function failed */
760 SetLastError(ERROR_GEN_FAILURE
);
763 /* We have enough space to add some information in the buffer */
764 if (Buffer
[wcslen(Buffer
) - 1] != '\\')
765 wcscat(Buffer
, L
"\\");
766 wcscat(Buffer
, L
"Inf\\");
767 wcscat(Buffer
, InfFile
);
769 /* Install specified section */
770 hInf
= SetupOpenInfFileW(Buffer
, NULL
, INF_STYLE_WIN4
, NULL
);
771 if (hInf
== INVALID_HANDLE_VALUE
)
774 Context
= SetupInitDefaultQueueCallback(hWnd
);
779 if (ret
&& InfSection
)
781 ret
= SetupInstallFromInfSectionW(
783 InfSection
, SPINST_ALL
,
784 NULL
, NULL
, SP_COPY_NEWER
,
785 SetupDefaultQueueCallbackW
, Context
,
788 if (ret
&& InfService
)
790 ret
= SetupInstallServicesFromInfSectionW(hInf
, InfService
, 0);
795 SetupTermDefaultQueueCallback(Context
);
796 if (hInf
!= INVALID_HANDLE_VALUE
)
797 SetupCloseInfFile(hInf
);
805 STARTUPINFOW StartupInfo
;
806 PROCESS_INFORMATION ProcessInformation
;
809 /* Hack: Install TCP/IP protocol driver */
810 bRes
= InstallInfSection(NULL
,
812 L
"MS_TCPIP.PrimaryInstall",
813 L
"MS_TCPIP.PrimaryInstall.Services");
814 if (!bRes
&& GetLastError() != ERROR_FILE_NOT_FOUND
)
816 DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
820 /* Start the TCP/IP protocol driver */
821 SetupStartService(L
"Tcpip", FALSE
);
822 SetupStartService(L
"Dhcp", FALSE
);
825 if (!CommonInstall())
828 /* Register components */
831 if (!SetupInstallFromInfSectionW(NULL
,
832 hSysSetupInf
, L
"RegistrationPhase2",
834 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
))
836 DPRINT1("SetupInstallFromInfSectionW failed!\n");
839 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
841 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
843 DPRINT1("Catching exception\n");
847 SetupCloseInfFile(hSysSetupInf
);
850 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
851 StartupInfo
.cb
= sizeof(StartupInfo
);
852 bRes
= CreateProcessW(L
"userinit.exe",
861 &ProcessInformation
);
865 CloseHandle(ProcessInformation
.hThread
);
866 CloseHandle(ProcessInformation
.hProcess
);
873 L
"Failed to load LiveCD! You can shutdown your computer, or press ENTER to reboot.",
881 SetSetupType(DWORD dwSetupType
)
886 dwError
= RegOpenKeyExW(
892 if (dwError
!= ERROR_SUCCESS
)
895 dwError
= RegSetValueExW(
900 (LPBYTE
)&dwSetupType
,
903 if (dwError
!= ERROR_SUCCESS
)
909 static DWORD CALLBACK
910 HotkeyThread(LPVOID Parameter
)
915 DPRINT("HotkeyThread start\n");
917 hotkey
= GlobalAddAtomW(L
"Setup Shift+F10 Hotkey");
919 if (!RegisterHotKey(NULL
, hotkey
, MOD_SHIFT
, VK_F10
))
920 DPRINT1("RegisterHotKey failed with %lu\n", GetLastError());
922 while (GetMessage(&msg
, NULL
, 0, 0))
924 if (msg
.hwnd
== NULL
&& msg
.message
== WM_HOTKEY
&& msg
.wParam
== hotkey
)
926 STARTUPINFOW si
= { sizeof(si
) };
927 PROCESS_INFORMATION pi
;
929 if (CreateProcessW(L
"cmd.exe",
940 CloseHandle(pi
.hProcess
);
941 CloseHandle(pi
.hThread
);
945 DPRINT1("Failed to launch command prompt: %lu\n", GetLastError());
950 UnregisterHotKey(NULL
, hotkey
);
951 GlobalDeleteAtom(hotkey
);
953 DPRINT("HotkeyThread terminate\n");
960 InitializeProgramFilesDir(VOID
)
965 WCHAR szProgramFilesDirPath
[MAX_PATH
];
966 WCHAR szCommonFilesDirPath
[MAX_PATH
];
967 WCHAR szBuffer
[MAX_PATH
];
969 /* Load 'Program Files' location */
970 if (!LoadStringW(hDllInstance
,
973 ARRAYSIZE(szBuffer
)))
975 DPRINT1("Error: %lu\n", GetLastError());
979 if (!LoadStringW(hDllInstance
,
981 szCommonFilesDirPath
,
982 ARRAYSIZE(szCommonFilesDirPath
)))
984 DPRINT1("Warning: %lu\n", GetLastError());
988 if (!ExpandEnvironmentStringsW(szBuffer
,
989 szProgramFilesDirPath
,
990 ARRAYSIZE(szProgramFilesDirPath
)))
992 DPRINT1("Error: %lu\n", GetLastError());
996 wcscpy(szBuffer
, szProgramFilesDirPath
);
997 wcscat(szBuffer
, L
"\\");
998 wcscat(szBuffer
, szCommonFilesDirPath
);
1000 if (!ExpandEnvironmentStringsW(szBuffer
,
1001 szCommonFilesDirPath
,
1002 ARRAYSIZE(szCommonFilesDirPath
)))
1004 DPRINT1("Warning: %lu\n", GetLastError());
1008 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1009 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
1013 if (Error
!= ERROR_SUCCESS
)
1015 DPRINT1("Error: %lu\n", Error
);
1019 dwLength
= (wcslen(szProgramFilesDirPath
) + 1) * sizeof(WCHAR
);
1020 Error
= RegSetValueExW(hKey
,
1024 (LPBYTE
)szProgramFilesDirPath
,
1026 if (Error
!= ERROR_SUCCESS
)
1028 DPRINT1("Error: %lu\n", Error
);
1033 dwLength
= (wcslen(szCommonFilesDirPath
) + 1) * sizeof(WCHAR
);
1034 Error
= RegSetValueExW(hKey
,
1038 (LPBYTE
)szCommonFilesDirPath
,
1040 if (Error
!= ERROR_SUCCESS
)
1042 DPRINT1("Warning: %lu\n", Error
);
1047 /* Create directory */
1049 if (!CreateDirectoryW(szProgramFilesDirPath
, NULL
))
1051 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1053 DPRINT1("Error: %lu\n", GetLastError());
1058 /* Create directory */
1060 if (!CreateDirectoryW(szCommonFilesDirPath
, NULL
))
1062 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1064 DPRINT1("Warning: %lu\n", GetLastError());
1075 InitializeDefaultUserLocale(VOID
)
1085 struct {LCTYPE LCType
; PWSTR pValue
;} LocaleData
[] = {
1087 {LOCALE_SDECIMAL
, L
"sDecimal"},
1088 {LOCALE_STHOUSAND
, L
"sThousand"},
1089 {LOCALE_SNEGATIVESIGN
, L
"sNegativeSign"},
1090 {LOCALE_SPOSITIVESIGN
, L
"sPositiveSign"},
1091 {LOCALE_SGROUPING
, L
"sGrouping"},
1092 {LOCALE_SLIST
, L
"sList"},
1093 {LOCALE_SNATIVEDIGITS
, L
"sNativeDigits"},
1094 {LOCALE_INEGNUMBER
, L
"iNegNumber"},
1095 {LOCALE_IDIGITS
, L
"iDigits"},
1096 {LOCALE_ILZERO
, L
"iLZero"},
1097 {LOCALE_IMEASURE
, L
"iMeasure"},
1098 {LOCALE_IDIGITSUBSTITUTION
, L
"NumShape"},
1101 {LOCALE_SCURRENCY
, L
"sCurrency"},
1102 {LOCALE_SMONDECIMALSEP
, L
"sMonDecimalSep"},
1103 {LOCALE_SMONTHOUSANDSEP
, L
"sMonThousandSep"},
1104 {LOCALE_SMONGROUPING
, L
"sMonGrouping"},
1105 {LOCALE_ICURRENCY
, L
"iCurrency"},
1106 {LOCALE_INEGCURR
, L
"iNegCurr"},
1107 {LOCALE_ICURRDIGITS
, L
"iCurrDigits"},
1110 {LOCALE_STIMEFORMAT
, L
"sTimeFormat"},
1111 {LOCALE_STIME
, L
"sTime"},
1112 {LOCALE_S1159
, L
"s1159"},
1113 {LOCALE_S2359
, L
"s2359"},
1114 {LOCALE_ITIME
, L
"iTime"},
1115 {LOCALE_ITIMEMARKPOSN
, L
"iTimePrefix"},
1116 {LOCALE_ITLZERO
, L
"iTLZero"},
1119 {LOCALE_SLONGDATE
, L
"sLongDate"},
1120 {LOCALE_SSHORTDATE
, L
"sShortDate"},
1121 {LOCALE_SDATE
, L
"sDate"},
1122 {LOCALE_IFIRSTDAYOFWEEK
, L
"iFirstDayOfWeek"},
1123 {LOCALE_IFIRSTWEEKOFYEAR
, L
"iFirstWeekOfYear"},
1124 {LOCALE_IDATE
, L
"iDate"},
1125 {LOCALE_ICALENDARTYPE
, L
"iCalendarType"},
1128 {LOCALE_SCOUNTRY
, L
"sCountry"},
1129 {LOCALE_SABBREVLANGNAME
, L
"sLanguage"},
1130 {LOCALE_ICOUNTRY
, L
"iCountry"},
1133 ret
= RegOpenKeyExW(HKEY_USERS
,
1134 L
".DEFAULT\\Control Panel\\International",
1136 KEY_READ
| KEY_WRITE
,
1138 if (ret
!= ERROR_SUCCESS
)
1143 dwSize
= 9 * sizeof(WCHAR
);
1144 ret
= RegQueryValueExW(hLocaleKey
,
1150 if (ret
!= ERROR_SUCCESS
)
1153 lcid
= (LCID
)wcstoul(szBuffer
, &ptr
, 16);
1158 while (LocaleData
[i
].pValue
!= NULL
)
1160 if (GetLocaleInfoW(lcid
,
1161 LocaleData
[i
].LCType
| LOCALE_NOUSEROVERRIDE
,
1163 ARRAYSIZE(szBuffer
)))
1165 RegSetValueExW(hLocaleKey
,
1166 LocaleData
[i
].pValue
,
1170 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1177 RegCloseKey(hLocaleKey
);
1183 SaveDefaultUserHive(VOID
)
1185 WCHAR szDefaultUserHive
[MAX_PATH
];
1186 HKEY hUserKey
= NULL
;
1190 DPRINT("SaveDefaultUserHive()\n");
1192 cchSize
= ARRAYSIZE(szDefaultUserHive
);
1193 GetDefaultUserProfileDirectoryW(szDefaultUserHive
, &cchSize
);
1195 wcscat(szDefaultUserHive
, L
"\\ntuser.dat");
1197 dwError
= RegOpenKeyExW(HKEY_USERS
,
1202 if (dwError
!= ERROR_SUCCESS
)
1204 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError
);
1208 pSetupEnablePrivilege(L
"SeBackupPrivilege", TRUE
);
1210 /* Save the Default hive */
1211 dwError
= RegSaveKeyExW(hUserKey
,
1214 REG_STANDARD_FORMAT
);
1215 if (dwError
== ERROR_ALREADY_EXISTS
)
1217 WCHAR szBackupHive
[MAX_PATH
];
1219 /* Build the backup hive file name by replacing the extension */
1220 wcscpy(szBackupHive
, szDefaultUserHive
);
1221 wcscpy(&szBackupHive
[wcslen(szBackupHive
) - 4], L
".bak");
1223 /* Back up the existing default user hive by renaming it, replacing any possible existing old backup */
1224 if (!MoveFileExW(szDefaultUserHive
,
1226 MOVEFILE_REPLACE_EXISTING
))
1228 dwError
= GetLastError();
1229 DPRINT1("Failed to create a default-user hive backup '%S', MoveFileExW failed (Error %lu)\n",
1230 szBackupHive
, dwError
);
1234 /* The backup has been done, retry saving the Default hive */
1235 dwError
= RegSaveKeyExW(hUserKey
,
1238 REG_STANDARD_FORMAT
);
1241 if (dwError
!= ERROR_SUCCESS
)
1243 DPRINT1("RegSaveKeyExW() failed (Error %lu)\n", dwError
);
1246 pSetupEnablePrivilege(L
"SeBackupPrivilege", FALSE
);
1248 RegCloseKey(hUserKey
);
1256 InstallReactOS(VOID
)
1258 WCHAR szBuffer
[MAX_PATH
];
1260 TOKEN_PRIVILEGES privs
;
1263 HANDLE hHotkeyThread
;
1266 InitializeSetupActionLog(FALSE
);
1267 LogItem(NULL
, L
"Installing ReactOS");
1269 CreateTempDir(L
"TEMP");
1270 CreateTempDir(L
"TMP");
1272 if (!InitializeProgramFilesDir())
1274 FatalError("InitializeProgramFilesDir() failed");
1278 if (!InitializeProfiles())
1280 FatalError("InitializeProfiles() failed");
1284 InitializeDefaultUserLocale();
1286 if (GetWindowsDirectoryW(szBuffer
, ARRAYSIZE(szBuffer
)))
1288 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1289 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
1292 &hKey
) == ERROR_SUCCESS
)
1294 RegSetValueExW(hKey
,
1299 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1301 RegSetValueExW(hKey
,
1306 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1311 PathAddBackslash(szBuffer
);
1312 wcscat(szBuffer
, L
"system");
1313 CreateDirectory(szBuffer
, NULL
);
1316 if (SaveDefaultUserHive() != ERROR_SUCCESS
)
1318 FatalError("SaveDefaultUserHive() failed");
1322 if (!CopySystemProfile(0))
1324 FatalError("CopySystemProfile() failed");
1328 hHotkeyThread
= CreateThread(NULL
, 0, HotkeyThread
, NULL
, 0, NULL
);
1330 /* Hack: Install TCP/IP protocol driver */
1331 ret
= InstallInfSection(NULL
,
1333 L
"MS_TCPIP.PrimaryInstall",
1334 L
"MS_TCPIP.PrimaryInstall.Services");
1335 if (!ret
&& GetLastError() != ERROR_FILE_NOT_FOUND
)
1337 DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
1341 /* Start the TCP/IP protocol driver */
1342 SetupStartService(L
"Tcpip", FALSE
);
1343 SetupStartService(L
"Dhcp", FALSE
);
1347 if (!CommonInstall())
1354 SetAutoAdminLogon();
1356 hShortcutsInf
= SetupOpenInfFileW(L
"shortcuts.inf",
1360 if (hShortcutsInf
== INVALID_HANDLE_VALUE
)
1362 FatalError("Failed to open shortcuts.inf");
1366 if (!CreateShortcuts(hShortcutsInf
, L
"ShortcutFolders"))
1368 FatalError("CreateShortcuts() failed");
1372 SetupCloseInfFile(hShortcutsInf
);
1374 hShortcutsInf
= SetupOpenInfFileW(L
"rosapps_shortcuts.inf",
1378 if (hShortcutsInf
!= INVALID_HANDLE_VALUE
)
1380 if (!CreateShortcuts(hShortcutsInf
, L
"ShortcutFolders"))
1382 FatalError("CreateShortcuts(rosapps) failed");
1385 SetupCloseInfFile(hShortcutsInf
);
1388 SetupCloseInfFile(hSysSetupInf
);
1393 PostThreadMessage(GetThreadId(hHotkeyThread
), WM_QUIT
, 0, 0);
1394 CloseHandle(hHotkeyThread
);
1397 LogItem(NULL
, L
"Installing ReactOS done");
1398 TerminateSetupActionLog();
1400 if (AdminInfo
.Name
!= NULL
)
1401 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Name
);
1403 if (AdminInfo
.Domain
!= NULL
)
1404 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Domain
);
1406 if (AdminInfo
.Password
!= NULL
)
1407 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Password
);
1409 /* Get shutdown privilege */
1410 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &token
))
1412 FatalError("OpenProcessToken() failed!");
1415 if (!LookupPrivilegeValue(NULL
,
1417 &privs
.Privileges
[0].Luid
))
1419 FatalError("LookupPrivilegeValue() failed!");
1422 privs
.PrivilegeCount
= 1;
1423 privs
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
1424 if (AdjustTokenPrivileges(token
,
1428 (PTOKEN_PRIVILEGES
)NULL
,
1431 FatalError("AdjustTokenPrivileges() failed!");
1435 ExitWindowsEx(EWX_REBOOT
, 0);
1441 * Standard Windows-compatible export, which dispatches
1442 * to either 'InstallReactOS' or 'InstallLiveCD'.
1446 InstallWindowsNt(INT argc
, WCHAR
** argv
)
1451 for (i
= 0; i
< argc
; ++i
)
1458 // NOTE: On Windows, "mini" means "minimal UI", and can be used
1459 // in addition to "newsetup"; these options are not exclusive.
1460 if (_wcsicmp(p
, L
"newsetup") == 0)
1461 return (INT
)InstallReactOS();
1462 else if (_wcsicmp(p
, L
"mini") == 0)
1463 return (INT
)InstallLiveCD();
1465 /* Add support for other switches */
1477 SetupChangeFontSize(
1479 IN LPCWSTR lpszFontSize
)
1481 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1489 SetupChangeLocaleEx(HWND hWnd
,
1491 LPCWSTR lpSrcRootPath
,
1496 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1504 SetupChangeLocale(HWND hWnd
, LCID Lcid
)
1506 return SetupChangeLocaleEx(hWnd
, Lcid
, NULL
, 0, 0, 0);
1513 LPCWSTR lpServiceName
,
1516 SC_HANDLE hManager
= NULL
;
1517 SC_HANDLE hService
= NULL
;
1518 DWORD dwError
= ERROR_SUCCESS
;
1520 hManager
= OpenSCManagerW(NULL
,
1522 SC_MANAGER_ALL_ACCESS
);
1523 if (hManager
== NULL
)
1525 dwError
= GetLastError();
1529 hService
= OpenServiceW(hManager
,
1532 if (hService
== NULL
)
1534 dwError
= GetLastError();
1538 if (!StartService(hService
, 0, NULL
))
1540 dwError
= GetLastError();
1545 if (hService
!= NULL
)
1546 CloseServiceHandle(hService
);
1548 if (hManager
!= NULL
)
1549 CloseServiceHandle(hManager
);