home *** CD-ROM | disk | FTP | other *** search
- // 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
-