Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
54c31d53
Commit
54c31d53
authored
Oct 15, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Make NtGetNlsSectionPtr() into a proper Nt syscall.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
892780a5
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
202 deletions
+151
-202
locale.c
dlls/kernel32/tests/locale.c
+6
-6
locale.c
dlls/ntdll/locale.c
+2
-182
ntdll.spec
dlls/ntdll/ntdll.spec
+2
-2
env.c
dlls/ntdll/unix/env.c
+141
-12
No files found.
dlls/kernel32/tests/locale.c
View file @
54c31d53
...
...
@@ -4131,7 +4131,7 @@ static void test_GetCPInfo(void)
status
=
pNtGetNlsSectionPtr
(
i
,
9999
,
NULL
,
&
ptr
,
&
size
);
switch
(
i
)
{
case
9
:
/*
unknown
*/
case
9
:
/*
sortkeys
*/
case
13
:
/* unknown */
ok
(
status
==
STATUS_INVALID_PARAMETER_1
||
status
==
STATUS_INVALID_PARAMETER_3
,
/* vista */
"%u: failed %x
\n
"
,
i
,
status
);
...
...
@@ -4160,9 +4160,9 @@ static void test_GetCPInfo(void)
status
=
pNtGetNlsSectionPtr
(
10
,
0
,
NULL
,
&
ptr2
,
&
size
);
ok
(
ptr
!=
ptr2
,
"got same pointer
\n
"
);
ret
=
UnmapViewOfFile
(
ptr
);
todo_wine
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ret
=
UnmapViewOfFile
(
ptr2
);
todo_wine
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
}
/* codepage tables */
...
...
@@ -4182,7 +4182,7 @@ static void test_GetCPInfo(void)
ok
(
!
table
.
DBCSCodePage
,
"wrong dbcs %u
\n
"
,
table
.
DBCSCodePage
);
}
ret
=
UnmapViewOfFile
(
ptr
);
todo_wine
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
status
=
pNtGetNlsSectionPtr
(
11
,
936
,
NULL
,
&
ptr
,
&
size
);
ok
(
!
status
,
"failed %x
\n
"
,
status
);
...
...
@@ -4220,7 +4220,7 @@ static void test_GetCPInfo(void)
}
}
ret
=
UnmapViewOfFile
(
ptr
);
todo_wine
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
/* normalization tables */
...
...
@@ -4238,7 +4238,7 @@ static void test_GetCPInfo(void)
if
(
status
)
break
;
ok
(
size
>
0x8000
&&
size
<=
0x30000
,
"wrong size %lx
\n
"
,
size
);
ret
=
UnmapViewOfFile
(
ptr
);
todo_wine
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
ok
(
ret
,
"UnmapViewOfFile failed err %u
\n
"
,
GetLastError
()
);
break
;
default:
ok
(
status
==
STATUS_OBJECT_NAME_NOT_FOUND
,
"%u: failed %x
\n
"
,
i
,
status
);
...
...
dlls/ntdll/locale.c
View file @
54c31d53
...
...
@@ -228,13 +228,13 @@ static NTSTATUS load_norm_table( ULONG form, const struct norm_table **info )
}
if
(
InterlockedCompareExchangePointer
(
(
void
**
)
&
norm_tables
[
form
],
data
,
NULL
))
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
NtUnmapViewOfSection
(
GetCurrentProcess
()
,
data
);
}
*
info
=
norm_tables
[
form
];
return
STATUS_SUCCESS
;
invalid:
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
NtUnmapViewOfSection
(
GetCurrentProcess
()
,
data
);
return
STATUS_INVALID_PARAMETER
;
}
...
...
@@ -534,156 +534,6 @@ static unsigned int compose_string( const struct norm_table *info, WCHAR *str, u
}
static
NTSTATUS
open_nls_data_file
(
ULONG
type
,
ULONG
id
,
HANDLE
*
file
)
{
static
const
WCHAR
pathfmtW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'%'
,
's'
,
'%'
,
's'
,
0
};
static
const
WCHAR
keyfmtW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'\\'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'S'
,
'e'
,
't'
,
'\\'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'\\'
,
'N'
,
'l'
,
's'
,
'\\'
,
'%'
,
's'
,
0
};
static
const
WCHAR
sortdirW
[]
=
{
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
'g'
,
'l'
,
'o'
,
'b'
,
'a'
,
'l'
,
'i'
,
'z'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
'\\'
,
's'
,
'o'
,
'r'
,
't'
,
'i'
,
'n'
,
'g'
,
'\\'
,
0
};
static
const
WCHAR
cpW
[]
=
{
'C'
,
'o'
,
'd'
,
'e'
,
'p'
,
'a'
,
'g'
,
'e'
,
0
};
static
const
WCHAR
normW
[]
=
{
'N'
,
'o'
,
'r'
,
'm'
,
'a'
,
'l'
,
'i'
,
'z'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
langW
[]
=
{
'L'
,
'a'
,
'n'
,
'g'
,
'u'
,
'a'
,
'g'
,
'e'
,
0
};
static
const
WCHAR
cpfmtW
[]
=
{
'%'
,
'u'
,
0
};
static
const
WCHAR
normfmtW
[]
=
{
'%'
,
'x'
,
0
};
static
const
WCHAR
langfmtW
[]
=
{
'%'
,
'0'
,
'4'
,
'x'
,
0
};
static
const
WCHAR
winedatadirW
[]
=
{
'W'
,
'I'
,
'N'
,
'E'
,
'D'
,
'A'
,
'T'
,
'A'
,
'D'
,
'I'
,
'R'
,
0
};
static
const
WCHAR
winebuilddirW
[]
=
{
'W'
,
'I'
,
'N'
,
'E'
,
'B'
,
'U'
,
'I'
,
'L'
,
'D'
,
'D'
,
'I'
,
'R'
,
0
};
static
const
WCHAR
dataprefixW
[]
=
{
'\\'
,
'n'
,
'l'
,
's'
,
'\\'
,
0
};
static
const
WCHAR
cpdefaultW
[]
=
{
'c'
,
'_'
,
'%'
,
'0'
,
'3'
,
'd'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
intlW
[]
=
{
'l'
,
'_'
,
'i'
,
'n'
,
't'
,
'l'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
normnfcW
[]
=
{
'n'
,
'o'
,
'r'
,
'm'
,
'n'
,
'f'
,
'c'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
normnfdW
[]
=
{
'n'
,
'o'
,
'r'
,
'm'
,
'n'
,
'f'
,
'd'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
normnfkcW
[]
=
{
'n'
,
'o'
,
'r'
,
'm'
,
'n'
,
'f'
,
'k'
,
'c'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
normnfkdW
[]
=
{
'n'
,
'o'
,
'r'
,
'm'
,
'n'
,
'f'
,
'k'
,
'd'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
normidnaW
[]
=
{
'n'
,
'o'
,
'r'
,
'm'
,
'i'
,
'd'
,
'n'
,
'a'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
static
const
WCHAR
sortkeysW
[]
=
{
's'
,
'o'
,
'r'
,
't'
,
'd'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
'.'
,
'n'
,
'l'
,
's'
,
0
};
DWORD
size
;
HANDLE
handle
;
NTSTATUS
status
=
STATUS_OBJECT_NAME_NOT_FOUND
;
IO_STATUS_BLOCK
io
;
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
,
valueW
;
WCHAR
buffer
[
MAX_PATH
],
value
[
10
];
const
WCHAR
*
name
=
NULL
,
*
dir
=
system_dir
;
KEY_VALUE_PARTIAL_INFORMATION
*
info
;
/* get filename from registry */
switch
(
type
)
{
case
NLS_SECTION_SORTKEYS
:
if
(
id
)
return
STATUS_INVALID_PARAMETER_1
;
buffer
[
0
]
=
0
;
break
;
case
NLS_SECTION_CASEMAP
:
if
(
id
)
return
STATUS_UNSUCCESSFUL
;
swprintf
(
buffer
,
ARRAY_SIZE
(
buffer
),
keyfmtW
,
langW
);
swprintf
(
value
,
ARRAY_SIZE
(
value
),
langfmtW
,
LANGIDFROMLCID
(
system_lcid
)
);
break
;
case
NLS_SECTION_CODEPAGE
:
swprintf
(
buffer
,
ARRAY_SIZE
(
buffer
),
keyfmtW
,
cpW
);
swprintf
(
value
,
ARRAY_SIZE
(
value
),
cpfmtW
,
id
);
break
;
case
NLS_SECTION_NORMALIZE
:
swprintf
(
buffer
,
ARRAY_SIZE
(
buffer
),
keyfmtW
,
normW
);
swprintf
(
value
,
ARRAY_SIZE
(
value
),
normfmtW
,
id
);
break
;
default:
return
STATUS_INVALID_PARAMETER_1
;
}
if
(
buffer
[
0
])
{
RtlInitUnicodeString
(
&
nameW
,
buffer
);
RtlInitUnicodeString
(
&
valueW
,
value
);
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
0
,
0
,
NULL
);
if
(
!
(
status
=
NtOpenKey
(
&
handle
,
KEY_READ
,
&
attr
)))
{
info
=
(
KEY_VALUE_PARTIAL_INFORMATION
*
)
buffer
;
size
=
sizeof
(
buffer
)
-
sizeof
(
WCHAR
);
if
(
!
(
status
=
NtQueryValueKey
(
handle
,
&
valueW
,
KeyValuePartialInformation
,
info
,
size
,
&
size
)))
{
((
WCHAR
*
)
info
->
Data
)[
info
->
DataLength
/
sizeof
(
WCHAR
)]
=
0
;
name
=
(
WCHAR
*
)
info
->
Data
;
}
NtClose
(
handle
);
}
}
if
(
!
name
||
!*
name
)
/* otherwise some hardcoded defaults */
{
switch
(
type
)
{
case
NLS_SECTION_SORTKEYS
:
name
=
sortkeysW
;
dir
=
sortdirW
;
break
;
case
NLS_SECTION_CASEMAP
:
name
=
intlW
;
break
;
case
NLS_SECTION_CODEPAGE
:
swprintf
(
buffer
,
ARRAY_SIZE
(
buffer
),
cpdefaultW
,
id
);
name
=
buffer
;
break
;
case
NLS_SECTION_NORMALIZE
:
switch
(
id
)
{
case
NormalizationC
:
name
=
normnfcW
;
break
;
case
NormalizationD
:
name
=
normnfdW
;
break
;
case
NormalizationKC
:
name
=
normnfkcW
;
break
;
case
NormalizationKD
:
name
=
normnfkdW
;
break
;
case
13
:
name
=
normidnaW
;
break
;
}
break
;
}
if
(
!
name
)
return
status
;
}
/* try to open file in system dir */
valueW
.
MaximumLength
=
(
wcslen
(
name
)
+
wcslen
(
dir
)
+
5
)
*
sizeof
(
WCHAR
);
if
(
!
(
valueW
.
Buffer
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
valueW
.
MaximumLength
)))
return
STATUS_NO_MEMORY
;
valueW
.
Length
=
swprintf
(
valueW
.
Buffer
,
valueW
.
MaximumLength
/
sizeof
(
WCHAR
),
pathfmtW
,
dir
,
name
)
*
sizeof
(
WCHAR
);
InitializeObjectAttributes
(
&
attr
,
&
valueW
,
0
,
0
,
NULL
);
status
=
NtOpenFile
(
file
,
GENERIC_READ
,
&
attr
,
&
io
,
FILE_SHARE_READ
,
FILE_SYNCHRONOUS_IO_ALERT
);
if
(
!
status
)
TRACE
(
"found %s
\n
"
,
debugstr_w
(
valueW
.
Buffer
));
RtlFreeUnicodeString
(
&
valueW
);
if
(
status
!=
STATUS_OBJECT_NAME_NOT_FOUND
&&
status
!=
STATUS_OBJECT_PATH_NOT_FOUND
)
return
status
;
/* not found, try in build or data dir */
RtlInitUnicodeString
(
&
nameW
,
winebuilddirW
);
valueW
.
MaximumLength
=
0
;
if
(
RtlQueryEnvironmentVariable_U
(
NULL
,
&
nameW
,
&
valueW
)
!=
STATUS_BUFFER_TOO_SMALL
)
{
RtlInitUnicodeString
(
&
nameW
,
winedatadirW
);
if
(
RtlQueryEnvironmentVariable_U
(
NULL
,
&
nameW
,
&
valueW
)
!=
STATUS_BUFFER_TOO_SMALL
)
return
status
;
}
valueW
.
MaximumLength
=
valueW
.
Length
+
sizeof
(
dataprefixW
)
+
wcslen
(
name
)
*
sizeof
(
WCHAR
);
if
(
!
(
valueW
.
Buffer
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
valueW
.
MaximumLength
)))
return
STATUS_NO_MEMORY
;
if
(
!
RtlQueryEnvironmentVariable_U
(
NULL
,
&
nameW
,
&
valueW
))
{
wcscat
(
valueW
.
Buffer
,
dataprefixW
);
wcscat
(
valueW
.
Buffer
,
name
);
valueW
.
Length
=
wcslen
(
valueW
.
Buffer
)
*
sizeof
(
WCHAR
);
InitializeObjectAttributes
(
&
attr
,
&
valueW
,
0
,
0
,
NULL
);
status
=
NtOpenFile
(
file
,
GENERIC_READ
,
&
attr
,
&
io
,
FILE_SHARE_READ
,
FILE_SYNCHRONOUS_IO_ALERT
);
if
(
!
status
)
TRACE
(
"found %s
\n
"
,
debugstr_w
(
valueW
.
Buffer
));
}
RtlFreeUnicodeString
(
&
valueW
);
return
status
;
}
void
init_unix_codepage
(
void
)
{
USHORT
*
data
=
unix_funcs
->
get_unix_codepage_data
();
...
...
@@ -925,36 +775,6 @@ NTSTATUS WINAPI RtlSetThreadPreferredUILanguages( DWORD flags, PCZZWSTR buffer,
}
/**************************************************************************
* NtGetNlsSectionPtr (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetNlsSectionPtr
(
ULONG
type
,
ULONG
id
,
void
*
unknown
,
void
**
ptr
,
SIZE_T
*
size
)
{
FILE_END_OF_FILE_INFORMATION
info
;
IO_STATUS_BLOCK
io
;
HANDLE
file
;
NTSTATUS
status
;
if
((
status
=
open_nls_data_file
(
type
,
id
,
&
file
)))
return
status
;
if
((
status
=
NtQueryInformationFile
(
file
,
&
io
,
&
info
,
sizeof
(
info
),
FileEndOfFileInformation
)))
goto
done
;
/* FIXME: return a heap block instead of a file mapping for now */
if
(
!
(
*
ptr
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
info
.
EndOfFile
.
QuadPart
)))
{
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
status
=
NtReadFile
(
file
,
0
,
NULL
,
NULL
,
&
io
,
*
ptr
,
info
.
EndOfFile
.
QuadPart
,
NULL
,
NULL
);
if
(
!
status
&&
io
.
Information
!=
info
.
EndOfFile
.
QuadPart
)
status
=
STATUS_INVALID_FILE_FOR_SECTION
;
if
(
!
status
)
*
size
=
io
.
Information
;
else
RtlFreeHeap
(
GetProcessHeap
(),
0
,
*
ptr
);
done:
NtClose
(
file
);
return
status
;
}
/******************************************************************
* RtlInitCodePageTable (NTDLL.@)
*/
...
...
dlls/ntdll/ntdll.spec
View file @
54c31d53
...
...
@@ -222,7 +222,7 @@
@ stdcall -norelay -syscall NtGetContextThread(long ptr)
@ stdcall -syscall NtGetCurrentProcessorNumber()
# @ stub NtGetDevicePowerState
@ stdcall NtGetNlsSectionPtr(long long long ptr ptr)
@ stdcall
-syscall
NtGetNlsSectionPtr(long long long ptr ptr)
@ stub NtGetPlugPlayEvent
@ stdcall NtGetTickCount()
@ stdcall -syscall NtGetWriteWatch(long long ptr long ptr ptr ptr)
...
...
@@ -1226,7 +1226,7 @@
@ stdcall -private -norelay -syscall ZwGetContextThread(long ptr) NtGetContextThread
@ stdcall -private -syscall ZwGetCurrentProcessorNumber() NtGetCurrentProcessorNumber
# @ stub ZwGetDevicePowerState
@ stdcall -private ZwGetNlsSectionPtr(long long long ptr ptr) NtGetNlsSectionPtr
@ stdcall -private
-syscall
ZwGetNlsSectionPtr(long long long ptr ptr) NtGetNlsSectionPtr
@ stub ZwGetPlugPlayEvent
@ stdcall -private ZwGetTickCount() NtGetTickCount
@ stdcall -private -syscall ZwGetWriteWatch(long long ptr long ptr ptr ptr) NtGetWriteWatch
...
...
dlls/ntdll/unix/env.c
View file @
54c31d53
...
...
@@ -84,16 +84,49 @@ static struct
void
*
wctable
;
}
unix_cp
;
static
void
*
read_nls_file
(
const
char
*
name
)
enum
nls_section_type
{
NLS_SECTION_SORTKEYS
=
9
,
NLS_SECTION_CASEMAP
=
10
,
NLS_SECTION_CODEPAGE
=
11
,
NLS_SECTION_NORMALIZE
=
12
};
static
char
*
get_nls_file_path
(
ULONG
type
,
ULONG
id
)
{
const
char
*
dir
=
build_dir
?
build_dir
:
data_dir
;
const
char
*
name
=
NULL
;
char
*
path
,
tmp
[
16
];
switch
(
type
)
{
case
NLS_SECTION_SORTKEYS
:
name
=
"sortdefault"
;
break
;
case
NLS_SECTION_CASEMAP
:
name
=
"l_intl"
;
break
;
case
NLS_SECTION_CODEPAGE
:
name
=
tmp
;
sprintf
(
tmp
,
"c_%03u"
,
id
);
break
;
case
NLS_SECTION_NORMALIZE
:
switch
(
id
)
{
case
NormalizationC
:
name
=
"normnfc"
;
break
;
case
NormalizationD
:
name
=
"normnfd"
;
break
;
case
NormalizationKC
:
name
=
"normnfkc"
;
break
;
case
NormalizationKD
:
name
=
"normnfkd"
;
break
;
case
13
:
name
=
"normidna"
;
break
;
}
break
;
}
if
(
!
name
)
return
NULL
;
if
(
!
(
path
=
malloc
(
strlen
(
dir
)
+
strlen
(
name
)
+
10
)))
return
NULL
;
sprintf
(
path
,
"%s/nls/%s.nls"
,
dir
,
name
);
return
path
;
}
static
void
*
read_nls_file
(
ULONG
type
,
ULONG
id
)
{
char
*
path
=
get_nls_file_path
(
type
,
id
);
struct
stat
st
;
char
*
path
;
void
*
data
,
*
ret
=
NULL
;
int
fd
;
if
(
!
(
path
=
malloc
(
strlen
(
dir
)
+
22
)))
return
NULL
;
sprintf
(
path
,
"%s/nls/%s.nls"
,
dir
,
name
);
if
((
fd
=
open
(
path
,
O_RDONLY
))
!=
-
1
)
{
fstat
(
fd
,
&
st
);
...
...
@@ -109,11 +142,73 @@ static void *read_nls_file( const char *name )
}
close
(
fd
);
}
else
ERR
(
"failed to load %
s
\n
"
,
path
);
else
ERR
(
"failed to load %
u/%u
\n
"
,
type
,
id
);
free
(
path
);
return
ret
;
}
static
NTSTATUS
open_nls_data_file
(
ULONG
type
,
ULONG
id
,
HANDLE
*
file
)
{
static
const
WCHAR
systemdirW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
0
};
static
const
WCHAR
sortdirW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
'g'
,
'l'
,
'o'
,
'b'
,
'a'
,
'l'
,
'i'
,
'z'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
'\\'
,
's'
,
'o'
,
'r'
,
't'
,
'i'
,
'n'
,
'g'
,
'\\'
,
0
};
NTSTATUS
status
=
STATUS_OBJECT_NAME_NOT_FOUND
;
IO_STATUS_BLOCK
io
;
OBJECT_ATTRIBUTES
attr
=
{
sizeof
(
attr
)
};
UNICODE_STRING
valueW
;
WCHAR
buffer
[
ARRAY_SIZE
(
sortdirW
)
+
16
];
char
*
p
,
*
path
=
get_nls_file_path
(
type
,
id
);
if
(
!
path
)
return
STATUS_OBJECT_NAME_NOT_FOUND
;
status
=
open_unix_file
(
file
,
path
,
GENERIC_READ
,
&
attr
,
0
,
FILE_SHARE_READ
,
FILE_OPEN
,
FILE_SYNCHRONOUS_IO_ALERT
,
NULL
,
0
);
if
(
status
==
STATUS_NO_SUCH_FILE
)
{
/* try to open file in system dir */
ntdll_wcscpy
(
buffer
,
type
==
NLS_SECTION_SORTKEYS
?
sortdirW
:
systemdirW
);
p
=
strrchr
(
path
,
'/'
)
+
1
;
ascii_to_unicode
(
buffer
+
ntdll_wcslen
(
buffer
),
p
,
strlen
(
p
)
+
1
);
valueW
.
Buffer
=
buffer
;
valueW
.
Length
=
ntdll_wcslen
(
buffer
)
*
sizeof
(
WCHAR
);
valueW
.
MaximumLength
=
sizeof
(
buffer
);
InitializeObjectAttributes
(
&
attr
,
&
valueW
,
0
,
0
,
NULL
);
status
=
NtOpenFile
(
file
,
GENERIC_READ
,
&
attr
,
&
io
,
FILE_SHARE_READ
,
FILE_SYNCHRONOUS_IO_ALERT
);
}
free
(
path
);
return
status
;
}
static
NTSTATUS
get_nls_section_name
(
ULONG
type
,
ULONG
id
,
WCHAR
name
[
32
]
)
{
char
buffer
[
32
];
switch
(
type
)
{
case
NLS_SECTION_SORTKEYS
:
if
(
id
)
return
STATUS_INVALID_PARAMETER_1
;
strcpy
(
buffer
,
"
\\
NLS
\\
NlsSectionSORTDEFAULT"
);
break
;
case
NLS_SECTION_CASEMAP
:
if
(
id
)
return
STATUS_UNSUCCESSFUL
;
strcpy
(
buffer
,
"
\\
NLS
\\
NlsSectionLANG_INTL"
);
break
;
case
NLS_SECTION_CODEPAGE
:
sprintf
(
buffer
,
"
\\
NLS
\\
NlsSectionCP%03u"
,
id
);
break
;
case
NLS_SECTION_NORMALIZE
:
sprintf
(
buffer
,
"
\\
NLS
\\
NlsSectionNORM%08x"
,
id
);
break
;
default:
return
STATUS_INVALID_PARAMETER_1
;
}
ascii_to_unicode
(
name
,
buffer
,
strlen
(
buffer
)
+
1
);
return
STATUS_SUCCESS
;
}
static
int
get_utf16
(
const
WCHAR
*
src
,
unsigned
int
srclen
,
unsigned
int
*
ch
)
{
...
...
@@ -167,7 +262,7 @@ static struct norm_table *nfc_table;
static
void
init_unix_codepage
(
void
)
{
nfc_table
=
read_nls_file
(
"normnfc"
);
nfc_table
=
read_nls_file
(
NLS_SECTION_NORMALIZE
,
NormalizationC
);
}
static
void
put_utf16
(
WCHAR
*
dst
,
unsigned
int
ch
)
...
...
@@ -398,11 +493,8 @@ static void init_unix_codepage(void)
{
if
(
charset_names
[
pos
].
cp
!=
CP_UTF8
)
{
char
name
[
16
];
void
*
data
;
sprintf
(
name
,
"c_%03u"
,
charset_names
[
pos
].
cp
);
if
((
data
=
read_nls_file
(
name
)))
init_unix_cptable
(
data
);
void
*
data
=
read_nls_file
(
NLS_SECTION_CODEPAGE
,
charset_names
[
pos
].
cp
);
if
(
data
)
init_unix_cptable
(
data
);
}
return
;
}
...
...
@@ -958,7 +1050,7 @@ void init_environment( int argc, char *argv[], char *envp[] )
init_unix_codepage
();
init_locale
();
if
((
case_table
=
read_nls_file
(
"l_intl"
)))
if
((
case_table
=
read_nls_file
(
NLS_SECTION_CASEMAP
,
0
)))
{
uctable
=
case_table
+
2
;
lctable
=
case_table
+
case_table
[
1
]
+
2
;
...
...
@@ -1283,6 +1375,43 @@ void CDECL get_locales( WCHAR *sys, WCHAR *user )
}
/**************************************************************************
* NtGetNlsSectionPtr (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetNlsSectionPtr
(
ULONG
type
,
ULONG
id
,
void
*
unknown
,
void
**
ptr
,
SIZE_T
*
size
)
{
UNICODE_STRING
nameW
;
OBJECT_ATTRIBUTES
attr
;
WCHAR
name
[
32
];
HANDLE
handle
,
file
;
NTSTATUS
status
;
if
((
status
=
get_nls_section_name
(
type
,
id
,
name
)))
return
status
;
nameW
.
Buffer
=
name
;
nameW
.
Length
=
ntdll_wcslen
(
name
)
*
sizeof
(
WCHAR
);
nameW
.
MaximumLength
=
sizeof
(
name
);
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
0
,
0
,
NULL
);
if
((
status
=
NtOpenSection
(
&
handle
,
SECTION_MAP_READ
,
&
attr
)))
{
if
((
status
=
open_nls_data_file
(
type
,
id
,
&
file
)))
return
status
;
attr
.
Attributes
=
OBJ_OPENIF
|
OBJ_PERMANENT
;
status
=
NtCreateSection
(
&
handle
,
SECTION_MAP_READ
,
&
attr
,
NULL
,
PAGE_READONLY
,
SEC_COMMIT
,
file
);
NtClose
(
file
);
if
(
status
==
STATUS_OBJECT_NAME_EXISTS
)
status
=
STATUS_SUCCESS
;
}
if
(
!
status
)
{
*
ptr
=
NULL
;
*
size
=
0
;
status
=
NtMapViewOfSection
(
handle
,
GetCurrentProcess
(),
ptr
,
0
,
0
,
NULL
,
size
,
ViewShare
,
0
,
PAGE_READONLY
);
}
NtClose
(
handle
);
return
status
;
}
/**********************************************************************
* NtQueryDefaultLocale (NTDLL.@)
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment