ntmakefile-clean-20040401
[openafs.git] / src / WINNT / client_creds / afswiz.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 #include <afs/fs_utils.h>
14 }
15
16 #include "afscreds.h"
17
18
19 /*
20  * PROTOTYPES _________________________________________________________________
21  *
22  */
23
24 BOOL CALLBACK WizCommon_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
25 BOOL CALLBACK WizStart_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
26 BOOL CALLBACK WizStarting_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
27 BOOL CALLBACK WizCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
28 BOOL CALLBACK WizMount_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
29 BOOL CALLBACK WizMounting_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
30 BOOL CALLBACK WizFinish_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
31
32 void WizStarting_OnInitDialog (HWND hDlg);
33 void WizStarting_OnTimer (HWND hDlg);
34
35 void WizCreds_OnInitDialog (HWND hDlg);
36 void WizCreds_OnEnable (HWND hDlg, BOOL fAllowEnable = TRUE);
37
38 void WizMount_OnInitDialog (HWND hDlg);
39 void WizMount_OnEnable (HWND hDlg, BOOL fAllowEnable = TRUE);
40 BOOL WizMount_IsSubmountValid (HWND hDlg);
41
42 void WizMounting_OnInitDialog (HWND hDlg);
43 void WizMounting_OnFinish (HWND hDlg);
44 DWORD CALLBACK WizMounting_Thread (LPVOID lp);
45
46
47 /*
48  * VARIABLES __________________________________________________________________
49  *
50  */
51
52 static struct l
53    {
54    DRIVEMAPLIST List;
55    BOOL fQueried;
56    HWND hDlg;
57    int idh;
58    TCHAR szSubmountReq[ MAX_PATH ];
59    } l;
60
61
62 /*
63  * WIZARD STATES ______________________________________________________________
64  *
65  */
66
67 typedef enum
68    {
69    STEP_START,
70    STEP_STARTING,
71    STEP_CREDS,
72    STEP_MOUNT,
73    STEP_MOUNTING,
74    STEP_FINISH,
75    } WIZSTEP;
76
77 static WIZARD_STATE aStates[] = {
78    { STEP_START,     IDD_WIZ_START,     WizStart_DlgProc,       0 },
79    { STEP_STARTING,  IDD_WIZ_STARTING,  WizStarting_DlgProc,    0 },
80    { STEP_CREDS,     IDD_WIZ_CREDS,     WizCreds_DlgProc,       0 },
81    { STEP_MOUNT,     IDD_WIZ_MOUNT,     WizMount_DlgProc,       0 },
82    { STEP_MOUNTING,  IDD_WIZ_MOUNTING,  WizMounting_DlgProc,    0 },
83    { STEP_FINISH,    IDD_WIZ_FINISH,    WizFinish_DlgProc,      0 }
84 };
85
86 static const int cStates = sizeof(aStates) / sizeof(aStates[0]);
87
88
89 /*
90  * ROUTINES ___________________________________________________________________
91  *
92  */
93
94 void ShowStartupWizard (void)
95 {
96    if (g.pWizard != NULL) // Already showing the wizard? Stop here.
97       return;
98
99    memset (&l, 0x00, sizeof(l));
100
101    g.pWizard = New(WIZARD);
102
103    g.pWizard->SetDialogTemplate (IDD_WIZARD, IDC_LHS, IDC_RHS, IDBACK, IDNEXT);
104    g.pWizard->SetGraphic (IDB_WIZ16, IDB_WIZ256);
105    g.pWizard->SetStates (aStates, cStates);
106    g.pWizard->SetState (STEP_START);
107
108    g.pWizard->Show();
109
110    Delete(g.pWizard);
111    g.pWizard = NULL;
112
113    Main_RepopulateTabs (TRUE);
114
115    FreeDriveMapList (&l.List);
116 }
117
118
119 BOOL CALLBACK WizCommon_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
120 {
121    switch (msg)
122      {
123      case WM_COMMAND:
124         switch (LOWORD(wp))
125            {
126            case IDCANCEL:
127               g.pWizard->Show(FALSE);
128               return TRUE;
129
130            case IDHELP:
131                WizCommon_DlgProc (hDlg, WM_HELP, 0, 0);
132                break;
133            }
134         break;
135
136       case WM_HELP:
137          if (l.idh)
138             WinHelp (GetParent(hDlg), g.szHelpFile, HELP_CONTEXT, l.idh);
139          break;
140      }
141    return FALSE;
142 }
143
144
145 BOOL CALLBACK WizStart_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
146 {
147    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
148       {
149       switch (msg)
150          {
151          case WM_INITDIALOG:
152             g.pWizard->EnableButtons (NEXT_BUTTON);
153             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
154             g.pWizard->SetDefaultControl (IDNEXT);
155             l.idh = IDH_AFSCREDS_WIZ_START;
156             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
157             break;
158
159          case WM_COMMAND:
160             switch (LOWORD(wp))
161                {
162                case IDNEXT:
163                   g.pWizard->SetState (STEP_STARTING);
164                   break;
165
166                case IDC_WIZARD:
167                   switch (HIWORD(wp))
168                      {
169                      case wcIS_STATE_DISABLED:
170                         return IsServiceRunning();
171                      }
172                   break;
173                }
174             break;
175          }
176       }
177
178    return FALSE;
179 }
180
181
182 BOOL CALLBACK WizStarting_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
183 {
184    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
185       {
186       switch (msg)
187          {
188          case WM_INITDIALOG:
189             g.pWizard->EnableButtons (0);
190             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
191             WizStarting_OnInitDialog (hDlg);
192             l.idh = IDH_AFSCREDS_WIZ_START_FAIL;
193             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), FALSE);
194             break;
195
196          case WM_TIMER:
197             WizStarting_OnTimer (hDlg);
198             break;
199
200          case WM_DESTROY:
201             KillTimer (hDlg, ID_WIZARD_TIMER);
202             break;
203
204          case IDC_WIZARD:
205             switch (HIWORD(wp))
206                {
207                case wcIS_STATE_DISABLED:
208                   return IsServiceRunning();
209                }
210             break;
211          }
212       }
213
214    return FALSE;
215 }
216
217
218 void WizStarting_OnInitDialog (HWND hDlg)
219 {
220    ShowWindow (GetDlgItem (hDlg, IDC_START_FAIL), SW_HIDE);
221    ShowWindow (GetDlgItem (hDlg, IDC_START_TRY), SW_SHOW);
222
223    SC_HANDLE hManager;
224     if ((hManager = OpenSCManager (NULL, NULL, 
225                                    SC_MANAGER_CONNECT |
226                                    SC_MANAGER_ENUMERATE_SERVICE |
227                                    SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
228       {
229       SC_HANDLE hService;
230           if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), 
231                                        SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
232          {
233          if (StartService (hService, 0, 0))
234                         TestAndDoMapShare(SERVICE_START_PENDING);
235
236          CloseServiceHandle (hService);
237          }
238
239       CloseServiceHandle (hManager);
240       }
241
242    SetTimer (hDlg, ID_WIZARD_TIMER, (ULONG)cmsecSERVICE, NULL);
243
244    WizStarting_OnTimer (hDlg);
245 }
246
247
248 void WizStarting_OnTimer (HWND hDlg)
249 {
250    SERVICE_STATUS Status;
251    memset (&Status, 0x00, sizeof(Status));
252    Status.dwCurrentState = SERVICE_STOPPED;
253
254    SC_HANDLE hManager;
255    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
256       {
257       SC_HANDLE hService;
258       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
259          {
260          QueryServiceStatus (hService, &Status);
261          CloseServiceHandle (hService);
262                  TestAndDoMapShare(Status.dwCurrentState);
263          }
264
265       CloseServiceHandle (hManager);
266       }
267
268    if (Status.dwCurrentState == SERVICE_RUNNING)
269       {
270       g.pWizard->SetState (STEP_CREDS);
271       }
272    else if (Status.dwCurrentState != SERVICE_START_PENDING)
273       {
274       KillTimer (hDlg, ID_WIZARD_TIMER);
275
276       ShowWindow (GetDlgItem (hDlg, IDC_START_FAIL), SW_SHOW);
277       ShowWindow (GetDlgItem (hDlg, IDC_START_TRY), SW_HIDE);
278       EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
279       }
280 }
281
282
283 BOOL CALLBACK WizCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
284 {
285    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
286       {
287       switch (msg)
288          {
289          case WM_INITDIALOG:
290             g.pWizard->EnableButtons (NEXT_BUTTON);
291             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
292             l.idh = IDH_AFSCREDS_WIZ_CREDS;
293             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
294             WizCreds_OnInitDialog (hDlg);
295             break;
296
297          case WM_COMMAND:
298             switch (LOWORD(wp))
299                {
300                case IDNEXT:
301                   if (!IsDlgButtonChecked (hDlg, IDC_YESCREDS))
302                      {
303                      g.pWizard->SetState (STEP_MOUNT);
304                      }
305                   else
306                      {
307                      TCHAR szCell[ cchRESOURCE ];
308                      GetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szCell, cchRESOURCE);
309                      TCHAR szUser[ cchRESOURCE ];
310                      GetDlgItemText (hDlg, IDC_NEWCREDS_USER, szUser, cchRESOURCE);
311                      TCHAR szPassword[ cchRESOURCE ];
312                      GetDlgItemText (hDlg, IDC_NEWCREDS_PASSWORD, szPassword, cchRESOURCE);
313
314                      WizCreds_OnEnable (hDlg, FALSE);
315
316                      if (ObtainNewCredentials (szCell, szUser, szPassword, FALSE) == 0)
317                         {
318                         g.pWizard->SetState (STEP_MOUNT);
319                         }
320                      else
321                         {
322                         WizCreds_OnEnable (hDlg);
323                         }
324                      }
325                   break;
326
327                case IDC_NOCREDS:
328                case IDC_YESCREDS:
329                case IDC_NEWCREDS_CELL:
330                case IDC_NEWCREDS_USER:
331                case IDC_NEWCREDS_PASSWORD:
332                   WizCreds_OnEnable (hDlg);
333                   break;
334                }
335             break;
336          }
337       }
338
339    return FALSE;
340 }
341
342
343 void WizCreds_OnInitDialog (HWND hDlg)
344 {
345    HKEY hk;
346
347    TCHAR szCell[ cchRESOURCE ] = TEXT("");
348    (void)GetDefaultCell (szCell);
349    SetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szCell);
350
351    TCHAR szUser[ cchRESOURCE ] = TEXT("");
352    if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hk) == 0)
353       {
354       DWORD dwSize = sizeof(szUser);
355       DWORD dwType = REG_SZ;
356       RegQueryValueEx (hk, TEXT("DefaultUserName"), NULL, &dwType, (PBYTE)szUser, &dwSize);
357       RegCloseKey (hk);
358       }
359    SetDlgItemText (hDlg, IDC_NEWCREDS_USER, szUser);
360    g.pWizard->SetDefaultControl (IDC_NEWCREDS_PASSWORD);
361
362    CheckDlgButton (hDlg, IDC_NOCREDS, FALSE);
363    CheckDlgButton (hDlg, IDC_YESCREDS, TRUE);
364    WizCreds_OnEnable (hDlg);
365 }
366
367
368 void WizCreds_OnEnable (HWND hDlg, BOOL fAllowEnable)
369 {
370    BOOL fEnable = fAllowEnable;
371
372    if (IsDlgButtonChecked (hDlg, IDC_YESCREDS))
373       {
374       TCHAR szText[ cchRESOURCE ];
375       GetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szText, cchRESOURCE);
376       if (!szText[0])
377          fEnable = FALSE;
378
379       GetDlgItemText (hDlg, IDC_NEWCREDS_USER, szText, cchRESOURCE);
380       if (!szText[0])
381          fEnable = FALSE;
382
383       GetDlgItemText (hDlg, IDC_NEWCREDS_PASSWORD, szText, cchRESOURCE);
384       if (!szText[0])
385          fEnable = FALSE;
386       }
387
388    g.pWizard->EnableButtons ((fEnable) ? NEXT_BUTTON : 0);
389
390    EnableWindow (GetDlgItem (hDlg, IDC_NOCREDS), fAllowEnable);
391    EnableWindow (GetDlgItem (hDlg, IDC_YESCREDS), fAllowEnable);
392
393    fEnable = fAllowEnable && IsDlgButtonChecked (hDlg, IDC_YESCREDS);
394    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_CELL), fEnable);
395    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_USER), fEnable);
396    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_PASSWORD), fEnable);
397 }
398
399
400 BOOL CALLBACK WizMount_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
401 {
402    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
403       {
404       switch (msg)
405          {
406          case WM_INITDIALOG:
407             g.pWizard->EnableButtons (BACK_BUTTON | NEXT_BUTTON);
408             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
409             g.pWizard->SetDefaultControl (IDNEXT);
410             l.idh = IDH_AFSCREDS_WIZ_MOUNT;
411             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
412
413             WizMount_OnInitDialog (hDlg);
414             break;
415
416          case WM_COMMAND:
417             switch (LOWORD(wp))
418                {
419                case IDBACK:
420                   g.pWizard->SetState (STEP_CREDS);
421                   break;
422
423                case IDNEXT:
424                   if (IsDlgButtonChecked (hDlg, IDC_YESMAP))
425                      {
426                      if (!WizMount_IsSubmountValid (hDlg))
427                         {
428                         Message (MB_ICONHAND, IDS_BADSUB_TITLE, IDS_BADSUB_DESC);
429                         break;
430                         }
431                      int iItem = SendDlgItemMessage (hDlg, IDC_MAP_LETTER, CB_GETCURSEL, 0, 0);
432                      int iDrive = SendDlgItemMessage (hDlg, IDC_MAP_LETTER, CB_GETITEMDATA, iItem, 0);
433                      l.List.aDriveMap[ iDrive ].chDrive = chDRIVE_A + iDrive;
434                      l.List.aDriveMap[ iDrive ].fActive = FALSE;
435                      l.List.aDriveMap[ iDrive ].fPersistent = TRUE;
436                      GetDlgItemText (hDlg, IDC_MAP_PATH, l.List.aDriveMap[ iDrive ].szMapping, MAX_PATH);
437                      GetDlgItemText (hDlg, IDC_MAP_DESC, l.szSubmountReq, MAX_PATH);
438                      WriteDriveMappings (&l.List);
439                      }
440                   g.pWizard->SetState (STEP_MOUNTING);
441                   break;
442
443                case IDC_NOMAP:
444                case IDC_YESMAP:
445                case IDC_MAP_PATH:
446                   WizMount_OnEnable (hDlg);
447                   break;
448                }
449             break;
450          }
451       }
452
453    return FALSE;
454 }
455
456
457 void WizMount_OnInitDialog (HWND hDlg)
458 {
459    QueryDriveMapList (&l.List);
460
461    size_t cMap = 0;
462    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
463       {
464       if (l.List.aDriveMap[iDrive].szMapping[0])
465          ++cMap;
466       }
467
468    if (cMap)
469       {
470       g.pWizard->SetState (STEP_MOUNTING);
471       return;
472       }
473
474    // Fill in the combo box
475    //
476    DWORD dwDrives = GetLogicalDrives() | 0x07; // Always pretend A,B,C: are used
477
478    int iItemSel = -1;
479    HWND hCombo = GetDlgItem (hDlg, IDC_MAP_LETTER);
480    SendMessage (hCombo, WM_SETREDRAW, FALSE, 0);
481
482    for (int ii = 0; ii < 26; ++ii)
483       {
484       if (!(dwDrives & (1<<ii)))
485          {
486          TCHAR szText[ cchRESOURCE ];
487          GetString (szText, IDS_MAP_LETTER);
488
489          LPTSTR pch;
490          if ((pch = (LPTSTR)lstrchr (szText, TEXT('*'))) != NULL)
491             *pch = TEXT('A') + ii;
492
493          int iItem = SendMessage (hCombo, CB_ADDSTRING, 0, (LPARAM)szText);
494          SendMessage (hCombo, CB_SETITEMDATA, iItem, ii);
495          if (iItemSel == -1)
496             iItemSel = iItem;
497          }
498       }
499
500    SendMessage (hCombo, WM_SETREDRAW, TRUE, 0);
501    SendMessage (hCombo, CB_SETCURSEL, iItemSel, 0);
502
503    SetDlgItemText (hDlg, IDC_MAP_PATH, cm_slash_mount_root);
504
505    CheckDlgButton (hDlg, IDC_NOMAP, FALSE);
506    CheckDlgButton (hDlg, IDC_YESMAP, TRUE);
507 }
508
509
510 void WizMount_OnEnable (HWND hDlg, BOOL fAllowEnable)
511 {
512    BOOL fEnable = fAllowEnable;
513
514    if (IsDlgButtonChecked (hDlg, IDC_YESMAP))
515       {
516       TCHAR szText[ cchRESOURCE ];
517       GetDlgItemText (hDlg, IDC_MAP_PATH, szText, cchRESOURCE);
518       if (!szText[0])
519          fEnable = FALSE;
520       }
521
522    EnableWindow (GetDlgItem (hDlg, IDC_NOMAP), fAllowEnable);
523    EnableWindow (GetDlgItem (hDlg, IDC_YESMAP), fAllowEnable);
524
525    EnableWindow (GetDlgItem (hDlg, IDNEXT), fEnable);
526    g.pWizard->EnableButtons ((fEnable) ? (BACK_BUTTON | NEXT_BUTTON) : (BACK_BUTTON));
527
528    fEnable = fAllowEnable && (!IsDlgButtonChecked (hDlg, IDC_NOMAP));
529
530    EnableWindow (GetDlgItem (hDlg, IDC_MAP_LETTER), fEnable);
531    EnableWindow (GetDlgItem (hDlg, IDC_MAP_PATH), fEnable);
532 }
533
534
535 BOOL WizMount_IsSubmountValid (HWND hDlg)
536 {
537    TCHAR szSubmount[ MAX_PATH ];
538    GetDlgItemText (hDlg, IDC_MAP_DESC, szSubmount, MAX_PATH);
539
540    if (!szSubmount[0])
541       return TRUE;
542
543    return IsValidSubmountName (szSubmount);
544 }
545
546
547 BOOL CALLBACK WizMounting_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
548 {
549    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
550       {
551       switch (msg)
552          {
553          case WM_INITDIALOG:
554             g.pWizard->EnableButtons (0);
555             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
556             g.pWizard->SetDefaultControl (IDNEXT);
557             l.idh = IDH_AFSCREDS_WIZ_MOUNT_FAIL;
558             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), FALSE);
559             WizMounting_OnInitDialog (hDlg);
560             break;
561
562          case WM_COMMAND:
563             switch (LOWORD(wp))
564                {
565                case IDNEXT:
566                   g.pWizard->SetState (STEP_FINISH);
567                   break;
568
569                case IDC_MAP_FINISH:
570                   WizMounting_OnFinish (hDlg);
571                   break;
572
573                case IDC_NOMAP:
574                case IDC_YESMAP:
575                case IDC_MAP_PATH:
576                   WizMount_OnEnable (hDlg);
577                   break;
578
579                case IDC_WIZARD:
580                   switch (HIWORD(wp))
581                      {
582                      case wcIS_STATE_DISABLED:
583                         size_t ii;
584                         for (ii = 0; ii < 26; ++ii)
585                            {
586                            if (!l.List.aDriveMap[ ii ].szMapping[0])
587                               continue;
588                            if (l.List.aDriveMap[ ii ].fActive)
589                               continue;
590                            return FALSE;
591                            }
592                         return TRUE;
593                      }
594                   break;
595                }
596             break;
597          }
598       }
599
600    return FALSE;
601 }
602
603
604 void WizMounting_OnInitDialog (HWND hDlg)
605 {
606    l.hDlg = hDlg;
607    ShowWindow (GetDlgItem (hDlg, IDC_MAP_TRY), SW_SHOW);
608    ShowWindow (GetDlgItem (hDlg, IDC_MAP_FAIL), SW_HIDE);
609
610    DWORD idThread;
611    CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)WizMounting_Thread, (LPVOID)0, 0, &idThread);
612 }
613
614
615 void WizMounting_OnFinish (HWND hDlg)
616 {
617    FreeDriveMapList (&l.List);
618    QueryDriveMapList (&l.List);
619
620    size_t cInactive = 0;
621    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
622       {
623       if (!l.List.aDriveMap[iDrive].szMapping[0])
624          continue;
625       if (l.List.aDriveMap[iDrive].fActive)
626          continue;
627       ++cInactive;
628       }
629
630    if (!cInactive)
631       {
632       g.pWizard->SetState (STEP_FINISH);
633       }
634    else
635       {
636       ShowWindow (GetDlgItem (hDlg, IDC_MAP_TRY), SW_HIDE);
637       ShowWindow (GetDlgItem (hDlg, IDC_MAP_FAIL), SW_SHOW);
638       EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
639       }
640 }
641
642
643 DWORD CALLBACK WizMounting_Thread (LPVOID lp)
644 {
645    size_t cInactive = 0;
646    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
647       {
648       if (!l.List.aDriveMap[iDrive].szMapping[0])
649          continue;
650       if (l.List.aDriveMap[iDrive].fActive)
651          continue;
652
653       DWORD status;
654       (void)ActivateDriveMap (l.List.aDriveMap[iDrive].chDrive, l.List.aDriveMap[iDrive].szMapping, l.szSubmountReq, l.List.aDriveMap[iDrive].fPersistent, &status);
655       l.szSubmountReq[0] = TEXT('\0');
656       }
657
658    PostMessage (l.hDlg, WM_COMMAND, IDC_MAP_FINISH, 0);
659    return 0;
660 }
661
662
663 BOOL CALLBACK WizFinish_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
664 {
665    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
666       {
667       switch (msg)
668          {
669          case WM_INITDIALOG:
670             g.pWizard->EnableButtons (NEXT_BUTTON);
671             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_FINISH);
672             g.pWizard->SetDefaultControl (IDNEXT);
673             EnableWindow (GetDlgItem (GetParent (hDlg), IDCANCEL), FALSE);
674             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), FALSE);
675             break;
676
677          case WM_COMMAND:
678             switch (LOWORD(wp))
679                {
680                case IDNEXT:
681                   g.pWizard->Show (FALSE);
682                   break;
683                }
684             break;
685          }
686       }
687
688    return FALSE;
689 }
690