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
bcbd13b7
Commit
bcbd13b7
authored
Sep 09, 2013
by
Nikolay Sivov
Committed by
Alexandre Julliard
Sep 09, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Added compatible sections for clrClass data.
parent
88d5cab5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
266 additions
and
129 deletions
+266
-129
actctx.c
dlls/kernel32/tests/actctx.c
+5
-3
actctx.c
dlls/ntdll/actctx.c
+261
-126
No files found.
dlls/kernel32/tests/actctx.c
View file @
bcbd13b7
...
@@ -1226,12 +1226,14 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU
...
@@ -1226,12 +1226,14 @@ static void test_find_com_redirection(HANDLE handle, const GUID *clsid, const GU
ok_
(
__FILE__
,
line
)(
IsEqualGUID
(
&
comclass
->
clsid2
,
clsid
),
"got wrong clsid2 %s
\n
"
,
debugstr_guid
(
&
comclass
->
clsid2
));
ok_
(
__FILE__
,
line
)(
IsEqualGUID
(
&
comclass
->
clsid2
,
clsid
),
"got wrong clsid2 %s
\n
"
,
debugstr_guid
(
&
comclass
->
clsid2
));
ok_
(
__FILE__
,
line
)(
IsEqualGUID
(
&
comclass
->
tlid
,
tlid
),
"got wrong tlid %s
\n
"
,
debugstr_guid
(
&
comclass
->
tlid
));
ok_
(
__FILE__
,
line
)(
IsEqualGUID
(
&
comclass
->
tlid
,
tlid
),
"got wrong tlid %s
\n
"
,
debugstr_guid
(
&
comclass
->
tlid
));
ok_
(
__FILE__
,
line
)(
comclass
->
name_len
>
0
,
"got modulename len %d
\n
"
,
comclass
->
name_len
);
ok_
(
__FILE__
,
line
)(
comclass
->
name_len
>
0
,
"got modulename len %d
\n
"
,
comclass
->
name_len
);
ok_
(
__FILE__
,
line
)(
comclass
->
progid_offset
==
comclass
->
size
+
comclass
->
clrdata_len
,
"got progid offset %d
\n
"
,
comclass
->
progid_offset
);
len
=
comclass
->
size
+
comclass
->
clrdata_len
;
ok_
(
__FILE__
,
line
)(
comclass
->
progid_offset
==
len
,
"got progid offset %d, expected %d
\n
"
,
comclass
->
progid_offset
,
len
);
ptr
=
(
WCHAR
*
)((
BYTE
*
)
comclass
+
comclass
->
progid_offset
);
ptr
=
(
WCHAR
*
)((
BYTE
*
)
comclass
+
comclass
->
progid_offset
);
ok_
(
__FILE__
,
line
)(
!
lstrcmpW
(
ptr
,
progid
),
"got wrong progid %s, expected %s
\n
"
,
wine_dbgstr_w
(
ptr
),
wine_dbgstr_w
(
progid
));
ok_
(
__FILE__
,
line
)(
!
lstrcmpW
(
ptr
,
progid
),
"got wrong progid %s, expected %s
\n
"
,
wine_dbgstr_w
(
ptr
),
wine_dbgstr_w
(
progid
));
ok_
(
__FILE__
,
line
)(
lstrlenW
(
p
tr
)
*
sizeof
(
WCHAR
)
==
comclass
->
progid_len
,
ok_
(
__FILE__
,
line
)(
lstrlenW
(
p
rogid
)
*
sizeof
(
WCHAR
)
==
comclass
->
progid_len
,
"got progid name length %d
, expected %d
\n
"
,
comclass
->
progid_len
,
lstrlenW
(
ptr
)
);
"got progid name length %d
\n
"
,
comclass
->
progid_len
);
/* data length is simply header length + string data length including nulls */
/* data length is simply header length + string data length including nulls */
len
=
comclass
->
size
+
comclass
->
progid_len
+
sizeof
(
WCHAR
)
+
comclass
->
clrdata_len
;
len
=
comclass
->
size
+
comclass
->
progid_len
+
sizeof
(
WCHAR
)
+
comclass
->
clrdata_len
;
...
...
dlls/ntdll/actctx.c
View file @
bcbd13b7
...
@@ -273,6 +273,19 @@ struct clrsurrogate_data
...
@@ -273,6 +273,19 @@ struct clrsurrogate_data
ULONG
name_len
;
ULONG
name_len
;
};
};
struct
clrclass_data
{
ULONG
size
;
DWORD
res
[
2
];
ULONG
module_len
;
ULONG
module_offset
;
ULONG
name_len
;
ULONG
name_offset
;
ULONG
version_len
;
ULONG
version_offset
;
DWORD
res2
[
2
];
};
/*
/*
Sections structure.
Sections structure.
...
@@ -332,13 +345,19 @@ struct clrsurrogate_data
...
@@ -332,13 +345,19 @@ struct clrsurrogate_data
<section header>
<section header>
<module names[]>
<module names[]>
<index[]>
<index[]>
<data[]> --- <data>
<data[]> --- <data> --- <data>
<progid>
<progid> <clrdata>
<name>
<version>
<progid>
This section uses two index records per comclass, one entry contains original guid
This section uses two index records per comclass, one entry contains original guid
as specified by context, another one has a generated guid. Index and strings handling
as specified by context, another one has a generated guid. Index and strings handling
is similar to typelib sections.
is similar to typelib sections.
For CLR classes additional data is stored after main COM class data, it contains
class name and runtime version string, see 'struct clrclass_data'.
Module name offsets are relative to section, progid offset is relative to data
Module name offsets are relative to section, progid offset is relative to data
structure itself.
structure itself.
...
@@ -394,8 +413,8 @@ struct entity
...
@@ -394,8 +413,8 @@ struct entity
WCHAR
*
clsid
;
WCHAR
*
clsid
;
WCHAR
*
tlbid
;
WCHAR
*
tlbid
;
WCHAR
*
progid
;
WCHAR
*
progid
;
WCHAR
*
name
;
/* not NULL for clrClass
*/
WCHAR
*
name
;
/* clrClass: class name
*/
WCHAR
*
version
;
WCHAR
*
version
;
/* clrClass: CLR runtime version */
DWORD
model
;
DWORD
model
;
DWORD
miscstatus
;
DWORD
miscstatus
;
DWORD
miscstatuscontent
;
DWORD
miscstatuscontent
;
...
@@ -554,6 +573,8 @@ static const WCHAR baseInterfaceW[] = {'b','a','s','e','I','n','t','e','r','f','
...
@@ -554,6 +573,8 @@ static const WCHAR baseInterfaceW[] = {'b','a','s','e','I','n','t','e','r','f','
static
const
WCHAR
nummethodsW
[]
=
{
'n'
,
'u'
,
'm'
,
'M'
,
'e'
,
't'
,
'h'
,
'o'
,
'd'
,
's'
,
0
};
static
const
WCHAR
nummethodsW
[]
=
{
'n'
,
'u'
,
'm'
,
'M'
,
'e'
,
't'
,
'h'
,
'o'
,
'd'
,
's'
,
0
};
static
const
WCHAR
proxyStubClsid32W
[]
=
{
'p'
,
'r'
,
'o'
,
'x'
,
'y'
,
'S'
,
't'
,
'u'
,
'b'
,
'C'
,
'l'
,
's'
,
'i'
,
'd'
,
'3'
,
'2'
,
0
};
static
const
WCHAR
proxyStubClsid32W
[]
=
{
'p'
,
'r'
,
'o'
,
'x'
,
'y'
,
'S'
,
't'
,
'u'
,
'b'
,
'C'
,
'l'
,
's'
,
'i'
,
'd'
,
'3'
,
'2'
,
0
};
static
const
WCHAR
runtimeVersionW
[]
=
{
'r'
,
'u'
,
'n'
,
't'
,
'i'
,
'm'
,
'e'
,
'V'
,
'e'
,
'r'
,
's'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
runtimeVersionW
[]
=
{
'r'
,
'u'
,
'n'
,
't'
,
'i'
,
'm'
,
'e'
,
'V'
,
'e'
,
'r'
,
's'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
mscoreeW
[]
=
{
'M'
,
'S'
,
'C'
,
'O'
,
'R'
,
'E'
,
'E'
,
'.'
,
'D'
,
'L'
,
'L'
,
0
};
static
const
WCHAR
mscoree2W
[]
=
{
'm'
,
's'
,
'c'
,
'o'
,
'r'
,
'e'
,
'e'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
activatewhenvisibleW
[]
=
{
'a'
,
'c'
,
't'
,
'i'
,
'v'
,
'a'
,
't'
,
'e'
,
'w'
,
'h'
,
'e'
,
'n'
,
'v'
,
'i'
,
's'
,
'i'
,
'b'
,
'l'
,
'e'
,
0
};
static
const
WCHAR
activatewhenvisibleW
[]
=
{
'a'
,
'c'
,
't'
,
'i'
,
'v'
,
'a'
,
't'
,
'e'
,
'w'
,
'h'
,
'e'
,
'n'
,
'v'
,
'i'
,
's'
,
'i'
,
'b'
,
'l'
,
'e'
,
0
};
static
const
WCHAR
actslikebuttonW
[]
=
{
'a'
,
'c'
,
't'
,
's'
,
'l'
,
'i'
,
'k'
,
'e'
,
'b'
,
'u'
,
't'
,
't'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
actslikebuttonW
[]
=
{
'a'
,
'c'
,
't'
,
's'
,
'l'
,
'i'
,
'k'
,
'e'
,
'b'
,
'u'
,
't'
,
't'
,
'o'
,
'n'
,
0
};
...
@@ -1845,7 +1866,7 @@ static BOOL parse_com_interface_external_proxy_stub_elem(xmlbuf_t* xmlbuf,
...
@@ -1845,7 +1866,7 @@ static BOOL parse_com_interface_external_proxy_stub_elem(xmlbuf_t* xmlbuf,
return
parse_expect_end_elem
(
xmlbuf
,
comInterfaceExternalProxyStubW
,
asmv1W
);
return
parse_expect_end_elem
(
xmlbuf
,
comInterfaceExternalProxyStubW
,
asmv1W
);
}
}
static
BOOL
parse_clr_class_elem
(
xmlbuf_t
*
xmlbuf
,
struct
assembly
*
assembly
)
static
BOOL
parse_clr_class_elem
(
xmlbuf_t
*
xmlbuf
,
struct
assembly
*
assembly
,
struct
actctx_loader
*
acl
)
{
{
xmlstr_t
attr_name
,
attr_value
,
elem
;
xmlstr_t
attr_name
,
attr_value
,
elem
;
BOOL
end
=
FALSE
,
error
,
ret
=
TRUE
;
BOOL
end
=
FALSE
,
error
,
ret
=
TRUE
;
...
@@ -1886,7 +1907,9 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
...
@@ -1886,7 +1907,9 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
}
}
}
}
if
(
error
||
end
)
return
end
;
if
(
error
)
return
FALSE
;
acl
->
actctx
->
sections
|=
SERVERREDIRECT_SECTION
;
if
(
end
)
return
TRUE
;
while
(
ret
&&
(
ret
=
next_xml_elem
(
xmlbuf
,
&
elem
)))
while
(
ret
&&
(
ret
=
next_xml_elem
(
xmlbuf
,
&
elem
)))
{
{
...
@@ -2196,7 +2219,7 @@ static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
...
@@ -2196,7 +2219,7 @@ static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
}
}
else
if
(
xml_elem_cmp
(
&
elem
,
clrClassW
,
asmv1W
))
else
if
(
xml_elem_cmp
(
&
elem
,
clrClassW
,
asmv1W
))
{
{
ret
=
parse_clr_class_elem
(
xmlbuf
,
assembly
);
ret
=
parse_clr_class_elem
(
xmlbuf
,
assembly
,
acl
);
}
}
else
if
(
xml_elem_cmp
(
&
elem
,
clrSurrogateW
,
asmv1W
))
else
if
(
xml_elem_cmp
(
&
elem
,
clrSurrogateW
,
asmv1W
))
{
{
...
@@ -3436,42 +3459,247 @@ static void generate_uuid(ULONG *seed, GUID *guid)
...
@@ -3436,42 +3459,247 @@ static void generate_uuid(ULONG *seed, GUID *guid)
guid
->
Data4
[
0
]
|=
0x80
;
guid
->
Data4
[
0
]
|=
0x80
;
}
}
static
void
get_comserver_datalen
(
const
struct
entity_array
*
entities
,
const
struct
dll_redirect
*
dll
,
unsigned
int
*
count
,
unsigned
int
*
len
,
unsigned
int
*
module_len
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
entities
->
num
;
i
++
)
{
struct
entity
*
entity
=
&
entities
->
base
[
i
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
)
{
/* each entry needs two index entries, extra one goes for alias GUID */
*
len
+=
2
*
sizeof
(
struct
guid_index
);
/* To save some memory we don't allocated two data structures,
instead alias index and normal index point to the same data structure. */
*
len
+=
sizeof
(
struct
comclassredirect_data
);
/* for clrClass store some more */
if
(
entity
->
u
.
comclass
.
name
)
{
unsigned
int
str_len
;
/* all string data is stored together in aligned block */
str_len
=
strlenW
(
entity
->
u
.
comclass
.
name
)
+
1
;
if
(
*
entity
->
u
.
comclass
.
progid
)
str_len
+=
strlenW
(
entity
->
u
.
comclass
.
progid
)
+
1
;
if
(
entity
->
u
.
comclass
.
version
)
str_len
+=
strlenW
(
entity
->
u
.
comclass
.
version
)
+
1
;
*
len
+=
sizeof
(
struct
clrclass_data
);
*
len
+=
aligned_string_len
(
str_len
*
sizeof
(
WCHAR
));
/* module name is forced to mscoree.dll, and stored two times with different case */
*
module_len
+=
sizeof
(
mscoreeW
)
+
sizeof
(
mscoree2W
);
}
else
{
/* progid string is stored separately */
if
(
*
entity
->
u
.
comclass
.
progid
)
*
len
+=
aligned_string_len
((
strlenW
(
entity
->
u
.
comclass
.
progid
)
+
1
)
*
sizeof
(
WCHAR
));
*
module_len
+=
(
strlenW
(
dll
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
}
*
count
+=
1
;
}
}
}
static
void
add_comserver_record
(
const
struct
guidsection_header
*
section
,
const
struct
entity_array
*
entities
,
const
struct
dll_redirect
*
dll
,
struct
guid_index
**
index
,
ULONG
*
data_offset
,
ULONG
*
module_offset
,
ULONG
*
seed
,
ULONG
rosterindex
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
entities
->
num
;
i
++
)
{
struct
entity
*
entity
=
&
entities
->
base
[
i
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
)
{
ULONG
module_len
,
progid_len
,
str_len
=
0
;
struct
comclassredirect_data
*
data
;
struct
guid_index
*
alias_index
;
struct
clrclass_data
*
clrdata
;
UNICODE_STRING
str
;
WCHAR
*
ptrW
;
if
(
*
entity
->
u
.
comclass
.
progid
)
progid_len
=
strlenW
(
entity
->
u
.
comclass
.
progid
)
*
sizeof
(
WCHAR
);
else
progid_len
=
0
;
module_len
=
dll
?
strlenW
(
dll
->
name
)
*
sizeof
(
WCHAR
)
:
strlenW
(
mscoreeW
)
*
sizeof
(
WCHAR
);
/* setup new index entry */
RtlInitUnicodeString
(
&
str
,
entity
->
u
.
comclass
.
clsid
);
RtlGUIDFromString
(
&
str
,
&
(
*
index
)
->
guid
);
(
*
index
)
->
data_offset
=
*
data_offset
;
(
*
index
)
->
data_len
=
sizeof
(
*
data
);
/* additional length added later */
(
*
index
)
->
rosterindex
=
rosterindex
;
/* Setup new index entry for alias guid. Alias index records are placed after
normal records, so normal guids are hit first on search. Note that class count
is doubled. */
alias_index
=
(
*
index
)
+
section
->
count
/
2
;
generate_uuid
(
seed
,
&
alias_index
->
guid
);
alias_index
->
data_offset
=
(
*
index
)
->
data_offset
;
alias_index
->
data_len
=
0
;
alias_index
->
rosterindex
=
(
*
index
)
->
rosterindex
;
/* setup data */
data
=
(
struct
comclassredirect_data
*
)((
BYTE
*
)
section
+
(
*
index
)
->
data_offset
);
data
->
size
=
sizeof
(
*
data
);
data
->
res
=
0
;
data
->
res1
[
0
]
=
0
;
data
->
res1
[
1
]
=
0
;
data
->
model
=
entity
->
u
.
comclass
.
model
;
data
->
clsid
=
(
*
index
)
->
guid
;
data
->
alias
=
alias_index
->
guid
;
data
->
clsid2
=
data
->
clsid
;
if
(
entity
->
u
.
comclass
.
tlbid
)
{
RtlInitUnicodeString
(
&
str
,
entity
->
u
.
comclass
.
tlbid
);
RtlGUIDFromString
(
&
str
,
&
data
->
tlbid
);
}
else
memset
(
&
data
->
tlbid
,
0
,
sizeof
(
data
->
tlbid
));
data
->
name_len
=
module_len
;
data
->
name_offset
=
*
module_offset
;
data
->
progid_len
=
progid_len
;
data
->
progid_offset
=
data
->
progid_len
?
data
->
size
:
0
;
/* in case of clrClass additional offset is added later */
data
->
clrdata_len
=
0
;
/* will be set later */
data
->
clrdata_offset
=
entity
->
u
.
comclass
.
name
?
sizeof
(
*
data
)
:
0
;
data
->
miscstatus
=
entity
->
u
.
comclass
.
miscstatus
;
data
->
miscstatuscontent
=
entity
->
u
.
comclass
.
miscstatuscontent
;
data
->
miscstatusthumbnail
=
entity
->
u
.
comclass
.
miscstatusthumbnail
;
data
->
miscstatusicon
=
entity
->
u
.
comclass
.
miscstatusicon
;
data
->
miscstatusdocprint
=
entity
->
u
.
comclass
.
miscstatusdocprint
;
/* mask describes which misc* data is available */
data
->
miscmask
=
0
;
if
(
data
->
miscstatus
)
data
->
miscmask
|=
MiscStatus
;
if
(
data
->
miscstatuscontent
)
data
->
miscmask
|=
MiscStatusContent
;
if
(
data
->
miscstatusthumbnail
)
data
->
miscmask
|=
MiscStatusThumbnail
;
if
(
data
->
miscstatusicon
)
data
->
miscmask
|=
MiscStatusIcon
;
if
(
data
->
miscstatusdocprint
)
data
->
miscmask
|=
MiscStatusDocPrint
;
if
(
data
->
clrdata_offset
)
{
clrdata
=
(
struct
clrclass_data
*
)((
BYTE
*
)
data
+
data
->
clrdata_offset
);
clrdata
->
size
=
sizeof
(
*
clrdata
);
clrdata
->
res
[
0
]
=
0
;
clrdata
->
res
[
1
]
=
2
;
/* FIXME: unknown field */
clrdata
->
module_len
=
strlenW
(
mscoreeW
)
*
sizeof
(
WCHAR
);
clrdata
->
module_offset
=
*
module_offset
+
data
->
name_len
+
sizeof
(
WCHAR
);
clrdata
->
name_len
=
strlenW
(
entity
->
u
.
comclass
.
name
)
*
sizeof
(
WCHAR
);
clrdata
->
name_offset
=
clrdata
->
size
;
clrdata
->
version_len
=
entity
->
u
.
comclass
.
version
?
strlenW
(
entity
->
u
.
comclass
.
version
)
*
sizeof
(
WCHAR
)
:
0
;
clrdata
->
version_offset
=
clrdata
->
version_len
?
clrdata
->
name_offset
+
clrdata
->
name_len
+
sizeof
(
WCHAR
)
:
0
;
clrdata
->
res2
[
0
]
=
0
;
clrdata
->
res2
[
1
]
=
0
;
data
->
clrdata_len
=
clrdata
->
size
+
clrdata
->
name_len
+
sizeof
(
WCHAR
);
/* module name */
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
section
+
clrdata
->
module_offset
);
memcpy
(
ptrW
,
mscoree2W
,
clrdata
->
module_len
);
ptrW
[
clrdata
->
module_len
/
sizeof
(
WCHAR
)]
=
0
;
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
section
+
data
->
name_offset
);
memcpy
(
ptrW
,
mscoreeW
,
data
->
name_len
);
ptrW
[
data
->
name_len
/
sizeof
(
WCHAR
)]
=
0
;
/* class name */
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
clrdata
+
clrdata
->
name_offset
);
memcpy
(
ptrW
,
entity
->
u
.
comclass
.
name
,
clrdata
->
name_len
);
ptrW
[
clrdata
->
name_len
/
sizeof
(
WCHAR
)]
=
0
;
/* runtime version, optional */
if
(
clrdata
->
version_len
)
{
data
->
clrdata_len
+=
clrdata
->
version_len
+
sizeof
(
WCHAR
);
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
clrdata
+
clrdata
->
version_offset
);
memcpy
(
ptrW
,
entity
->
u
.
comclass
.
version
,
clrdata
->
version_len
);
ptrW
[
clrdata
->
version_len
/
sizeof
(
WCHAR
)]
=
0
;
}
if
(
data
->
progid_len
)
data
->
progid_offset
+=
data
->
clrdata_len
;
(
*
index
)
->
data_len
+=
sizeof
(
*
clrdata
);
}
else
{
clrdata
=
NULL
;
/* module name */
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
section
+
data
->
name_offset
);
memcpy
(
ptrW
,
dll
->
name
,
data
->
name_len
);
ptrW
[
data
->
name_len
/
sizeof
(
WCHAR
)]
=
0
;
}
/* progid string */
if
(
data
->
progid_len
)
{
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
data
+
data
->
progid_offset
);
memcpy
(
ptrW
,
entity
->
u
.
comclass
.
progid
,
data
->
progid_len
);
ptrW
[
data
->
progid_len
/
sizeof
(
WCHAR
)]
=
0
;
}
/* string block length */
str_len
=
0
;
if
(
clrdata
)
{
str_len
+=
clrdata
->
name_len
+
sizeof
(
WCHAR
);
if
(
clrdata
->
version_len
)
str_len
+=
clrdata
->
version_len
+
sizeof
(
WCHAR
);
}
if
(
progid_len
)
str_len
+=
progid_len
+
sizeof
(
WCHAR
);
(
*
index
)
->
data_len
+=
aligned_string_len
(
str_len
);
alias_index
->
data_len
=
(
*
index
)
->
data_len
;
/* move to next data record */
(
*
data_offset
)
+=
sizeof
(
*
data
)
+
aligned_string_len
(
str_len
);
(
*
module_offset
)
+=
module_len
+
sizeof
(
WCHAR
);
if
(
clrdata
)
{
(
*
data_offset
)
+=
sizeof
(
*
clrdata
);
(
*
module_offset
)
+=
clrdata
->
module_len
+
sizeof
(
WCHAR
);
}
(
*
index
)
+=
1
;
}
}
}
static
NTSTATUS
build_comserver_section
(
ACTIVATION_CONTEXT
*
actctx
,
struct
guidsection_header
**
section
)
static
NTSTATUS
build_comserver_section
(
ACTIVATION_CONTEXT
*
actctx
,
struct
guidsection_header
**
section
)
{
{
unsigned
int
i
,
j
,
k
,
total_len
=
0
,
class_count
=
0
,
names_len
=
0
;
unsigned
int
i
,
j
,
total_len
=
0
,
class_count
=
0
,
names_len
=
0
;
struct
guid_index
*
index
,
*
alias_index
;
struct
comclassredirect_data
*
data
;
struct
guidsection_header
*
header
;
struct
guidsection_header
*
header
;
ULONG
module_offset
,
data_offset
;
ULONG
module_offset
,
data_offset
;
struct
guid_index
*
index
;
ULONG
seed
;
ULONG
seed
;
/* compute section length */
/* compute section length */
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
{
{
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
get_comserver_datalen
(
&
assembly
->
entities
,
NULL
,
&
class_count
,
&
total_len
,
&
names_len
);
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
{
{
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
for
(
k
=
0
;
k
<
dll
->
entities
.
num
;
k
++
)
get_comserver_datalen
(
&
dll
->
entities
,
dll
,
&
class_count
,
&
total_len
,
&
names_len
);
{
struct
entity
*
entity
=
&
dll
->
entities
.
base
[
k
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
)
{
/* each entry needs two index entries, extra one goes for alias GUID */
total_len
+=
2
*
sizeof
(
*
index
);
/* to save some memory we don't allocated two data structures,
instead alias index and normal index point to the same data structure */
total_len
+=
sizeof
(
*
data
);
/* help string is stored separately */
if
(
*
entity
->
u
.
comclass
.
progid
)
total_len
+=
aligned_string_len
((
strlenW
(
entity
->
u
.
comclass
.
progid
)
+
1
)
*
sizeof
(
WCHAR
));
/* module names are packed one after another */
names_len
+=
(
strlenW
(
dll
->
name
)
+
1
)
*
sizeof
(
WCHAR
);
class_count
++
;
}
}
}
}
}
}
...
@@ -3494,104 +3722,11 @@ static NTSTATUS build_comserver_section(ACTIVATION_CONTEXT* actctx, struct guids
...
@@ -3494,104 +3722,11 @@ static NTSTATUS build_comserver_section(ACTIVATION_CONTEXT* actctx, struct guids
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
for
(
i
=
0
;
i
<
actctx
->
num_assemblies
;
i
++
)
{
{
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
struct
assembly
*
assembly
=
&
actctx
->
assemblies
[
i
];
add_comserver_record
(
header
,
&
assembly
->
entities
,
NULL
,
&
index
,
&
data_offset
,
&
module_offset
,
&
seed
,
i
+
1
);
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
for
(
j
=
0
;
j
<
assembly
->
num_dlls
;
j
++
)
{
{
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
struct
dll_redirect
*
dll
=
&
assembly
->
dlls
[
j
];
for
(
k
=
0
;
k
<
dll
->
entities
.
num
;
k
++
)
add_comserver_record
(
header
,
&
dll
->
entities
,
dll
,
&
index
,
&
data_offset
,
&
module_offset
,
&
seed
,
i
+
1
);
{
struct
entity
*
entity
=
&
dll
->
entities
.
base
[
k
];
if
(
entity
->
kind
==
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
)
{
ULONG
module_len
,
progid_len
;
UNICODE_STRING
str
;
WCHAR
*
ptrW
;
if
(
*
entity
->
u
.
comclass
.
progid
)
progid_len
=
strlenW
(
entity
->
u
.
comclass
.
progid
)
*
sizeof
(
WCHAR
);
else
progid_len
=
0
;
module_len
=
strlenW
(
dll
->
name
)
*
sizeof
(
WCHAR
);
/* setup new index entry */
RtlInitUnicodeString
(
&
str
,
entity
->
u
.
comclass
.
clsid
);
RtlGUIDFromString
(
&
str
,
&
index
->
guid
);
index
->
data_offset
=
data_offset
;
index
->
data_len
=
sizeof
(
*
data
)
+
aligned_string_len
(
progid_len
);
index
->
rosterindex
=
i
+
1
;
/* Setup new index entry for alias guid. Alias index records are placed after
normal records, so normal guids are hit first on search */
alias_index
=
index
+
class_count
;
generate_uuid
(
&
seed
,
&
alias_index
->
guid
);
alias_index
->
data_offset
=
index
->
data_offset
;
alias_index
->
data_len
=
index
->
data_len
;
alias_index
->
rosterindex
=
index
->
rosterindex
;
/* setup data */
data
=
(
struct
comclassredirect_data
*
)((
BYTE
*
)
header
+
index
->
data_offset
);
data
->
size
=
sizeof
(
*
data
);
data
->
res
=
0
;
data
->
res1
[
0
]
=
0
;
data
->
res1
[
1
]
=
0
;
data
->
model
=
entity
->
u
.
comclass
.
model
;
data
->
clsid
=
index
->
guid
;
data
->
alias
=
alias_index
->
guid
;
data
->
clsid2
=
data
->
clsid
;
if
(
entity
->
u
.
comclass
.
tlbid
)
{
RtlInitUnicodeString
(
&
str
,
entity
->
u
.
comclass
.
tlbid
);
RtlGUIDFromString
(
&
str
,
&
data
->
tlbid
);
}
else
memset
(
&
data
->
tlbid
,
0
,
sizeof
(
data
->
tlbid
));
data
->
name_len
=
module_len
;
data
->
name_offset
=
module_offset
;
data
->
progid_len
=
progid_len
;
data
->
progid_offset
=
sizeof
(
*
data
);
data
->
clrdata_len
=
0
;
data
->
clrdata_offset
=
0
;
data
->
miscstatus
=
entity
->
u
.
comclass
.
miscstatus
;
data
->
miscstatuscontent
=
entity
->
u
.
comclass
.
miscstatuscontent
;
data
->
miscstatusthumbnail
=
entity
->
u
.
comclass
.
miscstatusthumbnail
;
data
->
miscstatusicon
=
entity
->
u
.
comclass
.
miscstatusicon
;
data
->
miscstatusdocprint
=
entity
->
u
.
comclass
.
miscstatusdocprint
;
/* mask describes which misc* data is available */
data
->
miscmask
=
0
;
if
(
data
->
miscstatus
)
data
->
miscmask
|=
MiscStatus
;
if
(
data
->
miscstatuscontent
)
data
->
miscmask
|=
MiscStatusContent
;
if
(
data
->
miscstatusthumbnail
)
data
->
miscmask
|=
MiscStatusThumbnail
;
if
(
data
->
miscstatusicon
)
data
->
miscmask
|=
MiscStatusIcon
;
if
(
data
->
miscstatusdocprint
)
data
->
miscmask
|=
MiscStatusDocPrint
;
/* module name */
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
header
+
data
->
name_offset
);
memcpy
(
ptrW
,
dll
->
name
,
data
->
name_len
);
ptrW
[
data
->
name_len
/
sizeof
(
WCHAR
)]
=
0
;
/* progid string */
if
(
data
->
progid_len
)
{
ptrW
=
(
WCHAR
*
)((
BYTE
*
)
data
+
data
->
progid_offset
);
memcpy
(
ptrW
,
entity
->
u
.
comclass
.
progid
,
data
->
progid_len
);
ptrW
[
data
->
progid_len
/
sizeof
(
WCHAR
)]
=
0
;
}
data_offset
+=
sizeof
(
*
data
);
if
(
progid_len
)
data_offset
+=
aligned_string_len
(
progid_len
+
sizeof
(
WCHAR
));
module_offset
+=
module_len
+
sizeof
(
WCHAR
);
index
++
;
}
}
}
}
}
}
...
@@ -3631,7 +3766,7 @@ static NTSTATUS find_comserver_redirection(ACTIVATION_CONTEXT* actctx, const GUI
...
@@ -3631,7 +3766,7 @@ static NTSTATUS find_comserver_redirection(ACTIVATION_CONTEXT* actctx, const GUI
data
->
ulDataFormatVersion
=
1
;
data
->
ulDataFormatVersion
=
1
;
data
->
lpData
=
comclass
;
data
->
lpData
=
comclass
;
/* full length includes string length with nulls */
/* full length includes string length with nulls */
data
->
ulLength
=
comclass
->
size
+
comclass
->
progid_len
+
sizeof
(
WCHAR
);
data
->
ulLength
=
comclass
->
size
+
comclass
->
progid_len
+
sizeof
(
WCHAR
)
+
comclass
->
clrdata_len
;
data
->
lpSectionGlobalData
=
(
BYTE
*
)
actctx
->
comserver_section
+
actctx
->
comserver_section
->
names_offset
;
data
->
lpSectionGlobalData
=
(
BYTE
*
)
actctx
->
comserver_section
+
actctx
->
comserver_section
->
names_offset
;
data
->
ulSectionGlobalDataLength
=
actctx
->
comserver_section
->
names_len
;
data
->
ulSectionGlobalDataLength
=
actctx
->
comserver_section
->
names_len
;
data
->
lpSectionBase
=
actctx
->
comserver_section
;
data
->
lpSectionBase
=
actctx
->
comserver_section
;
...
...
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