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
f1e59351
Commit
f1e59351
authored
Mar 07, 2011
by
Hans Leidekker
Committed by
Alexandre Julliard
Mar 07, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Manage one assembly cache per major version of the .NET runtime.
parent
40ad619a
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
134 additions
and
68 deletions
+134
-68
assembly.c
dlls/msi/assembly.c
+121
-65
msipriv.h
dlls/msi/msipriv.h
+9
-1
package.c
dlls/msi/package.c
+4
-2
No files found.
dlls/msi/assembly.c
View file @
f1e59351
...
...
@@ -31,66 +31,72 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
static
HRESULT
(
WINAPI
*
pCreateAssemblyCacheNet
)(
IAssemblyCache
**
,
DWORD
);
static
HRESULT
(
WINAPI
*
pCreateAssemblyCacheNet11
)(
IAssemblyCache
**
,
DWORD
);
static
HRESULT
(
WINAPI
*
pCreateAssemblyCacheNet20
)(
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
BOOL
init_function_pointers
(
void
)
{
static
const
WCHAR
szFusion
[]
=
{
'f'
,
'u'
,
's'
,
'i'
,
'o'
,
'n'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
HMODULE
hfusion
,
hmscoree
,
hsxs
;
HRESULT
hr
;
static
const
WCHAR
szVersion11
[]
=
{
'v'
,
'1'
,
'.'
,
'1'
,
'.'
,
'4'
,
'3'
,
'2'
,
'2'
,
0
};
static
const
WCHAR
szVersion20
[]
=
{
'v'
,
'2'
,
'.'
,
'0'
,
'.'
,
'5'
,
'0'
,
'7'
,
'2'
,
'7'
,
0
};
HMODULE
hfusion11
=
NULL
,
hfusion20
=
NULL
,
hmscoree
,
hsxs
;
if
(
pCreateAssemblyCacheNet
)
return
TRUE
;
if
(
pCreateAssemblyCacheNet
11
||
pCreateAssemblyCacheNet20
)
return
TRUE
;
if
(
!
(
hmscoree
=
LoadLibraryA
(
"mscoree.dll"
)))
{
WARN
(
"mscoree.dll not available
\n
"
);
return
FALSE
;
}
if
(
!
(
pLoadLibraryShim
=
(
void
*
)
GetProcAddress
(
hmscoree
,
"LoadLibraryShim"
)))
{
WARN
(
"LoadLibraryShim not available
\n
"
);
FreeLibrary
(
hmscoree
);
return
FALSE
;
}
hr
=
pLoadLibraryShim
(
szFusion
,
NULL
,
NULL
,
&
hfusion
);
if
(
FAILED
(
hr
))
{
WARN
(
"fusion.dll not available 0x%08x
\n
"
,
hr
);
FreeLibrary
(
hmscoree
);
return
FALSE
;
}
pCreateAssemblyCacheNet
=
(
void
*
)
GetProcAddress
(
hfusion
,
"CreateAssemblyCache"
);
if
(
!
(
hmscoree
=
LoadLibraryA
(
"mscoree.dll"
)))
return
FALSE
;
if
(
!
(
pGetFileVersion
=
(
void
*
)
GetProcAddress
(
hmscoree
,
"GetFileVersion"
)))
goto
error
;
if
(
!
(
pLoadLibraryShim
=
(
void
*
)
GetProcAddress
(
hmscoree
,
"LoadLibraryShim"
)))
goto
error
;
if
(
!
pLoadLibraryShim
(
szFusion
,
szVersion11
,
NULL
,
&
hfusion11
))
pCreateAssemblyCacheNet11
=
(
void
*
)
GetProcAddress
(
hfusion11
,
"CreateAssemblyCache"
);
if
(
!
pLoadLibraryShim
(
szFusion
,
szVersion20
,
NULL
,
&
hfusion20
))
pCreateAssemblyCacheNet20
=
(
void
*
)
GetProcAddress
(
hfusion20
,
"CreateAssemblyCache"
);
if
(
!
pCreateAssemblyCacheNet11
&&
!
pCreateAssemblyCacheNet20
)
goto
error
;
if
(
!
(
hsxs
=
LoadLibraryA
(
"sxs.dll"
)))
goto
error
;
if
(
!
(
pCreateAssemblyCacheSxs
=
(
void
*
)
GetProcAddress
(
hsxs
,
"CreateAssemblyCache"
)))
goto
error
;
return
TRUE
;
error:
pCreateAssemblyCacheNet11
=
NULL
;
pCreateAssemblyCacheNet20
=
NULL
;
FreeLibrary
(
hfusion11
);
FreeLibrary
(
hfusion20
);
FreeLibrary
(
hmscoree
);
if
(
!
(
hsxs
=
LoadLibraryA
(
"sxs.dll"
)))
{
WARN
(
"sxs.dll not available
\n
"
);
FreeLibrary
(
hfusion
);
return
FALSE
;
}
pCreateAssemblyCacheSxs
=
(
void
*
)
GetProcAddress
(
hsxs
,
"CreateAssemblyCache"
);
return
TRUE
;
}
static
BOOL
init_assembly_caches
(
MSIPACKAGE
*
package
)
{
HRESULT
hr
;
if
(
!
init_function_pointers
())
return
FALSE
;
if
(
package
->
cache_net
)
return
TRUE
;
if
(
package
->
cache_net
[
CLR_VERSION_V11
]
||
package
->
cache_net
[
CLR_VERSION_V20
])
return
TRUE
;
if
(
pCreateAssemblyCacheSxs
(
&
package
->
cache_sxs
,
0
)
!=
S_OK
)
return
FALSE
;
hr
=
pCreateAssemblyCacheNet
(
&
package
->
cache_net
,
0
);
if
(
hr
!=
S_OK
)
return
FALSE
;
if
(
pCreateAssemblyCacheNet11
)
pCreateAssemblyCacheNet11
(
&
package
->
cache_net
[
CLR_VERSION_V11
]
,
0
);
if
(
pCreateAssemblyCacheNet20
)
pCreateAssemblyCacheNet20
(
&
package
->
cache_net
[
CLR_VERSION_V20
],
0
)
;
hr
=
pCreateAssemblyCacheSxs
(
&
package
->
cache_sxs
,
0
);
if
(
hr
!=
S_OK
)
if
(
package
->
cache_net
[
CLR_VERSION_V11
]
||
package
->
cache_net
[
CLR_VERSION_V20
])
{
IAssemblyCache_Release
(
package
->
cache_net
);
package
->
cache_net
=
NULL
;
return
FALSE
;
}
return
TRUE
;
}
if
(
package
->
cache_net
[
CLR_VERSION_V11
])
{
IAssemblyCache_Release
(
package
->
cache_net
[
CLR_VERSION_V11
]
);
package
->
cache_net
[
CLR_VERSION_V11
]
=
NULL
;
}
if
(
package
->
cache_net
[
CLR_VERSION_V20
])
{
IAssemblyCache_Release
(
package
->
cache_net
[
CLR_VERSION_V20
]
);
package
->
cache_net
[
CLR_VERSION_V20
]
=
NULL
;
}
IAssemblyCache_Release
(
package
->
cache_sxs
);
package
->
cache_sxs
=
NULL
;
return
FALSE
;
}
MSIRECORD
*
get_assembly_record
(
MSIPACKAGE
*
package
,
const
WCHAR
*
comp
)
...
...
@@ -201,34 +207,36 @@ done:
return
display_name
;
}
static
BOOL
check_assembly_installed
(
MSIPACKAGE
*
package
,
MSIASSEMBLY
*
assembly
)
static
BOOL
is_assembly_installed
(
IAssemblyCache
*
cache
,
const
WCHAR
*
display_name
)
{
IAssemblyCache
*
cache
;
ASSEMBLY_INFO
info
;
HRESULT
hr
;
ASSEMBLY_INFO
info
;
if
(
assembly
->
application
)
memset
(
&
info
,
0
,
sizeof
(
info
)
);
info
.
cbAssemblyInfo
=
sizeof
(
info
);
hr
=
IAssemblyCache_QueryAssemblyInfo
(
cache
,
QUERYASMINFO_FLAG_GETSIZE
,
display_name
,
&
info
);
if
(
FAILED
(
hr
))
{
FIXME
(
"we should probably check the manifest file here
\n
"
);
if
(
msi_get_property_int
(
package
->
db
,
szInstalled
,
0
))
return
TRUE
;
TRACE
(
"QueryAssemblyInfo returned 0x%08x
\n
"
,
hr
);
return
FALSE
;
}
return
(
info
.
dwAssemblyFlags
==
ASSEMBLYINFO_FLAG_INSTALLED
);
}
if
(
!
init_assembly_caches
(
package
))
return
FALSE
;
if
(
assembly
->
attributes
==
msidbAssemblyAttributesWin32
)
cache
=
package
->
cache_sxs
;
else
cache
=
package
->
cache_net
;
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
};
static
const
WCHAR
clr_version_unknown
[]
=
{
'u'
,
'n'
,
'k'
,
'n'
,
'o'
,
'w'
,
'n'
,
0
};
memset
(
&
info
,
0
,
sizeof
(
info
)
);
info
.
cbAssemblyInfo
=
sizeof
(
info
);
hr
=
IAssemblyCache_QueryAssemblyInfo
(
cache
,
QUERYASMINFO_FLAG_VALIDATE
,
assembly
->
display_name
,
&
info
);
if
(
hr
!=
HRESULT_FROM_WIN32
(
ERROR_INSUFFICIENT_BUFFER
))
return
FALSE
;
static
const
WCHAR
*
clr_version
[]
=
{
clr_version_v11
,
clr_version_v20
}
;
return
(
info
.
dwAssemblyFlags
==
ASSEMBLYINFO_FLAG_INSTALLED
);
static
const
WCHAR
*
get_clr_version_str
(
enum
clr_version
version
)
{
if
(
version
>=
sizeof
(
clr_version
)
/
sizeof
(
clr_version
[
0
]))
return
clr_version_unknown
;
return
clr_version
[
version
];
}
MSIASSEMBLY
*
load_assembly
(
MSIPACKAGE
*
package
,
MSICOMPONENT
*
comp
)
...
...
@@ -236,9 +244,13 @@ MSIASSEMBLY *load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
MSIRECORD
*
rec
;
MSIASSEMBLY
*
a
;
if
(
!
(
rec
=
get_assembly_record
(
package
,
comp
->
Component
)))
if
(
!
(
rec
=
get_assembly_record
(
package
,
comp
->
Component
)))
return
NULL
;
if
(
!
init_assembly_caches
(
package
))
{
ERR
(
"can't initialize assembly caches
\n
"
);
msiobj_release
(
&
rec
->
hdr
);
return
NULL
;
}
if
(
!
(
a
=
msi_alloc_zero
(
sizeof
(
MSIASSEMBLY
)
)))
{
msiobj_release
(
&
rec
->
hdr
);
...
...
@@ -268,13 +280,57 @@ MSIASSEMBLY *load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
}
TRACE
(
"display name %s
\n
"
,
debugstr_w
(
a
->
display_name
));
a
->
installed
=
check_assembly_installed
(
package
,
a
);
if
(
a
->
application
)
{
FIXME
(
"we should probably check the manifest file here
\n
"
);
a
->
installed
=
(
msi_get_property_int
(
package
->
db
,
szInstalled
,
0
)
!=
0
);
}
else
{
if
(
a
->
attributes
==
msidbAssemblyAttributesWin32
)
a
->
installed
=
is_assembly_installed
(
package
->
cache_sxs
,
a
->
display_name
);
else
{
UINT
i
;
for
(
i
=
0
;
i
<
CLR_VERSION_MAX
;
i
++
)
{
a
->
clr_version
[
i
]
=
is_assembly_installed
(
package
->
cache_net
[
i
],
a
->
display_name
);
if
(
a
->
clr_version
[
i
])
{
TRACE
(
"runtime version %s
\n
"
,
debugstr_w
(
get_clr_version_str
(
i
)));
a
->
installed
=
TRUE
;
}
}
}
}
TRACE
(
"assembly is %s
\n
"
,
a
->
installed
?
"installed"
:
"not installed"
);
msiobj_release
(
&
rec
->
hdr
);
return
a
;
}
static
enum
clr_version
get_clr_version
(
const
WCHAR
*
filename
)
{
DWORD
len
;
HRESULT
hr
;
enum
clr_version
version
=
CLR_VERSION_V11
;
WCHAR
*
strW
;
hr
=
pGetFileVersion
(
filename
,
NULL
,
0
,
&
len
);
if
(
hr
!=
HRESULT_FROM_WIN32
(
ERROR_INSUFFICIENT_BUFFER
))
return
CLR_VERSION_V11
;
if
((
strW
=
msi_alloc
(
len
*
sizeof
(
WCHAR
)
)))
{
hr
=
pGetFileVersion
(
filename
,
strW
,
len
,
&
len
);
if
(
hr
==
S_OK
)
{
UINT
i
;
for
(
i
=
0
;
i
<
CLR_VERSION_MAX
;
i
++
)
if
(
!
strcmpW
(
strW
,
clr_version
[
i
]
))
version
=
i
;
}
msi_free
(
strW
);
}
return
version
;
}
UINT
install_assembly
(
MSIPACKAGE
*
package
,
MSICOMPONENT
*
comp
)
{
HRESULT
hr
;
...
...
@@ -304,7 +360,7 @@ UINT install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
else
{
manifest
=
get_loaded_file
(
package
,
comp
->
KeyPath
)
->
TargetPath
;
cache
=
package
->
cache_net
;
cache
=
package
->
cache_net
[
get_clr_version
(
manifest
)]
;
}
TRACE
(
"installing assembly %s
\n
"
,
debugstr_w
(
manifest
));
...
...
dlls/msi/msipriv.h
View file @
f1e59351
...
...
@@ -324,6 +324,13 @@ enum platform
PLATFORM_X64
};
enum
clr_version
{
CLR_VERSION_V11
,
CLR_VERSION_V20
,
CLR_VERSION_MAX
};
typedef
struct
tagMSIPACKAGE
{
MSIOBJECTHDR
hdr
;
...
...
@@ -342,7 +349,7 @@ typedef struct tagMSIPACKAGE
LPWSTR
ActionFormat
;
LPWSTR
LastAction
;
HANDLE
log_file
;
IAssemblyCache
*
cache_net
;
IAssemblyCache
*
cache_net
[
CLR_VERSION_MAX
]
;
IAssemblyCache
*
cache_sxs
;
struct
list
classes
;
...
...
@@ -423,6 +430,7 @@ typedef struct tagMSIASSEMBLY
LPWSTR
display_name
;
LPWSTR
tempdir
;
BOOL
installed
;
BOOL
clr_version
[
CLR_VERSION_MAX
];
}
MSIASSEMBLY
;
typedef
struct
tagMSICOMPONENT
...
...
dlls/msi/package.c
View file @
f1e59351
...
...
@@ -313,7 +313,8 @@ static void free_package_structures( MSIPACKAGE *package )
static
void
MSI_FreePackage
(
MSIOBJECTHDR
*
arg
)
{
MSIPACKAGE
*
package
=
(
MSIPACKAGE
*
)
arg
;
UINT
i
;
MSIPACKAGE
*
package
=
(
MSIPACKAGE
*
)
arg
;
if
(
package
->
dialog
)
msi_dialog_destroy
(
package
->
dialog
);
...
...
@@ -322,7 +323,8 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
free_package_structures
(
package
);
CloseHandle
(
package
->
log_file
);
if
(
package
->
cache_net
)
IAssemblyCache_Release
(
package
->
cache_net
);
for
(
i
=
0
;
i
<
CLR_VERSION_MAX
;
i
++
)
if
(
package
->
cache_net
[
i
])
IAssemblyCache_Release
(
package
->
cache_net
[
i
]
);
if
(
package
->
cache_sxs
)
IAssemblyCache_Release
(
package
->
cache_sxs
);
}
...
...
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