Leaked source code of windows server 2003
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.
 
 
 
 
 
 

510 lines
14 KiB

//+---------------------------------------------------------------------------
//
// 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 <mon.h>
#include "selfreg.hxx"
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 )
{
UrlMkAssert(( FALSE && "NULL hInst"));
return FALSE;
}
*lpszExeName = NULL;
if ( GetModuleFileName( g_hinstDll, lpszExeName, cch ) == 0)
{
UrlMkAssert(( 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) PtrToUlong(reCurrentEntry.pszKey), szKeyName,
sizeof(szKeyName));
if (cch > 0 && cch <= 1024)
{
reCurrentEntry.pszKey = szKeyName;
}
else
{
UrlMkAssert(( FALSE && "LoadString Failed ( 1)"));
continue;
}
}
lRet = RegCreateKey(hkRoot, reCurrentEntry.pszKey, &hkey);
if (lRet != ERROR_SUCCESS)
{
UrlMkAssert(( 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) PtrToUlong(reCurrentEntry.pbData), szResString,
sizeof(szResString));
if (cch > 0 && cch <= 1024)
{
reCurrentEntry.dwType = REG_SZ;
reCurrentEntry.pbData = (BYTE*) szResString;
}
else
{
UrlMkAssert(( 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 )
UrlMkAssert(( 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 )
UrlMkAssert(( FALSE && "RegSetValueEx Failed (2)"));
#endif
break;
default:
UrlMkAssert(( 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) PtrToUlong(rgEntries[i].pszKey), szKeyName,
sizeof(szKeyName));
if (cch > 0 && cch <= 1024)
{
pKey = szKeyName;
}
else
{
UrlMkAssert(( FALSE && "LoadString Failed (FDeleteEntries)"));
continue;
}
}
else
{
if ( KEYTYPE_STRING != rgEntries[i].iKeyType )
{
UrlMkAssert(( 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';
#ifdef UNIX
/* On Unix, we find the location of the dll using LD_LIBRARY_PATH
* which is included in the wrapper script
* So, we do not want to specify the whole path for the dll in the
* registry.
*/
*szFullPath = '\0';
#endif /* UNIX */
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;
}