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
06505c9a
Commit
06505c9a
authored
Dec 02, 2010
by
Hans Leidekker
Committed by
Alexandre Julliard
Dec 02, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Reuse temporary executables.
Fixes a custom action in the Office 2010 installer and makes installers that pack multiple custom actions in an executable faster.
parent
5a8ce4c7
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
41 deletions
+87
-41
custom.c
dlls/msi/custom.c
+63
-41
msipriv.h
dlls/msi/msipriv.h
+9
-0
package.c
dlls/msi/package.c
+15
-0
No files found.
dlls/msi/custom.c
View file @
06505c9a
...
...
@@ -355,60 +355,90 @@ end:
return
rc
;
}
static
UINT
store_binary_to_temp
(
MSIPACKAGE
*
package
,
LPCWSTR
source
,
LPWSTR
tmp_file
)
static
MSIBINARY
*
create_temp_binary
(
MSIPACKAGE
*
package
,
LPCWSTR
source
,
BOOL
dll
)
{
static
const
WCHAR
query
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'B'
,
'i'
,
'n'
,
'a'
,
'r'
,
'y'
,
'`'
,
' '
,
'W'
,
'H'
,
'E'
,
'R'
,
'E'
,
' '
,
'`'
,
'N'
,
'a'
,
'm'
,
'e'
,
'`'
,
' '
,
'='
,
' '
,
'\''
,
'%'
,
's'
,
'\''
,
0
};
MSIRECORD
*
row
=
0
;
MSIRECORD
*
row
;
MSIBINARY
*
binary
;
HANDLE
file
;
CHAR
buffer
[
1024
];
WCHAR
fmt
[
MAX_PATH
];
DWORD
sz
=
MAX_PATH
;
WCHAR
fmt
[
MAX_PATH
]
,
tmpfile
[
MAX_PATH
]
;
DWORD
sz
=
MAX_PATH
,
write
;
UINT
r
;
if
(
msi_get_property
(
package
->
db
,
cszTempFolder
,
fmt
,
&
sz
)
!=
ERROR_SUCCESS
)
GetTempPathW
(
MAX_PATH
,
fmt
);
if
(
GetTempFileNameW
(
fmt
,
szMsi
,
0
,
tmp_file
)
==
0
)
if
(
!
GetTempFileNameW
(
fmt
,
szMsi
,
0
,
tmpfile
)
)
{
TRACE
(
"
Unable to create file
\n
"
);
return
ERROR_FUNCTION_FAILED
;
TRACE
(
"
unable to create temp file %s (%u)
\n
"
,
debugstr_w
(
tmpfile
),
GetLastError
()
);
return
NULL
;
}
track_tempfile
(
package
,
tmp_file
);
row
=
MSI_QueryGetRecord
(
package
->
db
,
query
,
source
);
if
(
!
row
)
return
ERROR_FUNCTION_FAILED
;
return
NULL
;
/* write out the file */
file
=
CreateFileW
(
tmp_file
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
!
(
binary
=
msi_alloc_zero
(
sizeof
(
MSIBINARY
)
)))
{
msiobj_release
(
&
row
->
hdr
);
return
NULL
;
}
file
=
CreateFileW
(
tmpfile
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
file
==
INVALID_HANDLE_VALUE
)
r
=
ERROR_FUNCTION_FAILED
;
else
{
msiobj_release
(
&
row
->
hdr
);
return
NULL
;
}
do
{
DWORD
write
;
sz
=
sizeof
buffer
;
r
=
MSI_RecordReadStream
(
row
,
2
,
buffer
,
&
sz
);
sz
=
sizeof
(
buffer
);
r
=
MSI_RecordReadStream
(
row
,
2
,
buffer
,
&
sz
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"Failed to get stream
\n
"
);
break
;
}
WriteFile
(
file
,
buffer
,
sz
,
&
write
,
NULL
);
WriteFile
(
file
,
buffer
,
sz
,
&
write
,
NULL
);
}
while
(
sz
==
sizeof
buffer
);
CloseHandle
(
file
);
CloseHandle
(
file
);
msiobj_release
(
&
row
->
hdr
);
if
(
r
!=
ERROR_SUCCESS
)
{
DeleteFileW
(
tmpfile
);
msi_free
(
binary
);
return
NULL
;
}
msiobj_release
(
&
row
->
hdr
);
/* keep a reference to prevent the dll from being unloaded */
if
(
dll
&&
!
(
binary
->
module
=
LoadLibraryW
(
tmpfile
)))
{
ERR
(
"failed to load dll %s (%u)
\n
"
,
debugstr_w
(
binary
->
tmpfile
),
GetLastError
()
);
DeleteFileW
(
tmpfile
);
msi_free
(
binary
);
return
NULL
;
}
binary
->
source
=
strdupW
(
source
);
binary
->
tmpfile
=
strdupW
(
tmpfile
);
list_add_tail
(
&
package
->
binaries
,
&
binary
->
entry
);
return
binary
;
}
return
r
;
static
MSIBINARY
*
get_temp_binary
(
MSIPACKAGE
*
package
,
LPCWSTR
source
,
BOOL
dll
)
{
MSIBINARY
*
binary
;
LIST_FOR_EACH_ENTRY
(
binary
,
&
package
->
binaries
,
MSIBINARY
,
entry
)
{
if
(
!
strcmpW
(
binary
->
source
,
source
))
return
binary
;
}
return
create_temp_binary
(
package
,
source
,
dll
);
}
static
void
file_running_action
(
MSIPACKAGE
*
package
,
HANDLE
Handle
,
...
...
@@ -875,20 +905,15 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR
target
,
const
INT
type
,
LPCWSTR
action
)
{
msi_custom_action_info
*
info
;
WCHAR
tmp_file
[
MAX_PATH
]
;
MSIBINARY
*
binary
;
UINT
r
;
r
=
store_binary_to_temp
(
package
,
source
,
tmp_file
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
TRACE
(
"Calling function %s from %s
\n
"
,
debugstr_w
(
target
),
debugstr_w
(
tmp_file
));
if
(
!
(
binary
=
get_temp_binary
(
package
,
source
,
TRUE
)))
return
ERROR_FUNCTION_FAILED
;
if
(
!
strchrW
(
tmp_file
,
'.'
))
strcatW
(
tmp_file
,
szDot
);
TRACE
(
"Calling function %s from %s
\n
"
,
debugstr_w
(
target
),
debugstr_w
(
binary
->
tmpfile
));
info
=
do_msidbCustomActionTypeDll
(
package
,
type
,
tmp_
file
,
target
,
action
);
info
=
do_msidbCustomActionTypeDll
(
package
,
type
,
binary
->
tmp
file
,
target
,
action
);
r
=
wait_thread_handle
(
info
);
release_custom_action_data
(
info
);
...
...
@@ -898,7 +923,6 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
static
UINT
HANDLE_CustomType2
(
MSIPACKAGE
*
package
,
LPCWSTR
source
,
LPCWSTR
target
,
const
INT
type
,
LPCWSTR
action
)
{
WCHAR
tmp_file
[
MAX_PATH
];
STARTUPINFOW
si
;
PROCESS_INFORMATION
info
;
BOOL
rc
;
...
...
@@ -906,29 +930,27 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
WCHAR
*
deformated
=
NULL
;
WCHAR
*
cmd
;
static
const
WCHAR
spc
[]
=
{
' '
,
0
};
MSIBINARY
*
binary
;
UINT
r
;
memset
(
&
si
,
0
,
sizeof
(
STARTUPINFOW
));
r
=
store_binary_to_temp
(
package
,
source
,
tmp_file
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
!
(
binary
=
get_temp_binary
(
package
,
source
,
FALSE
)))
return
ERROR_FUNCTION_FAILED
;
deformat_string
(
package
,
target
,
&
deformated
);
len
=
strlenW
(
tmp_file
)
+
2
;
len
=
strlenW
(
binary
->
tmpfile
)
+
2
;
if
(
deformated
)
len
+=
strlenW
(
deformated
);
cmd
=
msi_alloc
(
sizeof
(
WCHAR
)
*
len
);
strcpyW
(
cmd
,
tmp_file
);
strcpyW
(
cmd
,
binary
->
tmpfile
);
if
(
deformated
)
{
strcatW
(
cmd
,
spc
);
strcatW
(
cmd
,
deformated
);
msi_free
(
deformated
);
}
...
...
dlls/msi/msipriv.h
View file @
06505c9a
...
...
@@ -163,6 +163,14 @@ typedef struct tagMSIPATCHINFO
MSIPATCHSTATE
state
;
}
MSIPATCHINFO
;
typedef
struct
tagMSIBINARY
{
struct
list
entry
;
WCHAR
*
source
;
WCHAR
*
tmpfile
;
HMODULE
module
;
}
MSIBINARY
;
typedef
struct
_column_info
{
LPCWSTR
table
;
...
...
@@ -330,6 +338,7 @@ typedef struct tagMSIPACKAGE
struct
list
files
;
struct
list
tempfiles
;
struct
list
folders
;
struct
list
binaries
;
LPWSTR
ActionFormat
;
LPWSTR
LastAction
;
HANDLE
log_file
;
...
...
dlls/msi/package.c
View file @
06505c9a
...
...
@@ -284,6 +284,20 @@ static void free_package_structures( MSIPACKAGE *package )
msi_free
(
patch
);
}
LIST_FOR_EACH_SAFE
(
item
,
cursor
,
&
package
->
binaries
)
{
MSIBINARY
*
binary
=
LIST_ENTRY
(
item
,
MSIBINARY
,
entry
);
list_remove
(
&
binary
->
entry
);
if
(
binary
->
module
)
FreeLibrary
(
binary
->
module
);
if
(
!
DeleteFileW
(
binary
->
tmpfile
))
ERR
(
"failed to delete %s (%u)
\n
"
,
debugstr_w
(
binary
->
tmpfile
),
GetLastError
());
msi_free
(
binary
->
source
);
msi_free
(
binary
->
tmpfile
);
msi_free
(
binary
);
}
msi_free
(
package
->
BaseURL
);
msi_free
(
package
->
PackagePath
);
msi_free
(
package
->
ProductCode
);
...
...
@@ -1059,6 +1073,7 @@ static MSIPACKAGE *msi_alloc_package( void )
list_init
(
&
package
->
sourcelist_info
);
list_init
(
&
package
->
sourcelist_media
);
list_init
(
&
package
->
patches
);
list_init
(
&
package
->
binaries
);
}
return
package
;
...
...
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