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
5eb30353
Commit
5eb30353
authored
Nov 11, 2015
by
Jacek Caban
Committed by
Alexandre Julliard
Nov 12, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Added KeyCachedInformation key info class implementation.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3d5db6bd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
101 additions
and
7 deletions
+101
-7
reg.c
dlls/ntdll/reg.c
+22
-4
reg.c
dlls/ntdll/tests/reg.c
+56
-1
winternl.h
include/winternl.h
+18
-1
registry.c
server/registry.c
+5
-1
No files found.
dlls/ntdll/reg.c
View file @
5eb30353
...
...
@@ -257,10 +257,11 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i
switch
(
info_class
)
{
case
KeyBasicInformation
:
data_ptr
=
((
KEY_BASIC_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyFullInformation
:
data_ptr
=
((
KEY_FULL_INFORMATION
*
)
info
)
->
Class
;
break
;
case
KeyNodeInformation
:
data_ptr
=
((
KEY_NODE_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyNameInformation
:
data_ptr
=
((
KEY_NAME_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyBasicInformation
:
data_ptr
=
((
KEY_BASIC_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyFullInformation
:
data_ptr
=
((
KEY_FULL_INFORMATION
*
)
info
)
->
Class
;
break
;
case
KeyNodeInformation
:
data_ptr
=
((
KEY_NODE_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyNameInformation
:
data_ptr
=
((
KEY_NAME_INFORMATION
*
)
info
)
->
Name
;
break
;
case
KeyCachedInformation
:
data_ptr
=
((
KEY_CACHED_INFORMATION
*
)
info
)
+
1
;
break
;
default:
FIXME
(
"Information class %d not implemented
\n
"
,
info_class
);
return
STATUS_INVALID_PARAMETER
;
...
...
@@ -332,6 +333,23 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i
memcpy
(
info
,
&
keyinfo
,
min
(
length
,
fixed_size
)
);
}
break
;
case
KeyCachedInformation
:
{
KEY_CACHED_INFORMATION
keyinfo
;
fixed_size
=
sizeof
(
keyinfo
);
keyinfo
.
LastWriteTime
.
QuadPart
=
reply
->
modif
;
keyinfo
.
TitleIndex
=
0
;
keyinfo
.
SubKeys
=
reply
->
subkeys
;
keyinfo
.
MaxNameLen
=
reply
->
max_subkey
;
keyinfo
.
Values
=
reply
->
values
;
keyinfo
.
MaxValueNameLen
=
reply
->
max_value
;
keyinfo
.
MaxValueDataLen
=
reply
->
max_data
;
keyinfo
.
NameLength
=
reply
->
namelen
;
memcpy
(
info
,
&
keyinfo
,
min
(
length
,
fixed_size
)
);
}
break
;
default:
break
;
}
*
result_len
=
fixed_size
+
reply
->
total
;
if
(
length
<
*
result_len
)
ret
=
STATUS_BUFFER_OVERFLOW
;
...
...
dlls/ntdll/tests/reg.c
View file @
5eb30353
...
...
@@ -1466,12 +1466,14 @@ static void test_long_value_name(void)
static
void
test_NtQueryKey
(
void
)
{
HANDLE
key
;
HANDLE
key
,
subkey
,
subkey2
;
NTSTATUS
status
;
OBJECT_ATTRIBUTES
attr
;
ULONG
length
,
len
;
KEY_NAME_INFORMATION
*
info
=
NULL
;
KEY_CACHED_INFORMATION
cached_info
;
UNICODE_STRING
str
;
DWORD
dw
;
InitializeObjectAttributes
(
&
attr
,
&
winetestpath
,
0
,
0
,
0
);
status
=
pNtOpenKey
(
&
key
,
KEY_READ
,
&
attr
);
...
...
@@ -1506,6 +1508,59 @@ static void test_NtQueryKey(void)
wine_dbgstr_wn
(
winetestpath
.
Buffer
,
winetestpath
.
Length
/
sizeof
(
WCHAR
)));
HeapFree
(
GetProcessHeap
(),
0
,
info
);
attr
.
RootDirectory
=
key
;
attr
.
ObjectName
=
&
str
;
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"test_subkey"
);
status
=
pNtCreateKey
(
&
subkey
,
GENERIC_ALL
,
&
attr
,
0
,
0
,
0
,
0
);
ok
(
status
==
STATUS_SUCCESS
,
"NtCreateKey failed: 0x%08x
\n
"
,
status
);
status
=
pNtQueryKey
(
subkey
,
KeyCachedInformation
,
&
cached_info
,
sizeof
(
cached_info
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"NtQueryKey Failed: 0x%08x
\n
"
,
status
);
if
(
status
==
STATUS_SUCCESS
)
{
ok
(
len
==
sizeof
(
cached_info
),
"got unexpected length %d
\n
"
,
len
);
ok
(
cached_info
.
SubKeys
==
0
,
"cached_info.SubKeys = %u
\n
"
,
cached_info
.
SubKeys
);
ok
(
cached_info
.
MaxNameLen
==
0
,
"cached_info.MaxNameLen = %u
\n
"
,
cached_info
.
MaxNameLen
);
ok
(
cached_info
.
Values
==
0
,
"cached_info.Values = %u
\n
"
,
cached_info
.
Values
);
ok
(
cached_info
.
MaxValueNameLen
==
0
,
"cached_info.MaxValueNameLen = %u
\n
"
,
cached_info
.
MaxValueNameLen
);
ok
(
cached_info
.
MaxValueDataLen
==
0
,
"cached_info.MaxValueDataLen = %u
\n
"
,
cached_info
.
MaxValueDataLen
);
ok
(
cached_info
.
NameLength
==
22
,
"cached_info.NameLength = %u
\n
"
,
cached_info
.
NameLength
);
}
attr
.
RootDirectory
=
subkey
;
attr
.
ObjectName
=
&
str
;
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"test_subkey2"
);
status
=
pNtCreateKey
(
&
subkey2
,
GENERIC_ALL
,
&
attr
,
0
,
0
,
0
,
0
);
ok
(
status
==
STATUS_SUCCESS
,
"NtCreateKey failed: 0x%08x
\n
"
,
status
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"val"
);
dw
=
64
;
status
=
pNtSetValueKey
(
subkey
,
&
str
,
0
,
REG_DWORD
,
&
dw
,
sizeof
(
dw
)
);
ok
(
status
==
STATUS_SUCCESS
,
"NtSetValueKey failed: 0x%08x
\n
"
,
status
);
status
=
pNtQueryKey
(
subkey
,
KeyCachedInformation
,
&
cached_info
,
sizeof
(
cached_info
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"NtQueryKey Failed: 0x%08x
\n
"
,
status
);
if
(
status
==
STATUS_SUCCESS
)
{
ok
(
len
==
sizeof
(
cached_info
),
"got unexpected length %d
\n
"
,
len
);
ok
(
cached_info
.
SubKeys
==
1
,
"cached_info.SubKeys = %u
\n
"
,
cached_info
.
SubKeys
);
ok
(
cached_info
.
MaxNameLen
==
24
,
"cached_info.MaxNameLen = %u
\n
"
,
cached_info
.
MaxNameLen
);
ok
(
cached_info
.
Values
==
1
,
"cached_info.Values = %u
\n
"
,
cached_info
.
Values
);
ok
(
cached_info
.
MaxValueNameLen
==
6
,
"cached_info.MaxValueNameLen = %u
\n
"
,
cached_info
.
MaxValueNameLen
);
ok
(
cached_info
.
MaxValueDataLen
==
4
,
"cached_info.MaxValueDataLen = %u
\n
"
,
cached_info
.
MaxValueDataLen
);
ok
(
cached_info
.
NameLength
==
22
,
"cached_info.NameLength = %u
\n
"
,
cached_info
.
NameLength
);
}
status
=
pNtDeleteKey
(
subkey2
);
ok
(
status
==
STATUS_SUCCESS
,
"NtDeleteSubkey failed: %x
\n
"
,
status
);
status
=
pNtDeleteKey
(
subkey
);
ok
(
status
==
STATUS_SUCCESS
,
"NtDeleteSubkey failed: %x
\n
"
,
status
);
pNtClose
(
subkey2
);
pNtClose
(
subkey
);
pNtClose
(
key
);
}
...
...
include/winternl.h
View file @
5eb30353
...
...
@@ -696,7 +696,12 @@ typedef enum _KEY_INFORMATION_CLASS {
KeyBasicInformation
,
KeyNodeInformation
,
KeyFullInformation
,
KeyNameInformation
KeyNameInformation
,
KeyCachedInformation
,
KeyFlagsInformation
,
KeyVirtualizationInformation
,
KeyHandleTagsInformation
,
MaxKeyInfoClass
}
KEY_INFORMATION_CLASS
;
typedef
enum
_KEY_VALUE_INFORMATION_CLASS
{
...
...
@@ -1024,6 +1029,18 @@ typedef struct _KEY_NAME_INFORMATION {
WCHAR
Name
[
1
];
}
KEY_NAME_INFORMATION
,
*
PKEY_NAME_INFORMATION
;
typedef
struct
_KEY_CACHED_INFORMATION
{
LARGE_INTEGER
LastWriteTime
;
ULONG
TitleIndex
;
ULONG
SubKeys
;
ULONG
MaxNameLen
;
ULONG
Values
;
ULONG
MaxValueNameLen
;
ULONG
MaxValueDataLen
;
ULONG
NameLength
;
}
KEY_CACHED_INFORMATION
,
*
PKEY_CACHED_INFORMATION
;
typedef
struct
_KEY_VALUE_ENTRY
{
PUNICODE_STRING
ValueName
;
...
...
server/registry.c
View file @
5eb30353
...
...
@@ -906,6 +906,7 @@ static void enum_key( const struct key *key, int index, int info_class,
reply
->
max_data
=
0
;
break
;
case
KeyFullInformation
:
case
KeyCachedInformation
:
for
(
i
=
0
;
i
<=
key
->
last_subkey
;
i
++
)
{
if
(
key
->
subkeys
[
i
]
->
namelen
>
max_subkey
)
max_subkey
=
key
->
subkeys
[
i
]
->
namelen
;
...
...
@@ -920,7 +921,10 @@ static void enum_key( const struct key *key, int index, int info_class,
reply
->
max_class
=
max_class
;
reply
->
max_value
=
max_value
;
reply
->
max_data
=
max_data
;
namelen
=
0
;
/* only return the class */
reply
->
namelen
=
namelen
;
if
(
info_class
==
KeyCachedInformation
)
classlen
=
0
;
/* don't return any data, only its size */
namelen
=
0
;
/* don't return name */
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
...
...
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