Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsapplib / al_browse.cpp
blob8020d9af588a0af95e0a7755195cfaa3c80e364c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
18 #include <WINNT/afsapplib.h>
19 #include "al_dynlink.h"
20 #include <WINNT/TaAfsAdmSvrClient.h>
24 * DEFINITIONS ________________________________________________________________
28 #define cxICON 19 // size of an ACL entry icon
30 #define cyICON 16 // size of an ACL entry icon
32 #define clrTRANSPARENT RGB(0,255,0) // background color on ACL entry icons
36 * BROWSE DIALOG ______________________________________________________________
40 typedef struct BROWSEDIALOGPARAMS {
41 TCHAR szCell[ cchRESOURCE ];
42 TCHAR szNamed[ cchRESOURCE ];
43 BOOL fThisCellOnly;
44 HIMAGELIST hImages;
46 BROWSETYPE bt; // for what entry type do we browse?
48 HWND hDlg;
49 HANDLE hThread;
50 BOOL fCanStopThreadEasily;
51 BOOL fShouldStopThread;
52 BOOL fThreadActive;
53 TCHAR szThreadCell[ cchRESOURCE ];
55 int idsTitle;
56 int idsPrompt;
57 int idsNone;
59 LPCELLLIST lpcl;
60 UINT_PTR hCreds;
61 } BROWSEDIALOGPARAMS, *LPBROWSEDIALOGPARAMS;
64 HRESULT CALLBACK DlgProc_Browse (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
65 void DlgProc_Browse_OnInitDialog (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
66 void DlgProc_Browse_OnNone (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
67 void DlgProc_Browse_SelectedEntry (HWND hDlg, BROWSEDIALOGPARAMS *pbdp);
68 void DlgProc_Browse_UpdateCellText (BROWSEDIALOGPARAMS *pbdp, LPTSTR pszCell);
70 BOOL DlgProc_Browse_StartSearch (BROWSEDIALOGPARAMS *pbdp, BOOL fCloseDlgIfFail);
71 void DlgProc_Browse_StopSearch (BROWSEDIALOGPARAMS *pbdp);
72 DWORD _stdcall DlgProc_Browse_ThreadProc (LPARAM lp);
74 void EnumeratePrincipalsRemotely (LPBROWSEDIALOGPARAMS pbdp, UINT_PTR idClient);
75 void EnumeratePrincipalsLocally (LPBROWSEDIALOGPARAMS pbdp);
79 *** ShowBrowseDialog
81 * This function presents a dialog which allows the user to select a user
82 * or group from a list.
86 BOOL AfsAppLib_ShowBrowseDialog (LPBROWSEDLG_PARAMS lpp)
88 BROWSEDIALOGPARAMS *pbdp;
89 BOOL rc = FALSE;
91 if ((pbdp = New (BROWSEDIALOGPARAMS)) != NULL)
93 memset (pbdp, 0x00, sizeof(BROWSEDIALOGPARAMS));
94 lstrcpy (pbdp->szNamed, lpp->szNamed);
95 lstrcpy (pbdp->szCell, lpp->szCell);
96 pbdp->lpcl = lpp->lpcl;
97 pbdp->bt = lpp->bt;
98 pbdp->idsTitle = lpp->idsTitle;
99 pbdp->idsPrompt = lpp->idsPrompt;
100 pbdp->idsNone = lpp->idsNone;
101 pbdp->hCreds = lpp->hCreds;
103 switch (pbdp->bt)
105 case btLOCAL_USER:
106 case btLOCAL_GROUP:
107 pbdp->fThisCellOnly = TRUE;
108 break;
110 case btANY_USER:
111 case btANY_GROUP:
112 pbdp->fThisCellOnly = FALSE;
113 break;
116 if (ModalDialogParam (IDD_APPLIB_BROWSE, lpp->hParent, (DLGPROC)DlgProc_Browse, (LPARAM)pbdp) == IDOK)
118 lstrcpy (lpp->szCell, pbdp->szCell);
119 lstrcpy (lpp->szNamed, pbdp->szNamed);
120 rc = TRUE;
123 Delete (pbdp);
126 return rc;
131 *** DlgProc_Browse
133 * This is the dialog proc for the Browse Cell dialog.
137 #define WM_FOUNDNAME (WM_USER +100)
138 #define WM_THREADSTART (WM_USER +101)
139 #define WM_THREADDONE (WM_USER +102)
141 HRESULT CALLBACK DlgProc_Browse (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
143 BROWSEDIALOGPARAMS *pbdp;
145 if (AfsAppLib_HandleHelp (IDD_APPLIB_BROWSE, hDlg, msg, wp, lp))
147 return FALSE;
150 if (msg == WM_INITDIALOG)
152 SetWindowLongPtr (hDlg, DWLP_USER, lp);
155 if ((pbdp = (BROWSEDIALOGPARAMS *)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
157 switch (msg)
159 case WM_INITDIALOG:
160 DlgProc_Browse_OnInitDialog (hDlg, pbdp);
161 break;
163 case WM_NOTIFY:
164 switch (((LPNMHDR)lp)->code)
166 case LVN_ITEMCHANGED:
167 if ( ((LPNM_LISTVIEW)lp)->uNewState & LVIS_SELECTED )
169 DlgProc_Browse_SelectedEntry (hDlg, pbdp);
171 break;
173 case NM_DBLCLK:
174 PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem(hDlg,IDC_BROWSE_SELECT));
175 break;
177 break;
179 case WM_DESTROY:
180 DlgProc_Browse_StopSearch (pbdp);
182 if (pbdp->hImages != NULL)
184 ListView_SetImageList (GetDlgItem (hDlg, IDC_BROWSE_LIST), 0, 0);
185 ImageList_Destroy (pbdp->hImages);
187 break;
189 case WM_FOUNDNAME:
191 LPTSTR pszName = (LPTSTR)lp;
192 if (pszName != NULL)
194 HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
195 LV_AddItem (hList, 1, INDEX_SORT, 0, 0, pszName);
196 FreeString (pszName);
198 break;
201 case WM_THREADSTART:
203 TCHAR szText[ cchRESOURCE ];
204 GetString (szText, IDS_BROWSE_WAITING);
205 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, szText);
206 break;
209 case WM_THREADDONE:
211 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, TEXT(""));
212 break;
215 case WM_COMMAND:
216 switch (LOWORD(wp))
218 case IDCANCEL:
219 EndDialog (hDlg, LOWORD(wp));
220 break;
222 case IDC_BROWSE_SELECT:
223 if ( (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL) &&
224 (IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE)) )
226 pbdp->szCell[0] = TEXT('\0');
227 pbdp->szNamed[0] = TEXT('\0');
229 else
231 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
232 GetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed, cchRESOURCE);
234 EndDialog (hDlg, IDOK);
235 break;
237 case IDC_BROWSE_CELL:
238 if (HIWORD(wp) == CBN_SELCHANGE)
240 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
241 DlgProc_Browse_StartSearch (pbdp, FALSE);
243 break;
245 case IDC_BROWSE_RESTART:
246 GetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell, cchNAME);
247 DlgProc_Browse_StartSearch (pbdp, FALSE);
248 PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_BROWSE_NAMED), (LPARAM)TRUE);
249 break;
251 case IDC_BROWSE_NAMED:
252 if (HIWORD(wp) == EN_UPDATE) // has the user hit Enter here?
254 TCHAR szTest[ cchRESOURCE ];
256 GetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest, cchRESOURCE);
258 if ( (lstrlen (szTest) > 0) &&
259 (szTest[ lstrlen(szTest)-1 ] == TEXT('\n')) )
261 szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
263 if ( (lstrlen (szTest) > 0) &&
264 (szTest[ lstrlen(szTest)-1 ] == TEXT('\r')) )
266 szTest[ lstrlen(szTest)-1 ] = TEXT('\0');
269 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, szTest);
270 PostMessage (hDlg, WM_COMMAND, MAKELONG(IDC_BROWSE_SELECT,BN_CLICKED), (LPARAM)GetDlgItem(hDlg,IDC_BROWSE_SELECT));
273 break;
275 case IDC_BROWSE_NONE:
276 DlgProc_Browse_OnNone (hDlg, pbdp);
277 break;
279 break;
283 return FALSE;
288 *** DlgProc_Browse_OnInitDialog
290 * The WM_INITDIALOG handler for the Browse dialog. This routine fills
291 * in the dialog with any starting parameters, and kicks off a new
292 * searching thread for the given cell.
296 void DlgProc_Browse_OnInitDialog (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
298 TCHAR szText[ cchRESOURCE ];
299 LPTSTR psz;
301 pbdp->hDlg = hDlg;
303 // We'll need an imagelist, if we want icons in the listview.
304 // This looks difficult but it's not--tis just a matter of selecting
305 // an appropriate bitmap.
307 if ((pbdp->hImages = ImageList_Create (cxICON, cyICON, ILC_COLOR4 | ILC_MASK, 1, 1)) != 0)
309 HBITMAP bmp;
311 if (pbdp->bt == btLOCAL_USER)
313 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_LOCAL_USER ));
315 else if (pbdp->bt == btANY_USER)
317 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_FOREIGN_USER ));
319 else if (pbdp->bt == btLOCAL_GROUP)
321 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_LOCAL_GROUP ));
323 else if (pbdp->bt == btANY_GROUP)
325 bmp = LoadBitmap (APPLIB_HINST, MAKEINTRESOURCE( IDB_FOREIGN_GROUP ));
328 if (bmp != NULL)
330 ImageList_AddMasked (pbdp->hImages, bmp, clrTRANSPARENT);
331 DeleteObject (bmp);
334 ListView_SetImageList (GetDlgItem (hDlg, IDC_BROWSE_LIST), pbdp->hImages, LVSIL_SMALL);
337 // There's a default pushbutton on this dialog, so that hitting
338 // RETURN when you're in the Cell combobox will restart the search
339 // (a default pushbutton always gets called when RETURN is hit,
340 // unless your control traps it). But the user doesn't want to *see*
341 // that thing, so move it way off the dialog's client area.
343 RECT r;
344 GetWindowRect (GetDlgItem (hDlg, IDC_BROWSE_RESTART), &r);
345 SetWindowPos (GetDlgItem (hDlg, IDC_BROWSE_RESTART), NULL,
346 0 - (r.right-r.left), 0 - (r.bottom-r.top), 0, 0,
347 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
349 // Fill in the choices underneath IDC_BROWSE_CELL. Can the
350 // user enter a new cell name?
352 if (pbdp->fThisCellOnly)
354 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CELL), FALSE);
356 else
358 CB_StartChange (GetDlgItem (hDlg, IDC_BROWSE_CELL));
360 if (!pbdp->lpcl)
362 TCHAR szDefCell[ cchNAME ];
363 if (AfsAppLib_GetLocalCell (szDefCell) && *szDefCell)
365 CB_AddItem (GetDlgItem (hDlg, IDC_BROWSE_CELL), szDefCell, 1);
368 else for (size_t ii = 0; ii < pbdp->lpcl->nCells; ++ii)
370 CB_AddItem (GetDlgItem (hDlg, IDC_BROWSE_CELL), pbdp->lpcl->aCells[ii], 1+ii);
373 CB_EndChange (GetDlgItem (hDlg, IDC_BROWSE_CELL), 1);
376 // Select various texts to display in the dialog
378 psz = FormatString (TEXT("%1"), TEXT("%m"), pbdp->idsTitle);
379 SetWindowText (hDlg, psz);
380 FreeString (psz);
381 GetString (szText, pbdp->idsPrompt);
382 SetDlgItemText (hDlg, IDC_BROWSE_TYPE, szText);
384 // If the caller wants us to display a "[X] No Group" checkbox, do so
385 // by creating a checkbox right underneath the IDC_BROWSE_NAMED edit
386 // control--note that we'll have to hide IDC_BROWSE_STATUS if that's
387 // the case.
389 if (pbdp->idsNone != 0)
391 ShowWindow (GetDlgItem (pbdp->hDlg, IDC_BROWSE_STATUS), FALSE);
393 RECT rr;
394 GetRectInParent (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NAMED), &rr);
396 LONG cy;
397 cy = rr.bottom -rr.top;
398 rr.top += cy +3;
399 rr.bottom = rr.top +cy;
401 GetString (szText, pbdp->idsNone);
402 CreateWindow ("Button", szText, WS_CHILD | BS_AUTOCHECKBOX,
403 rr.left, rr.top, rr.right-rr.left, rr.bottom-rr.top,
404 pbdp->hDlg, (HMENU)IDC_BROWSE_NONE, APPLIB_HINST, 0);
406 HFONT hf = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
407 SendMessage (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE), WM_SETFONT, (WPARAM)hf, FALSE);
408 ShowWindow (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE), TRUE);
410 if (pbdp->szNamed[0] == TEXT('\0'))
411 CheckDlgButton (pbdp->hDlg, IDC_BROWSE_NONE, TRUE);
412 else
413 CheckDlgButton (pbdp->hDlg, IDC_BROWSE_NONE, FALSE);
415 DlgProc_Browse_OnNone (pbdp->hDlg, pbdp);
418 SetDlgItemText (hDlg, IDC_BROWSE_CELL, pbdp->szCell);
419 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed);
421 // Start looking for users/groups
423 DlgProc_Browse_StartSearch (pbdp, TRUE);
428 *** DlgProc_Browse_OnNone
430 * This routine is called whenever the user checks or unchecks the
431 * "[X] None" checkbox (which we may not even be displaying)
435 void DlgProc_Browse_OnNone (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
437 if (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL)
439 BOOL fNone = IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE);
441 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_CELL), !fNone && !pbdp->fThisCellOnly);
442 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_NAMED), !fNone);
443 EnableWindow (GetDlgItem (hDlg, IDC_BROWSE_LIST), !fNone);
445 DlgProc_Browse_SelectedEntry (hDlg, pbdp);
451 *** DlgProc_Browse_SelectedEntry
453 * This routine is called whenever the user selects a new entry within
454 * the Browse dialog's listview
458 void DlgProc_Browse_SelectedEntry (HWND hDlg, BROWSEDIALOGPARAMS *pbdp)
460 if ( (GetDlgItem (pbdp->hDlg, IDC_BROWSE_NONE) != NULL) &&
461 (IsDlgButtonChecked (pbdp->hDlg, IDC_BROWSE_NONE)) )
463 pbdp->szNamed[0] = TEXT('\0');
465 else
467 HWND hList = GetDlgItem (hDlg, IDC_BROWSE_LIST);
468 short idxSelected = LV_GetSelected (hList);
470 if (idxSelected == -1)
471 pbdp->szNamed[0] = TEXT('\0');
472 else
473 LV_GetItemText (hList, idxSelected, 0, pbdp->szNamed);
475 SetDlgItemText (hDlg, IDC_BROWSE_NAMED, pbdp->szNamed);
481 *** DlgProc_Browse_UpdateCellText
483 * This routine places the given cell name in the browse dialog.
487 void DlgProc_Browse_UpdateCellText (BROWSEDIALOGPARAMS *pbdp, LPTSTR pszCell)
489 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_CELL, pbdp->szCell);
494 *** DlgProc_Browse_StartSearch
496 * This routine initiates a thread which enumerates all users/groups within
497 * the given cell, posting messages to describe what it finds to the Browse
498 * dialog's DLGPROC.
502 BOOL DlgProc_Browse_StartSearch (BROWSEDIALOGPARAMS *pbdp, BOOL fCloseDlgIfFail)
504 DWORD dwThreadID;
506 // Can't start a new search until the old search terminates.
508 DlgProc_Browse_StopSearch (pbdp);
510 // Then make sure that we have a valid cell to query--if not, it may
511 // be grounds to terminate the entire browse dialog.
513 lstrcpy (pbdp->szThreadCell, pbdp->szCell);
515 if (!pbdp->szCell[0])
517 AfsAppLib_GetLocalCell (pbdp->szCell);
519 lstrcpy (pbdp->szThreadCell, pbdp->szCell);
521 DlgProc_Browse_UpdateCellText (pbdp, pbdp->szThreadCell);
524 if (!pbdp->szCell[0])
526 if (fCloseDlgIfFail)
527 EndDialog (pbdp->hDlg, IDCANCEL);
529 MessageBeep (MB_ICONHAND);
530 Message (MB_ICONHAND, IDS_BROWSE_BADCELL_TITLE, IDS_BROWSE_BADCELL_DESC);
532 if (!fCloseDlgIfFail)
533 PostMessage (pbdp->hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (pbdp->hDlg, IDC_BROWSE_CELL), (LPARAM)TRUE);
534 return FALSE;
537 // Great--we can do the search. Start a thread to do so.
539 pbdp->fCanStopThreadEasily = FALSE;
540 pbdp->fShouldStopThread = FALSE;
541 pbdp->fThreadActive = FALSE;
543 ListView_DeleteAllItems (GetDlgItem (pbdp->hDlg, IDC_BROWSE_LIST));
545 pbdp->hThread = CreateThread (NULL, 0,
546 (LPTHREAD_START_ROUTINE)DlgProc_Browse_ThreadProc,
547 pbdp, 0, &dwThreadID);
549 return (pbdp->hThread == 0) ? FALSE : TRUE;
554 *** DlgProc_Browse_StopSearch
556 * This routine signals the search thread to stop, and will not return
557 * until it does.
561 void DlgProc_Browse_StopSearch (BROWSEDIALOGPARAMS *pbdp)
563 if (pbdp->fThreadActive)
565 if (pbdp->fCanStopThreadEasily)
567 pbdp->fShouldStopThread = TRUE;
569 WaitForSingleObject (pbdp->hThread, INFINITE);
571 else
573 TerminateThread (pbdp->hThread, 0);
574 pbdp->fThreadActive = FALSE;
578 SetDlgItemText (pbdp->hDlg, IDC_BROWSE_STATUS, TEXT(""));
583 *** DlgProc_Browse_ThreadProc
585 * The worker thread for the Browse dialog; this routine enumerates all
586 * users or groups on the given cell, posting a WM_FOUNDNAME message to
587 * the Browse dialog after every successful find. Note that LPARAM on
588 * such messages points to a string which should be freed with FreeString()
589 * when no longer needed.
593 DWORD _stdcall DlgProc_Browse_ThreadProc (LPARAM lp)
595 BROWSEDIALOGPARAMS *pbdp;
597 if ((pbdp = (BROWSEDIALOGPARAMS *)lp) != NULL)
599 pbdp->fThreadActive = TRUE;
601 PostMessage (pbdp->hDlg, WM_THREADSTART, 0, 0);
603 UINT_PTR idClient;
604 if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
606 EnumeratePrincipalsRemotely (pbdp, idClient);
608 else
610 if (OpenClientLibrary())
612 if (OpenKasLibrary())
614 EnumeratePrincipalsLocally (pbdp);
615 CloseKasLibrary();
618 CloseClientLibrary();
622 pbdp->fThreadActive = FALSE;
624 PostMessage (pbdp->hDlg, WM_THREADDONE, 0, 0);
627 return 0;
631 void EnumeratePrincipalsLocally (LPBROWSEDIALOGPARAMS pbdp)
633 ULONG status;
635 char szCellA[ MAX_PATH ];
636 CopyStringToAnsi (szCellA, pbdp->szCell);
638 PVOID hCell;
639 if (afsclient_CellOpen (szCellA, (PVOID)pbdp->hCreds, &hCell, (afs_status_p)&status))
641 // Enumerate the principals recognized by KAS.
643 PVOID hEnum;
644 if (kas_PrincipalGetBegin (hCell, NULL, &hEnum, (afs_status_p)&status))
646 pbdp->fCanStopThreadEasily = TRUE;
648 while (!pbdp->fShouldStopThread)
650 kas_identity_t who;
651 if (!kas_PrincipalGetNext (hEnum, &who, (afs_status_p)&status))
652 break;
654 LPTSTR pszName;
655 if ((pszName = CloneAnsi ((LPSTR)who.principal)) == NULL)
656 break;
658 PostMessage (pbdp->hDlg, WM_FOUNDNAME, 0, (LPARAM)pszName);
659 // pszName freed by DlgProc_Browse when it receives the message
662 kas_PrincipalGetDone (hEnum, (afs_status_p)&status);
665 afsclient_CellClose (hCell, (afs_status_p)&status);
670 void EnumeratePrincipalsRemotely (LPBROWSEDIALOGPARAMS pbdp, UINT_PTR idClient)
672 ULONG status;
674 // Open the relevant cell
676 ASID idCell;
677 if (asc_CellOpen (idClient, (PVOID)pbdp->hCreds, pbdp->szThreadCell, AFSADMSVR_SCOPE_USERS, &idCell, &status))
679 // Obtain a list of ASIDs from the admin server, each representing
680 // a principal which we want to show.
682 LPASIDLIST pAsidList;
683 if (asc_ObjectFindMultiple (idClient, idCell, TYPE_USER, NULL, NULL, &pAsidList, &status))
685 if (pAsidList)
687 // Obtain rudimentary properties (e.g., their names) for these ASIDs
689 LPASOBJPROPLIST pPropList;
690 if (asc_ObjectPropertiesGetMultiple (idClient, GET_RUDIMENTARY_DATA, idCell, pAsidList, &pPropList, &status))
692 if (pPropList)
694 // Use the information in {pPropList} to populate the display
696 for (size_t iEntry = 0; iEntry < pPropList->cEntries; ++iEntry)
698 LPTSTR pszName;
699 if ((pszName = CloneString (pPropList->aEntries[ iEntry ].ObjectProperties.szName)) != NULL)
701 PostMessage (pbdp->hDlg, WM_FOUNDNAME, 0, (LPARAM)pszName);
702 // pszName freed by DlgProc_Browse when it receives the message
706 asc_ObjPropListFree (&pPropList);
710 asc_AsidListFree (&pAsidList);
714 asc_CellClose (idClient, idCell, &status);