Commit aeb35b20 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

ole32: Store categories with offset so it's possible to copy them directly.

parent 4de8d4b0
...@@ -54,9 +54,11 @@ static ComCatMgrImpl COMCAT_ComCatMgr = ...@@ -54,9 +54,11 @@ static ComCatMgrImpl COMCAT_ComCatMgr =
{ &COMCAT_ICatInformation_Vtbl } { &COMCAT_ICatInformation_Vtbl }
}; };
struct class_categories { struct class_categories
LPCWSTR impl_strings; {
LPCWSTR req_strings; ULONG size; /* total length, including structure itself */
ULONG impl_offset;
ULONG req_offset;
}; };
static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid); static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid);
...@@ -195,22 +197,23 @@ static struct class_categories *COMCAT_PrepareClassCategories( ...@@ -195,22 +197,23 @@ static struct class_categories *COMCAT_PrepareClassCategories(
{ {
struct class_categories *categories; struct class_categories *categories;
WCHAR *strings; WCHAR *strings;
ULONG size;
categories = HeapAlloc( size = sizeof(struct class_categories) + ((impl_count + req_count)*CHARS_IN_GUID + 2)*sizeof(WCHAR);
GetProcessHeap(), HEAP_ZERO_MEMORY, categories = HeapAlloc(GetProcessHeap(), 0, size);
sizeof(struct class_categories) +
((impl_count + req_count) * CHARS_IN_GUID + 2) * sizeof(WCHAR));
if (categories == NULL) return categories; if (categories == NULL) return categories;
categories->size = size;
categories->impl_offset = sizeof(struct class_categories);
categories->req_offset = categories->impl_offset + (impl_count*CHARS_IN_GUID + 1)*sizeof(WCHAR);
strings = (WCHAR *)(categories + 1); strings = (WCHAR *)(categories + 1);
categories->impl_strings = strings;
while (impl_count--) { while (impl_count--) {
StringFromGUID2(impl_catids++, strings, CHARS_IN_GUID); StringFromGUID2(impl_catids++, strings, CHARS_IN_GUID);
strings += CHARS_IN_GUID; strings += CHARS_IN_GUID;
} }
*strings++ = 0; *strings++ = 0;
categories->req_strings = strings;
while (req_count--) { while (req_count--) {
StringFromGUID2(req_catids++, strings, CHARS_IN_GUID); StringFromGUID2(req_catids++, strings, CHARS_IN_GUID);
strings += CHARS_IN_GUID; strings += CHARS_IN_GUID;
...@@ -227,16 +230,20 @@ static HRESULT COMCAT_IsClassOfCategories( ...@@ -227,16 +230,20 @@ static HRESULT COMCAT_IsClassOfCategories(
HKEY key, HKEY key,
struct class_categories const* categories) struct class_categories const* categories)
{ {
const WCHAR *impl_strings, *req_strings;
HKEY subkey; HKEY subkey;
HRESULT res; HRESULT res;
DWORD index; DWORD index;
LPCWSTR string; LPCWSTR string;
impl_strings = (WCHAR*)((BYTE*)categories + categories->impl_offset);
req_strings = (WCHAR*)((BYTE*)categories + categories->req_offset);
/* Check that every given category is implemented by class. */ /* Check that every given category is implemented by class. */
if (*categories->impl_strings) { if (*impl_strings) {
res = open_classes_key(key, impl_keyname, KEY_READ, &subkey); res = open_classes_key(key, impl_keyname, KEY_READ, &subkey);
if (res != ERROR_SUCCESS) return S_FALSE; if (res != ERROR_SUCCESS) return S_FALSE;
for (string = categories->impl_strings; *string; string += CHARS_IN_GUID) { for (string = impl_strings; *string; string += CHARS_IN_GUID) {
HKEY catkey; HKEY catkey;
res = open_classes_key(subkey, string, 0, &catkey); res = open_classes_key(subkey, string, 0, &catkey);
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
...@@ -259,7 +266,7 @@ static HRESULT COMCAT_IsClassOfCategories( ...@@ -259,7 +266,7 @@ static HRESULT COMCAT_IsClassOfCategories(
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break; if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
if (size != CHARS_IN_GUID-1) continue; /* bogus catid in registry */ if (size != CHARS_IN_GUID-1) continue; /* bogus catid in registry */
for (string = categories->req_strings; *string; string += CHARS_IN_GUID) for (string = req_strings; *string; string += CHARS_IN_GUID)
if (!strcmpiW(string, keyname)) break; if (!strcmpiW(string, keyname)) break;
if (!*string) { if (!*string) {
RegCloseKey(subkey); RegCloseKey(subkey);
...@@ -1115,33 +1122,34 @@ static HRESULT WINAPI CLSIDEnumGUID_Clone( ...@@ -1115,33 +1122,34 @@ static HRESULT WINAPI CLSIDEnumGUID_Clone(
IEnumGUID *iface, IEnumGUID *iface,
IEnumGUID **ppenum) IEnumGUID **ppenum)
{ {
static const WCHAR keynameW[] = {'C','L','S','I','D',0};
CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 }; CLSID_IEnumGUIDImpl *cloned;
CLSID_IEnumGUIDImpl *new_this;
DWORD size;
TRACE("\n"); TRACE("(%p)->(%p)\n", This, ppenum);
if (ppenum == NULL) return E_POINTER; if (ppenum == NULL) return E_POINTER;
new_this = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl)); *ppenum = NULL;
if (new_this == NULL) return E_OUTOFMEMORY;
new_this->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl; cloned = HeapAlloc(GetProcessHeap(), 0, sizeof(CLSID_IEnumGUIDImpl));
new_this->ref = 1; if (cloned == NULL) return E_OUTOFMEMORY;
size = HeapSize(GetProcessHeap(), 0, This->categories);
new_this->categories = cloned->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl;
HeapAlloc(GetProcessHeap(), 0, size); cloned->ref = 1;
if (new_this->categories == NULL) {
HeapFree(GetProcessHeap(), 0, new_this); cloned->categories = HeapAlloc(GetProcessHeap(), 0, This->categories->size);
if (cloned->categories == NULL) {
HeapFree(GetProcessHeap(), 0, cloned);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
memcpy(new_this->categories, This->categories, size); memcpy(cloned->categories, This->categories, This->categories->size);
/* FIXME: could we more efficiently use DuplicateHandle? */
open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &new_this->key);
new_this->next_index = This->next_index;
*ppenum = &new_this->IEnumGUID_iface; cloned->key = NULL;
open_classes_key(HKEY_CLASSES_ROOT, keynameW, KEY_READ, &cloned->key);
cloned->next_index = This->next_index;
*ppenum = &cloned->IEnumGUID_iface;
return S_OK; return S_OK;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment