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 typedef struct _DLG_DATA
48 } DLG_DATA
, *PDLG_DATA
;
50 /* FUNCTIONS ****************************************************************/
53 FatalError(char *pszFmt
,...)
59 vsprintf(szBuffer
, pszFmt
, ap
);
62 LogItem(NULL
, L
"Failed");
64 strcat(szBuffer
, "\nRebooting now!");
84 HRESULT hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellLink
, (LPVOID
*)&psl
);
88 hr
= IShellLinkW_SetPath(psl
, pszCmd
);
91 hr
= IShellLinkW_SetArguments(psl
, pszArg
);
94 hr
= IShellLinkW_SetWorkingDirectory(psl
, pszDir
);
97 hr
= IShellLinkW_SetIconLocation(psl
, pszIconPath
, iIconNr
);
100 hr
= IShellLinkW_SetDescription(psl
, pszComment
);
102 hr
= IShellLinkW_QueryInterface(psl
, &IID_IPersistFile
, (LPVOID
*)&ppf
);
106 hr
= IPersistFile_Save(ppf
, pszLinkPath
, TRUE
);
107 IPersistFile_Release(ppf
);
110 IShellLinkW_Release(psl
);
122 LPCWSTR pszDescription
,
124 LPCWSTR pszWorkingDir
)
129 WCHAR szPath
[MAX_PATH
];
130 WCHAR szWorkingDirBuf
[MAX_PATH
];
132 /* If no working directory is provided, try to compute a default one */
133 if (pszWorkingDir
== NULL
|| pszWorkingDir
[0] == L
'\0')
135 if (ExpandEnvironmentStringsW(pszCommand
, szPath
, ARRAYSIZE(szPath
)) == 0)
136 wcscpy(szPath
, pszCommand
);
138 dwLen
= GetFullPathNameW(szPath
,
139 ARRAYSIZE(szWorkingDirBuf
),
142 if (dwLen
!= 0 && dwLen
<= ARRAYSIZE(szWorkingDirBuf
))
144 /* Since those should only be called with (.exe) files,
145 lpFilePart has not to be NULL */
146 ASSERT(lpFilePart
!= NULL
);
148 /* We're only interested in the path. Cut the file name off.
149 Also remove the trailing backslash unless the working directory
150 is only going to be a drive, i.e. C:\ */
151 *(lpFilePart
--) = L
'\0';
152 if (!(lpFilePart
- szWorkingDirBuf
== 2 &&
153 szWorkingDirBuf
[1] == L
':' && szWorkingDirBuf
[2] == L
'\\'))
157 pszWorkingDir
= szWorkingDirBuf
;
161 /* If we failed to compute a working directory, just do not use one */
162 if (pszWorkingDir
&& pszWorkingDir
[0] == L
'\0')
163 pszWorkingDir
= NULL
;
165 /* Build the shortcut file name */
166 wcscpy(szPath
, pszFolder
);
167 Ptr
= PathAddBackslash(szPath
);
168 wcscpy(Ptr
, pszName
);
170 /* Create the shortcut */
171 return SUCCEEDED(CreateShellLink(szPath
,
175 /* Special value to indicate no icon */
176 (iIconNr
!= -1 ? pszCommand
: NULL
),
182 static BOOL
CreateShortcutsFromSection(HINF hinf
, LPWSTR pszSection
, LPCWSTR pszFolder
)
187 WCHAR szCommand
[MAX_PATH
];
188 WCHAR szName
[MAX_PATH
];
189 WCHAR szDescription
[MAX_PATH
];
190 WCHAR szDirectory
[MAX_PATH
];
192 if (!SetupFindFirstLine(hinf
, pszSection
, NULL
, &Context
))
197 dwFieldCount
= SetupGetFieldCount(&Context
);
198 if (dwFieldCount
< 3)
201 if (!SetupGetStringFieldW(&Context
, 1, szCommand
, ARRAYSIZE(szCommand
), NULL
))
204 if (!SetupGetStringFieldW(&Context
, 2, szName
, ARRAYSIZE(szName
), NULL
))
207 if (!SetupGetStringFieldW(&Context
, 3, szDescription
, ARRAYSIZE(szDescription
), NULL
))
210 if (dwFieldCount
< 4 || !SetupGetIntField(&Context
, 4, &iIconNr
))
211 iIconNr
= -1; /* Special value to indicate no icon */
213 if (dwFieldCount
< 5 || !SetupGetStringFieldW(&Context
, 5, szDirectory
, ARRAYSIZE(szDirectory
), NULL
))
214 szDirectory
[0] = L
'\0';
216 wcscat(szName
, L
".lnk");
218 CreateShortcut(pszFolder
, szName
, szCommand
, szDescription
, iIconNr
, szDirectory
);
220 } while (SetupFindNextLine(&Context
, &Context
));
225 static BOOL
CreateShortcuts(HINF hinf
, LPCWSTR szSection
)
228 WCHAR szPath
[MAX_PATH
];
229 WCHAR szFolder
[MAX_PATH
];
230 WCHAR szFolderSection
[MAX_PATH
];
235 if (!SetupFindFirstLine(hinf
, szSection
, NULL
, &Context
))
240 if (SetupGetFieldCount(&Context
) < 2)
243 if (!SetupGetStringFieldW(&Context
, 0, szFolderSection
, ARRAYSIZE(szFolderSection
), NULL
))
246 if (!SetupGetIntField(&Context
, 1, &csidl
))
249 if (!SetupGetStringFieldW(&Context
, 2, szFolder
, ARRAYSIZE(szFolder
), NULL
))
252 if (FAILED(SHGetFolderPathAndSubDirW(NULL
, csidl
|CSIDL_FLAG_CREATE
, (HANDLE
)-1, SHGFP_TYPE_DEFAULT
, szFolder
, szPath
)))
255 CreateShortcutsFromSection(hinf
, szFolderSection
, szPath
);
257 } while (SetupFindNextLine(&Context
, &Context
));
268 WCHAR szTempDir
[MAX_PATH
];
269 WCHAR szBuffer
[MAX_PATH
];
273 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
274 L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
277 &hKey
) != ERROR_SUCCESS
)
279 FatalError("Error: %lu\n", GetLastError());
284 dwLength
= sizeof(szBuffer
);
285 if (RegQueryValueExW(hKey
,
290 &dwLength
) != ERROR_SUCCESS
)
292 FatalError("Error: %lu\n", GetLastError());
297 if (!ExpandEnvironmentStringsW(szBuffer
, szTempDir
, ARRAYSIZE(szTempDir
)))
299 FatalError("Error: %lu\n", GetLastError());
303 /* Create profiles directory */
304 if (!CreateDirectoryW(szTempDir
, NULL
))
306 if (GetLastError() != ERROR_ALREADY_EXISTS
)
308 FatalError("Error: %lu\n", GetLastError());
318 InstallSysSetupInfDevices(VOID
)
320 INFCONTEXT InfContext
;
321 WCHAR szLineBuffer
[256];
324 if (!SetupFindFirstLineW(hSysSetupInf
,
325 L
"DeviceInfsToInstall",
334 if (!SetupGetStringFieldW(&InfContext
,
337 ARRAYSIZE(szLineBuffer
),
343 if (!SetupDiInstallClassW(NULL
, szLineBuffer
, DI_QUIETINSTALL
, NULL
))
348 while (SetupFindNextLine(&InfContext
, &InfContext
));
354 InstallSysSetupInfComponents(VOID
)
356 INFCONTEXT InfContext
;
357 WCHAR szNameBuffer
[256];
358 WCHAR szSectionBuffer
[256];
359 HINF hComponentInf
= INVALID_HANDLE_VALUE
;
361 if (!SetupFindFirstLineW(hSysSetupInf
,
366 DPRINT("No Inf.Always section found\n");
372 if (!SetupGetStringFieldW(&InfContext
,
373 1, // Get the component name
375 ARRAYSIZE(szNameBuffer
),
378 FatalError("Error while trying to get component name\n");
382 if (!SetupGetStringFieldW(&InfContext
,
383 2, // Get the component install section
385 ARRAYSIZE(szSectionBuffer
),
388 FatalError("Error while trying to get component install section\n");
392 DPRINT("Trying to execute install section '%S' from '%S'\n", szSectionBuffer
, szNameBuffer
);
394 hComponentInf
= SetupOpenInfFileW(szNameBuffer
,
399 if (hComponentInf
== INVALID_HANDLE_VALUE
)
401 FatalError("SetupOpenInfFileW() failed to open '%S' (Error: %lu)\n", szNameBuffer
, GetLastError());
405 if (!SetupInstallFromInfSectionW(NULL
,
412 SetupDefaultQueueCallbackW
,
417 FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer
, GetLastError());
418 SetupCloseInfFile(hComponentInf
);
422 SetupCloseInfFile(hComponentInf
);
424 while (SetupFindNextLine(&InfContext
, &InfContext
));
433 RegisterTypeLibraries(HINF hinf
, LPCWSTR szSection
)
435 INFCONTEXT InfContext
;
437 WCHAR szName
[MAX_PATH
];
438 WCHAR szPath
[MAX_PATH
];
444 /* Begin iterating the entries in the inf section */
445 res
= SetupFindFirstLine(hinf
, szSection
, NULL
, &InfContext
);
446 if (!res
) return FALSE
;
450 /* Get the name of the current type library */
451 if (!SetupGetStringFieldW(&InfContext
, 1, szName
, ARRAYSIZE(szName
), NULL
))
453 FatalError("SetupGetStringFieldW failed\n");
457 if (!SetupGetIntField(&InfContext
, 2, &csidl
))
458 csidl
= CSIDL_SYSTEM
;
460 hret
= SHGetFolderPathW(NULL
, csidl
, NULL
, 0, szPath
);
463 FatalError("SHGetFolderPathW failed hret=0x%lx\n", hret
);
467 p
= PathAddBackslash(szPath
);
470 hmod
= LoadLibraryW(szPath
);
473 FatalError("LoadLibraryW failed\n");
477 __wine_register_resources(hmod
);
479 } while (SetupFindNextLine(&InfContext
, &InfContext
));
485 EnableUserModePnpManager(VOID
)
487 SC_HANDLE hSCManager
= NULL
;
488 SC_HANDLE hService
= NULL
;
489 SERVICE_STATUS_PROCESS ServiceStatus
;
491 DWORD BytesNeeded
, WaitTime
;
493 hSCManager
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
494 if (hSCManager
== NULL
)
496 DPRINT1("Unable to open the service control manager.\n");
497 DPRINT1("Last Error %d\n", GetLastError());
501 hService
= OpenServiceW(hSCManager
,
503 SERVICE_CHANGE_CONFIG
| SERVICE_START
| SERVICE_QUERY_STATUS
);
504 if (hService
== NULL
)
506 DPRINT1("Unable to open PlugPlay service\n");
510 bRet
= ChangeServiceConfigW(hService
,
515 NULL
, NULL
, NULL
, NULL
);
518 DPRINT1("Unable to change the service configuration\n");
522 bRet
= StartServiceW(hService
, 0, NULL
);
523 if (!bRet
&& (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING
))
525 DPRINT1("Unable to start service\n");
531 bRet
= QueryServiceStatusEx(hService
,
532 SC_STATUS_PROCESS_INFO
,
533 (LPBYTE
)&ServiceStatus
,
534 sizeof(ServiceStatus
),
538 DPRINT1("QueryServiceStatusEx() failed for PlugPlay service (error 0x%x)\n", GetLastError());
542 if (ServiceStatus
.dwCurrentState
!= SERVICE_START_PENDING
)
545 WaitTime
= ServiceStatus
.dwWaitHint
/ 10;
546 if (WaitTime
< 1000) WaitTime
= 1000;
547 else if (WaitTime
> 10000) WaitTime
= 10000;
551 if (ServiceStatus
.dwCurrentState
!= SERVICE_RUNNING
)
554 DPRINT1("Failed to start PlugPlay service\n");
561 if (hService
!= NULL
)
562 CloseServiceHandle(hService
);
563 if (hSCManager
!= NULL
)
564 CloseServiceHandle(hSCManager
);
568 static INT_PTR CALLBACK
569 StatusMessageWindowProc(
576 UNREFERENCED_PARAMETER(wParam
);
578 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
580 /* pDlgData is required for each case except WM_INITDIALOG */
581 if (uMsg
!= WM_INITDIALOG
&& pDlgData
== NULL
) return FALSE
;
590 /* Allocate pDlgData */
591 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*pDlgData
));
594 /* Set pDlgData to GWLP_USERDATA, so we can get it for new messages */
595 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
598 pDlgData
->hLogoBitmap
= LoadImageW(hDllInstance
,
599 MAKEINTRESOURCEW(IDB_REACTOS
), IMAGE_BITMAP
,
600 0, 0, LR_DEFAULTCOLOR
);
602 pDlgData
->hBarBitmap
= LoadImageW(hDllInstance
, MAKEINTRESOURCEW(IDB_LINE
),
603 IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
604 GetObject(pDlgData
->hBarBitmap
, sizeof(bm
), &bm
);
605 pDlgData
->BarWidth
= bm
.bmWidth
;
606 pDlgData
->BarHeight
= bm
.bmHeight
;
608 if (pDlgData
->hLogoBitmap
&& pDlgData
->hBarBitmap
)
610 if (SetTimer(hwndDlg
, IDT_BAR
, 20, NULL
) == 0)
612 DPRINT1("SetTimer(IDT_BAR) failed: %lu\n", GetLastError());
615 /* Get the animation bar control */
616 pDlgData
->hWndBarCtrl
= GetDlgItem(hwndDlg
, IDC_BAR
);
620 /* Get and set status text */
621 if (!LoadStringW(hDllInstance
, IDS_STATUS_INSTALL_DEV
, szMsg
, ARRAYSIZE(szMsg
)))
623 SetDlgItemTextW(hwndDlg
, IDC_STATUSLABEL
, szMsg
);
630 if (pDlgData
->hBarBitmap
)
633 * Default rotation bar image width is 413 (same as logo)
634 * We can divide 413 by 7 without remainder
636 pDlgData
->BarCounter
= (pDlgData
->BarCounter
+ 7) % pDlgData
->BarWidth
;
637 InvalidateRect(pDlgData
->hWndBarCtrl
, NULL
, FALSE
);
638 UpdateWindow(pDlgData
->hWndBarCtrl
);
645 LPDRAWITEMSTRUCT lpDis
= (LPDRAWITEMSTRUCT
)lParam
;
647 if (lpDis
->CtlID
!= IDC_BAR
)
652 if (pDlgData
->hBarBitmap
)
656 DWORD off
= pDlgData
->BarCounter
;
657 DWORD iw
= pDlgData
->BarWidth
;
658 DWORD ih
= pDlgData
->BarHeight
;
660 hdcMem
= CreateCompatibleDC(lpDis
->hDC
);
661 hOld
= SelectObject(hdcMem
, pDlgData
->hBarBitmap
);
662 BitBlt(lpDis
->hDC
, off
, 0, iw
- off
, ih
, hdcMem
, 0, 0, SRCCOPY
);
663 BitBlt(lpDis
->hDC
, 0, 0, off
, ih
, hdcMem
, iw
- off
, 0, SRCCOPY
);
664 SelectObject(hdcMem
, hOld
);
673 if (pDlgData
->hBarBitmap
)
675 KillTimer(hwndDlg
, IDT_BAR
);
678 DeleteObject(pDlgData
->hLogoBitmap
);
679 DeleteObject(pDlgData
->hBarBitmap
);
680 HeapFree(GetProcessHeap(), 0, pDlgData
);
688 ShowStatusMessageThread(
689 IN LPVOID lpParameter
)
693 UNREFERENCED_PARAMETER(lpParameter
);
695 hWnd
= CreateDialogParam(hDllInstance
,
696 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG
),
698 StatusMessageWindowProc
,
703 ShowWindow(hWnd
, SW_SHOW
);
705 /* Message loop for the Status window */
706 while (GetMessage(&Msg
, NULL
, 0, 0))
708 TranslateMessage(&Msg
);
709 DispatchMessage(&Msg
);
729 return ERROR_INVALID_PARAMETER
;
732 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
733 if (rc
!= ERROR_SUCCESS
)
735 if (dwType
!= REG_SZ
)
736 return ERROR_FILE_NOT_FOUND
;
737 pwszValue
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
739 return ERROR_NOT_ENOUGH_MEMORY
;
740 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)pwszValue
, &cbData
);
741 if (rc
!= ERROR_SUCCESS
)
743 HeapFree(GetProcessHeap(), 0, pwszValue
);
746 /* NULL-terminate the string */
747 pwszValue
[cbData
/ sizeof(WCHAR
)] = '\0';
750 return ERROR_SUCCESS
;
756 HKEY hControlKey
= NULL
;
757 LPWSTR pwszSystemStartOptions
= NULL
;
758 LPWSTR pwszCurrentOption
, pwszNextOption
; /* Pointers into SystemStartOptions */
759 BOOL bConsoleBoot
= FALSE
;
762 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
763 L
"SYSTEM\\CurrentControlSet\\Control",
767 if (rc
!= ERROR_SUCCESS
)
770 rc
= ReadRegSzKey(hControlKey
, L
"SystemStartOptions", &pwszSystemStartOptions
);
771 if (rc
!= ERROR_SUCCESS
)
774 /* Check for CONSOLE switch in SystemStartOptions */
775 pwszCurrentOption
= pwszSystemStartOptions
;
776 while (pwszCurrentOption
)
778 pwszNextOption
= wcschr(pwszCurrentOption
, L
' ');
780 *pwszNextOption
= L
'\0';
781 if (wcsicmp(pwszCurrentOption
, L
"CONSOLE") == 0)
783 DPRINT("Found %S. Switching to console boot\n", pwszCurrentOption
);
787 pwszCurrentOption
= pwszNextOption
? pwszNextOption
+ 1 : NULL
;
791 if (hControlKey
!= NULL
)
792 RegCloseKey(hControlKey
);
793 if (pwszSystemStartOptions
)
794 HeapFree(GetProcessHeap(), 0, pwszSystemStartOptions
);
801 HANDLE hThread
= NULL
;
802 BOOL bResult
= FALSE
;
804 hSysSetupInf
= SetupOpenInfFileW(L
"syssetup.inf",
808 if (hSysSetupInf
== INVALID_HANDLE_VALUE
)
810 FatalError("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
814 if (!InstallSysSetupInfDevices())
816 FatalError("InstallSysSetupInfDevices() failed!\n");
820 if(!InstallSysSetupInfComponents())
822 FatalError("InstallSysSetupInfComponents() failed!\n");
826 if (!IsConsoleBoot())
828 hThread
= CreateThread(NULL
,
830 ShowStatusMessageThread
,
836 if (!EnableUserModePnpManager())
838 FatalError("EnableUserModePnpManager() failed!\n");
842 if (CMP_WaitNoPendingInstallEvents(INFINITE
) != WAIT_OBJECT_0
)
844 FatalError("CMP_WaitNoPendingInstallEvents() failed!\n");
852 if (bResult
== FALSE
)
854 SetupCloseInfFile(hSysSetupInf
);
859 PostThreadMessage(GetThreadId(hThread
), WM_QUIT
, 0, 0);
860 WaitForSingleObject(hThread
, INFINITE
);
861 CloseHandle(hThread
);
871 STARTUPINFOW StartupInfo
;
872 PROCESS_INFORMATION ProcessInformation
;
875 if (!CommonInstall())
878 /* Install the TCP/IP protocol driver */
879 bRes
= InstallNetworkComponent(L
"MS_TCPIP");
880 if (!bRes
&& GetLastError() != ERROR_FILE_NOT_FOUND
)
882 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError());
886 /* Start the TCP/IP protocol driver */
887 SetupStartService(L
"Tcpip", FALSE
);
888 SetupStartService(L
"Dhcp", FALSE
);
889 SetupStartService(L
"Dnscache", FALSE
);
892 /* Register components */
895 if (!SetupInstallFromInfSectionW(NULL
,
896 hSysSetupInf
, L
"RegistrationPhase2",
898 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
))
900 DPRINT1("SetupInstallFromInfSectionW failed!\n");
903 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
905 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
907 DPRINT1("Catching exception\n");
911 SetupCloseInfFile(hSysSetupInf
);
914 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
915 StartupInfo
.cb
= sizeof(StartupInfo
);
916 bRes
= CreateProcessW(L
"userinit.exe",
925 &ProcessInformation
);
929 CloseHandle(ProcessInformation
.hThread
);
930 CloseHandle(ProcessInformation
.hProcess
);
937 L
"Failed to load LiveCD! You can shutdown your computer, or press ENTER to reboot.",
945 SetSetupType(DWORD dwSetupType
)
950 dwError
= RegOpenKeyExW(
956 if (dwError
!= ERROR_SUCCESS
)
959 dwError
= RegSetValueExW(
964 (LPBYTE
)&dwSetupType
,
967 if (dwError
!= ERROR_SUCCESS
)
973 static DWORD CALLBACK
974 HotkeyThread(LPVOID Parameter
)
979 DPRINT("HotkeyThread start\n");
981 hotkey
= GlobalAddAtomW(L
"Setup Shift+F10 Hotkey");
983 if (!RegisterHotKey(NULL
, hotkey
, MOD_SHIFT
, VK_F10
))
984 DPRINT1("RegisterHotKey failed with %lu\n", GetLastError());
986 while (GetMessage(&msg
, NULL
, 0, 0))
988 if (msg
.hwnd
== NULL
&& msg
.message
== WM_HOTKEY
&& msg
.wParam
== hotkey
)
990 STARTUPINFOW si
= { sizeof(si
) };
991 PROCESS_INFORMATION pi
;
993 if (CreateProcessW(L
"cmd.exe",
1004 CloseHandle(pi
.hProcess
);
1005 CloseHandle(pi
.hThread
);
1009 DPRINT1("Failed to launch command prompt: %lu\n", GetLastError());
1014 UnregisterHotKey(NULL
, hotkey
);
1015 GlobalDeleteAtom(hotkey
);
1017 DPRINT("HotkeyThread terminate\n");
1024 InitializeProgramFilesDir(VOID
)
1029 WCHAR szProgramFilesDirPath
[MAX_PATH
];
1030 WCHAR szCommonFilesDirPath
[MAX_PATH
];
1031 WCHAR szBuffer
[MAX_PATH
];
1033 /* Load 'Program Files' location */
1034 if (!LoadStringW(hDllInstance
,
1037 ARRAYSIZE(szBuffer
)))
1039 DPRINT1("Error: %lu\n", GetLastError());
1043 if (!LoadStringW(hDllInstance
,
1045 szCommonFilesDirPath
,
1046 ARRAYSIZE(szCommonFilesDirPath
)))
1048 DPRINT1("Warning: %lu\n", GetLastError());
1052 if (!ExpandEnvironmentStringsW(szBuffer
,
1053 szProgramFilesDirPath
,
1054 ARRAYSIZE(szProgramFilesDirPath
)))
1056 DPRINT1("Error: %lu\n", GetLastError());
1060 wcscpy(szBuffer
, szProgramFilesDirPath
);
1061 wcscat(szBuffer
, L
"\\");
1062 wcscat(szBuffer
, szCommonFilesDirPath
);
1064 if (!ExpandEnvironmentStringsW(szBuffer
,
1065 szCommonFilesDirPath
,
1066 ARRAYSIZE(szCommonFilesDirPath
)))
1068 DPRINT1("Warning: %lu\n", GetLastError());
1072 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1073 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
1077 if (Error
!= ERROR_SUCCESS
)
1079 DPRINT1("Error: %lu\n", Error
);
1083 dwLength
= (wcslen(szProgramFilesDirPath
) + 1) * sizeof(WCHAR
);
1084 Error
= RegSetValueExW(hKey
,
1088 (LPBYTE
)szProgramFilesDirPath
,
1090 if (Error
!= ERROR_SUCCESS
)
1092 DPRINT1("Error: %lu\n", Error
);
1097 dwLength
= (wcslen(szCommonFilesDirPath
) + 1) * sizeof(WCHAR
);
1098 Error
= RegSetValueExW(hKey
,
1102 (LPBYTE
)szCommonFilesDirPath
,
1104 if (Error
!= ERROR_SUCCESS
)
1106 DPRINT1("Warning: %lu\n", Error
);
1111 /* Create directory */
1113 if (!CreateDirectoryW(szProgramFilesDirPath
, NULL
))
1115 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1117 DPRINT1("Error: %lu\n", GetLastError());
1122 /* Create directory */
1124 if (!CreateDirectoryW(szCommonFilesDirPath
, NULL
))
1126 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1128 DPRINT1("Warning: %lu\n", GetLastError());
1139 InitializeDefaultUserLocale(VOID
)
1149 struct {LCTYPE LCType
; PWSTR pValue
;} LocaleData
[] = {
1151 {LOCALE_SDECIMAL
, L
"sDecimal"},
1152 {LOCALE_STHOUSAND
, L
"sThousand"},
1153 {LOCALE_SNEGATIVESIGN
, L
"sNegativeSign"},
1154 {LOCALE_SPOSITIVESIGN
, L
"sPositiveSign"},
1155 {LOCALE_SGROUPING
, L
"sGrouping"},
1156 {LOCALE_SLIST
, L
"sList"},
1157 {LOCALE_SNATIVEDIGITS
, L
"sNativeDigits"},
1158 {LOCALE_INEGNUMBER
, L
"iNegNumber"},
1159 {LOCALE_IDIGITS
, L
"iDigits"},
1160 {LOCALE_ILZERO
, L
"iLZero"},
1161 {LOCALE_IMEASURE
, L
"iMeasure"},
1162 {LOCALE_IDIGITSUBSTITUTION
, L
"NumShape"},
1165 {LOCALE_SCURRENCY
, L
"sCurrency"},
1166 {LOCALE_SMONDECIMALSEP
, L
"sMonDecimalSep"},
1167 {LOCALE_SMONTHOUSANDSEP
, L
"sMonThousandSep"},
1168 {LOCALE_SMONGROUPING
, L
"sMonGrouping"},
1169 {LOCALE_ICURRENCY
, L
"iCurrency"},
1170 {LOCALE_INEGCURR
, L
"iNegCurr"},
1171 {LOCALE_ICURRDIGITS
, L
"iCurrDigits"},
1174 {LOCALE_STIMEFORMAT
, L
"sTimeFormat"},
1175 {LOCALE_STIME
, L
"sTime"},
1176 {LOCALE_S1159
, L
"s1159"},
1177 {LOCALE_S2359
, L
"s2359"},
1178 {LOCALE_ITIME
, L
"iTime"},
1179 {LOCALE_ITIMEMARKPOSN
, L
"iTimePrefix"},
1180 {LOCALE_ITLZERO
, L
"iTLZero"},
1183 {LOCALE_SLONGDATE
, L
"sLongDate"},
1184 {LOCALE_SSHORTDATE
, L
"sShortDate"},
1185 {LOCALE_SDATE
, L
"sDate"},
1186 {LOCALE_IFIRSTDAYOFWEEK
, L
"iFirstDayOfWeek"},
1187 {LOCALE_IFIRSTWEEKOFYEAR
, L
"iFirstWeekOfYear"},
1188 {LOCALE_IDATE
, L
"iDate"},
1189 {LOCALE_ICALENDARTYPE
, L
"iCalendarType"},
1192 {LOCALE_SCOUNTRY
, L
"sCountry"},
1193 {LOCALE_SABBREVLANGNAME
, L
"sLanguage"},
1194 {LOCALE_ICOUNTRY
, L
"iCountry"},
1197 ret
= RegOpenKeyExW(HKEY_USERS
,
1198 L
".DEFAULT\\Control Panel\\International",
1200 KEY_READ
| KEY_WRITE
,
1202 if (ret
!= ERROR_SUCCESS
)
1207 dwSize
= 9 * sizeof(WCHAR
);
1208 ret
= RegQueryValueExW(hLocaleKey
,
1214 if (ret
!= ERROR_SUCCESS
)
1217 lcid
= (LCID
)wcstoul(szBuffer
, &ptr
, 16);
1222 while (LocaleData
[i
].pValue
!= NULL
)
1224 if (GetLocaleInfoW(lcid
,
1225 LocaleData
[i
].LCType
| LOCALE_NOUSEROVERRIDE
,
1227 ARRAYSIZE(szBuffer
)))
1229 RegSetValueExW(hLocaleKey
,
1230 LocaleData
[i
].pValue
,
1234 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1241 RegCloseKey(hLocaleKey
);
1247 SaveDefaultUserHive(VOID
)
1249 WCHAR szDefaultUserHive
[MAX_PATH
];
1250 HKEY hUserKey
= NULL
;
1254 DPRINT("SaveDefaultUserHive()\n");
1256 cchSize
= ARRAYSIZE(szDefaultUserHive
);
1257 GetDefaultUserProfileDirectoryW(szDefaultUserHive
, &cchSize
);
1259 wcscat(szDefaultUserHive
, L
"\\ntuser.dat");
1261 dwError
= RegOpenKeyExW(HKEY_USERS
,
1266 if (dwError
!= ERROR_SUCCESS
)
1268 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError
);
1272 pSetupEnablePrivilege(L
"SeBackupPrivilege", TRUE
);
1274 /* Save the Default hive */
1275 dwError
= RegSaveKeyExW(hUserKey
,
1278 REG_STANDARD_FORMAT
);
1279 if (dwError
== ERROR_ALREADY_EXISTS
)
1281 WCHAR szBackupHive
[MAX_PATH
];
1283 /* Build the backup hive file name by replacing the extension */
1284 wcscpy(szBackupHive
, szDefaultUserHive
);
1285 wcscpy(&szBackupHive
[wcslen(szBackupHive
) - 4], L
".bak");
1287 /* Back up the existing default user hive by renaming it, replacing any possible existing old backup */
1288 if (!MoveFileExW(szDefaultUserHive
,
1290 MOVEFILE_REPLACE_EXISTING
))
1292 dwError
= GetLastError();
1293 DPRINT1("Failed to create a default-user hive backup '%S', MoveFileExW failed (Error %lu)\n",
1294 szBackupHive
, dwError
);
1298 /* The backup has been done, retry saving the Default hive */
1299 dwError
= RegSaveKeyExW(hUserKey
,
1302 REG_STANDARD_FORMAT
);
1305 if (dwError
!= ERROR_SUCCESS
)
1307 DPRINT1("RegSaveKeyExW() failed (Error %lu)\n", dwError
);
1310 pSetupEnablePrivilege(L
"SeBackupPrivilege", FALSE
);
1312 RegCloseKey(hUserKey
);
1320 InstallReactOS(VOID
)
1322 WCHAR szBuffer
[MAX_PATH
];
1324 TOKEN_PRIVILEGES privs
;
1327 HANDLE hHotkeyThread
;
1330 InitializeSetupActionLog(FALSE
);
1331 LogItem(NULL
, L
"Installing ReactOS");
1333 CreateTempDir(L
"TEMP");
1334 CreateTempDir(L
"TMP");
1336 if (!InitializeProgramFilesDir())
1338 FatalError("InitializeProgramFilesDir() failed");
1342 if (!InitializeProfiles())
1344 FatalError("InitializeProfiles() failed");
1348 InitializeDefaultUserLocale();
1350 if (GetWindowsDirectoryW(szBuffer
, ARRAYSIZE(szBuffer
)))
1352 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1353 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
1356 &hKey
) == ERROR_SUCCESS
)
1358 RegSetValueExW(hKey
,
1363 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1365 RegSetValueExW(hKey
,
1370 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1375 PathAddBackslash(szBuffer
);
1376 wcscat(szBuffer
, L
"system");
1377 CreateDirectory(szBuffer
, NULL
);
1380 if (SaveDefaultUserHive() != ERROR_SUCCESS
)
1382 FatalError("SaveDefaultUserHive() failed");
1386 if (!CopySystemProfile(0))
1388 FatalError("CopySystemProfile() failed");
1392 hHotkeyThread
= CreateThread(NULL
, 0, HotkeyThread
, NULL
, 0, NULL
);
1394 if (!CommonInstall())
1397 /* Install the TCP/IP protocol driver */
1398 ret
= InstallNetworkComponent(L
"MS_TCPIP");
1399 if (!ret
&& GetLastError() != ERROR_FILE_NOT_FOUND
)
1401 DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError());
1405 /* Start the TCP/IP protocol driver */
1406 SetupStartService(L
"Tcpip", FALSE
);
1407 SetupStartService(L
"Dhcp", FALSE
);
1408 SetupStartService(L
"Dnscache", FALSE
);
1415 SetAutoAdminLogon();
1417 hShortcutsInf
= SetupOpenInfFileW(L
"shortcuts.inf",
1421 if (hShortcutsInf
== INVALID_HANDLE_VALUE
)
1423 FatalError("Failed to open shortcuts.inf");
1427 if (!CreateShortcuts(hShortcutsInf
, L
"ShortcutFolders"))
1429 FatalError("CreateShortcuts() failed");
1433 SetupCloseInfFile(hShortcutsInf
);
1435 hShortcutsInf
= SetupOpenInfFileW(L
"rosapps_shortcuts.inf",
1439 if (hShortcutsInf
!= INVALID_HANDLE_VALUE
)
1441 if (!CreateShortcuts(hShortcutsInf
, L
"ShortcutFolders"))
1443 FatalError("CreateShortcuts(rosapps) failed");
1446 SetupCloseInfFile(hShortcutsInf
);
1449 SetupCloseInfFile(hSysSetupInf
);
1454 PostThreadMessage(GetThreadId(hHotkeyThread
), WM_QUIT
, 0, 0);
1455 CloseHandle(hHotkeyThread
);
1458 LogItem(NULL
, L
"Installing ReactOS done");
1459 TerminateSetupActionLog();
1461 if (AdminInfo
.Name
!= NULL
)
1462 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Name
);
1464 if (AdminInfo
.Domain
!= NULL
)
1465 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Domain
);
1467 if (AdminInfo
.Password
!= NULL
)
1468 RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo
.Password
);
1470 /* Get shutdown privilege */
1471 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &token
))
1473 FatalError("OpenProcessToken() failed!");
1476 if (!LookupPrivilegeValue(NULL
,
1478 &privs
.Privileges
[0].Luid
))
1480 FatalError("LookupPrivilegeValue() failed!");
1483 privs
.PrivilegeCount
= 1;
1484 privs
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
1485 if (AdjustTokenPrivileges(token
,
1489 (PTOKEN_PRIVILEGES
)NULL
,
1492 FatalError("AdjustTokenPrivileges() failed!");
1496 ExitWindowsEx(EWX_REBOOT
, 0);
1502 * Standard Windows-compatible export, which dispatches
1503 * to either 'InstallReactOS' or 'InstallLiveCD'.
1507 InstallWindowsNt(INT argc
, WCHAR
** argv
)
1512 for (i
= 0; i
< argc
; ++i
)
1519 // NOTE: On Windows, "mini" means "minimal UI", and can be used
1520 // in addition to "newsetup"; these options are not exclusive.
1521 if (_wcsicmp(p
, L
"newsetup") == 0)
1522 return (INT
)InstallReactOS();
1523 else if (_wcsicmp(p
, L
"mini") == 0)
1524 return (INT
)InstallLiveCD();
1526 /* Add support for other switches */
1538 SetupChangeFontSize(
1540 IN LPCWSTR lpszFontSize
)
1542 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1550 SetupChangeLocaleEx(HWND hWnd
,
1552 LPCWSTR lpSrcRootPath
,
1557 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1565 SetupChangeLocale(HWND hWnd
, LCID Lcid
)
1567 return SetupChangeLocaleEx(hWnd
, Lcid
, NULL
, 0, 0, 0);
1574 LPCWSTR lpServiceName
,
1577 SC_HANDLE hManager
= NULL
;
1578 SC_HANDLE hService
= NULL
;
1579 DWORD dwError
= ERROR_SUCCESS
;
1581 hManager
= OpenSCManagerW(NULL
,
1583 SC_MANAGER_ALL_ACCESS
);
1584 if (hManager
== NULL
)
1586 dwError
= GetLastError();
1590 hService
= OpenServiceW(hManager
,
1593 if (hService
== NULL
)
1595 dwError
= GetLastError();
1599 if (!StartService(hService
, 0, NULL
))
1601 dwError
= GetLastError();
1606 if (hService
!= NULL
)
1607 CloseServiceHandle(hService
);
1609 if (hManager
!= NULL
)
1610 CloseServiceHandle(hManager
);