ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wizard.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         System setup
00004  * FILE:            dll/win32/syssetup/wizard.c
00005  * PURPOSE:         GUI controls
00006  * PROGRAMMERS:     Eric Kohl
00007  *                  Pierre Schweitzer <heis_spiter@hotmail.com>
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include "precomp.h"
00013 
00014 #define NDEBUG
00015 #include <debug.h>
00016 
00017 #define VMWINST
00018 
00019 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
00020 /* Private Message used to communicate progress from the background
00021    registration thread to the main thread.
00022    wParam = 0 Registration in progress
00023           = 1 Registration completed
00024    lParam = Pointer to a REGISTRATIONNOTIFY structure */
00025 
00026 typedef struct _REGISTRATIONNOTIFY
00027 {
00028     ULONG Progress;
00029     UINT ActivityID;
00030     LPCWSTR CurrentItem;
00031     LPCWSTR ErrorMessage;
00032 } REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY;
00033 
00034 typedef struct _REGISTRATIONDATA
00035 {
00036     HWND hwndDlg;
00037     ULONG DllCount;
00038     ULONG Registered;
00039     PVOID DefaultContext;
00040 } REGISTRATIONDATA, *PREGISTRATIONDATA;
00041 
00042 /* GLOBALS ******************************************************************/
00043 
00044 SETUPDATA SetupData;
00045 
00046 
00047 /* FUNCTIONS ****************************************************************/
00048 BOOL
00049 GetRosInstallCD(WCHAR *pwszPath, DWORD cchPathMax);
00050 
00051 #ifdef VMWINST
00052 static BOOL
00053 RunVMWInstall(HWND hWnd)
00054 {
00055     PROCESS_INFORMATION ProcInfo;
00056     MSG msg;
00057     DWORD ret;
00058     STARTUPINFOW si = {0};
00059     WCHAR InstallName[] = L"vmwinst.exe";
00060 
00061     si.cb = sizeof(STARTUPINFO);
00062 
00063     if(CreateProcessW(NULL, InstallName, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
00064                       NULL, NULL, &si, &ProcInfo))
00065     {
00066         EnableWindow(hWnd, FALSE);
00067         for (;;)
00068         {
00069             while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
00070             {
00071                 if (msg.message == WM_QUIT)
00072                     goto done;
00073                 TranslateMessage(&msg);
00074                 DispatchMessage(&msg);
00075             }
00076 
00077             ret = MsgWaitForMultipleObjects(1, &ProcInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS | QS_ALLINPUT);
00078             if (ret == WAIT_OBJECT_0)
00079                 break;
00080         }
00081 done:
00082         EnableWindow(hWnd, TRUE);
00083 
00084         CloseHandle(ProcInfo.hThread);
00085         CloseHandle(ProcInfo.hProcess);
00086         return TRUE;
00087     }
00088     return FALSE;
00089 }
00090 #endif
00091 
00092 static VOID
00093 CenterWindow(HWND hWnd)
00094 {
00095     HWND hWndParent;
00096     RECT rcParent;
00097     RECT rcWindow;
00098 
00099     hWndParent = GetParent(hWnd);
00100     if (hWndParent == NULL)
00101         hWndParent = GetDesktopWindow();
00102 
00103     GetWindowRect(hWndParent, &rcParent);
00104     GetWindowRect(hWnd, &rcWindow);
00105 
00106     SetWindowPos(hWnd,
00107                  HWND_TOP,
00108                  ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
00109                  ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
00110                  0,
00111                  0,
00112                  SWP_NOSIZE);
00113 }
00114 
00115 
00116 static HFONT
00117 CreateTitleFont(VOID)
00118 {
00119     NONCLIENTMETRICSW ncm;
00120     LOGFONTW LogFont;
00121     HDC hdc;
00122     INT FontSize;
00123     HFONT hFont;
00124 
00125     ncm.cbSize = sizeof(NONCLIENTMETRICSW);
00126     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
00127 
00128     LogFont = ncm.lfMessageFont;
00129     LogFont.lfWeight = FW_BOLD;
00130     wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
00131 
00132     hdc = GetDC(NULL);
00133     FontSize = 12;
00134     LogFont.lfHeight = 0 - GetDeviceCaps(hdc, LOGPIXELSY) * FontSize / 72;
00135     hFont = CreateFontIndirectW(&LogFont);
00136     ReleaseDC(NULL, hdc);
00137 
00138     return hFont;
00139 }
00140 
00141 
00142 static INT_PTR CALLBACK
00143 GplDlgProc(HWND hwndDlg,
00144            UINT uMsg,
00145            WPARAM wParam,
00146            LPARAM lParam)
00147 {
00148     HRSRC GplTextResource;
00149     HGLOBAL GplTextMem;
00150     PVOID GplTextLocked;
00151     PCHAR GplText;
00152     DWORD Size;
00153 
00154 
00155     switch (uMsg)
00156     {
00157         case WM_INITDIALOG:
00158             GplTextResource = FindResourceW(hDllInstance, MAKEINTRESOURCE(IDR_GPL), L"RT_TEXT");
00159             if (NULL == GplTextResource)
00160             {
00161                 break;
00162             }
00163             Size = SizeofResource(hDllInstance, GplTextResource);
00164             if (0 == Size)
00165             {
00166                 break;
00167             }
00168             GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1);
00169             if (NULL == GplText)
00170             {
00171                 break;
00172             }
00173             GplTextMem = LoadResource(hDllInstance, GplTextResource);
00174             if (NULL == GplTextMem)
00175             {
00176                 HeapFree(GetProcessHeap(), 0, GplText);
00177                 break;
00178             }
00179             GplTextLocked = LockResource(GplTextMem);
00180             if (NULL == GplTextLocked)
00181             {
00182                 HeapFree(GetProcessHeap(), 0, GplText);
00183                 break;
00184             }
00185             memcpy(GplText, GplTextLocked, Size);
00186             GplText[Size] = '\0';
00187             SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText);
00188             HeapFree(GetProcessHeap(), 0, GplText);
00189             SetFocus(GetDlgItem(hwndDlg, IDOK));
00190             return FALSE;
00191 
00192         case WM_CLOSE:
00193             EndDialog(hwndDlg, IDCANCEL);
00194             break;
00195 
00196         case WM_COMMAND:
00197             if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam))
00198             {
00199                 EndDialog(hwndDlg, IDOK);
00200             }
00201             break;
00202 
00203         default:
00204             break;
00205     }
00206 
00207     return FALSE;
00208 }
00209 
00210 
00211 static INT_PTR CALLBACK
00212 WelcomeDlgProc(HWND hwndDlg,
00213                UINT uMsg,
00214                WPARAM wParam,
00215                LPARAM lParam)
00216 {
00217     switch (uMsg)
00218     {
00219         case WM_INITDIALOG:
00220         {
00221             PSETUPDATA SetupData;
00222             HWND hwndControl;
00223             DWORD dwStyle;
00224 
00225             /* Get pointer to the global setup data */
00226             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
00227 
00228             hwndControl = GetParent(hwndDlg);
00229 
00230             /* Center the wizard window */
00231             CenterWindow (hwndControl);
00232 
00233             /* Hide the system menu */
00234             dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
00235             SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
00236 
00237             /* Hide and disable the 'Cancel' button */
00238             hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
00239             ShowWindow (hwndControl, SW_HIDE);
00240             EnableWindow (hwndControl, FALSE);
00241 
00242             /* Set title font */
00243             SendDlgItemMessage(hwndDlg,
00244                                IDC_WELCOMETITLE,
00245                                WM_SETFONT,
00246                                (WPARAM)SetupData->hTitleFont,
00247                                (LPARAM)TRUE);
00248         }
00249         break;
00250 
00251 
00252         case WM_NOTIFY:
00253         {
00254             LPNMHDR lpnm = (LPNMHDR)lParam;
00255 
00256             switch (lpnm->code)
00257             {
00258                 case PSN_SETACTIVE:
00259                     /* Enable the Next button */
00260                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
00261                     if (SetupData.UnattendSetup)
00262                     {
00263                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_ACKPAGE);
00264                         return TRUE;
00265                     }
00266                     break;
00267 
00268                 case PSN_WIZBACK:
00269                     SetupData.UnattendSetup = FALSE;
00270                     break;
00271 
00272                 default:
00273                     break;
00274             }
00275         }
00276         break;
00277 
00278         default:
00279             break;
00280     }
00281 
00282     return FALSE;
00283 }
00284 
00285 
00286 static INT_PTR CALLBACK
00287 AckPageDlgProc(HWND hwndDlg,
00288                UINT uMsg,
00289                WPARAM wParam,
00290                LPARAM lParam)
00291 {
00292     LPNMHDR lpnm;
00293     PWCHAR Projects;
00294     PWCHAR End, CurrentProject;
00295     INT ProjectsSize, ProjectsCount;
00296 
00297     switch (uMsg)
00298     {
00299         case WM_INITDIALOG:
00300         {
00301             Projects = NULL;
00302             ProjectsSize = 256;
00303             do
00304             {
00305                 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR));
00306                 if (NULL == Projects)
00307                 {
00308                     return FALSE;
00309                 }
00310                 ProjectsCount =  LoadStringW(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize);
00311                 if (0 == ProjectsCount)
00312                 {
00313                     HeapFree(GetProcessHeap(), 0, Projects);
00314                     return FALSE;
00315                 }
00316                 if (ProjectsCount < ProjectsSize - 1)
00317                 {
00318                     break;
00319                 }
00320                 HeapFree(GetProcessHeap(), 0, Projects);
00321                 ProjectsSize *= 2;
00322             }
00323             while (1);
00324             CurrentProject = Projects;
00325             while (L'\0' != *CurrentProject)
00326             {
00327                 End = wcschr(CurrentProject, L'\n');
00328                 if (NULL != End)
00329                 {
00330                     *End = L'\0';
00331                 }
00332                 (void)ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject);
00333                 if (NULL != End)
00334                 {
00335                     CurrentProject = End + 1;
00336                 }
00337                 else
00338                 {
00339                     CurrentProject += wcslen(CurrentProject);
00340                 }
00341             }
00342             HeapFree(GetProcessHeap(), 0, Projects);
00343         }
00344         break;
00345 
00346         case WM_COMMAND:
00347             if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam))
00348             {
00349                 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc);
00350             }
00351             break;
00352 
00353         case WM_NOTIFY:
00354         {
00355             lpnm = (LPNMHDR)lParam;
00356 
00357             switch (lpnm->code)
00358             {
00359                 case PSN_SETACTIVE:
00360                     /* Enable the Back and Next buttons */
00361                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
00362                     if (SetupData.UnattendSetup)
00363                     {
00364                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_OWNERPAGE);
00365                         return TRUE;
00366                     }
00367                     break;
00368 
00369                 case PSN_WIZBACK:
00370                     SetupData.UnattendSetup = FALSE;
00371                     break;
00372 
00373                 default:
00374                     break;
00375             }
00376         }
00377         break;
00378 
00379         default:
00380             break;
00381     }
00382 
00383     return FALSE;
00384 }
00385 
00386 static
00387 BOOL
00388 WriteOwnerSettings(WCHAR * OwnerName,
00389                    WCHAR * OwnerOrganization)
00390 {
00391     HKEY hKey;
00392     LONG res;
00393 
00394 
00395 
00396     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00397                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
00398                         0,
00399                         KEY_ALL_ACCESS,
00400                         &hKey);
00401 
00402     if (res != ERROR_SUCCESS)
00403     {
00404         return FALSE;
00405     }
00406 
00407     res = RegSetValueExW(hKey,
00408                          L"RegisteredOwner",
00409                          0,
00410                          REG_SZ,
00411                          (LPBYTE)OwnerName,
00412                          (wcslen(OwnerName) + 1) * sizeof(WCHAR));
00413 
00414     if (res != ERROR_SUCCESS)
00415     {
00416         RegCloseKey(hKey);
00417         return FALSE;
00418     }
00419 
00420     res = RegSetValueExW(hKey,
00421                          L"RegisteredOrganization",
00422                          0,
00423                          REG_SZ,
00424                          (LPBYTE)OwnerOrganization,
00425                          (wcslen(OwnerOrganization) + 1) * sizeof(WCHAR));
00426 
00427     RegCloseKey(hKey);
00428     return (res == ERROR_SUCCESS);
00429 }
00430 
00431 static INT_PTR CALLBACK
00432 OwnerPageDlgProc(HWND hwndDlg,
00433                  UINT uMsg,
00434                  WPARAM wParam,
00435                  LPARAM lParam)
00436 {
00437     WCHAR OwnerName[51];
00438     WCHAR OwnerOrganization[51];
00439     WCHAR Title[64];
00440     WCHAR ErrorName[256];
00441     LPNMHDR lpnm;
00442 
00443     switch (uMsg)
00444     {
00445         case WM_INITDIALOG:
00446         {
00447             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
00448             SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
00449 
00450             /* Set focus to owner name */
00451             SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
00452         }
00453         break;
00454 
00455 
00456         case WM_NOTIFY:
00457         {
00458             lpnm = (LPNMHDR)lParam;
00459 
00460             switch (lpnm->code)
00461             {
00462                 case PSN_SETACTIVE:
00463                     /* Enable the Back and Next buttons */
00464                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
00465                     if (SetupData.UnattendSetup)
00466                     {
00467                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERNAME), WM_SETTEXT, 0, (LPARAM)SetupData.OwnerName);
00468                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERORGANIZATION), WM_SETTEXT, 0, (LPARAM)SetupData.OwnerOrganization);
00469                         if (WriteOwnerSettings(SetupData.OwnerName, SetupData.OwnerOrganization))
00470                         {
00471                             SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_COMPUTERPAGE);
00472                             return TRUE;
00473                         }
00474                     }
00475                     break;
00476 
00477                 case PSN_WIZNEXT:
00478                     OwnerName[0] = 0;
00479                     if (GetDlgItemTextW(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
00480                     {
00481                         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, sizeof(Title) / sizeof(Title[0])))
00482                         {
00483                             wcscpy(Title, L"ReactOS Setup");
00484                         }
00485                         if (0 == LoadStringW(hDllInstance, IDS_WZD_NAME, ErrorName, sizeof(ErrorName) / sizeof(ErrorName[0])))
00486                         {
00487                             wcscpy(ErrorName, L"Setup cannot continue until you enter your name.");
00488                         }
00489                         MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK);
00490 
00491                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
00492                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00493 
00494                         return TRUE;
00495                     }
00496 
00497                     OwnerOrganization[0] = 0;
00498                     GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
00499 
00500                     if (!WriteOwnerSettings(OwnerName, OwnerOrganization))
00501                     {
00502                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
00503                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00504                         return TRUE;
00505                     }
00506 
00507                 case PSN_WIZBACK:
00508                     SetupData.UnattendSetup = FALSE;
00509                     break;
00510 
00511                 default:
00512                     break;
00513             }
00514         }
00515         break;
00516 
00517         default:
00518             break;
00519     }
00520 
00521     return FALSE;
00522 }
00523 
00524 static
00525 BOOL
00526 WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg)
00527 {
00528     WCHAR Title[64];
00529     WCHAR ErrorComputerName[256];
00530     if (!SetComputerNameW(ComputerName))
00531     {
00532         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, sizeof(Title) / sizeof(Title[0])))
00533         {
00534             wcscpy(Title, L"ReactOS Setup");
00535         }
00536         if (0 == LoadStringW(hDllInstance, IDS_WZD_SETCOMPUTERNAME, ErrorComputerName,
00537                              sizeof(ErrorComputerName) / sizeof(ErrorComputerName[0])))
00538         {
00539             wcscpy(ErrorComputerName, L"Setup failed to set the computer name.");
00540         }
00541         MessageBoxW(hwndDlg, ErrorComputerName, Title, MB_ICONERROR | MB_OK);
00542 
00543         return FALSE;
00544     }
00545 
00546     /* Try to also set DNS hostname */
00547     SetComputerNameExW(ComputerNamePhysicalDnsHostname, ComputerName);
00548 
00549     /* Set the account domain name */
00550     SetAccountDomain(ComputerName, NULL);
00551 
00552     return TRUE;
00553 }
00554 
00555 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
00556 static void
00557 GenerateComputerName(LPWSTR lpBuffer)
00558 {
00559     static const WCHAR Chars[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00560     static const unsigned cChars = sizeof(Chars) / sizeof(WCHAR) - 1;
00561     unsigned i;
00562 
00563     wcscpy(lpBuffer, L"REACTOS-");
00564 
00565     srand(GetTickCount());
00566 
00567     /* fill in 7 characters */
00568     for (i = 8; i < 15; i++)
00569         lpBuffer[i] = Chars[rand() % cChars];
00570 
00571     lpBuffer[15] = UNICODE_NULL; /* NULL-terminate */
00572 }
00573 
00574 static INT_PTR CALLBACK
00575 ComputerPageDlgProc(HWND hwndDlg,
00576                     UINT uMsg,
00577                     WPARAM wParam,
00578                     LPARAM lParam)
00579 {
00580     WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
00581     WCHAR Password1[15];
00582     WCHAR Password2[15];
00583     PWCHAR Password;
00584     WCHAR Title[64];
00585     WCHAR EmptyComputerName[256], NotMatchPassword[256], WrongPassword[256];
00586     LPNMHDR lpnm;
00587 
00588     if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, sizeof(Title) / sizeof(Title[0])))
00589     {
00590         wcscpy(Title, L"ReactOS Setup");
00591     }
00592 
00593     switch (uMsg)
00594     {
00595         case WM_INITDIALOG:
00596         {
00597             /* Generate a new pseudo-random computer name */
00598             GenerateComputerName(ComputerName);
00599 
00600             /* Display current computer name */
00601             SetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName);
00602 
00603             /* Set text limits */
00604             SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
00605             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 14, 0);
00606             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 14, 0);
00607 
00608             /* Set focus to computer name */
00609             SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
00610             if (SetupData.UnattendSetup)
00611             {
00612                 SendMessage(GetDlgItem(hwndDlg, IDC_COMPUTERNAME), WM_SETTEXT, 0, (LPARAM)SetupData.ComputerName);
00613                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD1), WM_SETTEXT, 0, (LPARAM)SetupData.AdminPassword);
00614                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD2), WM_SETTEXT, 0, (LPARAM)SetupData.AdminPassword);
00615             }
00616 
00617         }
00618         break;
00619 
00620 
00621         case WM_NOTIFY:
00622         {
00623             lpnm = (LPNMHDR)lParam;
00624 
00625             switch (lpnm->code)
00626             {
00627                 case PSN_SETACTIVE:
00628                     /* Enable the Back and Next buttons */
00629                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
00630                     if (SetupData.UnattendSetup && WriteComputerSettings(SetupData.ComputerName, hwndDlg))
00631                     {
00632                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_LOCALEPAGE);
00633                         return TRUE;
00634                     }
00635                     break;
00636 
00637                 case PSN_WIZNEXT:
00638                     if (0 == GetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName, MAX_COMPUTERNAME_LENGTH + 1))
00639                     {
00640                         if (0 == LoadStringW(hDllInstance, IDS_WZD_COMPUTERNAME, EmptyComputerName,
00641                                              sizeof(EmptyComputerName) / sizeof(EmptyComputerName[0])))
00642                         {
00643                             wcscpy(EmptyComputerName, L"Setup cannot continue until you enter the name of your computer.");
00644                         }
00645                         MessageBoxW(hwndDlg, EmptyComputerName, Title, MB_ICONERROR | MB_OK);
00646                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
00647                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00648                         return TRUE;
00649                     }
00650 
00651                     /* No need to check computer name for invalid characters,
00652                      * SetComputerName() will do it for us */
00653 
00654                     if (!WriteComputerSettings(ComputerName, hwndDlg))
00655                     {
00656                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
00657                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00658                         return TRUE;
00659                     }
00660 
00661 #if 0
00662                     /* Check if admin passwords have been entered */
00663                     if ((GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 15) == 0) ||
00664                             (GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 15) == 0))
00665                     {
00666                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDEMPTY, EmptyPassword,
00667                                              sizeof(EmptyPassword) / sizeof(EmptyPassword[0])))
00668                         {
00669                             wcscpy(EmptyPassword, L"You must enter a password !");
00670                         }
00671                         MessageBoxW(hwndDlg, EmptyPassword, Title, MB_ICONERROR | MB_OK);
00672                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00673                         return TRUE;
00674                     }
00675 #else
00676                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD1, Password1, 15);
00677                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD2, Password2, 15);
00678 #endif
00679                     /* Check if passwords match */
00680                     if (wcscmp(Password1, Password2))
00681                     {
00682                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDMATCH, NotMatchPassword,
00683                                              sizeof(NotMatchPassword) / sizeof(NotMatchPassword[0])))
00684                         {
00685                             wcscpy(NotMatchPassword, L"The passwords you entered do not match. Please enter the desired password again.");
00686                         }
00687                         MessageBoxW(hwndDlg, NotMatchPassword, Title, MB_ICONERROR | MB_OK);
00688                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00689                         return TRUE;
00690                     }
00691 
00692                     /* Check password for invalid characters */
00693                     Password = (PWCHAR)Password1;
00694                     while (*Password)
00695                     {
00696                         if (!isprint(*Password))
00697                         {
00698                             if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDCHAR, WrongPassword,
00699                                                  sizeof(WrongPassword) / sizeof(WrongPassword[0])))
00700                             {
00701                                 wcscpy(WrongPassword, L"The password you entered contains invalid characters. Please enter a cleaned password.");
00702                             }
00703                             MessageBoxW(hwndDlg, WrongPassword, Title, MB_ICONERROR | MB_OK);
00704                             SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
00705                             return TRUE;
00706                         }
00707                         Password++;
00708                     }
00709 
00710                     /* FIXME: Set admin password */
00711                     break;
00712 
00713                 case PSN_WIZBACK:
00714                     SetupData.UnattendSetup = FALSE;
00715                     break;
00716 
00717                 default:
00718                     break;
00719             }
00720         }
00721         break;
00722 
00723         default:
00724             break;
00725     }
00726 
00727     return FALSE;
00728 }
00729 
00730 
00731 static VOID
00732 SetKeyboardLayoutName(HWND hwnd)
00733 {
00734 #if 0
00735     TCHAR szLayoutPath[256];
00736     TCHAR szLocaleName[32];
00737     DWORD dwLocaleSize;
00738     HKEY hKey;
00739 
00740     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00741                      _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
00742                      0,
00743                      KEY_ALL_ACCESS,
00744                      &hKey))
00745         return;
00746 
00747     dwValueSize = 16 * sizeof(TCHAR);
00748     if (RegQueryValueEx(hKey,
00749                         NULL,
00750                         NULL,
00751                         NULL,
00752                         szLocaleName,
00753                         &dwLocaleSize))
00754     {
00755         RegCloseKey(hKey);
00756         return;
00757     }
00758 
00759     _tcscpy(szLayoutPath,
00760             _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
00761     _tcscat(szLayoutPath,
00762             szLocaleName);
00763 
00764     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00765                      szLayoutPath,
00766                      0,
00767                      KEY_ALL_ACCESS,
00768                      &hKey))
00769         return;
00770 
00771     dwValueSize = 32 * sizeof(TCHAR);
00772     if (RegQueryValueEx(hKey,
00773                         _T("Layout Text"),
00774                         NULL,
00775                         NULL,
00776                         szLocaleName,
00777                         &dwLocaleSize))
00778     {
00779         RegCloseKey(hKey);
00780         return;
00781     }
00782 
00783     RegCloseKey(hKey);
00784 #endif
00785 }
00786 
00787 
00788 static BOOL
00789 RunControlPanelApplet(HWND hwnd, WCHAR *lpCommandLine)
00790 {
00791     STARTUPINFOW StartupInfo;
00792     PROCESS_INFORMATION ProcessInformation;
00793 
00794     ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
00795     StartupInfo.cb = sizeof(STARTUPINFOW);
00796 
00797     if (!CreateProcessW(NULL,
00798                         lpCommandLine,
00799                         NULL,
00800                         NULL,
00801                         FALSE,
00802                         0,
00803                         NULL,
00804                         NULL,
00805                         &StartupInfo,
00806                         &ProcessInformation))
00807     {
00808         MessageBoxW(hwnd, L"Error: failed to launch rundll32", NULL, MB_ICONERROR);
00809         return FALSE;
00810     }
00811 
00812     WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
00813     CloseHandle(ProcessInformation.hThread);
00814     CloseHandle(ProcessInformation.hProcess);
00815     return TRUE;
00816 }
00817 
00818 static VOID
00819 WriteUserLocale(VOID)
00820 {
00821     HKEY hKey;
00822     LCID lcid;
00823     WCHAR Locale[12];
00824 
00825     lcid = GetSystemDefaultLCID();
00826 
00827     if (GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Locale, sizeof(Locale) / sizeof(Locale[0])) != 0)
00828     {
00829         if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Control Panel\\International",
00830                             0, NULL, REG_OPTION_NON_VOLATILE,
00831                             KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
00832         {
00833             RegSetValueExW(hKey, L"Locale", 0, REG_SZ, (LPBYTE)Locale, (wcslen(Locale) + 1) * sizeof(WCHAR));
00834             RegCloseKey(hKey);
00835         }
00836     }
00837 }
00838 
00839 static INT_PTR CALLBACK
00840 LocalePageDlgProc(HWND hwndDlg,
00841                   UINT uMsg,
00842                   WPARAM wParam,
00843                   LPARAM lParam)
00844 {
00845     PSETUPDATA SetupData;
00846 
00847     /* Retrieve pointer to the global setup data */
00848     SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
00849 
00850     switch (uMsg)
00851     {
00852         case WM_INITDIALOG:
00853         {
00854             /* Save pointer to the global setup data */
00855             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
00856             SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
00857             WriteUserLocale();
00858 
00859             SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
00860         }
00861         break;
00862 
00863         case WM_COMMAND:
00864             if (HIWORD(wParam) == BN_CLICKED)
00865             {
00866                 switch (LOWORD(wParam))
00867                 {
00868                     case IDC_CUSTOMLOCALE:
00869                         RunControlPanelApplet(hwndDlg, L"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,5");
00870                         /* FIXME: Update input locale name */
00871                         break;
00872 
00873                     case IDC_CUSTOMLAYOUT:
00874                         RunControlPanelApplet(hwndDlg, L"rundll32.exe shell32.dll,Control_RunDLL input.dll,@1");
00875                         break;
00876                 }
00877             }
00878             break;
00879 
00880         case WM_NOTIFY:
00881         {
00882             LPNMHDR lpnm = (LPNMHDR)lParam;
00883 
00884             switch (lpnm->code)
00885             {
00886                 case PSN_SETACTIVE:
00887                     /* Enable the Back and Next buttons */
00888                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
00889                     if (SetupData->UnattendSetup)
00890                     {
00891                         WCHAR wszPath[MAX_PATH], wszBuf[1024];
00892                         if (GetRosInstallCD(wszPath, _countof(wszPath)))
00893                             swprintf(wszBuf, L"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath);
00894                         else
00895                             wcscpy(wszBuf, L"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"unattend.inf\"");
00896 
00897                         RunControlPanelApplet(hwndDlg, wszBuf);
00898                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_DATETIMEPAGE);
00899                         return TRUE;
00900                     }
00901                     break;
00902 
00903                 case PSN_WIZNEXT:
00904                     break;
00905 
00906                 case PSN_WIZBACK:
00907                     SetupData->UnattendSetup = FALSE;
00908                     break;
00909 
00910                 default:
00911                     break;
00912             }
00913         }
00914         break;
00915 
00916         default:
00917             break;
00918     }
00919 
00920     return FALSE;
00921 }
00922 
00923 
00924 static PTIMEZONE_ENTRY
00925 GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
00926 {
00927     PTIMEZONE_ENTRY Entry;
00928 
00929     Entry = SetupData->TimeZoneListHead;
00930     while (Entry != NULL)
00931     {
00932         if (Entry->Index >= Index)
00933             return Entry;
00934 
00935         Entry = Entry->Next;
00936     }
00937 
00938     return NULL;
00939 }
00940 
00941 
00942 static VOID
00943 CreateTimeZoneList(PSETUPDATA SetupData)
00944 {
00945     WCHAR szKeyName[256];
00946     DWORD dwIndex;
00947     DWORD dwNameSize;
00948     DWORD dwValueSize;
00949     LONG lError;
00950     HKEY hZonesKey;
00951     HKEY hZoneKey;
00952 
00953     PTIMEZONE_ENTRY Entry;
00954     PTIMEZONE_ENTRY Current;
00955 
00956     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00957                       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
00958                       0,
00959                       KEY_ALL_ACCESS,
00960                       &hZonesKey))
00961         return;
00962 
00963     dwIndex = 0;
00964     while (TRUE)
00965     {
00966         dwNameSize = 256 * sizeof(WCHAR);
00967         lError = RegEnumKeyExW(hZonesKey,
00968                                dwIndex,
00969                                szKeyName,
00970                                &dwNameSize,
00971                                NULL,
00972                                NULL,
00973                                NULL,
00974                                NULL);
00975         if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
00976             break;
00977 
00978         if (RegOpenKeyExW(hZonesKey,
00979                           szKeyName,
00980                           0,
00981                           KEY_ALL_ACCESS,
00982                           &hZoneKey))
00983             break;
00984 
00985         Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
00986         if (Entry == NULL)
00987         {
00988             RegCloseKey(hZoneKey);
00989             break;
00990         }
00991 
00992         dwValueSize = 64 * sizeof(WCHAR);
00993         if (RegQueryValueExW(hZoneKey,
00994                              L"Display",
00995                              NULL,
00996                              NULL,
00997                              (LPBYTE)&Entry->Description,
00998                              &dwValueSize))
00999         {
01000             RegCloseKey(hZoneKey);
01001             break;
01002         }
01003 
01004         dwValueSize = 32 * sizeof(WCHAR);
01005         if (RegQueryValueExW(hZoneKey,
01006                              L"Std",
01007                              NULL,
01008                              NULL,
01009                              (LPBYTE)&Entry->StandardName,
01010                              &dwValueSize))
01011         {
01012             RegCloseKey(hZoneKey);
01013             break;
01014         }
01015 
01016         dwValueSize = 32 * sizeof(WCHAR);
01017         if (RegQueryValueExW(hZoneKey,
01018                              L"Dlt",
01019                              NULL,
01020                              NULL,
01021                              (LPBYTE)&Entry->DaylightName,
01022                              &dwValueSize))
01023         {
01024             RegCloseKey(hZoneKey);
01025             break;
01026         }
01027 
01028         dwValueSize = sizeof(DWORD);
01029         if (RegQueryValueExW(hZoneKey,
01030                              L"Index",
01031                              NULL,
01032                              NULL,
01033                              (LPBYTE)&Entry->Index,
01034                              &dwValueSize))
01035         {
01036             RegCloseKey(hZoneKey);
01037             break;
01038         }
01039 
01040         dwValueSize = sizeof(TZ_INFO);
01041         if (RegQueryValueExW(hZoneKey,
01042                              L"TZI",
01043                              NULL,
01044                              NULL,
01045                              (LPBYTE)&Entry->TimezoneInfo,
01046                              &dwValueSize))
01047         {
01048             RegCloseKey(hZoneKey);
01049             break;
01050         }
01051 
01052         RegCloseKey(hZoneKey);
01053 
01054         if (SetupData->TimeZoneListHead == NULL &&
01055                 SetupData->TimeZoneListTail == NULL)
01056         {
01057             Entry->Prev = NULL;
01058             Entry->Next = NULL;
01059             SetupData->TimeZoneListHead = Entry;
01060             SetupData->TimeZoneListTail = Entry;
01061         }
01062         else
01063         {
01064             Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
01065             if (Current != NULL)
01066             {
01067                 if (Current == SetupData->TimeZoneListHead)
01068                 {
01069                     /* Prepend to head */
01070                     Entry->Prev = NULL;
01071                     Entry->Next = SetupData->TimeZoneListHead;
01072                     SetupData->TimeZoneListHead->Prev = Entry;
01073                     SetupData->TimeZoneListHead = Entry;
01074                 }
01075                 else
01076                 {
01077                     /* Insert before current */
01078                     Entry->Prev = Current->Prev;
01079                     Entry->Next = Current;
01080                     Current->Prev->Next = Entry;
01081                     Current->Prev = Entry;
01082                 }
01083             }
01084             else
01085             {
01086                 /* Append to tail */
01087                 Entry->Prev = SetupData->TimeZoneListTail;
01088                 Entry->Next = NULL;
01089                 SetupData->TimeZoneListTail->Next = Entry;
01090                 SetupData->TimeZoneListTail = Entry;
01091             }
01092         }
01093 
01094         dwIndex++;
01095     }
01096 
01097     RegCloseKey(hZonesKey);
01098 }
01099 
01100 
01101 static VOID
01102 DestroyTimeZoneList(PSETUPDATA SetupData)
01103 {
01104     PTIMEZONE_ENTRY Entry;
01105 
01106     while (SetupData->TimeZoneListHead != NULL)
01107     {
01108         Entry = SetupData->TimeZoneListHead;
01109 
01110         SetupData->TimeZoneListHead = Entry->Next;
01111         if (SetupData->TimeZoneListHead != NULL)
01112         {
01113             SetupData->TimeZoneListHead->Prev = NULL;
01114         }
01115 
01116         HeapFree(GetProcessHeap(), 0, Entry);
01117     }
01118 
01119     SetupData->TimeZoneListTail = NULL;
01120 }
01121 
01122 static BOOL
01123 GetTimeZoneListIndex(LPDWORD lpIndex)
01124 {
01125     WCHAR szLanguageIdString[9];
01126     HKEY hKey;
01127     DWORD dwValueSize;
01128     DWORD Length;
01129     LPWSTR Buffer;
01130     LPWSTR Ptr;
01131     LPWSTR End;
01132     BOOL bFound = FALSE;
01133     unsigned long iLanguageID;
01134 
01135     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
01136                       L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
01137                       0,
01138                       KEY_ALL_ACCESS,
01139                       &hKey))
01140         return FALSE;
01141 
01142     dwValueSize = 9 * sizeof(WCHAR);
01143     if (RegQueryValueExW(hKey,
01144                          L"Default",
01145                          NULL,
01146                          NULL,
01147                          (LPBYTE)szLanguageIdString,
01148                          &dwValueSize))
01149     {
01150         RegCloseKey(hKey);
01151         return FALSE;
01152     }
01153 
01154     iLanguageID = wcstoul(szLanguageIdString, NULL, 16);
01155     RegCloseKey(hKey);
01156 
01157     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
01158                       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
01159                       0,
01160                       KEY_ALL_ACCESS,
01161                       &hKey))
01162         return FALSE;
01163 
01164     dwValueSize = 0;
01165     if (RegQueryValueExW(hKey,
01166                          L"IndexMapping",
01167                          NULL,
01168                          NULL,
01169                          NULL,
01170                          &dwValueSize))
01171     {
01172         RegCloseKey(hKey);
01173         return FALSE;
01174     }
01175 
01176     Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
01177     if (Buffer == NULL)
01178     {
01179         RegCloseKey(hKey);
01180         return FALSE;
01181     }
01182 
01183     if (RegQueryValueExW(hKey,
01184                          L"IndexMapping",
01185                          NULL,
01186                          NULL,
01187                          (LPBYTE)Buffer,
01188                          &dwValueSize))
01189     {
01190         HeapFree(GetProcessHeap(), 0, Buffer);
01191         RegCloseKey(hKey);
01192         return FALSE;
01193     }
01194 
01195     RegCloseKey(hKey);
01196 
01197     Ptr = Buffer;
01198     while (*Ptr != 0)
01199     {
01200         Length = wcslen(Ptr);
01201         if (wcstoul(Ptr, NULL, 16) == iLanguageID)
01202             bFound = TRUE;
01203 
01204         Ptr = Ptr + Length + 1;
01205         if (*Ptr == 0)
01206             break;
01207 
01208         if (bFound)
01209         {
01210             *lpIndex = wcstoul(Ptr, &End, 10);
01211             HeapFree(GetProcessHeap(), 0, Buffer);
01212             return TRUE;
01213         }
01214 
01215         Length = wcslen(Ptr);
01216         Ptr = Ptr + Length + 1;
01217     }
01218 
01219     HeapFree(GetProcessHeap(), 0, Buffer);
01220 
01221     return FALSE;
01222 }
01223 
01224 
01225 static VOID
01226 ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex)
01227 {
01228     PTIMEZONE_ENTRY Entry;
01229     DWORD dwIndex = 0;
01230     DWORD dwCount;
01231 
01232     GetTimeZoneListIndex(&dwEntryIndex);
01233 
01234     Entry = SetupData->TimeZoneListHead;
01235     while (Entry != NULL)
01236     {
01237         dwCount = SendMessage(hwnd,
01238                               CB_ADDSTRING,
01239                               0,
01240                               (LPARAM)Entry->Description);
01241 
01242         if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index)
01243             dwIndex = dwCount;
01244 
01245         Entry = Entry->Next;
01246     }
01247 
01248     SendMessage(hwnd,
01249                 CB_SETCURSEL,
01250                 (WPARAM)dwIndex,
01251                 0);
01252 }
01253 
01254 
01255 static VOID
01256 SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
01257 {
01258     TIME_ZONE_INFORMATION TimeZoneInformation;
01259     PTIMEZONE_ENTRY Entry;
01260     DWORD dwIndex;
01261     DWORD i;
01262 
01263     dwIndex = SendMessage(hwnd,
01264                           CB_GETCURSEL,
01265                           0,
01266                           0);
01267 
01268     i = 0;
01269     Entry = SetupData->TimeZoneListHead;
01270     while (i < dwIndex)
01271     {
01272         if (Entry == NULL)
01273             return;
01274 
01275         i++;
01276         Entry = Entry->Next;
01277     }
01278 
01279     wcscpy(TimeZoneInformation.StandardName,
01280            Entry->StandardName);
01281     wcscpy(TimeZoneInformation.DaylightName,
01282            Entry->DaylightName);
01283 
01284     TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
01285     TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
01286     TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
01287 
01288     memcpy(&TimeZoneInformation.StandardDate,
01289            &Entry->TimezoneInfo.StandardDate,
01290            sizeof(SYSTEMTIME));
01291     memcpy(&TimeZoneInformation.DaylightDate,
01292            &Entry->TimezoneInfo.DaylightDate,
01293            sizeof(SYSTEMTIME));
01294 
01295     /* Set time zone information */
01296     SetTimeZoneInformation(&TimeZoneInformation);
01297 }
01298 
01299 
01300 static BOOL
01301 GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
01302 {
01303     SYSTEMTIME Date;
01304     SYSTEMTIME Time;
01305 
01306     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
01307     {
01308         return FALSE;
01309     }
01310 
01311     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
01312     {
01313         return FALSE;
01314     }
01315 
01316     SetupData->SystemTime.wYear = Date.wYear;
01317     SetupData->SystemTime.wMonth = Date.wMonth;
01318     SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
01319     SetupData->SystemTime.wDay = Date.wDay;
01320     SetupData->SystemTime.wHour = Time.wHour;
01321     SetupData->SystemTime.wMinute = Time.wMinute;
01322     SetupData->SystemTime.wSecond = Time.wSecond;
01323     SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
01324 
01325     return TRUE;
01326 }
01327 
01328 
01329 static VOID
01330 SetAutoDaylightInfo(HWND hwnd)
01331 {
01332     HKEY hKey;
01333     DWORD dwValue = 1;
01334 
01335     if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
01336     {
01337         if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
01338                           L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
01339                           0,
01340                           KEY_SET_VALUE,
01341                           &hKey))
01342             return;
01343 
01344         RegSetValueExW(hKey,
01345                        L"DisableAutoDaylightTimeSet",
01346                        0,
01347                        REG_DWORD,
01348                        (LPBYTE)&dwValue,
01349                        sizeof(DWORD));
01350         RegCloseKey(hKey);
01351     }
01352 }
01353 
01354 
01355 static BOOL
01356 SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
01357 {
01358     HANDLE hToken;
01359     DWORD PrevSize;
01360     TOKEN_PRIVILEGES priv, previouspriv;
01361     BOOL Ret = FALSE;
01362 
01363     /*
01364      * enable the SeSystemtimePrivilege privilege
01365      */
01366 
01367     if(OpenProcessToken(GetCurrentProcess(),
01368                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
01369                         &hToken))
01370     {
01371         priv.PrivilegeCount = 1;
01372         priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
01373 
01374         if(LookupPrivilegeValue(NULL,
01375                                 SE_SYSTEMTIME_NAME,
01376                                 &priv.Privileges[0].Luid))
01377         {
01378             if(AdjustTokenPrivileges(hToken,
01379                                      FALSE,
01380                                      &priv,
01381                                      sizeof(previouspriv),
01382                                      &previouspriv,
01383                                      &PrevSize) &&
01384                     GetLastError() == ERROR_SUCCESS)
01385             {
01386                 /*
01387                  * We successfully enabled it, we're permitted to change the system time
01388                  * Call SetLocalTime twice to ensure correct results
01389                  */
01390                 Ret = SetLocalTime(&SetupData->SystemTime) &&
01391                       SetLocalTime(&SetupData->SystemTime);
01392 
01393                 /*
01394                  * for the sake of security, restore the previous status again
01395                  */
01396                 if(previouspriv.PrivilegeCount > 0)
01397                 {
01398                     AdjustTokenPrivileges(hToken,
01399                                           FALSE,
01400                                           &previouspriv,
01401                                           0,
01402                                           NULL,
01403                                           0);
01404                 }
01405             }
01406         }
01407         CloseHandle(hToken);
01408     }
01409 
01410     return Ret;
01411 }
01412 
01413 static BOOL
01414 WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData)
01415 {
01416     WCHAR Title[64];
01417     WCHAR ErrorLocalTime[256];
01418     GetLocalSystemTime(hwndDlg, SetupData);
01419     SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
01420                      SetupData);
01421 
01422     SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
01423     if(!SetSystemLocalTime(hwndDlg, SetupData))
01424     {
01425         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, sizeof(Title) / sizeof(Title[0])))
01426         {
01427             wcscpy(Title, L"ReactOS Setup");
01428         }
01429         if (0 == LoadStringW(hDllInstance, IDS_WZD_LOCALTIME, ErrorLocalTime,
01430                              sizeof(ErrorLocalTime) / sizeof(ErrorLocalTime[0])))
01431         {
01432             wcscpy(ErrorLocalTime, L"Setup was unable to set the local time.");
01433         }
01434         MessageBoxW(hwndDlg, ErrorLocalTime, Title, MB_ICONWARNING | MB_OK);
01435         return FALSE;
01436     }
01437 
01438     return TRUE;
01439 }
01440 
01441 static INT_PTR CALLBACK
01442 DateTimePageDlgProc(HWND hwndDlg,
01443                     UINT uMsg,
01444                     WPARAM wParam,
01445                     LPARAM lParam)
01446 {
01447     PSETUPDATA SetupData;
01448 
01449     /* Retrieve pointer to the global setup data */
01450     SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
01451 
01452     switch (uMsg)
01453     {
01454         case WM_INITDIALOG:
01455         {
01456             /* Save pointer to the global setup data */
01457             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
01458             SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
01459 
01460             CreateTimeZoneList(SetupData);
01461 
01462             if (SetupData->UnattendSetup)
01463             {
01464                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
01465                                  SetupData, SetupData->TimeZoneIndex);
01466 
01467                 if (!SetupData->DisableAutoDaylightTimeSet)
01468                 {
01469                     SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
01470                 }
01471             }
01472             else
01473             {
01474                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
01475                                  SetupData, 85 /* GMT time zone */);
01476 
01477                 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
01478             }
01479 
01480         }
01481         break;
01482 
01483 
01484         case WM_NOTIFY:
01485         {
01486             LPNMHDR lpnm = (LPNMHDR)lParam;
01487 
01488             switch (lpnm->code)
01489             {
01490                 case PSN_SETACTIVE:
01491                     /* Enable the Back and Next buttons */
01492                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
01493                     if (SetupData->UnattendSetup && WriteDateTimeSettings(hwndDlg, SetupData))
01494                     {
01495                         SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_PROCESSPAGE);
01496                         return TRUE;
01497                     }
01498                     break;
01499 
01500                 case PSN_WIZNEXT:
01501                 {
01502                     WriteDateTimeSettings(hwndDlg, SetupData);
01503                 }
01504                 break;
01505 
01506                 case PSN_WIZBACK:
01507                     SetupData->UnattendSetup = FALSE;
01508                     break;
01509 
01510                 default:
01511                     break;
01512             }
01513         }
01514         break;
01515 
01516         case WM_DESTROY:
01517             DestroyTimeZoneList(SetupData);
01518             break;
01519 
01520         default:
01521             break;
01522     }
01523 
01524     return FALSE;
01525 }
01526 
01527 
01528 static UINT CALLBACK
01529 RegistrationNotificationProc(PVOID Context,
01530                              UINT Notification,
01531                              UINT_PTR Param1,
01532                              UINT_PTR Param2)
01533 {
01534     PREGISTRATIONDATA RegistrationData;
01535     REGISTRATIONNOTIFY RegistrationNotify;
01536     PSP_REGISTER_CONTROL_STATUSW StatusInfo;
01537     UINT MessageID;
01538     WCHAR ErrorMessage[128];
01539 
01540     RegistrationData = (PREGISTRATIONDATA) Context;
01541 
01542     if (SPFILENOTIFY_STARTREGISTRATION == Notification ||
01543             SPFILENOTIFY_ENDREGISTRATION == Notification)
01544     {
01545         StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1;
01546         RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\');
01547         if (NULL == RegistrationNotify.CurrentItem)
01548         {
01549             RegistrationNotify.CurrentItem = StatusInfo->FileName;
01550         }
01551         else
01552         {
01553             RegistrationNotify.CurrentItem++;
01554         }
01555 
01556         if (SPFILENOTIFY_STARTREGISTRATION == Notification)
01557         {
01558             DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
01559                    StatusInfo->FileName);
01560             RegistrationNotify.ErrorMessage = NULL;
01561             RegistrationNotify.Progress = RegistrationData->Registered;
01562         }
01563         else
01564         {
01565             DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
01566                    StatusInfo->FileName);
01567             DPRINT("Win32Error %u FailureCode %u\n", StatusInfo->Win32Error,
01568                    StatusInfo->FailureCode);
01569             if (SPREG_SUCCESS != StatusInfo->FailureCode)
01570             {
01571                 switch(StatusInfo->FailureCode)
01572                 {
01573                     case SPREG_LOADLIBRARY:
01574                         MessageID = IDS_LOADLIBRARY_FAILED;
01575                         break;
01576                     case SPREG_GETPROCADDR:
01577                         MessageID = IDS_GETPROCADDR_FAILED;
01578                         break;
01579                     case SPREG_REGSVR:
01580                         MessageID = IDS_REGSVR_FAILED;
01581                         break;
01582                     case SPREG_DLLINSTALL:
01583                         MessageID = IDS_DLLINSTALL_FAILED;
01584                         break;
01585                     case SPREG_TIMEOUT:
01586                         MessageID = IDS_TIMEOUT;
01587                         break;
01588                     default:
01589                         MessageID = IDS_REASON_UNKNOWN;
01590                         break;
01591                 }
01592                 if (0 == LoadStringW(hDllInstance, MessageID,
01593                                      ErrorMessage,
01594                                      sizeof(ErrorMessage) /
01595                                      sizeof(ErrorMessage[0])))
01596                 {
01597                     ErrorMessage[0] = L'\0';
01598                 }
01599                 if (SPREG_TIMEOUT != StatusInfo->FailureCode)
01600                 {
01601                     FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
01602                                    StatusInfo->Win32Error, 0,
01603                                    ErrorMessage + wcslen(ErrorMessage),
01604                                    sizeof(ErrorMessage) / sizeof(ErrorMessage[0]) -
01605                                    wcslen(ErrorMessage), NULL);
01606                 }
01607                 RegistrationNotify.ErrorMessage = ErrorMessage;
01608             }
01609             else
01610             {
01611                 RegistrationNotify.ErrorMessage = NULL;
01612             }
01613             if (RegistrationData->Registered < RegistrationData->DllCount)
01614             {
01615                 RegistrationData->Registered++;
01616             }
01617         }
01618 
01619         RegistrationNotify.Progress = RegistrationData->Registered;
01620         RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS;
01621         SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY,
01622                     0, (LPARAM) &RegistrationNotify);
01623 
01624         return FILEOP_DOIT;
01625     }
01626     else
01627     {
01628         DPRINT1("Received unexpected notification %u\n", Notification);
01629         return SetupDefaultQueueCallback(RegistrationData->DefaultContext,
01630                                          Notification, Param1, Param2);
01631     }
01632 }
01633 
01634 
01635 static DWORD CALLBACK
01636 RegistrationProc(LPVOID Parameter)
01637 {
01638     PREGISTRATIONDATA RegistrationData;
01639     REGISTRATIONNOTIFY RegistrationNotify;
01640     DWORD LastError = NO_ERROR;
01641     WCHAR UnknownError[84];
01642 
01643     RegistrationData = (PREGISTRATIONDATA) Parameter;
01644     RegistrationData->Registered = 0;
01645     RegistrationData->DefaultContext = SetupInitDefaultQueueCallback(RegistrationData->hwndDlg);
01646 
01647     _SEH2_TRY
01648     {
01649         if (!SetupInstallFromInfSectionW(GetParent(RegistrationData->hwndDlg),
01650         hSysSetupInf,
01651         L"RegistrationPhase2",
01652         SPINST_REGISTRY |
01653         SPINST_REGISTERCALLBACKAWARE  |
01654         SPINST_REGSVR,
01655         0,
01656         NULL,
01657         0,
01658         RegistrationNotificationProc,
01659         RegistrationData,
01660         NULL,
01661         NULL))
01662         {
01663             LastError = GetLastError();
01664         }
01665     }
01666     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
01667     {
01668         DPRINT("Catching exception\n");
01669         LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode());
01670     }
01671     _SEH2_END;
01672 
01673     if (NO_ERROR == LastError)
01674     {
01675         RegistrationNotify.ErrorMessage = NULL;
01676     }
01677     else
01678     {
01679         DPRINT1("SetupInstallFromInfSection failed with error %u\n",
01680                 LastError);
01681         if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
01682                                 FORMAT_MESSAGE_FROM_SYSTEM, NULL, LastError, 0,
01683                                 (LPWSTR) &RegistrationNotify.ErrorMessage, 0,
01684                                 NULL))
01685         {
01686             if (0 == LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
01687                                  UnknownError,
01688                                  sizeof(UnknownError) / sizeof(UnknownError[0]) -
01689                                  20))
01690             {
01691                 wcscpy(UnknownError, L"Unknown error");
01692             }
01693             wcscat(UnknownError, L" ");
01694             _ultow(LastError, UnknownError + wcslen(UnknownError), 10);
01695             RegistrationNotify.ErrorMessage = UnknownError;
01696         }
01697     }
01698 
01699     RegistrationNotify.Progress = RegistrationData->DllCount;
01700     RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS;
01701     RegistrationNotify.CurrentItem = NULL;
01702     SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY,
01703                 1, (LPARAM) &RegistrationNotify);
01704     if (NULL != RegistrationNotify.ErrorMessage &&
01705             UnknownError != RegistrationNotify.ErrorMessage)
01706     {
01707         LocalFree((PVOID) RegistrationNotify.ErrorMessage);
01708     }
01709 
01710     SetupTermDefaultQueueCallback(RegistrationData->DefaultContext);
01711     HeapFree(GetProcessHeap(), 0, RegistrationData);
01712 
01713     // FIXME: Move this call to a separate cleanup page!
01714     RtlCreateBootStatusDataFile();
01715 
01716     return 0;
01717 }
01718 
01719 
01720 static BOOL
01721 StartComponentRegistration(HWND hwndDlg, PULONG MaxProgress)
01722 {
01723     HANDLE RegistrationThread;
01724     LONG DllCount;
01725     INFCONTEXT Context;
01726     WCHAR SectionName[512];
01727     PREGISTRATIONDATA RegistrationData;
01728 
01729     DllCount = -1;
01730     if (! SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2",
01731                               L"RegisterDlls", &Context))
01732     {
01733         DPRINT1("No RegistrationPhase2 section found\n");
01734         return FALSE;
01735     }
01736     if (! SetupGetStringFieldW(&Context, 1, SectionName,
01737                                sizeof(SectionName) / sizeof(SectionName[0]),
01738                                NULL))
01739     {
01740         DPRINT1("Unable to retrieve section name\n");
01741         return FALSE;
01742     }
01743     DllCount = SetupGetLineCountW(hSysSetupInf, SectionName);
01744     DPRINT("SectionName %S DllCount %ld\n", SectionName, DllCount);
01745     if (DllCount < 0)
01746     {
01747         SetLastError(STATUS_NOT_FOUND);
01748         return FALSE;
01749     }
01750 
01751     *MaxProgress = (ULONG) DllCount;
01752 
01753     /*
01754      * Create a background thread to do the actual registrations, so the
01755      * main thread can just run its message loop.
01756      */
01757     RegistrationThread = NULL;
01758     RegistrationData = HeapAlloc(GetProcessHeap(), 0,
01759                                  sizeof(REGISTRATIONDATA));
01760     if (RegistrationData != NULL)
01761     {
01762         RegistrationData->hwndDlg = hwndDlg;
01763         RegistrationData->DllCount = DllCount;
01764         RegistrationThread = CreateThread(NULL, 0, RegistrationProc,
01765                                           (LPVOID) RegistrationData, 0, NULL);
01766         if (RegistrationThread != NULL)
01767         {
01768             CloseHandle(RegistrationThread);
01769         }
01770         else
01771         {
01772             DPRINT1("CreateThread failed, error %u\n", GetLastError());
01773             HeapFree(GetProcessHeap(), 0, RegistrationData);
01774             return FALSE;
01775         }
01776     }
01777     else
01778     {
01779         DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
01780         return FALSE;
01781     }
01782 
01783     return TRUE;
01784 }
01785 
01786 
01787 static INT_PTR CALLBACK
01788 ProcessPageDlgProc(HWND hwndDlg,
01789                    UINT uMsg,
01790                    WPARAM wParam,
01791                    LPARAM lParam)
01792 {
01793     PSETUPDATA SetupData;
01794     PREGISTRATIONNOTIFY RegistrationNotify;
01795     static UINT oldActivityID = -1;
01796     WCHAR Title[64];
01797 
01798     /* Retrieve pointer to the global setup data */
01799     SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
01800 
01801     switch (uMsg)
01802     {
01803         case WM_INITDIALOG:
01804         {
01805             /* Save pointer to the global setup data */
01806             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
01807             SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
01808         }
01809         break;
01810 
01811         case WM_NOTIFY:
01812         {
01813             LPNMHDR lpnm = (LPNMHDR)lParam;
01814             ULONG MaxProgress = 0;
01815 
01816             switch (lpnm->code)
01817             {
01818                 case PSN_SETACTIVE:
01819                     /* Disable the Back and Next buttons */
01820                     PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
01821 
01822                     StartComponentRegistration(hwndDlg, &MaxProgress);
01823 
01824                     SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE,
01825                                        0, MAKELPARAM(0, MaxProgress));
01826                     SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS,
01827                                        0, 0);
01828                     break;
01829 
01830                 case PSN_WIZNEXT:
01831                     break;
01832 
01833                 case PSN_WIZBACK:
01834                     SetupData->UnattendSetup = FALSE;
01835                     break;
01836 
01837                 default:
01838                     break;
01839             }
01840         }
01841         break;
01842 
01843         case PM_REGISTRATION_NOTIFY:
01844         {
01845             WCHAR Activity[64];
01846             RegistrationNotify = (PREGISTRATIONNOTIFY) lParam;
01847             // update if necessary only
01848             if (oldActivityID != RegistrationNotify->ActivityID)
01849             {
01850                 if (0 != LoadStringW(hDllInstance, RegistrationNotify->ActivityID,
01851                                      Activity,
01852                                      sizeof(Activity) / sizeof(Activity[0])))
01853                 {
01854                     SendDlgItemMessageW(hwndDlg, IDC_ACTIVITY, WM_SETTEXT,
01855                                         0, (LPARAM) Activity);
01856                 }
01857                 oldActivityID = RegistrationNotify->ActivityID;
01858             }
01859             SendDlgItemMessageW(hwndDlg, IDC_ITEM, WM_SETTEXT, 0,
01860                                 (LPARAM)(NULL == RegistrationNotify->CurrentItem ?
01861                                          L"" : RegistrationNotify->CurrentItem));
01862             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS,
01863                                RegistrationNotify->Progress, 0);
01864             if (NULL != RegistrationNotify->ErrorMessage)
01865             {
01866                 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
01867                                      Title, sizeof(Title) / sizeof(Title[0])))
01868                 {
01869                     wcscpy(Title, L"ReactOS Setup");
01870                 }
01871                 MessageBoxW(hwndDlg, RegistrationNotify->ErrorMessage,
01872                             Title, MB_ICONERROR | MB_OK);
01873 
01874             }
01875 
01876             if (wParam)
01877             {
01878 #ifdef VMWINST
01879                 if(!SetupData->UnattendSetup && !SetupData->DisableVmwInst)
01880                     RunVMWInstall(GetParent(hwndDlg));
01881 #endif
01882 
01883                 /* Enable the Back and Next buttons */
01884                 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
01885                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
01886             }
01887         }
01888         return TRUE;
01889 
01890         default:
01891             break;
01892     }
01893 
01894     return FALSE;
01895 }
01896 
01897 
01898 static VOID
01899 SetInstallationCompleted(VOID)
01900 {
01901     HKEY hKey = 0;
01902     DWORD InProgress = 0;
01903     DWORD InstallDate;
01904 
01905     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
01906                        L"SYSTEM\\Setup",
01907                        0,
01908                        KEY_WRITE,
01909                        &hKey ) == ERROR_SUCCESS)
01910     {
01911         RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) );
01912         RegCloseKey( hKey );
01913     }
01914 
01915     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
01916                        L"Software\\Microsoft\\Windows NT\\CurrentVersion",
01917                        0,
01918                        KEY_WRITE,
01919                        &hKey ) == ERROR_SUCCESS)
01920     {
01921         InstallDate = (DWORD)time(NULL);
01922         RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) );
01923         RegCloseKey( hKey );
01924     }
01925 }
01926 
01927 
01928 static INT_PTR CALLBACK
01929 FinishDlgProc(HWND hwndDlg,
01930               UINT uMsg,
01931               WPARAM wParam,
01932               LPARAM lParam)
01933 {
01934 
01935     switch (uMsg)
01936     {
01937         case WM_INITDIALOG:
01938         {
01939             PSETUPDATA SetupData;
01940 
01941             /* Get pointer to the global setup data */
01942             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
01943 
01944             /* Set title font */
01945             SendDlgItemMessage(hwndDlg,
01946                                IDC_FINISHTITLE,
01947                                WM_SETFONT,
01948                                (WPARAM)SetupData->hTitleFont,
01949                                (LPARAM)TRUE);
01950             if (SetupData->UnattendSetup)
01951             {
01952                 KillTimer(hwndDlg, 1);
01953                 SetInstallationCompleted();
01954                 PostQuitMessage(0);
01955             }
01956         }
01957         break;
01958 
01959         case WM_DESTROY:
01960         {
01961             SetInstallationCompleted();
01962             PostQuitMessage(0);
01963             return TRUE;
01964         }
01965 
01966         case WM_TIMER:
01967         {
01968             INT Position;
01969             HWND hWndProgress;
01970 
01971             hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
01972             Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
01973             if (Position == 300)
01974             {
01975                 KillTimer(hwndDlg, 1);
01976                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
01977             }
01978             else
01979             {
01980                 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
01981             }
01982         }
01983         return TRUE;
01984 
01985         case WM_NOTIFY:
01986         {
01987             LPNMHDR lpnm = (LPNMHDR)lParam;
01988 
01989             switch (lpnm->code)
01990             {
01991                 case PSN_SETACTIVE:
01992                     /* Enable the correct buttons on for the active page */
01993                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
01994 
01995                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
01996                                        MAKELPARAM(0, 300));
01997                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
01998                     SetTimer(hwndDlg, 1, 50, NULL);
01999                     break;
02000 
02001                 case PSN_WIZFINISH:
02002                     DestroyWindow(GetParent(hwndDlg));
02003                     break;
02004 
02005                 default:
02006                     break;
02007             }
02008         }
02009         break;
02010 
02011         default:
02012             break;
02013     }
02014 
02015     return FALSE;
02016 }
02017 
02018 
02019 BOOL
02020 ProcessUnattendInf(HINF hUnattendedInf)
02021 {
02022     INFCONTEXT InfContext;
02023     WCHAR szName[256];
02024     WCHAR szValue[MAX_PATH];
02025     DWORD LineLength;
02026     HKEY hKey;
02027 
02028     if (!SetupFindFirstLineW(hUnattendedInf,
02029                              L"Unattend",
02030                              L"UnattendSetupEnabled",
02031                              &InfContext))
02032     {
02033         DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
02034         return FALSE;
02035     }
02036 
02037     if (!SetupGetStringFieldW(&InfContext,
02038                               1,
02039                               szValue,
02040                               sizeof(szValue) / sizeof(WCHAR),
02041                               &LineLength))
02042     {
02043         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
02044         return FALSE;
02045     }
02046 
02047     if (wcscmp(szValue, L"yes") != 0)
02048     {
02049         DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
02050         return FALSE;
02051     }
02052 
02053     if (!SetupFindFirstLineW(hUnattendedInf,
02054                              L"Unattend",
02055                              NULL,
02056                              &InfContext))
02057     {
02058         DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
02059         return FALSE;
02060     }
02061 
02062 
02063     do
02064     {
02065         if (!SetupGetStringFieldW(&InfContext,
02066                                   0,
02067                                   szName,
02068                                   sizeof(szName) / sizeof(WCHAR),
02069                                   &LineLength))
02070         {
02071             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
02072             return FALSE;
02073         }
02074 
02075         if (!SetupGetStringFieldW(&InfContext,
02076                                   1,
02077                                   szValue,
02078                                   sizeof(szValue) / sizeof(WCHAR),
02079                                   &LineLength))
02080         {
02081             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
02082             return FALSE;
02083         }
02084         DPRINT1("Name %S Value %S\n", szName, szValue);
02085         if (!wcscmp(szName, L"FullName"))
02086         {
02087             if ((sizeof(SetupData.OwnerName) / sizeof(TCHAR)) > LineLength)
02088             {
02089                 wcscpy(SetupData.OwnerName, szValue);
02090             }
02091         }
02092         else if (!wcscmp(szName, L"OrgName"))
02093         {
02094             if ((sizeof(SetupData.OwnerOrganization) / sizeof(WCHAR)) > LineLength)
02095             {
02096                 wcscpy(SetupData.OwnerOrganization, szValue);
02097             }
02098         }
02099         else if (!wcscmp(szName, L"ComputerName"))
02100         {
02101             if ((sizeof(SetupData.ComputerName) / sizeof(WCHAR)) > LineLength)
02102             {
02103                 wcscpy(SetupData.ComputerName, szValue);
02104             }
02105         }
02106         else if (!wcscmp(szName, L"AdminPassword"))
02107         {
02108             if ((sizeof(SetupData.AdminPassword) / sizeof(WCHAR)) > LineLength)
02109             {
02110                 wcscpy(SetupData.AdminPassword, szValue);
02111             }
02112         }
02113         else if (!wcscmp(szName, L"TimeZoneIndex"))
02114         {
02115             SetupData.TimeZoneIndex = _wtoi(szValue);
02116         }
02117         else if (!wcscmp(szName, L"DisableAutoDaylightTimeSet"))
02118         {
02119             SetupData.DisableAutoDaylightTimeSet = _wtoi(szValue);
02120         }
02121         else if (!wcscmp(szName, L"DisableVmwInst"))
02122         {
02123             if(!wcscmp(szValue, L"yes"))
02124                 SetupData.DisableVmwInst = 1;
02125             else
02126                 SetupData.DisableVmwInst = 0;
02127         }
02128 
02129     }
02130     while (SetupFindNextLine(&InfContext, &InfContext));
02131 
02132     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
02133                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
02134                       0,
02135                       KEY_SET_VALUE,
02136                       &hKey) != ERROR_SUCCESS)
02137     {
02138         DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
02139         return TRUE;
02140     }
02141 
02142 
02143     if (SetupFindFirstLineW(hUnattendedInf,
02144                             L"GuiRunOnce",
02145                             NULL,
02146                             &InfContext))
02147     {
02148 
02149         int i = 0;
02150         do
02151         {
02152             if(SetupGetStringFieldW(&InfContext,
02153                                     0,
02154                                     szValue,
02155                                     sizeof(szValue) / sizeof(WCHAR),
02156                                     NULL))
02157             {
02158                 WCHAR szPath[MAX_PATH];
02159                 swprintf(szName, L"%d", i);
02160                 DPRINT("szName %S szValue %S\n", szName, szValue);
02161 
02162                 if (ExpandEnvironmentStringsW(szValue, szPath, MAX_PATH))
02163                 {
02164                     DPRINT("value %S\n", szPath);
02165                     if (RegSetValueExW(hKey,
02166                                        szName,
02167                                        0,
02168                                        REG_SZ,
02169                                        (const BYTE*)szPath,
02170                                        (wcslen(szPath) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS)
02171                     {
02172                         i++;
02173                     }
02174                 }
02175             }
02176         } while(SetupFindNextLine(&InfContext, &InfContext));
02177     }
02178 
02179     RegCloseKey(hKey);
02180     return TRUE;
02181 }
02182 
02183 /*
02184  * GetRosInstallCD should find the path to ros installation medium
02185  * BUG 1
02186  * If there are more than one CDDrive in it containing a ReactOS
02187  * installation cd, then it will pick the first one regardless if
02188  * it is really the installation cd
02189  *
02190  * The best way to implement this is to set the key
02191  * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
02192  */
02193 
02194 BOOL
02195 GetRosInstallCD(WCHAR *pwszPath, DWORD cchPathMax)
02196 {
02197     WCHAR wszDrives[512];
02198     DWORD cchDrives;
02199     WCHAR *pwszDrive;
02200 
02201     cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives);
02202     if (cchDrives == 0 || cchDrives >= _countof(wszDrives))
02203     {
02204         /* buffer too small or failure */
02205         LogItem(SYSSETUP_SEVERITY_INFORMATION, L"GetLogicalDriveStringsW failed");
02206         return FALSE;
02207     }
02208 
02209     for (pwszDrive = wszDrives; pwszDrive[0]; pwszDrive += wcslen(pwszDrive) + 1)
02210     {
02211         if (GetDriveTypeW(pwszDrive) == DRIVE_CDROM)
02212         {
02213             WCHAR wszBuf[MAX_PATH];
02214             wsprintf(wszBuf, L"%sreactos\\system32\\ntoskrnl.exe", pwszDrive);
02215             LogItem(SYSSETUP_SEVERITY_INFORMATION, wszBuf);
02216             if (GetFileAttributesW(wszBuf) != INVALID_FILE_ATTRIBUTES)
02217             {
02218                 /* the file exists, so this is the right drive */
02219                 wcsncpy(pwszPath, pwszDrive, cchPathMax);
02220                 OutputDebugStringW(L"GetRosInstallCD: ");OutputDebugStringW(pwszPath);OutputDebugStringW(L"\n");
02221                 return TRUE;
02222             }
02223         }
02224     }
02225     return FALSE;
02226 }
02227 
02228 
02229 VOID
02230 ProcessUnattendSetup(VOID)
02231 {
02232     WCHAR szPath[MAX_PATH];
02233     HINF hUnattendedInf;
02234     DWORD dwLength;
02235 
02236     if (!GetRosInstallCD(szPath, MAX_PATH))
02237     {
02238         /* no cd drive found */
02239         return;
02240     }
02241 
02242     dwLength = wcslen(szPath);
02243     if (dwLength + 21 > MAX_PATH)
02244     {
02245         /* FIXME
02246          * allocate bigger buffer
02247          */
02248         return;
02249     }
02250 
02251     wcscat(szPath, L"reactos\\unattend.inf");
02252 
02253     hUnattendedInf = SetupOpenInfFileW(szPath,
02254                                        NULL,
02255                                        INF_STYLE_OLDNT,
02256                                        NULL);
02257 
02258     if (hUnattendedInf != INVALID_HANDLE_VALUE)
02259     {
02260         SetupData.UnattendSetup = ProcessUnattendInf(hUnattendedInf);
02261         SetupCloseInfFile(hUnattendedInf);
02262     }
02263 }
02264 
02265 
02266 VOID
02267 InstallWizard(VOID)
02268 {
02269     PROPSHEETHEADER psh;
02270     HPROPSHEETPAGE ahpsp[8];
02271     PROPSHEETPAGE psp = {0};
02272     UINT nPages = 0;
02273     HWND hWnd;
02274     MSG msg;
02275 
02276     /* Clear setup data */
02277     ZeroMemory(&SetupData, sizeof(SETUPDATA));
02278 
02279     ProcessUnattendSetup();
02280 
02281     /* Create the Welcome page */
02282     psp.dwSize = sizeof(PROPSHEETPAGE);
02283     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
02284     psp.hInstance = hDllInstance;
02285     psp.lParam = (LPARAM)&SetupData;
02286     psp.pfnDlgProc = WelcomeDlgProc;
02287     psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
02288     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02289 
02290     /* Create the Acknowledgements page */
02291     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02292     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE);
02293     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE);
02294     psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE);
02295     psp.pfnDlgProc = AckPageDlgProc;
02296     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02297 
02298     /* Create the Owner page */
02299     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02300     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
02301     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
02302     psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
02303     psp.pfnDlgProc = OwnerPageDlgProc;
02304     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02305 
02306     /* Create the Computer page */
02307     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02308     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
02309     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
02310     psp.pfnDlgProc = ComputerPageDlgProc;
02311     psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
02312     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02313 
02314 
02315     /* Create the Locale page */
02316     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02317     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
02318     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
02319     psp.pfnDlgProc = LocalePageDlgProc;
02320     psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
02321     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02322 
02323 
02324     /* Create the DateTime page */
02325     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02326     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
02327     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
02328     psp.pfnDlgProc = DateTimePageDlgProc;
02329     psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
02330     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02331 
02332 
02333     /* Create the Process page */
02334     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
02335     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
02336     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
02337     psp.pfnDlgProc = ProcessPageDlgProc;
02338     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
02339     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02340 
02341 
02342     /* Create the Finish page */
02343     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
02344     psp.pfnDlgProc = FinishDlgProc;
02345     psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
02346     ahpsp[nPages++] = CreatePropertySheetPage(&psp);
02347 
02348     /* Create the property sheet */
02349     psh.dwSize = sizeof(PROPSHEETHEADER);
02350     psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS;
02351     psh.hInstance = hDllInstance;
02352     psh.hwndParent = NULL;
02353     psh.nPages = nPages;
02354     psh.nStartPage = 0;
02355     psh.phpage = ahpsp;
02356     psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
02357     psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
02358 
02359     /* Create title font */
02360     SetupData.hTitleFont = CreateTitleFont();
02361 
02362     /* Display the wizard */
02363     hWnd = (HWND)PropertySheet(&psh);
02364     ShowWindow(hWnd, SW_SHOW);
02365 
02366     while (GetMessage(&msg, NULL, 0, 0))
02367     {
02368         if(!IsDialogMessage(hWnd, &msg))
02369         {
02370             TranslateMessage(&msg);
02371             DispatchMessage(&msg);
02372         }
02373     }
02374 
02375     DeleteObject(SetupData.hTitleFont);
02376 }
02377 
02378 /* EOF */

Generated on Sun May 27 2012 04:25:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.