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