ReactOS 0.4.15-dev-7918-g2a2556c
country.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/country.c
5 * PURPOSE: DOS32 Country support
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 *
8 * NOTE: Support for default (english) language only.
9 * For other languages, please use COUNTRY.SYS
10 */
11
12/* INCLUDES *******************************************************************/
13
14#include "ntvdm.h"
15
16#define NDEBUG
17#include <debug.h>
18
19#include "emulator.h"
20
21#include "country.h"
22#include "memory.h"
23
24/* PRIVATE VARIABLES **********************************************************/
25
26/* CaseMap routine: should call INT 65h, AL=20h */
27// ATM, just do nothing.
28static const BYTE CaseMapRoutine[] =
29{
30 0xCB // retf
31};
32
33#pragma pack(push, 1)
34
35#define DATATABLE(name, type, len) \
36 typedef struct _##name \
37 { \
38 WORD Size; \
39 type Data[(len)]; \
40 } name
41
42DATATABLE(UPPERCASE, CHAR, 0xFF-0x80+1);
43DATATABLE(LOWERCASE, CHAR, 0xFF-0x00+1);
44DATATABLE(FNAMETERM, BYTE, 22);
45DATATABLE(COLLATE , BYTE, 0xFF-0x00+1);
46DATATABLE(DBCSLEAD , WORD, 0x00+1);
47
48typedef struct _COUNTRY_DATA
49{
51 UPPERCASE UpCaseTbl; // Used also for filename uppercase
52 LOWERCASE LoCaseTbl;
53 FNAMETERM FNameTermTbl;
54 COLLATE CollateTbl;
55 DBCSLEAD DBCSLeadTbl;
57
58#pragma pack(pop)
59
60/* Global data contained in guest memory */
63
64WORD YesNoTable[2] = { MAKEWORD('Y', 0), MAKEWORD('N', 0) };
65
66/*
67 * See: http://www.ctyme.com/intr/rb-3163.htm#Table1754
68 * http://www.ctyme.com/intr/rb-3164.htm
69 * http://www.ctyme.com/intr/rb-3166.htm
70 */
71
72/* PRIVATE FUNCTIONS **********************************************************/
73
74/* PUBLIC FUNCTIONS ***********************************************************/
75
76WORD
78 OUT PDOS_COUNTRY_INFO CountryInfo)
79{
80 INT Return;
81 DWORD NumVal;
82
83 Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE | LOCALE_RETURN_NUMBER, // LOCALE_ILDATE | LOCALE_RETURN_NUMBER
84 (LPSTR)&NumVal,
85 sizeof(NumVal));
86 if (Return == 0) return LOWORD(GetLastError());
87 CountryInfo->DateTimeFormat = (WORD)NumVal;
88
90 (LPSTR)&CountryInfo->CurrencySymbol,
91 sizeof(CountryInfo->CurrencySymbol));
92 if (Return == 0) return LOWORD(GetLastError());
93
95 (LPSTR)&CountryInfo->ThousandSep,
96 sizeof(CountryInfo->ThousandSep));
97 if (Return == 0) return LOWORD(GetLastError());
98
100 (LPSTR)&CountryInfo->DecimalSep,
101 sizeof(CountryInfo->DecimalSep));
102 if (Return == 0) return LOWORD(GetLastError());
103
105 (LPSTR)&CountryInfo->DateSep,
106 sizeof(CountryInfo->DateSep));
107 if (Return == 0) return LOWORD(GetLastError());
108
110 (LPSTR)&CountryInfo->TimeSep,
111 sizeof(CountryInfo->TimeSep));
112 if (Return == 0) return LOWORD(GetLastError());
113
114 // NOTE: '4: Symbol replace decimal separator' is unsupported.
115 Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
116 (LPSTR)&NumVal,
117 sizeof(NumVal));
118 if (Return == 0) return LOWORD(GetLastError());
119 CountryInfo->CurrencyFormat = (BYTE)NumVal;
120
121 Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, // LOCALE_IDIGITS | LOCALE_RETURN_NUMBER
122 (LPSTR)&NumVal,
123 sizeof(NumVal));
124 if (Return == 0) return LOWORD(GetLastError());
125 CountryInfo->CurrencyDigitsNum = (BYTE)NumVal;
126
127 Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME | LOCALE_RETURN_NUMBER,
128 (LPSTR)&NumVal,
129 sizeof(NumVal));
130 if (Return == 0) return LOWORD(GetLastError());
131 CountryInfo->TimeFormat = (BYTE)NumVal;
132
134
135 // CountryInfo->DataListSep;
136
137 return ERROR_SUCCESS;
138}
139
140WORD
142 IN WORD CodePage,
143 IN WORD CountryId,
144 OUT PDOS_COUNTRY_INFO_2 CountryInfo,
146{
147 // FIXME: use: CodePage; CountryId
148 // FIXME: Check BufferSize
149 // FIXME: Use NLSFUNC resident?
150
151 switch (InfoId)
152 {
153 /* Get General Internationalization Info (similar to AX=3800h) */
154 case 0x01:
155 {
157 ErrorCode = DosGetCountryInfo(&CountryId,
158 &CountryInfo->CountryInfoEx.CountryInfo);
159 if (ErrorCode != ERROR_SUCCESS) return ErrorCode;
160 CountryInfo->CountryInfoEx.Size = sizeof(CountryInfo->CountryInfoEx);
161 CountryInfo->CountryInfoEx.CountryId = CountryId;
162 // CountryInfo->CodePage;
163 break;
164 }
165
166 /* Get Pointer to Uppercase Table */
167 case 0x02:
168 CountryInfo->UpCaseTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, UpCaseTbl), CountryDataSegment);
169 break;
170
171 /* Get Pointer to Lowercase Table */
172 case 0x03:
173 CountryInfo->LoCaseTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, LoCaseTbl), CountryDataSegment);
174 break;
175
176 /* Get Pointer to Filename Uppercase Table */
177 case 0x04:
178 CountryInfo->FNameUpCaseTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, UpCaseTbl), CountryDataSegment);
179 break;
180
181 /* Get Pointer to Filename Terminator Table */
182 case 0x05:
183 CountryInfo->FNameTermTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, FNameTermTbl), CountryDataSegment);
184 break;
185
186 /* Get Pointer to Collating Sequence Table */
187 case 0x06:
188 CountryInfo->CollateTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, CollateTbl), CountryDataSegment);
189 break;
190
191 /* Get Pointer to Double-Byte Character Set Table */
192 case 0x07:
193 CountryInfo->DBCSLeadTblPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, DBCSLeadTbl), CountryDataSegment);
194 break;
195
196 default:
198 }
199 CountryInfo->InfoId = InfoId;
200
201 return ERROR_SUCCESS;
202}
203
205{
206 Char = toupper(Char);
207
208 /* NO-type */
209 if (Char == YesNoTable[1])
210 return 0x0000;
211 /* YES-type */
212 if (Char == YesNoTable[0])
213 return 0x0001;
214 /* Unknown type */
215 return 0x0002;
216}
217
219{
220 // FIXME: Use the current locale
221 return toupper(Char);
222}
223
225{
226 while (Length-- > 0)
227 *DestStr++ = toupper(*SrcStr++);
228}
229
230VOID DosToUpperStrZ(PSTR DestStr, PSTR SrcStr)
231{
232 while (*SrcStr)
233 *DestStr++ = toupper(*SrcStr++);
234}
235
237{
238 UINT i;
239
240 /* Initialize some memory to store country information */
241 // FIXME: Can we use instead some static area from the DOS data structure??
243 if (CountryDataSegment == 0) return FALSE;
245
248 sizeof(CaseMapRoutine));
249
251 for (i = 0; i < CountryData->UpCaseTbl.Size; ++i)
252 CountryData->UpCaseTbl.Data[i] = 0x80 + i;
253
255 for (i = 0; i < CountryData->LoCaseTbl.Size; ++i)
256 CountryData->LoCaseTbl.Data[i] = i;
257
259 CountryData->FNameTermTbl.Data[ 0] = 0x01; // Dummy Byte
260 CountryData->FNameTermTbl.Data[ 1] = 0x00; // Lowest permissible Character Value for Filename
261 CountryData->FNameTermTbl.Data[ 2] = 0xFF; // Highest permissible Character Value for Filename
262 CountryData->FNameTermTbl.Data[ 3] = 0x00; // Dummy Byte
263 CountryData->FNameTermTbl.Data[ 4] = 0x00; // First excluded Character in Range \ all characters in this
264 CountryData->FNameTermTbl.Data[ 5] = 0x20; // Last excluded Character in Range / range are illegal
265 CountryData->FNameTermTbl.Data[ 6] = 0x02; // Dummy Byte
266 CountryData->FNameTermTbl.Data[ 7] = 14; // Number of illegal (terminator) Characters
267// CountryData->FNameTermTbl.Data[ 8] = ".\"/\\[]:|<>+=;,"; // Characters which terminate a Filename
268 CountryData->FNameTermTbl.Data[ 8] = '.';
269 CountryData->FNameTermTbl.Data[ 9] = '\"';
270 CountryData->FNameTermTbl.Data[10] = '/';
271 CountryData->FNameTermTbl.Data[11] = '\\';
272 CountryData->FNameTermTbl.Data[12] = '[';
273 CountryData->FNameTermTbl.Data[13] = ']';
274 CountryData->FNameTermTbl.Data[14] = ':';
275 CountryData->FNameTermTbl.Data[15] = '|';
276 CountryData->FNameTermTbl.Data[16] = '<';
277 CountryData->FNameTermTbl.Data[17] = '>';
278 CountryData->FNameTermTbl.Data[18] = '+';
279 CountryData->FNameTermTbl.Data[19] = '=';
280 CountryData->FNameTermTbl.Data[20] = ';';
281 CountryData->FNameTermTbl.Data[21] = ',';
282
284 for (i = 0; i < CountryData->CollateTbl.Size; ++i)
285 CountryData->CollateTbl.Data[i] = i;
286
287 CountryData->DBCSLeadTbl.Size = 0; // Empty DBCS table
288 CountryData->DBCSLeadTbl.Data[0] = 0x0000;
289
290 return TRUE;
291}
unsigned char BOOLEAN
int toupper(int c)
Definition: utclib.c:881
WORD DosIfCharYesNo(WORD Char)
Definition: country.c:204
static const BYTE CaseMapRoutine[]
Definition: country.c:28
VOID DosToUpperStrZ(PSTR DestStr, PSTR SrcStr)
Definition: country.c:230
BOOLEAN DosCountryInitialize(VOID)
Definition: country.c:236
WORD DosGetCountryInfoEx(IN BYTE InfoId, IN WORD CodePage, IN WORD CountryId, OUT PDOS_COUNTRY_INFO_2 CountryInfo, IN OUT PWORD BufferSize)
Definition: country.c:141
static WORD CountryDataSegment
Definition: country.c:61
struct _COUNTRY_DATA * PCOUNTRY_DATA
static PCOUNTRY_DATA CountryData
Definition: country.c:62
WORD DosGetCountryInfo(IN OUT PWORD CountryId, OUT PDOS_COUNTRY_INFO CountryInfo)
Definition: country.c:77
WORD YesNoTable[2]
Definition: country.c:64
CHAR DosToUpper(CHAR Char)
Definition: country.c:218
#define DATATABLE(name, type, len)
Definition: country.c:35
VOID DosToUpperStrN(PCHAR DestStr, PCHAR SrcStr, WORD Length)
Definition: country.c:224
struct _COUNTRY_DATA COUNTRY_DATA
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:1028
unsigned int UINT
Definition: ndis.h:50
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define LOCALE_USER_DEFAULT
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define LOWORD(l)
Definition: pedump.c:82
WORD * PWORD
Definition: pedump.c:67
LOWERCASE LoCaseTbl
Definition: country.c:52
BYTE CaseMapRoutine[sizeof(CaseMapRoutine)]
Definition: country.c:50
DBCSLEAD DBCSLeadTbl
Definition: country.c:55
COLLATE CollateTbl
Definition: country.c:54
UPPERCASE UpCaseTbl
Definition: country.c:51
FNAMETERM FNameTermTbl
Definition: country.c:53
WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
Definition: memory.c:136
char * PSTR
Definition: typedefs.h:51
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOCALE_ICURRDIGITS
Definition: winnls.h:54
#define LOCALE_SDATE
Definition: winnls.h:58
#define LOCALE_SDECIMAL
Definition: winnls.h:42
#define LOCALE_IDATE
Definition: winnls.h:63
#define LOCALE_ITIME
Definition: winnls.h:65
#define LOCALE_ICURRENCY
Definition: winnls.h:56
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define LOCALE_STIME
Definition: winnls.h:59
#define LOCALE_SCURRENCY
Definition: winnls.h:49
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193