2 * Copyright 2000, International Business Machines Corporation and others.
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
11 #include <afs/param.h>
15 #include "afs_config.h"
16 #include "tab_prefs.h"
22 * VARIABLES __________________________________________________________________
33 #define cREALLOC_PREFS 32
36 #define iswhite(_ch) (((_ch)==TEXT(' ')) || ((_ch)==TEXT('\t')))
39 #define iseol(_ch) (((_ch)==TEXT('\r')) || ((_ch)==TEXT('\n')))
42 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
47 * PROTOTYPES _________________________________________________________________
51 void PrefsTab_OnInitDialog (HWND hDlg);
52 BOOL PrefsTab_OnApply (HWND hDlg);
53 void PrefsTab_OnRefresh (HWND hDlg);
54 void PrefsTab_OnFillList (HWND hDlg);
55 void PrefsTab_OnSelect (HWND hDlg);
56 void PrefsTab_OnUpDown (HWND hDlg, BOOL fDown);
57 void PrefsTab_OnAdd (HWND hDlg);
58 void PrefsTab_OnEdit (HWND hDlg);
59 void PrefsTab_OnImport (HWND hDlg);
61 void PrefsTab_MergeServerPrefs (PSERVERPREFS pGlobal, PSERVERPREFS pAdd);
62 void PrefsTab_AddItem (HWND hDlg, PSERVERPREF pPref, BOOL fSelect);
63 void PrefsTab_AddItem (HWND hDlg, LPCTSTR pszServer, int iRank);
65 DWORD WINAPI PrefsTab_RefreshThread (PVOID lp);
66 DWORD WINAPI PrefsTab_ThreadProc (PVOID lp);
67 void PrefsTab_ThreadProcFunc (PSERVERPREFS pPrefs, BOOL *pfStopFlag);
69 int CALLBACK PrefsTab_SortFunction (HWND hList, HLISTITEM hItem1, LPARAM lpItem1, HLISTITEM hItem2, LPARAM lpItem2);
71 BOOL CALLBACK IPKey_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData);
72 HASHVALUE CALLBACK IPKey_HashObject (LPHASHLISTKEY pKey, PVOID pObject);
73 HASHVALUE CALLBACK IPKey_HashData (LPHASHLISTKEY pKey, PVOID pData);
75 BOOL CALLBACK PrefsEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
76 void PrefsEdit_OnInitDialog (HWND hDlg);
77 void PrefsEdit_OnOK (HWND hDlg);
78 void PrefsEdit_Enable (HWND hDlg);
82 * ROUTINES ___________________________________________________________________
86 BOOL CALLBACK PrefsTab_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
91 InitializeCriticalSection (&l.cs);
92 PrefsTab_OnInitDialog (hDlg);
99 if (!PrefsTab_OnApply (hDlg))
100 SetWindowLong (hDlg, DWL_MSGRESULT, TRUE);
104 PrefsTab_OnRefresh (hDlg);
109 PrefsTab_OnFillList (hDlg);
113 PrefsTab_OnAdd (hDlg);
117 PrefsTab_OnEdit (hDlg);
121 PrefsTab_OnUpDown (hDlg, FALSE);
125 PrefsTab_OnUpDown (hDlg, TRUE);
129 PrefsTab_OnImport (hDlg);
133 PrefsTab_DlgProc (hDlg, WM_HELP, 0, 0);
139 WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_PREFS_NT);
143 switch (((LPNMHDR)lp)->code)
146 PrefsTab_OnSelect (hDlg);
150 if (IsWindowEnabled (GetDlgItem (hDlg, IDC_EDIT)))
151 PrefsTab_OnEdit (hDlg);
161 void PrefsTab_OnInitDialog (HWND hDlg)
163 HICON hiUp = TaLocale_LoadIcon (IDI_UP);
164 HICON hiDown = TaLocale_LoadIcon (IDI_DOWN);
166 SendDlgItemMessage (hDlg, IDC_UP, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hiUp);
167 SendDlgItemMessage (hDlg, IDC_DOWN, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hiDown);
169 CheckDlgButton (hDlg, IDC_SHOW_FS, TRUE);
170 CheckDlgButton (hDlg, IDC_SHOW_VLS, FALSE);
172 l.hList = GetDlgItem (hDlg, IDC_LIST);
174 FASTLISTCOLUMN Column;
175 Column.dwFlags = FLCF_JUSTIFY_LEFT;
176 Column.cxWidth = 200;
177 GetString (Column.szText, IDS_PREFCOL_SERVER);
178 FastList_SetColumn (l.hList, 0, &Column);
180 Column.dwFlags = FLCF_JUSTIFY_RIGHT;
182 GetString (Column.szText, IDS_PREFCOL_RANK);
183 FastList_SetColumn (l.hList, 1, &Column);
185 FastList_SetSortFunction (l.hList, PrefsTab_SortFunction);
187 PrefsTab_OnFillList (hDlg);
188 PrefsTab_OnRefresh (hDlg);
192 BOOL PrefsTab_CommitChanges (BOOL fForce)
195 if ((hDlg = PropSheet_FindTabWindow (g.psh, (DLGPROC)PrefsTab_DlgProc)) == NULL)
198 SetWindowLong (hDlg, DWL_MSGRESULT, FALSE); // Make sure we try to apply
199 if (PrefsTab_OnApply (hDlg))
201 SetWindowLong (hDlg, DWL_MSGRESULT, TRUE);
206 BOOL PrefsTab_OnApply (HWND hDlg)
208 // Don't try to do anything if we've already failed the apply
209 if (GetWindowLong (hDlg, DWL_MSGRESULT))
212 if (g.Configuration.pFServers && g.Configuration.fChangedPrefs)
214 if (!Config_SetServerPrefs (g.Configuration.pFServers))
217 if (g.Configuration.pVLServers && g.Configuration.fChangedPrefs)
219 if (!Config_SetServerPrefs (g.Configuration.pVLServers))
222 g.Configuration.fChangedPrefs = FALSE;
227 void PrefsTab_OnRefresh (HWND hDlg)
230 CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)PrefsTab_RefreshThread, (PVOID)hDlg, 0, &idThread);
234 void PrefsTab_OnFillList (HWND hDlg)
236 EnterCriticalSection (&l.cs);
237 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
239 // Empty the fastlist, and clear from the lists any mention of HLISTITEMs.
241 FastList_Begin (l.hList);
242 FastList_RemoveAll (l.hList);
244 if (g.Configuration.pVLServers)
246 for (size_t ii = 0; ii < g.Configuration.pVLServers->cPrefs; ++ii)
247 g.Configuration.pVLServers->aPrefs[ ii ].hItem = NULL;
249 if (g.Configuration.pFServers)
251 for (size_t ii = 0; ii < g.Configuration.pFServers->cPrefs; ++ii)
252 g.Configuration.pFServers->aPrefs[ ii ].hItem = NULL;
255 // Fill in the fastlist by adding entries from the appropriate prefslist.
257 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
260 for (size_t ii = 0; ii < pPrefs->cPrefs; ++ii)
262 if (!pPrefs->aPrefs[ ii ].ipServer)
265 TCHAR szItem[ cchRESOURCE ];
266 if (!pPrefs->aPrefs[ ii ].szServer[0])
268 lstrcpy (szItem, inet_ntoa (*(struct in_addr *)&pPrefs->aPrefs[ ii ].ipServer));
272 wsprintf (szItem, TEXT("%s (%s)"),
273 pPrefs->aPrefs[ ii ].szServer,
274 inet_ntoa (*(struct in_addr *)&pPrefs->aPrefs[ ii ].ipServer));
278 memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
279 ai.iFirstImage = IMAGE_NOIMAGE;
280 ai.iSecondImage = IMAGE_NOIMAGE;
283 pPrefs->aPrefs[ ii ].hItem = FastList_AddItem (l.hList, &ai);
285 wsprintf (szItem, TEXT("%ld"), pPrefs->aPrefs[ ii ].iRank);
286 FastList_SetItemText (l.hList, pPrefs->aPrefs[ ii ].hItem, 1, szItem);
292 FastList_End (l.hList);
293 LeaveCriticalSection (&l.cs);
294 PrefsTab_OnSelect (hDlg);
298 void PrefsTab_OnSelect (HWND hDlg)
300 if (IsWindowEnabled (l.hList))
302 HLISTITEM hItem = FastList_FindFirstSelected (l.hList);
303 HLISTITEM hItemFirst = FastList_FindFirst (l.hList);
304 HLISTITEM hItemNext = FastList_FindNext (l.hList, hItem);
306 EnableWindow (GetDlgItem (hDlg, IDC_UP), (hItem && (hItem != hItemFirst)));
307 EnableWindow (GetDlgItem (hDlg, IDC_DOWN), (hItem && hItemNext));
308 EnableWindow (GetDlgItem (hDlg, IDC_ADD), TRUE);
309 EnableWindow (GetDlgItem (hDlg, IDC_IMPORT), TRUE);
310 EnableWindow (GetDlgItem (hDlg, IDC_EDIT), !!hItem);
315 void PrefsTab_OnUpDown (HWND hDlg, BOOL fDown)
317 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
318 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
321 if ((hItem = FastList_FindFirstSelected (l.hList)) == NULL)
325 hOther = (fDown) ? FastList_FindNext(l.hList,hItem) : FastList_FindPrevious(l.hList,hItem);
329 size_t iItem = (size_t)FastList_GetItemParam (l.hList, hItem);
330 size_t iOther = (size_t)FastList_GetItemParam (l.hList, hOther);
332 if (!pPrefs || (pPrefs->cPrefs <= iItem) || (pPrefs->cPrefs <= iOther))
335 FastList_Begin (l.hList);
337 PSERVERPREF pPref1 = &pPrefs->aPrefs[ iItem ];
338 PSERVERPREF pPref2 = &pPrefs->aPrefs[ iOther ];
340 if (pPref1->iRank == pPref2->iRank)
342 if (fDown && (pPref1->iRank < 65534))
344 else if ((!fDown) && (pPref1->iRank > 1))
346 pPref1->fChanged = TRUE;
348 else // (pPref1->iRating != pPref2->iRating)
350 pPref1->iRank ^= pPref2->iRank;
351 pPref2->iRank ^= pPref1->iRank;
352 pPref1->iRank ^= pPref2->iRank;
353 pPref1->fChanged = TRUE;
354 pPref2->fChanged = TRUE;
357 TCHAR szText[ cchRESOURCE ];
358 wsprintf (szText, TEXT("%ld"), pPref1->iRank);
359 FastList_SetItemText (l.hList, pPref1->hItem, 1, szText);
361 wsprintf (szText, TEXT("%ld"), pPref2->iRank);
362 FastList_SetItemText (l.hList, pPref2->hItem, 1, szText);
364 FastList_EnsureVisible (l.hList, hItem);
365 FastList_End (l.hList);
366 PrefsTab_OnSelect (hDlg);
368 g.Configuration.fChangedPrefs = TRUE;
372 void PrefsTab_OnAdd (HWND hDlg)
374 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
375 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
378 memset (&Pref, 0x00, sizeof(SERVERPREF));
381 if (ModalDialogParam (IDD_PREFS_EDIT, GetParent(hDlg), (DLGPROC)PrefsEdit_DlgProc, (LPARAM)&Pref) == IDOK)
383 PrefsTab_AddItem (hDlg, &Pref, TRUE);
384 PrefsTab_OnSelect (hDlg);
385 g.Configuration.fChangedPrefs = TRUE;
390 void PrefsTab_OnEdit (HWND hDlg)
392 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
393 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
396 if ((hItem = FastList_FindFirstSelected (l.hList)) == NULL)
399 PSERVERPREF pPref = &pPrefs->aPrefs[ FastList_GetItemParam (l.hList, hItem) ];
401 if (ModalDialogParam (IDD_PREFS_EDIT, GetParent(hDlg), (DLGPROC)PrefsEdit_DlgProc, (LPARAM)pPref) == IDOK)
403 FastList_Begin (l.hList);
405 TCHAR szText[ cchRESOURCE ];
406 wsprintf (szText, TEXT("%ld"), pPref->iRank);
407 FastList_SetItemText (l.hList, pPref->hItem, 1, szText);
408 pPref->fChanged = TRUE;
410 FastList_EnsureVisible (l.hList, hItem);
411 FastList_End (l.hList);
412 PrefsTab_OnSelect (hDlg);
413 g.Configuration.fChangedPrefs = TRUE;
418 void PrefsTab_OnImport (HWND hDlg)
420 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
421 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
423 TCHAR szFilename[ MAX_PATH ] = TEXT("");
424 if (Browse_Open (hDlg, szFilename, NULL, IDS_FILTER_TXT, 0, NULL, 0))
426 FastList_Begin (l.hList);
428 // Open the file and read it into memory.
431 if ((fh = CreateFile (szFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
433 DWORD cbLength = GetFileSize (fh, NULL);
434 LPTSTR pszBuffer = (LPTSTR)Allocate (sizeof(TCHAR) * (cbLength +2));
437 if (ReadFile (fh, pszBuffer, cbLength, &cbRead, NULL))
439 pszBuffer[ cbRead ] = TEXT('\0');
440 pszBuffer[ cbRead+1 ] = TEXT('\0');
442 // Scan the file line-by-line...
444 LPTSTR pszStart = pszBuffer;
445 while (pszStart && *pszStart)
447 while (iswhiteeol(*pszStart))
450 LPTSTR pszEnd = pszStart;
451 while (*pszEnd && !iseol(*pszEnd))
453 *pszEnd++ = TEXT('\0');
455 // Okay, {pszStart} points to a 0-terminated line in this file.
456 // If the line starts with '#', ';' or '//', skip it.
458 if ( (pszStart[0] != TEXT('#')) &&
459 (pszStart[0] != TEXT(';')) &&
460 ((pszStart[0] != TEXT('/')) || (pszStart[1] != TEXT('/'))) )
462 // Break the line up into two sections: the machine name,
465 TCHAR szServer[ MAX_PATH ];
466 for (LPTSTR pszOut = szServer; *pszStart && !iswhite(*pszStart); )
467 *pszOut++ = *pszStart++;
468 *pszOut = TEXT('\0');
470 while (iswhite(*pszStart))
473 TCHAR szRank[ MAX_PATH ];
474 for (pszOut = szRank; *pszStart && !iswhite(*pszStart); )
475 *pszOut++ = *pszStart++;
476 *pszOut = TEXT('\0');
478 PrefsTab_AddItem (hDlg, szServer, atoi(szRank));
481 // Process the next line in the file.
491 // Restart the background thread, to resolve unknown IP address
493 PrefsTab_OnRefresh (hDlg);
494 FastList_End (l.hList);
495 g.Configuration.fChangedPrefs = TRUE;
500 void PrefsTab_MergeServerPrefs (PSERVERPREFS pGlobal, PSERVERPREFS pAdd)
502 LPHASHLIST pList = New (HASHLIST);
503 LPHASHLISTKEY pKey = pList->CreateKey (TEXT("IP Address"), IPKey_Compare, IPKey_HashObject, IPKey_HashData);
505 for (size_t ii = 0; ii < pGlobal->cPrefs; ++ii)
507 if (!pGlobal->aPrefs[ ii ].ipServer)
509 pList->Add (&pGlobal->aPrefs[ ii ]);
513 for (ii = 0; ii < pAdd->cPrefs; ++ii)
515 if (!pAdd->aPrefs[ ii ].ipServer)
518 // The whole point of using a hashlist here is to allow this next call--
519 // on a hashlist, lookup and add are both constant-time, turning this
520 // merge into O(N) instead of (O(N^2))
522 if (pKey->GetFirstObject (&pAdd->aPrefs[ ii ].ipServer))
525 for ( ; iOut < pGlobal->cPrefs; ++iOut)
527 if (!pGlobal->aPrefs[ iOut ].ipServer)
531 if (REALLOC (pGlobal->aPrefs, pGlobal->cPrefs, 1+iOut, cREALLOC_PREFS))
533 memcpy (&pGlobal->aPrefs[ iOut ], &pAdd->aPrefs[ ii ], sizeof(SERVERPREFS));
542 void PrefsTab_AddItem (HWND hDlg, PSERVERPREF pPref, BOOL fSelect)
544 BOOL fVLServers = IsDlgButtonChecked (hDlg, IDC_SHOW_VLS);
545 PSERVERPREFS pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
547 for (size_t ii = 0; ii < pPrefs->cPrefs; ++ii)
549 if (pPrefs->aPrefs[ ii ].ipServer == pPref->ipServer)
552 if (ii == pPrefs->cPrefs)
554 for (ii = 0; ii < pPrefs->cPrefs; ++ii)
556 if (!pPrefs->aPrefs[ ii ].ipServer)
559 if (!REALLOC (pPrefs->aPrefs, pPrefs->cPrefs, 1+ii, cREALLOC_PREFS))
561 memcpy (&pPrefs->aPrefs[ ii ], pPref, sizeof(SERVERPREF));
564 FastList_Begin (l.hList);
566 if (!pPrefs->aPrefs[ ii ].hItem)
568 TCHAR szItem[ cchRESOURCE ];
569 if (!pPrefs->aPrefs[ ii ].szServer[0])
571 lstrcpy (szItem, inet_ntoa (*(struct in_addr *)&pPrefs->aPrefs[ ii ].ipServer));
575 wsprintf (szItem, TEXT("%s (%s)"),
576 pPrefs->aPrefs[ ii ].szServer,
577 inet_ntoa (*(struct in_addr *)&pPrefs->aPrefs[ ii ].ipServer));
581 memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
582 ai.iFirstImage = IMAGE_NOIMAGE;
583 ai.iSecondImage = IMAGE_NOIMAGE;
586 pPrefs->aPrefs[ ii ].hItem = FastList_AddItem (l.hList, &ai);
589 TCHAR szText[ cchRESOURCE ];
590 wsprintf (szText, TEXT("%ld"), pPrefs->aPrefs[ ii ].iRank);
591 FastList_SetItemText (l.hList, pPrefs->aPrefs[ ii ].hItem, 1, szText);
592 pPrefs->aPrefs[ ii ].fChanged = TRUE;
594 FastList_End (l.hList);
598 FastList_SelectItem (l.hList, pPrefs->aPrefs[ ii ].hItem, TRUE);
599 FastList_SetFocus (l.hList, pPrefs->aPrefs[ ii ].hItem);
600 FastList_EnsureVisible (l.hList, pPrefs->aPrefs[ ii ].hItem);
601 PrefsTab_OnSelect (hDlg);
606 void PrefsTab_AddItem (HWND hDlg, LPCTSTR pszServer, int iRank)
608 if ((iRank < 1) || (iRank > 65534))
612 memset (&Pref, 0x00, sizeof(SERVERPREF));
615 // If the server's name is an IP address, we'll translate it later
616 // when we do them en masse.
618 if (isdigit (pszServer[0]))
620 if ((Pref.ipServer = inet_addr (pszServer)) == INADDR_NONE)
623 else // (!isdigit (pszServer[0]))
626 if ((pEntry = gethostbyname (pszServer)) != NULL)
628 lstrcpy (Pref.szServer, pEntry->h_name);
629 Pref.ipServer = *(int *)pEntry->h_addr;
633 PrefsTab_AddItem (hDlg, &Pref, FALSE);
637 DWORD WINAPI PrefsTab_RefreshThread (PVOID lp)
639 HWND hDlg = (HWND)lp;
640 static BOOL *pfStopFlag = NULL;
642 // We may have a background thread or two working on resolving IP addresses.
643 // Flag them to stop.
645 EnterCriticalSection (&l.cs);
651 pfStopFlag = NULL; // Thread will free this when it terminates
653 // Retrieve PSERVERPREFS structures, and merge them into our globals
655 PSERVERPREFS pVLServers = Config_GetServerPrefs (TRUE);
656 PSERVERPREFS pFServers = Config_GetServerPrefs (FALSE);
658 if (!g.Configuration.pVLServers)
659 g.Configuration.pVLServers = pVLServers;
660 else if (g.Configuration.pVLServers && pVLServers)
661 PrefsTab_MergeServerPrefs (g.Configuration.pVLServers, pVLServers);
663 if (!g.Configuration.pFServers)
664 g.Configuration.pFServers = pFServers;
665 else if (g.Configuration.pFServers && pFServers)
666 PrefsTab_MergeServerPrefs (g.Configuration.pFServers, pFServers);
668 // Add entries to the fastlist
670 PrefsTab_OnFillList (hDlg);
672 // Fire up a background thread to resolve IP addresses into server names
674 pfStopFlag = New (BOOL);
678 CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)PrefsTab_ThreadProc, (PVOID)pfStopFlag, 0, &idThread);
679 l.fThreadActive = TRUE;
681 // Enable or disable controls based on whether the service is running
683 BOOL fRunning = (Config_GetServiceState() == SERVICE_RUNNING) ? TRUE : FALSE;
685 EnableWindow (GetDlgItem (hDlg, IDC_SHOW_FS), fRunning);
686 EnableWindow (GetDlgItem (hDlg, IDC_SHOW_VLS), fRunning);
687 EnableWindow (GetDlgItem (hDlg, IDC_LIST), fRunning);
688 EnableWindow (GetDlgItem (hDlg, IDC_UP), fRunning);
689 EnableWindow (GetDlgItem (hDlg, IDC_DOWN), fRunning);
690 EnableWindow (GetDlgItem (hDlg, IDC_IMPORT), fRunning);
691 EnableWindow (GetDlgItem (hDlg, IDC_ADD), fRunning);
692 EnableWindow (GetDlgItem (hDlg, IDC_EDIT), fRunning);
693 PrefsTab_OnSelect (hDlg);
695 TCHAR szText[ cchRESOURCE ];
696 GetString (szText, (fRunning) ? IDS_TIP_PREFS : IDS_WARN_STOPPED);
697 SetDlgItemText (hDlg, IDC_WARN, szText);
701 LeaveCriticalSection (&l.cs);
706 DWORD WINAPI PrefsTab_ThreadProc (PVOID lp)
708 BOOL *pfStopFlag = (BOOL*)lp;
711 PrefsTab_ThreadProcFunc (g.Configuration.pFServers, pfStopFlag);
712 PrefsTab_ThreadProcFunc (g.Configuration.pVLServers, pfStopFlag);
714 l.fThreadActive = FALSE;
721 void PrefsTab_ThreadProcFunc (PSERVERPREFS pPrefs, BOOL *pfStopFlag)
723 for (size_t ii = 0; ; ++ii)
725 // Find the next IP address to translate
727 EnterCriticalSection (&l.cs);
729 if ( (*pfStopFlag) || (ii >= pPrefs->cPrefs) )
731 LeaveCriticalSection (&l.cs);
736 if ( ((ipServer = pPrefs->aPrefs[ ii ].ipServer) == 0) ||
737 (pPrefs->aPrefs[ ii ].szServer[0] != TEXT('\0')) )
739 LeaveCriticalSection (&l.cs);
743 LeaveCriticalSection (&l.cs);
745 // Translate this IP address into a name
748 if ((pEntry = gethostbyaddr ((char*)&ipServer, sizeof(ipServer), AF_INET)) == NULL)
751 // Update the SERVERPREFS list, and if necessary, update the display
752 // to show the server's name
754 EnterCriticalSection (&l.cs);
758 if ((ii < pPrefs->cPrefs) && (ipServer == pPrefs->aPrefs[ ii ].ipServer))
760 lstrcpy (pPrefs->aPrefs[ ii ].szServer, pEntry->h_name);
761 if (pPrefs->aPrefs[ ii ].szServer[0])
763 if (pPrefs->aPrefs[ ii ].hItem)
765 TCHAR szItem[ cchRESOURCE ];
766 wsprintf (szItem, TEXT("%s (%s)"),
767 pPrefs->aPrefs[ ii ].szServer,
768 inet_ntoa (*(struct in_addr *)&pPrefs->aPrefs[ ii ].ipServer));
770 FastList_SetItemText (l.hList, pPrefs->aPrefs[ ii ].hItem, 0, szItem);
776 LeaveCriticalSection (&l.cs);
781 int CALLBACK PrefsTab_SortFunction (HWND hList, HLISTITEM hItem1, LPARAM lpItem1, HLISTITEM hItem2, LPARAM lpItem2)
783 static PSERVERPREFS pPrefs = NULL;
784 if (!hItem1 || !hItem2)
786 BOOL fVLServers = IsDlgButtonChecked (GetParent(hList), IDC_SHOW_VLS);
787 pPrefs = (fVLServers) ? g.Configuration.pVLServers : g.Configuration.pFServers;
791 if (!pPrefs || (pPrefs->cPrefs <= (size_t)lpItem1) || (pPrefs->cPrefs <= (size_t)lpItem2))
794 PSERVERPREF pPref1 = &pPrefs->aPrefs[ lpItem1 ];
795 PSERVERPREF pPref2 = &pPrefs->aPrefs[ lpItem2 ];
797 if (pPref1->iRank != pPref2->iRank)
798 return pPref1->iRank - pPref2->iRank;
800 ULONG ip1 = (ULONG)htonl (pPref1->ipServer);
801 ULONG ip2 = (ULONG)htonl (pPref2->ipServer);
802 return (ip1 < ip2) ? -1 : 1;
806 BOOL CALLBACK IPKey_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
808 return (((PSERVERPREF)pObject)->ipServer == *(int*)pData);
811 HASHVALUE CALLBACK IPKey_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
813 return IPKey_HashData (pKey, &((PSERVERPREF)pObject)->ipServer);
816 HASHVALUE CALLBACK IPKey_HashData (LPHASHLISTKEY pKey, PVOID pData)
822 BOOL CALLBACK PrefsEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
827 SetWindowLong (hDlg, DWL_USER, lp);
828 PrefsEdit_OnInitDialog (hDlg);
829 PrefsEdit_Enable (hDlg);
836 PrefsEdit_Enable (hDlg);
840 PrefsEdit_OnOK (hDlg);
844 EndDialog (hDlg, IDCANCEL);
848 PrefsEdit_DlgProc (hDlg, WM_HELP, 0, 0);
854 WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_PREFS_NT_ADDEDIT);
862 void PrefsEdit_OnInitDialog (HWND hDlg)
864 PSERVERPREF pPref = (PSERVERPREF)GetWindowLong (hDlg, DWL_USER);
867 EnableWindow (GetDlgItem (hDlg, IDC_SERVER), FALSE);
869 if (pPref->szServer[0])
871 SetDlgItemText (hDlg, IDC_SERVER, pPref->szServer);
873 else if (pPref->ipServer)
875 SetDlgItemText (hDlg, IDC_SERVER, inet_ntoa (*(struct in_addr *)&pPref->ipServer));
878 CreateSpinner (GetDlgItem (hDlg, IDC_RANK), 10, FALSE, 1, pPref->iRank, 65534);
882 void PrefsEdit_OnOK (HWND hDlg)
884 PSERVERPREF pPref = (PSERVERPREF)GetWindowLong (hDlg, DWL_USER);
885 pPref->iRank = SP_GetPos (GetDlgItem (hDlg, IDC_RANK));
887 if (IsWindowEnabled (GetDlgItem (hDlg, IDC_SERVER)))
892 TCHAR szServer[ cchRESOURCE ];
893 GetDlgItemText (hDlg, IDC_SERVER, szServer, cchRESOURCE);
894 if (isdigit (szServer[0]))
896 if ((pPref->ipServer = inet_addr (szServer)) == INADDR_NONE)
899 status = WSAGetLastError();
904 if ((pEntry = gethostbyaddr ((char*)&pPref->ipServer, sizeof(pPref->ipServer), AF_INET)) != NULL)
905 lstrcpy (pPref->szServer, pEntry->h_name);
908 else // (!isdigit(pData->szServer[0]))
911 if ((pEntry = gethostbyname (szServer)) == NULL)
914 status = WSAGetLastError();
918 lstrcpy (pPref->szServer, pEntry->h_name);
919 pPref->ipServer = *(int *)pEntry->h_addr;
925 Message (MB_ICONHAND | MB_OK, GetErrorTitle(), IDS_PREFERROR_RESOLVE, TEXT("%s%08lX"), szServer, status);
930 EndDialog (hDlg, IDOK);
934 void PrefsEdit_Enable (HWND hDlg)
936 TCHAR szServer[ cchRESOURCE ];
937 GetDlgItemText (hDlg, IDC_SERVER, szServer, cchRESOURCE);
939 EnableWindow (GetDlgItem (hDlg, IDOK), !!szServer[0]);