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