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
510e7467
Commit
510e7467
authored
Apr 22, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
setupapi: Add support for installing PE builtins as fake dlls.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
948fc851
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
20 deletions
+33
-20
fakedll.c
dlls/setupapi/fakedll.c
+33
-20
No files found.
dlls/setupapi/fakedll.c
View file @
510e7467
...
...
@@ -51,6 +51,7 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
setupapi
);
static
const
char
builtin_signature
[]
=
"Wine builtin DLL"
;
static
const
char
fakedll_signature
[]
=
"Wine placeholder DLL"
;
static
const
unsigned
int
file_alignment
=
512
;
...
...
@@ -191,14 +192,15 @@ failed:
/* read in the contents of a file into the global file buffer */
/* return 1 on success, 0 on nonexistent file, -1 on other error */
static
int
read_file
(
const
char
*
name
,
void
**
data
,
SIZE_T
*
size
)
static
int
read_file
(
const
char
*
name
,
void
**
data
,
SIZE_T
*
size
,
BOOL
expect_builtin
)
{
struct
stat
st
;
int
fd
,
ret
=
-
1
;
size_t
header_size
;
IMAGE_DOS_HEADER
*
dos
;
IMAGE_NT_HEADERS
*
nt
;
const
size_t
min_size
=
sizeof
(
*
dos
)
+
sizeof
(
fakedll_signature
)
+
const
char
*
signature
=
expect_builtin
?
builtin_signature
:
fakedll_signature
;
const
size_t
min_size
=
sizeof
(
*
dos
)
+
32
+
FIELD_OFFSET
(
IMAGE_NT_HEADERS
,
OptionalHeader
.
MajorLinkerVersion
);
if
((
fd
=
open
(
name
,
O_RDONLY
|
O_BINARY
))
==
-
1
)
return
0
;
...
...
@@ -220,8 +222,8 @@ static int read_file( const char *name, void **data, SIZE_T *size )
if
(
pread
(
fd
,
file_buffer
,
header_size
,
0
)
!=
header_size
)
goto
done
;
dos
=
file_buffer
;
if
(
dos
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
goto
done
;
if
(
dos
->
e_lfanew
<
s
izeof
(
fakedll_signature
)
)
goto
done
;
if
(
memcmp
(
dos
+
1
,
fakedll_signature
,
sizeof
(
fakedll_signature
)
))
goto
done
;
if
(
dos
->
e_lfanew
<
s
trlen
(
signature
)
+
1
)
goto
done
;
if
(
memcmp
(
dos
+
1
,
signature
,
strlen
(
signature
)
+
1
))
goto
done
;
if
(
dos
->
e_lfanew
+
FIELD_OFFSET
(
IMAGE_NT_HEADERS
,
OptionalHeader
.
MajorLinkerVersion
)
>
header_size
)
goto
done
;
nt
=
(
IMAGE_NT_HEADERS
*
)((
char
*
)
file_buffer
+
dos
->
e_lfanew
);
...
...
@@ -354,14 +356,15 @@ static BOOL is_fake_dll( HANDLE h )
{
IMAGE_DOS_HEADER
*
dos
;
DWORD
size
;
BYTE
buffer
[
sizeof
(
*
dos
)
+
sizeof
(
fakedll_signature
)
];
BYTE
buffer
[
sizeof
(
*
dos
)
+
32
];
if
(
!
ReadFile
(
h
,
buffer
,
sizeof
(
buffer
),
&
size
,
NULL
)
||
size
!=
sizeof
(
buffer
))
return
FALSE
;
dos
=
(
IMAGE_DOS_HEADER
*
)
buffer
;
if
(
dos
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
FALSE
;
if
(
dos
->
e_lfanew
<
size
)
return
FALSE
;
return
!
memcmp
(
dos
+
1
,
fakedll_signature
,
sizeof
(
fakedll_signature
)
);
return
(
!
memcmp
(
dos
+
1
,
builtin_signature
,
sizeof
(
builtin_signature
)
)
||
!
memcmp
(
dos
+
1
,
fakedll_signature
,
sizeof
(
fakedll_signature
)
));
}
/* create directories leading to a given file */
...
...
@@ -417,33 +420,39 @@ static void *load_fake_dll( const WCHAR *name, SIZE_T *size )
if
(
build_dir
)
{
strcpy
(
file
+
pos
+
len
+
1
,
".fake"
);
/* try as a dll */
ptr
=
file
+
pos
;
namelen
=
len
+
1
;
file
[
pos
+
len
+
1
]
=
0
;
if
(
namelen
>
4
&&
!
memcmp
(
ptr
+
namelen
-
4
,
".dll"
,
4
))
namelen
-=
4
;
ptr
=
prepend
(
ptr
,
ptr
,
namelen
);
ptr
=
prepend
(
ptr
,
"/dlls"
,
sizeof
(
"/dlls"
)
-
1
);
ptr
=
prepend
(
ptr
,
build_dir
,
strlen
(
build_dir
)
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
)))
goto
done
;
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
TRUE
)))
goto
done
;
strcpy
(
file
+
pos
+
len
+
1
,
".fake"
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
FALSE
)))
goto
done
;
/* now as a program */
ptr
=
file
+
pos
;
namelen
=
len
+
1
;
file
[
pos
+
len
+
1
]
=
0
;
if
(
namelen
>
4
&&
!
memcmp
(
ptr
+
namelen
-
4
,
".exe"
,
4
))
namelen
-=
4
;
ptr
=
prepend
(
ptr
,
ptr
,
namelen
);
ptr
=
prepend
(
ptr
,
"/programs"
,
sizeof
(
"/programs"
)
-
1
);
ptr
=
prepend
(
ptr
,
build_dir
,
strlen
(
build_dir
)
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
)))
goto
done
;
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
TRUE
)))
goto
done
;
strcpy
(
file
+
pos
+
len
+
1
,
".fake"
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
FALSE
)))
goto
done
;
}
file
[
pos
+
len
+
1
]
=
0
;
for
(
i
=
0
;
(
path
=
wine_dll_enum_load_path
(
i
));
i
++
)
{
ptr
=
prepend
(
file
+
pos
,
path
,
strlen
(
path
)
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
TRUE
)))
break
;
ptr
=
prepend
(
file
+
pos
,
"/fakedlls"
,
sizeof
(
"/fakedlls"
)
-
1
);
ptr
=
prepend
(
ptr
,
path
,
strlen
(
path
)
);
if
((
res
=
read_file
(
ptr
,
&
data
,
size
)))
break
;
if
((
res
=
read_file
(
ptr
,
&
data
,
size
,
FALSE
)))
break
;
}
done:
...
...
@@ -842,7 +851,7 @@ static void register_fake_dll( const WCHAR *name, const void *data, size_t size
}
/* copy a fake dll file to the dest directory */
static
void
install_fake_dll
(
WCHAR
*
dest
,
char
*
file
,
const
char
*
ext
)
static
int
install_fake_dll
(
WCHAR
*
dest
,
char
*
file
,
const
char
*
ext
,
BOOL
expect_builtin
)
{
int
ret
;
SIZE_T
size
;
...
...
@@ -852,8 +861,8 @@ static void install_fake_dll( WCHAR *dest, char *file, const char *ext )
char
*
name
=
strrchr
(
file
,
'/'
)
+
1
;
char
*
end
=
name
+
strlen
(
name
);
if
(
ext
)
strcpy
(
end
,
ext
);
if
(
!
(
ret
=
read_file
(
file
,
&
data
,
&
size
)))
return
;
strcpy
(
end
,
ext
);
if
(
!
(
ret
=
read_file
(
file
,
&
data
,
&
size
,
expect_builtin
)))
return
0
;
if
(
end
>
name
+
2
&&
!
strncmp
(
end
-
2
,
"16"
,
2
))
end
-=
2
;
/* remove "16" suffix */
dll_name_AtoW
(
destname
,
name
,
end
-
name
);
...
...
@@ -875,10 +884,11 @@ static void install_fake_dll( WCHAR *dest, char *file, const char *ext )
}
}
*
destname
=
0
;
/* restore it for next file */
return
ret
;
}
/* find and install all fake dlls in a given lib directory */
static
void
install_lib_dir
(
WCHAR
*
dest
,
char
*
file
,
const
char
*
default_ext
)
static
void
install_lib_dir
(
WCHAR
*
dest
,
char
*
file
,
const
char
*
default_ext
,
BOOL
expect_builtin
)
{
DIR
*
dir
;
struct
dirent
*
de
;
...
...
@@ -898,9 +908,10 @@ static void install_lib_dir( WCHAR *dest, char *file, const char *default_ext )
strcat
(
name
,
"/"
);
strcat
(
name
,
de
->
d_name
);
if
(
!
strchr
(
de
->
d_name
,
'.'
))
strcat
(
name
,
default_ext
);
install_fake_dll
(
dest
,
file
,
".fake"
);
if
(
!
install_fake_dll
(
dest
,
file
,
""
,
expect_builtin
))
install_fake_dll
(
dest
,
file
,
".fake"
,
FALSE
);
}
else
install_fake_dll
(
dest
,
file
,
NULL
);
else
install_fake_dll
(
dest
,
file
,
""
,
expect_builtin
);
}
closedir
(
dir
);
}
...
...
@@ -931,16 +942,18 @@ static BOOL create_wildcard_dlls( const WCHAR *dirname )
{
strcpy
(
file
,
build_dir
);
strcat
(
file
,
"/dlls"
);
install_lib_dir
(
dest
,
file
,
".dll"
);
install_lib_dir
(
dest
,
file
,
".dll"
,
TRUE
);
strcpy
(
file
,
build_dir
);
strcat
(
file
,
"/programs"
);
install_lib_dir
(
dest
,
file
,
".exe"
);
install_lib_dir
(
dest
,
file
,
".exe"
,
TRUE
);
}
for
(
i
=
0
;
(
path
=
wine_dll_enum_load_path
(
i
));
i
++
)
{
strcpy
(
file
,
path
);
install_lib_dir
(
dest
,
file
,
NULL
,
TRUE
);
strcpy
(
file
,
path
);
strcat
(
file
,
"/fakedlls"
);
install_lib_dir
(
dest
,
file
,
NULL
);
install_lib_dir
(
dest
,
file
,
NULL
,
FALSE
);
}
HeapFree
(
GetProcessHeap
(),
0
,
file
);
HeapFree
(
GetProcessHeap
(),
0
,
dest
);
...
...
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