windows-nt/Source/XPSP1/NT/shell/lib/dllreghelper.cpp
2020-09-26 16:20:57 +08:00

129 lines
4.7 KiB
C++

//------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000
//
// File: DllRegHelper.cpp
//
// Contents: helper classes to register COM components in DLLs
//
//------------------------------------------------------------------------
#include "DllRegHelper.h"
#pragma hdrstop
#include <comcat.h>
#include <advpub.h>
#include "ccstock.h"
#include "shlwapi.h"
#include "debug.h"
#include "mluisupp.h"
#define _APLHA_ComCat_WorkAround // { ALPHA ComCat bug work-around on alpha, nuke this eventually?
// ie40:63004: comcat does RegCloseKey(invalid) on checked
// nt/alpha if the clsid doesn't exist (e.g. for QuickLinksOld)
#if defined(_APLHA_ComCat_WorkAround)
//------------------------------------------------------------------------
//*** HasImplCat -- does "HKCR/CLSID/{clsid}/Implemented Categories" exist
// NOTES
// used for ComCat bug work-around on alpha
BOOL HasImplCat(const CATID *pclsid)
{
HKEY hk;
TCHAR szClass[GUIDSTR_MAX];
TCHAR szImpl[MAX_PATH]; // "CLSID/{clsid}/Implemented Categories" < MAX_PATH
// "CLSID/{clsid}/Implemented Categories"
SHStringFromGUID(*pclsid, szClass, ARRAYSIZE(szClass));
ASSERT(lstrlen(szClass) == GUIDSTR_MAX - 1);
wnsprintf(szImpl, ARRAYSIZE(szImpl), TEXT("CLSID\\%s\\Implemented Categories"), szClass);
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szImpl, 0, KEY_READ, &hk) == ERROR_SUCCESS) {
RegCloseKey(hk);
return TRUE;
}
else {
TraceMsg(DM_WARNING, "HasImplCat: %s: ret 0", szImpl);
return FALSE;
}
}
#endif // }
//------------------------------------------------------------------------
//*** RegisterOneCategory -- [un]register ComCat implementor(s) and category
// ENTRY/EXIT
// eRegister CCR_REG, CCR_UNREG, CCR_UNREGIMP
// CCR_REG, UNREG reg/unreg implementor(s) and category
// CCR_UNREGIMP unreg implementor(s) only
// pcatidCat e.g. CATID_DeskBand
// idResCat e.g. IDS_CATDESKBAND
// pcatidImpl e.g. c_DeskBandClasses
HRESULT DRH_RegisterOneCategory(const CATID *pcatidCat, UINT idResCat, const CATID * const *pcatidImpl, enum DRH_REG_MODE eRegister)
{
ICatRegister* pcr;
HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr));
if (SUCCEEDED(hr))
{
if (eRegister == CCR_REG)
{
// register the category
CATEGORYINFO catinfo;
catinfo.catid = *pcatidCat; // e.g. CATID_DESKBAND
catinfo.lcid = LOCALE_USER_DEFAULT;
MLLoadString(idResCat, catinfo.szDescription, ARRAYSIZE(catinfo.szDescription));
hr = pcr->RegisterCategories(1, &catinfo);
ASSERT(SUCCEEDED(hr));
// register the classes that implement categories
for ( ; *pcatidImpl != NULL; pcatidImpl++)
{
CLSID clsid = **pcatidImpl;
CATID catid = *pcatidCat;
hr = pcr->RegisterClassImplCategories(clsid, 1, &catid);
ASSERT(SUCCEEDED(hr));
}
}
else
{
// unregister the classes that implement categories
for ( ; *pcatidImpl != NULL; pcatidImpl++)
{
CLSID clsid = **pcatidImpl;
CATID catid = *pcatidCat;
#if defined(_APLHA_ComCat_WorkAround) // { ALPHA ComCat bug work-around on alpha, nuke this eventually?
// workaround comcat/alpha bug
// n.b. we do this for non-alpha too to reduce testing impact
// ie40:63004: comcat does RegCloseKey(invalid) on checked
// nt/alpha if the clsid doesn't exist (e.g. for QuickLinksOld)
if (!HasImplCat(&clsid))
continue;
#endif // }
hr = pcr->UnRegisterClassImplCategories(clsid, 1, &catid);
ASSERT(SUCCEEDED(hr));
}
if (eRegister == CCR_UNREG)
{
// Do we want to do this? other classes (e.g. 3rd party
// ones) might still be using the category. however since we're
// the component that added (and supports) the category, it
// seems correct that we should remove it when we unregister.
// unregister the category
CATID catid = *pcatidCat;
hr = pcr->UnRegisterCategories(1, &catid);
ASSERT(SUCCEEDED(hr));
}
}
pcr->Release();
}
return S_OK;
}