6 #include <WINNT/afsapplib.h>
7 #include "al_dynlink.h"
8 #include <WINNT/TaAfsAdmSvrClient.h>
12 * DEFINITIONS ________________________________________________________________
16 #define cxICON 19 // size of an ACL entry icon
18 #define cyICON 16 // size of an ACL entry icon
20 #define clrTRANSPARENT RGB(0,255,0) // background color on ACL entry icons
24 * BROWSE DIALOG ______________________________________________________________
28 typedef struct BROWSEDIALOGPARAMS {
29 TCHAR szCell[ cchRESOURCE ];
30 TCHAR szNamed[ cchRESOURCE ];
34 BROWSETYPE bt; // for what entry type do we browse?
38 BOOL fCanStopThreadEasily;
39 BOOL fShouldStopThread;
41 TCHAR szThreadCell[ cchRESOURCE ];
49 } BROWSEDIALOGPARAMS, *LPBROWSEDIALOGPARAMS;
52 BOOL CALLBACK DlgProc_Browse (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
53 void DlgProc_Browse_OnInitDialog (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
54 void DlgProc_Browse_OnNone (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
55 void DlgProc_Browse_SelectedEntry (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
56 void DlgProc_Browse_UpdateCellText (BROWSEDIALOGPARAMS *pbdp, LPTSTR pszCell);
58 BOOL DlgProc_Browse_StartSearch (BROWSEDIALOGPARAMS *pbdp, BOOL fCloseDlgIfFail);
59 void DlgProc_Browse_StopSearch (BROWSEDIALOGPARAMS *pbdp);
60 DWORD _stdcall DlgProc_Browse_ThreadProc (LPARAM lp);
62 void EnumeratePrincipalsRemotely (LPBROWSEDIALOGPARAMS pbdp, DWORD idClient);
63 void EnumeratePrincipalsLocally (LPBROWSEDIALOGPARAMS pbdp);
69 * This function presents a dialog which allows the user to select a user
70 * or group from a list.
74 BOOL AfsAppLib_ShowBrowseDialog (LPBROWSEDLG_PARAMS lpp)
76 BROWSEDIALOGPARAMS *pbdp;
79 if ((pbdp = New (BROWSEDIALOGPARAMS)) != NULL)
81 memset (pbdp, 0x00, sizeof(BROWSEDIALOGPARAMS));
82 lstrcpy (pbdp->szNamed, lpp->szNamed);
83 lstrcpy (pbdp->szCell, lpp->szCell);
84 pbdp->lpcl = lpp->lpcl;
86 pbdp->idsTitle = lpp->idsTitle;
87 pbdp->idsPrompt = lpp->idsPrompt;
88 pbdp->idsNone = lpp->idsNone;
89 pbdp->hCreds = lpp->hCreds;
95 pbdp->fThisCellOnly = TRUE;
100 pbdp->fThisCellOnly = FALSE;
104 if (ModalDialogParam (IDD_APPLIB_BROWSE, lpp->hParent, (DLGPROC)DlgProc_Browse, (LPARAM)pbdp) == IDOK)
106 lstrcpy (lpp->szCell, pbdp->szCell);
107 lstrcpy (lpp->szNamed, pbdp->szNamed);
121 * This is the dialog proc for the Browse Cell dialog.
125 #define WM_FOUNDNAME (WM_USER +100)
126 #define WM_THREADSTART (WM_USER +101)
127 #define WM_THREADDONE (WM_USER +102)
129 BOOL CALLBACK DlgProc_Browse (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
131 BROWSEDIALOGPARAMS *pbdp;
133 if (AfsAppLib_HandleHelp (IDD_APPLIB_BROWSE, hDlg, msg, wp, lp))
138 if (msg == WM_INITDIALOG)
140 SetWindowLong (hDlg, DWL_USER, lp);
143 if ((pbdp = (BROWSEDIALOGPARAMS *)GetWindowLong (hDlg, DWL_USER)) != NULL)
148 DlgProc_Browse_OnInitDialog (hDlg, pbdp);
152 switch (((LPNMHDR)lp)->code)
154 case LVN_ITEMCHANGED:
155 if ( ((LPNM_LISTVIEW)lp)->uNewState & LVIS_SELECTED )
157 DlgProc_Browse_SelectedEntry (hDlg, pbdp);
162 PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem(hDlg,IDC_BROWSE_SELECT));
168 DlgProc_Browse_StopSearch (pbdp);
170 if (pbdp->hImages != NULL)
172 ListView_SetImageList (GetDlgItem (hDlg, IDC_BROWSE_LIST), 0, 0);
173 ImageList_Destroy (pbdp->hImages);
179 LPTSTR pszName = (LPTSTR)lp;
182 HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
183 LV_AddItem (hList, 1, INDEX_SORT, 0, 0, pszName);
184 FreeString (pszName);
191 TCHAR szText[ cchRESOURCE ];
192 GetString (szText, IDS_BROWSE_WAITING);
193 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, szText);
199 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, TEXT(""));
207 EndDialog (hDlg, LOWORD(wp));
210 case IDC_BROWSE_SELECT:
211 if ( (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL) &&
212 (IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE)) )
214 pbdp->szCell[0] = TEXT('\0');
215 pbdp->szNamed[0] = TEXT('\0');
219 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
220 GetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed, cchRESOURCE);
222 EndDialog (hDlg, IDOK);
225 case IDC_BROWSE_CELL:
226 if (HIWORD(wp) == CBN_SELCHANGE)
228 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
229 DlgProc_Browse_StartSearch (pbdp, FALSE);
233 case IDC_BROWSE_RESTART:
234 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
235 DlgProc_Browse_StartSearch (pbdp, FALSE);
236 PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_BROWSE_NAMED), (LPARAM)TRUE);
239 case IDC_BROWSE_NAMED:
240 if (HIWORD(wp) == EN_UPDATE) // has the user hit Enter here?
242 TCHAR szTest[ cchRESOURCE ];
244 GetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest, cchRESOURCE);
246 if ( (lstrlen (szTest) > 0) &&
247 (szTest[ lstrlen(szTest)-1 ] == TEXT('\n')) )
249 szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
251 if ( (lstrlen (szTest) > 0) &&
252 (szTest[ lstrlen(szTest)-1 ] == TEXT('\r')) )
254 szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
257 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest);
258 PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem(hDlg,IDC_BROWSE_SELECT));
263 case IDC_BROWSE_NONE:
264 DlgProc_Browse_OnNone (hDlg, pbdp);
276 *** DlgProc_Browse_OnInitDialog
278 * The WM_INITDIALOG handler for the Browse dialog. This routine fills
279 * in the dialog with any starting parameters, and kicks off a new
280 * searching thread for the given cell.
284 void DlgProc_Browse_OnInitDialog (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
286 TCHAR szText[ cchRESOURCE ];
291 // We'll need an imagelist, if we want icons in the listview.
292 // This looks difficult but it's not--tis just a matter of selecting
293 // an appropriate bitmap.
295 if ((pbdp->hImages = ImageList_Create (cxICON, cyICON, ILC_COLOR4 | ILC_MASK, 1, 1)) != 0)
299 if (pbdp->bt == btLOCAL_USER)
301 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_LOCAL_USER ));
303 else if (pbdp->bt == btANY_USER)
305 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_FOREIGN_USER ));
307 else if (pbdp->bt == btLOCAL_GROUP)
309 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_LOCAL_GROUP ));
311 else if (pbdp->bt == btANY_GROUP)
313 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_FOREIGN_GROUP ));
318 ImageList_AddMasked (pbdp->hImages, bmp, clrTRANSPARENT);
322 ListView_SetImageList (GetDlgItem (hDlg, IDC_BROWSE_LIST), pbdp->hImages, LVSIL_SMALL);
325 // There's a default pushbutton on this dialog, so that hitting
326 // RETURN when you're in the Cell combobox will restart the search
327 // (a default pushbutton always gets called when RETURN is hit,
328 // unless your control traps it). But the user doesn't want to *see*
329 // that thing, so move it way off the dialog's client area.
332 GetWindowRect (GetDlgItem (hDlg, IDC_BROWSE_RESTART), &r);
333 SetWindowPos (GetDlgItem (hDlg, IDC_BROWSE_RESTART), NULL,
334 0 - (r.right-r.left), 0 - (r.bottom-r.top), 0, 0,
335 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
337 // Fill in the choices underneath IDC_BROWSE_CELL. Can the
338 // user enter a new cell name?
340 if (pbdp->fThisCellOnly)
342 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CELL), FALSE);
346 CB_StartChange (GetDlgItem (hDlg, IDC_BROWSE_CELL));
350 TCHAR szDefCell[ cchNAME ];
351 if (AfsAppLib_GetLocalCell (szDefCell) && *szDefCell)
353 CB_AddItem (GetDlgItem (hDlg, IDC_BROWSE_CELL), szDefCell, 1);
356 else for (size_t ii = 0; ii < pbdp->lpcl->nCells; ++ii)
358 CB_AddItem (GetDlgItem (hDlg, IDC_BROWSE_CELL), pbdp->lpcl->aCells[ii], 1+ii);
361 CB_EndChange (GetDlgItem (hDlg, IDC_BROWSE_CELL), 1);
364 // Select various texts to display in the dialog
366 psz = FormatString (TEXT("%1"), TEXT("%m"), pbdp->idsTitle);
367 SetWindowText (hDlg, psz);
369 GetString (szText, pbdp->idsPrompt);
370 SetDlgItemText (hDlg, IDC_BROWSE_TYPE, szText);
372 // If the caller wants us to display a "[X] No Group" checkbox, do so
373 // by creating a checkbox right underneath the IDC_BROWSE_NAMED edit
374 // control--note that we'll have to hide IDC_BROWSE_STATUS if that's
377 if (pbdp->idsNone != 0)
379 ShowWindow (GetDlgItem (pbdp->hDlg, IDC_BROWSE_STATUS), FALSE);
382 GetRectInParent (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NAMED), &rr);
385 cy = rr.bottom -rr.top;
387 rr.bottom = rr.top +cy;
389 GetString (szText, pbdp->idsNone);
390 CreateWindow ("Button", szText, WS_CHILD | BS_AUTOCHECKBOX,
391 rr.left, rr.top, rr.right-rr.left, rr.bottom-rr.top,
392 pbdp->hDlg, (HMENU)IDC_BROWSE_NONE, APPLIB_HINST, 0);
394 HFONT hf = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
395 SendMessage (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE), WM_SETFONT, (WPARAM)hf, FALSE);
396 ShowWindow (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE), TRUE);
398 if (pbdp->szNamed[0] == TEXT('\0'))
399 CheckDlgButton (pbdp->hDlg, IDC_BROWSE_NONE, TRUE);
401 CheckDlgButton (pbdp->hDlg, IDC_BROWSE_NONE, FALSE);
403 DlgProc_Browse_OnNone (pbdp->hDlg, pbdp);
406 SetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell);
407 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed);
409 // Start looking for users/groups
411 DlgProc_Browse_StartSearch (pbdp, TRUE);
416 *** DlgProc_Browse_OnNone
418 * This routine is called whenever the user checks or unchecks the
419 * "[X] None" checkbox (which we may not even be displaying)
423 void DlgProc_Browse_OnNone (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
425 if (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL)
427 BOOL fNone = IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE);
429 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CELL), !fNone && !pbdp->fThisCellOnly);
430 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_NAMED), !fNone);
431 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_LIST), !fNone);
433 DlgProc_Browse_SelectedEntry (hDlg, pbdp);
439 *** DlgProc_Browse_SelectedEntry
441 * This routine is called whenever the user selects a new entry within
442 * the Browse dialog's listview
446 void DlgProc_Browse_SelectedEntry (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
448 if ( (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL) &&
449 (IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE)) )
451 pbdp->szNamed[0] = TEXT('\0');
455 HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
456 short idxSelected = LV_GetSelected (hList);
458 if (idxSelected == -1)
459 pbdp->szNamed[0] = TEXT('\0');
461 LV_GetItemText (hList, idxSelected, 0, pbdp->szNamed);
463 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed);
469 *** DlgProc_Browse_UpdateCellText
471 * This routine places the given cell name in the browse dialog.
475 void DlgProc_Browse_UpdateCellText (BROWSEDIALOGPARAMS *pbdp, LPTSTR pszCell)
477 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_CELL, pbdp->szCell);
482 *** DlgProc_Browse_StartSearch
484 * This routine initiates a thread which enumerates all users/groups within
485 * the given cell, posting messages to describe what it finds to the Browse
490 BOOL DlgProc_Browse_StartSearch (BROWSEDIALOGPARAMS *pbdp, BOOL fCloseDlgIfFail)
494 // Can't start a new search until the old search terminates.
496 DlgProc_Browse_StopSearch (pbdp);
498 // Then make sure that we have a valid cell to query--if not, it may
499 // be grounds to terminate the entire browse dialog.
501 lstrcpy (pbdp->szThreadCell, pbdp->szCell);
503 if (!pbdp->szCell[0])
505 AfsAppLib_GetLocalCell (pbdp->szCell);
507 lstrcpy (pbdp->szThreadCell, pbdp->szCell);
509 DlgProc_Browse_UpdateCellText (pbdp, pbdp->szThreadCell);
512 if (!pbdp->szCell[0])
515 EndDialog (pbdp->hDlg, IDCANCEL);
517 MessageBeep (MB_ICONHAND);
518 Message (MB_ICONHAND, IDS_BROWSE_BADCELL_TITLE, IDS_BROWSE_BADCELL_DESC);
520 if (!fCloseDlgIfFail)
521 PostMessage (pbdp->hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (pbdp->hDlg, IDC_BROWSE_CELL), (LPARAM)TRUE);
525 // Great--we can do the search. Start a thread to do so.
527 pbdp->fCanStopThreadEasily = FALSE;
528 pbdp->fShouldStopThread = FALSE;
529 pbdp->fThreadActive = FALSE;
531 ListView_DeleteAllItems (GetDlgItem (pbdp->hDlg, IDC_BROWSE_LIST));
533 pbdp->hThread = CreateThread (NULL, 0,
534 (LPTHREAD_START_ROUTINE)DlgProc_Browse_ThreadProc,
535 pbdp, 0, &dwThreadID);
537 return (pbdp->hThread == 0) ? FALSE : TRUE;
542 *** DlgProc_Browse_StopSearch
544 * This routine signals the search thread to stop, and will not return
549 void DlgProc_Browse_StopSearch (BROWSEDIALOGPARAMS *pbdp)
551 if (pbdp->fThreadActive)
553 if (pbdp->fCanStopThreadEasily)
555 pbdp->fShouldStopThread = TRUE;
557 WaitForSingleObject (pbdp->hThread, INFINITE);
561 TerminateThread (pbdp->hThread, 0);
562 pbdp->fThreadActive = FALSE;
566 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, TEXT(""));
571 *** DlgProc_Browse_ThreadProc
573 * The worker thread for the Browse dialog; this routine enumerates all
574 * users or groups on the given cell, posting a WM_FOUNDNAME message to
575 * the Browse dialog after every successful find. Note that LPARAM on
576 * such messages points to a string which should be freed with FreeString()
577 * when no longer needed.
581 DWORD _stdcall DlgProc_Browse_ThreadProc (LPARAM lp)
583 BROWSEDIALOGPARAMS *pbdp;
585 if ((pbdp = (BROWSEDIALOGPARAMS *)lp) != NULL)
587 pbdp->fThreadActive = TRUE;
589 PostMessage (pbdp->hDlg, WM_THREADSTART, 0, 0);
592 if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
594 EnumeratePrincipalsRemotely (pbdp, idClient);
598 if (OpenClientLibrary())
600 if (OpenKasLibrary())
602 EnumeratePrincipalsLocally (pbdp);
606 CloseClientLibrary();
610 pbdp->fThreadActive = FALSE;
612 PostMessage (pbdp->hDlg, WM_THREADDONE, 0, 0);
619 void EnumeratePrincipalsLocally (LPBROWSEDIALOGPARAMS pbdp)
623 char szCellA[ MAX_PATH ];
624 CopyStringToAnsi (szCellA, pbdp->szCell);
627 if (afsclient_CellOpen (szCellA, pbdp->hCreds, &hCell, (afs_status_p)&status))
629 // Enumerate the principals recognized by KAS.
632 if (kas_PrincipalGetBegin (hCell, NULL, &hEnum, (afs_status_p)&status))
634 pbdp->fCanStopThreadEasily = TRUE;
636 while (!pbdp->fShouldStopThread)
639 if (!kas_PrincipalGetNext (hEnum, &who, (afs_status_p)&status))
643 if ((pszName = CloneAnsi ((LPSTR)who.principal)) == NULL)
646 PostMessage (pbdp->hDlg, WM_FOUNDNAME, 0, (LPARAM)pszName);
647 // pszName freed by DlgProc_Browse when it receives the message
650 kas_PrincipalGetDone (hEnum, (afs_status_p)&status);
653 afsclient_CellClose (hCell, (afs_status_p)&status);
658 void EnumeratePrincipalsRemotely (LPBROWSEDIALOGPARAMS pbdp, DWORD idClient)
662 // Open the relevant cell
665 if (asc_CellOpen (idClient, pbdp->hCreds, pbdp->szThreadCell, AFSADMSVR_SCOPE_USERS, &idCell, &status))
667 // Obtain a list of ASIDs from the admin server, each representing
668 // a principal which we want to show.
670 LPASIDLIST pAsidList;
671 if (asc_ObjectFindMultiple (idClient, idCell, TYPE_USER, NULL, NULL, &pAsidList, &status))
675 // Obtain rudimentary properties (e.g., their names) for these ASIDs
677 LPASOBJPROPLIST pPropList;
678 if (asc_ObjectPropertiesGetMultiple (idClient, GET_RUDIMENTARY_DATA, idCell, pAsidList, &pPropList, &status))
682 // Use the information in {pPropList} to populate the display
684 for (size_t iEntry = 0; iEntry < pPropList->cEntries; ++iEntry)
687 if ((pszName = CloneString (pPropList->aEntries[ iEntry ].ObjectProperties.szName)) != NULL)
689 PostMessage (pbdp->hDlg, WM_FOUNDNAME, 0, (LPARAM)pszName);
690 // pszName freed by DlgProc_Browse when it receives the message
694 asc_ObjPropListFree (&pPropList);
698 asc_AsidListFree (&pAsidList);
702 asc_CellClose (idClient, idCell, &status);