|
|
//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1993 **
//*********************************************************************
#include "admincfg.h"
UINT LoadUsersFromKey(HWND hwndList,HKEY hkeyRoot,TABLEENTRY * pTableEntry, DWORD dwType); UINT LoadOneEntry(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD *pdwFoundSettings); UINT LoadUserData(USERDATA ** ppUserData,HGLOBAL hTable,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD *pdwFoundSettings); UINT LoadPolicy(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser); UINT LoadSettings(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD *pdwFoundSettings); UINT LoadListboxData(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD * pdwFound); BOOL ReadStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, TABLEENTRY * pTableEntry,DWORD * pdwData,DWORD * pdwFound); BOOL ReadCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, TCHAR * pszValue,UINT cbValue,DWORD * pdwValue,DWORD * pdwFlags); BOOL CompareCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, STATEVALUE * pStateValue,DWORD * pdwFound);
// flags for detected settings
#define FS_PRESENT 0x0001
#define FS_DELETED 0x0002
/*******************************************************************
NAME: LoadFile
SYNOPSIS: Loads the specified policy file
********************************************************************/ BOOL LoadFile(TCHAR * pszFilename,HWND hwndApp,HWND hwndList,BOOL fDisplayErrors) { HKEY hkeyMain=NULL,hkeyUser=NULL,hkeyWorkstation=NULL,hkeyGroup=NULL,hkeyGroupPriority=NULL; UINT uRet; OFSTRUCT of; HCURSOR hOldCursor; HFILE hFile; of.cBytes = sizeof(of);
hOldCursor=SetCursor(LoadCursor(NULL,IDC_WAIT));
// RegLoadKey returns totally coarse error codes, so first do
// an open file on the file to get a sane error message if there's
// a problem
hFile = OpenFile(pszFilename,&of,OF_EXIST);
if (hFile == HFILE_ERROR) { SetCursor(hOldCursor); if (fDisplayErrors) DisplayStandardError(hwndApp,pszFilename,IDS_ErrREGERR_LOADKEY1, of.nErrCode); return FALSE; }
// Not needed. This will raise an exception.
// _lclose (hFile);
// load the hive file
if ((uRet = MyRegLoadKey(HKEY_LOCAL_MACHINE,szTMPDATA,pszFilename)) != ERROR_SUCCESS) { SetCursor(hOldCursor); if (fDisplayErrors) DisplayStandardError(hwndApp,pszFilename,IDS_ErrREGERR_LOADKEY1,uRet); return FALSE; }
// read information from local registry
if ( (RegOpenKey(HKEY_LOCAL_MACHINE,szTMPDATA,&hkeyMain) != ERROR_SUCCESS) || (RegOpenKey(hkeyMain,szUSERS,&hkeyUser) != ERROR_SUCCESS) || (RegOpenKey(hkeyMain,szWORKSTATIONS,&hkeyWorkstation) != ERROR_SUCCESS)) { SetCursor(hOldCursor);
if (fDisplayErrors) MsgBoxParam(hwndApp,IDS_ErrINVALIDPOLICYFILE,pszFilename, MB_ICONEXCLAMATION,MB_OK);
if (hkeyWorkstation) RegCloseKey(hkeyWorkstation); if (hkeyUser) RegCloseKey(hkeyUser); if (hkeyMain) RegCloseKey(hkeyMain); MyRegUnLoadKey(HKEY_LOCAL_MACHINE,szTMPDATA);
return FALSE; }
// if we fail to open these two keys no big deal, these are optional keys.
// HKEYs are checked below before we use them
RegOpenKey(hkeyMain,szUSERGROUPS,&hkeyGroup); RegOpenKey(hkeyMain,szUSERGROUPDATA,&hkeyGroupPriority);
// load users
if ((uRet = LoadUsersFromKey(hwndList,hkeyUser,gClassList.pUserCategoryList, UT_USER)) != ERROR_SUCCESS) goto cleanup; // load workstations
if ((uRet = LoadUsersFromKey(hwndList,hkeyWorkstation,gClassList.pMachineCategoryList, UT_MACHINE)) != ERROR_SUCCESS) goto cleanup;
#ifdef INCL_GROUP_SUPPORT
// load groups
if (hkeyGroupPriority && hkeyGroup) { if ((uRet = LoadGroupPriorityList(hkeyGroupPriority,hkeyGroup)) != ERROR_SUCCESS) goto cleanup;
if (uRet = LoadUsersFromKey(hwndList,hkeyGroup,gClassList.pUserCategoryList, UT_USER | UF_GROUP) != ERROR_SUCCESS) goto cleanup; } #endif
uRet = ERROR_SUCCESS; cleanup: RegCloseKey(hkeyUser); RegCloseKey(hkeyWorkstation); RegCloseKey(hkeyMain); if (hkeyGroup) RegCloseKey(hkeyGroup); if (hkeyGroupPriority) RegCloseKey(hkeyGroupPriority); MyRegUnLoadKey(HKEY_LOCAL_MACHINE,szTMPDATA); SetFileAttributes(pszFilename,FILE_ATTRIBUTE_ARCHIVE); ClearDeletedUserList(); SetCursor(hOldCursor);
if (uRet != ERROR_SUCCESS && fDisplayErrors) { if (uRet == ERROR_NOT_ENOUGH_MEMORY) { MsgBox(hwndApp,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK); } else { TCHAR szFmt[REGBUFLEN],szMsg[REGBUFLEN+MAX_PATH+1]; LoadSz(IDS_ErrREGERR_LOADKEY,szFmt,ARRAYSIZE(szFmt)); wsprintf(szMsg,szFmt,pszFilename,uRet); MsgBoxSz(hwndApp,szMsg,MB_ICONEXCLAMATION,MB_OK); } // remove any users that might have gotten loaded
RemoveAllUsers(hwndList); }
return (uRet == ERROR_SUCCESS); }
/*******************************************************************
NAME: LoadFromRegistry
SYNOPSIS: Loads policies from the registry
NOTES: Errors will be displayed if fDisplayErrors is TRUE.
********************************************************************/ BOOL LoadFromRegistry(HWND hwndApp,HWND hwndList,BOOL fDisplayErrors) { HKEY hkeyUser=NULL,hkeyWorkstation=NULL; UINT uRet = ERROR_SUCCESS; HGLOBAL hUser,hWorkstation; USERDATA * pUserData=NULL,* pWorkstationData=NULL; HCURSOR hOldCursor;
if ((RegOpenKeyEx(hkeyVirtHCU,NULL,0,KEY_ALL_ACCESS,&hkeyUser) != ERROR_SUCCESS) || (RegOpenKeyEx(hkeyVirtHLM,NULL,0,KEY_ALL_ACCESS,&hkeyWorkstation) != ERROR_SUCCESS)) { if (fDisplayErrors) MsgBox(hwndApp,IDS_ErrCANTOPENREGISTRY,MB_ICONEXCLAMATION,MB_OK); if (hkeyUser) RegCloseKey(hkeyUser); if (hkeyWorkstation) RegCloseKey(hkeyWorkstation); return FALSE; }
hUser = AddUser(hwndList,LoadSz(IDS_LOCALUSER,szSmallBuf,ARRAYSIZE(szSmallBuf)) ,UT_USER); hWorkstation = AddUser(hwndList,LoadSz(IDS_LOCALCOMPUTER,szSmallBuf, ARRAYSIZE(szSmallBuf)),UT_MACHINE);
if (!hUser || !hWorkstation || !(pUserData = (USERDATA *) GlobalLock(hUser)) || !(pWorkstationData = (USERDATA *) GlobalLock(hWorkstation)) ) { uRet = ERROR_NOT_ENOUGH_MEMORY; }
hOldCursor=SetCursor(LoadCursor(NULL,IDC_WAIT));
if (uRet == ERROR_SUCCESS) uRet = LoadUserData(&pUserData,gClassList.pUserCategoryList,hkeyUser,NULL, hUser,NULL); if (uRet == ERROR_SUCCESS) uRet = LoadUserData(&pWorkstationData,gClassList.pMachineCategoryList, hkeyWorkstation,NULL,hWorkstation,NULL);
RegCloseKey(hkeyUser); RegCloseKey(hkeyWorkstation); GlobalUnlock(hUser); GlobalUnlock(hWorkstation);
SetCursor(hOldCursor);
if (uRet != ERROR_SUCCESS) { if (uRet == ERROR_NOT_ENOUGH_MEMORY) { if (fDisplayErrors) MsgBox(hwndApp,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK); } else { TCHAR szMsg[REGBUFLEN+1]; wsprintf(szMsg,TEXT("%lu"),uRet); if (fDisplayErrors) MsgBoxParam(hwndApp,IDS_ErrREGERR_LOAD,szMsg,MB_ICONEXCLAMATION,MB_OK); }
RemoveAllUsers(hwndList); return FALSE; } ClearDeletedUserList();
return TRUE; }
UINT LoadUsersFromKey(HWND hwndList,HKEY hkeyRoot,TABLEENTRY * pTableEntry, DWORD dwType) { TCHAR szKeyName[MAX_PATH+1]; UINT uRet,nIndex=0; HGLOBAL hUser; USERDATA * pUserData; HKEY hKey; TCHAR szUnmappedName[MAXNAMELEN+1];
do { // enumerate the subkeys, which will be user/workstation names
if ((uRet=RegEnumKey(hkeyRoot,nIndex,szKeyName,ARRAYSIZE(szKeyName))) == ERROR_SUCCESS) {
// open the subkey
if ((uRet = RegOpenKey(hkeyRoot,szKeyName,&hKey)) != ERROR_SUCCESS) return uRet;
// allocate this user and add to list control
UnmapUserName(szKeyName,szUnmappedName,(BOOL) (dwType & UT_USER)); hUser = AddUser(hwndList,szUnmappedName,dwType); if ( !hUser || !(pUserData = (USERDATA *) GlobalLock(hUser))) { RegCloseKey(hKey); return ERROR_NOT_ENOUGH_MEMORY; }
// load user data into user's buffer
uRet=LoadUserData(&pUserData,pTableEntry,hKey,NULL,hUser,NULL);
#ifdef INCL_GROUP_SUPPORT
// add group name to bottom of priority list. The group name
// should already be somewhere on priority list because we loaded
// the list earlier, but this will add the group name to the bottom
// of the list if it's not on the list already. Adds extra robustness
// in the face of god-knows-whose-app creating flaky policy files.
if (dwType == (UT_USER | UF_GROUP)) AddGroupPriEntry(szUnmappedName); #endif
RegCloseKey(hKey); GlobalUnlock(hUser);
// make a copy of the initial state of each user, so on
// a save we only have to save the deltas. We need to only
// save the deltas, because saves have to be non-destructive--
// we can't clean the user's tree out and start over because
// there might be stuff in there we don't know about.
CloneUser(hUser);
if (uRet != ERROR_SUCCESS) return uRet; }
nIndex++; } while (uRet == ERROR_SUCCESS);
// end of enum will report ERROR_NO_MORE_ITEMS, don't report this as error
if (uRet == ERROR_NO_MORE_ITEMS) uRet = ERROR_SUCCESS;
return uRet; }
UINT LoadUserData(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD *pdwFoundSettings) { UINT uRet=ERROR_SUCCESS;
while (pTableEntry && (uRet == ERROR_SUCCESS)) {
uRet = LoadOneEntry(ppUserData,pTableEntry,hkeyRoot, pszCurrentKeyName,hUser,pdwFoundSettings);
pTableEntry = pTableEntry->pNext; }
return uRet; }
UINT LoadOneEntry(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD *pdwFoundSettings) { UINT uRet;
#if 0
wsprintf(szDebugOut,TEXT("LoadOneEntry: %s\r\n"),GETNAMEPTR(pTableEntry)); OutputDebugString(szDebugOut); #endif
// if there is a key name for this entry, it becomes the "current"
// key name-- it will be overridden if child entries specify their
// own keys, otherwise it's the default key for children to use
if (pTableEntry->uOffsetKeyName) { pszCurrentKeyName = GETKEYNAMEPTR(pTableEntry); }
if ((pTableEntry->dwType == ETYPE_CATEGORY || pTableEntry->dwType == ETYPE_ROOT) && (pTableEntry->pChild)) {
// if entry is a category, recusively process sub-categories and policies
if ((uRet=LoadUserData(ppUserData,pTableEntry->pChild, hkeyRoot,pszCurrentKeyName,hUser,pdwFoundSettings)) != ERROR_SUCCESS) { return uRet; } } else if (pTableEntry->dwType == ETYPE_POLICY) {
if ((uRet = LoadPolicy(ppUserData,pTableEntry,hkeyRoot, pszCurrentKeyName,hUser)) != ERROR_SUCCESS) { return uRet; }
} else if ( (pTableEntry->dwType & ETYPE_MASK) == ETYPE_SETTING && !(pTableEntry->dwType & STYPE_TEXT)) {
if ((uRet = LoadSettings(ppUserData,pTableEntry,hkeyRoot, pszCurrentKeyName,hUser,pdwFoundSettings)) != ERROR_SUCCESS) { return uRet; } }
return ERROR_SUCCESS; }
UINT LoadPolicy(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser) { DWORD dwData=0; UINT uRet; TCHAR * pszValueName; DWORD dwFoundSettings=0; BOOL fHasPolicySwitch=FALSE; BOOL fFound=FALSE,fCustomOn=FALSE,fCustomOff=FALSE;
// get the name of the value to read, if any
if (((POLICY *) pTableEntry)->uOffsetValueName) { fHasPolicySwitch = TRUE;
pszValueName = GETVALUENAMEPTR(((POLICY *) pTableEntry));
// first look for custom on/off values
if (((POLICY *) pTableEntry)->uOffsetValue_On) { fCustomOn = TRUE; if (CompareCustomValue(hkeyRoot,pszCurrentKeyName,pszValueName, (STATEVALUE *) ((TCHAR *) pTableEntry + ((POLICY *) pTableEntry)->uOffsetValue_On),&dwFoundSettings)) { dwData = 1; fFound = TRUE; } }
if (!fFound && ((POLICY *) pTableEntry)->uOffsetValue_Off) { fCustomOff = TRUE; if (CompareCustomValue(hkeyRoot,pszCurrentKeyName,pszValueName, (STATEVALUE *) ((TCHAR *) pTableEntry + ((POLICY *) pTableEntry)->uOffsetValue_Off),&dwFoundSettings)) { dwData = 0; fFound = TRUE; } }
// look for standard values if custom values have not been specified
if (!fCustomOn && !fCustomOff && ReadStandardValue(hkeyRoot,pszCurrentKeyName,pszValueName, pTableEntry,&dwData,&dwFoundSettings)) { fFound = TRUE; }
if (fFound) { // store data in user's buffer
(*ppUserData)->SettingData[((POLICY *) pTableEntry)->uDataIndex].uData = (dwData ? IMG_CHECKED : IMG_UNCHECKED); } }
dwFoundSettings = 0; // process settings underneath this policy (if any)
if (pTableEntry->pChild && (dwData || !fHasPolicySwitch)) { if ((uRet=LoadUserData(ppUserData,pTableEntry->pChild,hkeyRoot, pszCurrentKeyName,hUser,&dwFoundSettings)) !=ERROR_SUCCESS) { return uRet; } }
if (!fHasPolicySwitch) { // store data in user's buffer
if (dwFoundSettings) { (*ppUserData)->SettingData[((POLICY *) pTableEntry)->uDataIndex].uData = (dwFoundSettings & FS_PRESENT ? IMG_CHECKED : IMG_UNCHECKED); } }
return ERROR_SUCCESS; }
UINT LoadSettings(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD * pdwFound) { UINT uRet = ERROR_SUCCESS; TCHAR * pszValueName = NULL; DWORD dwData,dwFlags,dwFoundSettings=0; TCHAR szData[MAXSTRLEN]; BOOL fCustomOn=FALSE,fCustomOff=FALSE,fFound=FALSE; TCHAR * pObjectData = GETOBJECTDATAPTR(((SETTINGS *)pTableEntry)); TCHAR szNewValueName[MAX_PATH+1];
// get the name of the value to read
if (((SETTINGS *) pTableEntry)->uOffsetValueName) { pszValueName = GETVALUENAMEPTR(((SETTINGS *) pTableEntry)); } else return ERROR_NOT_ENOUGH_MEMORY;
switch (pTableEntry->dwType & STYPE_MASK) {
case STYPE_EDITTEXT: case STYPE_COMBOBOX:
dwFlags = ( (SETTINGS *) pTableEntry)->dwFlags;
// add prefixes if appropriate
PrependValueName(pszValueName,dwFlags, szNewValueName,ARRAYSIZE(szNewValueName));
if ((uRet = ReadRegistryStringValue(hkeyRoot,pszCurrentKeyName, szNewValueName,szData,ARRAYSIZE(szData) * sizeof(TCHAR))) == ERROR_SUCCESS) {
GlobalUnlock(hUser); if (!SetVariableLengthData(hUser,((SETTINGS *) pTableEntry)->uDataIndex,szData,lstrlen(szData)+1)) { return ERROR_NOT_ENOUGH_MEMORY; } if (!((*ppUserData) = (USERDATA *) GlobalLock(hUser))) return ERROR_NOT_ENOUGH_MEMORY;
// set flag that we found setting in registry/policy file
if (pdwFound) *pdwFound |= FS_PRESENT; } else if ((dwAppState & AS_POLICYFILE) && !(dwFlags & VF_DELETE)) { // see if this key is marked as deleted
PrependValueName(pszValueName,VF_DELETE, szNewValueName,ARRAYSIZE(szNewValueName)); if ((uRet = ReadRegistryStringValue(hkeyRoot,pszCurrentKeyName, szNewValueName,szData,ARRAYSIZE(szData) * sizeof(TCHAR))) == ERROR_SUCCESS) { // set flag that we found setting marked as deleted in
// policy file
if (pdwFound) *pdwFound |= FS_DELETED; } }
return ERROR_SUCCESS; break;
case STYPE_CHECKBOX:
// first look for custom on/off values
if (((CHECKBOXINFO *) pObjectData)->uOffsetValue_On) { fCustomOn = TRUE; if (CompareCustomValue(hkeyRoot,pszCurrentKeyName,pszValueName, (STATEVALUE *) ((TCHAR *) pTableEntry + ((CHECKBOXINFO *) pObjectData)->uOffsetValue_On),&dwFoundSettings)) { dwData = 1; fFound = TRUE; } }
if (!fFound && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off) { fCustomOff = TRUE; if (CompareCustomValue(hkeyRoot,pszCurrentKeyName,pszValueName, (STATEVALUE *) ((TCHAR *) pTableEntry + ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off),&dwFoundSettings)) { dwData = 0; fFound = TRUE; } }
// look for standard values if custom values have not been specified
if (!fFound && ReadStandardValue(hkeyRoot,pszCurrentKeyName,pszValueName, pTableEntry,&dwData,&dwFoundSettings)) { fFound = TRUE; }
if (fFound) { (*ppUserData)->SettingData[((SETTINGS *) pTableEntry)->uDataIndex].uData = dwData;
// set flag that we found setting in registry
if (pdwFound) *pdwFound |= dwFoundSettings; }
return ERROR_SUCCESS; break;
case STYPE_NUMERIC:
if (ReadStandardValue(hkeyRoot,pszCurrentKeyName,pszValueName, pTableEntry,&dwData,&dwFoundSettings)) {
(*ppUserData)->SettingData[((SETTINGS *) pTableEntry)->uDataIndex].uData = dwData;
// set flag that we found setting in registry
if (pdwFound) *pdwFound |= dwFoundSettings; } break;
case STYPE_DROPDOWNLIST:
if (ReadCustomValue(hkeyRoot,pszCurrentKeyName,pszValueName, szData,ARRAYSIZE(szData) * sizeof(TCHAR),&dwData,&dwFlags)) { BOOL fMatch = FALSE;
if ((dwAppState & AS_POLICYFILE) && (dwFlags & VF_DELETE)) { // set flag that we found setting marked as deleted
// in policy file
if (pdwFound) *pdwFound |= FS_DELETED; return ERROR_SUCCESS; }
// walk the list of DROPDOWNINFO structs (one for each state),
// and see if the value we found matches the value for the state
if ( ((SETTINGS *) pTableEntry)->uOffsetObjectData) { DROPDOWNINFO * pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR( ((SETTINGS *) pTableEntry)); UINT nIndex = 0; do { if (dwFlags == pddi->dwFlags) { if (pddi->dwFlags & VF_ISNUMERIC) { if (dwData == pddi->dwValue) fMatch = TRUE; } else if (!pddi->dwFlags) { if (!lstrcmpi(szData,(TCHAR *) pTableEntry + pddi->uOffsetValue)) fMatch = TRUE; } }
if (!pddi->uOffsetNextDropdowninfo || fMatch) break;
pddi = (DROPDOWNINFO *) ( (TCHAR *) pTableEntry + pddi->uOffsetNextDropdowninfo); nIndex++;
} while (!fMatch);
if (fMatch) { (*ppUserData)->SettingData[((SETTINGS *) pTableEntry)->uDataIndex].uData = nIndex;
// set flag that we found setting in registry
if (pdwFound) *pdwFound |= FS_PRESENT; } } }
break;
case STYPE_LISTBOX:
return LoadListboxData(ppUserData,pTableEntry,hkeyRoot, pszCurrentKeyName,hUser,pdwFound);
break; }
return ERROR_SUCCESS; }
/*******************************************************************
NAME: ReadCustomValue
SYNOPSIS: For specified keyname and value name, retrieve the value (if there is one).
NOTES: fills in pszValue if value is REG_SZ, fills in *pdwValue if value is REG_DWORD (and sets VF_ISNUMERIC). Sets VF_DELETE if value is marked for deletion.
********************************************************************/ BOOL ReadCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, TCHAR * pszValue,UINT cbValue,DWORD * pdwValue,DWORD * pdwFlags) { HKEY hKey; DWORD dwType,dwSize=cbValue * sizeof(TCHAR); BOOL fSuccess = FALSE; TCHAR szNewValueName[MAX_PATH+1];
*( (DWORD *)pszValue) = *pdwValue=0;
if (RegOpenKey(hkeyRoot,pszKeyName,&hKey) == ERROR_SUCCESS) { if (RegQueryValueEx(hKey,pszValueName,NULL,&dwType,(LPBYTE) pszValue, &dwSize) == ERROR_SUCCESS) {
if (dwType == REG_SZ) { // value returned in pszValueName
*pdwFlags = 0; fSuccess = TRUE; } else if (dwType == REG_DWORD || dwType == REG_BINARY) { // copy value to *pdwValue
memcpy(pdwValue,pszValue,sizeof(DWORD)); *pdwFlags = VF_ISNUMERIC; fSuccess = TRUE; }
} else { // see if this is a value that's marked for deletion
// (valuename is prepended with "**del."
PrependValueName(pszValueName,VF_DELETE, szNewValueName,ARRAYSIZE(szNewValueName));
if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue, &dwSize) == ERROR_SUCCESS) { fSuccess=TRUE; *pdwFlags = VF_DELETE; } else { // see if this is a soft value
// (valuename is prepended with "**soft."
PrependValueName(pszValueName,VF_SOFT, szNewValueName,ARRAYSIZE(szNewValueName));
if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue, &dwSize) == ERROR_SUCCESS) { fSuccess=TRUE; *pdwFlags = VF_SOFT; } } }
RegCloseKey(hKey); }
return fSuccess; }
BOOL CompareCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, STATEVALUE * pStateValue,DWORD * pdwFound) { TCHAR szValue[MAXSTRLEN]; DWORD dwValue; TCHAR szNewValueName[MAX_PATH+1];
// add prefixes if appropriate
PrependValueName(pszValueName,pStateValue->dwFlags, szNewValueName,ARRAYSIZE(szNewValueName));
if (pStateValue->dwFlags & VF_ISNUMERIC) { if ((ReadRegistryDWordValue(hkeyRoot,pszKeyName, szNewValueName,&dwValue) == ERROR_SUCCESS) && dwValue == pStateValue->dwValue) { *pdwFound = FS_PRESENT; return TRUE; } } else if (pStateValue->dwFlags & VF_DELETE) {
if (dwAppState & AS_POLICYFILE) { // see if this is a value that's marked for deletion
// (valuename is prepended with "**del."
if ((ReadRegistryStringValue(hkeyRoot,pszKeyName, szNewValueName,szValue,ARRAYSIZE(szValue) * sizeof(TCHAR))) == ERROR_SUCCESS) { *pdwFound = FS_DELETED; return TRUE; } } else { // return TRUE if value ISN't there...
if (ReadRegistryDWordValue(hkeyRoot,pszKeyName, szNewValueName,&dwValue) != ERROR_SUCCESS) { *pdwFound = FS_DELETED; return TRUE; } } } else { if ((ReadRegistryStringValue(hkeyRoot,pszKeyName, szNewValueName,szValue,ARRAYSIZE(szValue) * sizeof(TCHAR))) == ERROR_SUCCESS && !lstrcmpi(szValue,pStateValue->szValue)) { *pdwFound = FS_PRESENT; return TRUE; } }
return FALSE; }
BOOL ReadStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName, TABLEENTRY * pTableEntry,DWORD * pdwData,DWORD * pdwFound) { UINT uRet; TCHAR szNewValueName[MAX_PATH+1];
// add prefixes if appropriate
PrependValueName(pszValueName,((SETTINGS *) pTableEntry)->dwFlags, szNewValueName,ARRAYSIZE(szNewValueName));
if ( ((SETTINGS *) pTableEntry)->dwFlags & DF_TXTCONVERT) { // read numeric value as text if specified
TCHAR szNum[11]; uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName, szNewValueName,szNum,ARRAYSIZE(szNum) * sizeof(TCHAR)); if (uRet == ERROR_SUCCESS) { StringToNum(szNum,pdwData); *pdwFound = FS_PRESENT; return TRUE; } } else { // read numeric value as binary
uRet = ReadRegistryDWordValue(hkeyRoot,pszKeyName, szNewValueName,pdwData); if (uRet == ERROR_SUCCESS) { *pdwFound = FS_PRESENT; return TRUE; } }
// see if this settings has been marked as 'deleted'
if ((dwAppState & AS_POLICYFILE) && !(dwCmdLineFlags & CLF_DIALOGMODE)) { TCHAR szVal[MAX_PATH+1]; *pdwData = 0; PrependValueName(pszValueName,VF_DELETE,szNewValueName, ARRAYSIZE(szNewValueName)); uRet=ReadRegistryStringValue(hkeyRoot,pszKeyName, szNewValueName,szVal,ARRAYSIZE(szVal) * sizeof(TCHAR)); if (uRet == ERROR_SUCCESS) { *pdwFound = FS_DELETED; return TRUE; } }
return FALSE; }
UINT LoadListboxData(USERDATA ** ppUserData,TABLEENTRY * pTableEntry,HKEY hkeyRoot, TCHAR * pszCurrentKeyName,HGLOBAL hUser,DWORD * pdwFound) { HKEY hKey; UINT nIndex=0,nLen; TCHAR szValueName[MAX_PATH+1],szValueData[MAX_PATH+1]; DWORD cbValueName,cbValueData; DWORD dwType,dwAlloc=1024,dwUsed=0; HGLOBAL hBuf; TCHAR * pBuf; SETTINGS * pSettings = (SETTINGS *) pTableEntry; LISTBOXINFO * pListboxInfo = (LISTBOXINFO *) GETOBJECTDATAPTR(pSettings); BOOL fFoundValues=FALSE,fFoundDelvals=FALSE; UINT uRet=ERROR_SUCCESS;
if (RegOpenKey(hkeyRoot,pszCurrentKeyName,&hKey) != ERROR_SUCCESS) return ERROR_SUCCESS; // nothing to do
// allocate a temp buffer to read entries into
if (!(hBuf = GlobalAlloc(GHND,dwAlloc * sizeof(TCHAR))) || !(pBuf = (TCHAR *) GlobalLock(hBuf))) { if (hBuf) GlobalFree(hBuf); return ERROR_NOT_ENOUGH_MEMORY; }
while (TRUE) { cbValueName=ARRAYSIZE(szValueName); cbValueData=ARRAYSIZE(szValueData) * sizeof(TCHAR); uRet=RegEnumValue(hKey,nIndex,szValueName,&cbValueName,NULL, &dwType,szValueData,&cbValueData); // stop if we're out of items
if (uRet != ERROR_SUCCESS && uRet != ERROR_MORE_DATA) break; nIndex++;
// if valuename prefixed with '**', it's a control code, ignore it
if (szValueName[0] == TEXT('*') && szValueName[1] == TEXT('*')) { // if we found **delvals., then some sort of listbox stuff
// is going on, remember that we found this code
if (!lstrcmpi(szValueName,szDELVALS)) fFoundDelvals = TRUE; continue; }
// only process this item if enum was successful
// (so we'll skip items with weird errors like ERROR_MORE_DATA and
// but keep going with the enum)
if (uRet == ERROR_SUCCESS) { TCHAR * pszData;
// if there's no value name prefix scheme specified (e.g.
// value names are "foo1", "foo2", etc), and the explicit valuename
// flag isn't set where we remember the value name as well as
// the data for every value, then we need the value name to
// be the same as the value data ("thing.exe=thing.exe").
if (!(pSettings->dwFlags & DF_EXPLICITVALNAME) && !(pListboxInfo->uOffsetPrefix) && !(pListboxInfo->uOffsetValue)) { if (dwType != REG_SZ || lstrcmpi(szValueName,szValueData)) continue; // skip this value if val name != val data
}
// if explicit valuenames used, then copy the value name into
// buffer
if (pSettings->dwFlags & DF_EXPLICITVALNAME) { nLen = lstrlen(szValueName) + 1; if (!(pBuf=ResizeBuffer(pBuf,hBuf,dwUsed+nLen+4,&dwAlloc))) return ERROR_NOT_ENOUGH_MEMORY; lstrcpy(pBuf+dwUsed,szValueName); dwUsed += nLen; }
// for default listbox type, value data is the actual "data"
// and value name either will be the same as the data or
// some prefix + "1", "2", etc. If there's a data value to
// write for each entry, then the "data" is the value name
// (e.g. "Larry = foo", "Dave = foo"), etc. If explicit value names
// are turned on, then both the value name and data are stored
// and editable
// copy value data into buffer
if (pListboxInfo->uOffsetValue) { // data value set, use value name for data
pszData = szValueName; } else pszData = szValueData;
nLen = lstrlen(pszData) + 1; if (!(pBuf=ResizeBuffer(pBuf,hBuf,dwUsed+nLen+4,&dwAlloc))) return ERROR_NOT_ENOUGH_MEMORY; lstrcpy(pBuf+dwUsed,pszData); dwUsed += nLen; fFoundValues=TRUE; } }
// doubly null-terminate the buffer... safe to do this because we
// tacked on the extra "+4" in the ResizeBuffer calls above
*(pBuf+dwUsed) = TEXT('\0'); dwUsed++;
uRet = ERROR_SUCCESS;
if (fFoundValues) { // add the value data to user's buffer
GlobalUnlock(hUser); if (!SetVariableLengthData(hUser,((SETTINGS *) pTableEntry)->uDataIndex,pBuf,dwUsed)) { uRet = ERROR_NOT_ENOUGH_MEMORY; } else if (!((*ppUserData) = (USERDATA *) GlobalLock(hUser))) uRet = ERROR_NOT_ENOUGH_MEMORY; // set flag that we found setting in registry/policy file
if (pdwFound) *pdwFound |= FS_PRESENT; } else { if (fFoundDelvals && pdwFound) { *pdwFound |= FS_DELETED; } }
GlobalUnlock(hBuf); GlobalFree(hBuf);
RegCloseKey(hKey);
return uRet; }
|