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