- Support INIT section pragmas for msvc. Patch by Brezenbak.
[reactos.git] / reactos / ntoskrnl / rtl / nls.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/rtl/nls.c
5 * PURPOSE: Bitmap functions
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <internal/debug.h>
13
14 #if defined (ALLOC_PRAGMA)
15 #pragma alloc_text(INIT, RtlpInitNls)
16 #pragma alloc_text(INIT, RtlpImportAnsiCodePage)
17 #pragma alloc_text(INIT, RtlpImportOemCodePage)
18 #pragma alloc_text(INIT, RtlpImportUnicodeCasemap)
19 #pragma alloc_text(INIT, RtlpCreateInitialNlsTables)
20 #pragma alloc_text(INIT, RtlpCreateNlsSection)
21 #endif
22
23
24 /* GLOBALS *******************************************************************/
25
26
27 static PUSHORT NlsAnsiCodePageTable = NULL;
28 static ULONG NlsAnsiCodePageTableSize = 0;
29
30 static PUSHORT NlsOemCodePageTable = NULL;
31 static ULONG NlsOemCodePageTableSize = 0;
32
33 static PUSHORT NlsUnicodeCasemapTable = NULL;
34 static ULONG NlsUnicodeCasemapTableSize = 0;
35
36 PSECTION_OBJECT NlsSectionObject = NULL;
37 static PVOID NlsSectionBase = NULL;
38 static ULONG NlsSectionViewSize = 0;
39
40 ULONG NlsAnsiTableOffset = 0;
41 ULONG NlsOemTableOffset = 0;
42 ULONG NlsUnicodeTableOffset = 0;
43
44
45 /* FUNCTIONS *****************************************************************/
46
47 VOID
48 INIT_FUNCTION
49 STDCALL
50 RtlpInitNls(VOID)
51 {
52 ULONG_PTR BaseAddress;
53
54 /* Import NLS Data */
55 BaseAddress = CachedModules[AnsiCodepage]->ModStart;
56 RtlpImportAnsiCodePage((PUSHORT)BaseAddress,
57 CachedModules[AnsiCodepage]->ModEnd - BaseAddress);
58
59 BaseAddress = CachedModules[OemCodepage]->ModStart;
60 RtlpImportOemCodePage((PUSHORT)BaseAddress,
61 CachedModules[OemCodepage]->ModEnd - BaseAddress);
62
63 BaseAddress = CachedModules[UnicodeCasemap]->ModStart;
64 RtlpImportUnicodeCasemap((PUSHORT)BaseAddress,
65 CachedModules[UnicodeCasemap]->ModEnd - BaseAddress);
66
67 /* Create initial NLS tables */
68 RtlpCreateInitialNlsTables();
69
70 /* Create the NLS section */
71 RtlpCreateNlsSection();
72 }
73
74 VOID
75 INIT_FUNCTION
76 NTAPI
77 RtlpImportAnsiCodePage(PUSHORT TableBase,
78 ULONG Size)
79 {
80 NlsAnsiCodePageTable = TableBase;
81 NlsAnsiCodePageTableSize = Size;
82 }
83
84
85 VOID
86 INIT_FUNCTION
87 NTAPI
88 RtlpImportOemCodePage(PUSHORT TableBase,
89 ULONG Size)
90 {
91 NlsOemCodePageTable = TableBase;
92 NlsOemCodePageTableSize = Size;
93 }
94
95
96 VOID
97 NTAPI
98 INIT_FUNCTION
99 RtlpImportUnicodeCasemap(PUSHORT TableBase,
100 ULONG Size)
101 {
102 NlsUnicodeCasemapTable = TableBase;
103 NlsUnicodeCasemapTableSize = Size;
104 }
105
106
107 VOID
108 NTAPI
109 INIT_FUNCTION
110 RtlpCreateInitialNlsTables(VOID)
111 {
112 NLSTABLEINFO NlsTable;
113
114 if (NlsAnsiCodePageTable == NULL || NlsAnsiCodePageTableSize == 0 ||
115 NlsOemCodePageTable == NULL || NlsOemCodePageTableSize == 0 ||
116 NlsUnicodeCasemapTable == NULL || NlsUnicodeCasemapTableSize == 0)
117 {
118 KEBUGCHECKEX (0x32, STATUS_UNSUCCESSFUL, 1, 0, 0);
119 }
120
121 RtlInitNlsTables (NlsAnsiCodePageTable,
122 NlsOemCodePageTable,
123 NlsUnicodeCasemapTable,
124 &NlsTable);
125
126 RtlResetRtlTranslations (&NlsTable);
127 }
128
129 VOID
130 NTAPI
131 INIT_FUNCTION
132 RtlpCreateNlsSection(VOID)
133 {
134 NLSTABLEINFO NlsTable;
135 LARGE_INTEGER SectionSize;
136 NTSTATUS Status;
137
138 DPRINT("RtlpCreateNlsSection() called\n");
139
140 NlsSectionViewSize = ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE) +
141 ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE) +
142 ROUND_UP(NlsUnicodeCasemapTableSize, PAGE_SIZE);
143
144 DPRINT("NlsSectionViewSize %lx\n", NlsSectionViewSize);
145
146 SectionSize.QuadPart = (LONGLONG)NlsSectionViewSize;
147 Status = MmCreateSection(&NlsSectionObject,
148 SECTION_ALL_ACCESS,
149 NULL,
150 &SectionSize,
151 PAGE_READWRITE,
152 SEC_COMMIT,
153 NULL,
154 NULL);
155 if (!NT_SUCCESS(Status))
156 {
157 DPRINT1("MmCreateSection() failed\n");
158 KEBUGCHECKEX(0x32, Status, 1, 1, 0);
159 }
160 Status = ObInsertObject(NlsSectionObject,
161 NULL,
162 SECTION_ALL_ACCESS,
163 0,
164 NULL,
165 NULL);
166 if (!NT_SUCCESS(Status))
167 {
168 ObDereferenceObject(NlsSectionObject);
169 }
170 Status = MmMapViewInSystemSpace(NlsSectionObject,
171 &NlsSectionBase,
172 &NlsSectionViewSize);
173 if (!NT_SUCCESS(Status))
174 {
175 DPRINT1("MmMapViewInSystemSpace() failed\n");
176 KEBUGCHECKEX(0x32, Status, 1, 3, 0);
177 }
178
179 DPRINT("NlsSection: Base %p Size %lx\n",
180 NlsSectionBase,
181 NlsSectionViewSize);
182
183 NlsAnsiTableOffset = 0;
184 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
185 NlsAnsiCodePageTable,
186 NlsAnsiCodePageTableSize);
187
188 NlsOemTableOffset = NlsAnsiTableOffset + ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE);
189 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
190 NlsOemCodePageTable,
191 NlsOemCodePageTableSize);
192
193 NlsUnicodeTableOffset = NlsOemTableOffset + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE);
194 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
195 NlsUnicodeCasemapTable,
196 NlsUnicodeCasemapTableSize);
197
198 RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
199 (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
200 (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
201 &NlsTable);
202
203 RtlResetRtlTranslations (&NlsTable);
204 }