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