Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / client_config / dlg_automap.cpp
1 extern "C" {
2 #include <afs/param.h>
3 #include <afs/stds.h>
4 }
5
6 #include "afs_config.h"
7 #include <stdio.h>
8
9 /*
10  * DEFINITIONS ________________________________________________________________
11  *
12  */
13 static DRIVEMAPLIST GlobalDrives;
14 static TCHAR szHostName[128];
15
16 // DefineDosDrive actions
17 enum DDDACTION  { DDD_ADD, DDD_REMOVE };
18
19 #define DRIVE_LETTER_INDEX 2
20
21
22 /*
23  * PROTOTYPES _________________________________________________________________
24  *
25  */
26
27 void AutoMap_OnInitDialog (HWND hDlg);
28 void AutoMap_OnAdd (HWND hDlg);
29 void AutoMap_OnSelect (HWND hDlg);
30 void AutoMap_OnEdit (HWND hDlg);
31 void AutoMap_OnRemove (HWND hDlg);
32
33 void ShowDriveList(HWND hDlg, DRIVEMAPLIST& drives);
34 void AddToDriveList(DRIVEMAPLIST& DriveMapList, DRIVEMAP& DriveMap);
35 void RemoveFromDriveList(DRIVEMAPLIST& DriveMapList, DRIVEMAP& DriveMap);
36 DRIVEMAP *GetSelectedDrive(HWND hDlg, HLISTITEM  *pItem = 0);
37 BOOL DefineDosDrive(DRIVEMAP *pDrive, DDDACTION dddAction = DDD_ADD);
38
39 BOOL CALLBACK AutoMapEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
40 void AutoMapEdit_OnInitDialog (HWND hDlg);
41 void AutoMapEdit_OnOK (HWND hDlg);
42 void AutoMapEdit_Enable (HWND hDlg);
43
44
45 /*
46  * ROUTINES ___________________________________________________________________
47  *
48  */
49
50 BOOL CALLBACK AutoMap_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
51 {
52    switch (msg)
53       {
54       case WM_INITDIALOG:
55          AutoMap_OnInitDialog (hDlg);
56          break;
57
58       case WM_CTLCOLORSTATIC:
59          if ((HWND)lp == GetDlgItem (hDlg, IDC_CHUNK_SIZE))
60             {
61             if (IsWindowEnabled ((HWND)lp))
62                {
63                static HBRUSH hbrStatic = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
64                SetTextColor ((HDC)wp, GetSysColor (COLOR_WINDOWTEXT));
65                SetBkColor ((HDC)wp, GetSysColor (COLOR_WINDOW));
66                return (BOOL)hbrStatic;
67                }
68             }
69          break;
70
71       case WM_COMMAND:
72          switch (LOWORD(wp))
73             {
74             case IDHELP:
75                AutoMap_DlgProc (hDlg, WM_HELP, 0, 0);
76                break;
77
78             case IDOK:
79                EndDialog(hDlg, IDOK);
80                break;
81                 
82             case IDCANCEL:
83                EndDialog(hDlg, IDCANCEL);
84                break;
85
86                                 case IDC_ADD:
87                                         AutoMap_OnAdd(hDlg);
88                                         break;
89
90                                 case IDC_CHANGE:
91                                         AutoMap_OnEdit(hDlg);
92                                         break;
93
94                                 case IDC_REMOVE:
95                                         AutoMap_OnRemove(hDlg);
96                                         break;
97             }
98          break;
99
100       case WM_NOTIFY:
101          switch (((LPNMHDR)lp)->code)
102                 {
103             case FLN_ITEMSELECT:
104                AutoMap_OnSelect (hDlg);
105                break;
106
107             case FLN_LDBLCLICK:
108                if (IsWindowEnabled (GetDlgItem (hDlg, IDC_EDIT)))
109                   AutoMap_OnEdit (hDlg);
110                break;
111             }
112          break;
113
114       case WM_HELP:
115          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_ADVANCED_AUTOMAP);
116          break;
117       }
118
119    return FALSE;
120 }
121
122
123 void AddToDriveList(DRIVEMAPLIST& DriveMapList, DRIVEMAP& DriveMap)
124 {
125    int nCurDrive = DriveMap.chDrive - TEXT('A');
126    
127    memcpy(&DriveMapList.aDriveMap[nCurDrive], &DriveMap, sizeof(DRIVEMAP));
128 }
129
130
131 void RemoveFromDriveList(DRIVEMAPLIST& DriveMapList, DRIVEMAP& DriveMap)
132 {
133    int nCurDrive = DriveMap.chDrive - TEXT('A');
134    
135    memset(&DriveMapList.aDriveMap[nCurDrive], 0, sizeof(DRIVEMAP));
136 }
137
138
139 void AutoMap_OnInitDialog (HWND hDlg)
140 {
141    // Prepare the columns
142    HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
143
144    FASTLISTCOLUMN Column;
145    Column.dwFlags = FLCF_JUSTIFY_LEFT;
146    Column.cxWidth = 65;
147    GetString (Column.szText, IDS_DRIVE);
148    FastList_SetColumn (hList, 0, &Column);
149
150    Column.dwFlags = FLCF_JUSTIFY_LEFT;
151    Column.cxWidth = 266;
152    GetString (Column.szText, IDS_SUBCOL_PATH);
153    FastList_SetColumn (hList, 1, &Column);
154
155         gethostname(szHostName, sizeof(szHostName));
156
157    Config_GetGlobalDriveList(&GlobalDrives);
158
159    ShowDriveList(hDlg, GlobalDrives);
160 }
161
162
163 void ShowDriveList(HWND hDlg, DRIVEMAPLIST& drives)
164 {
165    // Prepare the columns
166    HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
167
168    // Fill in the list of drives
169    FastList_Begin (hList);
170
171    FastList_RemoveAll(hList);
172
173    for (size_t ii = 0; ii < 26; ++ii) {
174       if (!GlobalDrives.aDriveMap[ ii ].chDrive)
175          continue;
176
177       HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
178    
179         FASTLISTADDITEM ai;
180         memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
181         ai.iFirstImage = IMAGE_NOIMAGE;
182         ai.iSecondImage = IMAGE_NOIMAGE;
183         // There must be DRIVE_LETTER_INDEX number of spaces before the ? character
184         ai.pszText = _tcsdup(TEXT("  ?:"));
185         ai.pszText[DRIVE_LETTER_INDEX] = GlobalDrives.aDriveMap[ ii ].chDrive;
186         ai.lParam = 0;
187         
188         HLISTITEM hItem = FastList_AddItem (hList, &ai);
189    
190       TCHAR szAfsPath[ MAX_PATH ];
191       AdjustAfsPath (szAfsPath, GlobalDrives.aDriveMap[ ii ].szMapping, TRUE, FALSE);
192    
193         FastList_SetItemText (hList, hItem, 1, szAfsPath);
194    }
195
196    FastList_End (hList);
197 }
198
199
200 BOOL UpdateRegistry(DRIVEMAP *pDrive, BOOL bRemove)
201 {
202    TCHAR szKeyName[128];
203    TCHAR szValueName[128];
204    HKEY hKey;
205    LONG result;
206
207    if (!pDrive)
208       return FALSE;
209
210    _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), AFSConfigKeyName);
211
212    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_SET_VALUE, &hKey) != ERROR_SUCCESS)
213       return FALSE;
214
215    _stprintf(szValueName, TEXT("%c:"), pDrive->chDrive);
216  
217    if (bRemove) 
218       result = RegDeleteValue(hKey, szValueName);
219    else
220       result = RegSetValueEx(hKey, szValueName, 0, REG_SZ, (BYTE *)pDrive->szSubmount, lstrlen(pDrive->szSubmount) + 1);
221
222    RegCloseKey(hKey);
223    
224    return (result == ERROR_SUCCESS);
225 }
226
227
228 BOOL DefineDosDrive(DRIVEMAP *pDrive, DDDACTION dddAction)
229 {
230    TCHAR szAfsPath[MAX_PATH];
231    TCHAR szDrive[3] = TEXT("?:");
232    BOOL fResult = FALSE;
233
234    if (!pDrive)
235       return FALSE;
236
237    szDrive[0] = pDrive->chDrive;
238    _stprintf(szAfsPath, TEXT("\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s"), szDrive, szHostName, pDrive->szSubmount);
239
240    if (dddAction == DDD_REMOVE) {
241       fResult = DefineDosDevice(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, szDrive, szAfsPath);
242       if (!fResult)
243          Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), GetLastError());
244    } else if (dddAction == DDD_ADD) {
245       fResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szAfsPath);
246       if (!fResult)
247          Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), GetLastError());
248    }
249
250    if (fResult)
251          UpdateRegistry(pDrive, dddAction == DDD_REMOVE);
252
253    return fResult;
254 }   
255
256
257 void AutoMap_OnAdd(HWND hDlg)
258 {
259         DRIVEMAP DriveMap;
260    memset(&DriveMap, 0, sizeof(DRIVEMAP));
261
262         if (ModalDialogParam (IDD_GLOBAL_DRIVES_ADDEDIT, hDlg, (DLGPROC)AutoMapEdit_DlgProc, (LPARAM)&DriveMap) != IDOK)
263                 return;
264
265         if (DriveMap.chDrive) {
266       if (DefineDosDrive(&DriveMap)) {
267                    AddToDriveList(GlobalDrives, DriveMap);
268                    ShowDriveList(hDlg, GlobalDrives);
269                 }
270         }
271
272         AutoMap_OnSelect(hDlg);
273 }
274
275
276 void AutoMap_OnSelect (HWND hDlg)
277 {
278    HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
279
280    BOOL bEnable = FastList_FindFirstSelected (hList) != NULL;
281         
282         EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), bEnable);
283    EnableWindow (GetDlgItem (hDlg, IDC_CHANGE), bEnable);
284 }
285
286
287 DRIVEMAP *GetSelectedDrive(HWND hDlg, HLISTITEM  *pItem)
288 {
289         static DRIVEMAP DriveMap;
290    HLISTITEM hItem;
291    
292    HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
293
294    if (!pItem)
295       pItem = &hItem;
296
297    if ((*pItem = FastList_FindFirstSelected (hList)) == NULL)
298         return 0;
299         
300         LPCTSTR pszDrive = FastList_GetItemText (hList, *pItem, 0);
301    int nCurDrive = pszDrive[DRIVE_LETTER_INDEX] - TEXT('A');
302
303    memcpy(&DriveMap, &GlobalDrives.aDriveMap[nCurDrive], sizeof(DRIVEMAP));
304
305    return &DriveMap;
306 }
307
308    
309 void AutoMap_OnEdit (HWND hDlg)
310 {
311    DRIVEMAP *pOldDrive = GetSelectedDrive(hDlg);
312    if (!pOldDrive)
313       return;
314
315    DRIVEMAP NewDrive;
316    memcpy(&NewDrive, pOldDrive, sizeof(DRIVEMAP));
317         
318         if (ModalDialogParam (IDD_GLOBAL_DRIVES_ADDEDIT, hDlg, (DLGPROC)AutoMapEdit_DlgProc, (LPARAM)&NewDrive) != IDOK)
319                 return;
320
321    if (DefineDosDrive(pOldDrive, DDD_REMOVE)) {
322       RemoveFromDriveList(GlobalDrives, *pOldDrive);
323
324       if (DefineDosDrive(&NewDrive))
325            AddToDriveList(GlobalDrives, NewDrive);
326
327         ShowDriveList(hDlg, GlobalDrives);
328         }
329
330         AutoMap_OnSelect(hDlg);
331 }
332
333
334 void AutoMap_OnRemove (HWND hDlg)
335 {
336    HLISTITEM hItem;
337
338    HWND hList = GetDlgItem (hDlg, IDC_GLOBAL_DRIVE_LIST);
339
340    DRIVEMAP *pDrive = GetSelectedDrive(hDlg, &hItem);
341    if (pDrive == 0)
342       return;
343       
344    if (DefineDosDrive(pDrive, DDD_REMOVE)) {
345       RemoveFromDriveList(GlobalDrives, *pDrive);
346         FastList_RemoveItem (hList, hItem);
347    }
348
349         AutoMap_OnSelect(hDlg);
350 }
351
352
353 BOOL CALLBACK AutoMapEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
354 {
355    switch (msg)
356       {
357       case WM_INITDIALOG:
358          SetWindowLong (hDlg, DWL_USER, lp);
359          AutoMapEdit_OnInitDialog (hDlg);
360          break;
361
362       case WM_COMMAND:
363          switch (LOWORD(wp))
364             {
365             case IDOK:
366                AutoMapEdit_OnOK (hDlg);
367                break;
368
369             case IDCANCEL:
370                EndDialog (hDlg, IDCANCEL);
371                break;
372
373             case IDC_PATH:
374                AutoMapEdit_Enable (hDlg);
375                break;
376
377             case IDHELP:
378                AutoMapEdit_DlgProc (hDlg, WM_HELP, 0, 0);
379                break;
380             }
381          break;
382
383       case WM_HELP:
384          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_ADVANCED_AUTOMAP_ADDEDIT);
385          break;
386       }
387    return FALSE;
388 }
389
390
391 void AutoMapEdit_OnInitDialog (HWND hDlg)
392 {
393    PDRIVEMAP pMap = (PDRIVEMAP)GetWindowLong (hDlg, DWL_USER);
394
395    DWORD dwDrives = GetLogicalDrives() | 0x07; // Always pretend A,B,C: are used
396
397    // Fill in the combo box
398    //
399
400    if (pMap->chDrive != 0)
401       dwDrives &= ~( 1 << (pMap->chDrive - chDRIVE_A) );
402
403    int iItemSel = -1;
404    HWND hCombo = GetDlgItem (hDlg, IDC_DRIVE);
405    SendMessage (hCombo, WM_SETREDRAW, FALSE, 0);
406
407    for (int ii = 0; ii < 26; ++ii)
408       {
409       if (!(dwDrives & (1<<ii)))
410          {
411          TCHAR szText[ cchRESOURCE ];
412          GetString (szText, IDS_MAP_LETTER);
413
414          LPTSTR pch;
415          if ((pch = (LPTSTR)lstrchr (szText, TEXT('*'))) != NULL)
416             *pch = TEXT('A') + ii;
417
418          int iItem = SendMessage (hCombo, CB_ADDSTRING, 0, (LPARAM)szText);
419          SendMessage (hCombo, CB_SETITEMDATA, iItem, ii);
420          if (pMap->chDrive && (ii == pMap->chDrive - chDRIVE_A))
421             iItemSel = iItem;
422          else if ((!pMap->chDrive) && (iItemSel == -1))
423             iItemSel = iItem;
424          }
425       }
426
427    SendMessage (hCombo, WM_SETREDRAW, TRUE, 0);
428    SendMessage (hCombo, CB_SETCURSEL, iItemSel, 0);
429
430    TCHAR szMapping[ MAX_PATH ];
431    AdjustAfsPath (szMapping, ((pMap->szMapping[0]) ? pMap->szMapping : TEXT("/afs")), TRUE, FALSE);
432    SetDlgItemText (hDlg, IDC_PATH, szMapping);
433    SetDlgItemText (hDlg, IDC_DESC, pMap->szSubmount);
434
435    CheckDlgButton (hDlg, IDC_PERSISTENT, (pMap->chDrive == 0) ? TRUE : (pMap->fPersistent));
436
437    AutoMapEdit_Enable (hDlg);
438 }
439
440
441 void AutoMapEdit_OnOK (HWND hDlg)
442 {
443    PDRIVEMAP pMap = (PDRIVEMAP)GetWindowLong (hDlg, DWL_USER);
444
445    int iItem = SendDlgItemMessage (hDlg, IDC_DRIVE, CB_GETCURSEL, 0, 0);
446    int iDrive = SendDlgItemMessage (hDlg, IDC_DRIVE, CB_GETITEMDATA, iItem, 0);
447
448    pMap->chDrive = chDRIVE_A + iDrive;
449    GetDlgItemText (hDlg, IDC_PATH, pMap->szMapping, MAX_PATH);
450    GetDlgItemText (hDlg, IDC_DESC, pMap->szSubmount, MAX_PATH);
451    pMap->fPersistent = IsDlgButtonChecked (hDlg, IDC_PERSISTENT);
452
453    if (pMap->szSubmount[0] && !IsValidSubmountName (pMap->szSubmount))
454       {
455       Message (MB_ICONHAND, GetErrorTitle(), IDS_BADSUB_DESC);
456       return;
457       }
458
459    if ( (lstrncmpi (pMap->szMapping, TEXT("/afs"), lstrlen(TEXT("/afs")))) &&
460         (lstrncmpi (pMap->szMapping, TEXT("\\afs"), lstrlen(TEXT("\\afs")))) )
461       {
462       Message (MB_ICONHAND, GetErrorTitle(), IDS_BADMAP_DESC);
463       return;
464       }
465
466    // First get a proper submount
467    if (pMap->szSubmount[0]) {
468       TCHAR szNewSubmount[MAX_PATH];
469       PathToSubmount (szNewSubmount, pMap->szMapping, pMap->szSubmount, 0);
470       if (lstrcmp(szNewSubmount, pMap->szSubmount) != 0) {
471          Message (MB_OK | MB_ICONASTERISK, GetCautionTitle(), IDS_NEWSUB_DESC);
472          return;
473       }
474    } else { // If no submount was specified, then get a new one
475       if (!PathToSubmount (pMap->szSubmount, pMap->szMapping, 0, 0)) {
476          return;
477       }
478    }
479
480    EndDialog (hDlg, IDOK);
481 }
482
483
484 void AutoMapEdit_Enable (HWND hDlg)
485 {
486    TCHAR szPath[ MAX_PATH ];
487    GetDlgItemText (hDlg, IDC_PATH, szPath, MAX_PATH);
488    EnableWindow (GetDlgItem (hDlg, IDOK), (szPath[0] != TEXT('\0')));
489 }
490