2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: System setup
4 * FILE: dll/win32/syssetup/wizard.c
5 * PURPOSE: GUI controls
6 * PROGRAMMERS: Eric Kohl
7 * Pierre Schweitzer <heis_spiter@hotmail.com>
8 * Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
9 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
12 /* INCLUDES *****************************************************************/
28 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
29 /* Private Message used to communicate progress from the background
30 registration thread to the main thread.
31 wParam = 0 Registration in progress
32 = 1 Registration completed
33 lParam = Pointer to a REGISTRATIONNOTIFY structure */
35 typedef struct _REGISTRATIONNOTIFY
41 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
43 typedef struct _REGISTRATIONDATA
49 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
51 typedef struct _TIMEZONE_ENTRY
53 struct _TIMEZONE_ENTRY
*Prev
;
54 struct _TIMEZONE_ENTRY
*Next
;
55 WCHAR Description
[128]; /* 'Display' */
56 WCHAR StandardName
[32]; /* 'Std' */
57 WCHAR DaylightName
[32]; /* 'Dlt' */
58 REG_TZI_FORMAT TimezoneInfo
; /* 'TZI' */
60 } TIMEZONE_ENTRY
, *PTIMEZONE_ENTRY
;
63 /* FUNCTIONS ****************************************************************/
65 extern void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
69 CenterWindow(HWND hWnd
)
75 hWndParent
= GetParent(hWnd
);
76 if (hWndParent
== NULL
)
77 hWndParent
= GetDesktopWindow();
79 GetWindowRect(hWndParent
, &rcParent
);
80 GetWindowRect(hWnd
, &rcWindow
);
84 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
85 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
95 LOGFONTW LogFont
= {0};
99 LogFont
.lfWeight
= FW_BOLD
;
100 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
103 LogFont
.lfHeight
= -MulDiv(12, GetDeviceCaps(hdc
, LOGPIXELSY
), 72);
105 hFont
= CreateFontIndirectW(&LogFont
);
107 ReleaseDC(NULL
, hdc
);
116 LOGFONTW tmpFont
= {0};
120 /* Grabs the Drawing Context */
123 tmpFont
.lfHeight
= -MulDiv(8, GetDeviceCaps(hDc
, LOGPIXELSY
), 72);
124 tmpFont
.lfWeight
= FW_BOLD
;
125 wcscpy(tmpFont
.lfFaceName
, L
"MS Shell Dlg");
127 hBoldFont
= CreateFontIndirectW(&tmpFont
);
129 ReleaseDC(NULL
, hDc
);
134 static INT_PTR CALLBACK
135 GplDlgProc(HWND hwndDlg
,
140 HRSRC GplTextResource
;
150 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
151 if (NULL
== GplTextResource
)
155 Size
= SizeofResource(hDllInstance
, GplTextResource
);
160 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
165 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
166 if (NULL
== GplTextMem
)
168 HeapFree(GetProcessHeap(), 0, GplText
);
171 GplTextLocked
= LockResource(GplTextMem
);
172 if (NULL
== GplTextLocked
)
174 HeapFree(GetProcessHeap(), 0, GplText
);
177 memcpy(GplText
, GplTextLocked
, Size
);
178 GplText
[Size
] = '\0';
179 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
180 HeapFree(GetProcessHeap(), 0, GplText
);
181 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
185 EndDialog(hwndDlg
, IDCANCEL
);
189 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
191 EndDialog(hwndDlg
, IDOK
);
203 static INT_PTR CALLBACK
204 WelcomeDlgProc(HWND hwndDlg
,
209 PSETUPDATA pSetupData
;
211 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
220 /* Get pointer to the global setup data */
221 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
222 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
224 hwndControl
= GetParent(hwndDlg
);
226 /* Center the wizard window */
227 CenterWindow (hwndControl
);
229 /* Hide the system menu */
230 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
231 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
233 /* Hide and disable the 'Cancel' button */
234 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
235 ShowWindow (hwndControl
, SW_HIDE
);
236 EnableWindow (hwndControl
, FALSE
);
239 SendDlgItemMessage(hwndDlg
,
242 (WPARAM
)pSetupData
->hTitleFont
,
250 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
255 LogItem(L
"BEGIN", L
"WelcomePage");
256 /* Enable the Next button */
257 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
258 if (pSetupData
->UnattendSetup
)
260 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_ACKPAGE
);
266 LogItem(L
"END", L
"WelcomePage");
270 pSetupData
->UnattendSetup
= FALSE
;
287 static INT_PTR CALLBACK
288 AckPageDlgProc(HWND hwndDlg
,
295 PWCHAR End
, CurrentProject
;
296 INT ProjectsSize
, ProjectsCount
;
297 PSETUPDATA pSetupData
;
299 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
305 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
306 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
312 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
313 if (NULL
== Projects
)
317 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
318 if (0 == ProjectsCount
)
320 HeapFree(GetProcessHeap(), 0, Projects
);
323 if (ProjectsCount
< ProjectsSize
- 1)
327 HeapFree(GetProcessHeap(), 0, Projects
);
331 CurrentProject
= Projects
;
332 while (*CurrentProject
!= L
'\0')
334 End
= wcschr(CurrentProject
, L
'\n');
339 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
342 CurrentProject
= End
+ 1;
346 CurrentProject
+= wcslen(CurrentProject
);
349 HeapFree(GetProcessHeap(), 0, Projects
);
354 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
356 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
357 SetForegroundWindow(GetParent(hwndDlg
));
363 lpnm
= (LPNMHDR
)lParam
;
368 /* Enable the Back and Next buttons */
369 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
370 if (pSetupData
->UnattendSetup
)
372 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_PRODUCT
);
378 pSetupData
->UnattendSetup
= FALSE
;
394 static const WCHAR s_szProductOptions
[] = L
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
395 static const WCHAR s_szRosVersion
[] = L
"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version";
396 static const WCHAR s_szControlWindows
[] = L
"SYSTEM\\CurrentControlSet\\Control\\Windows";
398 typedef struct PRODUCT_OPTION_DATA
400 LPCWSTR ProductSuite
;
402 DWORD ReportAsWorkstation
;
404 } PRODUCT_OPTION_DATA
, *LPPRODUCT_OPTION_DATA
;
406 static const PRODUCT_OPTION_DATA s_ProductOptionData
[] =
408 { L
"Terminal Server\0", L
"ServerNT", 0, 0x200 },
409 { L
"\0", L
"WinNT", 1, 0x300 }
413 DoWriteProductOption(PRODUCT_OPTION nOption
)
418 DWORD dwValue
, cbData
;
419 const PRODUCT_OPTION_DATA
*pData
= &s_ProductOptionData
[nOption
];
420 ASSERT(0 <= nOption
&& nOption
< _countof(s_ProductOptionData
));
422 /* open ProductOptions key */
423 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szProductOptions
, 0, KEY_WRITE
, &hKey
);
426 DPRINT1("RegOpenKeyExW failed\n");
430 /* write ProductSuite */
431 pszData
= pData
->ProductSuite
;
432 cbData
= (lstrlenW(pszData
) + 2) * sizeof(WCHAR
);
433 error
= RegSetValueExW(hKey
, L
"ProductSuite", 0, REG_MULTI_SZ
, (const BYTE
*)pData
, cbData
);
436 DPRINT1("RegSetValueExW failed\n");
440 /* write ProductType */
441 pszData
= pData
->ProductType
;
442 cbData
= (lstrlenW(pszData
) + 1) * sizeof(WCHAR
);
443 error
= RegSetValueExW(hKey
, L
"ProductType", 0, REG_SZ
, (const BYTE
*)pData
, cbData
);
446 DPRINT1("RegSetValueExW failed\n");
452 /* open ReactOS version key */
453 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szRosVersion
, 0, KEY_WRITE
, &hKey
);
456 DPRINT1("RegOpenKeyExW failed\n");
460 /* write ReportAsWorkstation */
461 dwValue
= pData
->ReportAsWorkstation
;
462 cbData
= sizeof(dwValue
);
463 error
= RegSetValueExW(hKey
, L
"ReportAsWorkstation", 0, REG_DWORD
, (const BYTE
*)&dwValue
, cbData
);
466 DPRINT1("RegSetValueExW failed\n");
472 /* open Control Windows key */
473 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szControlWindows
, 0, KEY_WRITE
, &hKey
);
476 DPRINT1("RegOpenKeyExW failed\n");
480 /* write Control Windows CSDVersion */
481 dwValue
= pData
->CSDVersion
;
482 cbData
= sizeof(dwValue
);
483 error
= RegSetValueExW(hKey
, L
"CSDVersion", 0, REG_DWORD
, (const BYTE
*)&dwValue
, cbData
);
486 DPRINT1("RegSetValueExW failed\n");
494 return error
== ERROR_SUCCESS
;
498 OnChooseOption(HWND hwndDlg
, PRODUCT_OPTION nOption
)
501 ASSERT(0 <= nOption
&& nOption
< _countof(s_ProductOptionData
));
505 case PRODUCT_OPTION_SERVER
:
506 LoadStringW(hDllInstance
, IDS_PRODUCTSERVERINFO
, szText
, _countof(szText
));
509 case PRODUCT_OPTION_WORKSTATION
:
510 LoadStringW(hDllInstance
, IDS_PRODUCTWORKSTATIONINFO
, szText
, _countof(szText
));
517 SetDlgItemTextW(hwndDlg
, IDC_PRODUCT_DESCRIPTION
, szText
);
520 static INT_PTR CALLBACK
521 ProductPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
524 PSETUPDATA pSetupData
;
526 WCHAR szText
[64], szDefault
[64];;
529 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
535 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
536 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
538 LoadStringW(hDllInstance
, IDS_DEFAULT
, szDefault
, _countof(szDefault
));
540 LoadStringW(hDllInstance
, IDS_PRODUCTSERVERNAME
, szText
, _countof(szText
));
541 if (PRODUCT_OPTION_DEFAULT
== PRODUCT_OPTION_SERVER
)
543 StringCchCatW(szText
, _countof(szText
), L
" ");
544 StringCchCatW(szText
, _countof(szText
), szDefault
);
546 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_ADDSTRING
, 0, (LPARAM
)szText
);
548 LoadStringW(hDllInstance
, IDS_PRODUCTWORKSTATIONNAME
, szText
, _countof(szText
));
549 if (PRODUCT_OPTION_DEFAULT
== PRODUCT_OPTION_WORKSTATION
)
551 StringCchCatW(szText
, _countof(szText
), L
" ");
552 StringCchCatW(szText
, _countof(szText
), szDefault
);
554 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_ADDSTRING
, 0, (LPARAM
)szText
);
556 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_SETCURSEL
, PRODUCT_OPTION_DEFAULT
, 0);
557 OnChooseOption(hwndDlg
, PRODUCT_OPTION_DEFAULT
);
559 hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
560 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_ICON
, STM_SETICON
, (WPARAM
)hIcon
, 0);
565 if (HIWORD(wParam
) == CBN_SELCHANGE
&& IDC_PRODUCT_OPTIONS
== LOWORD(wParam
))
567 iItem
= SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_GETCURSEL
, 0, 0);
568 OnChooseOption(hwndDlg
, (PRODUCT_OPTION
)iItem
);
574 lpnm
= (LPNMHDR
)lParam
;
579 /* Enable the Back and Next buttons */
580 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
581 if (pSetupData
->UnattendSetup
)
583 OnChooseOption(hwndDlg
, pSetupData
->ProductOption
);
584 DoWriteProductOption(pSetupData
->ProductOption
);
585 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_LOCALEPAGE
);
591 iItem
= SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_GETCURSEL
, 0, 0);
592 pSetupData
->ProductOption
= (PRODUCT_OPTION
)iItem
;
593 DoWriteProductOption(pSetupData
->ProductOption
);
597 pSetupData
->UnattendSetup
= FALSE
;
615 WriteOwnerSettings(WCHAR
* OwnerName
,
616 WCHAR
* OwnerOrganization
)
621 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
622 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
627 if (res
!= ERROR_SUCCESS
)
632 res
= RegSetValueExW(hKey
,
637 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
639 if (res
!= ERROR_SUCCESS
)
645 res
= RegSetValueExW(hKey
,
646 L
"RegisteredOrganization",
649 (LPBYTE
)OwnerOrganization
,
650 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
653 return (res
== ERROR_SUCCESS
);
656 static INT_PTR CALLBACK
657 OwnerPageDlgProc(HWND hwndDlg
,
663 WCHAR OwnerOrganization
[51];
665 WCHAR ErrorName
[256];
667 PSETUPDATA pSetupData
;
669 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
675 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
676 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
678 /* set a localized ('Owner') placeholder string as default */
679 if (LoadStringW(hDllInstance
, IDS_MACHINE_OWNER_NAME
, OwnerName
, _countof(OwnerName
)))
681 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, WM_SETTEXT
, 0, (LPARAM
)OwnerName
);
684 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
685 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
687 /* Set focus to owner name */
688 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
690 /* Select the default text to quickly overwrite it by typing */
691 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_SETSEL
, 0, -1);
698 lpnm
= (LPNMHDR
)lParam
;
703 /* Enable the Back and Next buttons */
704 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
705 if (pSetupData
->UnattendSetup
)
707 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerName
);
708 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerOrganization
);
709 if (WriteOwnerSettings(pSetupData
->OwnerName
, pSetupData
->OwnerOrganization
))
711 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_COMPUTERPAGE
);
719 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
721 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
723 wcscpy(Title
, L
"ReactOS Setup");
725 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, ARRAYSIZE(ErrorName
)))
727 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
729 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
731 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
732 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
737 OwnerOrganization
[0] = 0;
738 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
740 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
742 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
743 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
748 pSetupData
->UnattendSetup
= FALSE
;
766 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
769 WCHAR ErrorComputerName
[256];
773 if (!SetComputerNameW(ComputerName
))
777 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
779 wcscpy(Title
, L
"ReactOS Setup");
781 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
782 ARRAYSIZE(ErrorComputerName
)))
784 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
786 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
792 /* Set the physical DNS domain */
793 SetComputerNameExW(ComputerNamePhysicalDnsDomain
, L
"");
795 /* Set the physical DNS hostname */
796 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
798 /* Set the accounts domain name */
799 SetAccountsDomainSid(NULL
, ComputerName
);
801 /* Now we need to set the Hostname */
802 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
803 L
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
807 if (lError
!= ERROR_SUCCESS
)
809 DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError
);
813 lError
= RegSetValueEx(hKey
,
817 (LPBYTE
)ComputerName
,
818 (wcslen(ComputerName
) + 1) * sizeof(WCHAR
));
819 if (lError
!= ERROR_SUCCESS
)
821 DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError
);
832 WriteDefaultLogonData(LPWSTR Domain
)
834 WCHAR szAdministratorName
[256];
838 if (LoadStringW(hDllInstance
,
839 IDS_ADMINISTRATOR_NAME
,
841 ARRAYSIZE(szAdministratorName
)) == 0)
843 wcscpy(szAdministratorName
, L
"Administrator");
846 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
847 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
851 if (lError
!= ERROR_SUCCESS
)
854 lError
= RegSetValueEx(hKey
,
855 L
"DefaultDomainName",
859 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
860 if (lError
!= ERROR_SUCCESS
)
862 DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n");
865 lError
= RegSetValueEx(hKey
,
869 (LPBYTE
)szAdministratorName
,
870 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
871 if (lError
!= ERROR_SUCCESS
)
873 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
882 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
884 GenerateComputerName(LPWSTR lpBuffer
)
886 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
887 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
890 wcscpy(lpBuffer
, L
"REACTOS-");
892 srand(GetTickCount());
894 /* fill in 7 characters */
895 for (i
= 8; i
< 15; i
++)
896 lpBuffer
[i
] = Chars
[rand() % cChars
];
898 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
901 static INT_PTR CALLBACK
902 ComputerPageDlgProc(HWND hwndDlg
,
907 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
908 WCHAR Password1
[128];
909 WCHAR Password2
[128];
912 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
914 PSETUPDATA pSetupData
;
916 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
918 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
920 wcscpy(Title
, L
"ReactOS Setup");
926 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
927 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
929 /* Generate a new pseudo-random computer name */
930 GenerateComputerName(ComputerName
);
932 /* Display current computer name */
933 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
935 /* Set text limits */
936 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
937 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
938 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
940 /* Set focus to computer name */
941 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
942 if (pSetupData
->UnattendSetup
)
944 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->ComputerName
);
945 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
946 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
947 WriteComputerSettings(pSetupData
->ComputerName
, NULL
);
948 SetAdministratorPassword(pSetupData
->AdminPassword
);
951 /* Store the administrator account name as the default user name */
952 WriteDefaultLogonData(pSetupData
->ComputerName
);
958 lpnm
= (LPNMHDR
)lParam
;
963 /* Enable the Back and Next buttons */
964 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
965 if (pSetupData
->UnattendSetup
&& WriteComputerSettings(pSetupData
->ComputerName
, hwndDlg
))
967 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_THEMEPAGE
);
973 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
975 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
976 ARRAYSIZE(EmptyComputerName
)))
978 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
980 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
981 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
982 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
986 /* No need to check computer name for invalid characters,
987 * SetComputerName() will do it for us */
989 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
991 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
992 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
996 #ifdef PASSWORDS_MANDATORY
997 /* Check if admin passwords have been entered */
998 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
999 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
1001 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
1002 ARRAYSIZE(EmptyPassword
)))
1004 wcscpy(EmptyPassword
, L
"You must enter a password !");
1006 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
1007 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1011 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
1012 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
1014 /* Check if passwords match */
1015 if (wcscmp(Password1
, Password2
))
1017 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
1018 ARRAYSIZE(NotMatchPassword
)))
1020 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
1022 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
1023 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1027 /* Check password for invalid characters */
1028 Password
= (PWCHAR
)Password1
;
1031 if (!isprint(*Password
))
1033 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
1034 ARRAYSIZE(WrongPassword
)))
1036 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
1038 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
1039 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1045 /* Set admin password */
1046 SetAdministratorPassword(Password1
);
1050 pSetupData
->UnattendSetup
= FALSE
;
1068 SetKeyboardLayoutName(HWND hwnd
)
1071 TCHAR szLayoutPath
[256];
1072 TCHAR szLocaleName
[32];
1076 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
1077 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
1083 dwValueSize
= 16 * sizeof(TCHAR
);
1084 if (RegQueryValueEx(hKey
,
1095 _tcscpy(szLayoutPath
,
1096 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
1097 _tcscat(szLayoutPath
,
1100 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
1107 dwValueSize
= 32 * sizeof(TCHAR
);
1108 if (RegQueryValueEx(hKey
,
1125 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
1128 STARTUPINFOW StartupInfo
;
1129 PROCESS_INFORMATION ProcessInformation
;
1130 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
1132 if (!pwszCPLParameters
)
1134 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
1138 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
1139 StartupInfo
.cb
= sizeof(StartupInfo
);
1140 ZeroMemory(&ProcessInformation
, sizeof(ProcessInformation
));
1142 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
1143 wcscat(CmdLine
, pwszCPLParameters
);
1145 if (!CreateProcessW(NULL
,
1154 &ProcessInformation
))
1156 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
1160 while ((MsgWaitForMultipleObjects(1, &ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
1162 while (PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
1164 TranslateMessage(&msg
);
1165 DispatchMessageW(&msg
);
1168 CloseHandle(ProcessInformation
.hThread
);
1169 CloseHandle(ProcessInformation
.hProcess
);
1174 WriteUserLocale(VOID
)
1180 lcid
= GetSystemDefaultLCID();
1182 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, ARRAYSIZE(Locale
)) != 0)
1184 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
1185 0, NULL
, REG_OPTION_NON_VOLATILE
,
1186 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
1188 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
1194 static INT_PTR CALLBACK
1195 LocalePageDlgProc(HWND hwndDlg
,
1200 PSETUPDATA SetupData
;
1202 /* Retrieve pointer to the global setup data */
1203 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1209 /* Save pointer to the global setup data */
1210 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1211 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1214 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
1219 if (HIWORD(wParam
) == BN_CLICKED
)
1221 switch (LOWORD(wParam
))
1223 case IDC_CUSTOMLOCALE
:
1224 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
1225 /* FIXME: Update input locale name */
1228 case IDC_CUSTOMLAYOUT
:
1229 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
1237 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1242 /* Enable the Back and Next buttons */
1243 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1244 if (SetupData
->UnattendSetup
)
1246 // if (!*SetupData->SourcePath)
1248 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32
1251 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_OWNERPAGE
);
1260 SetupData
->UnattendSetup
= FALSE
;
1277 static PTIMEZONE_ENTRY
1278 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1280 PTIMEZONE_ENTRY Entry
;
1282 Entry
= SetupData
->TimeZoneListHead
;
1283 while (Entry
!= NULL
)
1285 if (Entry
->Index
>= Index
)
1288 Entry
= Entry
->Next
;
1300 PSETUPDATA SetupData
= (PSETUPDATA
)Context
;
1301 PTIMEZONE_ENTRY Entry
;
1302 PTIMEZONE_ENTRY Current
;
1303 ULONG DescriptionSize
;
1304 ULONG StandardNameSize
;
1305 ULONG DaylightNameSize
;
1307 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1310 return ERROR_NOT_ENOUGH_MEMORY
;
1313 DescriptionSize
= sizeof(Entry
->Description
);
1314 StandardNameSize
= sizeof(Entry
->StandardName
);
1315 DaylightNameSize
= sizeof(Entry
->DaylightName
);
1317 lError
= QueryTimeZoneData(hZoneKey
,
1319 &Entry
->TimezoneInfo
,
1322 Entry
->StandardName
,
1324 Entry
->DaylightName
,
1326 if (lError
!= ERROR_SUCCESS
)
1328 HeapFree(GetProcessHeap(), 0, Entry
);
1332 if (SetupData
->TimeZoneListHead
== NULL
&&
1333 SetupData
->TimeZoneListTail
== NULL
)
1337 SetupData
->TimeZoneListHead
= Entry
;
1338 SetupData
->TimeZoneListTail
= Entry
;
1342 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1343 if (Current
!= NULL
)
1345 if (Current
== SetupData
->TimeZoneListHead
)
1347 /* Prepend to head */
1349 Entry
->Next
= SetupData
->TimeZoneListHead
;
1350 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1351 SetupData
->TimeZoneListHead
= Entry
;
1355 /* Insert before current */
1356 Entry
->Prev
= Current
->Prev
;
1357 Entry
->Next
= Current
;
1358 Current
->Prev
->Next
= Entry
;
1359 Current
->Prev
= Entry
;
1364 /* Append to tail */
1365 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1367 SetupData
->TimeZoneListTail
->Next
= Entry
;
1368 SetupData
->TimeZoneListTail
= Entry
;
1372 return ERROR_SUCCESS
;
1376 CreateTimeZoneList(PSETUPDATA SetupData
)
1378 EnumerateTimeZoneList(RetrieveTimeZone
, SetupData
);
1382 DestroyTimeZoneList(PSETUPDATA SetupData
)
1384 PTIMEZONE_ENTRY Entry
;
1386 while (SetupData
->TimeZoneListHead
!= NULL
)
1388 Entry
= SetupData
->TimeZoneListHead
;
1390 SetupData
->TimeZoneListHead
= Entry
->Next
;
1391 if (SetupData
->TimeZoneListHead
!= NULL
)
1393 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1396 HeapFree(GetProcessHeap(), 0, Entry
);
1399 SetupData
->TimeZoneListTail
= NULL
;
1404 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1406 PTIMEZONE_ENTRY Entry
;
1410 GetTimeZoneListIndex(&dwEntryIndex
);
1412 Entry
= SetupData
->TimeZoneListHead
;
1413 while (Entry
!= NULL
)
1415 dwCount
= SendMessage(hwnd
,
1418 (LPARAM
)Entry
->Description
);
1420 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1423 Entry
= Entry
->Next
;
1434 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1436 TIME_ZONE_INFORMATION TimeZoneInformation
;
1437 PTIMEZONE_ENTRY Entry
;
1441 dwIndex
= SendMessage(hwnd
,
1447 Entry
= SetupData
->TimeZoneListHead
;
1454 Entry
= Entry
->Next
;
1457 wcscpy(TimeZoneInformation
.StandardName
,
1458 Entry
->StandardName
);
1459 wcscpy(TimeZoneInformation
.DaylightName
,
1460 Entry
->DaylightName
);
1462 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1463 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1464 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1466 memcpy(&TimeZoneInformation
.StandardDate
,
1467 &Entry
->TimezoneInfo
.StandardDate
,
1468 sizeof(SYSTEMTIME
));
1469 memcpy(&TimeZoneInformation
.DaylightDate
,
1470 &Entry
->TimezoneInfo
.DaylightDate
,
1471 sizeof(SYSTEMTIME
));
1473 /* Set time zone information */
1474 SetTimeZoneInformation(&TimeZoneInformation
);
1479 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1484 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1489 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1494 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1495 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1496 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1497 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1498 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1499 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1500 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1501 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1508 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1513 * Call SetLocalTime twice to ensure correct results
1515 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1516 SetLocalTime(&SetupData
->SystemTime
);
1523 UpdateLocalSystemTime(HWND hwnd
)
1525 SYSTEMTIME LocalTime
;
1527 GetLocalTime(&LocalTime
);
1528 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), GDT_VALID
, &LocalTime
);
1529 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), GDT_VALID
, &LocalTime
);
1534 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1537 WCHAR ErrorLocalTime
[256];
1539 GetLocalSystemTime(hwndDlg
, SetupData
);
1540 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1543 SetAutoDaylight(SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
,
1544 BM_GETCHECK
, 0, 0) != BST_UNCHECKED
);
1545 if (!SetSystemLocalTime(hwndDlg
, SetupData
))
1547 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
1549 wcscpy(Title
, L
"ReactOS Setup");
1551 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1552 ARRAYSIZE(ErrorLocalTime
)))
1554 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1556 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1564 static INT_PTR CALLBACK
1565 DateTimePageDlgProc(HWND hwndDlg
,
1570 PSETUPDATA SetupData
;
1572 /* Retrieve pointer to the global setup data */
1573 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1579 /* Save pointer to the global setup data */
1580 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1581 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1583 CreateTimeZoneList(SetupData
);
1585 if (SetupData
->UnattendSetup
)
1587 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1588 SetupData
, SetupData
->TimeZoneIndex
);
1590 if (!SetupData
->DisableAutoDaylightTimeSet
)
1592 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1597 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1600 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1606 UpdateLocalSystemTime(hwndDlg
);
1610 switch (((LPNMHDR
)lParam
)->code
)
1613 /* Enable the Back and Next buttons */
1614 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1615 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1617 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1620 SetTimer(hwndDlg
, 1, 1000, NULL
);
1623 case PSN_KILLACTIVE
:
1624 case DTN_DATETIMECHANGE
:
1625 KillTimer(hwndDlg
, 1);
1629 WriteDateTimeSettings(hwndDlg
, SetupData
);
1633 SetupData
->UnattendSetup
= FALSE
;
1642 DestroyTimeZoneList(SetupData
);
1652 static struct ThemeInfo
1654 LPCWSTR PreviewBitmap
;
1659 { MAKEINTRESOURCE(IDB_CLASSIC
), IDS_CLASSIC
, NULL
},
1660 { MAKEINTRESOURCE(IDB_LAUTUS
), IDS_LAUTUS
, L
"themes\\lautus\\lautus.msstyles" },
1661 { MAKEINTRESOURCE(IDB_LUNAR
), IDS_LUNAR
, L
"themes\\lunar\\lunar.msstyles" },
1662 { MAKEINTRESOURCE(IDB_MIZU
), IDS_MIZU
, L
"themes\\mizu\\mizu.msstyles"},
1665 static INT_PTR CALLBACK
1666 ThemePageDlgProc(HWND hwndDlg
,
1671 PSETUPDATA SetupData
;
1674 /* Retrieve pointer to the global setup data */
1675 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1686 /* Save pointer to the global setup data */
1687 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1688 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1690 hListView
= GetDlgItem(hwndDlg
, IDC_THEMEPICKER
);
1693 himl
= ImageList_Create(180, 163, ILC_COLOR32
| ILC_MASK
, ARRAYSIZE(Themes
), 1);
1694 lvi
.mask
= LVIF_TEXT
| LVIF_IMAGE
|LVIF_STATE
;
1696 for (n
= 0; n
< ARRAYSIZE(Themes
); ++n
)
1698 WCHAR DisplayName
[100] = {0};
1699 /* Load the bitmap */
1700 HANDLE image
= LoadImageW(hDllInstance
, Themes
[n
].PreviewBitmap
, IMAGE_BITMAP
, 0, 0, LR_CREATEDIBSECTION
);
1701 ImageList_AddMasked(himl
, image
, RGB(255,0,255));
1703 /* Load the string */
1704 LoadStringW(hDllInstance
, Themes
[n
].DisplayName
, DisplayName
, ARRAYSIZE(DisplayName
));
1705 DisplayName
[ARRAYSIZE(DisplayName
)-1] = UNICODE_NULL
;
1707 /* Add the listview item */
1710 lvi
.pszText
= DisplayName
;
1711 ListView_InsertItem(hListView
, &lvi
);
1714 /* Register the imagelist */
1715 ListView_SetImageList(hListView
, himl
, LVSIL_NORMAL
);
1716 /* Transparant background */
1717 ListView_SetBkColor(hListView
, CLR_NONE
);
1718 ListView_SetTextBkColor(hListView
, CLR_NONE
);
1719 /* Reduce the size between the items */
1720 ListView_SetIconSpacing(hListView
, 190, 173);
1724 switch (((LPNMHDR
)lParam
)->code
)
1726 //case LVN_ITEMCHANGING:
1727 case LVN_ITEMCHANGED
:
1728 pnmv
= (LPNMLISTVIEW
)lParam
;
1729 if ((pnmv
->uChanged
& LVIF_STATE
) && (pnmv
->uNewState
& LVIS_SELECTED
))
1731 int iTheme
= pnmv
->iItem
;
1732 DPRINT1("Selected theme: %u\n", Themes
[iTheme
].DisplayName
);
1734 if (Themes
[iTheme
].ThemeFile
)
1736 WCHAR wszParams
[1024];
1737 WCHAR wszTheme
[MAX_PATH
];
1738 WCHAR
* format
= L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\"";
1740 SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES
, NULL
, SHGFP_TYPE_DEFAULT
, Themes
[iTheme
].ThemeFile
, wszTheme
);
1741 swprintf(wszParams
, format
, wszTheme
);
1742 RunControlPanelApplet(hwndDlg
, wszParams
);
1746 RunControlPanelApplet(hwndDlg
, L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme");
1751 /* Enable the Back and Next buttons */
1752 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1753 if (SetupData
->UnattendSetup
)
1755 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1764 SetupData
->UnattendSetup
= FALSE
;
1779 static UINT CALLBACK
1780 RegistrationNotificationProc(PVOID Context
,
1785 PREGISTRATIONDATA RegistrationData
;
1786 REGISTRATIONNOTIFY RegistrationNotify
;
1787 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1789 WCHAR ErrorMessage
[128];
1791 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1793 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1794 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1796 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1797 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1798 if (NULL
== RegistrationNotify
.CurrentItem
)
1800 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1804 RegistrationNotify
.CurrentItem
++;
1807 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1809 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1810 StatusInfo
->FileName
);
1811 RegistrationNotify
.ErrorMessage
= NULL
;
1812 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1816 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1817 StatusInfo
->FileName
);
1818 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1819 StatusInfo
->FailureCode
);
1820 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1822 switch(StatusInfo
->FailureCode
)
1824 case SPREG_LOADLIBRARY
:
1825 MessageID
= IDS_LOADLIBRARY_FAILED
;
1827 case SPREG_GETPROCADDR
:
1828 MessageID
= IDS_GETPROCADDR_FAILED
;
1831 MessageID
= IDS_REGSVR_FAILED
;
1833 case SPREG_DLLINSTALL
:
1834 MessageID
= IDS_DLLINSTALL_FAILED
;
1837 MessageID
= IDS_TIMEOUT
;
1840 MessageID
= IDS_REASON_UNKNOWN
;
1843 if (0 == LoadStringW(hDllInstance
, MessageID
,
1845 ARRAYSIZE(ErrorMessage
)))
1847 ErrorMessage
[0] = L
'\0';
1849 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1851 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1852 StatusInfo
->Win32Error
, 0,
1853 ErrorMessage
+ wcslen(ErrorMessage
),
1854 ARRAYSIZE(ErrorMessage
) - wcslen(ErrorMessage
),
1857 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1861 RegistrationNotify
.ErrorMessage
= NULL
;
1863 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1865 RegistrationData
->Registered
++;
1869 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1870 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1871 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1872 0, (LPARAM
) &RegistrationNotify
);
1878 DPRINT1("Received unexpected notification %u\n", Notification
);
1879 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1880 Notification
, Param1
, Param2
);
1885 static DWORD CALLBACK
1886 RegistrationProc(LPVOID Parameter
)
1888 PREGISTRATIONDATA RegistrationData
;
1889 REGISTRATIONNOTIFY RegistrationNotify
;
1890 DWORD LastError
= NO_ERROR
;
1891 WCHAR UnknownError
[84];
1893 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1894 RegistrationData
->Registered
= 0;
1895 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1899 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1901 L
"RegistrationPhase2",
1903 SPINST_REGISTERCALLBACKAWARE
|
1908 RegistrationNotificationProc
,
1913 LastError
= GetLastError();
1916 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1918 DPRINT("Catching exception\n");
1919 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1923 if (NO_ERROR
== LastError
)
1925 RegistrationNotify
.ErrorMessage
= NULL
;
1929 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1931 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1932 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1933 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1936 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1938 ARRAYSIZE(UnknownError
) - 20))
1940 wcscpy(UnknownError
, L
"Unknown error");
1942 wcscat(UnknownError
, L
" ");
1943 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1944 RegistrationNotify
.ErrorMessage
= UnknownError
;
1948 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1949 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1950 RegistrationNotify
.CurrentItem
= NULL
;
1951 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1952 1, (LPARAM
) &RegistrationNotify
);
1953 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1954 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1956 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1959 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1960 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1962 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1964 // FIXME: Move this call to a separate cleanup page!
1965 RtlCreateBootStatusDataFile();
1972 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1974 HANDLE RegistrationThread
;
1977 WCHAR SectionName
[512];
1978 PREGISTRATIONDATA RegistrationData
;
1981 if (!SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1982 L
"RegisterDlls", &Context
))
1984 DPRINT1("No RegistrationPhase2 section found\n");
1987 if (!SetupGetStringFieldW(&Context
, 1, SectionName
,
1988 ARRAYSIZE(SectionName
),
1991 DPRINT1("Unable to retrieve section name\n");
1994 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1995 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1998 SetLastError(STATUS_NOT_FOUND
);
2002 *MaxProgress
= (ULONG
) DllCount
;
2005 * Create a background thread to do the actual registrations, so the
2006 * main thread can just run its message loop.
2008 RegistrationThread
= NULL
;
2009 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
2010 sizeof(REGISTRATIONDATA
));
2011 if (RegistrationData
!= NULL
)
2013 RegistrationData
->hwndDlg
= hwndDlg
;
2014 RegistrationData
->DllCount
= DllCount
;
2015 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
2016 RegistrationData
, 0, NULL
);
2017 if (RegistrationThread
!= NULL
)
2019 CloseHandle(RegistrationThread
);
2023 DPRINT1("CreateThread failed, error %u\n", GetLastError());
2024 HeapFree(GetProcessHeap(), 0, RegistrationData
);
2030 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
2038 static INT_PTR CALLBACK
2039 ProcessPageDlgProc(HWND hwndDlg
,
2044 PSETUPDATA SetupData
;
2045 PREGISTRATIONNOTIFY RegistrationNotify
;
2046 static UINT oldActivityID
= -1;
2049 /* Retrieve pointer to the global setup data */
2050 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
2056 /* Save pointer to the global setup data */
2057 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2058 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
2064 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2065 ULONG MaxProgress
= 0;
2070 /* Disable the Back and Next buttons */
2071 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
2073 StartComponentRegistration(hwndDlg
, &MaxProgress
);
2075 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
2076 0, MAKELPARAM(0, MaxProgress
));
2077 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
2085 SetupData
->UnattendSetup
= FALSE
;
2094 case PM_REGISTRATION_NOTIFY
:
2097 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
2098 // update if necessary only
2099 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
2101 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
2103 ARRAYSIZE(Activity
)))
2105 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
2106 0, (LPARAM
) Activity
);
2108 oldActivityID
= RegistrationNotify
->ActivityID
;
2110 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
2111 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
2112 L
"" : RegistrationNotify
->CurrentItem
));
2113 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
2114 RegistrationNotify
->Progress
, 0);
2115 if (NULL
!= RegistrationNotify
->ErrorMessage
)
2117 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
2118 Title
, ARRAYSIZE(Title
)))
2120 wcscpy(Title
, L
"ReactOS Setup");
2122 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
2123 Title
, MB_ICONERROR
| MB_OK
);
2129 /* Enable the Back and Next buttons */
2130 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
2131 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
2145 SetInstallationCompleted(VOID
)
2148 DWORD InProgress
= 0;
2151 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2155 &hKey
) == ERROR_SUCCESS
)
2157 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
2158 RegCloseKey( hKey
);
2161 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2162 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2165 &hKey
) == ERROR_SUCCESS
)
2167 InstallDate
= (DWORD
)time(NULL
);
2168 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
2169 RegCloseKey( hKey
);
2173 static INT_PTR CALLBACK
2174 FinishDlgProc(HWND hwndDlg
,
2184 /* Get pointer to the global setup data */
2185 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2187 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2189 /* Run the Wine Gecko prompt */
2190 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2193 /* Set title font */
2194 SendDlgItemMessage(hwndDlg
,
2197 (WPARAM
)SetupData
->hTitleFont
,
2199 if (SetupData
->UnattendSetup
)
2201 KillTimer(hwndDlg
, 1);
2202 SetInstallationCompleted();
2210 SetInstallationCompleted();
2220 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2221 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2222 if (Position
== 300)
2224 KillTimer(hwndDlg
, 1);
2225 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2229 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2236 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2241 /* Enable the correct buttons on for the active page */
2242 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2244 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2245 MAKELPARAM(0, 300));
2246 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2247 SetTimer(hwndDlg
, 1, 50, NULL
);
2251 DestroyWindow(GetParent(hwndDlg
));
2269 * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium
2270 * in Win32 format, for later use by syssetup and storage in the registry.
2273 GetInstallSourceWin32(
2275 IN DWORD cchPathMax
,
2276 IN PCWSTR pwszNTPath
)
2278 WCHAR wszDrives
[512];
2279 WCHAR wszNTPath
[512]; // MAX_PATH ?
2283 *pwszPath
= UNICODE_NULL
;
2285 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2286 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2288 /* Buffer too small or failure */
2289 LogItem(NULL
, L
"GetLogicalDriveStringsW failed");
2293 for (pwszDrive
= wszDrives
; *pwszDrive
; pwszDrive
+= wcslen(pwszDrive
) + 1)
2295 WCHAR wszBuf
[MAX_PATH
];
2297 /* Retrieve the NT path corresponding to the current Win32 DOS path */
2298 pwszDrive
[2] = UNICODE_NULL
; // Temporarily remove the backslash
2299 QueryDosDeviceW(pwszDrive
, wszNTPath
, _countof(wszNTPath
));
2300 pwszDrive
[2] = L
'\\'; // Restore the backslash
2302 wcscat(wszNTPath
, L
"\\"); // Concat a backslash
2305 wsprintf(wszBuf
, L
"Testing '%s' --> '%s' %s a CD",
2306 pwszDrive
, wszNTPath
,
2307 (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
) ? L
"is" : L
"is not");
2308 LogItem(NULL
, wszBuf
);
2310 /* Check whether the NT path corresponds to the NT installation source path */
2311 if (!_wcsicmp(wszNTPath
, pwszNTPath
))
2314 wcscpy(pwszPath
, pwszDrive
); // cchPathMax
2317 wsprintf(wszBuf
, L
"GetInstallSourceWin32: %s", pwszPath
);
2318 LogItem(NULL
, wszBuf
);
2319 wcscat(wszBuf
, L
"\n");
2320 OutputDebugStringW(wszBuf
);
2330 ProcessUnattendSection(
2331 IN OUT PSETUPDATA pSetupData
)
2333 INFCONTEXT InfContext
;
2335 WCHAR szValue
[MAX_PATH
];
2339 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
2341 L
"UnattendSetupEnabled",
2344 DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError());
2348 if (!SetupGetStringFieldW(&InfContext
,
2354 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2358 if (_wcsicmp(szValue
, L
"yes") != 0)
2360 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2364 pSetupData
->UnattendSetup
= TRUE
;
2366 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
2371 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2377 if (!SetupGetStringFieldW(&InfContext
,
2383 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2387 if (!SetupGetStringFieldW(&InfContext
,
2393 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2396 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2397 if (!_wcsicmp(szName
, L
"FullName"))
2399 if (ARRAYSIZE(pSetupData
->OwnerName
) > LineLength
)
2401 wcscpy(pSetupData
->OwnerName
, szValue
);
2404 else if (!_wcsicmp(szName
, L
"OrgName"))
2406 if (ARRAYSIZE(pSetupData
->OwnerOrganization
) > LineLength
)
2408 wcscpy(pSetupData
->OwnerOrganization
, szValue
);
2411 else if (!_wcsicmp(szName
, L
"ComputerName"))
2413 if (ARRAYSIZE(pSetupData
->ComputerName
) > LineLength
)
2415 wcscpy(pSetupData
->ComputerName
, szValue
);
2418 else if (!_wcsicmp(szName
, L
"AdminPassword"))
2420 if (ARRAYSIZE(pSetupData
->AdminPassword
) > LineLength
)
2422 wcscpy(pSetupData
->AdminPassword
, szValue
);
2425 else if (!_wcsicmp(szName
, L
"TimeZoneIndex"))
2427 pSetupData
->TimeZoneIndex
= _wtoi(szValue
);
2429 else if (!_wcsicmp(szName
, L
"DisableAutoDaylightTimeSet"))
2431 pSetupData
->DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2433 else if (!_wcsicmp(szName
, L
"DisableGeckoInst"))
2435 if (!_wcsicmp(szValue
, L
"yes"))
2436 pSetupData
->DisableGeckoInst
= TRUE
;
2438 pSetupData
->DisableGeckoInst
= FALSE
;
2440 else if (!_wcsicmp(szName
, L
"ProductOption"))
2442 pSetupData
->ProductOption
= (PRODUCT_OPTION
)_wtoi(szValue
);
2444 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2446 if (SetupFindFirstLineW(pSetupData
->hSetupInf
,
2451 DEVMODEW dm
= { { 0 } };
2452 dm
.dmSize
= sizeof(dm
);
2453 if (EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &dm
))
2458 if (!SetupGetStringFieldW(&InfContext
,
2464 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2468 if (!SetupGetStringFieldW(&InfContext
,
2474 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2477 iValue
= _wtoi(szValue
);
2478 DPRINT1("Name %S Value %i\n", szName
, iValue
);
2483 if (!_wcsicmp(szName
, L
"BitsPerPel"))
2485 dm
.dmFields
|= DM_BITSPERPEL
;
2486 dm
.dmBitsPerPel
= iValue
;
2488 else if (!_wcsicmp(szName
, L
"XResolution"))
2490 dm
.dmFields
|= DM_PELSWIDTH
;
2491 dm
.dmPelsWidth
= iValue
;
2493 else if (!_wcsicmp(szName
, L
"YResolution"))
2495 dm
.dmFields
|= DM_PELSHEIGHT
;
2496 dm
.dmPelsHeight
= iValue
;
2498 else if (!_wcsicmp(szName
, L
"VRefresh"))
2500 dm
.dmFields
|= DM_DISPLAYFREQUENCY
;
2501 dm
.dmDisplayFrequency
= iValue
;
2503 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2505 ChangeDisplaySettingsW(&dm
, CDS_UPDATEREGISTRY
);
2509 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2510 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2513 &hKey
) != ERROR_SUCCESS
)
2515 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2519 if (SetupFindFirstLineW(pSetupData
->hSetupInf
,
2527 if (SetupGetStringFieldW(&InfContext
,
2533 WCHAR szPath
[MAX_PATH
];
2534 swprintf(szName
, L
"%d", i
);
2535 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2537 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2539 DPRINT("value %S\n", szPath
);
2540 if (RegSetValueExW(hKey
,
2544 (const BYTE
*)szPath
,
2545 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2551 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2559 IN OUT PSETUPDATA pSetupData
)
2561 WCHAR szPath
[MAX_PATH
];
2562 WCHAR szValue
[MAX_PATH
];
2563 INFCONTEXT InfContext
;
2568 pSetupData
->hSetupInf
= INVALID_HANDLE_VALUE
;
2570 /* Retrieve the path of the setup INF */
2571 GetSystemDirectoryW(szPath
, _countof(szPath
));
2572 wcscat(szPath
, L
"\\$winnt$.inf");
2574 /* Open the setup INF */
2575 pSetupData
->hSetupInf
= SetupOpenInfFileW(szPath
,
2579 if (pSetupData
->hSetupInf
== INVALID_HANDLE_VALUE
)
2581 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath
, GetLastError());
2586 /* Retrieve the NT source path from which the 1st-stage installer was run */
2587 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
2592 DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError());
2596 if (!SetupGetStringFieldW(&InfContext
,
2602 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2606 *pSetupData
->SourcePath
= UNICODE_NULL
;
2608 /* Close the setup INF as we are going to modify it manually */
2609 if (pSetupData
->hSetupInf
!= INVALID_HANDLE_VALUE
)
2610 SetupCloseInfFile(pSetupData
->hSetupInf
);
2613 /* Find the installation source path in Win32 format */
2614 if (!GetInstallSourceWin32(pSetupData
->SourcePath
,
2615 _countof(pSetupData
->SourcePath
),
2618 *pSetupData
->SourcePath
= UNICODE_NULL
;
2621 /* Save the path in Win32 format in the setup INF */
2622 swprintf(szValue
, L
"\"%s\"", pSetupData
->SourcePath
);
2623 WritePrivateProfileStringW(L
"data", L
"dospath", szValue
, szPath
);
2626 * Save it also in the registry, in the following keys:
2627 * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup ,
2628 * values "SourcePath" and "ServicePackSourcePath" (REG_SZ);
2629 * - HKLM\Software\Microsoft\Windows NT\CurrentVersion ,
2630 * value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386).
2633 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2634 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2639 if (res
!= ERROR_SUCCESS
)
2645 res
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2646 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
2648 REG_OPTION_NON_VOLATILE
,
2649 KEY_ALL_ACCESS
, // KEY_WRITE
2653 if (res
== ERROR_SUCCESS
)
2655 res
= RegSetValueExW(hKey
,
2659 (LPBYTE
)pSetupData
->SourcePath
,
2660 (wcslen(pSetupData
->SourcePath
) + 1) * sizeof(WCHAR
));
2662 res
= RegSetValueExW(hKey
,
2663 L
"ServicePackSourcePath",
2666 (LPBYTE
)pSetupData
->SourcePath
,
2667 (wcslen(pSetupData
->SourcePath
) + 1) * sizeof(WCHAR
));
2673 /* Now, re-open the setup INF (this must succeed) */
2674 pSetupData
->hSetupInf
= SetupOpenInfFileW(szPath
,
2678 if (pSetupData
->hSetupInf
== INVALID_HANDLE_VALUE
)
2680 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath
, GetLastError());
2684 /* Process the unattended section of the setup file */
2685 ProcessUnattendSection(pSetupData
);
2688 typedef DWORD(WINAPI
*PFNREQUESTWIZARDPAGES
)(PDWORD
, HPROPSHEETPAGE
*, PSETUPDATA
);
2693 PROPSHEETHEADER psh
= {0};
2694 HPROPSHEETPAGE
*phpage
= NULL
;
2695 PROPSHEETPAGE psp
= {0};
2699 PSETUPDATA pSetupData
= NULL
;
2700 HMODULE hNetShell
= NULL
;
2701 PFNREQUESTWIZARDPAGES pfn
= NULL
;
2702 DWORD dwPageCount
= 10, dwNetworkPageCount
= 0;
2704 LogItem(L
"BEGIN_SECTION", L
"InstallWizard");
2706 /* Allocate setup data */
2707 pSetupData
= HeapAlloc(GetProcessHeap(),
2710 if (pSetupData
== NULL
)
2712 LogItem(NULL
, L
"SetupData allocation failed!");
2714 L
"Setup failed to allocate global data!",
2716 MB_ICONERROR
| MB_OK
);
2719 pSetupData
->ProductOption
= PRODUCT_OPTION_DEFAULT
;
2721 hNetShell
= LoadLibraryW(L
"netshell.dll");
2722 if (hNetShell
!= NULL
)
2724 DPRINT("Netshell.dll loaded!\n");
2726 pfn
= (PFNREQUESTWIZARDPAGES
)GetProcAddress(hNetShell
,
2727 "NetSetupRequestWizardPages");
2730 pfn(&dwNetworkPageCount
, NULL
, NULL
);
2731 dwPageCount
+= dwNetworkPageCount
;
2735 DPRINT("PageCount: %lu\n", dwPageCount
);
2737 phpage
= HeapAlloc(GetProcessHeap(),
2739 dwPageCount
* sizeof(HPROPSHEETPAGE
));
2742 LogItem(NULL
, L
"Page array allocation failed!");
2744 L
"Setup failed to allocate page array!",
2746 MB_ICONERROR
| MB_OK
);
2750 /* Process the $winnt$.inf setup file */
2751 ProcessSetupInf(pSetupData
);
2753 /* Create the Welcome page */
2754 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2755 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2756 psp
.hInstance
= hDllInstance
;
2757 psp
.lParam
= (LPARAM
)pSetupData
;
2758 psp
.pfnDlgProc
= WelcomeDlgProc
;
2759 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2760 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2762 /* Create the Acknowledgements page */
2763 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2764 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2765 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2766 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2767 psp
.pfnDlgProc
= AckPageDlgProc
;
2768 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2770 /* Create the Product page */
2771 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2772 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PRODUCTTITLE
);
2773 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE
);
2774 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PRODUCT
);
2775 psp
.pfnDlgProc
= ProductPageDlgProc
;
2776 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2778 /* Create the Locale page */
2779 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2780 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2781 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2782 psp
.pfnDlgProc
= LocalePageDlgProc
;
2783 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2784 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2786 /* Create the Owner page */
2787 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2788 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2789 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2790 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2791 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2792 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2794 /* Create the Computer page */
2795 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2796 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2797 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2798 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2799 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2800 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2802 /* Create the DateTime page */
2803 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2804 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2805 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2806 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2807 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2808 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2810 /* Create the theme selection page */
2811 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2812 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE
);
2813 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE
);
2814 psp
.pfnDlgProc
= ThemePageDlgProc
;
2815 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_THEMEPAGE
);
2816 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2818 pSetupData
->uFirstNetworkWizardPage
= IDD_PROCESSPAGE
;
2819 pSetupData
->uPostNetworkWizardPage
= IDD_PROCESSPAGE
;
2823 pfn(&dwNetworkPageCount
, &phpage
[nPages
], pSetupData
);
2824 nPages
+= dwNetworkPageCount
;
2827 /* Create the Process page */
2828 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2829 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2830 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2831 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2832 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2833 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2835 /* Create the Finish page */
2836 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2837 psp
.pfnDlgProc
= FinishDlgProc
;
2838 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2839 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2841 ASSERT(nPages
== dwPageCount
);
2843 /* Create the property sheet */
2844 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2845 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2846 psh
.hInstance
= hDllInstance
;
2847 psh
.hwndParent
= NULL
;
2848 psh
.nPages
= nPages
;
2850 psh
.phpage
= phpage
;
2851 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2852 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2854 /* Create title font */
2855 pSetupData
->hTitleFont
= CreateTitleFont();
2856 pSetupData
->hBoldFont
= CreateBoldFont();
2858 /* Display the wizard */
2859 hWnd
= (HWND
)PropertySheet(&psh
);
2860 ShowWindow(hWnd
, SW_SHOW
);
2862 while (GetMessage(&msg
, NULL
, 0, 0))
2864 if (!IsDialogMessage(hWnd
, &msg
))
2866 TranslateMessage(&msg
);
2867 DispatchMessage(&msg
);
2871 DeleteObject(pSetupData
->hBoldFont
);
2872 DeleteObject(pSetupData
->hTitleFont
);
2874 if (pSetupData
->hSetupInf
!= INVALID_HANDLE_VALUE
)
2875 SetupCloseInfFile(pSetupData
->hSetupInf
);
2879 HeapFree(GetProcessHeap(), 0, phpage
);
2881 if (hNetShell
!= NULL
)
2882 FreeLibrary(hNetShell
);
2884 if (pSetupData
!= NULL
)
2885 HeapFree(GetProcessHeap(), 0, pSetupData
);
2887 LogItem(L
"END_SECTION", L
"InstallWizard");