Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmui.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2008 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS text-mode setup 00022 * FILE: subsys/system/usetup/mui.c 00023 * PURPOSE: Text-mode setup 00024 * PROGRAMMER: 00025 */ 00026 00027 #include "usetup.h" 00028 #include "muifonts.h" 00029 #include "muilanguages.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 extern 00035 VOID 00036 PopupError(IN PCCH Text, 00037 IN PCCH Status, 00038 IN PINPUT_RECORD Ir, 00039 IN ULONG WaitEvent); 00040 00041 static 00042 ULONG 00043 FindLanguageIndex(VOID) 00044 { 00045 ULONG lngIndex = 0; 00046 00047 if (SelectedLanguageId == NULL) 00048 { 00049 /* default to english */ 00050 return 0; 00051 } 00052 00053 do 00054 { 00055 if (_wcsicmp(LanguageList[lngIndex].LanguageID , SelectedLanguageId) == 0) 00056 { 00057 return lngIndex; 00058 } 00059 00060 lngIndex++; 00061 }while (LanguageList[lngIndex].MuiPages != NULL); 00062 00063 return 0; 00064 } 00065 00066 BOOLEAN 00067 IsLanguageAvailable(PWCHAR LanguageId) 00068 { 00069 ULONG lngIndex = 0; 00070 00071 do 00072 { 00073 if (_wcsicmp(LanguageList[lngIndex].LanguageID , LanguageId) == 0) 00074 return TRUE; 00075 00076 lngIndex++; 00077 }while (LanguageList[lngIndex].MuiPages != NULL); 00078 00079 return FALSE; 00080 } 00081 00082 00083 static 00084 const MUI_ENTRY * 00085 FindMUIEntriesOfPage(IN ULONG PageNumber) 00086 { 00087 ULONG muiIndex = 0; 00088 ULONG lngIndex; 00089 const MUI_PAGE * Pages = NULL; 00090 00091 lngIndex = max(FindLanguageIndex(), 0); 00092 Pages = LanguageList[lngIndex].MuiPages; 00093 00094 do 00095 { 00096 if (Pages[muiIndex].Number == PageNumber) 00097 return Pages[muiIndex].MuiEntry; 00098 00099 muiIndex++; 00100 }while (Pages[muiIndex].MuiEntry != NULL); 00101 00102 return NULL; 00103 } 00104 00105 static 00106 const MUI_ERROR * 00107 FindMUIErrorEntries(VOID) 00108 { 00109 ULONG lngIndex = max(FindLanguageIndex(), 0); 00110 return LanguageList[lngIndex].MuiErrors; 00111 } 00112 00113 static 00114 const MUI_STRING * 00115 FindMUIStringEntries(VOID) 00116 { 00117 ULONG lngIndex = max(FindLanguageIndex(), 0); 00118 return LanguageList[lngIndex].MuiStrings; 00119 } 00120 00121 LPCWSTR 00122 MUIDefaultKeyboardLayout(VOID) 00123 { 00124 ULONG lngIndex = max(FindLanguageIndex(), 0); 00125 return LanguageList[lngIndex].MuiLayouts[0].LayoutID; 00126 } 00127 00128 PWCHAR 00129 MUIGetGeoID(VOID) 00130 { 00131 ULONG lngIndex = max(FindLanguageIndex(), 0); 00132 return LanguageList[lngIndex].GeoID; 00133 } 00134 00135 const MUI_LAYOUTS * 00136 MUIGetLayoutsList(VOID) 00137 { 00138 ULONG lngIndex = max(FindLanguageIndex(), 0); 00139 return LanguageList[lngIndex].MuiLayouts; 00140 } 00141 00142 VOID 00143 MUIClearPage(IN ULONG page) 00144 { 00145 const MUI_ENTRY * entry; 00146 int index; 00147 00148 entry = FindMUIEntriesOfPage(page); 00149 if (!entry) 00150 { 00151 PopupError("Error: Failed to find translated page", 00152 NULL, 00153 NULL, 00154 POPUP_WAIT_NONE); 00155 return; 00156 } 00157 00158 index = 0; 00159 do 00160 { 00161 CONSOLE_ClearStyledText(entry[index].X, 00162 entry[index].Y, 00163 entry[index].Flags, 00164 strlen(entry[index].Buffer)); 00165 index++; 00166 } 00167 while (entry[index].Buffer != NULL); 00168 } 00169 00170 VOID 00171 MUIDisplayPage(IN ULONG page) 00172 { 00173 const MUI_ENTRY * entry; 00174 int index; 00175 00176 entry = FindMUIEntriesOfPage(page); 00177 if (!entry) 00178 { 00179 PopupError("Error: Failed to find translated page", 00180 NULL, 00181 NULL, 00182 POPUP_WAIT_NONE); 00183 return; 00184 } 00185 00186 index = 0; 00187 do 00188 { 00189 CONSOLE_SetStyledText(entry[index].X, 00190 entry[index].Y, 00191 entry[index].Flags, 00192 entry[index].Buffer); 00193 00194 index++; 00195 } 00196 while (entry[index].Buffer != NULL); 00197 } 00198 00199 VOID 00200 MUIDisplayError(IN ULONG ErrorNum, OUT PINPUT_RECORD Ir, IN ULONG WaitEvent) 00201 { 00202 const MUI_ERROR * entry; 00203 00204 if (ErrorNum >= ERROR_LAST_ERROR_CODE) 00205 { 00206 PopupError("Invalid error number provided", 00207 "Press ENTER to continue", 00208 Ir, 00209 POPUP_WAIT_ENTER); 00210 00211 return; 00212 } 00213 00214 entry = FindMUIErrorEntries(); 00215 if (!entry) 00216 { 00217 PopupError("Error: Failed to find translated error message", 00218 NULL, 00219 NULL, 00220 POPUP_WAIT_NONE); 00221 return; 00222 } 00223 00224 PopupError(entry[ErrorNum].ErrorText, 00225 entry[ErrorNum].ErrorStatus, 00226 Ir, 00227 WaitEvent); 00228 } 00229 00230 LPSTR 00231 MUIGetString(ULONG Number) 00232 { 00233 ULONG i; 00234 const MUI_STRING * entry; 00235 CHAR szErr[100]; 00236 00237 entry = FindMUIStringEntries(); 00238 if (entry) 00239 { 00240 for (i = 0; entry[i].Number != 0; i++) 00241 { 00242 if (entry[i].Number == Number) 00243 { 00244 return entry[i].String; 00245 } 00246 } 00247 } 00248 00249 sprintf(szErr, "Error: failed find string id %lu for language index %lu\n", Number, FindLanguageIndex()); 00250 00251 PopupError(szErr, 00252 NULL, 00253 NULL, 00254 POPUP_WAIT_NONE); 00255 00256 return "<nostring>"; 00257 } 00258 00259 static BOOLEAN 00260 AddHotkeySettings(IN LPCWSTR Hotkey, IN LPCWSTR LangHotkey, IN LPCWSTR LayoutHotkey) 00261 { 00262 OBJECT_ATTRIBUTES ObjectAttributes; 00263 UNICODE_STRING KeyName; 00264 UNICODE_STRING ValueName; 00265 HANDLE KeyHandle; 00266 ULONG Disposition; 00267 NTSTATUS Status; 00268 00269 RtlInitUnicodeString(&KeyName, 00270 L"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Toggle"); 00271 InitializeObjectAttributes(&ObjectAttributes, 00272 &KeyName, 00273 OBJ_CASE_INSENSITIVE, 00274 NULL, 00275 NULL); 00276 00277 Status = NtCreateKey(&KeyHandle, 00278 KEY_SET_VALUE, 00279 &ObjectAttributes, 00280 0, 00281 NULL, 00282 0, 00283 &Disposition); 00284 00285 if(!NT_SUCCESS(Status)) 00286 { 00287 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 00288 return FALSE; 00289 } 00290 00291 RtlInitUnicodeString(&ValueName, 00292 L"Hotkey"); 00293 00294 Status = NtSetValueKey(KeyHandle, 00295 &ValueName, 00296 0, 00297 REG_SZ, 00298 (PVOID)Hotkey, 00299 (1 + 1) * sizeof(WCHAR)); 00300 if (!NT_SUCCESS(Status)) 00301 { 00302 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00303 NtClose(KeyHandle); 00304 return FALSE; 00305 } 00306 00307 RtlInitUnicodeString(&ValueName, 00308 L"Language Hotkey"); 00309 00310 Status = NtSetValueKey(KeyHandle, 00311 &ValueName, 00312 0, 00313 REG_SZ, 00314 (PVOID)LangHotkey, 00315 (1 + 1) * sizeof(WCHAR)); 00316 if (!NT_SUCCESS(Status)) 00317 { 00318 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00319 NtClose(KeyHandle); 00320 return FALSE; 00321 } 00322 00323 RtlInitUnicodeString(&ValueName, 00324 L"Layout Hotkey"); 00325 00326 Status = NtSetValueKey(KeyHandle, 00327 &ValueName, 00328 0, 00329 REG_SZ, 00330 (PVOID)LayoutHotkey, 00331 (1 + 1) * sizeof(WCHAR)); 00332 if (!NT_SUCCESS(Status)) 00333 { 00334 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00335 NtClose(KeyHandle); 00336 return FALSE; 00337 } 00338 00339 NtClose(KeyHandle); 00340 return TRUE; 00341 } 00342 00343 BOOLEAN 00344 AddKbLayoutsToRegistry(IN const MUI_LAYOUTS * MuiLayouts) 00345 { 00346 OBJECT_ATTRIBUTES ObjectAttributes; 00347 UNICODE_STRING KeyName; 00348 UNICODE_STRING ValueName; 00349 HANDLE KeyHandle; 00350 HANDLE SubKeyHandle; 00351 NTSTATUS Status; 00352 ULONG Disposition; 00353 ULONG uIndex = 0; 00354 ULONG uCount = 0; 00355 WCHAR szKeyName[48] = L"\\Registry\\User\\.DEFAULT\\Keyboard Layout"; 00356 WCHAR szValueName[3 + 1]; 00357 WCHAR szLangID[8 + 1]; 00358 00359 // Open the keyboard layout key 00360 RtlInitUnicodeString(&KeyName, 00361 szKeyName); 00362 InitializeObjectAttributes(&ObjectAttributes, 00363 &KeyName, 00364 OBJ_CASE_INSENSITIVE, 00365 NULL, 00366 NULL); 00367 00368 Status = NtCreateKey(&KeyHandle, 00369 KEY_CREATE_SUB_KEY, 00370 &ObjectAttributes, 00371 0, 00372 NULL, 00373 0, 00374 &Disposition); 00375 00376 if(NT_SUCCESS(Status)) 00377 NtClose(KeyHandle); 00378 else 00379 { 00380 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 00381 return FALSE; 00382 } 00383 00384 KeyName.MaximumLength = sizeof(szKeyName); 00385 Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload"); 00386 00387 if(!NT_SUCCESS(Status)) 00388 { 00389 DPRINT1("RtlAppend failed! (%lx)\n", Status); 00390 DPRINT1("String is %wZ\n", &KeyName); 00391 return FALSE; 00392 } 00393 00394 InitializeObjectAttributes(&ObjectAttributes, 00395 &KeyName, 00396 OBJ_CASE_INSENSITIVE, 00397 NULL, 00398 NULL); 00399 00400 Status = NtCreateKey(&KeyHandle, 00401 KEY_SET_VALUE, 00402 &ObjectAttributes, 00403 0, 00404 NULL, 00405 0, 00406 &Disposition); 00407 00408 if (!NT_SUCCESS(Status)) 00409 { 00410 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 00411 return FALSE; 00412 } 00413 00414 RtlInitUnicodeString(&KeyName, L"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Substitutes"); 00415 InitializeObjectAttributes(&ObjectAttributes, 00416 &KeyName, 00417 OBJ_CASE_INSENSITIVE, 00418 NULL, 00419 NULL); 00420 00421 Status = NtCreateKey(&SubKeyHandle, 00422 KEY_SET_VALUE, 00423 &ObjectAttributes, 00424 0, 00425 NULL, 00426 0, 00427 &Disposition); 00428 00429 if(!NT_SUCCESS(Status)) 00430 { 00431 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 00432 NtClose(SubKeyHandle); 00433 NtClose(KeyHandle); 00434 return FALSE; 00435 } 00436 00437 do 00438 { 00439 if (uIndex > 19) break; 00440 00441 swprintf(szValueName, L"%u", uIndex + 1); 00442 RtlInitUnicodeString(&ValueName, szValueName); 00443 00444 swprintf(szLangID, L"0000%s", MuiLayouts[uIndex].LangID); 00445 00446 if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0) 00447 { 00448 Status = NtSetValueKey(KeyHandle, 00449 &ValueName, 00450 0, 00451 REG_SZ, 00452 (PVOID)MuiLayouts[uIndex].LayoutID, 00453 (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); 00454 if (!NT_SUCCESS(Status)) 00455 { 00456 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); 00457 NtClose(SubKeyHandle); 00458 NtClose(KeyHandle); 00459 return FALSE; 00460 } 00461 } 00462 else 00463 { 00464 swprintf(szLangID, L"d%03u%s", uCount, MuiLayouts[uIndex].LangID); 00465 Status = NtSetValueKey(KeyHandle, 00466 &ValueName, 00467 0, 00468 REG_SZ, 00469 (PVOID)szLangID, 00470 (wcslen(szLangID)+1) * sizeof(WCHAR)); 00471 if (!NT_SUCCESS(Status)) 00472 { 00473 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); 00474 NtClose(SubKeyHandle); 00475 NtClose(KeyHandle); 00476 return FALSE; 00477 } 00478 00479 RtlInitUnicodeString(&ValueName, szLangID); 00480 00481 Status = NtSetValueKey(SubKeyHandle, 00482 &ValueName, 00483 0, 00484 REG_SZ, 00485 (PVOID)MuiLayouts[uIndex].LayoutID, 00486 (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); 00487 if (!NT_SUCCESS(Status)) 00488 { 00489 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex); 00490 NtClose(SubKeyHandle); 00491 NtClose(KeyHandle); 00492 return FALSE; 00493 } 00494 00495 uCount++; 00496 } 00497 00498 uIndex++; 00499 } 00500 while (MuiLayouts[uIndex].LangID != NULL); 00501 00502 if (uIndex > 1) 00503 AddHotkeySettings(L"2", L"2", L"1"); 00504 else 00505 AddHotkeySettings(L"3", L"3", L"3"); 00506 00507 NtClose(SubKeyHandle); 00508 NtClose(KeyHandle); 00509 return TRUE; 00510 } 00511 00512 BOOLEAN 00513 AddKeyboardLayouts(VOID) 00514 { 00515 ULONG lngIndex = 0; 00516 do 00517 { 00518 if (_wcsicmp(LanguageList[lngIndex].LanguageID , SelectedLanguageId) == 0) 00519 { 00520 return AddKbLayoutsToRegistry(LanguageList[lngIndex].MuiLayouts); 00521 } 00522 00523 lngIndex++; 00524 } 00525 while (LanguageList[lngIndex].MuiPages != NULL); 00526 00527 return FALSE; 00528 } 00529 00530 static BOOLEAN 00531 AddCodepageToRegistry(IN LPCWSTR ACPage, IN LPCWSTR OEMCPage, IN LPCWSTR MACCPage) 00532 { 00533 OBJECT_ATTRIBUTES ObjectAttributes; 00534 UNICODE_STRING KeyName; 00535 UNICODE_STRING ValueName; 00536 HANDLE KeyHandle; 00537 NTSTATUS Status; 00538 00539 // Open the nls codepage key 00540 RtlInitUnicodeString(&KeyName, 00541 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage"); 00542 InitializeObjectAttributes(&ObjectAttributes, 00543 &KeyName, 00544 OBJ_CASE_INSENSITIVE, 00545 NULL, 00546 NULL); 00547 Status = NtOpenKey(&KeyHandle, 00548 KEY_WRITE, 00549 &ObjectAttributes); 00550 if (!NT_SUCCESS(Status)) 00551 { 00552 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); 00553 return FALSE; 00554 } 00555 00556 // Set ANSI codepage 00557 RtlInitUnicodeString(&ValueName, L"ACP"); 00558 Status = NtSetValueKey(KeyHandle, 00559 &ValueName, 00560 0, 00561 REG_SZ, 00562 (PVOID)ACPage, 00563 (wcslen(ACPage)+1) * sizeof(WCHAR)); 00564 if (!NT_SUCCESS(Status)) 00565 { 00566 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00567 NtClose(KeyHandle); 00568 return FALSE; 00569 } 00570 00571 // Set OEM codepage 00572 RtlInitUnicodeString(&ValueName, L"OEMCP"); 00573 Status = NtSetValueKey(KeyHandle, 00574 &ValueName, 00575 0, 00576 REG_SZ, 00577 (PVOID)OEMCPage, 00578 (wcslen(OEMCPage)+1) * sizeof(WCHAR)); 00579 if (!NT_SUCCESS(Status)) 00580 { 00581 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00582 NtClose(KeyHandle); 00583 return FALSE; 00584 } 00585 00586 // Set MAC codepage 00587 RtlInitUnicodeString(&ValueName, L"MACCP"); 00588 Status = NtSetValueKey(KeyHandle, 00589 &ValueName, 00590 0, 00591 REG_SZ, 00592 (PVOID)MACCPage, 00593 (wcslen(MACCPage)+1) * sizeof(WCHAR)); 00594 if (!NT_SUCCESS(Status)) 00595 { 00596 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 00597 NtClose(KeyHandle); 00598 return FALSE; 00599 } 00600 00601 NtClose(KeyHandle); 00602 00603 return TRUE; 00604 } 00605 00606 static BOOLEAN 00607 AddFontsSettingsToRegistry(IN const MUI_SUBFONT * MuiSubFonts) 00608 { 00609 OBJECT_ATTRIBUTES ObjectAttributes; 00610 UNICODE_STRING KeyName; 00611 UNICODE_STRING ValueName; 00612 HANDLE KeyHandle; 00613 NTSTATUS Status; 00614 ULONG uIndex = 0; 00615 00616 RtlInitUnicodeString(&KeyName, 00617 L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SysFontSubstitutes"); 00618 InitializeObjectAttributes(&ObjectAttributes, 00619 &KeyName, 00620 OBJ_CASE_INSENSITIVE, 00621 NULL, 00622 NULL); 00623 Status = NtOpenKey(&KeyHandle, 00624 KEY_WRITE, 00625 &ObjectAttributes); 00626 if (!NT_SUCCESS(Status)) 00627 { 00628 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); 00629 return FALSE; 00630 } 00631 00632 do 00633 { 00634 RtlInitUnicodeString(&ValueName, MuiSubFonts[uIndex].FontName); 00635 Status = NtSetValueKey(KeyHandle, 00636 &ValueName, 00637 0, 00638 REG_SZ, 00639 (PVOID)MuiSubFonts[uIndex].SubFontName, 00640 (wcslen(MuiSubFonts[uIndex].SubFontName)+1) * sizeof(WCHAR)); 00641 if (!NT_SUCCESS(Status)) 00642 { 00643 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); 00644 NtClose(KeyHandle); 00645 return FALSE; 00646 } 00647 00648 uIndex++; 00649 } 00650 while (MuiSubFonts[uIndex].FontName != NULL); 00651 00652 NtClose(KeyHandle); 00653 00654 return TRUE; 00655 } 00656 00657 BOOLEAN 00658 AddCodePage(VOID) 00659 { 00660 ULONG lngIndex = 0; 00661 do 00662 { 00663 if (_wcsicmp(LanguageList[lngIndex].LanguageID , SelectedLanguageId) == 0) 00664 { 00665 if (AddCodepageToRegistry(LanguageList[lngIndex].ACPage, 00666 LanguageList[lngIndex].OEMCPage, 00667 LanguageList[lngIndex].MACCPage)&& 00668 AddFontsSettingsToRegistry(LanguageList[lngIndex].MuiSubFonts)) 00669 { 00670 return TRUE; 00671 } 00672 else 00673 { 00674 return FALSE; 00675 } 00676 } 00677 00678 lngIndex++; 00679 } 00680 while (LanguageList[lngIndex].MuiPages != NULL); 00681 00682 return FALSE; 00683 } 00684 00685 VOID 00686 SetConsoleCodePage(VOID) 00687 { 00688 ULONG lngIndex = 0; 00689 UINT wCodePage; 00690 00691 do 00692 { 00693 if (_wcsicmp(LanguageList[lngIndex].LanguageID , SelectedLanguageId) == 0) 00694 { 00695 wCodePage = (UINT) wcstoul(LanguageList[lngIndex].OEMCPage, NULL, 10); 00696 SetConsoleOutputCP(wCodePage); 00697 return; 00698 } 00699 00700 lngIndex++; 00701 } 00702 while (LanguageList[lngIndex].MuiPages != NULL); 00703 } 00704 00705 /* EOF */ Generated on Sat May 26 2012 04:16:58 for ReactOS by
1.7.6.1
|