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
dc222830
Commit
dc222830
authored
Apr 10, 2015
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 10, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Add support for patching global assembly files.
parent
d263c91c
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
161 additions
and
22 deletions
+161
-22
assembly.c
dlls/msi/assembly.c
+70
-1
files.c
dlls/msi/files.c
+89
-21
msipriv.h
dlls/msi/msipriv.h
+2
-0
No files found.
dlls/msi/assembly.c
View file @
dc222830
...
...
@@ -38,6 +38,8 @@ static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD );
static
HRESULT
(
WINAPI
*
pCreateAssemblyCacheSxs
)(
IAssemblyCache
**
,
DWORD
);
static
HRESULT
(
WINAPI
*
pLoadLibraryShim
)(
LPCWSTR
,
LPCWSTR
,
LPVOID
,
HMODULE
*
);
static
HRESULT
(
WINAPI
*
pGetFileVersion
)(
LPCWSTR
,
LPWSTR
,
DWORD
,
DWORD
*
);
static
HRESULT
(
WINAPI
*
pCreateAssemblyNameObject
)(
IAssemblyName
**
,
LPCWSTR
,
DWORD
,
LPVOID
);
static
HRESULT
(
WINAPI
*
pCreateAssemblyEnum
)(
IAssemblyEnum
**
,
IUnknown
*
,
IAssemblyName
*
,
DWORD
,
LPVOID
);
static
HMODULE
hfusion10
,
hfusion11
,
hfusion20
,
hfusion40
,
hmscoree
,
hsxs
;
...
...
@@ -79,8 +81,11 @@ static BOOL init_function_pointers( void )
pCreateAssemblyCacheNet20
=
(
void
*
)
GetProcAddress
(
hfusion20
,
"CreateAssemblyCache"
);
if
(
!
pLoadLibraryShim
(
szFusion
,
szVersion40
,
NULL
,
&
hfusion40
))
{
pCreateAssemblyCacheNet40
=
(
void
*
)
GetProcAddress
(
hfusion40
,
"CreateAssemblyCache"
);
pCreateAssemblyNameObject
=
(
void
*
)
GetProcAddress
(
hfusion40
,
"CreateAssemblyNameObject"
);
pCreateAssemblyEnum
=
(
void
*
)
GetProcAddress
(
hfusion40
,
"CreateAssemblyEnum"
);
}
return
TRUE
;
}
...
...
@@ -259,6 +264,70 @@ static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_n
return
FALSE
;
}
WCHAR
*
msi_get_assembly_path
(
MSIPACKAGE
*
package
,
const
WCHAR
*
displayname
)
{
HRESULT
hr
;
ASSEMBLY_INFO
info
;
IAssemblyCache
*
cache
=
package
->
cache_net
[
CLR_VERSION_V40
];
if
(
!
cache
)
return
NULL
;
memset
(
&
info
,
0
,
sizeof
(
info
)
);
info
.
cbAssemblyInfo
=
sizeof
(
info
);
hr
=
IAssemblyCache_QueryAssemblyInfo
(
cache
,
0
,
displayname
,
&
info
);
if
(
hr
!=
E_NOT_SUFFICIENT_BUFFER
)
return
NULL
;
if
(
!
(
info
.
pszCurrentAssemblyPathBuf
=
msi_alloc
(
info
.
cchBuf
*
sizeof
(
WCHAR
)
)))
return
NULL
;
hr
=
IAssemblyCache_QueryAssemblyInfo
(
cache
,
0
,
displayname
,
&
info
);
if
(
FAILED
(
hr
))
{
msi_free
(
info
.
pszCurrentAssemblyPathBuf
);
return
NULL
;
}
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
info
.
pszCurrentAssemblyPathBuf
));
return
info
.
pszCurrentAssemblyPathBuf
;
}
IAssemblyEnum
*
msi_create_assembly_enum
(
MSIPACKAGE
*
package
,
const
WCHAR
*
displayname
)
{
HRESULT
hr
;
IAssemblyName
*
name
;
IAssemblyEnum
*
ret
;
WCHAR
*
str
;
UINT
len
=
0
;
if
(
!
pCreateAssemblyNameObject
||
!
pCreateAssemblyEnum
)
return
NULL
;
hr
=
pCreateAssemblyNameObject
(
&
name
,
displayname
,
CANOF_PARSE_DISPLAY_NAME
,
NULL
);
if
(
FAILED
(
hr
))
return
NULL
;
hr
=
IAssemblyName_GetName
(
name
,
&
len
,
NULL
);
if
(
hr
!=
E_NOT_SUFFICIENT_BUFFER
||
!
(
str
=
msi_alloc
(
len
*
sizeof
(
WCHAR
)
)))
{
IAssemblyName_Release
(
name
);
return
NULL
;
}
hr
=
IAssemblyName_GetName
(
name
,
&
len
,
str
);
IAssemblyName_Release
(
name
);
if
(
FAILED
(
hr
))
{
msi_free
(
str
);
return
NULL
;
}
hr
=
pCreateAssemblyNameObject
(
&
name
,
str
,
0
,
NULL
);
msi_free
(
str
);
if
(
FAILED
(
hr
))
return
NULL
;
hr
=
pCreateAssemblyEnum
(
&
ret
,
NULL
,
name
,
ASM_CACHE_GAC
,
NULL
);
IAssemblyName_Release
(
name
);
if
(
FAILED
(
hr
))
return
NULL
;
return
ret
;
}
static
const
WCHAR
clr_version_v10
[]
=
{
'v'
,
'1'
,
'.'
,
'0'
,
'.'
,
'3'
,
'7'
,
'0'
,
'5'
,
0
};
static
const
WCHAR
clr_version_v11
[]
=
{
'v'
,
'1'
,
'.'
,
'1'
,
'.'
,
'4'
,
'3'
,
'2'
,
'2'
,
0
};
static
const
WCHAR
clr_version_v20
[]
=
{
'v'
,
'2'
,
'.'
,
'0'
,
'.'
,
'5'
,
'0'
,
'7'
,
'2'
,
'7'
,
0
};
...
...
dlls/msi/files.c
View file @
dc222830
...
...
@@ -32,6 +32,8 @@
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
...
...
@@ -493,6 +495,78 @@ static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
return
TRUE
;
}
static
UINT
patch_file
(
MSIPACKAGE
*
package
,
MSIFILEPATCH
*
patch
)
{
UINT
r
=
ERROR_SUCCESS
;
WCHAR
*
tmpfile
=
msi_create_temp_file
(
package
->
db
);
if
(
!
tmpfile
)
return
ERROR_INSTALL_FAILURE
;
if
(
ApplyPatchToFileW
(
patch
->
path
,
patch
->
File
->
TargetPath
,
tmpfile
,
0
))
{
DeleteFileW
(
patch
->
File
->
TargetPath
);
MoveFileW
(
tmpfile
,
patch
->
File
->
TargetPath
);
}
else
{
WARN
(
"failed to patch %s: %08x
\n
"
,
debugstr_w
(
patch
->
File
->
TargetPath
),
GetLastError
());
r
=
ERROR_INSTALL_FAILURE
;
}
DeleteFileW
(
patch
->
path
);
DeleteFileW
(
tmpfile
);
msi_free
(
tmpfile
);
return
r
;
}
static
UINT
patch_assembly
(
MSIPACKAGE
*
package
,
MSIASSEMBLY
*
assembly
,
MSIFILEPATCH
*
patch
)
{
UINT
r
=
ERROR_FUNCTION_FAILED
;
IAssemblyName
*
name
;
IAssemblyEnum
*
iter
;
if
(
!
(
iter
=
msi_create_assembly_enum
(
package
,
assembly
->
display_name
)))
return
ERROR_FUNCTION_FAILED
;
while
((
IAssemblyEnum_GetNextAssembly
(
iter
,
NULL
,
&
name
,
0
)
==
S_OK
))
{
WCHAR
*
displayname
,
*
path
;
UINT
len
=
0
;
HRESULT
hr
;
hr
=
IAssemblyName_GetDisplayName
(
name
,
NULL
,
&
len
,
0
);
if
(
hr
!=
E_NOT_SUFFICIENT_BUFFER
||
!
(
displayname
=
msi_alloc
(
len
*
sizeof
(
WCHAR
)
)))
break
;
hr
=
IAssemblyName_GetDisplayName
(
name
,
displayname
,
&
len
,
0
);
if
(
FAILED
(
hr
))
{
msi_free
(
displayname
);
break
;
}
if
((
path
=
msi_get_assembly_path
(
package
,
displayname
)))
{
if
(
!
CopyFileW
(
path
,
patch
->
File
->
TargetPath
,
FALSE
))
{
ERR
(
"Failed to copy file %s -> %s (%u)
\n
"
,
debugstr_w
(
path
),
debugstr_w
(
patch
->
File
->
TargetPath
),
GetLastError
()
);
msi_free
(
path
);
msi_free
(
displayname
);
IAssemblyName_Release
(
name
);
break
;
}
r
=
patch_file
(
package
,
patch
);
msi_free
(
path
);
}
msi_free
(
displayname
);
IAssemblyName_Release
(
name
);
if
(
r
==
ERROR_SUCCESS
)
break
;
}
IAssemblyEnum_Release
(
iter
);
return
r
;
}
UINT
ACTION_PatchFiles
(
MSIPACKAGE
*
package
)
{
MSIFILEPATCH
*
patch
;
...
...
@@ -549,34 +623,28 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
LIST_FOR_EACH_ENTRY
(
patch
,
&
package
->
filepatches
,
MSIFILEPATCH
,
entry
)
{
WCHAR
*
tmpfile
;
BOOL
ret
;
MSICOMPONENT
*
comp
=
patch
->
File
->
Component
;
if
(
!
patch
->
path
)
continue
;
if
(
!
(
tmpfile
=
msi_create_temp_file
(
package
->
db
)))
{
rc
=
ERROR_INSTALL_FAILURE
;
goto
done
;
}
ret
=
ApplyPatchToFileW
(
patch
->
path
,
patch
->
File
->
TargetPath
,
tmpfile
,
0
);
if
(
ret
)
{
DeleteFileW
(
patch
->
File
->
TargetPath
);
MoveFileW
(
tmpfile
,
patch
->
File
->
TargetPath
);
}
if
(
msi_is_global_assembly
(
comp
))
rc
=
patch_assembly
(
package
,
comp
->
assembly
,
patch
);
else
WARN
(
"failed to patch %s: %08x
\n
"
,
debugstr_w
(
patch
->
File
->
TargetPath
),
GetLastError
());
DeleteFileW
(
patch
->
path
);
DeleteFileW
(
tmpfile
);
msi_free
(
tmpfile
);
rc
=
patch_file
(
package
,
patch
);
if
(
!
ret
&&
!
(
patch
->
Attributes
&
msidbPatchAttributesNonVital
))
if
(
rc
&&
!
(
patch
->
Attributes
&
msidbPatchAttributesNonVital
))
{
ERR
(
"Failed to apply patch to file: %s
\n
"
,
debugstr_w
(
patch
->
File
->
File
));
rc
=
ERROR_INSTALL_FAILURE
;
goto
done
;
break
;
}
if
(
msi_is_global_assembly
(
comp
))
{
if
((
rc
=
msi_install_assembly
(
package
,
comp
)))
{
ERR
(
"Failed to install patched assembly
\n
"
);
break
;
}
}
}
...
...
dlls/msi/msipriv.h
View file @
dc222830
...
...
@@ -1042,6 +1042,8 @@ extern UINT msi_uninstall_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN
extern
BOOL
msi_init_assembly_caches
(
MSIPACKAGE
*
)
DECLSPEC_HIDDEN
;
extern
void
msi_destroy_assembly_caches
(
MSIPACKAGE
*
)
DECLSPEC_HIDDEN
;
extern
BOOL
msi_is_global_assembly
(
MSICOMPONENT
*
)
DECLSPEC_HIDDEN
;
extern
IAssemblyEnum
*
msi_create_assembly_enum
(
MSIPACKAGE
*
,
const
WCHAR
*
)
DECLSPEC_HIDDEN
;
extern
WCHAR
*
msi_get_assembly_path
(
MSIPACKAGE
*
,
const
WCHAR
*
)
DECLSPEC_HIDDEN
;
extern
WCHAR
*
msi_font_version_from_file
(
const
WCHAR
*
)
DECLSPEC_HIDDEN
;
extern
WCHAR
**
msi_split_string
(
const
WCHAR
*
,
WCHAR
)
DECLSPEC_HIDDEN
;
extern
UINT
msi_set_original_database_property
(
MSIDATABASE
*
,
const
WCHAR
*
)
DECLSPEC_HIDDEN
;
...
...
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