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
14 #include <afs/param.h>
18 #include "afs_config.h"
19 #include "tab_prefs.h"
25 * VARIABLES __________________________________________________________________
36 #define cREALLOC_PREFS 32
39 #define iswhite(_ch) (((_ch)==TEXT(' ')) || ((_ch)==TEXT('\t')))
42 #define iseol(_ch) (((_ch)==TEXT('\r')) || ((_ch)==TEXT('\n')))
45 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
50 * PROTOTYPES _________________________________________________________________
54 void PrefsTab_OnInitDialog (HWND hDlg
);
55 BOOL
PrefsTab_OnApply (HWND hDlg
);
56 void PrefsTab_OnRefresh (HWND hDlg
);
57 void PrefsTab_OnFillList (HWND hDlg
);
58 void PrefsTab_OnSelect (HWND hDlg
);
59 void PrefsTab_OnUpDown (HWND hDlg
, BOOL fDown
);
60 void PrefsTab_OnAdd (HWND hDlg
);
61 void PrefsTab_OnEdit (HWND hDlg
);
62 void PrefsTab_OnImport (HWND hDlg
);
64 void PrefsTab_MergeServerPrefs (PSERVERPREFS pGlobal
, PSERVERPREFS pAdd
);
65 void PrefsTab_AddItem (HWND hDlg
, PSERVERPREF pPref
, BOOL fSelect
);
66 void PrefsTab_AddItem (HWND hDlg
, LPCTSTR pszServer
, int iRank
);
68 DWORD WINAPI
PrefsTab_RefreshThread (PVOID lp
);
69 DWORD WINAPI
PrefsTab_ThreadProc (PVOID lp
);
70 void PrefsTab_ThreadProcFunc (PSERVERPREFS pPrefs
, BOOL
*pfStopFlag
);
72 int CALLBACK
PrefsTab_SortFunction (HWND hList
, HLISTITEM hItem1
, LPARAM lpItem1
, HLISTITEM hItem2
, LPARAM lpItem2
);
74 BOOL CALLBACK
IPKey_Compare (LPHASHLISTKEY pKey
, PVOID pObject
, PVOID pData
);
75 HASHVALUE CALLBACK
IPKey_HashObject (LPHASHLISTKEY pKey
, PVOID pObject
);
76 HASHVALUE CALLBACK
IPKey_HashData (LPHASHLISTKEY pKey
, PVOID pData
);
78 BOOL CALLBACK
PrefsEdit_DlgProc (HWND hDlg
, UINT msg
, WPARAM wp
, LPARAM lp
);
79 void PrefsEdit_OnInitDialog (HWND hDlg
);
80 void PrefsEdit_OnOK (HWND hDlg
);
81 void PrefsEdit_Enable (HWND hDlg
);
85 * ROUTINES ___________________________________________________________________
89 BOOL CALLBACK
PrefsTab_DlgProc (HWND hDlg
, UINT msg
, WPARAM wp
, LPARAM lp
)
94 InitializeCriticalSection (&l
.cs
);
95 PrefsTab_OnInitDialog (hDlg
);
102 if (!PrefsTab_OnApply (hDlg
))
103 SetWindowLongPtr (hDlg
, DWLP_MSGRESULT
, TRUE
);
107 PrefsTab_OnRefresh (hDlg
);
112 PrefsTab_OnFillList (hDlg
);
116 PrefsTab_OnAdd (hDlg
);
120 PrefsTab_OnEdit (hDlg
);
124 PrefsTab_OnUpDown (hDlg
, FALSE
);
128 PrefsTab_OnUpDown (hDlg
, TRUE
);
132 PrefsTab_OnImport (hDlg
);
136 PrefsTab_DlgProc (hDlg
, WM_HELP
, 0, 0);
142 WinHelp (hDlg
, g
.szHelpFile
, HELP_CONTEXT
, IDH_AFSCONFIG_PREFS_NT
);
146 switch (((LPNMHDR
)lp
)->code
)
149 PrefsTab_OnSelect (hDlg
);
153 if (IsWindowEnabled (GetDlgItem (hDlg
, IDC_EDIT
)))
154 PrefsTab_OnEdit (hDlg
);
164 void PrefsTab_OnInitDialog (HWND hDlg
)
166 HICON hiUp
= TaLocale_LoadIcon (IDI_UP
);
167 HICON hiDown
= TaLocale_LoadIcon (IDI_DOWN
);
169 SendDlgItemMessage (hDlg
, IDC_UP
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)hiUp
);
170 SendDlgItemMessage (hDlg
, IDC_DOWN
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)hiDown
);
172 CheckDlgButton (hDlg
, IDC_SHOW_FS
, TRUE
);
173 CheckDlgButton (hDlg
, IDC_SHOW_VLS
, FALSE
);
175 l
.hList
= GetDlgItem (hDlg
, IDC_LIST
);
177 FASTLISTCOLUMN Column
;
178 Column
.dwFlags
= FLCF_JUSTIFY_LEFT
;
179 Column
.cxWidth
= 200;
180 GetString (Column
.szText
, IDS_PREFCOL_SERVER
);
181 FastList_SetColumn (l
.hList
, 0, &Column
);
183 Column
.dwFlags
= FLCF_JUSTIFY_RIGHT
;
185 GetString (Column
.szText
, IDS_PREFCOL_RANK
);
186 FastList_SetColumn (l
.hList
, 1, &Column
);
188 FastList_SetSortFunction (l
.hList
, PrefsTab_SortFunction
);
190 PrefsTab_OnFillList (hDlg
);
191 PrefsTab_OnRefresh (hDlg
);
195 BOOL
PrefsTab_CommitChanges (BOOL fForce
)
198 if ((hDlg
= PropSheet_FindTabWindow (g
.psh
, (DLGPROC
)PrefsTab_DlgProc
)) == NULL
)
201 SetWindowLongPtr (hDlg
, DWLP_MSGRESULT
, FALSE
); // Make sure we try to apply
202 if (PrefsTab_OnApply (hDlg
))
204 SetWindowLongPtr (hDlg
, DWLP_MSGRESULT
, TRUE
);
209 BOOL
PrefsTab_OnApply (HWND hDlg
)
211 // Don't try to do anything if we've already failed the apply
212 if (GetWindowLongPtr (hDlg
, DWLP_MSGRESULT
))
215 if (g
.Configuration
.pFServers
&& g
.Configuration
.fChangedPrefs
)
217 if (!Config_SetServerPrefs (g
.Configuration
.pFServers
))
220 if (g
.Configuration
.pVLServers
&& g
.Configuration
.fChangedPrefs
)
222 if (!Config_SetServerPrefs (g
.Configuration
.pVLServers
))
225 g
.Configuration
.fChangedPrefs
= FALSE
;
230 void PrefsTab_OnRefresh (HWND hDlg
)
233 CreateThread (NULL
, 0, (LPTHREAD_START_ROUTINE
)PrefsTab_RefreshThread
, (PVOID
)hDlg
, 0, &idThread
);
237 void PrefsTab_OnFillList (HWND hDlg
)
239 EnterCriticalSection (&l
.cs
);
240 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
242 // Empty the fastlist, and clear from the lists any mention of HLISTITEMs.
244 FastList_Begin (l
.hList
);
245 FastList_RemoveAll (l
.hList
);
247 if (g
.Configuration
.pVLServers
)
249 for (size_t ii
= 0; ii
< g
.Configuration
.pVLServers
->cPrefs
; ++ii
)
250 g
.Configuration
.pVLServers
->aPrefs
[ ii
].hItem
= NULL
;
252 if (g
.Configuration
.pFServers
)
254 for (size_t ii
= 0; ii
< g
.Configuration
.pFServers
->cPrefs
; ++ii
)
255 g
.Configuration
.pFServers
->aPrefs
[ ii
].hItem
= NULL
;
258 // Fill in the fastlist by adding entries from the appropriate prefslist.
260 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
263 for (size_t ii
= 0; ii
< pPrefs
->cPrefs
; ++ii
)
265 if (!pPrefs
->aPrefs
[ ii
].ipServer
)
268 TCHAR szItem
[ cchRESOURCE
];
269 if (!pPrefs
->aPrefs
[ ii
].szServer
[0])
271 lstrcpy (szItem
, inet_ntoa (*(struct in_addr
*)&pPrefs
->aPrefs
[ ii
].ipServer
));
275 wsprintf (szItem
, TEXT("%s (%s)"),
276 pPrefs
->aPrefs
[ ii
].szServer
,
277 inet_ntoa (*(struct in_addr
*)&pPrefs
->aPrefs
[ ii
].ipServer
));
281 memset (&ai
, 0x00, sizeof(FASTLISTADDITEM
));
282 ai
.iFirstImage
= IMAGE_NOIMAGE
;
283 ai
.iSecondImage
= IMAGE_NOIMAGE
;
286 pPrefs
->aPrefs
[ ii
].hItem
= FastList_AddItem (l
.hList
, &ai
);
288 wsprintf (szItem
, TEXT("%ld"), pPrefs
->aPrefs
[ ii
].iRank
);
289 FastList_SetItemText (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
, 1, szItem
);
295 FastList_End (l
.hList
);
296 LeaveCriticalSection (&l
.cs
);
297 PrefsTab_OnSelect (hDlg
);
301 void PrefsTab_OnSelect (HWND hDlg
)
303 if (IsWindowEnabled (l
.hList
))
305 HLISTITEM hItem
= FastList_FindFirstSelected (l
.hList
);
306 HLISTITEM hItemFirst
= FastList_FindFirst (l
.hList
);
307 HLISTITEM hItemNext
= FastList_FindNext (l
.hList
, hItem
);
309 EnableWindow (GetDlgItem (hDlg
, IDC_UP
), (hItem
&& (hItem
!= hItemFirst
)));
310 EnableWindow (GetDlgItem (hDlg
, IDC_DOWN
), (hItem
&& hItemNext
));
311 EnableWindow (GetDlgItem (hDlg
, IDC_ADD
), TRUE
);
312 EnableWindow (GetDlgItem (hDlg
, IDC_IMPORT
), TRUE
);
313 EnableWindow (GetDlgItem (hDlg
, IDC_EDIT
), !!hItem
);
318 void PrefsTab_OnUpDown (HWND hDlg
, BOOL fDown
)
320 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
321 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
324 if ((hItem
= FastList_FindFirstSelected (l
.hList
)) == NULL
)
328 hOther
= (fDown
) ? FastList_FindNext(l
.hList
,hItem
) : FastList_FindPrevious(l
.hList
,hItem
);
332 size_t iItem
= (size_t)FastList_GetItemParam (l
.hList
, hItem
);
333 size_t iOther
= (size_t)FastList_GetItemParam (l
.hList
, hOther
);
335 if (!pPrefs
|| (pPrefs
->cPrefs
<= iItem
) || (pPrefs
->cPrefs
<= iOther
))
338 FastList_Begin (l
.hList
);
340 PSERVERPREF pPref1
= &pPrefs
->aPrefs
[ iItem
];
341 PSERVERPREF pPref2
= &pPrefs
->aPrefs
[ iOther
];
343 if (pPref1
->iRank
== pPref2
->iRank
)
345 if (fDown
&& (pPref1
->iRank
< 65534))
347 else if ((!fDown
) && (pPref1
->iRank
> 1))
349 pPref1
->fChanged
= TRUE
;
351 else // (pPref1->iRating != pPref2->iRating)
353 pPref1
->iRank
^= pPref2
->iRank
;
354 pPref2
->iRank
^= pPref1
->iRank
;
355 pPref1
->iRank
^= pPref2
->iRank
;
356 pPref1
->fChanged
= TRUE
;
357 pPref2
->fChanged
= TRUE
;
360 TCHAR szText
[ cchRESOURCE
];
361 wsprintf (szText
, TEXT("%ld"), pPref1
->iRank
);
362 FastList_SetItemText (l
.hList
, pPref1
->hItem
, 1, szText
);
364 wsprintf (szText
, TEXT("%ld"), pPref2
->iRank
);
365 FastList_SetItemText (l
.hList
, pPref2
->hItem
, 1, szText
);
367 FastList_EnsureVisible (l
.hList
, hItem
);
368 FastList_End (l
.hList
);
369 PrefsTab_OnSelect (hDlg
);
371 g
.Configuration
.fChangedPrefs
= TRUE
;
375 void PrefsTab_OnAdd (HWND hDlg
)
377 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
378 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
381 memset (&Pref
, 0x00, sizeof(SERVERPREF
));
384 if (ModalDialogParam (IDD_PREFS_EDIT
, GetParent(hDlg
), (DLGPROC
)PrefsEdit_DlgProc
, (LPARAM
)&Pref
) == IDOK
)
386 PrefsTab_AddItem (hDlg
, &Pref
, TRUE
);
387 PrefsTab_OnSelect (hDlg
);
388 g
.Configuration
.fChangedPrefs
= TRUE
;
393 void PrefsTab_OnEdit (HWND hDlg
)
395 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
396 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
399 if ((hItem
= FastList_FindFirstSelected (l
.hList
)) == NULL
)
402 PSERVERPREF pPref
= &pPrefs
->aPrefs
[ FastList_GetItemParam (l
.hList
, hItem
) ];
404 if (ModalDialogParam (IDD_PREFS_EDIT
, GetParent(hDlg
), (DLGPROC
)PrefsEdit_DlgProc
, (LPARAM
)pPref
) == IDOK
)
406 FastList_Begin (l
.hList
);
408 TCHAR szText
[ cchRESOURCE
];
409 wsprintf (szText
, TEXT("%ld"), pPref
->iRank
);
410 FastList_SetItemText (l
.hList
, pPref
->hItem
, 1, szText
);
411 pPref
->fChanged
= TRUE
;
413 FastList_EnsureVisible (l
.hList
, hItem
);
414 FastList_End (l
.hList
);
415 PrefsTab_OnSelect (hDlg
);
416 g
.Configuration
.fChangedPrefs
= TRUE
;
421 void PrefsTab_OnImport (HWND hDlg
)
423 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
424 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
426 TCHAR szFilename
[ MAX_PATH
] = TEXT("");
427 if (Browse_Open (hDlg
, szFilename
, NULL
, IDS_FILTER_TXT
, 0, NULL
, 0))
429 FastList_Begin (l
.hList
);
431 // Open the file and read it into memory.
434 if ((fh
= CreateFile (szFilename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
)) != INVALID_HANDLE_VALUE
)
436 DWORD cbLength
= GetFileSize (fh
, NULL
);
437 LPTSTR pszBuffer
= (LPTSTR
)Allocate (sizeof(TCHAR
) * (cbLength
+2));
440 if (ReadFile (fh
, pszBuffer
, cbLength
, &cbRead
, NULL
))
442 pszBuffer
[ cbRead
] = TEXT('\0');
443 pszBuffer
[ cbRead
+1 ] = TEXT('\0');
445 // Scan the file line-by-line...
447 LPTSTR pszStart
= pszBuffer
;
448 while (pszStart
&& *pszStart
)
450 while (iswhiteeol(*pszStart
))
453 LPTSTR pszEnd
= pszStart
;
454 while (*pszEnd
&& !iseol(*pszEnd
))
456 *pszEnd
++ = TEXT('\0');
458 // Okay, {pszStart} points to a 0-terminated line in this file.
459 // If the line starts with '#', ';' or '//', skip it.
461 if ( (pszStart
[0] != TEXT('#')) &&
462 (pszStart
[0] != TEXT(';')) &&
463 ((pszStart
[0] != TEXT('/')) || (pszStart
[1] != TEXT('/'))) )
465 // Break the line up into two sections: the machine name,
468 TCHAR szServer
[ MAX_PATH
];
470 for (pszOut
= szServer
; *pszStart
&& !iswhite(*pszStart
); )
471 *pszOut
++ = *pszStart
++;
472 *pszOut
= TEXT('\0');
474 while (iswhite(*pszStart
))
477 TCHAR szRank
[ MAX_PATH
];
478 for (pszOut
= szRank
; *pszStart
&& !iswhite(*pszStart
); )
479 *pszOut
++ = *pszStart
++;
480 *pszOut
= TEXT('\0');
482 PrefsTab_AddItem (hDlg
, szServer
, atoi(szRank
));
485 // Process the next line in the file.
495 // Restart the background thread, to resolve unknown IP address
497 PrefsTab_OnRefresh (hDlg
);
498 FastList_End (l
.hList
);
499 g
.Configuration
.fChangedPrefs
= TRUE
;
504 void PrefsTab_MergeServerPrefs (PSERVERPREFS pGlobal
, PSERVERPREFS pAdd
)
506 LPHASHLIST pList
= New (HASHLIST
);
507 LPHASHLISTKEY pKey
= pList
->CreateKey (TEXT("IP Address"), IPKey_Compare
, IPKey_HashObject
, IPKey_HashData
);
510 for (ii
= 0; ii
< pGlobal
->cPrefs
; ++ii
)
512 if (!pGlobal
->aPrefs
[ ii
].ipServer
)
514 pList
->Add (&pGlobal
->aPrefs
[ ii
]);
518 for (ii
= 0; ii
< pAdd
->cPrefs
; ++ii
)
520 if (!pAdd
->aPrefs
[ ii
].ipServer
)
523 // The whole point of using a hashlist here is to allow this next call--
524 // on a hashlist, lookup and add are both constant-time, turning this
525 // merge into O(N) instead of (O(N^2))
527 if (pKey
->GetFirstObject (&pAdd
->aPrefs
[ ii
].ipServer
))
530 for ( ; iOut
< pGlobal
->cPrefs
; ++iOut
)
532 if (!pGlobal
->aPrefs
[ iOut
].ipServer
)
536 if (REALLOC (pGlobal
->aPrefs
, pGlobal
->cPrefs
, 1+iOut
, cREALLOC_PREFS
))
538 memcpy (&pGlobal
->aPrefs
[ iOut
], &pAdd
->aPrefs
[ ii
], sizeof(SERVERPREFS
));
547 void PrefsTab_AddItem (HWND hDlg
, PSERVERPREF pPref
, BOOL fSelect
)
549 BOOL fVLServers
= IsDlgButtonChecked (hDlg
, IDC_SHOW_VLS
);
550 PSERVERPREFS pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
553 for (ii
= 0; ii
< pPrefs
->cPrefs
; ++ii
)
555 if (pPrefs
->aPrefs
[ ii
].ipServer
== pPref
->ipServer
)
558 if (ii
== pPrefs
->cPrefs
)
560 for (ii
= 0; ii
< pPrefs
->cPrefs
; ++ii
)
562 if (!pPrefs
->aPrefs
[ ii
].ipServer
)
565 if (!REALLOC (pPrefs
->aPrefs
, pPrefs
->cPrefs
, 1+ii
, cREALLOC_PREFS
))
567 memcpy (&pPrefs
->aPrefs
[ ii
], pPref
, sizeof(SERVERPREF
));
570 FastList_Begin (l
.hList
);
572 if (!pPrefs
->aPrefs
[ ii
].hItem
)
574 TCHAR szItem
[ cchRESOURCE
];
575 if (!pPrefs
->aPrefs
[ ii
].szServer
[0])
577 lstrcpy (szItem
, inet_ntoa (*(struct in_addr
*)&pPrefs
->aPrefs
[ ii
].ipServer
));
581 wsprintf (szItem
, TEXT("%s (%s)"),
582 pPrefs
->aPrefs
[ ii
].szServer
,
583 inet_ntoa (*(struct in_addr
*)&pPrefs
->aPrefs
[ ii
].ipServer
));
587 memset (&ai
, 0x00, sizeof(FASTLISTADDITEM
));
588 ai
.iFirstImage
= IMAGE_NOIMAGE
;
589 ai
.iSecondImage
= IMAGE_NOIMAGE
;
592 pPrefs
->aPrefs
[ ii
].hItem
= FastList_AddItem (l
.hList
, &ai
);
595 TCHAR szText
[ cchRESOURCE
];
596 wsprintf (szText
, TEXT("%ld"), pPrefs
->aPrefs
[ ii
].iRank
);
597 FastList_SetItemText (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
, 1, szText
);
598 pPrefs
->aPrefs
[ ii
].fChanged
= TRUE
;
600 FastList_End (l
.hList
);
604 FastList_SelectItem (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
, TRUE
);
605 FastList_SetFocus (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
);
606 FastList_EnsureVisible (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
);
607 PrefsTab_OnSelect (hDlg
);
612 void PrefsTab_AddItem (HWND hDlg
, LPCTSTR pszServer
, int iRank
)
614 if ((iRank
< 1) || (iRank
> 65534))
618 memset (&Pref
, 0x00, sizeof(SERVERPREF
));
621 // If the server's name is an IP address, we'll translate it later
622 // when we do them en masse.
624 if (isdigit (pszServer
[0]))
626 if ((Pref
.ipServer
= inet_addr (pszServer
)) == INADDR_NONE
)
629 else // (!isdigit (pszServer[0]))
632 if ((pEntry
= gethostbyname (pszServer
)) != NULL
)
634 lstrcpy (Pref
.szServer
, pEntry
->h_name
);
635 Pref
.ipServer
= *(int *)pEntry
->h_addr
;
639 PrefsTab_AddItem (hDlg
, &Pref
, FALSE
);
643 DWORD WINAPI
PrefsTab_RefreshThread (PVOID lp
)
645 HWND hDlg
= (HWND
)lp
;
646 static BOOL
*pfStopFlag
= NULL
;
648 // We may have a background thread or two working on resolving IP addresses.
649 // Flag them to stop.
651 EnterCriticalSection (&l
.cs
);
657 pfStopFlag
= NULL
; // Thread will free this when it terminates
659 // Retrieve PSERVERPREFS structures, and merge them into our globals
661 PSERVERPREFS pVLServers
= Config_GetServerPrefs (TRUE
);
662 PSERVERPREFS pFServers
= Config_GetServerPrefs (FALSE
);
664 if (!g
.Configuration
.pVLServers
)
665 g
.Configuration
.pVLServers
= pVLServers
;
666 else if (g
.Configuration
.pVLServers
&& pVLServers
)
667 PrefsTab_MergeServerPrefs (g
.Configuration
.pVLServers
, pVLServers
);
669 if (!g
.Configuration
.pFServers
)
670 g
.Configuration
.pFServers
= pFServers
;
671 else if (g
.Configuration
.pFServers
&& pFServers
)
672 PrefsTab_MergeServerPrefs (g
.Configuration
.pFServers
, pFServers
);
674 // Add entries to the fastlist
676 PrefsTab_OnFillList (hDlg
);
678 // Fire up a background thread to resolve IP addresses into server names
680 pfStopFlag
= New (BOOL
);
684 CreateThread (NULL
, 0, (LPTHREAD_START_ROUTINE
)PrefsTab_ThreadProc
, (PVOID
)pfStopFlag
, 0, &idThread
);
685 l
.fThreadActive
= TRUE
;
687 // Enable or disable controls based on whether the service is running
689 BOOL fRunning
= (Config_GetServiceState() == SERVICE_RUNNING
) ? TRUE
: FALSE
;
691 EnableWindow (GetDlgItem (hDlg
, IDC_SHOW_FS
), fRunning
);
692 EnableWindow (GetDlgItem (hDlg
, IDC_SHOW_VLS
), fRunning
);
693 EnableWindow (GetDlgItem (hDlg
, IDC_LIST
), fRunning
);
694 EnableWindow (GetDlgItem (hDlg
, IDC_UP
), fRunning
);
695 EnableWindow (GetDlgItem (hDlg
, IDC_DOWN
), fRunning
);
696 EnableWindow (GetDlgItem (hDlg
, IDC_IMPORT
), fRunning
);
697 EnableWindow (GetDlgItem (hDlg
, IDC_ADD
), fRunning
);
698 EnableWindow (GetDlgItem (hDlg
, IDC_EDIT
), fRunning
);
699 PrefsTab_OnSelect (hDlg
);
701 TCHAR szText
[ cchRESOURCE
];
702 GetString (szText
, (fRunning
) ? IDS_TIP_PREFS
: IDS_WARN_STOPPED
);
703 SetDlgItemText (hDlg
, IDC_WARN
, szText
);
707 LeaveCriticalSection (&l
.cs
);
712 DWORD WINAPI
PrefsTab_ThreadProc (PVOID lp
)
714 BOOL
*pfStopFlag
= (BOOL
*)lp
;
717 PrefsTab_ThreadProcFunc (g
.Configuration
.pFServers
, pfStopFlag
);
718 PrefsTab_ThreadProcFunc (g
.Configuration
.pVLServers
, pfStopFlag
);
720 l
.fThreadActive
= FALSE
;
727 void PrefsTab_ThreadProcFunc (PSERVERPREFS pPrefs
, BOOL
*pfStopFlag
)
729 for (size_t ii
= 0; ; ++ii
)
731 // Find the next IP address to translate
733 EnterCriticalSection (&l
.cs
);
735 if ( (*pfStopFlag
) || (ii
>= pPrefs
->cPrefs
) )
737 LeaveCriticalSection (&l
.cs
);
742 if ( ((ipServer
= pPrefs
->aPrefs
[ ii
].ipServer
) == 0) ||
743 (pPrefs
->aPrefs
[ ii
].szServer
[0] != TEXT('\0')) )
745 LeaveCriticalSection (&l
.cs
);
749 LeaveCriticalSection (&l
.cs
);
751 // Translate this IP address into a name
754 if ((pEntry
= gethostbyaddr ((char*)&ipServer
, sizeof(ipServer
), AF_INET
)) == NULL
)
757 // Update the SERVERPREFS list, and if necessary, update the display
758 // to show the server's name
760 EnterCriticalSection (&l
.cs
);
764 if ((ii
< pPrefs
->cPrefs
) && (ipServer
== pPrefs
->aPrefs
[ ii
].ipServer
))
766 lstrcpy (pPrefs
->aPrefs
[ ii
].szServer
, pEntry
->h_name
);
767 if (pPrefs
->aPrefs
[ ii
].szServer
[0])
769 if (pPrefs
->aPrefs
[ ii
].hItem
)
771 TCHAR szItem
[ cchRESOURCE
];
772 wsprintf (szItem
, TEXT("%s (%s)"),
773 pPrefs
->aPrefs
[ ii
].szServer
,
774 inet_ntoa (*(struct in_addr
*)&pPrefs
->aPrefs
[ ii
].ipServer
));
776 FastList_SetItemText (l
.hList
, pPrefs
->aPrefs
[ ii
].hItem
, 0, szItem
);
782 LeaveCriticalSection (&l
.cs
);
787 int CALLBACK
PrefsTab_SortFunction (HWND hList
, HLISTITEM hItem1
, LPARAM lpItem1
, HLISTITEM hItem2
, LPARAM lpItem2
)
789 static PSERVERPREFS pPrefs
= NULL
;
790 if (!hItem1
|| !hItem2
)
792 BOOL fVLServers
= IsDlgButtonChecked (GetParent(hList
), IDC_SHOW_VLS
);
793 pPrefs
= (fVLServers
) ? g
.Configuration
.pVLServers
: g
.Configuration
.pFServers
;
797 if (!pPrefs
|| (pPrefs
->cPrefs
<= (size_t)lpItem1
) || (pPrefs
->cPrefs
<= (size_t)lpItem2
))
800 PSERVERPREF pPref1
= &pPrefs
->aPrefs
[ lpItem1
];
801 PSERVERPREF pPref2
= &pPrefs
->aPrefs
[ lpItem2
];
803 if (pPref1
->iRank
!= pPref2
->iRank
)
804 return pPref1
->iRank
- pPref2
->iRank
;
806 ULONG ip1
= (ULONG
)htonl (pPref1
->ipServer
);
807 ULONG ip2
= (ULONG
)htonl (pPref2
->ipServer
);
808 return (ip1
< ip2
) ? -1 : 1;
812 BOOL CALLBACK
IPKey_Compare (LPHASHLISTKEY pKey
, PVOID pObject
, PVOID pData
)
814 return (((PSERVERPREF
)pObject
)->ipServer
== *(int*)pData
);
817 HASHVALUE CALLBACK
IPKey_HashObject (LPHASHLISTKEY pKey
, PVOID pObject
)
819 return IPKey_HashData (pKey
, &((PSERVERPREF
)pObject
)->ipServer
);
822 HASHVALUE CALLBACK
IPKey_HashData (LPHASHLISTKEY pKey
, PVOID pData
)
828 BOOL CALLBACK
PrefsEdit_DlgProc (HWND hDlg
, UINT msg
, WPARAM wp
, LPARAM lp
)
833 SetWindowLongPtr (hDlg
, DWLP_USER
, lp
);
834 PrefsEdit_OnInitDialog (hDlg
);
835 PrefsEdit_Enable (hDlg
);
842 PrefsEdit_Enable (hDlg
);
846 PrefsEdit_OnOK (hDlg
);
850 EndDialog (hDlg
, IDCANCEL
);
854 PrefsEdit_DlgProc (hDlg
, WM_HELP
, 0, 0);
860 WinHelp (hDlg
, g
.szHelpFile
, HELP_CONTEXT
, IDH_AFSCONFIG_PREFS_NT_ADDEDIT
);
868 void PrefsEdit_OnInitDialog (HWND hDlg
)
870 PSERVERPREF pPref
= (PSERVERPREF
)GetWindowLongPtr (hDlg
, DWLP_USER
);
873 EnableWindow (GetDlgItem (hDlg
, IDC_SERVER
), FALSE
);
875 if (pPref
->szServer
[0])
877 SetDlgItemText (hDlg
, IDC_SERVER
, pPref
->szServer
);
879 else if (pPref
->ipServer
)
881 SetDlgItemText (hDlg
, IDC_SERVER
, inet_ntoa (*(struct in_addr
*)&pPref
->ipServer
));
884 CreateSpinner (GetDlgItem (hDlg
, IDC_RANK
), 10, FALSE
, 1, pPref
->iRank
, 65534);
888 void PrefsEdit_OnOK (HWND hDlg
)
890 PSERVERPREF pPref
= (PSERVERPREF
)GetWindowLongPtr (hDlg
, DWLP_USER
);
891 pPref
->iRank
= SP_GetPos (GetDlgItem (hDlg
, IDC_RANK
));
893 if (IsWindowEnabled (GetDlgItem (hDlg
, IDC_SERVER
)))
898 TCHAR szServer
[ cchRESOURCE
];
899 GetDlgItemText (hDlg
, IDC_SERVER
, szServer
, cchRESOURCE
);
900 if (isdigit (szServer
[0]))
902 if ((pPref
->ipServer
= inet_addr (szServer
)) == INADDR_NONE
)
905 status
= WSAGetLastError();
910 if ((pEntry
= gethostbyaddr ((char*)&pPref
->ipServer
, sizeof(pPref
->ipServer
), AF_INET
)) != NULL
)
911 lstrcpy (pPref
->szServer
, pEntry
->h_name
);
914 else // (!isdigit(pData->szServer[0]))
917 if ((pEntry
= gethostbyname (szServer
)) == NULL
)
920 status
= WSAGetLastError();
924 lstrcpy (pPref
->szServer
, pEntry
->h_name
);
925 pPref
->ipServer
= *(int *)pEntry
->h_addr
;
931 Message (MB_ICONHAND
| MB_OK
, GetErrorTitle(), IDS_PREFERROR_RESOLVE
, TEXT("%s%08lX"), szServer
, status
);
936 EndDialog (hDlg
, IDOK
);
940 void PrefsEdit_Enable (HWND hDlg
)
942 TCHAR szServer
[ cchRESOURCE
];
943 GetDlgItemText (hDlg
, IDC_SERVER
, szServer
, cchRESOURCE
);
945 EnableWindow (GetDlgItem (hDlg
, IDOK
), !!szServer
[0]);