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