503 lines
12 KiB
C++
503 lines
12 KiB
C++
|
||
|
||
// Microsoft Windows
|
||
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
||
|
||
// File: selfreg.cxx
|
||
|
||
// Contents: Taken from Office96
|
||
// Source file for the common self registration code used by all the
|
||
// sub projects of Sweeper project. They are
|
||
// UrlMon
|
||
// UrlMnPrx
|
||
|
||
// Exports: HrDllRegisterServer()
|
||
// HrDllUnregisterServer()
|
||
|
||
// Classes:
|
||
|
||
// Functions:
|
||
|
||
// History: 5-03-96 JohannP (Johann Posch) Created
|
||
|
||
|
||
#include <eapp.h>
|
||
|
||
HINSTANCE g_hinstDll = NULL;
|
||
PFNLOADSTRING g_pfnLoadString = NULL;
|
||
|
||
|
||
|
||
// Function: GetDllFullPath
|
||
|
||
// Synopsis:
|
||
|
||
// Arguments: [lpszExeName] --
|
||
// [cch] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
BOOL GetDllFullPath( LPSTR lpszExeName, DWORD cch )
|
||
{
|
||
if ( NULL == g_hinstDll )
|
||
{
|
||
EProtAssert(( FALSE && "NULL hInst"));
|
||
return FALSE;
|
||
}
|
||
|
||
*lpszExeName = NULL;
|
||
|
||
if ( GetModuleFileName( g_hinstDll, lpszExeName, cch ) == 0)
|
||
{
|
||
EProtAssert(( FALSE && "GetModuleFileName Failed"));
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
inline BOOL IsASeparator( char ch )
|
||
{
|
||
return (ch == '\\' || ch == '/' || ch == ':');
|
||
}
|
||
|
||
|
||
|
||
// Function: ParseAFileName
|
||
|
||
// Synopsis:
|
||
|
||
// Arguments: [szFileName] --
|
||
// [piRetLen] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
LPSTR ParseAFileName( LPSTR szFileName, int *piRetLen)
|
||
{
|
||
LPSTR pszFile;
|
||
|
||
// Start at the end of the filename.
|
||
pszFile = szFileName + ( lstrlen(szFileName) - 1 );
|
||
|
||
// Back up to a '\\' or beginning or something!! We just want a file
|
||
// name!. Whatever comes first.
|
||
while ( pszFile > szFileName && !IsASeparator(*pszFile ) )
|
||
pszFile = CharPrev(szFileName, pszFile);
|
||
|
||
if ( pszFile != szFileName )
|
||
pszFile = CharNext(pszFile);
|
||
|
||
if ( piRetLen )
|
||
*piRetLen = lstrlen(pszFile);
|
||
|
||
return pszFile;
|
||
}
|
||
|
||
|
||
|
||
|
||
// Function: FRegisterEntries
|
||
|
||
// Synopsis: FRegisterEntries: Register a group of reg entries off a base key.
|
||
|
||
// Arguments: [hkRoot] --
|
||
// [rgEntries] --
|
||
// [dwEntries] --
|
||
// [pszPath] --
|
||
// [pszBinderName] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
BOOL FRegisterEntries(HKEY hkRoot, const REGENTRY rgEntries[],
|
||
DWORD dwEntries, char *pszPath, char *pszBinderName)
|
||
{
|
||
HKEY hkey = NULL;
|
||
LONG lRet;
|
||
char szValue[1024];
|
||
char szResString[1024];
|
||
char szKeyName[1024];
|
||
BOOL fRet = FALSE;
|
||
int i;
|
||
|
||
for (i = 0; i < (int)dwEntries; i++)
|
||
{
|
||
// We work with a copy of the entry, since we might modify it
|
||
REGENTRY reCurrentEntry = rgEntries[i];
|
||
|
||
if (reCurrentEntry.iKeyType == KEYTYPE_RESID)
|
||
{
|
||
int cch;
|
||
if (g_pfnLoadString == NULL)
|
||
return FALSE;
|
||
cch = g_pfnLoadString(g_hinstDll, (UINT)reCurrentEntry.pszKey, szKeyName,
|
||
sizeof(szKeyName));
|
||
if (cch > 0 && cch <= 1024)
|
||
{
|
||
reCurrentEntry.pszKey = szKeyName;
|
||
}
|
||
else
|
||
{
|
||
EProtAssert(( FALSE && "LoadString Failed ( 1)"));
|
||
continue;
|
||
}
|
||
}
|
||
|
||
lRet = RegCreateKey(hkRoot, reCurrentEntry.pszKey, &hkey);
|
||
|
||
if (lRet != ERROR_SUCCESS)
|
||
{
|
||
EProtAssert(( FALSE && "RegCreateKey Failed ( 1)"));
|
||
continue;
|
||
}
|
||
|
||
// If the type is REG_RESID, then pbData holds the resource ID. We
|
||
// load the resource string, then modify our reCurrentEntry to point
|
||
// to it.
|
||
|
||
if (reCurrentEntry.dwType == REG_RESID)
|
||
{
|
||
int cch;
|
||
if (g_pfnLoadString == NULL)
|
||
return FALSE;
|
||
|
||
cch = g_pfnLoadString(g_hinstDll, (UINT)reCurrentEntry.pbData, szResString,
|
||
sizeof(szResString));
|
||
if (cch > 0 && cch <= 1024)
|
||
{
|
||
reCurrentEntry.dwType = REG_SZ;
|
||
reCurrentEntry.pbData = (BYTE*) szResString;
|
||
}
|
||
else
|
||
{
|
||
EProtAssert(( FALSE && "LoadString Failed (2)"));
|
||
reCurrentEntry.pbData = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
// Set the value if there is one
|
||
if (reCurrentEntry.pbData != NULL || reCurrentEntry.dwType != REG_SZ)
|
||
{
|
||
switch (reCurrentEntry.dwType)
|
||
{
|
||
case REG_SZ:
|
||
// Replace the first %s with the path, and the second
|
||
// %s with the name of the binder app (may not do anything).
|
||
if (pszPath != NULL && pszBinderName != NULL)
|
||
{
|
||
wsprintf(szValue, (char*)reCurrentEntry.pbData, pszPath,
|
||
pszBinderName);
|
||
|
||
lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0,
|
||
REG_SZ, (BYTE*)szValue, lstrlen(szValue)+1);
|
||
#if DBG == 1
|
||
if ( ERROR_SUCCESS != lRet )
|
||
EProtAssert(( FALSE && "RegSetValueEx Failed ( 1)"));
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
case REG_DWORD:
|
||
lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0,
|
||
REG_DWORD, (BYTE*)&reCurrentEntry.pbData, sizeof(DWORD));
|
||
|
||
#if DBG == 1
|
||
if ( ERROR_SUCCESS != lRet )
|
||
EProtAssert(( FALSE && "RegSetValueEx Failed (2)"));
|
||
#endif
|
||
break;
|
||
|
||
default:
|
||
EProtAssert(( FALSE && "Unexpected reg entry type"));
|
||
// Unexpected type: ignore
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Close the subkey
|
||
RegCloseKey(hkey);
|
||
hkey = NULL;
|
||
}
|
||
|
||
fRet = TRUE;
|
||
|
||
// Close the base key if it was open
|
||
if (hkey)
|
||
RegCloseKey(hkey);
|
||
|
||
return fRet;
|
||
}
|
||
|
||
|
||
/*
|
||
* FRegisterEntryGroups: Register several groups of reg entries.
|
||
*/
|
||
BOOL FRegisterEntryGroups(const REGENTRYGROUP *rgRegEntryGroups,
|
||
char *pszPath, char *pszBinderName)
|
||
{
|
||
BOOL fError = FALSE;
|
||
int i;
|
||
|
||
// Keep going even if we get some errors
|
||
for (i=0; rgRegEntryGroups[i].hkRoot != NULL; i++)
|
||
{
|
||
if (!FRegisterEntries(rgRegEntryGroups[i].hkRoot, rgRegEntryGroups[i].rgEntries,
|
||
rgRegEntryGroups[i].dwEntries,pszPath, pszBinderName))
|
||
{
|
||
fError = TRUE;
|
||
}
|
||
}
|
||
|
||
return !fError;
|
||
}
|
||
|
||
|
||
|
||
// Function: FDeleteEntries
|
||
|
||
// Synopsis: Delete a group of reg entries off a base key.
|
||
|
||
// Arguments: [hkRoot] --
|
||
// [rgEntries] --
|
||
// [dwEntries] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
BOOL FDeleteEntries(HKEY hkRoot, const REGENTRY rgEntries[], DWORD dwEntries)
|
||
{
|
||
LONG lRet;
|
||
int i;
|
||
char szKeyName[1024];
|
||
PSTR pKey;
|
||
|
||
// Delete in reverse order, to kill children before parent
|
||
for (i = (int)dwEntries - 1; i >= 0; i--)
|
||
{
|
||
pKey = NULL;
|
||
|
||
if (rgEntries[i].iKeyType == KEYTYPE_RESID)
|
||
{
|
||
int cch;
|
||
cch = g_pfnLoadString(g_hinstDll, (UINT)rgEntries[i].pszKey, szKeyName,
|
||
sizeof(szKeyName));
|
||
if (cch > 0 && cch <= 1024)
|
||
{
|
||
pKey = szKeyName;
|
||
}
|
||
else
|
||
{
|
||
EProtAssert(( FALSE && "LoadString Failed (FDeleteEntries)"));
|
||
continue;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( KEYTYPE_STRING != rgEntries[i].iKeyType )
|
||
{
|
||
EProtAssert(( FALSE && "Unknown Key Type"));
|
||
continue;
|
||
}
|
||
pKey = rgEntries[i].pszKey;
|
||
}
|
||
|
||
if (pKey != NULL)
|
||
{
|
||
// Delete the current key if it has no subkeys.
|
||
// Ignore the return value.
|
||
lRet = RegDeleteKey(hkRoot, pKey);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
// Function: FDeleteEntryGroups
|
||
|
||
// Synopsis: Delete the base keys of all the given groups.
|
||
|
||
|
||
// Arguments: [rgRegEntryGroups] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
BOOL FDeleteEntryGroups(const REGENTRYGROUP *rgRegEntryGroups)
|
||
{
|
||
BOOL fError = FALSE;
|
||
|
||
// Keep going even if we get some errors
|
||
for (int i=0; rgRegEntryGroups[i].hkRoot != NULL; i++)
|
||
{
|
||
if (!FDeleteEntries(rgRegEntryGroups[i].hkRoot,
|
||
rgRegEntryGroups[i].rgEntries,
|
||
rgRegEntryGroups[i].dwEntries))
|
||
{
|
||
fError = TRUE;
|
||
}
|
||
}
|
||
|
||
return !fError;
|
||
}
|
||
|
||
|
||
#ifdef NOT_USED
|
||
/*
|
||
* FDeleteSubtree - Delete given key and all subkeys
|
||
*/
|
||
BOOL FDeleteSubtree(HKEY hkRoot, char *pszKey)
|
||
{
|
||
HKEY hkey = NULL;
|
||
LONG lRet;
|
||
char szSubKey[MAX_PATH];
|
||
|
||
lRet = RegOpenKey(hkRoot, pszKey, &hkey);
|
||
if (lRet != ERROR_SUCCESS)
|
||
goto End;
|
||
|
||
// remove all subkeys
|
||
for (;;)
|
||
{
|
||
lRet = RegEnumKey(hkey, 0, szSubKey, sizeof szSubKey);
|
||
|
||
if (lRet == ERROR_NO_MORE_ITEMS)
|
||
break;
|
||
|
||
if (lRet != ERROR_SUCCESS)
|
||
goto End;
|
||
|
||
if (!FDeleteSubtree(hkey, szSubKey))
|
||
goto End;
|
||
}
|
||
|
||
End:
|
||
if (hkey != NULL)
|
||
RegCloseKey (hkey);
|
||
|
||
lRet = RegDeleteKey(hkRoot, pszKey);
|
||
|
||
return (lRet == ERROR_SUCCESS);
|
||
}
|
||
#endif // NOT_USED
|
||
|
||
|
||
|
||
|
||
|
||
// Function: HrDllRegisterServer
|
||
|
||
// Synopsis: registers an entrygroup
|
||
|
||
// Arguments: [HINSTANCE] --
|
||
// [hinstDll] --
|
||
// [pfnLoadString] --
|
||
// [pszAppName] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
HRESULT HrDllRegisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll,
|
||
PFNLOADSTRING pfnLoadString, char *pszAppName)
|
||
{
|
||
// REVIEW: for Windows dll, do we want to register full path?
|
||
BOOL fRet = TRUE;
|
||
char szFullPath[MAX_PATH];
|
||
char szFileName[MAX_PATH];
|
||
char *pszFileName;
|
||
|
||
g_hinstDll = hinstDll;
|
||
if ((g_pfnLoadString = pfnLoadString) == NULL)
|
||
// set the pointer to windows LoadString() api
|
||
g_pfnLoadString = (PFNLOADSTRING) LoadString;
|
||
|
||
if (!GetDllFullPath(szFullPath, MAX_PATH))
|
||
return E_FAIL;
|
||
|
||
pszFileName = ParseAFileName(szFullPath, NULL);
|
||
|
||
if (pszAppName != NULL)
|
||
lstrcpy(szFileName, pszAppName);
|
||
else
|
||
lstrcpy(szFileName, pszFileName);
|
||
|
||
// Terminate the path at the file name
|
||
*pszFileName = '\0';
|
||
fRet = FRegisterEntryGroups(rgRegEntryGroups, szFullPath, szFileName);
|
||
|
||
g_hinstDll = NULL;
|
||
g_pfnLoadString = NULL;
|
||
return fRet ? NOERROR : E_FAIL;
|
||
}
|
||
|
||
|
||
|
||
// Function: HrDllUnregisterServer
|
||
|
||
// Synopsis: unregisters an entrygroup
|
||
|
||
// Arguments: [HINSTANCE] --
|
||
// [hinstDll] --
|
||
// [pfnLoadString] --
|
||
|
||
// Returns:
|
||
|
||
// History: 95 OfficeXX created
|
||
// 5-03-96 JohannP (Johann Posch) port urlmon
|
||
|
||
// Notes:
|
||
|
||
|
||
HRESULT HrDllUnregisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll, PFNLOADSTRING pfnLoadString)
|
||
{
|
||
g_hinstDll = hinstDll;
|
||
if ((g_pfnLoadString = pfnLoadString) == NULL)
|
||
// set the pointer to windows LoadString() api
|
||
g_pfnLoadString = (PFNLOADSTRING) LoadString;
|
||
|
||
FDeleteEntryGroups(rgRegEntryGroups);
|
||
|
||
g_hinstDll = NULL;
|
||
g_pfnLoadString = NULL;
|
||
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
|
||
|