ntdll: Added compatible ProgID section.
This commit is contained in:
parent
b8a973dc52
commit
84d9b2502e
|
@ -1506,11 +1506,6 @@ static void test_find_progid_redirection(HANDLE handle, const GUID *clsid, const
|
||||||
ret = pFindActCtxSectionStringA(0, NULL,
|
ret = pFindActCtxSectionStringA(0, NULL,
|
||||||
ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION,
|
ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION,
|
||||||
progid, &data);
|
progid, &data);
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
skip("failed for progid=%s\n", progid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ok_(__FILE__, line)(ret, "FindActCtxSectionStringA failed: %u\n", GetLastError());
|
ok_(__FILE__, line)(ret, "FindActCtxSectionStringA failed: %u\n", GetLastError());
|
||||||
|
|
||||||
progiddata = (struct progidredirect_data*)data.lpData;
|
progiddata = (struct progidredirect_data*)data.lpData;
|
||||||
|
|
|
@ -288,6 +288,13 @@ struct clrclass_data
|
||||||
DWORD res2[2];
|
DWORD res2[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct progidredirect_data
|
||||||
|
{
|
||||||
|
ULONG size;
|
||||||
|
DWORD reserved;
|
||||||
|
ULONG clsid_offset;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Sections structure.
|
Sections structure.
|
||||||
|
@ -388,6 +395,18 @@ struct clrclass_data
|
||||||
|
|
||||||
There's nothing special about this section, same way to store strings is used,
|
There's nothing special about this section, same way to store strings is used,
|
||||||
no modules part as it belongs to assembly level, not a file.
|
no modules part as it belongs to assembly level, not a file.
|
||||||
|
|
||||||
|
- ProgID section format:
|
||||||
|
|
||||||
|
<section header>
|
||||||
|
<guids[]>
|
||||||
|
<index[]>
|
||||||
|
<data[]> --- <progid>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
This sections uses generated alias guids from COM server section. This way
|
||||||
|
ProgID -> CLSID mapping returns generated guid, not the real one. ProgID string
|
||||||
|
is stored too, aligned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct progids
|
struct progids
|
||||||
|
@ -489,7 +508,8 @@ enum context_sections
|
||||||
TLIBREDIRECT_SECTION = 4,
|
TLIBREDIRECT_SECTION = 4,
|
||||||
SERVERREDIRECT_SECTION = 8,
|
SERVERREDIRECT_SECTION = 8,
|
||||||
IFACEREDIRECT_SECTION = 16,
|
IFACEREDIRECT_SECTION = 16,
|
||||||
CLRSURROGATES_SECTION = 32
|
CLRSURROGATES_SECTION = 32,
|
||||||
|
PROGIDREDIRECT_SECTION = 64
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _ACTIVATION_CONTEXT
|
typedef struct _ACTIVATION_CONTEXT
|
||||||
|
@ -505,6 +525,7 @@ typedef struct _ACTIVATION_CONTEXT
|
||||||
DWORD sections;
|
DWORD sections;
|
||||||
struct strsection_header *wndclass_section;
|
struct strsection_header *wndclass_section;
|
||||||
struct strsection_header *dllredirect_section;
|
struct strsection_header *dllredirect_section;
|
||||||
|
struct strsection_header *progid_section;
|
||||||
struct guidsection_header *tlib_section;
|
struct guidsection_header *tlib_section;
|
||||||
struct guidsection_header *comserver_section;
|
struct guidsection_header *comserver_section;
|
||||||
struct guidsection_header *ifaceps_section;
|
struct guidsection_header *ifaceps_section;
|
||||||
|
@ -1064,6 +1085,7 @@ static void actctx_release( ACTIVATION_CONTEXT *actctx )
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, actctx->comserver_section );
|
RtlFreeHeap( GetProcessHeap(), 0, actctx->comserver_section );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, actctx->ifaceps_section );
|
RtlFreeHeap( GetProcessHeap(), 0, actctx->ifaceps_section );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, actctx->clrsurrogate_section );
|
RtlFreeHeap( GetProcessHeap(), 0, actctx->clrsurrogate_section );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, actctx->progid_section );
|
||||||
actctx->magic = 0;
|
actctx->magic = 0;
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, actctx );
|
RtlFreeHeap( GetProcessHeap(), 0, actctx );
|
||||||
}
|
}
|
||||||
|
@ -1497,6 +1519,8 @@ static BOOL parse_com_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll, str
|
||||||
if (error) return FALSE;
|
if (error) return FALSE;
|
||||||
|
|
||||||
acl->actctx->sections |= SERVERREDIRECT_SECTION;
|
acl->actctx->sections |= SERVERREDIRECT_SECTION;
|
||||||
|
if (entity->u.comclass.progid)
|
||||||
|
acl->actctx->sections |= PROGIDREDIRECT_SECTION;
|
||||||
|
|
||||||
if (end) return TRUE;
|
if (end) return TRUE;
|
||||||
|
|
||||||
|
@ -1517,6 +1541,10 @@ static BOOL parse_com_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll, str
|
||||||
ret = parse_unknown_elem(xmlbuf, &elem);
|
ret = parse_unknown_elem(xmlbuf, &elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity->u.comclass.progids.num)
|
||||||
|
acl->actctx->sections |= PROGIDREDIRECT_SECTION;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,6 +1939,8 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly, st
|
||||||
|
|
||||||
if (error) return FALSE;
|
if (error) return FALSE;
|
||||||
acl->actctx->sections |= SERVERREDIRECT_SECTION;
|
acl->actctx->sections |= SERVERREDIRECT_SECTION;
|
||||||
|
if (entity->u.comclass.progid)
|
||||||
|
acl->actctx->sections |= PROGIDREDIRECT_SECTION;
|
||||||
if (end) return TRUE;
|
if (end) return TRUE;
|
||||||
|
|
||||||
while (ret && (ret = next_xml_elem(xmlbuf, &elem)))
|
while (ret && (ret = next_xml_elem(xmlbuf, &elem)))
|
||||||
|
@ -1930,6 +1960,10 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly, st
|
||||||
ret = parse_unknown_elem(xmlbuf, &elem);
|
ret = parse_unknown_elem(xmlbuf, &elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity->u.comclass.progids.num)
|
||||||
|
acl->actctx->sections |= PROGIDREDIRECT_SECTION;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4135,6 +4169,216 @@ static NTSTATUS find_clr_surrogate(ACTIVATION_CONTEXT* actctx, const GUID *guid,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_progid_datalen(struct entity_array *entities, unsigned int *count, unsigned int *total_len)
|
||||||
|
{
|
||||||
|
unsigned int i, j, single_len;
|
||||||
|
|
||||||
|
single_len = sizeof(struct progidredirect_data) + sizeof(struct string_index) + sizeof(GUID);
|
||||||
|
for (i = 0; i < entities->num; i++)
|
||||||
|
{
|
||||||
|
struct entity *entity = &entities->base[i];
|
||||||
|
if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
|
||||||
|
{
|
||||||
|
if (entity->u.comclass.progid)
|
||||||
|
{
|
||||||
|
*total_len += single_len + aligned_string_len((strlenW(entity->u.comclass.progid)+1)*sizeof(WCHAR));
|
||||||
|
*count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < entity->u.comclass.progids.num; j++)
|
||||||
|
*total_len += aligned_string_len((strlenW(entity->u.comclass.progids.progids[j])+1)*sizeof(WCHAR));
|
||||||
|
|
||||||
|
*total_len += single_len*entity->u.comclass.progids.num;
|
||||||
|
*count += entity->u.comclass.progids.num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_progid_record(struct strsection_header *section, const WCHAR *progid, const GUID *alias,
|
||||||
|
struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
|
||||||
|
{
|
||||||
|
struct progidredirect_data *data;
|
||||||
|
UNICODE_STRING str;
|
||||||
|
GUID *guid_ptr;
|
||||||
|
WCHAR *ptrW;
|
||||||
|
|
||||||
|
/* setup new index entry */
|
||||||
|
|
||||||
|
/* hash progid name */
|
||||||
|
RtlInitUnicodeString(&str, progid);
|
||||||
|
RtlHashUnicodeString(&str, TRUE, HASH_STRING_ALGORITHM_X65599, &(*index)->hash);
|
||||||
|
|
||||||
|
(*index)->name_offset = *data_offset;
|
||||||
|
(*index)->name_len = str.Length;
|
||||||
|
(*index)->data_offset = (*index)->name_offset + aligned_string_len(str.MaximumLength);
|
||||||
|
(*index)->data_len = sizeof(*data);
|
||||||
|
(*index)->rosterindex = rosterindex;
|
||||||
|
|
||||||
|
*data_offset += aligned_string_len(str.MaximumLength);
|
||||||
|
|
||||||
|
/* setup data structure */
|
||||||
|
data = (struct progidredirect_data*)((BYTE*)section + *data_offset);
|
||||||
|
data->size = sizeof(*data);
|
||||||
|
data->reserved = 0;
|
||||||
|
data->clsid_offset = *global_offset;
|
||||||
|
|
||||||
|
/* write progid string */
|
||||||
|
ptrW = (WCHAR*)((BYTE*)section + (*index)->name_offset);
|
||||||
|
memcpy(ptrW, progid, (*index)->name_len);
|
||||||
|
ptrW[(*index)->name_len/sizeof(WCHAR)] = 0;
|
||||||
|
|
||||||
|
/* write guid to global area */
|
||||||
|
guid_ptr = (GUID*)((BYTE*)section + data->clsid_offset);
|
||||||
|
*guid_ptr = *alias;
|
||||||
|
|
||||||
|
/* to next entry */
|
||||||
|
*global_offset += sizeof(GUID);
|
||||||
|
*data_offset += data->size;
|
||||||
|
(*index) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_progid_record(ACTIVATION_CONTEXT* actctx, struct strsection_header *section, const struct entity_array *entities,
|
||||||
|
struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < entities->num; i++)
|
||||||
|
{
|
||||||
|
struct entity *entity = &entities->base[i];
|
||||||
|
if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
|
||||||
|
{
|
||||||
|
const struct progids *progids = &entity->u.comclass.progids;
|
||||||
|
struct comclassredirect_data *comclass;
|
||||||
|
struct guid_index *guid_index;
|
||||||
|
UNICODE_STRING str;
|
||||||
|
GUID clsid;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&str, entity->u.comclass.clsid);
|
||||||
|
RtlGUIDFromString(&str, &clsid);
|
||||||
|
|
||||||
|
guid_index = find_guid_index(actctx->comserver_section, &clsid);
|
||||||
|
comclass = get_comclass_data(actctx, guid_index);
|
||||||
|
|
||||||
|
if (entity->u.comclass.progid)
|
||||||
|
write_progid_record(section, entity->u.comclass.progid, &comclass->alias,
|
||||||
|
index, data_offset, global_offset, rosterindex);
|
||||||
|
|
||||||
|
for (j = 0; j < progids->num; j++)
|
||||||
|
write_progid_record(section, progids->progids[j], &comclass->alias,
|
||||||
|
index, data_offset, global_offset, rosterindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS build_progid_section(ACTIVATION_CONTEXT* actctx, struct strsection_header **section)
|
||||||
|
{
|
||||||
|
unsigned int i, j, total_len = 0, count = 0;
|
||||||
|
struct strsection_header *header;
|
||||||
|
ULONG data_offset, global_offset;
|
||||||
|
struct string_index *index;
|
||||||
|
|
||||||
|
/* compute section length */
|
||||||
|
for (i = 0; i < actctx->num_assemblies; i++)
|
||||||
|
{
|
||||||
|
struct assembly *assembly = &actctx->assemblies[i];
|
||||||
|
|
||||||
|
get_progid_datalen(&assembly->entities, &count, &total_len);
|
||||||
|
for (j = 0; j < assembly->num_dlls; j++)
|
||||||
|
{
|
||||||
|
struct dll_redirect *dll = &assembly->dlls[j];
|
||||||
|
get_progid_datalen(&dll->entities, &count, &total_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_len += sizeof(*header);
|
||||||
|
|
||||||
|
header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
|
||||||
|
if (!header) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
memset(header, 0, sizeof(*header));
|
||||||
|
header->magic = STRSECTION_MAGIC;
|
||||||
|
header->size = sizeof(*header);
|
||||||
|
header->count = count;
|
||||||
|
header->global_offset = header->size;
|
||||||
|
header->global_len = count*sizeof(GUID);
|
||||||
|
header->index_offset = header->size + header->global_len;
|
||||||
|
|
||||||
|
index = (struct string_index*)((BYTE*)header + header->index_offset);
|
||||||
|
data_offset = header->index_offset + count*sizeof(*index);
|
||||||
|
global_offset = header->global_offset;
|
||||||
|
|
||||||
|
for (i = 0; i < actctx->num_assemblies; i++)
|
||||||
|
{
|
||||||
|
struct assembly *assembly = &actctx->assemblies[i];
|
||||||
|
|
||||||
|
add_progid_record(actctx, header, &assembly->entities, &index, &data_offset, &global_offset, i + 1);
|
||||||
|
for (j = 0; j < assembly->num_dlls; j++)
|
||||||
|
{
|
||||||
|
struct dll_redirect *dll = &assembly->dlls[j];
|
||||||
|
add_progid_record(actctx, header, &dll->entities, &index, &data_offset, &global_offset, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*section = header;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct progidredirect_data *get_progid_data(ACTIVATION_CONTEXT *actctx, const struct string_index *index)
|
||||||
|
{
|
||||||
|
return (struct progidredirect_data*)((BYTE*)actctx->progid_section + index->data_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS find_progid_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *name,
|
||||||
|
PACTCTX_SECTION_KEYED_DATA data)
|
||||||
|
{
|
||||||
|
struct progidredirect_data *progid;
|
||||||
|
struct string_index *index;
|
||||||
|
|
||||||
|
if (!(actctx->sections & PROGIDREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
|
||||||
|
|
||||||
|
if (!actctx->comserver_section)
|
||||||
|
{
|
||||||
|
struct guidsection_header *section;
|
||||||
|
|
||||||
|
NTSTATUS status = build_comserver_section(actctx, §ion);
|
||||||
|
if (status) return status;
|
||||||
|
|
||||||
|
if (interlocked_cmpxchg_ptr((void**)&actctx->comserver_section, section, NULL))
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!actctx->progid_section)
|
||||||
|
{
|
||||||
|
struct strsection_header *section;
|
||||||
|
|
||||||
|
NTSTATUS status = build_progid_section(actctx, §ion);
|
||||||
|
if (status) return status;
|
||||||
|
|
||||||
|
if (interlocked_cmpxchg_ptr((void**)&actctx->progid_section, section, NULL))
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
index = find_string_index(actctx->progid_section, name);
|
||||||
|
if (!index) return STATUS_SXS_KEY_NOT_FOUND;
|
||||||
|
|
||||||
|
progid = get_progid_data(actctx, index);
|
||||||
|
|
||||||
|
data->ulDataFormatVersion = 1;
|
||||||
|
data->lpData = progid;
|
||||||
|
data->ulLength = progid->size;
|
||||||
|
data->lpSectionGlobalData = (BYTE*)actctx->progid_section + actctx->progid_section->global_offset;
|
||||||
|
data->ulSectionGlobalDataLength = actctx->progid_section->global_len;
|
||||||
|
data->lpSectionBase = actctx->progid_section;
|
||||||
|
data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->progid_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,
|
static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind,
|
||||||
const UNICODE_STRING *section_name,
|
const UNICODE_STRING *section_name,
|
||||||
DWORD flags, PACTCTX_SECTION_KEYED_DATA data)
|
DWORD flags, PACTCTX_SECTION_KEYED_DATA data)
|
||||||
|
@ -4150,6 +4394,8 @@ static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind,
|
||||||
status = find_window_class(actctx, section_name, data);
|
status = find_window_class(actctx, section_name, data);
|
||||||
break;
|
break;
|
||||||
case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION:
|
case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION:
|
||||||
|
status = find_progid_redirection(actctx, section_name, data);
|
||||||
|
break;
|
||||||
case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE:
|
case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE:
|
||||||
FIXME("Unsupported yet section_kind %x\n", section_kind);
|
FIXME("Unsupported yet section_kind %x\n", section_kind);
|
||||||
return STATUS_SXS_SECTION_NOT_FOUND;
|
return STATUS_SXS_SECTION_NOT_FOUND;
|
||||||
|
|
|
@ -59,6 +59,8 @@ static const GUID IID_Testiface = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x
|
||||||
static const GUID IID_Testiface2 = { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
static const GUID IID_Testiface2 = { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||||
static const GUID IID_Testiface3 = { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
static const GUID IID_Testiface3 = { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||||
static const GUID IID_Testiface4 = { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
static const GUID IID_Testiface4 = { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||||
|
static const GUID IID_Testiface5 = { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||||
|
static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
|
||||||
static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
|
static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
|
||||||
|
|
||||||
static WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
|
static WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
|
||||||
|
@ -236,6 +238,9 @@ static const char actctx_manifest[] =
|
||||||
" <comClass clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
|
" <comClass clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
|
||||||
" progid=\"StdFont\""
|
" progid=\"StdFont\""
|
||||||
" />"
|
" />"
|
||||||
|
" <comClass clsid=\"{62222222-1234-1234-1234-56789abcdef0}\" >"
|
||||||
|
" <progid>ProgId.ProgId.1</progid>"
|
||||||
|
" </comClass>"
|
||||||
" <comInterfaceProxyStub "
|
" <comInterfaceProxyStub "
|
||||||
" name=\"Iifaceps\""
|
" name=\"Iifaceps\""
|
||||||
" iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
|
" iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
|
||||||
|
@ -256,6 +261,12 @@ static const char actctx_manifest[] =
|
||||||
" iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
|
" iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
|
||||||
" proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
|
" proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
|
||||||
" />"
|
" />"
|
||||||
|
" <clrClass "
|
||||||
|
" clsid=\"{72222222-1234-1234-1234-56789abcdef0}\""
|
||||||
|
" name=\"clrclass\""
|
||||||
|
" >"
|
||||||
|
" <progid>clrprogid.1</progid>"
|
||||||
|
" </clrClass>"
|
||||||
"</assembly>";
|
"</assembly>";
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_Testclass, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
|
DEFINE_GUID(CLSID_Testclass, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
|
||||||
|
@ -304,6 +315,13 @@ todo_wine
|
||||||
ok(!lstrcmpiW(progid, customfontW), "got wrong progid %s\n", wine_dbgstr_w(progid));
|
ok(!lstrcmpiW(progid, customfontW), "got wrong progid %s\n", wine_dbgstr_w(progid));
|
||||||
CoTaskMemFree(progid);
|
CoTaskMemFree(progid);
|
||||||
|
|
||||||
|
/* classes without default progid, progid list is not used */
|
||||||
|
hr = ProgIDFromCLSID(&IID_Testiface5, &progid);
|
||||||
|
ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = ProgIDFromCLSID(&IID_Testiface6, &progid);
|
||||||
|
ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
pDeactivateActCtx(0, cookie);
|
pDeactivateActCtx(0, cookie);
|
||||||
pReleaseActCtx(handle);
|
pReleaseActCtx(handle);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue