mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented NLS section (not usable yet) and updated NLS functions.
svn path=/trunk/; revision=4685
This commit is contained in:
parent
54aa3104d4
commit
556a38e0c0
14 changed files with 449 additions and 362 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rtl.h,v 1.7 2003/04/26 23:13:27 hyperion Exp $
|
||||
/* $Id: rtl.h,v 1.8 2003/05/15 11:01:02 ekohl Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -921,7 +921,7 @@ RtlCreateUnicodeStringFromAsciiz (OUT PUNICODE_STRING Destination,
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
RtlCustomCPToUnicodeN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
IN PCPTABLEINFO CustomCP,
|
||||
PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -1181,7 +1181,7 @@ RtlImageDirectoryEntryToData (
|
|||
PIMAGE_NT_HEADERS
|
||||
STDCALL
|
||||
RtlImageNtHeader (
|
||||
PVOID BaseAddress
|
||||
IN PVOID BaseAddress
|
||||
);
|
||||
|
||||
PIMAGE_SECTION_HEADER
|
||||
|
@ -1208,6 +1208,22 @@ RtlInitAnsiString (
|
|||
PCSZ SourceString
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
RtlInitCodePageTable (
|
||||
IN PUSHORT TableBase,
|
||||
OUT PCPTABLEINFO CodePageTable
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
RtlInitNlsTables (
|
||||
OUT PNLSTABLEINFO NlsTable,
|
||||
IN PUSHORT CaseTableBase,
|
||||
IN PUSHORT OemTableBase,
|
||||
IN PUSHORT AnsiTableBase
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
RtlInitString (
|
||||
|
@ -1282,15 +1298,21 @@ RtlIsGenericTableEmpty (
|
|||
IN PRTL_GENERIC_TABLE Table
|
||||
);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName,
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
RtlIsNameLegalDOS8Dot3 (
|
||||
IN PUNICODE_STRING UnicodeName,
|
||||
IN PANSI_STRING AnsiName,
|
||||
OUT PBOOLEAN SpacesFound);
|
||||
OUT PBOOLEAN SpacesFound
|
||||
);
|
||||
|
||||
ULONG STDCALL
|
||||
RtlIsTextUnicode (PVOID Buffer,
|
||||
ULONG
|
||||
STDCALL
|
||||
RtlIsTextUnicode (
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
ULONG *Flags);
|
||||
ULONG *Flags
|
||||
);
|
||||
|
||||
LARGE_INTEGER
|
||||
STDCALL
|
||||
|
@ -1626,12 +1648,21 @@ RtlReAllocateHeap (
|
|||
DWORD size
|
||||
);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlReserveChunk(IN USHORT CompressionFormat,
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlReserveChunk (
|
||||
IN USHORT CompressionFormat,
|
||||
IN OUT PUCHAR *CompressedBuffer,
|
||||
IN PUCHAR EndOfCompressedBufferPlus1,
|
||||
OUT PUCHAR *ChunkBuffer,
|
||||
IN ULONG ChunkSize);
|
||||
IN ULONG ChunkSize
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
RtlResetRtlTranslations (
|
||||
IN PNLSTABLEINFO NlsTable
|
||||
);
|
||||
|
||||
/*
|
||||
* VOID
|
||||
|
@ -1835,7 +1866,7 @@ RtlUnicodeStringToOemString (
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
RtlUnicodeToCustomCPN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
IN PCPTABLEINFO CustomCP,
|
||||
PCHAR MbString,
|
||||
ULONG MbSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -1927,7 +1958,7 @@ RtlUpcaseUnicodeStringToOemString (
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
RtlUpcaseUnicodeToCustomCPN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
IN PCPTABLEINFO CustomCP,
|
||||
PCHAR MbString,
|
||||
ULONG MbSize,
|
||||
PULONG ResultSize,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rtltypes.h,v 1.5 2003/04/26 23:13:27 hyperion Exp $
|
||||
/* $Id: rtltypes.h,v 1.6 2003/05/15 11:01:02 ekohl Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -153,36 +153,32 @@ typedef struct _RTL_ATOM_TABLE
|
|||
LIST_ENTRY Slot[0];
|
||||
} RTL_ATOM_TABLE, *PRTL_ATOM_TABLE;
|
||||
|
||||
typedef struct _LB_RANGE
|
||||
{
|
||||
UCHAR upper;
|
||||
UCHAR lower;
|
||||
} LB_RANGE;
|
||||
|
||||
typedef struct _RTL_NLS_DATA
|
||||
#define MAXIMUM_LEADBYTES 12
|
||||
|
||||
typedef struct _CPTABLEINFO
|
||||
{
|
||||
USHORT CodePage;
|
||||
USHORT MaxCharacterSize; // SBCS = 1, DBCS = 2
|
||||
WCHAR DefaultCharacter;
|
||||
WCHAR char1;
|
||||
WCHAR char2;
|
||||
WCHAR char3;
|
||||
USHORT DbcsFlag;
|
||||
LB_RANGE LeadByteRange[6];
|
||||
USHORT reserved;
|
||||
PWCHAR MultiByteToUnicode;
|
||||
PCHAR UnicodeToMultiByte;
|
||||
PWCHAR DosMultiByteToUnicode;
|
||||
PCHAR DbcsTags;
|
||||
} RTL_NLS_DATA, *PRTL_NLS_DATA;
|
||||
USHORT MaximumCharacterSize; // SBCS = 1, DBCS = 2
|
||||
USHORT DefaultCharacter;
|
||||
USHORT UniDefaultChar;
|
||||
USHORT TransDefaultChar;
|
||||
USHORT TransUniDefaultChar;
|
||||
USHORT DBCSCodePage;
|
||||
UCHAR LeadByte[MAXIMUM_LEADBYTES];
|
||||
PUSHORT MultiByteTable;
|
||||
PVOID WideCharTable;
|
||||
PUSHORT DBCSRanges;
|
||||
PUSHORT DBCSOffsets;
|
||||
} CPTABLEINFO, *PCPTABLEINFO;
|
||||
|
||||
typedef struct _RTL_NLS_TABLE
|
||||
typedef struct _NLSTABLEINFO
|
||||
{
|
||||
RTL_NLS_DATA OemInfo;
|
||||
RTL_NLS_DATA AnsiInfo;
|
||||
PWCHAR UpcaseTable;
|
||||
PWCHAR DowncaseTable;
|
||||
} RTL_NLS_TABLE, *PRTL_NLS_TABLE;
|
||||
CPTABLEINFO OemTableInfo;
|
||||
CPTABLEINFO AnsiTableInfo;
|
||||
PUSHORT UpperCaseTable;
|
||||
PUSHORT LowerCaseTable;
|
||||
} NLSTABLEINFO, *PNLSTABLEINFO;
|
||||
|
||||
|
||||
typedef struct _RTL_GENERIC_TABLE
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.def,v 1.98 2003/04/29 02:16:59 hyperion Exp $
|
||||
; $Id: ntdll.def,v 1.99 2003/05/15 11:02:03 ekohl Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -441,8 +441,8 @@ RtlImageRvaToSection@12
|
|||
RtlImageRvaToVa@16
|
||||
RtlImpersonateSelf@4
|
||||
RtlInitAnsiString@8
|
||||
;RtlInitCodePageTable
|
||||
;RtlInitNlsTables
|
||||
RtlInitCodePageTable@8
|
||||
RtlInitNlsTables@16
|
||||
RtlInitString@8
|
||||
RtlInitUnicodeString@8
|
||||
;RtlInitializeAtomPackage
|
||||
|
@ -526,7 +526,7 @@ RtlReAllocateHeap@16
|
|||
RtlReleasePebLock@0
|
||||
RtlReleaseResource@4
|
||||
;RtlRemoteCall
|
||||
;RtlResetRtlTranslations
|
||||
RtlResetRtlTranslations@4
|
||||
RtlRunDecodeUnicodeString@8
|
||||
RtlRunEncodeUnicodeString@8
|
||||
RtlSecondsSince1970ToTime@8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.edf,v 1.87 2003/04/29 02:16:59 hyperion Exp $
|
||||
; $Id: ntdll.edf,v 1.88 2003/05/15 11:02:03 ekohl Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -52,7 +52,7 @@ LdrQueryProcessModuleInformation=LdrQueryProcessModuleInformation@12
|
|||
LdrShutdownProcess=LdrShutdownProcess@0
|
||||
LdrShutdownThread=LdrShutdownThread@0
|
||||
LdrUnloadDll=LdrUnloadDll@4
|
||||
;LdrVerifyImageMatchesChecksum@16
|
||||
;LdrVerifyImageMatchesChecksum=LdrVerifyImageMatchesChecksum@16
|
||||
NlsAnsiCodePage DATA
|
||||
NlsMbCodePageTag DATA
|
||||
NlsMbOemCodePageTag DATA
|
||||
|
@ -440,8 +440,8 @@ RtlImageRvaToSection=RtlImageRvaToSection@12
|
|||
RtlImageRvaToVa=RtlImageRvaToVa@16
|
||||
RtlImpersonateSelf=RtlImpersonateSelf@4
|
||||
RtlInitAnsiString=RtlInitAnsiString@8
|
||||
;RtlInitCodePageTable
|
||||
;RtlInitNlsTables
|
||||
RtlInitCodePageTable=RtlInitCodePageTable@8
|
||||
RtlInitNlsTables=RtlInitNlsTables@16
|
||||
RtlInitString=RtlInitString@8
|
||||
RtlInitUnicodeString=RtlInitUnicodeString@8
|
||||
;RtlInitializeAtomPackage
|
||||
|
@ -525,7 +525,7 @@ RtlReAllocateHeap=RtlReAllocateHeap@16
|
|||
RtlReleasePebLock=RtlReleasePebLock@0
|
||||
RtlReleaseResource=RtlReleaseResource@4
|
||||
;RtlRemoteCall
|
||||
;RtlResetRtlTranslations
|
||||
RtlResetRtlTranslations=RtlResetRtlTranslations@4
|
||||
RtlRunDecodeUnicodeString=RtlRunDecodeUnicodeString@8
|
||||
RtlRunEncodeUnicodeString=RtlRunEncodeUnicodeString@8
|
||||
RtlSecondsSince1970ToTime=RtlSecondsSince1970ToTime@8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: exception.c,v 1.13 2003/04/07 23:10:08 gvg Exp $
|
||||
/* $Id: exception.c,v 1.14 2003/05/15 11:03:20 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -70,6 +70,6 @@ RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress,
|
|||
ExitStatus = (NTSTATUS) (StartAddress)(Parameter);
|
||||
|
||||
NtTerminateProcess(NtCurrentProcess(), ExitStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: image.c,v 1.4 2002/09/08 10:23:05 chorns Exp $
|
||||
/* $Id: image.c,v 1.5 2003/05/15 11:03:21 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -29,12 +29,13 @@ RtlImageNtHeader (IN PVOID BaseAddress)
|
|||
DPRINT1("NtHeader %x\n", (BaseAddress + DosHeader->e_lfanew));
|
||||
}
|
||||
|
||||
// if (DosHeader && DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
// {
|
||||
if (DosHeader && DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
NtHeader = (PIMAGE_NT_HEADERS)(BaseAddress + DosHeader->e_lfanew);
|
||||
if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
|
||||
return NtHeader;
|
||||
// }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: nls.c,v 1.7 2003/03/16 13:07:02 chorns Exp $
|
||||
/* $Id: nls.c,v 1.8 2003/05/15 11:03:21 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -59,21 +59,14 @@ PWCHAR NlsUnicodeLowercaseTable = NULL;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* Missing functions:
|
||||
* RtlInitCodePageTable
|
||||
* RtlInitNlsTables
|
||||
* RtlResetRtlTranslations
|
||||
*/
|
||||
|
||||
/*
|
||||
* RtlConsoleMultiByteToUnicodeN@24
|
||||
*/
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlCustomCPToUnicodeN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
|
||||
PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -83,7 +76,7 @@ RtlCustomCPToUnicodeN (
|
|||
ULONG Size = 0;
|
||||
ULONG i;
|
||||
|
||||
if (NlsData->DbcsFlag == FALSE)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
|
||||
|
@ -96,7 +89,7 @@ RtlCustomCPToUnicodeN (
|
|||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
*UnicodeString = NlsData->MultiByteToUnicode[(int)*CustomString];
|
||||
*UnicodeString = CustomCP->MultiByteTable[(int)*CustomString];
|
||||
UnicodeString++;
|
||||
CustomString++;
|
||||
}
|
||||
|
@ -112,18 +105,33 @@ RtlCustomCPToUnicodeN (
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
RtlGetDefaultCodePage (
|
||||
PUSHORT AnsiCodePage,
|
||||
PUSHORT OemCodePage
|
||||
)
|
||||
VOID STDCALL
|
||||
RtlGetDefaultCodePage(PUSHORT AnsiCodePage,
|
||||
PUSHORT OemCodePage)
|
||||
{
|
||||
*AnsiCodePage = NlsAnsiCodePage;
|
||||
*OemCodePage = NlsOemCodePage;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlInitCodePageTable(IN PUSHORT TableBase,
|
||||
OUT PCPTABLEINFO CodePageTable)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlInitNlsTables(OUT PNLSTABLEINFO NlsTable,
|
||||
IN PUSHORT CaseTableBase,
|
||||
IN PUSHORT OemTableBase,
|
||||
IN PUSHORT AnsiTableBase)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlMultiByteToUnicodeN (
|
||||
|
@ -240,21 +248,25 @@ RtlOemToUnicodeN (
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlUnicodeToCustomCPN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
VOID STDCALL
|
||||
RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
|
||||
PCHAR CustomString,
|
||||
ULONG CustomSize,
|
||||
PULONG ResultSize,
|
||||
PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize
|
||||
)
|
||||
ULONG UnicodeSize)
|
||||
{
|
||||
ULONG Size = 0;
|
||||
ULONG i;
|
||||
|
||||
if (NlsData->DbcsFlag == 0)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
|
||||
|
@ -267,7 +279,7 @@ RtlUnicodeToCustomCPN (
|
|||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
*CustomString = NlsData->UnicodeToMultiByte[*UnicodeString];
|
||||
*CustomString = ((PCHAR)CustomCP->WideCharTable)[*UnicodeString];
|
||||
CustomString++;
|
||||
UnicodeString++;
|
||||
}
|
||||
|
@ -400,22 +412,19 @@ RtlUnicodeToOemN (
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlUpcaseUnicodeToCustomCPN (
|
||||
PRTL_NLS_DATA NlsData,
|
||||
NTSTATUS STDCALL
|
||||
RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
|
||||
PCHAR CustomString,
|
||||
ULONG CustomSize,
|
||||
PULONG ResultSize,
|
||||
PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize
|
||||
)
|
||||
ULONG UnicodeSize)
|
||||
{
|
||||
WCHAR UpcaseChar;
|
||||
ULONG Size = 0;
|
||||
ULONG i;
|
||||
|
||||
if (NlsData->DbcsFlag == 0)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
|
||||
|
@ -428,7 +437,7 @@ RtlUpcaseUnicodeToCustomCPN (
|
|||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
*CustomString = NlsData->UnicodeToMultiByte[*UnicodeString];
|
||||
*CustomString = ((PCHAR)CustomCP->WideCharTable)[*UnicodeString];
|
||||
#if 0
|
||||
UpcaseChar = NlsUnicodeUpcaseTable[*UnicodeString];
|
||||
*CustomString = NlsData->UnicodeToMultiByte[UpcaseChar];
|
||||
|
|
33
reactos/ntoskrnl/include/internal/nls.h
Normal file
33
reactos/ntoskrnl/include/internal/nls.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2003 Eric Kohl <ekohl@rz-online.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_NLS_H
|
||||
#define __NTOSKRNL_INCLUDE_INTERNAL_NLS_H
|
||||
|
||||
|
||||
extern PSECTION_OBJECT NlsSection;
|
||||
|
||||
|
||||
VOID RtlpInitNlsTables(VOID);
|
||||
NTSTATUS RtlpInitNlsSection(VOID);
|
||||
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_NLS_H */
|
||||
|
||||
/* EOF */
|
|
@ -50,15 +50,6 @@ BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
|
|||
BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
|
||||
VOID KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
|
||||
VOID RtlpInitNlsTables(VOID);
|
||||
|
||||
NTSTATUS RtlpInitNlsSections(ULONG Mod1Start,
|
||||
ULONG Mod1End,
|
||||
ULONG Mod2Start,
|
||||
ULONG Mod2End,
|
||||
ULONG Mod3Start,
|
||||
ULONG Mod3End);
|
||||
|
||||
#endif /* __ASM__ */
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: main.c,v 1.153 2003/05/13 21:28:26 chorns Exp $
|
||||
/* $Id: main.c,v 1.154 2003/05/15 11:05:20 ekohl Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
|
@ -47,6 +47,7 @@
|
|||
#include <internal/trap.h>
|
||||
#include "../dbg/kdb.h"
|
||||
#include <internal/registry.h>
|
||||
#include <internal/nls.h>
|
||||
#include <reactos/bugcodes.h>
|
||||
|
||||
#ifdef HALDBG
|
||||
|
@ -333,7 +334,7 @@ ExpInitializeExecutive(VOID)
|
|||
(PADDRESS_RANGE)&KeMemoryMap,
|
||||
KeMemoryMapRangeCount);
|
||||
|
||||
/* create default nls tables */
|
||||
/* Create default nls tables */
|
||||
RtlpInitNlsTables();
|
||||
|
||||
/*
|
||||
|
@ -425,6 +426,10 @@ ExpInitializeExecutive(VOID)
|
|||
CmInitializeRegistry();
|
||||
NtInit();
|
||||
MmInit3();
|
||||
|
||||
/* Create the nls section */
|
||||
RtlpInitNlsSection();
|
||||
|
||||
CcInit();
|
||||
KdInit2();
|
||||
FsRtlpInitFileLockingImplementation();
|
||||
|
@ -444,42 +449,6 @@ ExpInitializeExecutive(VOID)
|
|||
KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
|
||||
}
|
||||
|
||||
/* Pass 1: load nls files */
|
||||
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
|
||||
{
|
||||
name = (PCHAR)KeLoaderModules[i].String;
|
||||
if (RtlpCheckFileNameExtension(name, ".nls"))
|
||||
{
|
||||
ULONG Mod2Start = 0;
|
||||
ULONG Mod2End = 0;
|
||||
ULONG Mod3Start = 0;
|
||||
ULONG Mod3End = 0;
|
||||
|
||||
name = (PCHAR)KeLoaderModules[i+1].String;
|
||||
if (RtlpCheckFileNameExtension(name, ".nls"))
|
||||
{
|
||||
Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
|
||||
Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
|
||||
|
||||
name = (PCHAR)KeLoaderModules[i+2].String;
|
||||
if (RtlpCheckFileNameExtension(name, ".nls"))
|
||||
{
|
||||
Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
|
||||
Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize nls sections */
|
||||
RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
|
||||
(ULONG)KeLoaderModules[i].ModEnd,
|
||||
Mod2Start,
|
||||
Mod2End,
|
||||
Mod3Start,
|
||||
Mod3End);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 2: import system hive registry chunk */
|
||||
SetupBoot = TRUE;
|
||||
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
|
||||
|
@ -629,6 +598,7 @@ ExpInitializeExecutive(VOID)
|
|||
{
|
||||
KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Crash the system if the initial process terminates within 5 seconds.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.def,v 1.151 2003/04/25 18:36:10 fireball Exp $
|
||||
; $Id: ntoskrnl.def,v 1.152 2003/05/15 11:07:51 ekohl Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -758,7 +758,7 @@ RtlGetGroupSecurityDescriptor@12
|
|||
RtlGetOwnerSecurityDescriptor@12
|
||||
RtlImageNtHeader@4
|
||||
RtlInitAnsiString@8
|
||||
;RtlInitCodePageTable
|
||||
RtlInitCodePageTable@8
|
||||
RtlInitString@8
|
||||
RtlInitUnicodeString@8
|
||||
RtlInitializeBitMap@12
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.edf,v 1.137 2003/04/25 18:36:10 fireball Exp $
|
||||
; $Id: ntoskrnl.edf,v 1.138 2003/05/15 11:07:51 ekohl Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -757,7 +757,7 @@ RtlGetGroupSecurityDescriptor=RtlGetGroupSecurityDescriptor@12
|
|||
RtlGetOwnerSecurityDescriptor=RtlGetOwnerSecurityDescriptor@12
|
||||
RtlImageNtHeader=RtlImageNtHeader@4
|
||||
RtlInitAnsiString=RtlInitAnsiString@8
|
||||
;RtlInitCodePageTable
|
||||
RtlInitCodePageTable=RtlInitCodePageTable@8
|
||||
RtlInitString=RtlInitString@8
|
||||
RtlInitUnicodeString=RtlInitUnicodeString@8
|
||||
RtlInitializeBitMap=RtlInitializeBitMap@12
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: process.c,v 1.97 2003/04/26 23:13:33 hyperion Exp $
|
||||
/* $Id: process.c,v 1.98 2003/05/15 11:06:24 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -28,10 +28,12 @@
|
|||
#include <roscfg.h>
|
||||
#include <internal/se.h>
|
||||
#include <internal/kd.h>
|
||||
#include <internal/nls.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
|
||||
|
@ -54,8 +56,8 @@ static ULONG PiProcessNotifyRoutineCount = 0;
|
|||
static PCREATE_PROCESS_NOTIFY_ROUTINE
|
||||
PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PEPROCESS
|
||||
PsGetNextProcess(PEPROCESS OldProcess)
|
||||
|
@ -310,40 +312,70 @@ PiDeleteProcess(PVOID ObjectBody)
|
|||
|
||||
static NTSTATUS
|
||||
PsCreatePeb(HANDLE ProcessHandle,
|
||||
PVOID ImageBase,
|
||||
PVOID* RPeb)
|
||||
PEPROCESS Process,
|
||||
PVOID ImageBase)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID PebBase;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
ULONG PebSize;
|
||||
PEB Peb;
|
||||
ULONG BytesWritten;
|
||||
PPEB Peb;
|
||||
PUCHAR BaseAddress;
|
||||
ULONG ViewSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
memset(&Peb, 0, sizeof(Peb));
|
||||
Peb.ImageBaseAddress = ImageBase;
|
||||
|
||||
PebBase = (PVOID)PEB_BASE;
|
||||
PebSize = 0x1000;
|
||||
/* Allocate the Process Environment Block (PEB) */
|
||||
Peb = (PPEB)PEB_BASE;
|
||||
PebSize = PAGE_SIZE;
|
||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||
&PebBase,
|
||||
(PVOID*)&Peb,
|
||||
0,
|
||||
&PebSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
|
||||
|
||||
KeAttachProcess(Process);
|
||||
|
||||
/* Map the NLS section into the new process */
|
||||
BaseAddress = NULL;
|
||||
ViewSize = 0;
|
||||
SectionOffset.QuadPart = 0LL;
|
||||
Status = MmMapViewOfSection(NlsSection,
|
||||
Process,
|
||||
(PVOID*)&BaseAddress,
|
||||
0,
|
||||
0,
|
||||
&SectionOffset,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
SEC_NO_CHANGE | MEM_TOP_DOWN,
|
||||
PAGE_READONLY);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
|
||||
KeDetachProcess();
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NtWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)PEB_BASE,
|
||||
&Peb,
|
||||
sizeof(Peb),
|
||||
&BytesWritten);
|
||||
DPRINT("BaseAddress %p ViewSize %lu\n", BaseAddress, ViewSize);
|
||||
|
||||
DPRINT("PsCreatePeb: Peb created at %x\n", PebBase);
|
||||
/* Initialize the PEB */
|
||||
RtlZeroMemory(Peb, sizeof(PEB));
|
||||
Peb->ImageBaseAddress = ImageBase;
|
||||
|
||||
*RPeb = PebBase;
|
||||
/* FIXME: Initialize more PEB variables */
|
||||
Peb->AnsiCodePageData = BaseAddress;
|
||||
// Peb->OemCodePageData =
|
||||
|
||||
|
||||
Process->Peb = Peb;
|
||||
KeDetachProcess();
|
||||
|
||||
DPRINT("PsCreatePeb: Peb created at %p\n", Peb);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
@ -434,7 +466,6 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
KIRQL oldIrql;
|
||||
PVOID LdrStartupAddr;
|
||||
PVOID ImageBase;
|
||||
PVOID Peb;
|
||||
PEPORT DebugPort;
|
||||
PEPORT ExceptionPort;
|
||||
PVOID BaseAddress;
|
||||
|
@ -658,8 +689,8 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
*/
|
||||
DPRINT("Creating PEB\n");
|
||||
Status = PsCreatePeb(*ProcessHandle,
|
||||
ImageBase,
|
||||
&Peb);
|
||||
Process,
|
||||
ImageBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
|
||||
|
@ -669,7 +700,6 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
*ProcessHandle = NULL;
|
||||
return(Status);
|
||||
}
|
||||
Process->Peb = Peb;
|
||||
|
||||
/*
|
||||
* Maybe send a message to the creator process's debugger
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: nls.c,v 1.10 2002/11/10 13:36:59 robd Exp $
|
||||
/* $Id: nls.c,v 1.11 2003/05/15 11:07:07 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -20,24 +20,20 @@
|
|||
* 4) Add multi-byte translation code.
|
||||
*/
|
||||
|
||||
#ifdef WIN32_REGDBG
|
||||
#include "cm_win32.h"
|
||||
#else
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
//#include <internal/nls.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/nls.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#endif
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
BOOLEAN NlsMbCodePageTag = FALSE;
|
||||
BOOLEAN NlsMbOemCodePageTag = FALSE;
|
||||
|
||||
BYTE NlsLeadByteInfo = 0; /* ? */
|
||||
UCHAR NlsLeadByteInfo = 0; /* ? */
|
||||
|
||||
USHORT NlsOemLeadByteInfo = 0;
|
||||
|
||||
|
@ -53,6 +49,8 @@ PCHAR UnicodeToOemTable =NULL; /* size: 65536*sizeof(CHAR) */
|
|||
PWCHAR UnicodeUpcaseTable = NULL; /* size: 65536*sizeof(WCHAR) */
|
||||
PWCHAR UnicodeLowercaseTable = NULL; /* size: 65536*sizeof(WCHAR) */
|
||||
|
||||
PSECTION_OBJECT NlsSection = NULL;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -150,78 +148,81 @@ RtlpInitNlsTables(VOID)
|
|||
|
||||
|
||||
NTSTATUS
|
||||
RtlpInitNlsSections(ULONG Mod1Start,
|
||||
ULONG Mod1End,
|
||||
ULONG Mod2Start,
|
||||
ULONG Mod2End,
|
||||
ULONG Mod3Start,
|
||||
ULONG Mod3End)
|
||||
RtlpInitNlsSection(VOID)
|
||||
{
|
||||
UNICODE_STRING UnicodeString;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE DirectoryHandle;
|
||||
HANDLE SectionHandle;
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER SectionSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Ansi section start: 0x%08lX\n", Mod1Start);
|
||||
DPRINT("Ansi section end: 0x%08lX\n", Mod1End);
|
||||
DPRINT("Oem section start: 0x%08lX\n", Mod2Start);
|
||||
DPRINT("Oem section end: 0x%08lX\n", Mod2End);
|
||||
DPRINT("Upcase section start: 0x%08lX\n", Mod3Start);
|
||||
DPRINT("Upcase section end: 0x%08lX\n", Mod3End);
|
||||
PUCHAR MappedBuffer;
|
||||
ULONG Size;
|
||||
ULONG ViewSize;
|
||||
|
||||
/* Create the '\NLS' directory */
|
||||
RtlInitUnicodeStringFromLiteral(&UnicodeString,
|
||||
L"\\NLS");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&UnicodeString,
|
||||
OBJ_PERMANENT,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtCreateDirectoryObject(&DirectoryHandle,
|
||||
0,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return(Status);
|
||||
DPRINT1("RtlpInitNlsSection() called\n");
|
||||
|
||||
/* Create the 'NlsSectionUnicode' section */
|
||||
RtlInitUnicodeStringFromLiteral(&UnicodeString,
|
||||
L"NlsSectionUnicode");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&UnicodeString,
|
||||
OBJ_PERMANENT,
|
||||
DirectoryHandle,
|
||||
NULL);
|
||||
SectionSize.QuadPart = (Mod1End - Mod1Start) +
|
||||
(Mod2End - Mod2Start) + (Mod3End - Mod3Start);
|
||||
DPRINT("NlsSectionUnicode size: 0x%I64X\n", SectionSize.QuadPart);
|
||||
Size = 4096;
|
||||
|
||||
DPRINT("Nls section size: 0x%lx\n", Size);
|
||||
|
||||
/* Create the nls section */
|
||||
SectionSize.QuadPart = (ULONGLONG)Size;
|
||||
Status = NtCreateSection(&SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
NULL,
|
||||
&SectionSize,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
SEC_COMMIT,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateSection() failed (Status %lx)\n", Status);
|
||||
KeBugCheck(0);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
/* create and initialize code page table */
|
||||
|
||||
/* map the nls table into the 'NlsSectionUnicode' section */
|
||||
|
||||
|
||||
/* Get the pointer to the nls section object */
|
||||
Status = ObReferenceObjectByHandle(SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
MmSectionObjectType,
|
||||
KernelMode,
|
||||
(PVOID*)&NlsSection,
|
||||
NULL);
|
||||
NtClose(SectionHandle);
|
||||
NtClose(DirectoryHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ObReferenceObjectByHandle() failed (Status %lx)\n", Status);
|
||||
KeBugCheck(0);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Map the nls section into system address space */
|
||||
ViewSize = 4096;
|
||||
Status = MmMapViewInSystemSpace(NlsSection,
|
||||
(PVOID*)&MappedBuffer,
|
||||
&ViewSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmMapViewInSystemSpace() failed (Status %lx)\n", Status);
|
||||
KeBugCheck(0);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT1("BaseAddress %p\n", MappedBuffer);
|
||||
|
||||
strcpy(MappedBuffer, "This is a teststring!");
|
||||
|
||||
/* ... */
|
||||
|
||||
|
||||
|
||||
DPRINT1("RtlpInitNlsSection() done\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData,
|
||||
RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
|
||||
PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -231,7 +232,7 @@ RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData,
|
|||
ULONG Size = 0;
|
||||
ULONG i;
|
||||
|
||||
if (NlsData->DbcsFlag == FALSE)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
|
||||
|
@ -244,7 +245,7 @@ RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData,
|
|||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
*UnicodeString = NlsData->MultiByteToUnicode[(unsigned int)*CustomString];
|
||||
*UnicodeString = CustomCP->MultiByteTable[(unsigned int)*CustomString];
|
||||
UnicodeString++;
|
||||
CustomString++;
|
||||
}
|
||||
|
@ -268,6 +269,24 @@ RtlGetDefaultCodePage(PUSHORT AnsiCodePage,
|
|||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlInitCodePageTable(IN PUSHORT TableBase,
|
||||
OUT PCPTABLEINFO CodePageTable)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlInitNlsTables(OUT PNLSTABLEINFO NlsTable,
|
||||
IN PUSHORT CaseTableBase,
|
||||
IN PUSHORT OemTableBase,
|
||||
IN PUSHORT AnsiTableBase)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlMultiByteToUnicodeN(PWCHAR UnicodeString,
|
||||
ULONG UnicodeSize,
|
||||
|
@ -364,8 +383,15 @@ RtlOemToUnicodeN(PWCHAR UnicodeString,
|
|||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
||||
RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
|
||||
PCHAR CustomString,
|
||||
ULONG CustomSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -375,7 +401,7 @@ RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
|||
ULONG Size = 0;
|
||||
ULONG i;
|
||||
|
||||
if (NlsData->DbcsFlag == 0)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
|
||||
|
@ -388,7 +414,7 @@ RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
|||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
*CustomString = NlsData->UnicodeToMultiByte[(unsigned int)*UnicodeString];
|
||||
*CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString];
|
||||
CustomString++;
|
||||
UnicodeString++;
|
||||
}
|
||||
|
@ -501,7 +527,7 @@ RtlUnicodeToOemN(PCHAR OemString,
|
|||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
||||
RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
|
||||
PCHAR CustomString,
|
||||
ULONG CustomSize,
|
||||
PULONG ResultSize,
|
||||
|
@ -512,7 +538,7 @@ RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
|||
ULONG i;
|
||||
WCHAR wc;
|
||||
|
||||
if (NlsData->DbcsFlag == 0)
|
||||
if (CustomCP->DBCSCodePage == 0)
|
||||
{
|
||||
/* single-byte code page */
|
||||
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
|
||||
|
@ -526,7 +552,7 @@ RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData,
|
|||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
wc = UnicodeUpcaseTable[(unsigned int)*UnicodeString];
|
||||
*CustomString = NlsData->UnicodeToMultiByte[(unsigned int)wc];
|
||||
*CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc];
|
||||
CustomString++;
|
||||
UnicodeString++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue