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
5696c3c2
Commit
5696c3c2
authored
Nov 11, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
setupapi: Add an extension to support file copies from module resources.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
354aabd7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
5 deletions
+65
-5
queue.c
dlls/setupapi/queue.c
+65
-5
No files found.
dlls/setupapi/queue.c
View file @
5696c3c2
...
...
@@ -19,6 +19,7 @@
*/
#include <stdarg.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
...
...
@@ -151,8 +152,11 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
unsigned
int
src_len
=
1
,
dst_len
=
1
;
WCHAR
*
source
=
(
PWSTR
)
paths
->
Source
,
*
target
=
(
PWSTR
)
paths
->
Target
;
if
(
op
->
media
)
src_len
+=
lstrlenW
(
op
->
media
->
root
)
+
1
;
if
(
op
->
src_path
)
src_len
+=
lstrlenW
(
op
->
src_path
)
+
1
;
if
(
op
->
src_file
[
0
]
!=
'@'
)
{
if
(
op
->
media
)
src_len
+=
lstrlenW
(
op
->
media
->
root
)
+
1
;
if
(
op
->
src_path
)
src_len
+=
lstrlenW
(
op
->
src_path
)
+
1
;
}
if
(
op
->
src_file
)
src_len
+=
lstrlenW
(
op
->
src_file
)
+
1
;
if
(
op
->
dst_path
)
dst_len
+=
lstrlenW
(
op
->
dst_path
)
+
1
;
if
(
op
->
dst_file
)
dst_len
+=
lstrlenW
(
op
->
dst_file
)
+
1
;
...
...
@@ -170,7 +174,10 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
paths
->
Target
=
target
=
HeapAlloc
(
GetProcessHeap
(),
0
,
dst_len
);
}
if
(
!
source
||
!
target
)
return
FALSE
;
concat_W
(
source
,
op
->
media
?
op
->
media
->
root
:
NULL
,
op
->
src_path
,
op
->
src_file
);
if
(
op
->
src_file
[
0
]
!=
'@'
)
concat_W
(
source
,
op
->
media
?
op
->
media
->
root
:
NULL
,
op
->
src_path
,
op
->
src_file
);
else
lstrcpyW
(
source
,
op
->
src_file
);
concat_W
(
target
,
NULL
,
op
->
dst_path
,
op
->
dst_file
);
paths
->
Win32Error
=
0
;
paths
->
Flags
=
0
;
...
...
@@ -1002,6 +1009,59 @@ static BOOL create_full_pathW(const WCHAR *path)
return
ret
;
}
static
BOOL
copy_file
(
LPCWSTR
source
,
LPCWSTR
target
)
{
WCHAR
module
[
MAX_PATH
];
HMODULE
mod
=
NULL
;
HRSRC
res
;
HGLOBAL
data
;
HANDLE
handle
;
DWORD
size
,
written
;
BOOL
ret
=
FALSE
;
int
id
=
0
;
const
WCHAR
*
p
;
TRACE
(
"%s -> %s
\n
"
,
debugstr_w
(
source
),
debugstr_w
(
target
)
);
if
(
source
[
0
]
!=
'@'
)
return
CopyFileW
(
source
,
target
,
FALSE
);
/* Wine extension: when the source of a file copy is in the format "@file.dll,-123"
* the source data is extracted from the corresponding file.dll resource */
source
++
;
/* skip '@' */
p
=
wcschr
(
source
,
','
);
if
(
!
p
||
p
-
source
>=
MAX_PATH
)
{
SetLastError
(
ERROR_RESOURCE_DATA_NOT_FOUND
);
return
FALSE
;
}
memcpy
(
module
,
source
,
(
p
-
source
)
*
sizeof
(
WCHAR
)
);
module
[
p
-
source
]
=
0
;
id
=
-
wcstol
(
p
+
1
,
NULL
,
10
);
if
(
id
<=
0
||
id
>
0xffff
||
!
(
mod
=
LoadLibraryExW
(
module
,
0
,
LOAD_LIBRARY_AS_DATAFILE
))
||
!
(
res
=
FindResourceW
(
mod
,
MAKEINTRESOURCEW
(
id
),
L"WINE_DATA_FILE"
))
||
!
(
data
=
LoadResource
(
mod
,
res
)))
{
WARN
(
"failed to save %s #%d to %s
\n
"
,
debugstr_w
(
module
),
-
id
,
debugstr_w
(
target
)
);
if
(
mod
)
FreeLibrary
(
mod
);
SetLastError
(
ERROR_RESOURCE_DATA_NOT_FOUND
);
return
FALSE
;
}
size
=
SizeofResource
(
mod
,
res
);
if
((
handle
=
CreateFileW
(
target
,
GENERIC_WRITE
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
CREATE_ALWAYS
,
0
,
0
))
==
INVALID_HANDLE_VALUE
)
{
WARN
(
"failed to save %s #%d to %s
\n
"
,
debugstr_w
(
module
),
-
id
,
debugstr_w
(
target
)
);
if
(
mod
)
FreeLibrary
(
mod
);
return
FALSE
;
}
ret
=
WriteFile
(
handle
,
LockResource
(
data
),
size
,
&
written
,
NULL
)
&&
written
==
size
;
CloseHandle
(
handle
);
if
(
!
ret
)
DeleteFileW
(
target
);
return
ret
;
}
static
BOOL
do_file_copyW
(
LPCWSTR
source
,
LPCWSTR
target
,
DWORD
style
,
PSP_FILE_CALLBACK_W
handler
,
PVOID
context
)
{
...
...
@@ -1124,7 +1184,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
if
(
docopy
)
{
rc
=
CopyFileW
(
source
,
target
,
FALSE
);
rc
=
copy_file
(
source
,
target
);
if
(
!
rc
&&
GetLastError
()
==
ERROR_SHARING_VIOLATION
&&
(
style
&
SP_COPY_IN_USE_NEEDS_REBOOT
))
{
...
...
@@ -1134,7 +1194,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
if
(
GetTempPathW
(
MAX_PATH
,
temp
)
&&
GetTempFileNameW
(
temp
,
L"SET"
,
0
,
temp_file
))
{
rc
=
CopyFileW
(
source
,
temp_file
,
FALSE
);
rc
=
copy_file
(
source
,
temp_file
);
if
(
rc
)
rc
=
MoveFileExW
(
temp_file
,
target
,
MOVEFILE_DELAY_UNTIL_REBOOT
);
else
...
...
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