Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

505 lines
12 KiB

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 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'
#define ERROR_BADKEY_WIN16 2 // needed when running on Win32s
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)
{
DWORD dwIndex = 0L;
TCHAR szSubKeyName[256];
HKEY hCurrentKey;
DWORD dwResult;
if ((dwResult = RegOpenKey(hParentKey, szKeyName, &hCurrentKey)) ==
ERROR_SUCCESS)
{
// Remove all subkeys of the key to delete
while ((dwResult = RegEnumKey(hCurrentKey, 0, szSubKeyName, 255)) ==
ERROR_SUCCESS)
{
if ((dwResult = _AfxRecursiveRegDeleteKey(hCurrentKey,
szSubKeyName)) != ERROR_SUCCESS)
break;
}
// If all went well, we should now be able to delete the requested key
if ((dwResult == ERROR_NO_MORE_ITEMS) || (dwResult == ERROR_BADKEY) ||
(dwResult == ERROR_BADKEY_WIN16))
{
dwResult = RegDeleteKey(hParentKey, szKeyName);
}
}
RegCloseKey(hCurrentKey);
return dwResult;
}
BOOL AFXAPI AfxOleRegisterTypeLib(HINSTANCE hInstance, REFGUID tlid,
LPCTSTR pszFileName, LPCTSTR pszHelpDir)
{
USES_CONVERSION;
BOOL bSuccess = FALSE;
CString strPathName;
::GetModuleFileName(hInstance, strPathName.GetBuffer(_MAX_PATH),
_MAX_PATH);
strPathName.ReleaseBuffer();
// 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;
}
LPTYPELIB ptlib = NULL;
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)
{
USES_CONVERSION;
// 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 ((_tcsicmp(szLocale, _T("HELPDIR")) == 0) ||
(_tcsicmp(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);
return _AfxRegDeleteKeySucceeded(error);
}
static const LPCTSTR rglpszCtrlProgID[] =
{
_T("\0") _T("%1"),
_T("CLSID\0") _T("%2"),
NULL
};
static const LPCTSTR rglpszCtrlClassID[] =
{
_T("\0") _T("%1"),
_T("ProgID\0") _T("%2"),
_T("InprocServer32\0") _T("%3"),
_T("ToolboxBitmap32\0") _T("%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 szKey[_MAX_PATH];
wsprintf(szKey, _T("CLSID\\%s"), lpszClassID);
if (::RegCreateKey(HKEY_CLASSES_ROOT, szKey, &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(rglpszCtrlProgID, 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(rglpszCtrlClassID, 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);
}
Error:
if (hkeyProgID != NULL)
::RegCloseKey(hkeyProgID);
if (hkeyClassID != NULL)
::RegCloseKey(hkeyClassID);
return bSuccess;
}
#define INPROCSERVER _T("InprocServer32")
#define INPROCSERVER_2 _T("InprocServer")
#define TOOLBOXBITMAP _T("ToolboxBitmap32")
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];
// 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;
long error;
BOOL bRetCode = TRUE;
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;
}
static const LPCTSTR rglpszPropPageClass[] =
{
_T("\0") _T("%1"),
_T("InprocServer32\0") _T("%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
UNUSED(nRegFlags);
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(rglpszPropPageClass, rglpszSymbols,
2, TRUE, hkeyClassID);
if (!bSuccess)
goto Error;
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