| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #ifdef AFXCTL_FACT_SEG
- #pragma code_seg(AFXCTL_FACT_SEG)
- #endif
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define new DEBUG_NEW
- #define GUID_CCH 39 // Characters in string form of guid, including '\0'
- inline BOOL _AfxRegDeleteKeySucceeded(LONG error)
- {
- return (error == ERROR_SUCCESS) || (error == ERROR_BADKEY) ||
- (error == ERROR_FILE_NOT_FOUND);
- }
- // Under Win32, a reg key may not be deleted unless it is empty.
- // Thus, to delete a tree, one must recursively enumerate and
- // delete all of the sub-keys.
- LONG AFXAPI _AfxRecursiveRegDeleteKey(HKEY hParentKey, LPTSTR szKeyName)
- {
- // one implementation for everybody
- return AfxDelRegTreeHelper(hParentKey, szKeyName);
- }
- void _AfxUnregisterInterfaces(ITypeLib* pTypeLib)
- {
- TCHAR szKey[128];
- lstrcpy(szKey, _T("Interface\\"));
- LPTSTR pszGuid = szKey + lstrlen(szKey);
- int cTypeInfo = pTypeLib->GetTypeInfoCount();
- for (int i = 0; i < cTypeInfo; i++)
- {
- TYPEKIND tk;
- if (SUCCEEDED(pTypeLib->GetTypeInfoType(i, &tk)) &&
- (tk == TKIND_DISPATCH || tk == TKIND_INTERFACE))
- {
- ITypeInfo* pTypeInfo = NULL;
- if (SUCCEEDED(pTypeLib->GetTypeInfo(i, &pTypeInfo)))
- {
- TYPEATTR* pTypeAttr;
- if (SUCCEEDED(pTypeInfo->GetTypeAttr(&pTypeAttr)))
- {
- #if defined(_UNICODE) || defined(OLE2ANSI)
- StringFromGUID2(pTypeAttr->guid, pszGuid, GUID_CCH);
- #else
- WCHAR wszGuid[39];
- StringFromGUID2(pTypeAttr->guid, wszGuid, GUID_CCH);
- _wcstombsz(pszGuid, wszGuid, GUID_CCH);
- #endif
- _AfxRecursiveRegDeleteKey(HKEY_CLASSES_ROOT, szKey);
- pTypeInfo->ReleaseTypeAttr(pTypeAttr);
- }
- pTypeInfo->Release();
- }
- }
- }
- }
- BOOL AFXAPI AfxOleRegisterTypeLib(HINSTANCE hInstance, REFGUID tlid,
- LPCTSTR pszFileName, LPCTSTR pszHelpDir)
- {
- USES_CONVERSION;
- BOOL bSuccess = FALSE;
- CString strPathName;
- TCHAR *szPathName = strPathName.GetBuffer(_MAX_PATH);
- ::GetModuleFileName(hInstance, szPathName, _MAX_PATH);
- strPathName.ReleaseBuffer();
- LPTYPELIB ptlib = NULL;
- // If a filename was specified, replace final component of path with it.
- if (pszFileName != NULL)
- {
- int iBackslash = strPathName.ReverseFind('\\');
- if (iBackslash != -1)
- strPathName = strPathName.Left(iBackslash+1);
- strPathName += pszFileName;
- }
- if (SUCCEEDED(LoadTypeLib(T2COLE(strPathName), &ptlib)))
- {
- ASSERT_POINTER(ptlib, ITypeLib);
- LPTLIBATTR pAttr;
- GUID tlidActual = GUID_NULL;
- if (SUCCEEDED(ptlib->GetLibAttr(&pAttr)))
- {
- ASSERT_POINTER(pAttr, TLIBATTR);
- tlidActual = pAttr->guid;
- ptlib->ReleaseTLibAttr(pAttr);
- }
- // Check that the guid of the loaded type library matches
- // the tlid parameter.
- ASSERT(IsEqualGUID(tlid, tlidActual));
- if (IsEqualGUID(tlid, tlidActual))
- {
- // Register the type library.
- if (SUCCEEDED(RegisterTypeLib(ptlib,
- T2OLE((LPTSTR)(LPCTSTR)strPathName), T2OLE((LPTSTR)pszHelpDir))))
- bSuccess = TRUE;
- }
- RELEASE(ptlib);
- }
- else
- {
- TRACE1("Warning: Could not load type library from %s\n", (LPCTSTR)strPathName);
- }
- return bSuccess;
- }
- #define TYPELIBWIN _T("win32")
- #define TYPELIBWIN_2 _T("win16")
- BOOL AFXAPI AfxOleUnregisterTypeLib(REFGUID tlid, WORD wVerMajor,
- WORD wVerMinor, LCID lcid)
- {
- USES_CONVERSION;
- // Load type library before unregistering it.
- ITypeLib* pTypeLib = NULL;
- if (wVerMajor != 0)
- {
- if (FAILED(LoadRegTypeLib(tlid, wVerMajor, wVerMinor, lcid, &pTypeLib)))
- pTypeLib = NULL;
- }
- // Format typelib guid as a string
- OLECHAR szTypeLibID[GUID_CCH];
- int cchGuid = ::StringFromGUID2(tlid, szTypeLibID, GUID_CCH);
- ASSERT(cchGuid == GUID_CCH); // Did StringFromGUID2 work?
- if (cchGuid != GUID_CCH)
- return FALSE;
- TCHAR szKeyTypeLib[_MAX_PATH];
- BOOL bSurgical = FALSE;
- LONG error = ERROR_SUCCESS;
- wsprintf(szKeyTypeLib, _T("TYPELIB\\%s"), OLE2CT(szTypeLibID));
- HKEY hKeyTypeLib;
- if (RegOpenKey(HKEY_CLASSES_ROOT, szKeyTypeLib, &hKeyTypeLib) ==
- ERROR_SUCCESS)
- {
- int iKeyVersion = 0;
- HKEY hKeyVersion;
- TCHAR szVersion[_MAX_PATH];
- // Iterate through all installed versions of the control
- while (RegEnumKey(hKeyTypeLib, iKeyVersion, szVersion, _MAX_PATH) ==
- ERROR_SUCCESS)
- {
- hKeyVersion = NULL;
- BOOL bSurgicalVersion = FALSE;
- if (RegOpenKey(hKeyTypeLib, szVersion, &hKeyVersion) !=
- ERROR_SUCCESS)
- {
- ++iKeyVersion;
- continue;
- }
- int iKeyLocale = 0;
- HKEY hKeyLocale;
- TCHAR szLocale[_MAX_PATH];
- // Iterate through all registered locales for this version
- while (RegEnumKey(hKeyVersion, iKeyLocale, szLocale, _MAX_PATH) ==
- ERROR_SUCCESS)
- {
- // Don't remove HELPDIR or FLAGS keys.
- if ((lstrcmpi(szLocale, _T("HELPDIR")) == 0) ||
- (lstrcmpi(szLocale, _T("FLAGS")) == 0))
- {
- ++iKeyLocale;
- continue;
- }
- hKeyLocale = NULL;
- if (RegOpenKey(hKeyVersion, szLocale, &hKeyLocale) !=
- ERROR_SUCCESS)
- {
- ++iKeyLocale;
- continue;
- }
- // Check if a 16-bit key is found when unregistering 32-bit
- HKEY hkey;
- if (RegOpenKey(hKeyLocale, TYPELIBWIN_2, &hkey) ==
- ERROR_SUCCESS)
- {
- RegCloseKey(hkey);
- // Only remove the keys specific to the 32-bit version
- // of control, leaving things intact for 16-bit version.
- error = _AfxRecursiveRegDeleteKey(hKeyLocale, TYPELIBWIN);
- bSurgicalVersion = TRUE;
- RegCloseKey(hKeyLocale);
- }
- else
- {
- // Delete everything for this locale.
- RegCloseKey(hKeyLocale);
- if (_AfxRecursiveRegDeleteKey(hKeyVersion, szLocale) ==
- ERROR_SUCCESS)
- {
- // Start over again, so we don't skip anything.
- iKeyLocale = 0;
- continue;
- }
- }
- ++iKeyLocale;
- }
- RegCloseKey(hKeyVersion);
- if (bSurgicalVersion)
- {
- bSurgical = TRUE;
- }
- else
- {
- if (_AfxRecursiveRegDeleteKey(hKeyTypeLib, szVersion) ==
- ERROR_SUCCESS)
- {
- // Start over again, to make sure we don't skip anything.
- iKeyVersion = 0;
- continue;
- }
- }
- ++iKeyVersion;
- }
- RegCloseKey(hKeyTypeLib);
- }
- if (!bSurgical)
- error = _AfxRecursiveRegDeleteKey(HKEY_CLASSES_ROOT, szKeyTypeLib);
- if (_AfxRegDeleteKeySucceeded(error))
- {
- // If type library was unregistered successfully, then also unregister
- // interfaces.
- if (pTypeLib != NULL)
- {
- ITypeLib* pDummy = NULL;
- if (FAILED(LoadRegTypeLib(tlid, wVerMajor, wVerMinor, lcid, &pDummy)))
- _AfxUnregisterInterfaces(pTypeLib);
- else
- pDummy->Release();
- pTypeLib->Release();
- }
- }
- return _AfxRegDeleteKeySucceeded(error);
- }
- AFX_STATIC_DATA const LPCTSTR _afxCtrlProgID[] =
- {
- _T("\0") _T("%1"),
- _T("CLSID\0") _T("%2"),
- NULL
- };
- #define INPROCSERVER _T("InprocServer32")
- #define INPROCSERVER_2 _T("InprocServer")
- #define TOOLBOXBITMAP _T("ToolboxBitmap32")
- AFX_STATIC_DATA const LPCTSTR _afxCtrlClassID[] =
- {
- _T("\0") _T("%1"),
- _T("ProgID\0") _T("%2"),
- INPROCSERVER _T("\0%3"),
- TOOLBOXBITMAP _T("\0%3, %4"),
- _T("MiscStatus\0") _T("0"),
- _T("MiscStatus\\1\0") _T("%5"),
- _T("Control\0") _T(""),
- _T("TypeLib\0") _T("%6"),
- _T("Version\0") _T("%7"),
- NULL
- };
- BOOL AFXAPI AfxOleRegisterControlClass(HINSTANCE hInstance,
- REFCLSID clsid, LPCTSTR pszProgID, UINT idTypeName, UINT idBitmap,
- int nRegFlags, DWORD dwMiscStatus, REFGUID tlid, WORD wVerMajor,
- WORD wVerMinor)
- {
- USES_CONVERSION;
- BOOL bSuccess = FALSE;
- // Format class ID as a string
- OLECHAR szClassID[GUID_CCH];
- int cchGuid = ::StringFromGUID2(clsid, szClassID, GUID_CCH);
- LPCTSTR lpszClassID = OLE2CT(szClassID);
- ASSERT(cchGuid == GUID_CCH); // Did StringFromGUID2 work?
- if (cchGuid != GUID_CCH)
- return FALSE;
- // Format typelib guid as a string
- OLECHAR szTypeLibID[GUID_CCH];
- cchGuid = ::StringFromGUID2(tlid, szTypeLibID, GUID_CCH);
- ASSERT(cchGuid == GUID_CCH); // Did StringFromGUID2 work?
- if (cchGuid != GUID_CCH)
- return FALSE;
- CString strPathName;
- AfxGetModuleShortFileName(hInstance, strPathName);
- CString strTypeName;
- if (!strTypeName.LoadString(idTypeName))
- {
- ASSERT(FALSE); // Name string not present in resources
- strTypeName = lpszClassID; // Use Class ID instead
- }
- TCHAR szBitmapID[_MAX_PATH];
- _itot(idBitmap, szBitmapID, 10);
- TCHAR szMiscStatus[_MAX_PATH];
- _ltot(dwMiscStatus, szMiscStatus, 10);
- // Format version string as "major.minor"
- TCHAR szVersion[_MAX_PATH];
- wsprintf(szVersion, _T("%d.%d"), wVerMajor, wVerMinor);
- // Attempt to open registry keys.
- HKEY hkeyClassID = NULL;
- HKEY hkeyProgID = NULL;
- TCHAR szScratch[_MAX_PATH];
- wsprintf(szScratch, _T("CLSID\\%s"), lpszClassID);
- if (::RegCreateKey(HKEY_CLASSES_ROOT, szScratch, &hkeyClassID) !=
- ERROR_SUCCESS)
- goto Error;
- if (::RegCreateKey(HKEY_CLASSES_ROOT, pszProgID, &hkeyProgID) !=
- ERROR_SUCCESS)
- goto Error;
- ASSERT(hkeyClassID != NULL);
- ASSERT(hkeyProgID != NULL);
- LPCTSTR rglpszSymbols[7];
- rglpszSymbols[0] = strTypeName;
- rglpszSymbols[1] = lpszClassID;
- bSuccess = AfxOleRegisterHelper(_afxCtrlProgID, rglpszSymbols, 2,
- TRUE, hkeyProgID);
- if (!bSuccess)
- goto Error;
- rglpszSymbols[1] = pszProgID;
- rglpszSymbols[2] = strPathName;
- rglpszSymbols[3] = szBitmapID;
- rglpszSymbols[4] = szMiscStatus;
- rglpszSymbols[5] = OLE2CT(szTypeLibID);
- rglpszSymbols[6] = szVersion;
- bSuccess = AfxOleRegisterHelper(_afxCtrlClassID, rglpszSymbols, 7,
- TRUE, hkeyClassID);
- if (!bSuccess)
- goto Error;
- if (nRegFlags & afxRegInsertable)
- {
- bSuccess =
- (::RegSetValue(hkeyProgID, _T("Insertable"), REG_SZ, _T(""), 0) ==
- ERROR_SUCCESS) &&
- (::RegSetValue(hkeyClassID, _T("Insertable"), REG_SZ, _T(""), 0) ==
- ERROR_SUCCESS);
- }
- if (nRegFlags & afxRegApartmentThreading)
- {
- HKEY hkeyInprocServer32;
- bSuccess = (::RegOpenKey(hkeyClassID, INPROCSERVER,
- &hkeyInprocServer32) == ERROR_SUCCESS);
- if (!bSuccess)
- goto Error;
- ASSERT(hkeyInprocServer32 != NULL);
- static TCHAR szApartment[] = _T("Apartment");
- bSuccess = (::RegSetValueEx(hkeyInprocServer32, _T("ThreadingModel"), 0,
- REG_SZ, (const BYTE*)szApartment, (lstrlen(szApartment)+1) * sizeof(TCHAR)) ==
- ERROR_SUCCESS);
- ::RegCloseKey(hkeyInprocServer32);
- }
- Error:
- if (hkeyProgID != NULL)
- ::RegCloseKey(hkeyProgID);
- if (hkeyClassID != NULL)
- ::RegCloseKey(hkeyClassID);
- return bSuccess;
- }
- BOOL AFXAPI AfxOleUnregisterClass(REFCLSID clsid, LPCTSTR pszProgID)
- {
- USES_CONVERSION;
- // Format class ID as a string
- OLECHAR szClassID[GUID_CCH];
- int cchGuid = ::StringFromGUID2(clsid, szClassID, GUID_CCH);
- LPCTSTR lpszClassID = OLE2CT(szClassID);
- ASSERT(cchGuid == GUID_CCH); // Did StringFromGUID2 work?
- if (cchGuid != GUID_CCH)
- return FALSE;
- TCHAR szKey[_MAX_PATH];
- long error;
- BOOL bRetCode = TRUE;
- // check to see if a 16-bit InprocServer key is found when unregistering
- // 32-bit (or vice versa).
- wsprintf(szKey, _T("CLSID\\%s\\%s"), lpszClassID, INPROCSERVER_2);
- HKEY hkey;
- BOOL bSurgical = RegOpenKey(HKEY_CLASSES_ROOT, szKey, &hkey) ==
- ERROR_SUCCESS;
- if (bSurgical)
- {
- // Only remove the keys specific to this version of the control,
- // leaving things in tact for the other version.
- wsprintf(szKey, _T("CLSID\\%s\\%s"), lpszClassID, INPROCSERVER);
- error = RegDeleteKey(HKEY_CLASSES_ROOT, szKey);
- bRetCode = bRetCode && _AfxRegDeleteKeySucceeded(error);
- wsprintf(szKey, _T("CLSID\\%s\\%s"), lpszClassID, TOOLBOXBITMAP);
- error = RegDeleteKey(HKEY_CLASSES_ROOT, szKey);
- bRetCode = bRetCode && _AfxRegDeleteKeySucceeded(error);
- }
- else
- {
- // No other versions of this control were detected,
- // so go ahead and remove the control completely.
- wsprintf(szKey, _T("CLSID\\%s"), lpszClassID);
- error = _AfxRecursiveRegDeleteKey(HKEY_CLASSES_ROOT, szKey);
- bRetCode = bRetCode && _AfxRegDeleteKeySucceeded(error);
- if (pszProgID != NULL)
- {
- error = _AfxRecursiveRegDeleteKey(HKEY_CLASSES_ROOT,
- (LPTSTR)pszProgID);
- bRetCode = bRetCode && _AfxRegDeleteKeySucceeded(error);
- }
- }
- return bRetCode;
- }
- AFX_STATIC_DATA const LPCTSTR _afxPropPageClass[] =
- {
- _T("\0") _T("%1"),
- INPROCSERVER _T("\0%2"),
- NULL
- };
- BOOL AFXAPI AfxOleRegisterPropertyPageClass(HINSTANCE hInstance,
- REFCLSID clsid, UINT idTypeName)
- {
- return AfxOleRegisterPropertyPageClass(hInstance, clsid, idTypeName, 0);
- }
- BOOL AFXAPI AfxOleRegisterPropertyPageClass(HINSTANCE hInstance,
- REFCLSID clsid, UINT idTypeName, int nRegFlags)
- {
- ASSERT(!(nRegFlags & afxRegInsertable)); // can't be insertable
- USES_CONVERSION;
- BOOL bSuccess = FALSE;
- // Format class ID as a string
- OLECHAR szClassID[GUID_CCH];
- int cchGuid = ::StringFromGUID2(clsid, szClassID, GUID_CCH);
- LPCTSTR lpszClassID = OLE2CT(szClassID);
- ASSERT(cchGuid == GUID_CCH); // Did StringFromGUID2 work?
- if (cchGuid != GUID_CCH)
- return FALSE;
- CString strPathName;
- AfxGetModuleShortFileName(hInstance, strPathName);
- CString strTypeName;
- if (!strTypeName.LoadString(idTypeName))
- {
- ASSERT(FALSE); // Name string not present in resources
- strTypeName = lpszClassID; // Use Class ID instead
- }
- HKEY hkeyClassID = NULL;
- TCHAR szKey[_MAX_PATH];
- wsprintf(szKey, _T("CLSID\\%s"), lpszClassID);
- if (::RegCreateKey(HKEY_CLASSES_ROOT, szKey, &hkeyClassID) !=
- ERROR_SUCCESS)
- goto Error;
- LPCTSTR rglpszSymbols[2];
- rglpszSymbols[0] = strTypeName;
- rglpszSymbols[1] = strPathName;
- bSuccess = AfxOleRegisterHelper(_afxPropPageClass, rglpszSymbols,
- 2, TRUE, hkeyClassID);
- if (!bSuccess)
- goto Error;
- if (nRegFlags & afxRegApartmentThreading)
- {
- HKEY hkeyInprocServer32;
- bSuccess = (::RegOpenKey(hkeyClassID, INPROCSERVER,
- &hkeyInprocServer32) == ERROR_SUCCESS);
- if (!bSuccess)
- goto Error;
- ASSERT(hkeyInprocServer32 != NULL);
- static TCHAR szApartment[] = _T("Apartment");
- bSuccess = (::RegSetValueEx(hkeyInprocServer32, _T("ThreadingModel"), 0,
- REG_SZ, (const BYTE*)szApartment, (lstrlen(szApartment)+1) * sizeof(TCHAR)) ==
- ERROR_SUCCESS);
- ::RegCloseKey(hkeyInprocServer32);
- }
- Error:
- if (hkeyClassID != NULL)
- ::RegCloseKey(hkeyClassID);
- return bSuccess;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Force any extra compiler-generated code into AFX_INIT_SEG
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
|