Jacek Caban : atl100: Added AtlRegisterClassCategoriesHelper implementation .
Alexandre Julliard
julliard at winehq.org
Mon Dec 24 14:03:04 CST 2012
Module: wine
Branch: master
Commit: 56c094186f7baf72310acee2194b6a13ae237be6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=56c094186f7baf72310acee2194b6a13ae237be6
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Dec 24 15:13:39 2012 +0100
atl100: Added AtlRegisterClassCategoriesHelper implementation.
---
dlls/atl100/atl.c | 75 +++++++++++++++++++++++++++++++++++++++-
dlls/atl100/tests/Makefile.in | 2 +-
dlls/atl100/tests/atl.c | 62 +++++++++++++++++++++++++++++++++
include/atlbase.h | 11 ++++++
4 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/dlls/atl100/atl.c b/dlls/atl100/atl.c
index 570fe5c..219365d 100644
--- a/dlls/atl100/atl.c
+++ b/dlls/atl100/atl.c
@@ -1,5 +1,6 @@
/*
* Copyright 2012 Stefan Leichter
+ * Copyright 2012 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,6 +25,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(atl100);
+static ICatRegister *catreg;
+
/***********************************************************************
* AtlAdvise [atl100.@]
*/
@@ -379,8 +382,60 @@ HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid,
*/
HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
{
- FIXME("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
- return E_NOTIMPL;
+ const struct _ATL_CATMAP_ENTRY *iter;
+ HRESULT hres;
+
+ TRACE("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
+
+ if(!catreg) {
+ ICatRegister *new_catreg;
+
+ hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ICatRegister, (void**)&new_catreg);
+ if(FAILED(hres))
+ return hres;
+
+ if(InterlockedCompareExchangePointer((void**)&catreg, new_catreg, NULL))
+ ICatRegister_Release(new_catreg);
+ }
+
+ for(iter = catmap; iter->iType != _ATL_CATMAP_ENTRY_END; iter++) {
+ CATID catid = *iter->pcatid; /* For stupid lack of const in ICatRegister declaration. */
+
+ if(iter->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED) {
+ if(reg)
+ hres = ICatRegister_RegisterClassImplCategories(catreg, clsid, 1, &catid);
+ else
+ hres = ICatRegister_UnRegisterClassImplCategories(catreg, clsid, 1, &catid);
+ }else {
+ if(reg)
+ hres = ICatRegister_RegisterClassReqCategories(catreg, clsid, 1, &catid);
+ else
+ hres = ICatRegister_UnRegisterClassReqCategories(catreg, clsid, 1, &catid);
+ }
+ if(FAILED(hres))
+ return hres;
+ }
+
+ if(!reg) {
+ WCHAR reg_path[256] = {'C','L','S','I','D','\\'}, *ptr = reg_path+6;
+
+ static const WCHAR implemented_catW[] =
+ {'I','m','p','l','e','m','e','n','t','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
+ static const WCHAR required_catW[] =
+ {'R','e','q','u','i','r','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
+
+ ptr += StringFromGUID2(clsid, ptr, 64)-1;
+ *ptr++ = '\\';
+
+ memcpy(ptr, implemented_catW, sizeof(implemented_catW));
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
+
+ memcpy(ptr, required_catW, sizeof(required_catW));
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
+ }
+
+ return S_OK;
}
/***********************************************************************
@@ -390,3 +445,19 @@ DWORD WINAPI AtlGetVersion(void *pReserved)
{
return _ATL_VER;
}
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+ switch(fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ break;
+ case DLL_PROCESS_DETACH:
+ if(catreg)
+ ICatRegister_Release(catreg);
+ }
+
+ return TRUE;
+}
diff --git a/dlls/atl100/tests/Makefile.in b/dlls/atl100/tests/Makefile.in
index 4230bad..29e83d0 100644
--- a/dlls/atl100/tests/Makefile.in
+++ b/dlls/atl100/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = atl100.dll
-IMPORTS = ole32 atl100
+IMPORTS = atl100 ole32 advapi32
EXTRADEFS = -D_ATL_VER=_ATL_VER_100
C_SRCS = \
diff --git a/dlls/atl100/tests/atl.c b/dlls/atl100/tests/atl.c
index 7e6a7e0..e7882fa 100644
--- a/dlls/atl100/tests/atl.c
+++ b/dlls/atl100/tests/atl.c
@@ -25,6 +25,18 @@
#include <wine/test.h>
+static const GUID CLSID_Test =
+ {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
+#define CLSID_TEST_STR "178fc163-0000-0000-0000-000000000046"
+
+static const GUID CATID_CatTest1 =
+ {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x46}};
+#define CATID_CATTEST1_STR "178fc163-0000-0000-0000-000000000146"
+
+static const GUID CATID_CatTest2 =
+ {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x46}};
+#define CATID_CATTEST2_STR "178fc163-0000-0000-0000-000000000246"
+
static void test_winmodule(void)
{
_AtlCreateWndData create_data[3];
@@ -95,11 +107,61 @@ static void test_winmodule(void)
ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
}
+#define test_key_exists(a,b) _test_key_exists(__LINE__,a,b)
+static void _test_key_exists(unsigned line, HKEY root, const char *key_name)
+{
+ HKEY key;
+ DWORD res;
+
+ res = RegOpenKeyA(root, key_name, &key);
+ ok_(__FILE__,line)(res == ERROR_SUCCESS, "Could not open key %s\n", key_name);
+ if(res == ERROR_SUCCESS)
+ RegCloseKey(key);
+}
+
+#define test_key_not_exists(a,b) _test_key_not_exists(__LINE__,a,b)
+static void _test_key_not_exists(unsigned line, HKEY root, const char *key_name)
+{
+ HKEY key;
+ DWORD res;
+
+ res = RegOpenKeyA(root, key_name, &key);
+ ok_(__FILE__,line)(res == ERROR_FILE_NOT_FOUND, "Attempting to open %s returned %u\n", key_name, res);
+ if(res == ERROR_SUCCESS)
+ RegCloseKey(key);
+}
+
+static void test_regcat(void)
+{
+ HRESULT hres;
+
+ const struct _ATL_CATMAP_ENTRY catmap[] = {
+ {_ATL_CATMAP_ENTRY_IMPLEMENTED, &CATID_CatTest1},
+ {_ATL_CATMAP_ENTRY_REQUIRED, &CATID_CatTest2},
+ {_ATL_CATMAP_ENTRY_END}
+ };
+
+ hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, TRUE);
+ ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
+
+ test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
+ test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories\\{" CATID_CATTEST1_STR "}");
+ test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories\\{" CATID_CATTEST2_STR "}");
+
+ hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, FALSE);
+ ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
+
+ test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories");
+ test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories");
+ test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
+}
+
START_TEST(atl)
{
CoInitialize(NULL);
test_winmodule();
+ test_regcat();
CoUninitialize();
}
diff --git a/include/atlbase.h b/include/atlbase.h
index 831150d..ee8167c 100644
--- a/include/atlbase.h
+++ b/include/atlbase.h
@@ -22,6 +22,7 @@
#define __WINE_ATLBASE_H__
#include <atliface.h>
+#include <comcat.h>
/* Wine extension: we (ab)use _ATL_VER to handle struct layout differences between ATL versions. */
#define _ATL_VER_30 0x0300
@@ -213,6 +214,16 @@ struct _ATL_REGMAP_ENTRY
LPCOLESTR szData;
};
+struct _ATL_CATMAP_ENTRY
+{
+ int iType;
+ const CATID *pcatid;
+};
+
+#define _ATL_CATMAP_ENTRY_END 0
+#define _ATL_CATMAP_ENTRY_IMPLEMENTED 1
+#define _ATL_CATMAP_ENTRY_REQUIRED 2
+
HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID * iid, LPDWORD dpw);
HRESULT WINAPI AtlAxAttachControl(IUnknown*,HWND,IUnknown**);
HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**);
More information about the wine-cvs
mailing list