|
|
/*
File uitls.c
A set of utilities useful for upgrading mpr v1 to NT 5.0.
Paul Mayfield, 9/11/97 */
#include "upgrade.h"
#include <rtcfg.h>
#include <mprapip.h>
CONST WCHAR c_szSystemCCSServices[] = L"System\\CurrentControlSet\\Services"; static const WCHAR c_szConfigurationFlags[] = L"ConfigurationFlags"; CONST WCHAR c_szRouter[] = L"RemoteAccess";
//
// Initializes a dword table with given initial count
// and maximum string size;
//
DWORD dwtInitialize( OUT dwt *This, IN DWORD dwCount, IN DWORD dwMaxSize) { DWORD i; if (!This) return ERROR_INVALID_PARAMETER;
// Initialize the structure
ZeroMemory(This, sizeof(dwt)); This->dwCount = 0; This->dwSize = dwCount;
// Allocate the table
This->pValues = (dwValueNode *) UtlAlloc( dwCount * sizeof(dwValueNode)); if (!This->pValues) return ERROR_NOT_ENOUGH_MEMORY; // Allocate all of the name strings
for (i = 0; i < (DWORD)This->dwSize; i++) { This->pValues[i].Name = (PWCHAR) UtlAlloc( dwMaxSize * sizeof(WCHAR)); if (!This->pValues[i].Name) { return ERROR_NOT_ENOUGH_MEMORY; } }
return NO_ERROR; }
//
// Free's resources held by the given dword table.
//
DWORD dwtCleanup( IN dwt * This) { DWORD i; if (!This) { return NO_ERROR; }
for (i = 0; i < (DWORD)This->dwSize; i++) { if (This->pValues[i].Name) { UtlFree(This->pValues[i].Name); } }
if (This->pValues) { UtlFree(This->pValues); } return NO_ERROR; }
//
// Retrieves the given value from the table
//
DWORD dwtGetValue( IN dwt * This, IN PWCHAR ValName, OUT LPDWORD pValue) { DWORD i;
if (!ValName || !pValue) { return ERROR_INVALID_PARAMETER; }
for (i = 0; i < This->dwCount; i++) { if (wcscmp(ValName,This->pValues[i].Name) == 0) { *pValue = This->pValues[i].Value; return NO_ERROR; } }
return ERROR_NOT_FOUND; }
//
// Loads all of the dword values of a given registry
// key into a dword table.
//
DWORD dwtLoadRegistyTable( OUT dwt *This, IN HKEY hkParams) { DWORD dwErr, dwMaxSize, dwSize, dwCount, i; DWORD dwDataSize = sizeof(DWORD), dwType = REG_DWORD;
if (!This) return ERROR_INVALID_PARAMETER;
// Initialize the structure
ZeroMemory(This, sizeof(dwt));
// Find out how many parameters there are.
dwErr = RegQueryInfoKey( hkParams, NULL, NULL, NULL, NULL, NULL, NULL, &dwCount, &dwMaxSize, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) return dwErr;
if (dwCount == 0) { This->dwCount = This->dwSize = 0; return NO_ERROR; } dwMaxSize += 1;
do { // Fill in the table
dwtInitialize(This, dwCount, dwMaxSize); for (i = 0; i < dwCount; i++) { dwSize = dwMaxSize; dwErr = RegEnumValueW( hkParams, i, This->pValues[This->dwCount].Name, &dwSize, 0, &dwType, NULL, NULL); if (dwErr != ERROR_SUCCESS) { break; } if (dwType != REG_DWORD) { continue; }
dwErr = RegQueryValueExW( hkParams, This->pValues[This->dwCount].Name, 0, &dwType, (LPBYTE)&(This->pValues[This->dwCount].Value), &dwDataSize); if (dwErr != ERROR_SUCCESS) { break; } This->dwCount++; } } while (FALSE);
return dwErr; }
DWORD dwtPrint( IN dwt *This) { DWORD i;
if (!This) return ERROR_INVALID_PARAMETER;
return NO_ERROR; }
//
// Enumerates all of the subkeys of a given key
//
DWORD UtlEnumRegistrySubKeys( IN HKEY hkRoot, IN PWCHAR pszPath, IN RegKeyEnumFuncPtr pCallback, IN HANDLE hData) { DWORD dwErr = NO_ERROR, i, dwNameSize = 0, dwCurSize = 0; DWORD dwCount = 0; HKEY hkKey = NULL, hkCurKey = NULL; PWCHAR pszName = NULL; BOOL bCloseKey = FALSE;
do { if (pszPath) { bCloseKey = TRUE; // Open the key to enumerate
//
dwErr = RegOpenKeyExW( hkRoot, pszPath, 0, KEY_ALL_ACCESS, &hkKey); if (dwErr != NO_ERROR) { break; } } else { bCloseKey = FALSE; hkKey = hkRoot; }
// Find out how many sub keys there are
//
dwErr = RegQueryInfoKeyW( hkKey, NULL, NULL, NULL, &dwCount, &dwNameSize, NULL, NULL, NULL, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) { return dwErr; } dwNameSize++;
// Allocate the name buffer
//
pszName = (PWCHAR) UtlAlloc(dwNameSize * sizeof(WCHAR)); if (pszName == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Loop through the keys
//
for (i = 0; i < dwCount; i++) { dwCurSize = dwNameSize; // Get the name of the current key
//
dwErr = RegEnumKeyExW( hkKey, i, pszName, &dwCurSize, 0, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) { continue; }
// Open the subkey
//
dwErr = RegOpenKeyExW( hkKey, pszName, 0, KEY_ALL_ACCESS, &hkCurKey); if (dwErr != ERROR_SUCCESS) { continue; }
// Call the callback
//
dwErr = pCallback(pszName, hkCurKey, hData); RegCloseKey(hkCurKey); if (dwErr != NO_ERROR) { break; } }
} while (FALSE);
// Cleanup
{ if ((hkKey != NULL) && (bCloseKey)) { RegCloseKey(hkKey); } if (pszName) { UtlFree(pszName); } }
return dwErr; }
//
// Enumerates interfaces from the registry
//
DWORD UtlEnumerateInterfaces ( IN IfEnumFuncPtr pCallback, IN HANDLE hUserData) { DWORD dwErr, i, dwIfCount, dwIfTot, dwResume = 0; DWORD dwPrefBufSize = sizeof(MPR_INTERFACE_0) * 100; MPR_INTERFACE_0 * pIfs = NULL; HANDLE hConfig; BOOL bContinue = TRUE;
// Validate parameters
if (pCallback == NULL) return ERROR_INVALID_PARAMETER;
// Connect to the configuration server
dwErr = MprConfigServerConnect(NULL, &hConfig); if (dwErr != NO_ERROR) return dwErr;
// Get list of all interfaces
dwErr = MprConfigInterfaceEnum( hConfig, 0, (LPBYTE*)&pIfs, dwPrefBufSize, &dwIfCount, &dwIfTot, &dwResume); if (dwErr == ERROR_NO_MORE_ITEMS) return NO_ERROR; else if ((dwErr != NO_ERROR) && (dwErr != ERROR_MORE_DATA)) return dwErr;
// Loop through the interfaces
do { // Call the callback for each interface as long
// as we're instructed to continue
for (i = 0; i < dwIfCount; i++) { if (bContinue) { bContinue = (*pCallback)( hConfig, &(pIfs[i]), hUserData); } } if (bContinue == FALSE) break; // Free up the interface list buffer
if (pIfs) MprConfigBufferFree(pIfs); pIfs = NULL;
// Get list of all ip interfaces
dwErr = MprConfigInterfaceEnum( hConfig, 0, (LPBYTE*)&pIfs, dwPrefBufSize, &dwIfCount, &dwIfTot, &dwResume); if (dwErr == ERROR_NO_MORE_ITEMS) { dwErr = NO_ERROR; break; } else if ((dwErr != NO_ERROR) && (dwErr != ERROR_MORE_DATA)) break; else continue; } while (TRUE);
// Cleanup
{ if (pIfs) MprConfigBufferFree(pIfs); if (hConfig) MprConfigServerDisconnect(hConfig); }
return dwErr; }
//
// If the given info blob exists in the given toc header
// reset it with the given information, otherwise add
// it as an entry in the TOC.
//
DWORD UtlUpdateInfoBlock ( IN BOOL bOverwrite, IN LPVOID pHeader, IN DWORD dwEntryId, IN DWORD dwSize, IN DWORD dwCount, IN LPBYTE pEntry, OUT LPVOID* ppNewHeader, OUT LPDWORD lpdwNewSize) { PRTR_INFO_BLOCK_HEADER pNewHeader; DWORD dwErr; // Attempt to find the entry
dwErr = MprInfoBlockFind( pHeader, dwEntryId, NULL, NULL, NULL);
// If we find it, reset it
if (dwErr == NO_ERROR) { if (bOverwrite) { dwErr = MprInfoBlockSet( pHeader, dwEntryId, dwSize, dwCount, pEntry, ppNewHeader); if (dwErr == NO_ERROR) { pNewHeader = (PRTR_INFO_BLOCK_HEADER)(*ppNewHeader); *lpdwNewSize = pNewHeader->Size; } } else { return ERROR_ALREADY_EXISTS; } }
// Otherwise, create it
else if (dwErr == ERROR_NOT_FOUND) { dwErr = MprInfoBlockAdd( pHeader, dwEntryId, dwSize, dwCount, pEntry, ppNewHeader); if (dwErr == NO_ERROR) { pNewHeader = (PRTR_INFO_BLOCK_HEADER)(*ppNewHeader); *lpdwNewSize = pNewHeader->Size; } }
return dwErr; }
// Common allocation routine
PVOID UtlAlloc (DWORD dwSize) { return RtlAllocateHeap (RtlProcessHeap (), 0, dwSize); }
// Common deallocation routine
VOID UtlFree (PVOID pvBuffer) { RtlFreeHeap (RtlProcessHeap (), 0, pvBuffer); }
// Copies a string
//
PWCHAR UtlDupString( IN PWCHAR pszString) { PWCHAR pszRet = NULL;
if ((pszString == NULL) || (*pszString == L'\0')) { return NULL; }
pszRet = (PWCHAR) UtlAlloc((wcslen(pszString) + 1) * sizeof(WCHAR)); if (pszRet == NULL) { return NULL; }
wcscpy(pszRet, pszString); return pszRet; }
// Error reporting
void UtlPrintErr(DWORD err) { WCHAR buf[1024]; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,NULL,err,0,buf,1024,NULL); PrintMessage(buf); PrintMessage(L"\n"); }
//----------------------------------------------------------------------------
// Function: UtlAccessRouterKey
//
// Creates/opens the Router key on HKEY_LOCAL_MACHINE.
//----------------------------------------------------------------------------
DWORD UtlAccessRouterKey(HKEY* hkeyRouter) { LPWSTR lpwsPath; DWORD dwErr, dwSize;
if (!hkeyRouter) return ERROR_INVALID_PARAMETER;
*hkeyRouter = NULL;
//
// compute the length of the string
//
dwSize = lstrlen(c_szSystemCCSServices) + 1 + lstrlen(c_szRouter) + 1;
//
// allocate space for the path
//
lpwsPath = (LPWSTR)UtlAlloc(dwSize * sizeof(WCHAR)); if (!lpwsPath) return ERROR_NOT_ENOUGH_MEMORY;
wsprintf(lpwsPath, L"%s\\%s", c_szSystemCCSServices, c_szRouter);
//
// open the router key
//
dwErr = RegOpenKeyExW( HKEY_LOCAL_MACHINE, lpwsPath, 0, KEY_ALL_ACCESS, hkeyRouter ); if (dwErr!=ERROR_SUCCESS) { PrintMessage(L"ERROR in UtlAccessRouterKey\n"); }
UtlFree(lpwsPath); return dwErr; }
//----------------------------------------------------------------------------
// Function: UtlSetupBackupPrivelege
//
// Enables/disables backup privilege for the current process.
//----------------------------------------------------------------------------
DWORD UtlEnablePrivilege(PWCHAR pszPrivilege, BOOL bEnable) { LUID luid; HANDLE hToken; TOKEN_PRIVILEGES tp;
OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
if (! LookupPrivilegeValueW(NULL, pszPrivilege, &luid)) { return GetLastError(); }
tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (! AdjustTokenPrivileges( hToken, !bEnable, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { return GetLastError(); }
return NO_ERROR; }
DWORD UtlSetupBackupPrivelege(BOOL bEnable) { return UtlEnablePrivilege(SE_BACKUP_NAME, bEnable); }
DWORD UtlSetupRestorePrivilege(BOOL bEnable) { return UtlEnablePrivilege(SE_RESTORE_NAME, bEnable); }
// Loads the given saved off settings into a temporary key
// and returns a handle to that key.
//
DWORD UtlLoadSavedSettings( IN HKEY hkRoot, IN PWCHAR pszTempKey, IN PWCHAR pszFile, OUT HKEY* phkTemp) { HKEY hkRestore = NULL; DWORD dwErr = NO_ERROR, dwDisposition = 0; BOOL bBackup = FALSE, bRestore = FALSE;
do { // Enable the backup and restore priveleges
//
bBackup = (UtlSetupBackupPrivelege (TRUE) == NO_ERROR); bRestore = (UtlSetupRestorePrivilege(TRUE) == NO_ERROR); if (!bBackup || !bRestore) { return ERROR_CAN_NOT_COMPLETE; }
// Create a temporary key into which the saved config
// can be loaded.
//
if ((dwErr = RegCreateKeyExW( hkRoot, pszTempKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkRestore, &dwDisposition)) != NO_ERROR) { PrintMessage(L"Unable to create restore key.\n"); break; }
// Load the saved configuration
//
dwErr = RegRestoreKey(hkRestore, pszFile, 0); if (dwErr != ERROR_SUCCESS) { break; }
// Assign the return value
//
*phkTemp = hkRestore;
} while (FALSE);
// Cleanup
{ if (bBackup) { UtlSetupBackupPrivelege(FALSE); } if (bRestore) { UtlSetupRestorePrivilege(FALSE); } } return NO_ERROR; }
//
// Delete the tree of registry values starting at hkRoot
//
DWORD UtlDeleteRegistryTree( IN HKEY hkRoot) { DWORD dwErr, dwCount, dwNameSize, dwDisposition; DWORD i, dwCurNameSize; PWCHAR pszNameBuf; HKEY hkTemp; // Find out how many keys there are in the source
dwErr = RegQueryInfoKey ( hkRoot, NULL, NULL, NULL, &dwCount, &dwNameSize, NULL, NULL, NULL, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) return dwErr; dwNameSize++;
__try { // Allocate the buffers
pszNameBuf = (PWCHAR) UtlAlloc(dwNameSize * sizeof(WCHAR)); if (!pszNameBuf) return ERROR_NOT_ENOUGH_MEMORY;
// Loop through the keys -- deleting all subkey trees
for (i = 0; i < dwCount; i++) { dwCurNameSize = dwNameSize;
// Get the current source key
dwErr = RegEnumKeyExW( hkRoot, i, pszNameBuf, &dwCurNameSize, 0, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) continue;
// Open the subkey
dwErr = RegCreateKeyExW( hkRoot, pszNameBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkTemp, &dwDisposition); if (dwErr != ERROR_SUCCESS) continue;
// Delete the subkey tree
UtlDeleteRegistryTree(hkTemp);
// Close the temp handle
RegCloseKey(hkTemp); }
// Loop through the keys -- deleting all subkeys themselves
for (i = 0; i < dwCount; i++) { dwCurNameSize = dwNameSize;
// Get the current source key
dwErr = RegEnumKeyExW( hkRoot, 0, pszNameBuf, &dwCurNameSize, 0, NULL, NULL, NULL); if (dwErr != ERROR_SUCCESS) continue;
// Delete the subkey tree
dwErr = RegDeleteKey(hkRoot, pszNameBuf); } } __finally { if (pszNameBuf) UtlFree(pszNameBuf); }
return NO_ERROR; }
DWORD UtlMarkRouterConfigured() { DWORD dwErr, dwVal; HKEY hkRouter = NULL;
dwErr = UtlAccessRouterKey(&hkRouter); if (dwErr == NO_ERROR) { dwVal = 1; RegSetValueEx( hkRouter, c_szConfigurationFlags, 0, REG_DWORD, (CONST BYTE*)&dwVal, sizeof(DWORD)); RegCloseKey(hkRouter); } return dwErr; }
|