xref: /reactos/base/applications/cmdutils/chcp/chcp.c (revision 53221834)
1 /*
2  * PROJECT:     ReactOS Change CodePage Command
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Displays or changes the active console input and output code pages.
5  * COPYRIGHT:   Copyright 1999 Eric Kohl
6  *              Copyright 2017-2021 Hermes Belusca-Maito
7  */
8 /*
9  * CHCP.C - chcp internal command.
10  *
11  * 23-Dec-1998 (Eric Kohl)
12  *     Started.
13  *
14  * 02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
15  *     Remove all hardcoded strings in En.rc
16  */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #include <windef.h>
22 #include <winbase.h>
23 #include <wincon.h>
24 
25 #include <conutils.h>
26 
27 #include "resource.h"
28 
29 // INT CommandChcp(LPTSTR cmd, LPTSTR param)
30 int wmain(int argc, WCHAR* argv[])
31 {
32     UINT uOldCodePage, uNewCodePage;
33 
34     /* Initialize the Console Standard Streams */
35     ConInitStdStreams();
36 
37     /* Print help */
38     if (argc > 1 && wcscmp(argv[1], L"/?") == 0)
39     {
40         ConResPuts(StdOut, STRING_CHCP_HELP);
41         return 0;
42     }
43 
44     if (argc == 1)
45     {
46         /* Display the active code page number */
47         ConResPrintf(StdOut, STRING_CHCP_ERROR1, GetConsoleOutputCP());
48         return 0;
49     }
50 
51     if (argc > 2)
52     {
53         /* Too many parameters */
54         ConResPrintf(StdErr, STRING_ERROR_INVALID_PARAM_FORMAT, argv[2]);
55         return 1;
56     }
57 
58     uNewCodePage = (UINT)_wtoi(argv[1]);
59 
60     if (uNewCodePage == 0)
61     {
62         ConResPrintf(StdErr, STRING_ERROR_INVALID_PARAM_FORMAT, argv[1]);
63         return 1;
64     }
65 
66 /**
67  ** IMPORTANT NOTE: This code must be kept synchronized with MODE.COM!SetConsoleCPState()
68  **/
69 
70     /*
71      * Save the original console code page to be restored
72      * in case SetConsoleCP() or SetConsoleOutputCP() fails.
73      */
74     uOldCodePage = GetConsoleCP();
75 
76     /*
77      * Try changing the console input and output code pages.
78      * If it succeeds, refresh the local code page information.
79      */
80     if (SetConsoleCP(uNewCodePage))
81     {
82         if (SetConsoleOutputCP(uNewCodePage))
83         {
84             /* Success, reset the current thread UI language
85              * and update the streams cached code page. */
86             ConSetThreadUILanguage(0);
87             ConStdStreamsSetCacheCodePage(uNewCodePage, uNewCodePage);
88 
89             /* Display the active code page number */
90             ConResPrintf(StdOut, STRING_CHCP_ERROR1, GetConsoleOutputCP());
91             return 0;
92         }
93         else
94         {
95             /* Failure, restore the original console code page */
96             SetConsoleCP(uOldCodePage);
97         }
98     }
99 
100     /* An error happened, display an error and bail out */
101     ConResPuts(StdErr, STRING_CHCP_ERROR4);
102     return 1;
103 }
104