2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: freeldr/winldr/wlregistry.c
5 * PURPOSE: Registry support functions
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES ***************************************************************/
22 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
23 IN LPCSTR DirectoryPath
,
24 IN LPCSTR AnsiFileName
,
25 IN LPCSTR OemFileName
,
26 IN LPCSTR LanguageFileName
);
29 /* FUNCTIONS **************************************************************/
32 WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
33 IN LPCSTR DirectoryPath
,
37 CHAR FullHiveName
[256];
40 ULONG_PTR HiveDataPhysical
;
41 PVOID HiveDataVirtual
;
43 /* Concatenate path and filename to get the full name */
44 strcpy(FullHiveName
, DirectoryPath
);
45 strcat(FullHiveName
, HiveName
);
46 //Print(L"Loading %s...\n", FullHiveName);
47 FileHandle
= FsOpenFile(FullHiveName
);
49 if (FileHandle
== NULL
)
51 UiMessageBox("Opening hive file failed!");
55 /* Get the file length */
56 HiveFileSize
= FsGetFileSize(FileHandle
);
58 if (HiveFileSize
== 0)
60 FsCloseFile(FileHandle
);
61 UiMessageBox("Hive file has 0 size!");
65 /* Round up the size to page boundary and alloc memory */
66 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemory(
67 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
);
69 if (HiveDataPhysical
== 0)
71 FsCloseFile(FileHandle
);
72 UiMessageBox("Unable to alloc memory for a hive!");
76 /* Convert address to virtual */
78 HiveDataVirtual
= (PVOID
)(KSEG0_BASE
| HiveDataPhysical
);
80 HiveDataVirtual
= (PVOID
)HiveDataPhysical
;
83 /* Fill LoaderBlock's entries */
84 LoaderBlock
->RegistryLength
= HiveFileSize
;
85 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
87 /* Finally read from file to the memory */
88 Status
= FsReadFile(FileHandle
, HiveFileSize
, NULL
, (PVOID
)HiveDataPhysical
);
89 FsCloseFile(FileHandle
);
92 UiMessageBox("Unable to read from hive file!");
99 // Queries registry for those three file names
100 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
104 LONG rc
= ERROR_SUCCESS
;
106 WCHAR szIdBuffer
[80];
107 WCHAR NameBuffer
[80];
110 /* open the codepage key */
111 rc
= RegOpenKey(NULL
,
112 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
114 if (rc
!= ERROR_SUCCESS
)
116 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
120 /* get ANSI codepage */
121 BufferSize
= sizeof(szIdBuffer
);
122 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
123 if (rc
!= ERROR_SUCCESS
)
125 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
129 BufferSize
= sizeof(NameBuffer
);
130 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
131 if (rc
!= ERROR_SUCCESS
)
133 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
136 sprintf(AnsiName
, "%S", NameBuffer
);
138 /* get OEM codepage */
139 BufferSize
= sizeof(szIdBuffer
);
140 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
141 if (rc
!= ERROR_SUCCESS
)
143 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
147 BufferSize
= sizeof(NameBuffer
);
148 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
149 if (rc
!= ERROR_SUCCESS
)
151 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
154 sprintf(OemName
, "%S", NameBuffer
);
156 /* open the language key */
157 rc
= RegOpenKey(NULL
,
158 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
160 if (rc
!= ERROR_SUCCESS
)
162 //strcpy(szErrorOut, "Couldn't open Language registry key");
166 /* get the Unicode case table */
167 BufferSize
= sizeof(szIdBuffer
);
168 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
169 if (rc
!= ERROR_SUCCESS
)
171 //strcpy(szErrorOut, "Couldn't get Language Default setting");
175 BufferSize
= sizeof(NameBuffer
);
176 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
177 if (rc
!= ERROR_SUCCESS
)
179 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
182 sprintf(LangName
, "%S", NameBuffer
);
187 BOOLEAN
WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
188 IN LPCSTR DirectoryPath
)
190 CHAR SearchPath
[1024];
191 CHAR AnsiName
[256], OemName
[256], LangName
[256];
194 // There is a simple logic here: try to load usual hive (system), if it
195 // fails, then give system.alt a try, and finally try a system.sav
197 // FIXME: For now we only try system
198 strcpy(SearchPath
, DirectoryPath
);
199 strcat(SearchPath
, "SYSTEM32\\CONFIG\\");
200 Status
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, "SYSTEM");
206 // Initialize in-memory registry
207 RegInitializeRegistry();
209 // Import what was loaded
210 Status
= RegImportBinaryHive((PCHAR
)VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
213 UiMessageBox("Importing binary hive failed!");
217 // Initialize the 'CurrentControlSet' link
218 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
220 UiMessageBox("Initializing CurrentControlSet link failed!");
224 Status
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
227 UiMessageBox("Getting NLS names from registry failed!");
231 DbgPrint((DPRINT_WINDOWS
, "NLS data %s %s %s\n", AnsiName
, OemName
, LangName
));
233 /* Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */
234 strcpy(SearchPath
, DirectoryPath
);
235 strcat(SearchPath
, "SYSTEM32\\");
236 Status
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
237 DbgPrint((DPRINT_WINDOWS
, "NLS data loaded with status %d\n", Status
));
243 /* PRIVATE FUNCTIONS ******************************************************/
246 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
247 IN LPCSTR DirectoryPath
,
248 IN LPCSTR AnsiFileName
,
249 IN LPCSTR OemFileName
,
250 IN LPCSTR LanguageFileName
)
253 PFILE AnsiFileHandle
;
255 PFILE LanguageFileHandle
;
256 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
258 ULONG_PTR NlsDataBase
;
260 BOOLEAN Status
, AnsiEqualsOem
= FALSE
;
262 /* There may be a case, when OEM and ANSI page coincide */
263 if (!strcmp(AnsiFileName
, OemFileName
))
264 AnsiEqualsOem
= TRUE
;
266 /* Open file with ANSI and store its size */
267 //Print(L"Loading %s...\n", Filename);
268 strcpy(FileName
, DirectoryPath
);
269 strcat(FileName
, AnsiFileName
);
270 AnsiFileHandle
= FsOpenFile(FileName
);
272 if (AnsiFileHandle
== NULL
)
275 AnsiFileSize
= FsGetFileSize(AnsiFileHandle
);
276 DbgPrint((DPRINT_WINDOWS
, "AnsiFileSize: %d\n", AnsiFileSize
));
277 FsCloseFile(AnsiFileHandle
);
279 /* Open OEM file and store its length */
286 //Print(L"Loading %s...\n", Filename);
287 strcpy(FileName
, DirectoryPath
);
288 strcat(FileName
, OemFileName
);
289 OemFileHandle
= FsOpenFile(FileName
);
291 if (OemFileHandle
== NULL
)
294 OemFileSize
= FsGetFileSize(OemFileHandle
);
295 FsCloseFile(OemFileHandle
);
297 DbgPrint((DPRINT_WINDOWS
, "OemFileSize: %d\n", OemFileSize
));
299 /* And finally open the language codepage file and store its length */
300 //Print(L"Loading %s...\n", Filename);
301 strcpy(FileName
, DirectoryPath
);
302 strcat(FileName
, LanguageFileName
);
303 LanguageFileHandle
= FsOpenFile(FileName
);
305 if (LanguageFileHandle
== NULL
)
308 LanguageFileSize
= FsGetFileSize(LanguageFileHandle
);
309 FsCloseFile(LanguageFileHandle
);
310 DbgPrint((DPRINT_WINDOWS
, "LanguageFileSize: %d\n", LanguageFileSize
));
312 /* Sum up all three length, having in mind that every one of them
313 must start at a page boundary => thus round up each file to a page */
314 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
315 MM_SIZE_TO_PAGES(OemFileSize
) +
316 MM_SIZE_TO_PAGES(LanguageFileSize
);
318 NlsDataBase
= (ULONG_PTR
)MmAllocateMemory(TotalSize
*MM_PAGE_SIZE
);
320 if (NlsDataBase
== 0)
324 NlsVirtual
= (PVOID
)(KSEG0_BASE
| NlsDataBase
);
325 #elif defined(_M_PPC)
326 NlsVirtual
= (PVOID
)NlsDataBase
;
328 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
329 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
330 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
331 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
332 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
333 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
335 /* Ansi and OEM data are the same - just set pointers to the same area */
337 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
340 /* Now actually read the data into memory, starting with Ansi file */
341 strcpy(FileName
, DirectoryPath
);
342 strcat(FileName
, AnsiFileName
);
343 AnsiFileHandle
= FsOpenFile(FileName
);
345 if (AnsiFileHandle
== NULL
)
348 Status
= FsReadFile(AnsiFileHandle
, AnsiFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
));
353 FsCloseFile(AnsiFileHandle
);
355 /* OEM now, if it doesn't equal Ansi of course */
358 strcpy(FileName
, DirectoryPath
);
359 strcat(FileName
, OemFileName
);
360 OemFileHandle
= FsOpenFile(FileName
);
362 if (OemFileHandle
== NULL
)
365 Status
= FsReadFile(OemFileHandle
, OemFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
));
370 FsCloseFile(AnsiFileHandle
);
373 /* finally the language file */
374 strcpy(FileName
, DirectoryPath
);
375 strcat(FileName
, LanguageFileName
);
376 LanguageFileHandle
= FsOpenFile(FileName
);
378 if (LanguageFileHandle
== NULL
)
381 Status
= FsReadFile(LanguageFileHandle
, LanguageFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
));
386 FsCloseFile(LanguageFileHandle
);
389 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
390 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
392 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
394 /* Convert NlsTables address to VA */
395 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
400 //UiMessageBox("Error reading NLS file %s\n", Filename);
401 UiMessageBox("Error reading NLS file!");