//********************************************************************* //* Microsoft Windows ** //* Copyright(c) Microsoft Corp., 1994 ** //********************************************************************* #include "admincfg.h" #include "regstr.h" BOOL InitSettingData(TABLEENTRY * pTableEntry,SETTINGDATA *pSettingData); HGLOBAL AllocateUser(CHAR * szName,DWORD dwType); VOID RemoveDeletedUser(USERHDR * pUserHdr); USERHDR * pDeletedUserList = NULL; UINT nDeletedUserCount = 0; /******************************************************************* NAME: AddUser SYNOPSIS: Allocates a user and adds it to the list control. ********************************************************************/ HGLOBAL AddUser(HWND hwndList,CHAR * szName,DWORD dwType) { HGLOBAL hUser; LV_ITEM lvi; UINT uStrID=0; if (!(hUser = AllocateUser(szName,dwType))) return NULL; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM; lvi.iItem = 0; lvi.iSubItem = 0; lvi.state = 0; lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvi.pszText = szName; lvi.cchTextMax = lstrlen(szName)+1; lvi.iImage = GetUserImageIndex(dwType); lvi.lParam = (LPARAM) hUser; if (dwAppState & AS_POLICYFILE) { // if a "default user/default workstation" entry exists, init the new // user/computer with that data switch (dwType & UT_MASK) { case UT_USER: uStrID = IDS_DEFAULTUSER; break; case UT_MACHINE: uStrID = IDS_DEFAULTCOMPUTER; break; } if (uStrID) { LV_FINDINFO lvfi; CHAR szDefaultName[USERNAMELEN+1]; int iSel=-1; HGLOBAL hDefaultUser; USERDATA * pUserData; BOOL fFound=FALSE; LoadSz(uStrID,szDefaultName,sizeof(szDefaultName)); lvfi.flags = LVFI_STRING | LVFI_NOCASE; lvfi.psz = szDefaultName; while (!fFound && (iSel=ListView_FindItem(hwndUser,iSel,&lvfi)) >= 0) { hDefaultUser=(HGLOBAL) LongToHandle(ListView_GetItemParm(hwndUser,iSel)); if (hDefaultUser && (pUserData = (USERDATA *) GlobalLock(hDefaultUser))) { if ( (pUserData->hdr.dwType & UT_MASK) == dwType) fFound = TRUE; GlobalUnlock(hDefaultUser); } } // copy default user data to new user if (fFound) CopyUser(hDefaultUser,hUser); } } if (ListView_InsertItem(hwndList,&lvi) < 0) { FreeUser(hUser); return NULL; } return hUser; } /******************************************************************* NAME: AllocateUser SYNOPSIS: Allocates memory for user information and initializes the data area ********************************************************************/ HGLOBAL AllocateUser(CHAR * szName,DWORD dwType) { HGLOBAL hMem; USERDATA * pUserData; DWORD dwNeeded; TABLEENTRY * pTableEntry; dwNeeded = sizeof(USERDATA) + sizeof(SETTINGDATA) * ( (dwType & UT_USER) ? gClassList.nUserDataItems : gClassList.nMachineDataItems ); if (!(hMem=GlobalAlloc(GHND,dwNeeded))) return NULL; if (!(pUserData = (USERDATA *) GlobalLock(hMem))) { GlobalFree(hMem); return NULL; } // init the data structure pUserData->dwSize = dwNeeded; pUserData->hdr.dwType = dwType; pUserData->nSettings = ( (dwType & UT_USER) ? gClassList.nUserDataItems : gClassList.nMachineDataItems ); lstrcpy(pUserData->hdr.szName,szName); pTableEntry = ( ( dwType & UT_USER ) ? gClassList.pUserCategoryList : gClassList.pMachineCategoryList); if (!InitSettingData(pTableEntry,pUserData->SettingData)) { GlobalUnlock(hMem); GlobalFree(hMem); return NULL; } // remove this user from the deleted list, if it's on it RemoveDeletedUser(&pUserData->hdr); GlobalUnlock(hMem); return hMem; } /******************************************************************* NAME: CloneUser SYNOPSIS: Clones the specified user by allocating a duplicate buffer, copying the data to the 2nd buffer and storing a handle to the new buffer in the original. This is so the initial state of a user can be preserved so we can do non-destructive saves. ********************************************************************/ BOOL CloneUser(HGLOBAL hUser) { USERDATA * pUserData = (USERDATA *) GlobalLock(hUser); USERDATA * pUserDataClone; HGLOBAL hUserClone; if (!pUserData) return FALSE; // free existing clone if there is one if (pUserData->hClone) { GlobalFree(pUserData->hClone); pUserData->hClone = NULL; } hUserClone = GlobalAlloc(GHND,pUserData->dwSize); if (!hUserClone || !(pUserDataClone = (USERDATA *) GlobalLock(hUserClone))) { if (hUserClone) GlobalFree(hUserClone); GlobalUnlock(hUser); return FALSE; } // copy the user data to clone and save handle to clone in original user memcpy (pUserDataClone,pUserData,pUserData->dwSize); pUserData->hClone = hUserClone; GlobalUnlock(hUser); GlobalUnlock(hUserClone); return TRUE; } BOOL CopyUser(HGLOBAL hUserSrc,HGLOBAL hUserDst) { BOOL fRet=FALSE; USERDATA * pUserDataSrc = NULL,* pUserDataDst = NULL; HGLOBAL hCloneDst; USERHDR UserhdrDst; if (!(pUserDataSrc = (USERDATA *) GlobalLock(hUserSrc)) || !(pUserDataDst = (USERDATA *) GlobalLock(hUserDst))) { goto cleanup; } // save destination user header & clone handle.. don't want to overwrite // this stuff UserhdrDst = pUserDataDst->hdr; hCloneDst = pUserDataDst->hClone; // resize buffer if necessary if (pUserDataDst->dwSize != pUserDataSrc->dwSize) { if (!(pUserDataDst = (USERDATA *) ResizeBuffer((CHAR *) pUserDataDst, hUserDst,pUserDataSrc->dwSize,&pUserDataDst->dwSize))) { goto cleanup; } } // copy src to dest memcpy(pUserDataDst,pUserDataSrc,pUserDataSrc->dwSize); fRet = TRUE; // put the destination user's old header & clone handle back in the // user data pUserDataDst->hClone = hCloneDst; pUserDataDst->hdr = UserhdrDst; cleanup: if (pUserDataSrc) GlobalUnlock(hUserSrc); if (pUserDataDst) GlobalUnlock(hUserDst); return fRet; } /******************************************************************* NAME: InitSettingData SYNOPSIS: Walks a template tree and initializes user's data buffer according to template tree NOTES: Sets checkboxes to "indeterminate", puts default text in data buffer, etc. ********************************************************************/ BOOL InitSettingData(TABLEENTRY * pTableEntry,SETTINGDATA *pSettingData) { while (pTableEntry) { if (pTableEntry->pChild && !InitSettingData(pTableEntry->pChild,pSettingData)) return FALSE; if (pTableEntry->dwType == ETYPE_POLICY) { pSettingData[ ( (POLICY *) pTableEntry)->uDataIndex].dwType = pTableEntry->dwType; pSettingData[ ( (POLICY *) pTableEntry)->uDataIndex].uData = (dwAppState & AS_POLICYFILE ? IMG_INDETERMINATE : IMG_UNCHECKED); } else if ((pTableEntry->dwType & ETYPE_MASK) == ETYPE_SETTING) { SETTINGS * pSetting = (SETTINGS *) pTableEntry; pSettingData[pSetting->uDataIndex].dwType = pTableEntry->dwType; switch (pTableEntry->dwType & STYPE_MASK) { case STYPE_EDITTEXT: case STYPE_COMBOBOX: if (pSetting->dwFlags & DF_USEDEFAULT) { pSettingData[pSetting->uDataIndex].uData = INIT_WITH_DEFAULT; break; case STYPE_CHECKBOX: pSettingData[pSetting->uDataIndex].uData = ( (pSetting->dwFlags & DF_USEDEFAULT) ? 1 : 0); break; case STYPE_NUMERIC: pSettingData[pSetting->uDataIndex].uData = ( (pSetting->dwFlags & DF_USEDEFAULT) ? (((NUMERICINFO *) GETOBJECTDATAPTR(pSetting))) ->uDefValue : NO_VALUE); break; case STYPE_DROPDOWNLIST: pSettingData[pSetting->uDataIndex].uData = ( (pSetting->dwFlags & DF_USEDEFAULT) ? (((DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting))) ->uDefaultItemIndex : NO_VALUE); break; } } } pTableEntry = pTableEntry->pNext; } return TRUE; } /******************************************************************* NAME: FreeUser SYNOPSIS: Frees a user buffer. If it has a clone, frees the clone too. ********************************************************************/ BOOL FreeUser(HGLOBAL hUser) { USERDATA * pUserData; // free user's clone if one exists if (pUserData = (USERDATA *) GlobalLock(hUser)) { if (pUserData->hClone) { if (GlobalFlags(pUserData->hClone)) GlobalUnlock(pUserData->hClone); GlobalFree(pUserData->hClone); } GlobalUnlock(hUser); } if (GlobalFlags(hUser)) GlobalUnlock(hUser); GlobalFree(hUser); return TRUE; } BOOL RemoveAllUsers(HWND hwndList) { UINT nIndex,nCount = ListView_GetItemCount(hwndList); for (nIndex=0;nIndexhdr; GlobalUnlock(hUser); return TRUE; } UINT GetUserImageIndex(DWORD dwUserType) { return ( (dwUserType & UT_USER ? ( (dwUserType & UF_GROUP) ? IMG_USERS : IMG_USER) : (dwUserType & UF_GROUP) ? IMG_MACHINES : IMG_MACHINE ) ); } // when a user is deleted from the main window, we can't just delete it from // the file right away, so add the user to a list of people we've deleted. // If/when the user saves, we'll commit the changes and delete them from the // file. BOOL AddDeletedUser(USERHDR * pUserHdr) { USERHDR * pTemp; // alloc/realloc buffer to hold copy of the user header if (!pDeletedUserList) { pDeletedUserList = (USERHDR *) GlobalAlloc(GPTR,sizeof(USERHDR)); if (!pDeletedUserList) return FALSE; // out of memory } else { pTemp = (USERHDR *) GlobalReAlloc((HGLOBAL) pDeletedUserList, sizeof(USERHDR) * (nDeletedUserCount + 1),GMEM_ZEROINIT | GMEM_MOVEABLE); if (!pTemp) return FALSE; pDeletedUserList = pTemp; } pDeletedUserList[nDeletedUserCount] = *pUserHdr; nDeletedUserCount++; return TRUE; } USERHDR * GetDeletedUser(UINT nIndex) { if (!pDeletedUserList || nIndex >= nDeletedUserCount) return NULL; return &pDeletedUserList[nIndex]; } // when adding a user, check to see if it's on the deleted list // and if so remove it. (ex: add "joe", remove "joe", add "joe". // on 2nd add, have to remove "joe" from deleted list) VOID RemoveDeletedUser(USERHDR * pUserHdr) { UINT nIndex; for (nIndex=0;nIndexszName) && (pDeletedUserList[nIndex].dwType == pUserHdr->dwType)) { // move subsequent entries up one slot in the array nDeletedUserCount --; while (nIndex