patch-from-shadow-to-jaltman-bkbox-20031120
[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     },
79    { STEP_STARTING,  IDD_WIZ_STARTING,  WizStarting_DlgProc  },
80    { STEP_CREDS,     IDD_WIZ_CREDS,     WizCreds_DlgProc     },
81    { STEP_MOUNT,     IDD_WIZ_MOUNT,     WizMount_DlgProc     },
82    { STEP_MOUNTING,  IDD_WIZ_MOUNTING,  WizMounting_DlgProc  },
83    { STEP_FINISH,    IDD_WIZ_FINISH,    WizFinish_DlgProc    },
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, SC_MANAGER_ALL_ACCESS)) != NULL)
225       {
226       SC_HANDLE hService;
227       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), SERVICE_ALL_ACCESS)) != NULL)
228          {
229          if (StartService (hService, 0, 0))
230                         TestAndDoMapShare(SERVICE_START_PENDING);
231
232          CloseServiceHandle (hService);
233          }
234
235       CloseServiceHandle (hManager);
236       }
237
238    SetTimer (hDlg, ID_WIZARD_TIMER, (ULONG)cmsecSERVICE, NULL);
239
240    WizStarting_OnTimer (hDlg);
241 }
242
243
244 void WizStarting_OnTimer (HWND hDlg)
245 {
246    SERVICE_STATUS Status;
247    memset (&Status, 0x00, sizeof(Status));
248    Status.dwCurrentState = SERVICE_STOPPED;
249
250    SC_HANDLE hManager;
251    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
252       {
253       SC_HANDLE hService;
254       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
255          {
256          QueryServiceStatus (hService, &Status);
257          CloseServiceHandle (hService);
258                  TestAndDoMapShare(Status.dwCurrentState);
259          }
260
261       CloseServiceHandle (hManager);
262       }
263
264    if (Status.dwCurrentState == SERVICE_RUNNING)
265       {
266       g.pWizard->SetState (STEP_CREDS);
267       }
268    else if (Status.dwCurrentState != SERVICE_START_PENDING)
269       {
270       KillTimer (hDlg, ID_WIZARD_TIMER);
271
272       ShowWindow (GetDlgItem (hDlg, IDC_START_FAIL), SW_SHOW);
273       ShowWindow (GetDlgItem (hDlg, IDC_START_TRY), SW_HIDE);
274       EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
275       }
276 }
277
278
279 BOOL CALLBACK WizCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
280 {
281    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
282       {
283       switch (msg)
284          {
285          case WM_INITDIALOG:
286             g.pWizard->EnableButtons (NEXT_BUTTON);
287             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
288             l.idh = IDH_AFSCREDS_WIZ_CREDS;
289             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
290             WizCreds_OnInitDialog (hDlg);
291             break;
292
293          case WM_COMMAND:
294             switch (LOWORD(wp))
295                {
296                case IDNEXT:
297                   if (!IsDlgButtonChecked (hDlg, IDC_YESCREDS))
298                      {
299                      g.pWizard->SetState (STEP_MOUNT);
300                      }
301                   else
302                      {
303                      TCHAR szCell[ cchRESOURCE ];
304                      GetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szCell, cchRESOURCE);
305                      TCHAR szUser[ cchRESOURCE ];
306                      GetDlgItemText (hDlg, IDC_NEWCREDS_USER, szUser, cchRESOURCE);
307                      TCHAR szPassword[ cchRESOURCE ];
308                      GetDlgItemText (hDlg, IDC_NEWCREDS_PASSWORD, szPassword, cchRESOURCE);
309
310                      WizCreds_OnEnable (hDlg, FALSE);
311
312                      if (ObtainNewCredentials (szCell, szUser, szPassword) == 0)
313                         {
314                         g.pWizard->SetState (STEP_MOUNT);
315                         }
316                      else
317                         {
318                         WizCreds_OnEnable (hDlg);
319                         }
320                      }
321                   break;
322
323                case IDC_NOCREDS:
324                case IDC_YESCREDS:
325                case IDC_NEWCREDS_CELL:
326                case IDC_NEWCREDS_USER:
327                case IDC_NEWCREDS_PASSWORD:
328                   WizCreds_OnEnable (hDlg);
329                   break;
330                }
331             break;
332          }
333       }
334
335    return FALSE;
336 }
337
338
339 void WizCreds_OnInitDialog (HWND hDlg)
340 {
341    HKEY hk;
342
343    TCHAR szCell[ cchRESOURCE ] = TEXT("");
344    (void)GetDefaultCell (szCell);
345    SetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szCell);
346
347    TCHAR szUser[ cchRESOURCE ] = TEXT("");
348    if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hk) == 0)
349       {
350       DWORD dwSize = sizeof(szUser);
351       DWORD dwType = REG_SZ;
352       RegQueryValueEx (hk, TEXT("DefaultUserName"), NULL, &dwType, (PBYTE)szUser, &dwSize);
353       RegCloseKey (hk);
354       }
355    SetDlgItemText (hDlg, IDC_NEWCREDS_USER, szUser);
356    g.pWizard->SetDefaultControl (IDC_NEWCREDS_PASSWORD);
357
358    CheckDlgButton (hDlg, IDC_NOCREDS, FALSE);
359    CheckDlgButton (hDlg, IDC_YESCREDS, TRUE);
360    WizCreds_OnEnable (hDlg);
361 }
362
363
364 void WizCreds_OnEnable (HWND hDlg, BOOL fAllowEnable)
365 {
366    BOOL fEnable = fAllowEnable;
367
368    if (IsDlgButtonChecked (hDlg, IDC_YESCREDS))
369       {
370       TCHAR szText[ cchRESOURCE ];
371       GetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szText, cchRESOURCE);
372       if (!szText[0])
373          fEnable = FALSE;
374
375       GetDlgItemText (hDlg, IDC_NEWCREDS_USER, szText, cchRESOURCE);
376       if (!szText[0])
377          fEnable = FALSE;
378
379       GetDlgItemText (hDlg, IDC_NEWCREDS_PASSWORD, szText, cchRESOURCE);
380       if (!szText[0])
381          fEnable = FALSE;
382       }
383
384    g.pWizard->EnableButtons ((fEnable) ? NEXT_BUTTON : 0);
385
386    EnableWindow (GetDlgItem (hDlg, IDC_NOCREDS), fAllowEnable);
387    EnableWindow (GetDlgItem (hDlg, IDC_YESCREDS), fAllowEnable);
388
389    fEnable = fAllowEnable && IsDlgButtonChecked (hDlg, IDC_YESCREDS);
390    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_CELL), fEnable);
391    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_USER), fEnable);
392    EnableWindow (GetDlgItem (hDlg, IDC_NEWCREDS_PASSWORD), fEnable);
393 }
394
395
396 BOOL CALLBACK WizMount_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
397 {
398    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
399       {
400       switch (msg)
401          {
402          case WM_INITDIALOG:
403             g.pWizard->EnableButtons (BACK_BUTTON | NEXT_BUTTON);
404             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
405             g.pWizard->SetDefaultControl (IDNEXT);
406             l.idh = IDH_AFSCREDS_WIZ_MOUNT;
407             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
408
409             WizMount_OnInitDialog (hDlg);
410             break;
411
412          case WM_COMMAND:
413             switch (LOWORD(wp))
414                {
415                case IDBACK:
416                   g.pWizard->SetState (STEP_CREDS);
417                   break;
418
419                case IDNEXT:
420                   if (IsDlgButtonChecked (hDlg, IDC_YESMAP))
421                      {
422                      if (!WizMount_IsSubmountValid (hDlg))
423                         {
424                         Message (MB_ICONHAND, IDS_BADSUB_TITLE, IDS_BADSUB_DESC);
425                         break;
426                         }
427                      int iItem = SendDlgItemMessage (hDlg, IDC_MAP_LETTER, CB_GETCURSEL, 0, 0);
428                      int iDrive = SendDlgItemMessage (hDlg, IDC_MAP_LETTER, CB_GETITEMDATA, iItem, 0);
429                      l.List.aDriveMap[ iDrive ].chDrive = chDRIVE_A + iDrive;
430                      l.List.aDriveMap[ iDrive ].fActive = FALSE;
431                      l.List.aDriveMap[ iDrive ].fPersistent = TRUE;
432                      GetDlgItemText (hDlg, IDC_MAP_PATH, l.List.aDriveMap[ iDrive ].szMapping, MAX_PATH);
433                      GetDlgItemText (hDlg, IDC_MAP_DESC, l.szSubmountReq, MAX_PATH);
434                      WriteDriveMappings (&l.List);
435                      }
436                   g.pWizard->SetState (STEP_MOUNTING);
437                   break;
438
439                case IDC_NOMAP:
440                case IDC_YESMAP:
441                case IDC_MAP_PATH:
442                   WizMount_OnEnable (hDlg);
443                   break;
444                }
445             break;
446          }
447       }
448
449    return FALSE;
450 }
451
452
453 void WizMount_OnInitDialog (HWND hDlg)
454 {
455    QueryDriveMapList (&l.List);
456
457    size_t cMap = 0;
458    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
459       {
460       if (l.List.aDriveMap[iDrive].szMapping[0])
461          ++cMap;
462       }
463
464    if (cMap)
465       {
466       g.pWizard->SetState (STEP_MOUNTING);
467       return;
468       }
469
470    // Fill in the combo box
471    //
472    DWORD dwDrives = GetLogicalDrives() | 0x07; // Always pretend A,B,C: are used
473
474    int iItemSel = -1;
475    HWND hCombo = GetDlgItem (hDlg, IDC_MAP_LETTER);
476    SendMessage (hCombo, WM_SETREDRAW, FALSE, 0);
477
478    for (int ii = 0; ii < 26; ++ii)
479       {
480       if (!(dwDrives & (1<<ii)))
481          {
482          TCHAR szText[ cchRESOURCE ];
483          GetString (szText, IDS_MAP_LETTER);
484
485          LPTSTR pch;
486          if ((pch = (LPTSTR)lstrchr (szText, TEXT('*'))) != NULL)
487             *pch = TEXT('A') + ii;
488
489          int iItem = SendMessage (hCombo, CB_ADDSTRING, 0, (LPARAM)szText);
490          SendMessage (hCombo, CB_SETITEMDATA, iItem, ii);
491          if (iItemSel == -1)
492             iItemSel = iItem;
493          }
494       }
495
496    SendMessage (hCombo, WM_SETREDRAW, TRUE, 0);
497    SendMessage (hCombo, CB_SETCURSEL, iItemSel, 0);
498
499    SetDlgItemText (hDlg, IDC_MAP_PATH, cm_slash_mount_root);
500
501    CheckDlgButton (hDlg, IDC_NOMAP, FALSE);
502    CheckDlgButton (hDlg, IDC_YESMAP, TRUE);
503 }
504
505
506 void WizMount_OnEnable (HWND hDlg, BOOL fAllowEnable)
507 {
508    BOOL fEnable = fAllowEnable;
509
510    if (IsDlgButtonChecked (hDlg, IDC_YESMAP))
511       {
512       TCHAR szText[ cchRESOURCE ];
513       GetDlgItemText (hDlg, IDC_MAP_PATH, szText, cchRESOURCE);
514       if (!szText[0])
515          fEnable = FALSE;
516       }
517
518    EnableWindow (GetDlgItem (hDlg, IDC_NOMAP), fAllowEnable);
519    EnableWindow (GetDlgItem (hDlg, IDC_YESMAP), fAllowEnable);
520
521    EnableWindow (GetDlgItem (hDlg, IDNEXT), fEnable);
522    g.pWizard->EnableButtons ((fEnable) ? (BACK_BUTTON | NEXT_BUTTON) : (BACK_BUTTON));
523
524    fEnable = fAllowEnable && (!IsDlgButtonChecked (hDlg, IDC_NOMAP));
525
526    EnableWindow (GetDlgItem (hDlg, IDC_MAP_LETTER), fEnable);
527    EnableWindow (GetDlgItem (hDlg, IDC_MAP_PATH), fEnable);
528 }
529
530
531 BOOL WizMount_IsSubmountValid (HWND hDlg)
532 {
533    TCHAR szSubmount[ MAX_PATH ];
534    GetDlgItemText (hDlg, IDC_MAP_DESC, szSubmount, MAX_PATH);
535
536    if (!szSubmount[0])
537       return TRUE;
538
539    return IsValidSubmountName (szSubmount);
540 }
541
542
543 BOOL CALLBACK WizMounting_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
544 {
545    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
546       {
547       switch (msg)
548          {
549          case WM_INITDIALOG:
550             g.pWizard->EnableButtons (0);
551             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_NEXT);
552             g.pWizard->SetDefaultControl (IDNEXT);
553             l.idh = IDH_AFSCREDS_WIZ_MOUNT_FAIL;
554             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), FALSE);
555             WizMounting_OnInitDialog (hDlg);
556             break;
557
558          case WM_COMMAND:
559             switch (LOWORD(wp))
560                {
561                case IDNEXT:
562                   g.pWizard->SetState (STEP_FINISH);
563                   break;
564
565                case IDC_MAP_FINISH:
566                   WizMounting_OnFinish (hDlg);
567                   break;
568
569                case IDC_NOMAP:
570                case IDC_YESMAP:
571                case IDC_MAP_PATH:
572                   WizMount_OnEnable (hDlg);
573                   break;
574
575                case IDC_WIZARD:
576                   switch (HIWORD(wp))
577                      {
578                      case wcIS_STATE_DISABLED:
579                         size_t ii;
580                         for (ii = 0; ii < 26; ++ii)
581                            {
582                            if (!l.List.aDriveMap[ ii ].szMapping[0])
583                               continue;
584                            if (l.List.aDriveMap[ ii ].fActive)
585                               continue;
586                            return FALSE;
587                            }
588                         return TRUE;
589                      }
590                   break;
591                }
592             break;
593          }
594       }
595
596    return FALSE;
597 }
598
599
600 void WizMounting_OnInitDialog (HWND hDlg)
601 {
602    l.hDlg = hDlg;
603    ShowWindow (GetDlgItem (hDlg, IDC_MAP_TRY), SW_SHOW);
604    ShowWindow (GetDlgItem (hDlg, IDC_MAP_FAIL), SW_HIDE);
605
606    DWORD idThread;
607    CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)WizMounting_Thread, (LPVOID)0, 0, &idThread);
608 }
609
610
611 void WizMounting_OnFinish (HWND hDlg)
612 {
613    FreeDriveMapList (&l.List);
614    QueryDriveMapList (&l.List);
615
616    size_t cInactive = 0;
617    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
618       {
619       if (!l.List.aDriveMap[iDrive].szMapping[0])
620          continue;
621       if (l.List.aDriveMap[iDrive].fActive)
622          continue;
623       ++cInactive;
624       }
625
626    if (!cInactive)
627       {
628       g.pWizard->SetState (STEP_FINISH);
629       }
630    else
631       {
632       ShowWindow (GetDlgItem (hDlg, IDC_MAP_TRY), SW_HIDE);
633       ShowWindow (GetDlgItem (hDlg, IDC_MAP_FAIL), SW_SHOW);
634       EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), TRUE);
635       }
636 }
637
638
639 DWORD CALLBACK WizMounting_Thread (LPVOID lp)
640 {
641    size_t cInactive = 0;
642    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
643       {
644       if (!l.List.aDriveMap[iDrive].szMapping[0])
645          continue;
646       if (l.List.aDriveMap[iDrive].fActive)
647          continue;
648
649       DWORD status;
650       (void)ActivateDriveMap (l.List.aDriveMap[iDrive].chDrive, l.List.aDriveMap[iDrive].szMapping, l.szSubmountReq, l.List.aDriveMap[iDrive].fPersistent, &status);
651       l.szSubmountReq[0] = TEXT('\0');
652       }
653
654    PostMessage (l.hDlg, WM_COMMAND, IDC_MAP_FINISH, 0);
655    return 0;
656 }
657
658
659 BOOL CALLBACK WizFinish_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
660 {
661    if (!WizCommon_DlgProc (hDlg, msg, wp, lp))
662       {
663       switch (msg)
664          {
665          case WM_INITDIALOG:
666             g.pWizard->EnableButtons (NEXT_BUTTON);
667             g.pWizard->SetButtonText (IDNEXT, IDS_WIZ_FINISH);
668             g.pWizard->SetDefaultControl (IDNEXT);
669             EnableWindow (GetDlgItem (GetParent (hDlg), IDCANCEL), FALSE);
670             EnableWindow (GetDlgItem (GetParent (hDlg), IDHELP), FALSE);
671             break;
672
673          case WM_COMMAND:
674             switch (LOWORD(wp))
675                {
676                case IDNEXT:
677                   g.pWizard->Show (FALSE);
678                   break;
679                }
680             break;
681          }
682       }
683
684    return FALSE;
685 }
686