[USERINIT]: Addendum to r72821 + demote to WARNing the displayed message if the insta...
[reactos.git] / reactos / base / system / userinit / livecd.c
index 4d8b623..5653ac6 100644 (file)
@@ -18,16 +18,16 @@ InitImageInfo(PIMGINFO ImgInfo)
 
     ZeroMemory(ImgInfo, sizeof(*ImgInfo));
 
-    ImgInfo->hBitmap = LoadImage(hInstance,
-                                 MAKEINTRESOURCE(IDB_ROSLOGO),
-                                 IMAGE_BITMAP,
-                                 0,
-                                 0,
-                                 LR_DEFAULTCOLOR);
+    ImgInfo->hBitmap = LoadImageW(hInstance,
+                                  MAKEINTRESOURCEW(IDB_ROSLOGO),
+                                  IMAGE_BITMAP,
+                                  0,
+                                  0,
+                                  LR_DEFAULTCOLOR);
 
     if (ImgInfo->hBitmap != NULL)
     {
-        GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
+        GetObject(ImgInfo->hBitmap, sizeof(bitmap), &bitmap);
 
         ImgInfo->cxSource = bitmap.bmWidth;
         ImgInfo->cySource = bitmap.bmHeight;
@@ -46,11 +46,11 @@ IsLiveCD(VOID)
 
     TRACE("IsLiveCD()\n");
 
-    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                      REGSTR_PATH_CURRENT_CONTROL_SET,
-                      0,
-                      KEY_QUERY_VALUE,
-                      &ControlKey);
+    rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                       REGSTR_PATH_CURRENT_CONTROL_SET,
+                       0,
+                       KEY_QUERY_VALUE,
+                       &ControlKey);
     if (rc != ERROR_SUCCESS)
     {
         WARN("RegOpenKeyEx() failed with error %lu\n", rc);
@@ -110,7 +110,7 @@ LocalesEnumProc(LPTSTR lpLocale)
     {
         if (bSpain == FALSE)
         {
-            LoadStringW(hInstance, IDS_SPAIN, lang, 255);
+            LoadStringW(hInstance, IDS_SPAIN, lang, ARRAYSIZE(lang));
             bSpain = TRUE;
         }
         else
@@ -120,7 +120,7 @@ LocalesEnumProc(LPTSTR lpLocale)
     }
     else
     {
-        GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(WCHAR));
+        GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, ARRAYSIZE(lang));
     }
 
     if (bNoShow == FALSE)
@@ -151,7 +151,7 @@ CreateLanguagesList(HWND hwnd)
 
     /* Select current locale */
     /* or should it be System and not user? */
-    GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(WCHAR));
+    GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, ARRAYSIZE(langSel));
 
     SendMessageW(hList,
                  CB_SELECTSTRING,
@@ -160,6 +160,201 @@ CreateLanguagesList(HWND hwnd)
 }
 
 
+static
+BOOL
+GetLayoutName(
+    LPCWSTR szLCID,
+    LPWSTR szName)
+{
+    HKEY hKey;
+    DWORD dwBufLen;
+    WCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
+    HANDLE hLib;
+    UINT i, j, k;
+
+    wsprintf(szBuf, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", szLCID);
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+    {
+        dwBufLen = sizeof(szDispName);
+
+        if (RegQueryValueExW(hKey, L"Layout Display Name", NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
+        {
+            if (szDispName[0] == '@')
+            {
+                for (i = 0; i < wcslen(szDispName); i++)
+                {
+                    if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
+                    {
+                        for (j = i + 2, k = 0; j < wcslen(szDispName)+1; j++, k++)
+                        {
+                            szIndex[k] = szDispName[j];
+                        }
+                        szDispName[i - 1] = '\0';
+                        break;
+                    }
+                    else
+                        szDispName[i] = szDispName[i + 1];
+                }
+
+                if (ExpandEnvironmentStringsW(szDispName, szPath, ARRAYSIZE(szPath)))
+                {
+                    hLib = LoadLibraryW(szPath);
+                    if (hLib)
+                    {
+                        if (LoadStringW(hLib, _wtoi(szIndex), szPath, ARRAYSIZE(szPath)) != 0)
+                        {
+                            wcscpy(szName, szPath);
+                            RegCloseKey(hKey);
+                            return TRUE;
+                        }
+                        FreeLibrary(hLib);
+                    }
+                }
+            }
+        }
+
+        dwBufLen = sizeof(szBuf);
+
+        if (RegQueryValueExW(hKey, L"Layout Text", NULL, NULL, (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS)
+        {
+            RegCloseKey(hKey);
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+
+static
+VOID
+SetKeyboardLayout(
+    HWND hwnd)
+{
+    INT iCurSel;
+    ULONG ulLayoutId;
+    HKL hKl;
+    WCHAR szLayoutId[9];
+
+    iCurSel = SendMessageW(hwnd, CB_GETCURSEL, 0, 0);
+    if (iCurSel == CB_ERR)
+        return;
+
+    ulLayoutId = (ULONG)SendMessageW(hwnd, CB_GETITEMDATA, iCurSel, 0);
+    if (ulLayoutId == (ULONG)CB_ERR)
+        return;
+
+    swprintf(szLayoutId, L"%08lx", ulLayoutId);
+
+    hKl = LoadKeyboardLayoutW(szLayoutId, KLF_ACTIVATE | KLF_REPLACELANG | KLF_SETFORPROCESS);
+    SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE);
+}
+
+
+static
+VOID
+SelectKeyboardForLanguage(
+    HWND hwnd,
+    LCID lcid)
+{
+    INT i, nCount;
+    LCID LayoutId;
+
+    TRACE("LCID: %08lx\n", lcid);
+    TRACE("LangID: %04lx\n", LANGIDFROMLCID(lcid));
+
+    nCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
+
+    for (i = 0; i < nCount; i++)
+    {
+        LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
+        TRACE("Layout: %08lx\n", LayoutId);
+
+        if (LANGIDFROMLCID(LayoutId) == LANGIDFROMLCID(lcid))
+        {
+            TRACE("Found 1: %08lx --> %08lx\n", LayoutId, lcid);
+            SendMessageW(hwnd, CB_SETCURSEL, i, 0);
+            return;
+        }
+    }
+
+    for (i = 0; i < nCount; i++)
+    {
+        LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
+        TRACE("Layout: %08lx\n", LayoutId);
+
+        if (PRIMARYLANGID(LayoutId) == PRIMARYLANGID(lcid))
+        {
+            TRACE("Found 2: %08lx --> %08lx\n", LayoutId, lcid);
+            SendMessageW(hwnd, CB_SETCURSEL, i, 0);
+            return;
+        }
+    }
+
+    TRACE("No match found!\n");
+}
+
+
+static
+VOID
+CreateKeyboardLayoutList(
+    HWND hItemsList)
+{
+    HKEY hKey;
+    WCHAR szLayoutId[9], szCurrentLayoutId[9];
+    WCHAR KeyName[MAX_PATH];
+    DWORD dwIndex = 0;
+    DWORD dwSize;
+    INT iIndex;
+    LONG lError;
+    ULONG ulLayoutId;
+
+    if (!GetKeyboardLayoutNameW(szCurrentLayoutId))
+        wcscpy(szCurrentLayoutId, L"00000409");
+
+    lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                           L"System\\CurrentControlSet\\Control\\Keyboard Layouts",
+                           0,
+                           KEY_ENUMERATE_SUB_KEYS,
+                           &hKey);
+    if (lError != ERROR_SUCCESS)
+        return;
+
+    while (TRUE)
+    {
+        dwSize = ARRAYSIZE(szLayoutId);
+
+        lError = RegEnumKeyExW(hKey,
+                               dwIndex,
+                               szLayoutId,
+                               &dwSize,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+        if (lError != ERROR_SUCCESS)
+            break;
+
+        GetLayoutName(szLayoutId, KeyName);
+
+        iIndex = (INT)SendMessageW(hItemsList, CB_ADDSTRING, 0, (LPARAM)KeyName);
+
+        ulLayoutId = wcstoul(szLayoutId, NULL, 16);
+        SendMessageW(hItemsList, CB_SETITEMDATA, iIndex, (LPARAM)ulLayoutId);
+
+        if (wcscmp(szLayoutId, szCurrentLayoutId) == 0)
+        {
+            SendMessageW(hItemsList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
+        }
+
+        dwIndex++;
+    }
+
+    RegCloseKey(hKey);
+}
+
+
 static
 VOID
 InitializeDefaultUserLocale(
@@ -263,10 +458,10 @@ InitializeDefaultUserLocale(
     i = 0;
     while (LocaleData[i].pValue != NULL)
     {
-        if (GetLocaleInfo(lcid,
-                          LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE,
-                          szBuffer,
-                          sizeof(szBuffer) / sizeof(WCHAR)))
+        if (GetLocaleInfoW(lcid,
+                           LocaleData[i].LCType | LOCALE_NOUSEROVERRIDE,
+                           szBuffer,
+                           ARRAYSIZE(szBuffer)))
         {
             RegSetValueExW(hLocaleKey,
                            LocaleData[i].pValue,
@@ -320,7 +515,7 @@ OnDrawItem(
 
     if (lpDrawItem->CtlID == uCtlID)
     {
-        /* position image in centre of dialog */
+        /* Position image in centre of dialog */
         left = (lpDrawItem->rcItem.right - pState->ImageInfo.cxSource) / 2;
 
         hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
@@ -354,19 +549,23 @@ LocaleDlgProc(
     PSTATE pState;
 
     /* Retrieve pointer to the state */
-    pState = (PSTATE)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
+    pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
 
     switch (uMsg)
     {
         case WM_INITDIALOG:
             /* Save pointer to the global state */
             pState = (PSTATE)lParam;
-            SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pState);
+            SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState);
 
             /* Center the dialog window */
-            CenterWindow (hwndDlg);
+            CenterWindow(hwndDlg);
+
+            /* Fill the language and keyboard layout lists */
             CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
+            CreateKeyboardLayoutList(GetDlgItem(hwndDlg, IDC_LAYOUTLIST));
 
+            /* Disable the 'Cancel' button*/
             EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
             return FALSE;
 
@@ -377,12 +576,11 @@ LocaleDlgProc(
             return TRUE;
 
         case WM_COMMAND:
-            if (HIWORD(wParam) == BN_CLICKED)
+            switch (LOWORD(wParam))
             {
-                switch (LOWORD(wParam))
-                {
-                    case IDOK:
-                        {
+                case IDC_LANGUAGELIST:
+                    if (HIWORD(wParam) == CBN_SELCHANGE)
+                    {
                         LCID NewLcid;
                         INT iCurSel;
 
@@ -391,28 +589,60 @@ LocaleDlgProc(
                                                      CB_GETCURSEL,
                                                      0,
                                                      0);
-                if (iCurSel == CB_ERR)
+                        if (iCurSel == CB_ERR)
+                            break;
+
+                        NewLcid = SendDlgItemMessageW(hwndDlg,
+                                                      IDC_LANGUAGELIST,
+                                                      CB_GETITEMDATA,
+                                                      iCurSel,
+                                                      0);
+                        if (NewLcid == (LCID)CB_ERR)
+                            break;
+
+                        TRACE("LCID: 0x%08lx\n", NewLcid);
+                        SelectKeyboardForLanguage(GetDlgItem(hwndDlg, IDC_LAYOUTLIST),
+                                                  NewLcid);
+                    }
                     break;
 
-                NewLcid = SendDlgItemMessageW(hwndDlg,
-                                              IDC_LANGUAGELIST,
-                                              CB_GETITEMDATA,
-                                              iCurSel,
-                                              0);
-                if (NewLcid == (LCID)CB_ERR)
-                    break;
+                case IDOK:
+                    if (HIWORD(wParam) == BN_CLICKED)
+                    {
+                        LCID NewLcid;
+                        INT iCurSel;
 
-                            SetThreadLocale(NewLcid);
-                            InitializeDefaultUserLocale(&NewLcid);
-                        }
+                        iCurSel = SendDlgItemMessageW(hwndDlg,
+                                                     IDC_LANGUAGELIST,
+                                                     CB_GETCURSEL,
+                                                     0,
+                                                     0);
+                        if (iCurSel == CB_ERR)
+                            break;
+
+                        NewLcid = SendDlgItemMessageW(hwndDlg,
+                                                      IDC_LANGUAGELIST,
+                                                      CB_GETITEMDATA,
+                                                      iCurSel,
+                                                      0);
+                        if (NewLcid == (LCID)CB_ERR)
+                            break;
+
+                        /* Set the locale for the current thread */
+                        NtSetDefaultLocale(TRUE, NewLcid);
+
+                        /* Store the locale setings in the registry */
+                        InitializeDefaultUserLocale(&NewLcid);
+
+                        SetKeyboardLayout(GetDlgItem(hwndDlg, IDC_LAYOUTLIST));
 
                         pState->NextPage = STARTPAGE;
                         EndDialog(hwndDlg, 0);
-                        break;
+                    }
+                    break;
 
-                    default:
-                        break;
-                }
+                default:
+                    break;
             }
             break;
 
@@ -436,14 +666,14 @@ StartDlgProc(
     PSTATE pState;
 
     /* Retrieve pointer to the state */
-    pState = (PSTATE)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
+    pState = (PSTATE)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
 
     switch (uMsg)
     {
         case WM_INITDIALOG:
             /* Save pointer to the state */
             pState = (PSTATE)lParam;
-            SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pState);
+            SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pState);
 
             /* Center the dialog window */
             CenterWindow(hwndDlg);
@@ -504,19 +734,19 @@ RunLiveCD(
         switch (pState->NextPage)
         {
             case LOCALEPAGE:
-                DialogBoxParam(hInstance,
-                               MAKEINTRESOURCE(IDD_LOCALEPAGE),
-                               NULL,
-                               LocaleDlgProc,
-                               (LPARAM)pState);
+                DialogBoxParamW(hInstance,
+                                MAKEINTRESOURCEW(IDD_LOCALEPAGE),
+                                NULL,
+                                LocaleDlgProc,
+                                (LPARAM)pState);
                 break;
 
             case STARTPAGE:
-                DialogBoxParam(hInstance,
-                               MAKEINTRESOURCE(IDD_STARTPAGE),
-                               NULL,
-                               StartDlgProc,
-                               (LPARAM)pState);
+                DialogBoxParamW(hInstance,
+                                MAKEINTRESOURCEW(IDD_STARTPAGE),
+                                NULL,
+                                StartDlgProc,
+                                (LPARAM)pState);
                 break;
 
             default: