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
36acd614
Commit
36acd614
authored
Aug 23, 2013
by
Nikolay Sivov
Committed by
Alexandre Julliard
Aug 23, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement compatible typelib section.
parent
1ca7eb64
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
296 additions
and
17 deletions
+296
-17
actctx.c
dlls/kernel32/tests/actctx.c
+0
-2
actctx.c
dlls/ntdll/actctx.c
+296
-15
No files found.
dlls/kernel32/tests/actctx.c
View file @
36acd614
...
...
@@ -1319,9 +1319,7 @@ static void test_typelib_section(void)
ret
=
pFindActCtxSectionGuid
(
0
,
NULL
,
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
,
&
IID_TlibTest
,
&
data
);
todo_wine
ok
(
ret
,
"got %d
\n
"
,
ret
);
if
(
!
ret
)
return
;
ret
=
pFindActCtxSectionGuid
(
0
,
NULL
,
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
,
...
...
dlls/ntdll/actctx.c
View file @
36acd614
...
...
@@ -51,7 +51,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(actctx);
ACTCTX_FLAG_HMODULE_VALID )
#define ACTCTX_MAGIC 0xC07E3E11
#define SECTION_MAGIC 0x64487353
#define STRSECTION_MAGIC 0x64487353
/* dHsS */
#define GUIDSECTION_MAGIC 0x64487347
/* dHsG */
/* we don't want to include winuser.h */
#define RT_MANIFEST ((ULONG_PTR)24)
...
...
@@ -122,6 +123,26 @@ struct string_index
ULONG
rosterindex
;
};
struct
guidsection_header
{
DWORD
magic
;
ULONG
size
;
DWORD
unk
[
3
];
ULONG
count
;
ULONG
index_offset
;
DWORD
unk2
;
ULONG
names_offset
;
ULONG
names_len
;
};
struct
guid_index
{
GUID
guid
;
ULONG
data_offset
;
ULONG
data_len
;
ULONG
rosterindex
;
};
struct
wndclass_redirect_data
{
ULONG
size
;
...
...
@@ -139,6 +160,20 @@ struct dllredirect_data
DWORD
res
[
3
];
};
struct
tlibredirect_data
{
ULONG
size
;
DWORD
res
;
ULONG
name_len
;
ULONG
name_offset
;
LANGID
langid
;
WORD
flags
;
ULONG
help_len
;
ULONG
help_offset
;
WORD
major_version
;
WORD
minor_version
;
};
/*
Sections structure.
...
...
@@ -177,6 +212,21 @@ struct dllredirect_data
<data>
This section doesn't seem to carry any payload data except dll names.
- typelib section format:
<section header>
<module names[]>
<index[]>
<data[]> --- <data>
<helpstring>
Header is fixed length, index is an array of fixed length 'struct guid_index'.
All strings are WCHAR, null terminated, 4-bytes aligned. Module names part is
4-bytes aligned as a whole.
Module name offsets are relative to section, helpstring offset is relative to data
structure itself.
*/
struct
entity
...
...
@@ -254,8 +304,9 @@ struct assembly
enum
context_sections
{
WINDOWCLASS_SECTION
=
1
,
DLLREDIRECT_SECTION
=
2
WINDOWCLASS_SECTION
=
1
,
DLLREDIRECT_SECTION
=
2
,
TLIBREDIRECT_SECTION
=
4
};
typedef
struct
_ACTIVATION_CONTEXT
...
...
@@ -269,8 +320,9 @@ typedef struct _ACTIVATION_CONTEXT
unsigned
int
allocated_assemblies
;
/* section data */
DWORD
sections
;
struct
strsection_header
*
wndclass_section
;
struct
strsection_header
*
dllredirect_section
;
struct
strsection_header
*
wndclass_section
;
struct
strsection_header
*
dllredirect_section
;
struct
guidsection_header
*
tlib_section
;
}
ACTIVATION_CONTEXT
;
struct
actctx_loader
...
...
@@ -1156,7 +1208,7 @@ error:
return
FALSE
;
}
static
BOOL
parse_typelib_elem
(
xmlbuf_t
*
xmlbuf
,
struct
dll_redirect
*
dll
)
static
BOOL
parse_typelib_elem
(
xmlbuf_t
*
xmlbuf
,
struct
dll_redirect
*
dll
,
struct
actctx_loader
*
acl
)
{
xmlstr_t
attr_name
,
attr_value
;
BOOL
end
=
FALSE
,
error
;
...
...
@@ -1189,7 +1241,12 @@ static BOOL parse_typelib_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll)
}
}
if
(
error
||
end
)
return
end
;
if
(
error
)
return
FALSE
;
acl
->
actctx
->
sections
|=
TLIBREDIRECT_SECTION
;
if
(
end
)
return
TRUE
;
return
parse_expect_end_elem
(
xmlbuf
,
typelibW
,
asmv1W
);
}
...
...
@@ -1555,7 +1612,7 @@ static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly, struct
}
else
if
(
xmlstr_cmp
(
&
elem
,
typelibW
))
{
ret
=
parse_typelib_elem
(
xmlbuf
,
dll
);
ret
=
parse_typelib_elem
(
xmlbuf
,
dll
,
acl
);
}
else
if
(
xmlstr_cmp
(
&
elem
,
windowClassW
))
{
...
...
@@ -2355,7 +2412,7 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
if
(
!
header
)
return
STATUS_NO_MEMORY
;
memset
(
header
,
0
,
sizeof
(
*
header
));
header
->
magic
=
SECTION_MAGIC
;
header
->
magic
=
S
TRS
ECTION_MAGIC
;
header
->
size
=
sizeof
(
*
header
);
header
->
count
=
dll_count
;
header
->
index_offset
=
sizeof
(
*
header
);
...
...
@@ -2434,6 +2491,26 @@ static struct string_index *find_string_index(const struct strsection_header *se
return
index
;
}
static
struct
guid_index
*
find_guid_index
(
const
struct
guidsection_header
*
section
,
const
GUID
*
guid
)
{
struct
guid_index
*
iter
,
*
index
=
NULL
;
ULONG
i
;
iter
=
(
struct
guid_index
*
)((
BYTE
*
)
section
+
section
->
index_offset
);
for
(
i
=
0
;
i
<
section
->
count
;
i
++
)
{
if
(
!
memcmp
(
guid
,
&
iter
->
guid
,
sizeof
(
*
guid
)))
{
index
=
iter
;
break
;
}
iter
++
;
}
return
index
;
}
static
inline
struct
dllredirect_data
*
get_dllredirect_data
(
ACTIVATION_CONTEXT
*
ctxt
,
struct
string_index
*
index
)
{
return
(
struct
dllredirect_data
*
)((
BYTE
*
)
ctxt
->
dllredirect_section
+
index
->
data_offset
);
...
...
@@ -2536,7 +2613,7 @@ static NTSTATUS build_wndclass_section(ACTIVATION_CONTEXT* actctx, struct strsec
if
(
!
header
)
return
STATUS_NO_MEMORY
;
memset
(
header
,
0
,
sizeof
(
*
header
));
header
->
magic
=
SECTION_MAGIC
;
header
->
magic
=
S
TRS
ECTION_MAGIC
;
header
->
size
=
sizeof
(
*
header
);
header
->
count
=
class_count
;
header
->
index_offset
=
sizeof
(
*
header
);
...
...
@@ -2688,6 +2765,174 @@ static NTSTATUS find_window_class(ACTIVATION_CONTEXT* actctx, const UNICODE_STRI
return
STATUS_SUCCESS
;
}
static
NTSTATUS
build_tlib_section
(
ACTIVATION_CONTEXT
*
actctx
,
struct
guidsection_header
**
section
)
{
unsigned
int
i
,
j
,
k
,
total_len
=
0
,
tlib_count
=
0
,
names_len
=
0
;
struct
guidsection_header
*
header
;
ULONG
module_offset
,
data_offset
;
struct
tlibredirect_data
*
data
;
struct
guid_index
*
index
;
/* compute section length */
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
{
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
{
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
for
(
k
=
0
;
k
<
dll
->
entities
.
num
;
k
++
)
{
struct
entity
*
entity
=
&
dll
->
entities
.
base
[
k
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
)
{
/* each entry needs index, data and string data for module name and help string */
total_len
+=
sizeof
(
*
index
);
total_len
+=
sizeof
(
*
data
);
/* help string is stored separately */
if
(
*
entity
->
u
.
typelib
.
helpdir
)
total_len
+=
aligned_string_len
((
strlenW
(
entity
->
u
.
typelib
.
helpdir
)
+
1
)
*
sizeof
(
WCHAR
));
/* module names are packed one after another */
names_len
+=
(
strlenW
(
dll
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
tlib_count
++
;
}
}
}
}
total_len
+=
aligned_string_len
(
names_len
);
total_len
+=
sizeof
(
*
header
);
header
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
total_len
);
if
(
!
header
)
return
STATUS_NO_MEMORY
;
memset
(
header
,
0
,
sizeof
(
*
header
));
header
->
magic
=
GUIDSECTION_MAGIC
;
header
->
size
=
sizeof
(
*
header
);
header
->
count
=
tlib_count
;
header
->
index_offset
=
sizeof
(
*
header
)
+
aligned_string_len
(
names_len
);
index
=
(
struct
guid_index
*
)((
BYTE
*
)
header
+
header
->
index_offset
);
module_offset
=
sizeof
(
*
header
);
data_offset
=
header
->
index_offset
+
tlib_count
*
sizeof
(
*
index
);
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
{
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
{
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
for
(
k
=
0
;
k
<
dll
->
entities
.
num
;
k
++
)
{
struct
entity
*
entity
=
&
dll
->
entities
.
base
[
k
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
)
{
ULONG
module_len
,
help_len
;
UNICODE_STRING
str
;
WCHAR
*
ptrW
;
if
(
*
entity
->
u
.
typelib
.
helpdir
)
help_len
=
strlenW
(
entity
->
u
.
typelib
.
helpdir
)
*
sizeof
(
WCHAR
);
else
help_len
=
0
;
module_len
=
strlenW
(
dll
->
name
)
*
sizeof
(
WCHAR
);
/* setup new index entry */
RtlInitUnicodeString
(
&
str
,
entity
->
u
.
typelib
.
tlbid
);
RtlGUIDFromString
(
&
str
,
&
index
->
guid
);
index
->
data_offset
=
data_offset
;
index
->
data_len
=
sizeof
(
*
data
)
+
aligned_string_len
(
help_len
);
index
->
rosterindex
=
i
+
1
;
/* setup data */
data
=
(
struct
tlibredirect_data
*
)((
BYTE
*
)
header
+
index
->
data_offset
);
data
->
size
=
sizeof
(
*
data
);
data
->
res
=
0
;
data
->
name_len
=
module_len
;
data
->
name_offset
=
module_offset
;
/* FIXME: resourceid handling is really weird, and it doesn't seem to be useful */
data
->
langid
=
0
;
data
->
flags
=
entity
->
u
.
typelib
.
flags
;
data
->
help_len
=
help_len
;
data
->
help_offset
=
sizeof
(
*
data
);
data
->
major_version
=
entity
->
u
.
typelib
.
major
;
data
->
minor_version
=
entity
->
u
.
typelib
.
minor
;
/* module name */
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
header
+
data
->
name_offset
);
memcpy
(
ptrW
,
dll
->
name
,
data
->
name_len
);
ptrW
[
data
->
name_len
/
sizeof
(
WCHAR
)]
=
0
;
/* help string */
if
(
data
->
help_len
)
{
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
data
+
data
->
help_offset
);
memcpy
(
ptrW
,
entity
->
u
.
typelib
.
helpdir
,
data
->
help_len
);
ptrW
[
data
->
help_len
/
sizeof
(
WCHAR
)]
=
0
;
}
data_offset
+=
sizeof
(
*
data
);
if
(
help_len
)
data_offset
+=
aligned_string_len
(
help_len
+
sizeof
(
WCHAR
));
module_offset
+=
module_len
+
sizeof
(
WCHAR
);
index
++
;
}
}
}
}
*
section
=
header
;
return
STATUS_SUCCESS
;
}
static
inline
struct
tlibredirect_data
*
get_tlib_data
(
ACTIVATION_CONTEXT
*
actctx
,
struct
guid_index
*
index
)
{
return
(
struct
tlibredirect_data
*
)((
BYTE
*
)
actctx
->
tlib_section
+
index
->
data_offset
);
}
static
NTSTATUS
find_tlib_redirection
(
ACTIVATION_CONTEXT
*
actctx
,
const
GUID
*
guid
,
ACTCTX_SECTION_KEYED_DATA
*
data
)
{
struct
guid_index
*
index
=
NULL
;
struct
tlibredirect_data
*
tlib
;
if
(
!
(
actctx
->
sections
&
TLIBREDIRECT_SECTION
))
return
STATUS_SXS_KEY_NOT_FOUND
;
if
(
!
actctx
->
tlib_section
)
{
struct
guidsection_header
*
section
;
NTSTATUS
status
=
build_tlib_section
(
actctx
,
&
section
);
if
(
status
)
return
status
;
if
(
interlocked_cmpxchg_ptr
((
void
**
)
&
actctx
->
tlib_section
,
section
,
NULL
))
RtlFreeHeap
(
GetProcessHeap
(),
0
,
section
);
}
index
=
find_guid_index
(
actctx
->
tlib_section
,
guid
);
if
(
!
index
)
return
STATUS_SXS_KEY_NOT_FOUND
;
tlib
=
get_tlib_data
(
actctx
,
index
);
data
->
ulDataFormatVersion
=
1
;
data
->
lpData
=
tlib
;
/* full length includes string length with nulls */
data
->
ulLength
=
tlib
->
size
+
tlib
->
help_len
+
sizeof
(
WCHAR
);
data
->
lpSectionGlobalData
=
NULL
;
data
->
ulSectionGlobalDataLength
=
0
;
data
->
lpSectionBase
=
actctx
->
tlib_section
;
data
->
ulSectionTotalLength
=
RtlSizeHeap
(
GetProcessHeap
(),
0
,
actctx
->
tlib_section
);
data
->
hActCtx
=
NULL
;
if
(
data
->
cbSize
>=
FIELD_OFFSET
(
ACTCTX_SECTION_KEYED_DATA
,
ulAssemblyRosterIndex
)
+
sizeof
(
ULONG
))
data
->
ulAssemblyRosterIndex
=
index
->
rosterindex
;
return
STATUS_SUCCESS
;
}
static
NTSTATUS
find_string
(
ACTIVATION_CONTEXT
*
actctx
,
ULONG
section_kind
,
const
UNICODE_STRING
*
section_name
,
DWORD
flags
,
PACTCTX_SECTION_KEYED_DATA
data
)
...
...
@@ -2702,9 +2947,6 @@ static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind,
case
ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION
:
status
=
find_window_class
(
actctx
,
section_name
,
data
);
break
;
case
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
:
case
ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION
:
case
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
:
case
ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION
:
case
ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE
:
case
ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES
:
...
...
@@ -2725,6 +2967,35 @@ static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind,
return
STATUS_SUCCESS
;
}
static
NTSTATUS
find_guid
(
ACTIVATION_CONTEXT
*
actctx
,
ULONG
section_kind
,
const
GUID
*
guid
,
DWORD
flags
,
PACTCTX_SECTION_KEYED_DATA
data
)
{
NTSTATUS
status
;
switch
(
section_kind
)
{
case
ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
:
status
=
find_tlib_redirection
(
actctx
,
guid
,
data
);
break
;
case
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
:
case
ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION
:
FIXME
(
"Unsupported yet section_kind %x
\n
"
,
section_kind
);
return
STATUS_SXS_SECTION_NOT_FOUND
;
default:
WARN
(
"Unknown section_kind %x
\n
"
,
section_kind
);
return
STATUS_SXS_SECTION_NOT_FOUND
;
}
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
if
(
flags
&
FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
)
{
actctx_addref
(
actctx
);
data
->
hActCtx
=
actctx
;
}
return
STATUS_SUCCESS
;
}
/* initialize the activation context for the current process */
void
actctx_init
(
void
)
{
...
...
@@ -3244,8 +3515,9 @@ NTSTATUS WINAPI RtlFindActivationContextSectionGuid( ULONG flags, const GUID *ex
const
GUID
*
guid
,
void
*
ptr
)
{
ACTCTX_SECTION_KEYED_DATA
*
data
=
ptr
;
NTSTATUS
status
=
STATUS_SXS_KEY_NOT_FOUND
;
FIXME
(
"%08x %s %u %s %p: stub
\n
"
,
flags
,
debugstr_guid
(
extguid
),
section_kind
,
debugstr_guid
(
guid
),
data
);
TRACE
(
"%08x %s %u %s %p
\n
"
,
flags
,
debugstr_guid
(
extguid
),
section_kind
,
debugstr_guid
(
guid
),
data
);
if
(
extguid
)
{
...
...
@@ -3262,5 +3534,14 @@ NTSTATUS WINAPI RtlFindActivationContextSectionGuid( ULONG flags, const GUID *ex
if
(
!
data
||
data
->
cbSize
<
FIELD_OFFSET
(
ACTCTX_SECTION_KEYED_DATA
,
ulAssemblyRosterIndex
)
||
!
guid
)
return
STATUS_INVALID_PARAMETER
;
return
STATUS_NOT_IMPLEMENTED
;
if
(
NtCurrentTeb
()
->
ActivationContextStack
.
ActiveFrame
)
{
ACTIVATION_CONTEXT
*
actctx
=
check_actctx
(
NtCurrentTeb
()
->
ActivationContextStack
.
ActiveFrame
->
ActivationContext
);
if
(
actctx
)
status
=
find_guid
(
actctx
,
section_kind
,
guid
,
flags
,
data
);
}
if
(
status
!=
STATUS_SUCCESS
)
status
=
find_guid
(
process_actctx
,
section_kind
,
guid
,
flags
,
data
);
return
status
;
}
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