Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / client_config / tab_drives.cpp
1 extern "C" {
2 #include <afs/param.h>
3 #include <afs/stds.h>
4 }
5
6 #include "afs_config.h"
7 #include "tab_drives.h"
8
9
10 /*
11  * PROTOTYPES _________________________________________________________________
12  *
13  */
14
15 void DrivesTab_OnInitDialog (HWND hDlg);
16 void DrivesTab_OnSelect (HWND hDlg);
17 void DrivesTab_OnCheck (HWND hDlg);
18 void DrivesTab_OnAdd (HWND hDlg);
19 void DrivesTab_OnEdit (HWND hDlg);
20 void DrivesTab_OnRemove (HWND hDlg);
21 void DrivesTab_OnAdvanced (HWND hDlg);
22
23 void DrivesTab_Enable (HWND hDlg);
24 int DrivesTab_DriveFromItem (HWND hDlg, int iItem);
25 void DrivesTab_FillList (HWND hDlg);
26 void DrivesTab_EditMapping (HWND hDlg, int iDrive);
27
28 BOOL CALLBACK DriveEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
29 void DriveEdit_OnInitDialog (HWND hDlg);
30 void DriveEdit_OnOK (HWND hDlg);
31 void DriveEdit_Enable (HWND hDlg);
32
33 BOOL CALLBACK Submounts_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
34 void Submounts_OnInitDialog (HWND hDlg);
35 void Submounts_OnApply (HWND hDlg);
36 void Submounts_OnSelect (HWND hDlg);
37 void Submounts_OnAdd (HWND hDlg);
38 void Submounts_OnEdit (HWND hDlg);
39 void Submounts_OnRemove (HWND hDlg);
40 void Submounts_EditSubmount (HWND hDlg, PSUBMOUNT pSubmount);
41
42 BOOL CALLBACK SubEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
43 void SubEdit_OnInitDialog (HWND hDlg);
44 void SubEdit_OnOK (HWND hDlg);
45 void SubEdit_Enable (HWND hDlg);
46
47
48 /*
49  * ROUTINES ___________________________________________________________________
50  *
51  */
52
53 BOOL CALLBACK DrivesTab_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
54 {
55    switch (msg)
56       {
57       case WM_INITDIALOG:
58          DrivesTab_OnInitDialog (hDlg);
59          break;
60
61       case WM_COMMAND:
62          switch (LOWORD(wp))
63             {
64             case IDC_REFRESH:
65                DrivesTab_Enable (hDlg);
66                break;
67
68             case IDC_LIST:
69                if (HIWORD(wp) == LBN_CLICKED)
70                   DrivesTab_OnCheck (hDlg);
71                else if ((HIWORD(wp) == LBN_SELCHANGE) || (HIWORD(wp) == LBN_SELCANCEL))
72                   DrivesTab_OnSelect (hDlg);
73                break;
74
75             case IDC_ADD:
76                DrivesTab_OnAdd (hDlg);
77                break;
78
79             case IDC_EDIT:
80                DrivesTab_OnEdit (hDlg);
81                break;
82
83             case IDC_REMOVE:
84                DrivesTab_OnRemove (hDlg);
85                break;
86
87             case IDC_ADVANCED:
88                DrivesTab_OnAdvanced (hDlg);
89                break;
90
91             case IDHELP:
92                DrivesTab_DlgProc (hDlg, WM_HELP, 0, 0);
93                break;
94             }
95          break;
96
97       case WM_HELP:
98          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_DRIVES);
99          break;
100       }
101
102    return FALSE;
103 }
104
105
106 void DrivesTab_OnInitDialog (HWND hDlg)
107 {
108    ShowWindow (GetDlgItem (hDlg, IDC_ADVANCED), g.fIsWinNT);
109
110    DrivesTab_FillList (hDlg);
111 }
112
113
114 void DrivesTab_OnSelect (HWND hDlg)
115 {
116    if (IsWindowEnabled (GetDlgItem (hDlg, IDC_LIST)))
117       {
118       UINT iSel = SendDlgItemMessage (hDlg, IDC_LIST, LB_GETCURSEL, 0, 0);
119
120       EnableWindow (GetDlgItem (hDlg, IDC_EDIT), (iSel != -1));
121       EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), (iSel != -1));
122       }
123 }
124
125
126 void DrivesTab_OnCheck (HWND hDlg)
127 {
128    HWND hList = GetDlgItem (hDlg, IDC_LIST);
129    int iItemSel = SendMessage (hList, LB_GETCURSEL, 0, 0);
130    int iDriveSel = DrivesTab_DriveFromItem (hDlg, iItemSel);
131    BOOL fChecked = SendMessage (hList, LB_GETITEMDATA, iItemSel, 0);
132
133    if (iDriveSel != -1)
134       {
135       DWORD dwStatus;
136       if (fChecked && g.Configuration.NetDrives.aDriveMap[ iDriveSel ].szMapping[0] && !g.Configuration.NetDrives.aDriveMap[ iDriveSel ].fActive)
137          {
138          if (!ActivateDriveMap (g.Configuration.NetDrives.aDriveMap[ iDriveSel ].chDrive, g.Configuration.NetDrives.aDriveMap[ iDriveSel ].szMapping, g.Configuration.NetDrives.aDriveMap[ iDriveSel ].szSubmount, g.Configuration.NetDrives.aDriveMap[ iDriveSel ].fPersistent, &dwStatus))
139             Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), dwStatus);
140          DrivesTab_FillList (hDlg);
141          }
142       else if (!fChecked && g.Configuration.NetDrives.aDriveMap[ iDriveSel ].fActive)
143          {
144          if (!InactivateDriveMap (g.Configuration.NetDrives.aDriveMap[ iDriveSel ].chDrive, &dwStatus))
145             Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), dwStatus);
146          DrivesTab_FillList (hDlg);
147          }
148       }
149 }
150
151
152 void DrivesTab_OnAdd (HWND hDlg)
153 {
154    DrivesTab_EditMapping (hDlg, -1);
155 }
156
157
158 void DrivesTab_OnEdit (HWND hDlg)
159 {
160    HWND hList = GetDlgItem (hDlg, IDC_LIST);
161    int iItemSel = SendMessage (hList, LB_GETCURSEL, 0, 0);
162    int iDriveSel = DrivesTab_DriveFromItem (hDlg, iItemSel);
163
164    DrivesTab_EditMapping (hDlg, iDriveSel);
165 }
166
167
168 void DrivesTab_OnRemove (HWND hDlg)
169 {
170    HWND hList = GetDlgItem (hDlg, IDC_LIST);
171    int iItemSel = SendMessage (hList, LB_GETCURSEL, 0, 0);
172    int iDriveSel = DrivesTab_DriveFromItem (hDlg, iItemSel);
173
174    if (iDriveSel != -1)
175       {
176       if (g.Configuration.NetDrives.aDriveMap[ iDriveSel ].szMapping[0])
177          {
178          if (g.Configuration.NetDrives.aDriveMap[ iDriveSel ].fActive)
179             {
180             DWORD dwStatus;
181             if (!InactivateDriveMap (g.Configuration.NetDrives.aDriveMap[ iDriveSel ].chDrive, &dwStatus))
182                {
183                Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), dwStatus);
184                return;
185                }
186             }
187          g.Configuration.NetDrives.aDriveMap[ iDriveSel ].szMapping[0] = TEXT('\0');
188          WriteDriveMappings (&g.Configuration.NetDrives);
189
190          DrivesTab_FillList (hDlg);
191          }
192       }
193 }
194
195
196 void DrivesTab_OnAdvanced (HWND hDlg)
197 {
198    TCHAR szTitle[ cchRESOURCE ];
199    GetString (szTitle, IDS_SUBMOUNTS_TITLE);
200
201    LPPROPSHEET psh = PropSheet_Create (szTitle, FALSE, GetParent(hDlg), 0);
202    psh->sh.dwFlags |= PSH_NOAPPLYNOW;  // Remove the Apply button
203    psh->sh.dwFlags |= PSH_HASHELP;     // Add a Help button instead
204    PropSheet_AddTab (psh, szTitle, IDD_SUBMOUNTS, (DLGPROC)Submounts_DlgProc, 0, TRUE);
205    PropSheet_ShowModal (psh);
206 }
207
208
209 void DrivesTab_Enable (HWND hDlg)
210 {
211    BOOL fRunning = (Config_GetServiceState() == SERVICE_RUNNING);
212
213    EnableWindow (GetDlgItem (hDlg, IDC_LIST), fRunning);
214    EnableWindow (GetDlgItem (hDlg, IDC_ADD), fRunning);
215    EnableWindow (GetDlgItem (hDlg, IDC_EDIT), fRunning);
216    EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), fRunning);
217
218    TCHAR szText[ cchRESOURCE ];
219    GetString (szText, (fRunning) ? IDS_TIP_DRIVES : IDS_WARN_STOPPED);
220    SetDlgItemText (hDlg, IDC_WARN, szText);
221 }
222
223
224 int DrivesTab_DriveFromItem (HWND hDlg, int iItem)
225 {
226    TCHAR szItem[ 1024 ] = TEXT("");
227    SendDlgItemMessage (hDlg, IDC_LIST, LB_GETTEXT, iItem, (LPARAM)szItem);
228
229    LPTSTR pch;
230    if ((pch = (LPTSTR)lstrchr (szItem, TEXT(':'))) != NULL)
231       {
232       if (pch > szItem)
233          {
234          pch--;
235          if ((*pch >= TEXT('A')) && (*pch <= TEXT('Z')))
236             return (*pch) - TEXT('A');
237          }
238       }
239
240    return -1;
241 }
242
243
244 void DrivesTab_FillList (HWND hDlg)
245 {
246    FreeDriveMapList (&g.Configuration.NetDrives);
247    QueryDriveMapList (&g.Configuration.NetDrives);
248
249    HWND hList = GetDlgItem (hDlg, IDC_LIST);
250    int iItemSel = SendMessage (hList, LB_GETCURSEL, 0, 0);
251    int iDriveSel = DrivesTab_DriveFromItem (hDlg, iItemSel);
252    SendMessage (hList, WM_SETREDRAW, FALSE, 0);
253    SendMessage (hList, LB_RESETCONTENT, 0, 0);
254
255    iItemSel = -1;
256
257    for (int iDrive = 0; iDrive < 26; ++iDrive)
258       {
259       if (!g.Configuration.NetDrives.aDriveMap[ iDrive ].szMapping[0])
260          continue;
261
262       TCHAR szAfsPath[ MAX_PATH ];
263       AdjustAfsPath (szAfsPath, g.Configuration.NetDrives.aDriveMap[ iDrive ].szMapping, TRUE, FALSE);
264
265       LPTSTR psz = FormatString (IDS_DRIVE_MAP, TEXT("%c%s"), g.Configuration.NetDrives.aDriveMap[ iDrive ].chDrive, szAfsPath);
266       int iItem = SendMessage (hList, LB_ADDSTRING, 0, (LPARAM)psz);
267       SendMessage (hList, LB_SETITEMDATA, iItem, g.Configuration.NetDrives.aDriveMap[ iDrive ].fActive);
268
269       if (iDrive == iDriveSel)
270          iItemSel = iItem;
271       }
272
273    SendMessage (hList, WM_SETREDRAW, TRUE, 0);
274    if (iItemSel != -1)
275       SendMessage (hList, LB_SETCURSEL, iItemSel, 0);
276
277    DrivesTab_Enable (hDlg);
278    DrivesTab_OnSelect (hDlg);
279 }
280
281
282 void DrivesTab_EditMapping (HWND hDlg, int iDrive)
283 {
284    DRIVEMAP DriveMapOrig;
285    memset (&DriveMapOrig, 0x00, sizeof(DRIVEMAP));
286
287    if (iDrive != -1)
288       {
289       memcpy (&DriveMapOrig, &g.Configuration.NetDrives.aDriveMap[ iDrive ], sizeof(DRIVEMAP));
290       }
291
292    DRIVEMAP DriveMap;
293    memcpy (&DriveMap, &DriveMapOrig, sizeof(DRIVEMAP));
294
295    if (ModalDialogParam (IDD_DRIVE_EDIT, GetParent(hDlg), (DLGPROC)DriveEdit_DlgProc, (LPARAM)&DriveMap) == IDOK)
296       {
297       TCHAR szAfsPathOrig[ MAX_PATH ] = TEXT("");
298       if (iDrive != -1)
299          AdjustAfsPath (szAfsPathOrig, DriveMapOrig.szMapping, TRUE, TRUE);
300
301       TCHAR szAfsPathNew[ MAX_PATH ];
302       AdjustAfsPath (szAfsPathNew, DriveMap.szMapping, TRUE, TRUE);
303
304       if ( (lstrcmpi (szAfsPathOrig, szAfsPathNew)) ||
305            (lstrcmpi (DriveMapOrig.szSubmount, DriveMap.szSubmount)) ||
306            (DriveMapOrig.chDrive != DriveMap.chDrive) ||
307            (DriveMapOrig.fPersistent != DriveMap.fPersistent) )
308          {
309          DWORD dwStatus;
310
311          if ((iDrive != -1) && (DriveMapOrig.fActive))
312             {
313             if (!InactivateDriveMap (DriveMapOrig.chDrive, &dwStatus))
314                {
315                Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), dwStatus);
316                DrivesTab_FillList (hDlg);
317                return;
318                }
319             }
320
321          if (!ActivateDriveMap (DriveMap.chDrive, szAfsPathNew, DriveMap.szSubmount, DriveMap.fPersistent, &dwStatus))
322             {
323             Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), dwStatus);
324             DrivesTab_FillList (hDlg);
325             return;
326             }
327
328          if (DriveMap.szSubmount[0])
329             {
330             TCHAR szSubmountNow[ MAX_PATH ];
331             if (GetDriveSubmount (DriveMap.chDrive, szSubmountNow))
332                {
333                if (lstrcmpi (DriveMap.szSubmount, szSubmountNow))
334                   Message (MB_OK | MB_ICONASTERISK, GetCautionTitle(), IDS_NEWSUB_DESC);
335                }
336             }
337
338          if (iDrive != -1)
339             memset (&g.Configuration.NetDrives.aDriveMap[ iDrive ], 0x00, sizeof(DRIVEMAP));
340          memcpy (&g.Configuration.NetDrives.aDriveMap[ DriveMap.chDrive-chDRIVE_A ], &DriveMap, sizeof(DRIVEMAP));
341          lstrcpy (g.Configuration.NetDrives.aDriveMap[ DriveMap.chDrive-chDRIVE_A ].szMapping, szAfsPathNew);
342          WriteDriveMappings (&g.Configuration.NetDrives);
343
344          DrivesTab_FillList (hDlg);
345          }
346       }
347 }
348
349
350 BOOL CALLBACK DriveEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
351 {
352    switch (msg)
353       {
354       case WM_INITDIALOG:
355          SetWindowLong (hDlg, DWL_USER, lp);
356          DriveEdit_OnInitDialog (hDlg);
357          break;
358
359       case WM_COMMAND:
360          switch (LOWORD(wp))
361             {
362             case IDOK:
363                DriveEdit_OnOK (hDlg);
364                break;
365
366             case IDCANCEL:
367                EndDialog (hDlg, IDCANCEL);
368                break;
369
370             case IDC_PATH:
371                DriveEdit_Enable (hDlg);
372                break;
373
374             case IDHELP:
375                DriveEdit_DlgProc (hDlg, WM_HELP, 0, 0);
376                break;
377             }
378          break;
379
380       case WM_HELP:
381          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_DRIVES_ADDEDIT);
382          break;
383       }
384    return FALSE;
385 }
386
387
388 void DriveEdit_OnInitDialog (HWND hDlg)
389 {
390    PDRIVEMAP pMap = (PDRIVEMAP)GetWindowLong (hDlg, DWL_USER);
391
392    // Fill in the combo box
393    //
394    DWORD dwDrives = GetLogicalDrives() | 0x07; // Always pretend A,B,C: are used
395
396    if (pMap->chDrive != 0)
397       dwDrives &= ~( 1 << (pMap->chDrive - chDRIVE_A) );
398
399    int iItemSel = -1;
400    HWND hCombo = GetDlgItem (hDlg, IDC_DRIVE);
401    SendMessage (hCombo, WM_SETREDRAW, FALSE, 0);
402
403    for (int ii = 0; ii < 26; ++ii)
404       {
405       if (!(dwDrives & (1<<ii)))
406          {
407          TCHAR szText[ cchRESOURCE ];
408          GetString (szText, IDS_MAP_LETTER);
409
410          LPTSTR pch;
411          if ((pch = (LPTSTR)lstrchr (szText, TEXT('*'))) != NULL)
412             *pch = TEXT('A') + ii;
413
414          int iItem = SendMessage (hCombo, CB_ADDSTRING, 0, (LPARAM)szText);
415          SendMessage (hCombo, CB_SETITEMDATA, iItem, ii);
416          if (pMap->chDrive && (ii == pMap->chDrive - chDRIVE_A))
417             iItemSel = iItem;
418          else if ((!pMap->chDrive) && (iItemSel == -1))
419             iItemSel = iItem;
420          }
421       }
422
423    SendMessage (hCombo, WM_SETREDRAW, TRUE, 0);
424    SendMessage (hCombo, CB_SETCURSEL, iItemSel, 0);
425
426    TCHAR szMapping[ MAX_PATH ];
427    AdjustAfsPath (szMapping, ((pMap->szMapping[0]) ? pMap->szMapping : TEXT("/afs")), TRUE, FALSE);
428    SetDlgItemText (hDlg, IDC_PATH, szMapping);
429    SetDlgItemText (hDlg, IDC_DESC, pMap->szSubmount);
430
431    CheckDlgButton (hDlg, IDC_PERSISTENT, (pMap->chDrive == 0) ? TRUE : (pMap->fPersistent));
432
433    DriveEdit_Enable (hDlg);
434 }
435
436
437 void DriveEdit_OnOK (HWND hDlg)
438 {
439    PDRIVEMAP pMap = (PDRIVEMAP)GetWindowLong (hDlg, DWL_USER);
440
441    int iItem = SendDlgItemMessage (hDlg, IDC_DRIVE, CB_GETCURSEL, 0, 0);
442    int iDrive = SendDlgItemMessage (hDlg, IDC_DRIVE, CB_GETITEMDATA, iItem, 0);
443
444    pMap->chDrive = chDRIVE_A + iDrive;
445    GetDlgItemText (hDlg, IDC_PATH, pMap->szMapping, MAX_PATH);
446    GetDlgItemText (hDlg, IDC_DESC, pMap->szSubmount, MAX_PATH);
447    pMap->fPersistent = IsDlgButtonChecked (hDlg, IDC_PERSISTENT);
448
449    if (pMap->szSubmount[0] && !IsValidSubmountName (pMap->szSubmount))
450       {
451       Message (MB_ICONHAND, GetErrorTitle(), IDS_BADSUB_DESC);
452       return;
453       }
454
455    if ( (lstrncmpi (pMap->szMapping, TEXT("/afs"), lstrlen(TEXT("/afs")))) &&
456         (lstrncmpi (pMap->szMapping, TEXT("\\afs"), lstrlen(TEXT("\\afs")))) )
457       {
458       Message (MB_ICONHAND, GetErrorTitle(), IDS_BADMAP_DESC);
459       return;
460       }
461
462    EndDialog (hDlg, IDOK);
463 }
464
465
466 void DriveEdit_Enable (HWND hDlg)
467 {
468    TCHAR szPath[ MAX_PATH ];
469    GetDlgItemText (hDlg, IDC_PATH, szPath, MAX_PATH);
470    EnableWindow (GetDlgItem (hDlg, IDOK), (szPath[0] != TEXT('\0')));
471 }
472
473
474 BOOL CALLBACK Submounts_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
475 {
476    switch (msg)
477       {
478       case WM_INITDIALOG:
479          Submounts_OnInitDialog (hDlg);
480          break;
481
482       case WM_COMMAND:
483          switch (LOWORD(wp))
484             {
485             case IDAPPLY:
486                Submounts_OnApply (hDlg);
487                break;
488
489             case IDC_ADD:
490                Submounts_OnAdd (hDlg);
491                break;
492
493             case IDC_EDIT:
494                Submounts_OnEdit (hDlg);
495                break;
496
497             case IDC_REMOVE:
498                Submounts_OnRemove (hDlg);
499                break;
500
501             case IDHELP:
502                Submounts_DlgProc (hDlg, WM_HELP, 0, 0);
503                break;
504             }
505          break;
506
507       case WM_HELP:
508          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_SUBMOUNTS_NT);
509          break;
510
511       case WM_NOTIFY:
512          switch (((LPNMHDR)lp)->code)
513             {
514             case FLN_ITEMSELECT:
515                Submounts_OnSelect (hDlg);
516                break;
517
518             case FLN_LDBLCLICK:
519                if (IsWindowEnabled (GetDlgItem (hDlg, IDC_EDIT)))
520                   Submounts_OnEdit (hDlg);
521                break;
522             }
523          break;
524       }
525
526    return FALSE;
527 }
528
529
530 void Submounts_OnInitDialog (HWND hDlg)
531 {
532    // Prepare the columns on the server list
533    //
534    HWND hList = GetDlgItem (hDlg, IDC_LIST);
535
536    FASTLISTCOLUMN Column;
537    Column.dwFlags = FLCF_JUSTIFY_LEFT;
538    Column.cxWidth = 100;
539    GetString (Column.szText, IDS_SUBCOL_SHARE);
540    FastList_SetColumn (hList, 0, &Column);
541
542    Column.dwFlags = FLCF_JUSTIFY_LEFT;
543    Column.cxWidth = 200;
544    GetString (Column.szText, IDS_SUBCOL_PATH);
545    FastList_SetColumn (hList, 1, &Column);
546
547    // Remove the Context Help [?] thing from the title bar
548    //
549    DWORD dwStyle = GetWindowLong (GetParent (hDlg), GWL_STYLE);
550    dwStyle &= ~DS_CONTEXTHELP;
551    SetWindowLong (GetParent (hDlg), GWL_STYLE, dwStyle);
552
553    dwStyle = GetWindowLong (GetParent (hDlg), GWL_EXSTYLE);
554    dwStyle &= ~WS_EX_CONTEXTHELP;
555    SetWindowLong (GetParent (hDlg), GWL_EXSTYLE, dwStyle);
556
557    // Fill in the list of submounts
558    //
559    FastList_Begin (hList);
560
561    for (size_t ii = 0; ii < g.Configuration.NetDrives.cSubmounts; ++ii)
562       {
563       if (!g.Configuration.NetDrives.aSubmounts[ ii ].szSubmount[0])
564          continue;
565
566       FASTLISTADDITEM ai;
567       memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
568       ai.iFirstImage = IMAGE_NOIMAGE;
569       ai.iSecondImage = IMAGE_NOIMAGE;
570       ai.pszText = g.Configuration.NetDrives.aSubmounts[ ii ].szSubmount;
571       ai.lParam = 0;
572       HLISTITEM hItem = FastList_AddItem (hList, &ai);
573
574       TCHAR szMapping[ MAX_PATH ];
575       AdjustAfsPath (szMapping, g.Configuration.NetDrives.aSubmounts[ ii ].szMapping, TRUE, FALSE);
576       FastList_SetItemText (hList, hItem, 1, szMapping);
577       }
578
579    FastList_End (hList);
580    Submounts_OnSelect (hDlg);
581 }
582
583
584 void Submounts_OnApply (HWND hDlg)
585 {
586    HWND hList = GetDlgItem (hDlg, IDC_LIST);
587
588    // Remove our current list of submounts
589    //
590    for (size_t ii = 0; ii < g.Configuration.NetDrives.cSubmounts; ++ii)
591       {
592       RemoveSubMount (g.Configuration.NetDrives.aSubmounts[ ii ].szSubmount);
593       }
594
595    // Add back all our new submounts
596    //
597    HLISTITEM hItem;
598    for (hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
599       {
600       LPCTSTR pszSubmount;
601       if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) == NULL)
602          continue;
603       LPCTSTR pszMapping;
604       if ((pszMapping = FastList_GetItemText (hList, hItem, 1)) == NULL)
605          continue;
606
607       AddSubMount ((LPTSTR)pszSubmount, (LPTSTR)pszMapping);
608       }
609
610    FreeDriveMapList (&g.Configuration.NetDrives);
611    QueryDriveMapList (&g.Configuration.NetDrives);
612 }
613
614
615 void Submounts_OnSelect (HWND hDlg)
616 {
617    HWND hList = GetDlgItem (hDlg, IDC_LIST);
618
619    size_t cSelected = 0;
620    size_t cSelectedInUse = 0;
621
622    HLISTITEM hItem;
623    for (hItem = FastList_FindFirstSelected (hList); hItem; hItem = FastList_FindNextSelected (hList, hItem))
624       {
625       cSelected++;
626
627       LPCTSTR pszSubmount;
628       if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) != NULL)
629          {
630          for (size_t ii = 0; ii < g.Configuration.NetDrives.cSubmounts; ++ii)
631             {
632             if (!lstrcmpi (pszSubmount, g.Configuration.NetDrives.aSubmounts[ii].szSubmount))
633                {
634                if (g.Configuration.NetDrives.aSubmounts[ii].fInUse)
635                   cSelectedInUse++;
636                }
637             }
638          }
639       }
640
641    EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), (cSelected != 0) && (!cSelectedInUse));
642    EnableWindow (GetDlgItem (hDlg, IDC_EDIT), (cSelected == 1) && (!cSelectedInUse));
643 }
644
645
646 void Submounts_OnAdd (HWND hDlg)
647 {
648    HWND hList = GetDlgItem (hDlg, IDC_LIST);
649
650    SUBMOUNT Submount;
651    memset (&Submount, 0x00, sizeof(Submount));
652
653    Submounts_EditSubmount (hDlg, &Submount);
654 }
655
656
657 void Submounts_OnEdit (HWND hDlg)
658 {
659    HWND hList = GetDlgItem (hDlg, IDC_LIST);
660
661    HLISTITEM hItem;
662    if ((hItem = FastList_FindFirstSelected (hList)) != NULL)
663       {
664       LPCTSTR pszSubmount = FastList_GetItemText (hList, hItem, 0);
665       LPCTSTR pszMapping = FastList_GetItemText (hList, hItem, 1);
666
667       SUBMOUNT Submount;
668       memset (&Submount, 0x00, sizeof(Submount));
669       lstrcpy (Submount.szSubmount, pszSubmount);
670       lstrcpy (Submount.szMapping, pszMapping);
671
672       Submounts_EditSubmount (hDlg, &Submount);
673       }
674 }
675
676
677 void Submounts_OnRemove (HWND hDlg)
678 {
679    HWND hList = GetDlgItem (hDlg, IDC_LIST);
680    FastList_Begin (hList);
681
682    HLISTITEM hItem;
683    while ((hItem = FastList_FindFirstSelected (hList)) != NULL)
684       {
685       FastList_RemoveItem (hList, hItem);
686       }
687
688    FastList_End (hList);
689 }
690
691
692 void Submounts_EditSubmount (HWND hDlg, PSUBMOUNT pSubmount)
693 {
694    HWND hList = GetDlgItem (hDlg, IDC_LIST);
695
696    if (ModalDialogParam (IDD_SUBMOUNT_EDIT, GetParent(hDlg), (DLGPROC)SubEdit_DlgProc, (LPARAM)pSubmount) == IDOK)
697       {
698       TCHAR szMapping[ MAX_PATH ];
699       AdjustAfsPath (szMapping, pSubmount->szMapping, TRUE, FALSE);
700
701       HLISTITEM hItem;
702       for (hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
703          {
704          LPCTSTR pszSubmount;
705          if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) == NULL)
706             continue;
707
708          if (!lstrcmpi (pszSubmount, pSubmount->szSubmount))
709             break;
710          }
711
712       if (!hItem)
713          {
714          FASTLISTADDITEM ai;
715          memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
716          ai.iFirstImage = IMAGE_NOIMAGE;
717          ai.iSecondImage = IMAGE_NOIMAGE;
718          ai.pszText = pSubmount->szSubmount;
719          ai.lParam = 0;
720          hItem = FastList_AddItem (hList, &ai);
721          }
722
723       FastList_SetItemText (hList, hItem, 1, szMapping);
724       }
725 }
726
727
728 BOOL CALLBACK SubEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
729 {
730    switch (msg)
731       {
732       case WM_INITDIALOG:
733          SetWindowLong (hDlg, DWL_USER, lp);
734          SubEdit_OnInitDialog (hDlg);
735          SubEdit_Enable (hDlg);
736          break;
737
738       case WM_COMMAND:
739          switch (LOWORD(wp))
740             {
741             case IDOK:
742                SubEdit_OnOK (hDlg);
743                break;
744
745             case IDCANCEL:
746                EndDialog (hDlg, IDCANCEL);
747                break;
748
749             case IDC_SUBMOUNT:
750             case IDC_MAPPING:
751                SubEdit_Enable (hDlg);
752                break;
753
754             case IDHELP:
755                SubEdit_DlgProc (hDlg, WM_HELP, 0, 0);
756                break;
757             }
758          break;
759
760       case WM_HELP:
761          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_SUBMOUNTS_NT_ADDEDIT);
762          break;
763       }
764
765    return 0;
766 }
767
768
769 void SubEdit_OnInitDialog (HWND hDlg)
770 {
771    PSUBMOUNT pSubmount = (PSUBMOUNT)GetWindowLong (hDlg, DWL_USER);
772
773    SetDlgItemText (hDlg, IDC_SUBMOUNT, pSubmount->szSubmount);
774    SetDlgItemText (hDlg, IDC_MAPPING, pSubmount->szMapping);
775 }
776
777
778 void SubEdit_OnOK (HWND hDlg)
779 {
780    PSUBMOUNT pSubmount = (PSUBMOUNT)GetWindowLong (hDlg, DWL_USER);
781    GetDlgItemText (hDlg, IDC_SUBMOUNT, pSubmount->szSubmount, MAX_PATH);
782    GetDlgItemText (hDlg, IDC_MAPPING, pSubmount->szMapping, MAX_PATH);
783    EndDialog (hDlg, IDOK);
784 }
785
786
787 void SubEdit_Enable (HWND hDlg)
788 {
789    BOOL fEnable = TRUE;
790
791    TCHAR szText[ MAX_PATH ];
792    GetDlgItemText (hDlg, IDC_SUBMOUNT, szText, MAX_PATH);
793    if (!szText[0])
794       fEnable = FALSE;
795
796    GetDlgItemText (hDlg, IDC_MAPPING, szText, MAX_PATH);
797    if (!szText[0])
798       fEnable = FALSE;
799
800    EnableWindow (GetDlgItem (hDlg, IDOK), fEnable);
801 }
802