Source code of Windows XP (NT5)
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.

496 lines
12 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. #include "admincfg.h"
  6. #include "regstr.h"
  7. BOOL InitSettingData(TABLEENTRY * pTableEntry,SETTINGDATA *pSettingData);
  8. HGLOBAL AllocateUser(CHAR * szName,DWORD dwType);
  9. VOID RemoveDeletedUser(USERHDR * pUserHdr);
  10. USERHDR * pDeletedUserList = NULL;
  11. UINT nDeletedUserCount = 0;
  12. /*******************************************************************
  13. NAME: AddUser
  14. SYNOPSIS: Allocates a user and adds it to the list control.
  15. ********************************************************************/
  16. HGLOBAL AddUser(HWND hwndList,CHAR * szName,DWORD dwType)
  17. {
  18. HGLOBAL hUser;
  19. LV_ITEM lvi;
  20. UINT uStrID=0;
  21. if (!(hUser = AllocateUser(szName,dwType))) return NULL;
  22. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
  23. lvi.iItem = 0;
  24. lvi.iSubItem = 0;
  25. lvi.state = 0;
  26. lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  27. lvi.pszText = szName;
  28. lvi.cchTextMax = lstrlen(szName)+1;
  29. lvi.iImage = GetUserImageIndex(dwType);
  30. lvi.lParam = (LPARAM) hUser;
  31. if (dwAppState & AS_POLICYFILE) {
  32. // if a "default user/default workstation" entry exists, init the new
  33. // user/computer with that data
  34. switch (dwType & UT_MASK) {
  35. case UT_USER:
  36. uStrID = IDS_DEFAULTUSER;
  37. break;
  38. case UT_MACHINE:
  39. uStrID = IDS_DEFAULTCOMPUTER;
  40. break;
  41. }
  42. if (uStrID) {
  43. LV_FINDINFO lvfi;
  44. CHAR szDefaultName[USERNAMELEN+1];
  45. int iSel=-1;
  46. HGLOBAL hDefaultUser;
  47. USERDATA * pUserData;
  48. BOOL fFound=FALSE;
  49. LoadSz(uStrID,szDefaultName,sizeof(szDefaultName));
  50. lvfi.flags = LVFI_STRING | LVFI_NOCASE;
  51. lvfi.psz = szDefaultName;
  52. while (!fFound && (iSel=ListView_FindItem(hwndUser,iSel,&lvfi)) >= 0) {
  53. hDefaultUser=(HGLOBAL) LongToHandle(ListView_GetItemParm(hwndUser,iSel));
  54. if (hDefaultUser && (pUserData = (USERDATA *)
  55. GlobalLock(hDefaultUser))) {
  56. if ( (pUserData->hdr.dwType & UT_MASK) == dwType)
  57. fFound = TRUE;
  58. GlobalUnlock(hDefaultUser);
  59. }
  60. }
  61. // copy default user data to new user
  62. if (fFound)
  63. CopyUser(hDefaultUser,hUser);
  64. }
  65. }
  66. if (ListView_InsertItem(hwndList,&lvi) < 0) {
  67. FreeUser(hUser);
  68. return NULL;
  69. }
  70. return hUser;
  71. }
  72. /*******************************************************************
  73. NAME: AllocateUser
  74. SYNOPSIS: Allocates memory for user information and initializes
  75. the data area
  76. ********************************************************************/
  77. HGLOBAL AllocateUser(CHAR * szName,DWORD dwType)
  78. {
  79. HGLOBAL hMem;
  80. USERDATA * pUserData;
  81. DWORD dwNeeded;
  82. TABLEENTRY * pTableEntry;
  83. dwNeeded = sizeof(USERDATA) + sizeof(SETTINGDATA) *
  84. ( (dwType & UT_USER) ? gClassList.nUserDataItems :
  85. gClassList.nMachineDataItems );
  86. if (!(hMem=GlobalAlloc(GHND,dwNeeded))) return NULL;
  87. if (!(pUserData = (USERDATA *) GlobalLock(hMem))) {
  88. GlobalFree(hMem);
  89. return NULL;
  90. }
  91. // init the data structure
  92. pUserData->dwSize = dwNeeded;
  93. pUserData->hdr.dwType = dwType;
  94. pUserData->nSettings = ( (dwType & UT_USER)
  95. ? gClassList.nUserDataItems : gClassList.nMachineDataItems );
  96. lstrcpy(pUserData->hdr.szName,szName);
  97. pTableEntry = ( ( dwType & UT_USER ) ? gClassList.pUserCategoryList :
  98. gClassList.pMachineCategoryList);
  99. if (!InitSettingData(pTableEntry,pUserData->SettingData)) {
  100. GlobalUnlock(hMem);
  101. GlobalFree(hMem);
  102. return NULL;
  103. }
  104. // remove this user from the deleted list, if it's on it
  105. RemoveDeletedUser(&pUserData->hdr);
  106. GlobalUnlock(hMem);
  107. return hMem;
  108. }
  109. /*******************************************************************
  110. NAME: CloneUser
  111. SYNOPSIS: Clones the specified user by allocating a duplicate buffer,
  112. copying the data to the 2nd buffer and storing a handle to
  113. the new buffer in the original. This is so the initial state
  114. of a user can be preserved so we can do non-destructive saves.
  115. ********************************************************************/
  116. BOOL CloneUser(HGLOBAL hUser)
  117. {
  118. USERDATA * pUserData = (USERDATA *) GlobalLock(hUser);
  119. USERDATA * pUserDataClone;
  120. HGLOBAL hUserClone;
  121. if (!pUserData) return FALSE;
  122. // free existing clone if there is one
  123. if (pUserData->hClone) {
  124. GlobalFree(pUserData->hClone);
  125. pUserData->hClone = NULL;
  126. }
  127. hUserClone = GlobalAlloc(GHND,pUserData->dwSize);
  128. if (!hUserClone || !(pUserDataClone = (USERDATA *) GlobalLock(hUserClone))) {
  129. if (hUserClone)
  130. GlobalFree(hUserClone);
  131. GlobalUnlock(hUser);
  132. return FALSE;
  133. }
  134. // copy the user data to clone and save handle to clone in original user
  135. memcpy (pUserDataClone,pUserData,pUserData->dwSize);
  136. pUserData->hClone = hUserClone;
  137. GlobalUnlock(hUser);
  138. GlobalUnlock(hUserClone);
  139. return TRUE;
  140. }
  141. BOOL CopyUser(HGLOBAL hUserSrc,HGLOBAL hUserDst)
  142. {
  143. BOOL fRet=FALSE;
  144. USERDATA * pUserDataSrc = NULL,* pUserDataDst = NULL;
  145. HGLOBAL hCloneDst;
  146. USERHDR UserhdrDst;
  147. if (!(pUserDataSrc = (USERDATA *) GlobalLock(hUserSrc)) ||
  148. !(pUserDataDst = (USERDATA *) GlobalLock(hUserDst))) {
  149. goto cleanup;
  150. }
  151. // save destination user header & clone handle.. don't want to overwrite
  152. // this stuff
  153. UserhdrDst = pUserDataDst->hdr;
  154. hCloneDst = pUserDataDst->hClone;
  155. // resize buffer if necessary
  156. if (pUserDataDst->dwSize != pUserDataSrc->dwSize) {
  157. if (!(pUserDataDst = (USERDATA *) ResizeBuffer((CHAR *) pUserDataDst,
  158. hUserDst,pUserDataSrc->dwSize,&pUserDataDst->dwSize))) {
  159. goto cleanup;
  160. }
  161. }
  162. // copy src to dest
  163. memcpy(pUserDataDst,pUserDataSrc,pUserDataSrc->dwSize);
  164. fRet = TRUE;
  165. // put the destination user's old header & clone handle back in the
  166. // user data
  167. pUserDataDst->hClone = hCloneDst;
  168. pUserDataDst->hdr = UserhdrDst;
  169. cleanup:
  170. if (pUserDataSrc)
  171. GlobalUnlock(hUserSrc);
  172. if (pUserDataDst)
  173. GlobalUnlock(hUserDst);
  174. return fRet;
  175. }
  176. /*******************************************************************
  177. NAME: InitSettingData
  178. SYNOPSIS: Walks a template tree and initializes user's data buffer
  179. according to template tree
  180. NOTES: Sets checkboxes to "indeterminate", puts default text
  181. in data buffer, etc.
  182. ********************************************************************/
  183. BOOL InitSettingData(TABLEENTRY * pTableEntry,SETTINGDATA *pSettingData)
  184. {
  185. while (pTableEntry) {
  186. if (pTableEntry->pChild &&
  187. !InitSettingData(pTableEntry->pChild,pSettingData))
  188. return FALSE;
  189. if (pTableEntry->dwType == ETYPE_POLICY) {
  190. pSettingData[ ( (POLICY *) pTableEntry)->uDataIndex].dwType =
  191. pTableEntry->dwType;
  192. pSettingData[ ( (POLICY *) pTableEntry)->uDataIndex].uData
  193. = (dwAppState & AS_POLICYFILE ? IMG_INDETERMINATE :
  194. IMG_UNCHECKED);
  195. } else if ((pTableEntry->dwType & ETYPE_MASK) == ETYPE_SETTING) {
  196. SETTINGS * pSetting = (SETTINGS *) pTableEntry;
  197. pSettingData[pSetting->uDataIndex].dwType =
  198. pTableEntry->dwType;
  199. switch (pTableEntry->dwType & STYPE_MASK) {
  200. case STYPE_EDITTEXT:
  201. case STYPE_COMBOBOX:
  202. if (pSetting->dwFlags & DF_USEDEFAULT) {
  203. pSettingData[pSetting->uDataIndex].uData =
  204. INIT_WITH_DEFAULT;
  205. break;
  206. case STYPE_CHECKBOX:
  207. pSettingData[pSetting->uDataIndex].uData =
  208. ( (pSetting->dwFlags & DF_USEDEFAULT) ? 1 : 0);
  209. break;
  210. case STYPE_NUMERIC:
  211. pSettingData[pSetting->uDataIndex].uData =
  212. ( (pSetting->dwFlags & DF_USEDEFAULT) ?
  213. (((NUMERICINFO *) GETOBJECTDATAPTR(pSetting)))
  214. ->uDefValue : NO_VALUE);
  215. break;
  216. case STYPE_DROPDOWNLIST:
  217. pSettingData[pSetting->uDataIndex].uData =
  218. ( (pSetting->dwFlags & DF_USEDEFAULT) ?
  219. (((DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting)))
  220. ->uDefaultItemIndex : NO_VALUE);
  221. break;
  222. }
  223. }
  224. }
  225. pTableEntry = pTableEntry->pNext;
  226. }
  227. return TRUE;
  228. }
  229. /*******************************************************************
  230. NAME: FreeUser
  231. SYNOPSIS: Frees a user buffer. If it has a clone, frees the clone too.
  232. ********************************************************************/
  233. BOOL FreeUser(HGLOBAL hUser)
  234. {
  235. USERDATA * pUserData;
  236. // free user's clone if one exists
  237. if (pUserData = (USERDATA *) GlobalLock(hUser)) {
  238. if (pUserData->hClone) {
  239. if (GlobalFlags(pUserData->hClone))
  240. GlobalUnlock(pUserData->hClone);
  241. GlobalFree(pUserData->hClone);
  242. }
  243. GlobalUnlock(hUser);
  244. }
  245. if (GlobalFlags(hUser))
  246. GlobalUnlock(hUser);
  247. GlobalFree(hUser);
  248. return TRUE;
  249. }
  250. BOOL RemoveAllUsers(HWND hwndList)
  251. {
  252. UINT nIndex,nCount = ListView_GetItemCount(hwndList);
  253. for (nIndex=0;nIndex<nCount;nIndex++)
  254. RemoveUser(hwndList,0,FALSE);
  255. #ifdef INCL_GROUP_SUPPORT
  256. FreeGroupPriorityList();
  257. #endif
  258. return TRUE;
  259. }
  260. BOOL RemoveUser(HWND hwndList,UINT nIndex,BOOL fMarkDeleted)
  261. {
  262. HGLOBAL hUser;
  263. hUser = (HGLOBAL) LongToHandle(ListView_GetItemParm(hwndList,nIndex));
  264. if (!hUser) return FALSE;
  265. if (fMarkDeleted) {
  266. USERHDR UserHdr;
  267. if (!GetUserHeader(hUser,&UserHdr))
  268. return FALSE;
  269. if (!AddDeletedUser(&UserHdr))
  270. return FALSE;
  271. }
  272. FreeUser(hUser);
  273. ListView_DeleteItem(hwndList,nIndex);
  274. return TRUE;
  275. }
  276. BOOL SortUsers(VOID)
  277. {
  278. ListView_Arrange(hwndUser,LVA_SORTASCENDING);
  279. return TRUE;
  280. }
  281. BOOL AddDefaultUsers(HWND hwndList)
  282. {
  283. if (!AddUser(hwndList,LoadSz(IDS_DEFAULTUSER,szSmallBuf,sizeof(szSmallBuf)),
  284. UT_USER)) return FALSE;
  285. if (!AddUser(hwndList,LoadSz(IDS_DEFAULTCOMPUTER,szSmallBuf,sizeof(szSmallBuf)),
  286. UT_MACHINE)) return FALSE;
  287. return TRUE;
  288. }
  289. BOOL GetUserHeader(HGLOBAL hUser,USERHDR * pUserHdr)
  290. {
  291. USERDATA * pUserData;
  292. if (!(pUserData = (USERDATA *) GlobalLock(hUser)))
  293. return FALSE;
  294. *pUserHdr = pUserData->hdr;
  295. GlobalUnlock(hUser);
  296. return TRUE;
  297. }
  298. UINT GetUserImageIndex(DWORD dwUserType)
  299. {
  300. return ( (dwUserType & UT_USER ?
  301. ( (dwUserType & UF_GROUP) ? IMG_USERS : IMG_USER) :
  302. (dwUserType & UF_GROUP) ? IMG_MACHINES : IMG_MACHINE ) );
  303. }
  304. // when a user is deleted from the main window, we can't just delete it from
  305. // the file right away, so add the user to a list of people we've deleted.
  306. // If/when the user saves, we'll commit the changes and delete them from the
  307. // file.
  308. BOOL AddDeletedUser(USERHDR * pUserHdr)
  309. {
  310. USERHDR * pTemp;
  311. // alloc/realloc buffer to hold copy of the user header
  312. if (!pDeletedUserList) {
  313. pDeletedUserList = (USERHDR *) GlobalAlloc(GPTR,sizeof(USERHDR));
  314. if (!pDeletedUserList)
  315. return FALSE; // out of memory
  316. } else {
  317. pTemp = (USERHDR *) GlobalReAlloc((HGLOBAL) pDeletedUserList,
  318. sizeof(USERHDR) * (nDeletedUserCount + 1),GMEM_ZEROINIT | GMEM_MOVEABLE);
  319. if (!pTemp) return FALSE;
  320. pDeletedUserList = pTemp;
  321. }
  322. pDeletedUserList[nDeletedUserCount] = *pUserHdr;
  323. nDeletedUserCount++;
  324. return TRUE;
  325. }
  326. USERHDR * GetDeletedUser(UINT nIndex)
  327. {
  328. if (!pDeletedUserList || nIndex >= nDeletedUserCount)
  329. return NULL;
  330. return &pDeletedUserList[nIndex];
  331. }
  332. // when adding a user, check to see if it's on the deleted list
  333. // and if so remove it. (ex: add "joe", remove "joe", add "joe".
  334. // on 2nd add, have to remove "joe" from deleted list)
  335. VOID RemoveDeletedUser(USERHDR * pUserHdr)
  336. {
  337. UINT nIndex;
  338. for (nIndex=0;nIndex<nDeletedUserCount;nIndex++) {
  339. // got a match?
  340. if (!lstrcmpi(pDeletedUserList[nIndex].szName,
  341. pUserHdr->szName) && (pDeletedUserList[nIndex].dwType ==
  342. pUserHdr->dwType)) {
  343. // move subsequent entries up one slot in the array
  344. nDeletedUserCount --;
  345. while (nIndex<nDeletedUserCount) {
  346. pDeletedUserList[nIndex] = pDeletedUserList[nIndex+1];
  347. nIndex++;
  348. }
  349. }
  350. }
  351. }
  352. VOID ClearDeletedUserList(VOID)
  353. {
  354. if (pDeletedUserList)
  355. GlobalFree(pDeletedUserList);
  356. pDeletedUserList = NULL;
  357. nDeletedUserCount = 0;
  358. }
  359. // maps the localized default entries in resource ("default user",
  360. // "default computer") to hard-coded non-localized name (".default").
  361. // Other names are unchanged (szMappedName returned same as szUserName)
  362. VOID MapUserName(CHAR * szUserName,CHAR * szMappedName)
  363. {
  364. if (!lstrcmpi(szUserName,LoadSz(IDS_DEFAULTUSER,szSmallBuf,
  365. sizeof(szSmallBuf))) ||
  366. !lstrcmpi(szUserName,LoadSz(IDS_DEFAULTCOMPUTER,szSmallBuf,
  367. sizeof(szSmallBuf)))) {
  368. lstrcpy(szMappedName,szDEFAULTENTRY);
  369. }
  370. else lstrcpy(szMappedName,szUserName);
  371. }
  372. // unmaps the ".default" hard-coded entry to the localized text
  373. // "default user" or "default computer"
  374. VOID UnmapUserName(CHAR * szMappedName,CHAR * szUserName,BOOL fUser)
  375. {
  376. if (!lstrcmpi(szMappedName,szDEFAULTENTRY)) {
  377. lstrcpy(szUserName,LoadSz( (fUser ? IDS_DEFAULTUSER :
  378. IDS_DEFAULTCOMPUTER),szSmallBuf,sizeof(szSmallBuf)));
  379. } else {
  380. lstrcpy(szUserName,szMappedName);
  381. }
  382. }