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
ac08b038
Commit
ac08b038
authored
Mar 02, 2010
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Initial support for Wow64 registry redirection.
parent
615e0e64
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
53 additions
and
6 deletions
+53
-6
reg.c
dlls/ntdll/tests/reg.c
+2
-1
registry.c
server/registry.c
+43
-5
thread.c
server/thread.c
+7
-0
thread.h
server/thread.h
+1
-0
No files found.
dlls/ntdll/tests/reg.c
View file @
ac08b038
...
...
@@ -1157,7 +1157,8 @@ static void test_redirection(void)
dw
=
get_key_value
(
key
,
"Winetest"
,
0
);
ok
(
dw
==
64
||
broken
(
dw
==
32
)
/* xp64 */
,
"wrong value %u
\n
"
,
dw
);
check_key_value
(
key
,
"Winetest"
,
KEY_WOW64_64KEY
,
64
);
check_key_value
(
key
,
"Winetest"
,
KEY_WOW64_32KEY
,
32
);
dw
=
get_key_value
(
key
,
"Winetest"
,
KEY_WOW64_32KEY
);
todo_wine
ok
(
dw
==
32
,
"wrong value %u
\n
"
,
dw
);
pNtClose
(
key
);
status
=
pNtCreateKey
(
&
key
,
KEY_WOW64_32KEY
|
KEY_ALL_ACCESS
,
&
attr
,
0
,
0
,
0
,
0
);
...
...
server/registry.c
View file @
ac08b038
...
...
@@ -84,6 +84,7 @@ struct key
#define KEY_DELETED 0x0002
/* key has been deleted */
#define KEY_DIRTY 0x0004
/* key has been modified */
#define KEY_SYMLINK 0x0008
/* key is a symbolic link */
#define KEY_WOW64 0x0010
/* key contains a Wow6432Node subkey */
/* a key value */
struct
key_value
...
...
@@ -109,6 +110,7 @@ static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between peri
static
struct
timeout_user
*
save_timeout_user
;
/* saving timer */
static
const
WCHAR
root_name
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
};
static
const
WCHAR
wow6432node
[]
=
{
'W'
,
'o'
,
'w'
,
'6'
,
'4'
,
'3'
,
'2'
,
'N'
,
'o'
,
'd'
,
'e'
};
static
const
WCHAR
symlink_value
[]
=
{
'S'
,
'y'
,
'm'
,
'b'
,
'o'
,
'l'
,
'i'
,
'c'
,
'L'
,
'i'
,
'n'
,
'k'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
};
static
const
struct
unicode_str
symlink_str
=
{
symlink_value
,
sizeof
(
symlink_value
)
};
...
...
@@ -166,6 +168,12 @@ static const struct object_ops key_ops =
};
static
inline
int
is_wow6432node
(
const
WCHAR
*
name
,
unsigned
int
len
)
{
return
(
len
==
sizeof
(
wow6432node
)
&&
!
memicmpW
(
name
,
wow6432node
,
sizeof
(
wow6432node
)
/
sizeof
(
WCHAR
)
));
}
/*
* The registry text file format v2 used by this code is similar to the one
* used by REGEDIT import/export functionality, with the following differences:
...
...
@@ -528,6 +536,7 @@ static struct key *alloc_subkey( struct key *parent, const struct unicode_str *n
for
(
i
=
++
parent
->
last_subkey
;
i
>
index
;
i
--
)
parent
->
subkeys
[
i
]
=
parent
->
subkeys
[
i
-
1
];
parent
->
subkeys
[
index
]
=
key
;
if
(
is_wow6432node
(
key
->
name
,
key
->
namelen
))
parent
->
flags
|=
KEY_WOW64
;
}
return
key
;
}
...
...
@@ -546,6 +555,7 @@ static void free_subkey( struct key *parent, int index )
parent
->
last_subkey
--
;
key
->
flags
|=
KEY_DELETED
;
key
->
parent
=
NULL
;
if
(
is_wow6432node
(
key
->
name
,
key
->
namelen
))
parent
->
flags
&=
~
KEY_WOW64
;
release_object
(
key
);
/* try to shrink the array */
...
...
@@ -587,6 +597,22 @@ static struct key *find_subkey( const struct key *key, const struct unicode_str
return
NULL
;
}
/* return the wow64 variant of the key, or the key itself if none */
static
struct
key
*
find_wow64_subkey
(
struct
key
*
key
,
const
struct
unicode_str
*
name
)
{
static
const
struct
unicode_str
wow6432node_str
=
{
wow6432node
,
sizeof
(
wow6432node
)
};
int
index
;
if
(
!
(
key
->
flags
&
KEY_WOW64
))
return
key
;
if
(
!
is_wow6432node
(
name
->
str
,
name
->
len
))
{
key
=
find_subkey
(
key
,
&
wow6432node_str
,
&
index
);
assert
(
key
);
/* if KEY_WOW64 is set we must find it */
}
return
key
;
}
/* follow a symlink and return the resolved key */
static
struct
key
*
follow_symlink
(
struct
key
*
key
,
int
iteration
)
{
...
...
@@ -618,13 +644,15 @@ static struct key *follow_symlink( struct key *key, int iteration )
}
/* open a subkey */
static
struct
key
*
open_key
(
struct
key
*
key
,
const
struct
unicode_str
*
name
,
unsigned
int
attributes
)
static
struct
key
*
open_key
(
struct
key
*
key
,
const
struct
unicode_str
*
name
,
unsigned
int
access
,
unsigned
int
attributes
)
{
int
index
;
struct
unicode_str
token
;
token
.
str
=
NULL
;
if
(
!
get_path_token
(
name
,
&
token
))
return
NULL
;
if
(
access
&
KEY_WOW64_32KEY
)
key
=
find_wow64_subkey
(
key
,
&
token
);
while
(
token
.
len
)
{
if
(
!
(
key
=
find_subkey
(
key
,
&
token
,
&
index
)))
...
...
@@ -634,6 +662,7 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
}
get_path_token
(
name
,
&
token
);
if
(
!
token
.
len
)
break
;
if
(
!
(
access
&
KEY_WOW64_64KEY
))
key
=
find_wow64_subkey
(
key
,
&
token
);
if
(
!
(
key
=
follow_symlink
(
key
,
0
)))
{
set_error
(
STATUS_OBJECT_NAME_NOT_FOUND
);
...
...
@@ -641,6 +670,7 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
}
}
if
(
!
(
access
&
KEY_WOW64_64KEY
))
key
=
find_wow64_subkey
(
key
,
&
token
);
if
(
!
(
attributes
&
OBJ_OPENLINK
)
&&
!
(
key
=
follow_symlink
(
key
,
0
)))
{
set_error
(
STATUS_OBJECT_NAME_NOT_FOUND
);
...
...
@@ -654,7 +684,7 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
/* create a subkey */
static
struct
key
*
create_key
(
struct
key
*
key
,
const
struct
unicode_str
*
name
,
const
struct
unicode_str
*
class
,
unsigned
int
options
,
unsigned
int
attributes
,
int
*
created
)
unsigned
int
a
ccess
,
unsigned
int
a
ttributes
,
int
*
created
)
{
int
index
;
struct
unicode_str
token
,
next
;
...
...
@@ -668,6 +698,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
token
.
str
=
NULL
;
if
(
!
get_path_token
(
name
,
&
token
))
return
NULL
;
*
created
=
0
;
if
(
access
&
KEY_WOW64_32KEY
)
key
=
find_wow64_subkey
(
key
,
&
token
);
while
(
token
.
len
)
{
struct
key
*
subkey
;
...
...
@@ -675,6 +706,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
key
=
subkey
;
get_path_token
(
name
,
&
token
);
if
(
!
token
.
len
)
break
;
if
(
!
(
access
&
KEY_WOW64_64KEY
))
key
=
find_wow64_subkey
(
key
,
&
token
);
if
(
!
(
key
=
follow_symlink
(
key
,
0
)))
{
set_error
(
STATUS_OBJECT_NAME_NOT_FOUND
);
...
...
@@ -684,6 +716,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
if
(
!
token
.
len
)
/* the key already exists */
{
if
(
!
(
access
&
KEY_WOW64_64KEY
))
key
=
find_wow64_subkey
(
key
,
&
token
);
if
(
options
&
REG_OPTION_CREATE_LINK
)
{
set_error
(
STATUS_OBJECT_NAME_COLLISION
);
...
...
@@ -1786,6 +1819,8 @@ DECL_HANDLER(create_key)
struct
unicode_str
name
,
class
;
unsigned
int
access
=
req
->
access
;
if
(
!
is_wow64_thread
(
current
))
access
=
(
access
&
~
KEY_WOW64_32KEY
)
|
KEY_WOW64_64KEY
;
reply
->
hkey
=
0
;
if
(
req
->
namelen
>
get_req_data_size
())
...
...
@@ -1806,7 +1841,8 @@ DECL_HANDLER(create_key)
/* NOTE: no access rights are required from the parent handle to create a key */
if
((
parent
=
get_parent_hkey_obj
(
req
->
parent
)))
{
if
((
key
=
create_key
(
parent
,
&
name
,
&
class
,
req
->
options
,
req
->
attributes
,
&
reply
->
created
)))
if
((
key
=
create_key
(
parent
,
&
name
,
&
class
,
req
->
options
,
access
,
req
->
attributes
,
&
reply
->
created
)))
{
reply
->
hkey
=
alloc_handle
(
current
->
process
,
key
,
access
,
req
->
attributes
);
release_object
(
key
);
...
...
@@ -1822,12 +1858,14 @@ DECL_HANDLER(open_key)
struct
unicode_str
name
;
unsigned
int
access
=
req
->
access
;
if
(
!
is_wow64_thread
(
current
))
access
=
(
access
&
~
KEY_WOW64_32KEY
)
|
KEY_WOW64_64KEY
;
reply
->
hkey
=
0
;
/* NOTE: no access rights are required to open the parent key, only the child key */
if
((
parent
=
get_parent_hkey_obj
(
req
->
parent
)))
{
get_req_path
(
&
name
,
!
req
->
parent
);
if
((
key
=
open_key
(
parent
,
&
name
,
req
->
attributes
)))
if
((
key
=
open_key
(
parent
,
&
name
,
access
,
req
->
attributes
)))
{
reply
->
hkey
=
alloc_handle
(
current
->
process
,
key
,
access
,
req
->
attributes
);
release_object
(
key
);
...
...
@@ -1961,7 +1999,7 @@ DECL_HANDLER(load_registry)
{
int
dummy
;
get_req_path
(
&
name
,
!
req
->
hkey
);
if
((
key
=
create_key
(
parent
,
&
name
,
NULL
,
0
,
0
,
&
dummy
)))
if
((
key
=
create_key
(
parent
,
&
name
,
NULL
,
0
,
KEY_WOW64_64KEY
,
0
,
&
dummy
)))
{
load_registry
(
key
,
req
->
file
);
release_object
(
key
);
...
...
server/thread.c
View file @
ac08b038
...
...
@@ -67,6 +67,7 @@ static const unsigned int supported_cpus = CPU_FLAG(CPU_SPARC);
#else
#error Unsupported CPU
#endif
#define CPU_64BIT_MASK CPU_FLAG(CPU_x86_64)
/* thread queues */
...
...
@@ -408,6 +409,12 @@ struct thread *get_thread_from_pid( int pid )
return
NULL
;
}
/* determine if the thread is wow64 (32-bit client running on 64-bit server) */
int
is_wow64_thread
(
struct
thread
*
thread
)
{
return
(
supported_cpus
&
CPU_64BIT_MASK
)
&&
!
(
CPU_FLAG
(
thread
->
process
->
cpu
)
&
CPU_64BIT_MASK
);
}
int
set_thread_affinity
(
struct
thread
*
thread
,
affinity_t
affinity
)
{
int
ret
=
0
;
...
...
server/thread.h
View file @
ac08b038
...
...
@@ -118,6 +118,7 @@ extern int thread_add_inflight_fd( struct thread *thread, int client, int server
extern
int
thread_get_inflight_fd
(
struct
thread
*
thread
,
int
client
);
extern
struct
thread_snapshot
*
thread_snap
(
int
*
count
);
extern
struct
token
*
thread_get_impersonation_token
(
struct
thread
*
thread
);
extern
int
is_wow64_thread
(
struct
thread
*
thread
);
extern
int
set_thread_affinity
(
struct
thread
*
thread
,
affinity_t
affinity
);
/* ptrace functions */
...
...
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