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
282246ec
Commit
282246ec
authored
Apr 13, 2008
by
James Hawkins
Committed by
Alexandre Julliard
Apr 15, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fusion: Implement IAssemblyCache::InstallAssembly.
parent
d3afff85
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
943 additions
and
40 deletions
+943
-40
Makefile.in
dlls/fusion/Makefile.in
+2
-1
asmcache.c
dlls/fusion/asmcache.c
+132
-2
assembly.c
dlls/fusion/assembly.c
+573
-0
fusionpriv.h
dlls/fusion/fusionpriv.h
+212
-0
asmcache.c
dlls/fusion/tests/asmcache.c
+24
-37
No files found.
dlls/fusion/Makefile.in
View file @
282246ec
...
...
@@ -3,11 +3,12 @@ TOPOBJDIR = ../..
SRCDIR
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
fusion.dll
IMPORTS
=
kernel32
IMPORTS
=
advapi32 dbghelp kernel32 shlwapi version
C_SRCS
=
\
asmcache.c
\
asmname.c
\
assembly.c
\
fusion.c
\
fusion_main.c
...
...
dlls/fusion/asmcache.c
View file @
282246ec
...
...
@@ -19,18 +19,78 @@
*/
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winver.h"
#include "wincrypt.h"
#include "winreg.h"
#include "shlwapi.h"
#include "dbghelp.h"
#include "ole2.h"
#include "fusion.h"
#include "corerror.h"
#include "fusionpriv.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
fusion
);
static
BOOL
create_full_path
(
LPCSTR
path
)
{
LPSTR
new_path
;
BOOL
ret
=
TRUE
;
int
len
;
new_path
=
HeapAlloc
(
GetProcessHeap
(),
0
,
lstrlenA
(
path
)
+
1
);
if
(
!
new_path
)
return
FALSE
;
lstrcpyA
(
new_path
,
path
);
while
((
len
=
lstrlenA
(
new_path
))
&&
new_path
[
len
-
1
]
==
'\\'
)
new_path
[
len
-
1
]
=
0
;
while
(
!
CreateDirectoryA
(
new_path
,
NULL
))
{
LPSTR
slash
;
DWORD
last_error
=
GetLastError
();
if
(
last_error
==
ERROR_ALREADY_EXISTS
)
break
;
if
(
last_error
!=
ERROR_PATH_NOT_FOUND
)
{
ret
=
FALSE
;
break
;
}
if
(
!
(
slash
=
strrchr
(
new_path
,
'\\'
)))
{
ret
=
FALSE
;
break
;
}
len
=
slash
-
new_path
;
new_path
[
len
]
=
0
;
if
(
!
create_full_path
(
new_path
))
{
ret
=
FALSE
;
break
;
}
new_path
[
len
]
=
'\\'
;
}
HeapFree
(
GetProcessHeap
(),
0
,
new_path
);
return
ret
;
}
/* IAssemblyCache */
typedef
struct
{
...
...
@@ -130,10 +190,80 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
LPCWSTR
pszManifestFilePath
,
LPCFUSION_INSTALL_REFERENCE
pRefData
)
{
FIXME
(
"(%p, %d, %s, %p) stub!
\n
"
,
iface
,
dwFlags
,
ASSEMBLY
*
assembly
;
LPSTR
filename
;
LPSTR
name
=
NULL
;
LPSTR
token
=
NULL
;
LPSTR
version
=
NULL
;
LPSTR
asmpath
=
NULL
;
CHAR
path
[
MAX_PATH
];
CHAR
windir
[
MAX_PATH
];
LPWSTR
ext
;
HRESULT
hr
;
static
const
WCHAR
ext_exe
[]
=
{
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
ext_dll
[]
=
{
'.'
,
'd'
,
'l'
,
'l'
,
0
};
TRACE
(
"(%p, %d, %s, %p)
\n
"
,
iface
,
dwFlags
,
debugstr_w
(
pszManifestFilePath
),
pRefData
);
return
E_NOTIMPL
;
if
(
!
pszManifestFilePath
||
!*
pszManifestFilePath
)
return
E_INVALIDARG
;
if
(
!
(
ext
=
strrchrW
(
pszManifestFilePath
,
'.'
)))
return
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
);
if
(
lstrcmpW
(
ext
,
ext_exe
)
&&
lstrcmpW
(
ext
,
ext_dll
))
return
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
);
if
(
GetFileAttributesW
(
pszManifestFilePath
)
==
INVALID_FILE_ATTRIBUTES
)
return
HRESULT_FROM_WIN32
(
ERROR_FILE_NOT_FOUND
);
hr
=
assembly_create
(
&
assembly
,
pszManifestFilePath
);
if
(
FAILED
(
hr
))
{
hr
=
COR_E_ASSEMBLYEXPECTED
;
goto
done
;
}
hr
=
assembly_get_name
(
assembly
,
&
name
);
if
(
FAILED
(
hr
))
goto
done
;
hr
=
assembly_get_pubkey_token
(
assembly
,
&
token
);
if
(
FAILED
(
hr
))
goto
done
;
hr
=
assembly_get_version
(
assembly
,
&
version
);
if
(
FAILED
(
hr
))
goto
done
;
GetWindowsDirectoryA
(
windir
,
MAX_PATH
);
FIXME
(
"Ignoring assembly architecture!
\n
"
);
sprintf
(
path
,
"%s
\\
assembly
\\
GAC_MSIL
\\
%s
\\
%s__%s
\\
"
,
windir
,
name
,
version
,
token
);
create_full_path
(
path
);
hr
=
assembly_get_path
(
assembly
,
&
asmpath
);
if
(
FAILED
(
hr
))
goto
done
;
filename
=
PathFindFileNameA
(
asmpath
);
lstrcatA
(
path
,
filename
);
if
(
!
CopyFileA
(
asmpath
,
path
,
FALSE
))
hr
=
HRESULT_FROM_WIN32
(
GetLastError
());
done:
HeapFree
(
GetProcessHeap
(),
0
,
name
);
HeapFree
(
GetProcessHeap
(),
0
,
token
);
HeapFree
(
GetProcessHeap
(),
0
,
version
);
HeapFree
(
GetProcessHeap
(),
0
,
asmpath
);
assembly_release
(
assembly
);
return
hr
;
}
static
const
IAssemblyCacheVtbl
AssemblyCacheVtbl
=
{
...
...
dlls/fusion/assembly.c
0 → 100644
View file @
282246ec
/*
* assembly parser
*
* Copyright 2008 James Hawkins
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winver.h"
#include "wincrypt.h"
#include "dbghelp.h"
#include "ole2.h"
#include "fusion.h"
#include "fusionpriv.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#define MAX_CLR_TABLES 64
typedef
struct
tagCLRTABLE
{
DWORD
rows
;
DWORD
offset
;
}
CLRTABLE
;
struct
tagASSEMBLY
{
LPSTR
path
;
HANDLE
hfile
;
HANDLE
hmap
;
BYTE
*
data
;
IMAGE_NT_HEADERS32
*
nthdr
;
IMAGE_COR20_HEADER
*
corhdr
;
METADATAHDR
*
metadatahdr
;
METADATATABLESHDR
*
tableshdr
;
DWORD
numtables
;
DWORD
*
numrows
;
CLRTABLE
tables
[
MAX_CLR_TABLES
];
BYTE
*
strings
;
BYTE
*
blobs
;
};
/* FIXME: fill in */
const
DWORD
COR_TABLE_SIZES
[
64
]
=
{
sizeof
(
MODULETABLE
),
sizeof
(
TYPEREFTABLE
),
sizeof
(
TYPEDEFTABLE
),
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
sizeof
(
ASSEMBLYTABLE
),
0
,
0
,
0
,
0
,
0
,
0
,
0
,
sizeof
(
MANIFESTRESTABLE
),
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
LPSTR
strdupWtoA
(
LPCWSTR
str
)
{
LPSTR
ret
=
NULL
;
DWORD
len
;
if
(
!
str
)
return
ret
;
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
str
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
if
(
ret
)
WideCharToMultiByte
(
CP_ACP
,
0
,
str
,
-
1
,
ret
,
len
,
NULL
,
NULL
);
return
ret
;
}
static
DWORD
rva_to_offset
(
IMAGE_NT_HEADERS
*
nthdrs
,
DWORD
rva
)
{
DWORD
offset
=
rva
,
limit
;
IMAGE_SECTION_HEADER
*
img
;
WORD
i
;
img
=
IMAGE_FIRST_SECTION
(
nthdrs
);
if
(
rva
<
img
->
PointerToRawData
)
return
rva
;
for
(
i
=
0
;
i
<
nthdrs
->
FileHeader
.
NumberOfSections
;
i
++
)
{
if
(
img
[
i
].
SizeOfRawData
)
limit
=
img
[
i
].
SizeOfRawData
;
else
limit
=
img
[
i
].
Misc
.
VirtualSize
;
if
(
rva
>=
img
[
i
].
VirtualAddress
&&
rva
<
(
img
[
i
].
VirtualAddress
+
limit
))
{
if
(
img
[
i
].
PointerToRawData
!=
0
)
{
offset
-=
img
[
i
].
VirtualAddress
;
offset
+=
img
[
i
].
PointerToRawData
;
}
return
offset
;
}
}
return
0
;
}
static
BYTE
*
GetData
(
BYTE
*
pData
,
ULONG
*
pLength
)
{
if
((
*
pData
&
0x80
)
==
0x00
)
{
*
pLength
=
(
*
pData
&
0x7f
);
return
pData
+
1
;
}
if
((
*
pData
&
0xC0
)
==
0x80
)
{
*
pLength
=
((
*
pData
&
0x3f
)
<<
8
|
*
(
pData
+
1
));
return
pData
+
2
;
}
if
((
*
pData
&
0xE0
)
==
0xC0
)
{
*
pLength
=
((
*
pData
&
0x1f
)
<<
24
|
*
(
pData
+
1
)
<<
16
|
*
(
pData
+
2
)
<<
8
|
*
(
pData
+
3
));
return
pData
+
4
;
}
*
pLength
=
(
ULONG
)
-
1
;
return
0
;
}
static
VOID
*
assembly_data_offset
(
ASSEMBLY
*
assembly
,
ULONG
offset
)
{
return
(
VOID
*
)
&
assembly
->
data
[
offset
];
}
static
HRESULT
parse_clr_tables
(
ASSEMBLY
*
assembly
,
ULONG
offset
)
{
DWORD
i
,
previ
,
offidx
;
ULONG
currofs
;
currofs
=
offset
;
assembly
->
tableshdr
=
(
METADATATABLESHDR
*
)
assembly_data_offset
(
assembly
,
currofs
);
if
(
!
assembly
->
tableshdr
)
return
E_FAIL
;
currofs
+=
sizeof
(
METADATATABLESHDR
);
assembly
->
numrows
=
(
DWORD
*
)
assembly_data_offset
(
assembly
,
currofs
);
if
(
!
assembly
->
numrows
)
return
E_FAIL
;
assembly
->
numtables
=
0
;
for
(
i
=
0
;
i
<
MAX_CLR_TABLES
;
i
++
)
{
if
((
i
<
32
&&
(
assembly
->
tableshdr
->
MaskValid
.
LowPart
>>
i
)
&
1
)
||
(
i
>=
32
&&
(
assembly
->
tableshdr
->
MaskValid
.
HighPart
>>
i
)
&
1
))
{
assembly
->
numtables
++
;
}
}
currofs
+=
assembly
->
numtables
*
sizeof
(
DWORD
);
memset
(
assembly
->
tables
,
-
1
,
MAX_CLR_TABLES
*
sizeof
(
CLRTABLE
));
if
(
assembly
->
tableshdr
->
MaskValid
.
LowPart
&
1
)
{
assembly
->
tables
[
0
].
offset
=
currofs
;
assembly
->
tables
[
0
].
rows
=
assembly
->
numrows
[
0
];
}
previ
=
0
;
offidx
=
1
;
for
(
i
=
1
;
i
<
MAX_CLR_TABLES
;
i
++
)
{
if
((
i
<
32
&&
(
assembly
->
tableshdr
->
MaskValid
.
LowPart
>>
i
)
&
1
)
||
(
i
>=
32
&&
(
assembly
->
tableshdr
->
MaskValid
.
HighPart
>>
i
)
&
1
))
{
currofs
+=
COR_TABLE_SIZES
[
previ
]
*
assembly
->
numrows
[
offidx
-
1
];
assembly
->
tables
[
i
].
offset
=
currofs
;
assembly
->
tables
[
i
].
rows
=
assembly
->
numrows
[
offidx
];
offidx
++
;
previ
=
i
;
}
}
return
S_OK
;
}
static
HRESULT
parse_clr_metadata
(
ASSEMBLY
*
assembly
)
{
METADATASTREAMHDR
*
streamhdr
;
ULONG
rva
,
i
,
ofs
;
LPSTR
stream
;
HRESULT
hr
;
BYTE
*
ptr
;
rva
=
assembly
->
corhdr
->
MetaData
.
VirtualAddress
;
assembly
->
metadatahdr
=
ImageRvaToVa
(
assembly
->
nthdr
,
assembly
->
data
,
rva
,
NULL
);
if
(
!
assembly
->
metadatahdr
)
return
E_FAIL
;
ptr
=
ImageRvaToVa
(
assembly
->
nthdr
,
assembly
->
data
,
rva
+
sizeof
(
METADATAHDR
),
NULL
);
if
(
!
ptr
)
return
E_FAIL
;
for
(
i
=
0
;
i
<
assembly
->
metadatahdr
->
Streams
;
i
++
)
{
streamhdr
=
(
METADATASTREAMHDR
*
)
ptr
;
ofs
=
rva_to_offset
(
assembly
->
nthdr
,
rva
+
streamhdr
->
Offset
);
ptr
+=
sizeof
(
METADATASTREAMHDR
);
stream
=
(
LPSTR
)
ptr
;
if
(
!
lstrcmpA
(
stream
,
"#~"
))
{
hr
=
parse_clr_tables
(
assembly
,
ofs
);
if
(
FAILED
(
hr
))
return
hr
;
}
else
if
(
!
lstrcmpA
(
stream
,
"#Strings"
))
assembly
->
strings
=
(
BYTE
*
)
assembly_data_offset
(
assembly
,
ofs
);
else
if
(
!
lstrcmpA
(
stream
,
"#Blob"
))
assembly
->
blobs
=
(
BYTE
*
)
assembly_data_offset
(
assembly
,
ofs
);
ptr
+=
lstrlenA
(
stream
);
while
(
!*
ptr
)
ptr
++
;
}
return
S_OK
;
}
static
HRESULT
parse_pe_header
(
ASSEMBLY
*
assembly
)
{
IMAGE_DATA_DIRECTORY
*
datadirs
;
assembly
->
nthdr
=
ImageNtHeader
(
assembly
->
data
);
if
(
!
assembly
->
nthdr
)
return
E_FAIL
;
datadirs
=
assembly
->
nthdr
->
OptionalHeader
.
DataDirectory
;
if
(
!
datadirs
)
return
E_FAIL
;
if
(
!
datadirs
[
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].
VirtualAddress
||
!
datadirs
[
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].
Size
)
{
return
E_FAIL
;
}
assembly
->
corhdr
=
ImageRvaToVa
(
assembly
->
nthdr
,
assembly
->
data
,
datadirs
[
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].
VirtualAddress
,
NULL
);
if
(
!
assembly
->
corhdr
)
return
E_FAIL
;
return
S_OK
;
}
HRESULT
assembly_create
(
ASSEMBLY
**
out
,
LPCWSTR
file
)
{
ASSEMBLY
*
assembly
;
HRESULT
hr
;
*
out
=
NULL
;
assembly
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
ASSEMBLY
));
if
(
!
assembly
)
return
E_OUTOFMEMORY
;
ZeroMemory
(
assembly
,
sizeof
(
ASSEMBLY
));
assembly
->
path
=
strdupWtoA
(
file
);
if
(
!
assembly
->
path
)
return
E_OUTOFMEMORY
;
assembly
->
hfile
=
CreateFileW
(
file
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
!
assembly
->
hfile
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
assembly
->
hmap
=
CreateFileMappingW
(
assembly
->
hfile
,
NULL
,
PAGE_READONLY
,
0
,
0
,
NULL
);
if
(
!
assembly
->
hmap
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
assembly
->
data
=
MapViewOfFile
(
assembly
->
hmap
,
FILE_MAP_READ
,
0
,
0
,
0
);
if
(
!
assembly
->
data
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
hr
=
parse_pe_header
(
assembly
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
parse_clr_metadata
(
assembly
);
if
(
FAILED
(
hr
))
return
hr
;
*
out
=
assembly
;
return
S_OK
;
}
HRESULT
assembly_release
(
ASSEMBLY
*
assembly
)
{
if
(
!
assembly
)
return
S_OK
;
HeapFree
(
GetProcessHeap
(),
0
,
assembly
->
path
);
UnmapViewOfFile
(
assembly
->
data
);
CloseHandle
(
assembly
->
hmap
);
CloseHandle
(
assembly
->
hfile
);
HeapFree
(
GetProcessHeap
(),
0
,
assembly
);
return
S_OK
;
}
static
LPSTR
assembly_dup_str
(
ASSEMBLY
*
assembly
,
WORD
index
)
{
return
strdup
((
LPSTR
)
&
assembly
->
strings
[
index
]);
}
HRESULT
assembly_get_name
(
ASSEMBLY
*
assembly
,
LPSTR
*
name
)
{
ASSEMBLYTABLE
*
asmtbl
;
ULONG
offset
;
offset
=
assembly
->
tables
[
0x20
].
offset
;
/* FIXME: add constants */
if
(
offset
<
0
)
return
E_FAIL
;
asmtbl
=
(
ASSEMBLYTABLE
*
)
assembly_data_offset
(
assembly
,
offset
);
if
(
!
asmtbl
)
return
E_FAIL
;
*
name
=
assembly_dup_str
(
assembly
,
asmtbl
->
Name
);
if
(
!*
name
)
return
E_OUTOFMEMORY
;
return
S_OK
;
}
HRESULT
assembly_get_path
(
ASSEMBLY
*
assembly
,
LPSTR
*
path
)
{
*
path
=
strdup
(
assembly
->
path
);
if
(
!*
path
)
return
E_OUTOFMEMORY
;
return
S_OK
;
}
HRESULT
assembly_get_version
(
ASSEMBLY
*
assembly
,
LPSTR
*
version
)
{
LPSTR
verdata
;
VS_FIXEDFILEINFO
*
ffi
;
HRESULT
hr
=
S_OK
;
DWORD
size
;
size
=
GetFileVersionInfoSizeA
(
assembly
->
path
,
NULL
);
if
(
!
size
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
verdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
if
(
!
verdata
)
return
E_OUTOFMEMORY
;
if
(
!
GetFileVersionInfoA
(
assembly
->
path
,
0
,
size
,
verdata
))
{
hr
=
HRESULT_FROM_WIN32
(
GetLastError
());
goto
done
;
}
if
(
!
VerQueryValueA
(
verdata
,
"
\\
"
,
(
LPVOID
*
)
&
ffi
,
&
size
))
{
hr
=
HRESULT_FROM_WIN32
(
GetLastError
());
goto
done
;
}
*
version
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_PATH
);
if
(
!*
version
)
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
sprintf
(
*
version
,
"%d.%d.%d.%d"
,
HIWORD
(
ffi
->
dwFileVersionMS
),
LOWORD
(
ffi
->
dwFileVersionMS
),
HIWORD
(
ffi
->
dwFileVersionLS
),
LOWORD
(
ffi
->
dwFileVersionLS
));
done:
HeapFree
(
GetProcessHeap
(),
0
,
verdata
);
return
hr
;
}
HRESULT
assembly_get_architecture
(
ASSEMBLY
*
assembly
,
DWORD
fixme
)
{
/* FIXME */
return
S_OK
;
}
static
BYTE
*
assembly_get_blob
(
ASSEMBLY
*
assembly
,
WORD
index
,
ULONG
*
size
)
{
return
GetData
(
&
assembly
->
blobs
[
index
],
size
);
}
static
void
bytes_to_str
(
BYTE
*
bytes
,
DWORD
len
,
LPSTR
str
)
{
int
i
;
static
const
char
hexval
[
16
]
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
for
(
i
=
0
;
i
<
len
;
i
++
)
{
str
[
i
*
2
]
=
hexval
[((
bytes
[
i
]
>>
4
)
&
0xF
)];
str
[
i
*
2
+
1
]
=
hexval
[(
bytes
[
i
])
&
0x0F
];
}
}
#define BYTES_PER_TOKEN 8
#define CHARS_PER_BYTE 2
#define TOKEN_LENGTH (BYTES_PER_TOKEN * CHARS_PER_BYTE + 1)
HRESULT
assembly_get_pubkey_token
(
ASSEMBLY
*
assembly
,
LPSTR
*
token
)
{
ASSEMBLYTABLE
*
asmtbl
;
ULONG
i
,
offset
,
size
;
BYTE
*
hashdata
;
HCRYPTPROV
crypt
;
HCRYPTHASH
hash
;
BYTE
*
pubkey
;
BYTE
tokbytes
[
BYTES_PER_TOKEN
];
HRESULT
hr
=
E_FAIL
;
LPSTR
tok
;
*
token
=
NULL
;
offset
=
assembly
->
tables
[
0x20
].
offset
;
/* FIXME: add constants */
if
(
offset
<
0
)
return
E_FAIL
;
asmtbl
=
(
ASSEMBLYTABLE
*
)
assembly_data_offset
(
assembly
,
offset
);
if
(
!
asmtbl
)
return
E_FAIL
;
pubkey
=
assembly_get_blob
(
assembly
,
asmtbl
->
PublicKey
,
&
size
);
if
(
!
CryptAcquireContextA
(
&
crypt
,
NULL
,
NULL
,
PROV_RSA_FULL
,
CRYPT_VERIFYCONTEXT
))
return
E_FAIL
;
if
(
!
CryptCreateHash
(
crypt
,
CALG_SHA1
,
0
,
0
,
&
hash
))
return
E_FAIL
;
if
(
!
CryptHashData
(
hash
,
pubkey
,
size
,
0
))
return
E_FAIL
;
size
=
0
;
if
(
!
CryptGetHashParam
(
hash
,
HP_HASHVAL
,
NULL
,
&
size
,
0
))
return
E_FAIL
;
hashdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
if
(
!
hashdata
)
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
if
(
!
CryptGetHashParam
(
hash
,
HP_HASHVAL
,
hashdata
,
&
size
,
0
))
goto
done
;
for
(
i
=
size
-
1
;
i
>=
size
-
8
;
i
--
)
tokbytes
[
size
-
i
-
1
]
=
hashdata
[
i
];
tok
=
HeapAlloc
(
GetProcessHeap
(),
0
,
TOKEN_LENGTH
);
if
(
!
tok
)
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
bytes_to_str
(
tokbytes
,
BYTES_PER_TOKEN
,
tok
);
tok
[
TOKEN_LENGTH
-
1
]
=
'\0'
;
*
token
=
tok
;
hr
=
S_OK
;
done:
HeapFree
(
GetProcessHeap
(),
0
,
hashdata
);
CryptDestroyHash
(
hash
);
CryptReleaseContext
(
crypt
,
0
);
return
hr
;
}
dlls/fusion/fusionpriv.h
0 → 100644
View file @
282246ec
/*
* fusion private definitions
*
* Copyright 2008 James Hawkins
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_FUSION_PRIVATE__
#define __WINE_FUSION_PRIVATE__
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
typedef
struct
{
ULONG
Signature
;
USHORT
MajorVersion
;
USHORT
MinorVersion
;
ULONG
Reserved
;
ULONG
VersionLength
;
BYTE
Version
[
12
];
BYTE
Flags
;
WORD
Streams
;
}
METADATAHDR
;
#include <pshpack1.h>
typedef
struct
{
DWORD
Offset
;
DWORD
Size
;
}
METADATASTREAMHDR
;
typedef
struct
{
DWORD
Reserved1
;
BYTE
MajorVersion
;
BYTE
MinorVersion
;
BYTE
HeapOffsetSizes
;
BYTE
Reserved2
;
LARGE_INTEGER
MaskValid
;
LARGE_INTEGER
MaskSorted
;
}
METADATATABLESHDR
;
typedef
struct
{
WORD
Generation
;
WORD
Name
;
WORD
Mvid
;
WORD
EncId
;
WORD
EncBaseId
;
}
MODULETABLE
;
typedef
struct
{
DWORD
Flags
;
WORD
Name
;
WORD
Namespace
;
WORD
Extends
;
WORD
FieldList
;
WORD
MethodList
;
}
TYPEDEFTABLE
;
typedef
struct
{
DWORD
ResolutionScope
;
WORD
Name
;
WORD
Namespace
;
}
TYPEREFTABLE
;
typedef
struct
{
DWORD
HashAlgId
;
WORD
MajorVersion
;
WORD
MinorVersion
;
WORD
BuildNumber
;
WORD
RevisionNumber
;
DWORD
Flags
;
WORD
PublicKey
;
WORD
Name
;
WORD
Culture
;
}
ASSEMBLYTABLE
;
typedef
struct
{
DWORD
Offset
;
DWORD
Flags
;
WORD
Name
;
WORD
Implementation
;
}
MANIFESTRESTABLE
;
typedef
struct
{
DWORD
ImportLookupTable
;
DWORD
DateTimeStamp
;
DWORD
ForwarderChain
;
DWORD
Name
;
DWORD
ImportAddressTable
;
BYTE
pad
[
20
];
}
IMPORTTABLE
;
typedef
struct
{
DWORD
HintNameTableRVA
;
BYTE
pad
[
8
];
}
IMPORTLOOKUPTABLE
;
typedef
struct
{
WORD
Hint
;
BYTE
Name
[
12
];
BYTE
Module
[
12
];
DWORD
Reserved
;
WORD
EntryPoint
;
DWORD
RVA
;
}
HINTNAMETABLE
;
typedef
struct
{
DWORD
PageRVA
;
DWORD
Size
;
DWORD
Relocation
;
}
RELOCATION
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
WCHAR
szKey
[
17
];
VS_FIXEDFILEINFO
Value
;
}
VS_VERSIONINFO
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
WCHAR
szKey
[
13
];
}
VARFILEINFO
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
WCHAR
szKey
[
13
];
DWORD
Value
;
}
VAR
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
WCHAR
szKey
[
15
];
}
STRINGFILEINFO
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
WCHAR
szKey
[
9
];
}
STRINGTABLE
;
typedef
struct
{
WORD
wLength
;
WORD
wValueLength
;
WORD
wType
;
}
STRINGHDR
;
typedef
struct
{
DWORD
Size
;
DWORD
Signature
;
DWORD
HeaderVersion
;
DWORD
SkipData
;
BYTE
Data
[
168
];
}
RESOURCE
;
#include <poppack.h>
struct
tagASSEMBLY
;
typedef
struct
tagASSEMBLY
ASSEMBLY
;
HRESULT
assembly_create
(
ASSEMBLY
**
out
,
LPCWSTR
file
);
HRESULT
assembly_release
(
ASSEMBLY
*
assembly
);
HRESULT
assembly_get_name
(
ASSEMBLY
*
assembly
,
LPSTR
*
name
);
HRESULT
assembly_get_path
(
ASSEMBLY
*
assembly
,
LPSTR
*
path
);
HRESULT
assembly_get_version
(
ASSEMBLY
*
assembly
,
LPSTR
*
version
);
HRESULT
assembly_get_architecture
(
ASSEMBLY
*
assembly
,
DWORD
fixme
);
HRESULT
assembly_get_pubkey_token
(
ASSEMBLY
*
assembly
,
LPSTR
*
token
);
#endif
/* __WINE_FUSION_PRIVATE__ */
dlls/fusion/tests/asmcache.c
View file @
282246ec
...
...
@@ -853,6 +853,7 @@ static void test_InstallAssembly(void)
IAssemblyCache
*
cache
;
HRESULT
hr
;
ULONG
disp
;
DWORD
attr
;
static
const
WCHAR
empty
[]
=
{
0
};
static
const
WCHAR
noext
[]
=
{
'f'
,
'i'
,
'l'
,
'e'
,
0
};
...
...
@@ -877,64 +878,44 @@ static void test_InstallAssembly(void)
/* NULL pszManifestFilePath */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
NULL
,
NULL
);
todo_wine
{
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got %08x
\n
"
,
hr
);
}
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got %08x
\n
"
,
hr
);
/* empty pszManifestFilePath */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
empty
,
NULL
);
todo_wine
{
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got %08x
\n
"
,
hr
);
}
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got %08x
\n
"
,
hr
);
/* pszManifestFilePath has no extension */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
noext
,
NULL
);
todo_wine
{
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
),
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x
\n
"
,
hr
);
}
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
),
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x
\n
"
,
hr
);
/* pszManifestFilePath has bad extension */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
badext
,
NULL
);
todo_wine
{
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
),
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x
\n
"
,
hr
);
}
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_INVALID_NAME
),
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_NAME), got %08x
\n
"
,
hr
);
/* pszManifestFilePath has dll extension */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
dllext
,
NULL
);
todo_wine
{
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_FILE_NOT_FOUND
),
"Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x
\n
"
,
hr
);
}
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_FILE_NOT_FOUND
),
"Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x
\n
"
,
hr
);
/* pszManifestFilePath has exe extension */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
exeext
,
NULL
);
todo_wine
{
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_FILE_NOT_FOUND
),
"Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x
\n
"
,
hr
);
}
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_FILE_NOT_FOUND
),
"Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x
\n
"
,
hr
);
/* empty file */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
testdll
,
NULL
);
todo_wine
{
ok
(
hr
==
COR_E_ASSEMBLYEXPECTED
,
"Expected COR_E_ASSEMBLYEXPECTED, got %08x
\n
"
,
hr
);
}
ok
(
hr
==
COR_E_ASSEMBLYEXPECTED
,
"Expected COR_E_ASSEMBLYEXPECTED, got %08x
\n
"
,
hr
);
/* wine assembly */
hr
=
IAssemblyCache_InstallAssembly
(
cache
,
0
,
winedll
,
NULL
);
todo_wine
{
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
}
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
attr
=
GetFileAttributes
(
"C:
\\
windows
\\
assembly
\\
GAC_MSIL
\\
wine
\\
"
"1.0.0.0__2d03617b1c31e2f5/wine.dll"
);
ok
(
attr
!=
INVALID_FILE_ATTRIBUTES
,
"Expected assembly to exist
\n
"
);
/* uninstall the assembly from the GAC */
hr
=
IAssemblyCache_UninstallAssembly
(
cache
,
0
,
wine
,
NULL
,
&
disp
);
...
...
@@ -945,6 +926,12 @@ static void test_InstallAssembly(void)
"Expected IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED, got %d
\n
"
,
disp
);
}
/* FIXME: remove once UninstallAssembly is implemented */
DeleteFileA
(
"C:
\\
windows
\\
assembly
\\
GAC_MSIL
\\
wine
\\
"
"1.0.0.0__2d03617b1c31e2f5
\\
wine.dll"
);
RemoveDirectoryA
(
"C:
\\
windows
\\
assembly
\\
GAC_MSIL
\\
wine
\\
1.0.0.0__2d03617b1c31e2f5"
);
RemoveDirectoryA
(
"C:
\\
windows
\\
assembly
\\
GAC_MSIL
\\
wine"
);
DeleteFileA
(
"test.dll"
);
DeleteFileA
(
"wine.dll"
);
IAssemblyCache_Release
(
cache
);
...
...
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