windows-updates-20010819
[openafs.git] / src / WINNT / win9xpanel / WinAfsLoadDlg.cpp
1 // WinAfsLoadDlg.cpp : implementation file
2 //
3 /* Copyright 2000, International Business Machines Corporation and others.
4         All Rights Reserved.
5  
6         This software has been released under the terms of the IBM Public
7         License.  For details, see the LICENSE file in the top-level source
8         directory or online at http://www.openafs.org/dl/license10.html
9 */
10
11 #include "stdafx.h"
12 #include "WinAfsLoad.h"
13 #include "WinAfsLoadDlg.h"
14 #include "modver.h"
15 #include "encript.h"
16 #include <winreg.h>
17 #include "change.h"
18 #include "cregkey.h"
19 #include "force.h"
20 #include "retry.h"
21 #include <Lmcons.h>
22 #include "settings.h"
23 #include "afsmsg95.h"
24 #include "ProgBarDlg.h"
25 #include "MyFrame.h"
26 #include "commandsettings.h"
27 //#include <process.h>
28
29 #define PASSWORDSIZE 32
30 #define USERNAMESIZE 32
31 #define SHARENAMESIZE 12
32 #define MAXSHARES 10
33 #define DRIVESIZE 3
34 #define AUTOSIZE 1
35 #define ITEMCHECKED 0x2000      //CONTROL List defined for checked and not checked condition
36 #define ITEMNOTCHECKED 0x1000
37 #define TIMEINTERVAL 200        
38 #define CHECKDIR 2500   //NUMBER CYCLE before checking directory for changes (2.5 seconds)
39 #define MAXWORLDINDEX 25        //Number of frames (-1) in the whirling world
40
41 #ifdef _DEBUG
42 #define new DEBUG_NEW
43 #undef THIS_FILE
44 static char THIS_FILE[] = __FILE__;
45 #endif
46
47
48 /////////////////////////////////////////////////////////////////////////////
49 // CAboutDlg dialog used for App About
50
51 class CAboutDlg : public CDialog
52 {
53 public:
54         CAboutDlg();
55
56 // Dialog Data
57         //{{AFX_DATA(CAboutDlg)
58         enum { IDD = IDD_ABOUTBOX };
59         CString m_sVersion;
60         //}}AFX_DATA
61
62         // ClassWizard generated virtual function overrides
63         //{{AFX_VIRTUAL(CAboutDlg)
64         protected:
65         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
66         //}}AFX_VIRTUAL
67
68 // Implementation
69 protected:
70         //{{AFX_MSG(CAboutDlg)
71         //}}AFX_MSG
72         DECLARE_MESSAGE_MAP()
73 };
74
75 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
76 {
77         //{{AFX_DATA_INIT(CAboutDlg)
78         m_sVersion = _T("");
79         //}}AFX_DATA_INIT
80 }
81
82 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
83 {
84         CDialog::DoDataExchange(pDX);
85         //{{AFX_DATA_MAP(CAboutDlg)
86         DDX_Text(pDX, IDC_STATICABOUT, m_sVersion);
87         //}}AFX_DATA_MAP
88 }
89
90 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
91         //{{AFX_MSG_MAP(CAboutDlg)
92                 // No message handlers
93         //}}AFX_MSG_MAP
94 END_MESSAGE_MAP()
95
96
97 class CCancel
98 {
99         BOOL *m_pPtr;
100         BOOL m_bVal;
101 public:
102         CCancel(BOOL &sav,BOOL val){m_pPtr=&sav;m_bVal=val;}
103         ~CCancel(){
104                 *m_pPtr=m_bVal;
105         }
106 };
107
108 /////////////////////////////////////////////////////////////////////////////
109 // CWinAfsLoadDlg dialog
110
111 CWinAfsLoadDlg::CWinAfsLoadDlg(const char *user,const char *pass,CWnd* pParent /*=NULL*/)
112         : CDialog(CWinAfsLoadDlg::IDD, pParent), m_trayIcon(WM_MY_TRAY_NOTIFICATION,IDR_MAINFRAME,IDR_TRAYICON)
113 {
114         //{{AFX_DATA_INIT(CWinAfsLoadDlg)
115         m_sPassword = _T("");
116         m_sUsername = _T("");
117         m_sMountDisplay = _T("");
118         //}}AFX_DATA_INIT
119         // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
120         if (user)
121                 m_sUsername=user;
122         if (pass)
123                 m_sPassword=pass;
124         m_bConnect=CWINAFSLOADAPP->m_bConnect;
125         m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
126         m_pImagelist=NULL;
127         m_iActiveItem=-1;               //used in MountList to indicate which item is clicked on
128         m_nAutTimer=m_nDirTimer=0;
129         m_pEncript=NULL;
130         m_PowerResumeDelay=-1;
131 //      m_PowerDelay=0;
132 }
133
134 void CWinAfsLoadDlg::DoDataExchange(CDataExchange* pDX)
135 {
136         CDialog::DoDataExchange(pDX);
137         //{{AFX_DATA_MAP(CWinAfsLoadDlg)
138         DDX_Control(pDX, IDC_WORLD, m_cWorld);
139         DDX_Control(pDX, IDC_AUTHWARN, m_cAuthWarn);
140         DDX_Control(pDX, IDC_AUTH, m_cAuthenicate);
141         DDX_Control(pDX, IDC_SAVEUSERNAME, m_cSaveUsername);
142         DDX_Control(pDX, IDC_DRIVEMOUNTLIST, m_cMountlist);
143         DDX_Control(pDX, IDC_CHANGE, m_cChange);
144         DDX_Control(pDX, IDC_REMOVE, m_cRemove);
145         DDX_Control(pDX, IDC_OPTIONLINE, m_cOptionLine);
146         DDX_Control(pDX, IDC_CHECKADVANCED, m_cCheckAdvanceDisplay);
147         DDX_Control(pDX, IDC_CONNECT, m_cConnect);
148         DDX_Control(pDX, IDC_CANCEL, m_cCancel);
149         DDX_Control(pDX, IDC_PASSWORD, m_cPassword);
150         DDX_Control(pDX, IDC_USERNAME, m_cUsername);
151         DDX_Text(pDX, IDC_PASSWORD, m_sPassword);
152         DDV_MaxChars(pDX, m_sPassword, 32);
153         DDX_Text(pDX, IDC_USERNAME, m_sUsername);
154         DDV_MaxChars(pDX, m_sUsername, 32);
155         DDX_Text(pDX, IDC_MOUNTDISPLAY, m_sMountDisplay);
156         //}}AFX_DATA_MAP
157 }
158
159 BEGIN_MESSAGE_MAP(CWinAfsLoadDlg, CDialog)
160         //{{AFX_MSG_MAP(CWinAfsLoadDlg)
161         ON_WM_SYSCOMMAND()
162         ON_WM_PAINT()
163         ON_BN_CLICKED(IDC_CONNECT, OnConnect)
164         ON_BN_CLICKED(IDC_CHECKADVANCED, OnCheckadvanced)
165         ON_COMMAND(IDM_APP_OPEN, OnAppOpen)
166         ON_BN_CLICKED(IDC_CHANGE, OnChange)
167         ON_BN_CLICKED(IDC_ADD, OnAdd)
168         ON_BN_CLICKED(IDC_REMOVE, OnRemove)
169         ON_NOTIFY(NM_CLICK, IDC_DRIVEMOUNTLIST, OnClickDrivemountlist)
170         ON_NOTIFY(LVN_ITEMCHANGED, IDC_DRIVEMOUNTLIST, OnItemchangedDrivemountlist)
171         ON_WM_QUERYENDSESSION()
172         ON_WM_TIMER()
173         ON_BN_CLICKED(IDC_AUTH, OnAuthenicate)
174         ON_WM_DESTROY()
175         ON_WM_CTLCOLOR()
176         ON_COMMAND(IDC_SHOWBACK, OnShow)
177         ON_WM_HELPINFO()
178         ON_BN_CLICKED(IDC_HELPMAIN, OnHelpmain)
179         ON_BN_CLICKED(IDC_SETTINGS, OnSettings)
180         ON_BN_CLICKED(IDC_CANCEL, OnCancel)
181         ON_WM_SYSCOMMAND()
182         //}}AFX_MSG_MAP
183         ON_BN_CLICKED(IDM_EXPLORERAFS, OnTrayButton0)
184         ON_BN_CLICKED(IDM_EXPLORERAFS+16, OnTrayButton1)
185         ON_BN_CLICKED(IDM_EXPLORERAFS+32, OnTrayButton2)
186         ON_BN_CLICKED(IDM_EXPLORERAFS+48, OnTrayButton3)
187         ON_BN_CLICKED(IDM_EXPLORERAFS+64, OnTrayButton4)
188         ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify )
189         ON_MESSAGE(WM_POWERBROADCAST,OnPowerBroadcast)
190         ON_MESSAGE(WM_ERRORMSG,OnErrorMessage)
191 END_MESSAGE_MAP()
192
193 /////////////////////////////////////////////////////////////////////////////
194 // CWinAfsLoadDlg message handlers
195
196
197 BOOL CWinAfsLoadDlg::OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
198 {
199     TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
200     UINT nID =pNMHDR->idFrom;
201     if (pTTT->uFlags & TTF_IDISHWND)
202     {
203         // idFrom is actually the HWND of the tool
204         nID = ::GetDlgCtrlID((HWND)nID);
205                 switch (nID)
206                 {
207                 case IDC_CHECKADVANCED:
208                         if (m_cCheckAdvanceDisplay.GetCheck())
209                     pTTT->lpszText = MAKEINTRESOURCE(IDS_HIDEADVANCE);
210                         else
211                     pTTT->lpszText = MAKEINTRESOURCE(nID);
212             pTTT->hinst = AfxGetResourceHandle();
213             return(TRUE);
214
215                 case IDC_SAVEUSERNAME:
216                         if (m_cSaveUsername.GetCheck())
217                     pTTT->lpszText = MAKEINTRESOURCE(IDS_FORGETUSERNAME);
218                         else
219                     pTTT->lpszText = MAKEINTRESOURCE(nID);
220             pTTT->hinst = AfxGetResourceHandle();
221             return(TRUE);
222                 case IDC_CANCEL:
223                         if (m_bServiceIsActive)
224                     pTTT->lpszText = MAKEINTRESOURCE(IDS_HIDE);
225                         else
226                     pTTT->lpszText = MAKEINTRESOURCE(nID);
227             pTTT->hinst = AfxGetResourceHandle();
228             return(TRUE);
229                 case IDC_CONNECT:
230                         if (m_bServiceIsActive)
231                     pTTT->lpszText = MAKEINTRESOURCE(IDS_DISCONNECT);
232                         else
233                     pTTT->lpszText = MAKEINTRESOURCE(nID);
234             pTTT->hinst = AfxGetResourceHandle();
235             return(TRUE);
236                 default:
237             pTTT->lpszText = MAKEINTRESOURCE(nID);
238             pTTT->hinst = AfxGetResourceHandle();
239             return(TRUE);
240                 case 0:
241                         break;
242         }
243     }
244     return(FALSE);
245 }
246
247 BOOL CWinAfsLoadDlg::PreTranslateMessage(MSG* pMsg) 
248 {
249         // TODO: Add your specialized code here and/or call the base class
250         // get the accelerator table to work, i.e. press <enter> is same as IDC_CONNECT
251         if (m_hAccelTable) 
252         {
253                 if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
254                         return(TRUE);
255         }
256         return CDialog::PreTranslateMessage(pMsg);
257 }
258
259 BOOL CWinAfsLoadDlg::OnInitDialog()
260 {
261         DWORD rc;
262         char compName[129];
263         CString msg;
264         CDialog::OnInitDialog();
265         // Add "About..." menu item to system menu.
266
267         // IDM_ABOUTBOX must be in the system command range.
268         ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
269         ASSERT(IDM_ABOUTBOX < 0xF000);
270
271         CMenu* pSysMenu = GetSystemMenu(FALSE);
272         if (pSysMenu != NULL)
273         {
274                 CString strMenu;
275                 strMenu.LoadString(IDS_ABOUTBOX);
276                 ASSERT(!strMenu.IsEmpty());
277                 pSysMenu->AppendMenu(MF_SEPARATOR);
278                 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strMenu);
279         }
280         if (CWINAFSLOADAPP->m_bShowAfs)
281                 OnShowAddMenus();
282         // Set the icon for this dialog.  The framework does this automatically
283         //  when the application's main window is not a dialog
284         SetIcon(m_hIcon, TRUE);                 // Set big icon
285         SetIcon(m_hIcon, FALSE);                // Set small icon
286         // TODO: Add extra initialization here
287
288         m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1)); 
289
290 // bind to socket's DLL
291
292         DWORD uStatus;
293         WSADATA WSAData;
294         if ((uStatus = WSAStartup(MAKEWORD(1,1), &WSAData)) == 0) {
295                 LOG("AFS:Startup%s",WSAData.szDescription);
296         } else {
297                 msg.Format("AFS Error - Cannot find socket.dll status=0x%0x", uStatus);
298                 AfxMessageBox(msg,MB_OK);
299                 SendMessage(WM_CLOSE,0,0);
300                 LOG("WM_CLOSE3");
301                 return FALSE;
302         }
303
304         // We need to make sure the DLL's support the features provided by the CListCtrl common control
305         // That is they must be later than 4.71 
306     
307 //      ver.GetFileVersionInfo("comctl32.dll",vernum);  //use this form if Win95???
308
309         DWORD vernum;
310     DLLVERSIONINFO dvi;
311         CModuleVersion ver;
312         if (!ver.DllGetVersion("comctl32.dll", dvi,vernum))
313                 ver.GetFileVersionInfo("comctl32.dll",vernum);
314         LOG("comctl32 %d.%d",(vernum>>16) & 0xff,vernum & 0xff);
315         if(vernum< PACKVERSION(4,70))
316         {
317                 msg.Format("Current Version %d.%d, Recommend at least version 4.70 for COMCTL32.dll, (Install, 401COMUPD.EXE or Internet Explorer 4.01 SP2 or better)",HIWORD(vernum),LOWORD(vernum));
318                 MessageBox(msg, "AFS DLL Version Warning", MB_OK);
319                 m_cCheckAdvanceDisplay.ModifyStyle(0,WS_DISABLED);
320         } else {
321         if (!ver.DllGetVersion("Shell32.dll", dvi,vernum))
322                 ver.GetFileVersionInfo("Shell32.dll",vernum);
323         LOG("Shell32 %d.%d",(vernum>>16) & 0xff,vernum & 0xff);
324         if(vernum< PACKVERSION(4,00))
325         {
326                 msg.Format("Current Version %d.%d, Recommend at least version 4.00 for SHELL32.dll, (Install Internet Explorer 4.01 SP2 or better)",HIWORD(vernum),LOWORD(vernum));
327                 MessageBox(msg, "AFS DLL Version Warning", MB_OK);
328                 m_cCheckAdvanceDisplay.ModifyStyle(0,WS_DISABLED);
329         }
330         }
331         if (!ver.DllGetVersion("ADVAPI32.dll", dvi,vernum))
332                 ver.GetFileVersionInfo("ADVAPI32.dll",vernum);
333         LOG("ADVAPI32 %d.%d",(vernum>>16) & 0xff,vernum & 0xff);
334         m_pEncript = (CEncript *)new CEncript(this);
335         
336
337         // initiallze AFS and setup Progress display
338         if (!m_cAfs.Init(this,msg))
339                 HandleError(msg);
340
341         m_trayIcon.AddIcon(this);
342         EnableToolTips(TRUE);
343         
344         m_bServiceIsActive=FALSE;
345         // Obtain Version String
346         CRegkey key(HKEY_LOCAL_MACHINE,"Software\\Open AFS\\AFS Control Center","CurrentVersion");
347         key.GetString("VersionString",m_VersionString,128);
348         msg.Format("%s %s",AFSTITLE,m_VersionString);
349         SetWindowText(msg);
350
351         UpdateData(TRUE);
352
353         rc = 128; GetComputerName(compName, &rc);
354         m_sComputername=compName;
355         m_sMountDisplay.Format("Connected Drives on Computer:%s",compName);
356         m_sUsername="";
357         CRect rect;
358         GetWindowRect(&m_OriginalRect);
359         m_cOptionLine.GetWindowRect(&rect);
360         m_DialogShrink=rect.top-m_OriginalRect.top+5;   //make it above the edit box
361         SetWindowPos(&wndTop,0,0,m_OriginalRect.right-m_OriginalRect.left,m_DialogShrink,SWP_NOMOVE|SWP_NOZORDER);
362         // Pull registration information out
363         CRegkey regkey("AFS\\Window");
364         UINT logintime=0;
365         DWORD size=sizeof(m_PowerResumeDelay);
366         regkey.GetBinary("PowerResumeDelay",(LPBYTE)&m_PowerResumeDelay,size);
367         if (m_PowerResumeDelay<=0) {
368                 m_PowerResumeDelay=20;  //seconds
369                 regkey.PutBinary("PowerResumeDelay",(LPBYTE)&m_PowerResumeDelay,size);
370         }
371         CHAR pLoginName[UNLEN + 1];
372         size=UNLEN;
373         if (CWINAFSLOADAPP->m_bNoID)
374         {
375                 CWnd *w=GetDlgItem(IDC_USERNAME);
376                 w->EnableWindow(FALSE);
377                 w=GetDlgItem(IDC_PASSWORD);
378                 w->EnableWindow(FALSE);
379                 w=GetDlgItem(IDC_SAVEUSERNAME);
380                 w->EnableWindow(FALSE);
381         } else {
382                 if (GetUserName(pLoginName,&size))
383                 {
384                         m_sLoginName=pLoginName;
385                 } else
386                         m_sLoginName="Bozo";
387                 CString sUser,sPass;
388                 RegPassword(sUser,sPass,TRUE);
389                 if (m_sUsername=="")
390                 {
391                         m_sUsername=sUser;
392                 }
393                 if ((m_sUsername=="") && (m_sLoginName!="Bozo"))
394                 {
395                         m_sUsername=m_sLoginName;
396                 }
397                 if ((m_sPassword=="") || (m_sPassword.IsEmpty()))
398                 {
399                         m_sPassword=sPass;
400                 }
401                 if (m_sPassword.IsEmpty())
402                 {
403                         m_cSaveUsername.SetCheck(FALSE);
404                         RegLastUser(m_sUsername,TRUE);
405                 } else
406                         m_cSaveUsername.SetCheck(TRUE);
407         }
408         // Initialize mount control list
409
410         m_pImagelist = new CImageList();
411         ASSERT(m_pImagelist != NULL);    // serious allocation failure checking
412         m_pImagelist->Create(16, 16, 0, 2, 2);
413         m_cMountlist.SetImageList(m_pImagelist, LVSIL_SMALL);
414
415         m_cMountlist.GetWindowRect(&rect);
416         {// don't particullary want to keep the DC around
417         CClientDC dc(this);
418         CSize cSize=dc.GetTextExtent("*",1);
419         CSize dSize=dc.GetTextExtent("XXXXXXXXXXX",12);
420         cSize.cx+=10;
421         int r=rect.Width()-cSize.cx-dSize.cx;
422 #define COLDRIVE 0
423         m_cMountlist.InsertColumn(COLDRIVE, "Drive", LVCFMT_LEFT,
424                 r * 1/5, 0);
425 #define COLPATH 1
426         m_cMountlist.InsertColumn(COLPATH, "Afs Path", LVCFMT_LEFT,
427                 r * 4/5, 1);
428 #define COLAUTO 2
429         m_cMountlist.InsertColumn(COLAUTO, "*", LVCFMT_CENTER,
430                 cSize.cx, 1);
431 #define COLSHARE 3
432 #define NUMCOL 4
433         m_cMountlist.InsertColumn(COLSHARE, "Share Name", LVCFMT_LEFT,
434                 dSize.cx, 1);
435         m_cMountlist.SetExtendedStyle(m_cMountlist.GetExtendedStyle() | LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES );
436         }
437         ProfileData(FALSE);
438         UpdateData(FALSE);
439         DismountAll(msg,3);
440         BuildDriveList(TRUE);
441         m_seqIndex=0;
442         m_seqCount=0;                   //set up sequence timer for moving world
443         m_nShown=0;
444         m_cAuthWarn.ShowWindow(SW_HIDE);
445         m_bkBrush.CreateSolidBrush(RGB(255,255,0));
446    
447 // WHIRLING world display
448         m_cWorld.SetWindowPos(NULL,0,0,42,42,SWP_NOMOVE|SWP_NOZORDER);
449         m_cWorld.GetWindowRect(&m_WorldRect);
450         ScreenToClient(&m_WorldRect);
451     VERIFY( m_bmpWorld.LoadBitmap( IDB_WORLD ) );
452
453         m_seqCount=0;
454         m_seqIndex=0;
455         m_dirCount=0;
456         m_nDirTimer=SetTimer(WM_DIRTIMER,TIMEINTERVAL,0);
457 #ifdef _DEBUG
458         m_nAutTimer=SetTimer(WM_AUTTIMER,10000,0);
459 #else
460         m_nAutTimer=SetTimer(WM_AUTTIMER,60000,0);
461 #endif
462         m_bRestartAFSD=FALSE;
463         m_OSVersion.dwOSVersionInfoSize=sizeof(m_OSVersion);
464         GetVersionEx(&m_OSVersion);                     //get OS type & version
465         if (m_bConnect)
466                 PostMessage(WM_COMMAND,IDC_CONNECT,0);
467         else 
468                 GotoDlgCtrl(&m_cConnect);
469         return FALSE;
470         // return TRUE  unless you set the focus to a control
471 }       // end OnInitDialog
472
473 BOOL CWinAfsLoadDlg::RegPassword(CString &user,CString &pass,BOOL fetch)
474 {
475         DWORD len;
476         char *pBuffer;
477         CString sKey;
478         sKey.Format("AFS\\Security\\%s",m_sLoginName);
479         CRegkey regkey(sKey);
480         if (regkey.Getkey()==0) return FALSE;
481         if (fetch)
482         {
483                 regkey.GetString("UserName",user,USERNAMESIZE);
484                 if (user.IsEmpty()||(user==""))
485                 {
486                         return TRUE;
487                 }
488                 len=PASSWORDSIZE;
489                 pBuffer=new char[(int)len+1];
490                 regkey.GetBinary("Password",(LPBYTE)pBuffer,len);
491                 if (len==0)
492                         return TRUE;
493                 if (m_pEncript)
494                         m_pEncript->Encript(m_sComputername,m_sLoginName,user
495                         ,(UCHAR *)pBuffer,len,FALSE);
496                 pBuffer[(int)len]=0;
497                 pass=pBuffer;
498                 delete(pBuffer);
499         } else {
500                 if (user.IsEmpty()||pass.IsEmpty()) {
501                         regkey.PutString("UserName",user);
502                         regkey.PutBinary("Password",NULL,0);
503                         return TRUE;
504                 }
505                 if (regkey.PutString("UserName",user))
506                 {
507                         len=pass.GetLength();
508                         pBuffer=new char[(int)len+1];
509                         strcpy(pBuffer,pass);
510                         if (m_pEncript)
511                                 m_pEncript->Encript(m_sComputername,m_sLoginName,user
512                                 ,(UCHAR *)pBuffer,len,TRUE);
513                         else
514                                 len=strlen(pBuffer);
515                         regkey.PutBinary("Password",(LPBYTE)pBuffer,len);
516                         delete(pBuffer);
517                 }
518         }
519         return TRUE;
520 }
521
522 BOOL CWinAfsLoadDlg::RegLastUser(CString &user,BOOL fetch)
523 {
524         CString sKey;
525         sKey.Format("AFS\\Security\\%s",m_sLoginName);
526         CRegkey regkey(sKey);
527         if (regkey.Getkey()==0) return FALSE;
528         if (fetch)
529         {
530                 regkey.GetString("LastUser",user,USERNAMESIZE);
531                 return TRUE;
532         }
533         return (regkey.PutString("LastUser",user));
534 }
535
536 // MOdify the system menu
537 /// need to add items to Icon Menu also
538 /// check out sc_close for close postion rather than depend on fixed position
539 /// Need to add Menu Item aphbetical to drive letter
540
541 #define NUMOFMENUDRIVES 5
542 #define INSERTPOSITION 6
543
544 void CWinAfsLoadDlg::AddMenu(const char *sDrive,const char *share)
545 {
546         CMenu* pSysMenu = GetSystemMenu(FALSE);
547         if (pSysMenu == NULL) return;
548         CString msg;
549         msg.Format("%s  %s",sDrive,share);
550         UINT id=pSysMenu->GetMenuItemID(INSERTPOSITION);        //insert before About Menu Item
551         if (id==IDM_EXPLORERAFS) 
552         {
553                 char lpString[3];
554 // limit number of drives added to is NUMOFDRIVES
555                 int i=INSERTPOSITION;
556                 do {
557                         int len=pSysMenu->GetMenuString(i,lpString,2,MF_BYPOSITION);
558                         if (*sDrive==*lpString) return;
559                         UINT nID=pSysMenu->GetMenuItemID(++i);
560                         if  ((nID<IDM_EXPLORERAFS) || (nID>IDM_EXPLORERAFS+16*(NUMOFMENUDRIVES-1)))//NOT a Drive ITEM
561                         {
562                                 pSysMenu->InsertMenu(i,MF_BYPOSITION,IDM_EXPLORERAFS+16*(i-INSERTPOSITION),msg);
563                                 MENUBLOCK blk(IDM_EXPLORERAFS+16*(i-INSERTPOSITION),msg);
564                                 m_trayIcon.AddDrive(blk);
565                                 return;
566                         }
567                 } while (i<INSERTPOSITION+NUMOFMENUDRIVES-1);
568         } else {
569                 id=IDM_ABOUTBOX;
570                 MENUBLOCK blk(IDM_EXPLORERAFS,msg);
571                 m_trayIcon.AddDrive(blk);
572                 if (!pSysMenu->InsertMenu(INSERTPOSITION,MF_BYPOSITION,MF_SEPARATOR)) return;
573                 if (!pSysMenu->InsertMenu(INSERTPOSITION,MF_BYPOSITION,IDM_EXPLORERAFS,msg)) return;
574         }
575         return;
576 }
577
578 void CWinAfsLoadDlg::RemoveMenu(const char *sDrive)
579 {
580         CMenu* pSysMenu = GetSystemMenu(FALSE);
581         if (pSysMenu == NULL) return;
582         UINT nID=pSysMenu->GetMenuItemID(INSERTPOSITION);
583         if ((nID<IDM_EXPLORERAFS)||(nID>IDM_EXPLORERAFS+16*NUMOFMENUDRIVES)) return;
584         char lpString[3];
585         for (int i=INSERTPOSITION;i<=INSERTPOSITION+NUMOFMENUDRIVES-1;i++)
586         {
587                 int len=pSysMenu->GetMenuString(i,lpString,2,MF_BYPOSITION);
588                 if (*sDrive==*lpString)
589                 {
590                         MENUBLOCK blk;
591                         blk.title=sDrive;
592                         blk.mID=pSysMenu->GetMenuItemID(i);
593                         m_trayIcon.RemoveDrive(blk);
594                         if (!pSysMenu->RemoveMenu(i,MF_BYPOSITION )) return;
595                         if  ((i==INSERTPOSITION)&& (pSysMenu->GetMenuItemID(i)==MF_SEPARATOR))
596                                 pSysMenu->RemoveMenu(i,MF_BYPOSITION);
597                         return;
598                 }
599         }
600 /// scan rest of list to see if you need to add a drive
601         return;
602 }
603 void CWinAfsLoadDlg::OnSysCommand(UINT nID, LPARAM lParam)
604 {
605         switch (nID & 0xFFF0)
606         {
607         case IDM_VIEWAFS:
608                 {
609                 HWND hwnd=m_cAfs.GetLoadWindowHandle();
610                 if (hwnd==NULL) break;
611                 UINT show=(::IsWindowVisible(hwnd))?SW_HIDE:SW_SHOWNORMAL;
612                 ::ShowWindow(m_cAfs.GetLoadWindowHandle(),show);
613                 }
614                 break;
615         case IDM_CAPTUREWINDOW:
616                 CWINAFSLOADAPP->m_bLogWindow=TRUE;
617                 CWINAFSLOADAPP->ShowLog(TRUE);
618                 break;
619         case IDM_CAPTUREFILE:
620                 CWINAFSLOADAPP->m_bLog=TRUE;
621                 CWINAFSLOADAPP->ShowPrint(TRUE);
622                 break;
623         case IDM_ABOUTBOX:
624                 {
625                 CAboutDlg dlgAbout;
626                 // Lets update About box to include version information 
627                 char wdir[MAX_PATH];
628 #ifdef _DEBUG 
629                 wsprintf(wdir,"%s.exe",((CWinAfsLoadApp *)AfxGetApp())->m_pszExeName);
630 #else
631                 wsprintf(wdir,"%s.exe",CWINAFSLOADAPP->m_pszExeName);
632 #endif
633                 DWORD wHandle;
634                 DWORD rc;
635                 rc =GetFileVersionInfoSize(wdir,&wHandle);
636                 if (rc>0)
637                 {
638                         BYTE *lpData=(BYTE *)new BYTE[rc];
639                         if (GetFileVersionInfo(wdir,wHandle,rc,lpData))
640                         {
641                                 UINT len;
642                                 struct TRANSLATION {
643                                         WORD langID;         // language ID
644                                         WORD charset;        // character set (code page)
645                                 };
646                                 CString msg;
647                                 TRANSLATION mTrans,* pTrans;
648                                 if (VerQueryValue(lpData,
649                                         "\\VarFileInfo\\Translation", (PVOID *)&pTrans, &len) && len >= 4) {
650                                         mTrans = *pTrans;
651                                         TRACE("code page = %d\n", mTrans.charset);
652                                         }
653                                 LPCTSTR pVal;
654                                 UINT iLenVal;
655                                 CString query;
656                                 query.Format(_T("\\StringFileInfo\\%04x%04x\\%s"),
657                                         mTrans.langID,
658                                         mTrans.charset,
659                                         _T("ProductVersion"));
660                                 if (VerQueryValue(lpData, (LPTSTR)(LPCTSTR)query,
661                                         (LPVOID*)&pVal, &iLenVal)) {
662 //                                      dlgAbout.m_sVersion.Format("WinAFSload Version %s",pVal);
663                                 }
664                         }
665                         delete lpData;
666                 }
667                 dlgAbout.DoModal();
668                 }
669         case SC_ICON:
670                 if (GetFocus())
671                         m_trayIcon.MinimiseToTray(this);        //only if click on miminization botton i
672                 else 
673                         CDialog::OnSysCommand(nID, lParam);     //do this to mimic the normal windows behavor
674                 break;
675
676         default:
677                 if ((nID>=IDM_EXPLORERAFS)&&(nID<=IDM_EXPLORERAFS+16*NUMOFMENUDRIVES))
678                 {
679                         CMenu* pSysMenu = GetSystemMenu(FALSE);
680                         if (pSysMenu == NULL) return;
681                         CString msg;
682                         char sDrive[3];
683                         pSysMenu->GetMenuString(nID,sDrive,3,MF_BYCOMMAND);
684                         if (!m_cAfs.StartExployer(msg,sDrive))
685                                 HandleError(msg);
686                         break;
687                 }
688                 CDialog::OnSysCommand(nID, lParam);
689                 break;
690         }
691 }
692
693 // If you add a minimize button to your dialog, you will need the code below
694 //  to draw the icon.  For MFC applications using the document/view model,
695 //  this is automatically done for you by the framework.
696
697 void CWinAfsLoadDlg::OnPaint() 
698 {
699         CPaintDC dc(this); // device context for painting
700         if (IsIconic())
701         {
702                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
703
704                 // Center icon in client rectangle
705                 int cxIcon = GetSystemMetrics(SM_CXICON);
706                 int cyIcon = GetSystemMetrics(SM_CYICON);
707                 CRect rect;
708                 GetClientRect(&rect);
709                 int x = (rect.Width() - cxIcon + 1) / 2;
710                 int y = (rect.Height() - cyIcon + 1) / 2;
711
712                 // Draw the icon
713                 dc.DrawIcon(x, y, m_hIcon);
714         }
715         else
716         {
717                 m_bmpWorld.DrawTrans(dc,m_WorldRect,(m_WorldRect.Width()-1)*m_seqIndex);
718         }
719 }
720
721
722 void CWinAfsLoadDlg::HandleError(const char *s,BOOL display)
723 {
724         LOG(s);
725         UpdateData(FALSE);
726         if (display)
727         {       
728                 m_cAfs.FinishProgress();
729                 CWait wait(IDC_ARROW);
730                 MessageBox(s,"AFS Client Warning",MB_ICONWARNING | MB_OK);
731         }
732 }
733
734
735 void CWinAfsLoadDlg::OnConnect() 
736 {
737 // This is required to keep a process from getting inbehind the error display dialog box and hitting the Connect Button again.
738 // the best way to avoid this would have been to separate GUI task from processes; that way
739 // the Connect button would have bee disabled while the process is busy or if waiting for an error response!  It is possible 
740 // to send a ClickMessage to the Connect button even with the a modal dialog box overlaying the main dialog!
741
742         if (CWait::IsBusy()) return;
743         CString msg;
744         CWait wait;
745         m_iActiveItem=-1;               //necessary to indicate to MountList that items being changed are done by program not by mouse input
746         UpdateData(TRUE);
747         if (m_bServiceIsActive) // DOS is active so lets terminate
748         {
749                 // disconnect any connected AFS mounts, unless there are files open!
750                 if (!DismountAll(msg,0))
751                         return;
752                 TerminateBackground();
753                 m_nShown=0;
754                 m_cAuthWarn.ShowWindow(SW_HIDE);
755                 return;
756         }
757         CCancel cancel(m_bConnect,FALSE);               //clear m_bConnect when connection done
758         if (                                                                    // if username is present then must have password
759                 IsGetTokens() 
760                 && (m_sPassword=="")
761                 ) 
762         {
763                 HandleError("You must enter a password!");
764                 m_cPassword.SetFocus();
765                 return;
766         }
767         CProgress progress(this,7);
768         progress.Next();
769         if (!m_cAfs.Create(msg,m_sComputername,m_procInfo)) 
770         {
771                 progress.Finish();
772                 HandleError(msg);
773                 m_procInfo.hThread=0;
774                 return;
775         }
776         // CWINAFSLOADAPP->m_sMsg contains the host name used for login
777         LOG("AFS Client Console started successfully [%s].",(const char *)m_sComputername);
778         CString sDrive;
779
780         CString sKey;
781         int iMounted=-1;
782         for (int iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
783         {
784                 sKey = m_cMountlist.GetItemText(iItem,COLSHARE);
785                 if (stricmp(sKey,"all")!=0) continue;           // lets find the All first
786                 CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
787                 if (sAuto!="*")
788                         continue;
789                 sDrive=m_cMountlist.GetItemText(iItem,COLDRIVE);
790                 LOG("Connect %s %s",sDrive,sKey);
791                 if (m_cAfs.Mount(msg,sDrive,sKey))
792                 {
793                         m_cMountlist.SetCheck(iItem,TRUE);
794                         AddMenu(sDrive,sKey);
795                         iMounted=iItem;
796                 } else {
797                         CString msg2;
798                         m_cAfs.Shutdown(msg2);
799                         m_procInfo.hThread=0;
800                         msg2.Format("Connect can't continue: %s",msg);
801                         progress.Finish();
802                         HandleError(msg2);
803                         return;
804                 }
805                 break;
806         }
807         if (iMounted<0){
808                 // Scan for any other connection
809                 for (int iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
810                 {
811                         CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
812                         if (sAuto!="*")
813                                 continue;
814                         sDrive=m_cMountlist.GetItemText(iItem,COLDRIVE);
815                         LOG("Connect %s %s",sDrive,sKey);
816                         if (m_cAfs.Mount(msg,sDrive,sKey))
817                         {
818                                 m_cMountlist.SetCheck(iItem,TRUE);
819                                 AddMenu(sDrive,sKey);
820                                 iMounted=iItem;
821                         } else {
822                                 CString msg2;
823                                 m_cAfs.Shutdown(msg2);
824                                 m_procInfo.hThread=0;
825                                 msg2.Format("Connect can't continue: %s",msg);
826                                 progress.Finish();
827                                 HandleError(msg2);
828                                 return;
829                         }
830                         break;
831                 }
832         }
833         progress.Next();
834         if  (IsGetTokens())
835         {
836 #if 0
837                 if (iMounted<0)         //have we mounted at least one drive
838                 {
839                         m_cAfs.Shutdown(msg);
840                         m_procInfo.hThread=0;
841                         msg="Connect can't continue, mountable drive not defined";
842                         progress.Finish();
843                         HandleError(msg);
844                         return;
845                 }
846 #endif
847                 if (!m_cAfs.Authencate(msg,m_sUsername,m_sPassword))
848                 {
849                         CString msg2;
850                         m_cAfs.Dismount(msg2,sDrive,TRUE);
851                         m_cMountlist.SetCheck(iItem,FALSE);
852                         RemoveMenu(sDrive);
853                         m_cAfs.Shutdown(msg2);
854                         m_procInfo.hThread=0;
855                         progress.Finish();
856                         HandleError(msg);
857                         return;
858                 }
859         }
860         progress.Next();        
861         // scan through the list for any additional items to connect
862         BuildDriveList();
863         for (iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
864         {
865                 CString sKey(m_cMountlist.GetItemText(iItem,COLSHARE));
866                 if (iItem==iMounted) continue;
867                 CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
868                 if (sAuto!="*")
869                         continue;
870                 sDrive=m_cMountlist.GetItemText(iItem,COLDRIVE);
871                 LOG("Connect %s %s",sDrive,sKey);
872                 if (m_cAfs.Mount(msg,sDrive,sKey))
873                 {
874                         m_cMountlist.SetCheck(iItem,TRUE);
875                         AddMenu(sDrive,sKey);
876                 } else
877                         HandleError(msg);
878         }
879         if (!m_cAfs.StartExployer(msg,sDrive))
880                 HandleError(msg);
881         if (!m_cSaveUsername.GetCheck())
882         {
883                 m_sPassword.Empty();
884                 UpdateData(FALSE);
885         }
886 //      Sleep(5000)
887         m_bServiceIsActive=TRUE;        //DON'T allow shutdown until DOS is terminated
888         UpdateConnect();
889         if (m_bConnect)
890                 PostMessage(WM_COMMAND,IDC_CANCEL,0);
891 }
892
893 void CWinAfsLoadDlg::PostNcDestroy() 
894 {
895         // TODO: Add your specialized code here and/or call the base class
896         WSACleanup();
897         if( m_pImagelist != NULL)
898                 delete m_pImagelist;
899         if (m_pEncript)
900                 delete m_pEncript;
901     m_bmpWorld.DeleteObject();
902         CDialog::PostNcDestroy();
903 }
904
905
906 void CWinAfsLoadDlg::OnCancel() 
907 {
908         // TODO: Add your control notification handler code here
909         
910         if (m_bServiceIsActive)
911                 ShowWindow(SW_HIDE);
912         else
913         {
914                 CString msg,warn="";
915                 ProfileData(TRUE);
916                 CString user,pass;
917                 UpdateData(TRUE);
918                 RegPassword(user,pass,TRUE);
919                 if (m_cSaveUsername.GetCheck())
920                 {
921                         if (!m_pEncript->IsValid())
922                                 warn="\n\nAt this time if you choose to save your password on your harddrive, it will not be in encripted form.\n\n\
923 To encript your password you must have version 4.71 of ADVAPI32.dll (or better).\n Note: To upgrade this system file, install Internet Explorer 4.01 SP2 (or better).\n\n\
924 HINT:To intstall Internet Explorer 4.01 Service Pack 2\n\
925 1. Insert the CD that contains Service Pack 2\n\
926 2. Use the Explorer to navigate to the CDROM sub-Directory \\IE4SP2\\I386\n\
927 3. Double Click on Setup \n\
928 4. Follow the instructions for standard Installation\n\
929 5. If asked, select option to install Windows Desktop Update\n\
930 6. You will have to restart your computer when installation is completed\n\
931 7. You may remove all other components except SP2 (approximatly 90MB)";
932                         if ((user==m_sUsername) && (m_sPassword!=pass))
933                         {
934                                 msg.Format("Your password is different from what was previous saved on disk.\n Do you wish to update? %s",warn);
935                                 if (MessageBox(msg
936                                         ,"AFS - Security Warning"
937                                         , MB_ICONWARNING | MB_YESNO)==IDYES) 
938                                 RegPassword(m_sUsername,m_sPassword,FALSE);
939                         } else if (user==""){
940                                 if (m_pEncript)
941                                         msg.Format("Your user name and password (encrypted) will be saved on your disk.\n Do you wish to save?");
942                                 else
943                                         msg.Format("Your user name and password will be saved on your disk.\n Do you wish to save?%s",warn);
944                                 if (MessageBox(msg,"AFS - Security Warning"
945                                         , MB_ICONWARNING | MB_YESNO)==IDYES) 
946                                 RegPassword(m_sUsername,m_sPassword,FALSE);
947                         } else if (user!=m_sUsername){
948                                 msg.Format("Previous saved on the disk a user name (%s) and password will be overwritten by new user name (%s) and password(encrypted). Do you wish to update?%s",user,m_sUsername,warn);
949                                 if (MessageBox(msg,"AFS - Security Warning"
950                                         , MB_ICONWARNING | MB_YESNO)==IDYES) 
951                                 RegPassword(m_sUsername,m_sPassword,FALSE);
952                         }
953                 }
954                 else 
955                 {
956                         if ((pass!="")&&(user==m_sUsername))
957                         {
958                                 msg.Format("Previous user name (%s) and password will be removed from the disk\nDo you wish to clear?",user);
959                                 if (MessageBox(msg,"AFS - Security Warning",  
960                                         MB_ICONWARNING | MB_YESNO)==IDYES) 
961                                 {
962                                         user="";
963                                         RegPassword(user,user,FALSE);
964                                 }
965                         }
966                 }
967                 RegLastUser(m_sUsername,FALSE);
968                 CDialog::OnCancel();
969         }
970 }
971
972 void CWinAfsLoadDlg::OnCheckadvanced() 
973 {
974         // TODO: Add your control notification handler code here
975         if (m_cCheckAdvanceDisplay.GetCheck()) 
976         {
977                 CWait wait;
978                 if (m_bServiceIsActive)
979                         UpdateMountDisplay();
980                 SetWindowPos(&wndTop,0,0,m_OriginalRect.right-m_OriginalRect.left,m_OriginalRect.bottom-m_OriginalRect.top,SWP_NOMOVE|SWP_NOZORDER);
981         } else {
982                 SetWindowPos(&wndTop,0,0,m_OriginalRect.right-m_OriginalRect.left,m_DialogShrink,SWP_NOMOVE|SWP_NOZORDER);
983         }
984 }
985
986 BOOL  CWinAfsLoadDlg::DismountAll(CString &msg,INT mode) 
987 {// mode =0 , give user option to retry or cancel
988         //mode =1, give user option to force
989         //mode =3 , force it anyway
990         TCHAR szDrive[] = TEXT("*:");
991         TCHAR szMapping[ MAX_PATH ] = TEXT("");
992         LPTSTR pszSubmount = szMapping;
993     DWORD dwSize = MAX_PATH;
994         TCHAR pBuffer[MAX_PATH];
995         if (strlen(m_cAfs.MountName())==0)
996                 return TRUE;
997         for (TCHAR chDrive = 'D'; chDrive <= 'Z'; ++chDrive)
998         {
999                 szDrive[0]=chDrive;
1000                 if (WNetGetConnection (szDrive, szMapping, &dwSize) == NO_ERROR)
1001                 {
1002                         CHAR *p=strstr(szMapping,m_cAfs.MountName());
1003                         if (p)
1004                         {
1005                                 LOG("Disconnect %s %s",szDrive,szMapping);
1006                                 if (!m_cAfs.Dismount(msg,szDrive,(mode==3)))
1007                                 {
1008                                         CWait wait;
1009                                         switch (mode)
1010                                         {
1011                                         case 1: //Option to force
1012                                                 {
1013                                                 CForce dlg;
1014                                                 dlg.m_sMsg=msg;
1015                                                 switch (dlg.DoModal())
1016                                                 {
1017                                                 case IDOK:
1018                                                         LOG("Force Disconnect %s %s",szDrive,szMapping);
1019                                                         if (!m_cAfs.Dismount(msg,szDrive,TRUE))
1020                                                                 return FALSE;
1021                                                         break;
1022                                                 default:
1023                                                         return FALSE;
1024                                                 }
1025                                                 }
1026                                                 break;
1027                                         default:
1028                                                 {//option to return
1029                                                 CRetry dlg(TRUE);
1030                                                 dlg.m_sMsg=msg;
1031                                                 switch (dlg.DoModal())
1032                                                 {
1033                                                 case IDC_FORCE:
1034                                                         LOG("Force Disconnect %s %s",szDrive,szMapping);
1035                                                         if (!m_cAfs.Dismount(msg,szDrive,TRUE))
1036                                                                 return FALSE;
1037                                                         break;
1038                                                 case IDOK:
1039                                                         chDrive--;
1040                                                         continue;
1041
1042                                                 default:
1043                                                         return FALSE;
1044                                                 }
1045                                                 }
1046                                         }
1047                                 }
1048                                 p=strrchr(szMapping,'\\');
1049                                 if (p)
1050                                 for (int iItem=m_cMountlist.GetItemCount()-1;iItem>=0;iItem--)
1051                                 {
1052                                         m_cMountlist.GetItemText(iItem,COLSHARE,pBuffer,MAX_PATH);
1053                                         if (stricmp(p+1,pBuffer)!=0) continue;
1054                                         m_cMountlist.GetItemText(iItem,COLDRIVE,pBuffer,MAX_PATH);
1055                                         if (stricmp(szDrive,pBuffer)!=0) continue;
1056                                         m_cMountlist.SetCheck(iItem,FALSE);
1057                                         RemoveMenu(szDrive);
1058                                         break;
1059                                 }
1060                         }
1061                 }
1062         }
1063         return TRUE;
1064 }
1065
1066 BOOL CWinAfsLoadDlg::TerminateBackground(BOOL bDisplay,CString *emsg) 
1067 {// if bDisplay==FALSE then skip error message and don't update connect buttons (power down needs this option)
1068 // IF error and emsg!=NULL then return error messaage
1069         CString msg;
1070         CWait wait;
1071         if (!m_cAfs.Shutdown(msg))
1072         {
1073                 HandleError(msg,bDisplay);
1074                 m_cConnect.ModifyStyle(0,WS_DISABLED,0);
1075                 m_cConnect.Invalidate();
1076                 m_cCancel.SetWindowText("Exit");
1077                 m_cCancel.Invalidate();
1078                 m_trayIcon.SetConnectState(2);
1079                 m_bServiceIsActive=FALSE;
1080                 if (emsg) 
1081                         *emsg=msg;
1082                 return FALSE;
1083         }
1084         m_bServiceIsActive=FALSE;
1085         if (bDisplay)
1086                 UpdateConnect();
1087         LOG("AFS Client Console stopped");
1088         return TRUE;
1089 }
1090
1091 void CWinAfsLoadDlg::UpdateConnect()
1092 {
1093         if (m_bRestartAFSD)
1094         {
1095                 m_cConnect.ModifyStyle(WS_DISABLED,0);
1096                 m_cAuthenicate.ModifyStyle(WS_DISABLED,0);
1097                 return;
1098         }
1099         if (m_bServiceIsActive)
1100         {
1101                 m_cConnect.SetWindowText("DisConnect");
1102                 m_cConnect.Invalidate();
1103                 m_cCancel.SetWindowText("Cancel");
1104                 m_cCancel.Invalidate();
1105                 if (!CWINAFSLOADAPP->m_bNoID)
1106                 {       
1107                         m_cAuthenicate.ModifyStyle(WS_DISABLED,0);
1108                         if (IsGetTokens())
1109                                 m_cAuthenicate.SetWindowText("ReAuthenicate");
1110                          else   //tokens are not gotten; allow authenication
1111                                 m_cAuthenicate.SetWindowText("Authenicate");
1112                         m_cAuthenicate.Invalidate();
1113                 }
1114                 m_trayIcon.SetConnectState(0);
1115                 return;
1116         }
1117         m_cConnect.SetWindowText("Connect");
1118         m_cConnect.Invalidate();
1119         m_cCancel.SetWindowText("Exit");
1120         m_cCancel.Invalidate();
1121         m_cAuthenicate.ModifyStyle(0,WS_DISABLED);
1122         m_cAuthenicate.Invalidate();
1123         m_trayIcon.SetConnectState(1);
1124 }
1125
1126
1127 void CWinAfsLoadDlg::OnAppOpen() 
1128 {
1129         // TODO: Add your command handler code here
1130         //required so when icon menu is "Open" it will show the hidden application
1131         m_trayIcon.MaximiseFromTray(this);
1132 //      ShowWindow(SW_SHOW);
1133 }
1134
1135 // Up to 4 drives can be listed on the menu for the user to click on and start up explorer
1136 void CWinAfsLoadDlg::OnTrayButton0() 
1137 {
1138         OnSysCommand(IDM_EXPLORERAFS, 0);
1139 }
1140 void CWinAfsLoadDlg::OnTrayButton1() 
1141 {
1142         OnSysCommand(IDM_EXPLORERAFS+16, 0);
1143 }
1144 void CWinAfsLoadDlg::OnTrayButton2() 
1145 {
1146         OnSysCommand(IDM_EXPLORERAFS+32, 0);
1147 }
1148 void CWinAfsLoadDlg::OnTrayButton3() 
1149 {
1150         OnSysCommand(IDM_EXPLORERAFS+48, 0);
1151 }
1152 void CWinAfsLoadDlg::OnTrayButton4() 
1153 {
1154         OnSysCommand(IDM_EXPLORERAFS+64, 0);
1155 }
1156
1157 #define MAXDRIVESIZE (SHARENAMESIZE+5)*MAXSHARES
1158
1159 BOOL CWinAfsLoadDlg::ProfileData(BOOL put)
1160 {
1161         CString dINI;
1162         CString tINI;
1163         dINI.Format("%safsdsbmd.ini",CWINAFSLOADAPP->m_sTargetDir);
1164         tINI.Format("%safsdsbmt.ini",CWINAFSLOADAPP->m_sTargetDir);
1165         BOOL ret=TRUE;
1166         if (put)
1167         {
1168 #define BLOCKSIZE MAX_PATH+SHARENAMESIZE+3
1169                 int scur=BLOCKSIZE;
1170                 char *sblock=(char *)malloc(scur);
1171                 int sused=0;
1172                 char *sptr=sblock;
1173                 int dcur=128;
1174                 char *dblock=(char *)malloc(dcur);
1175                 int dused=0;
1176                 char *dptr=dblock;
1177                 for (int iItem=m_cMountlist.GetItemCount()-1;iItem>=0;iItem--)
1178                 {
1179                         CString sKey(m_cMountlist.GetItemText(iItem,COLSHARE));
1180                         CString sPath(m_cMountlist.GetItemText(iItem,COLPATH));
1181                         CString sDrive(m_cMountlist.GetItemText(iItem,COLDRIVE));
1182                         CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
1183                         if (!sKey.IsEmpty() && !sPath.IsEmpty())
1184                         {// going a lot of trouble to handle any size buffer with out puting a limit on it
1185                                 int len=sKey.GetLength()+sDrive.GetLength()+sAuto.GetLength()+2;
1186                                 if (dused+len>=dcur)
1187                                         dblock=(char *)realloc(dblock,(dcur+=128));
1188                                 dptr=dblock+dused;
1189                                 wsprintf(dptr,"%s=%s%s",sKey,sAuto,sDrive);
1190                                 dused+=len;
1191                                 len=sKey.GetLength()+sPath.GetLength()+2;
1192                                 if (sused+len>=scur)
1193                                         sblock=(char *)realloc(sblock,(scur+=BLOCKSIZE));
1194                                 sptr=sblock+sused;
1195                                 wsprintf(sptr,"%s=%s",sKey,sPath);
1196                                 sused+=len;
1197                         }
1198                 }
1199                 *(sblock+sused)=0;      //put extra null at the end
1200                 *(dblock+dused)=0;
1201                 WritePrivateProfileSection("AFS Submounts",sblock,tINI);
1202                 WritePrivateProfileSection("AFS Drivemounts",dblock,dINI);
1203                 delete dblock;
1204                 delete sblock;
1205         } else {        //get
1206                 char sShare[SHARENAMESIZE+1];
1207                 CHAR sPath[MAX_PATH+1];
1208                 CHAR sDriveMount[MAXDRIVESIZE+2];
1209                 CHAR sDrive[DRIVESIZE+1];
1210                 CHAR sAuto[AUTOSIZE+1];
1211                 strcpy(sAuto," ");
1212                 CString path;
1213                 // lets scan for all and home first, we want to place them first
1214                 //mode: 0=look for all, 1=look for home, 2=finish the rest              
1215                 for(int mode=0;mode<3;mode++)
1216                 {
1217                         int drivelen=GetPrivateProfileString("AFS Drivemounts", NULL, "", sDriveMount, MAXDRIVESIZE,dINI);
1218                         if (drivelen>=MAXDRIVESIZE)
1219                         {
1220                                 CString msg;
1221                                 msg.Format("Profile String Error - Too many entries (%d)",MAXSHARES);
1222                                 HandleError(msg,TRUE);
1223                                 return FALSE;
1224                         }
1225                         PCHAR pDrivekey=sDriveMount;
1226                         while (drivelen>1)
1227                         {
1228                                 if ((strlen(pDrivekey)==0) || (strlen(pDrivekey)>SHARENAMESIZE))
1229                                 {
1230                                         HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
1231                                         ret=FALSE;
1232                                         break;
1233                                 }
1234                                 strcpy(sShare,pDrivekey);
1235                                 if (GetPrivateProfileString("AFS Drivemounts", sShare, "", sDrive, DRIVESIZE,dINI)==0)
1236                                 {
1237                                         HandleError("Profile String Error - AFS Drivemounts - Drive Name",FALSE);
1238                                         ret=FALSE;
1239                                         break;
1240                                 }
1241                                 if (sDrive[0]=='*')     //test for leading *
1242                                 {
1243                                         strcpy(sAuto,"*");
1244                                         strrev(sDrive);
1245                                         sDrive[strlen(sDrive)-1]=0;
1246                                 } else
1247                                         strcpy(sAuto," ");
1248                                 sDrive[1]=0;    //force to be single character
1249                                 strupr(sDrive);
1250                                 if (strspn(sDrive,"DEFGHIJKLMNOPQRSTUVWXYZ")==0)
1251                                 {
1252                                         HandleError("Profile String Error - AFS Drivemounts - Drive Letter",FALSE);
1253                                         ret=FALSE;
1254                                         break;
1255                                 }
1256                                 strcat(sDrive,":");
1257                                 switch (mode)
1258                                 {
1259                                 case 0:
1260                                         if (stricmp("all",sShare)!=0) break;
1261                                         if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
1262                                         {
1263                                                 strcpy(sPath,"/");      //none defined
1264                                         }
1265                                         AddToList(sDrive,sPath,sShare,sAuto);
1266                                         drivelen=0;
1267                                         continue;
1268
1269                                 case 1:
1270                                         if (stricmp("home",sShare)!=0) break;
1271                                         if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
1272                                         {
1273                                                 HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
1274                                                 ret=FALSE;
1275                                                 break;
1276                                         }
1277                                         AddToList(sDrive,sPath,sShare,sAuto);
1278                                         drivelen=0;
1279                                         continue;
1280                                 default:
1281                                         if ((stricmp("all",sShare)==0)|| (stricmp("home",sShare)==0)) break;
1282                                         if (GetPrivateProfileString("AFS Submounts", sShare, "", sPath, MAX_PATH,tINI)==0)
1283                                         {
1284                                                 HandleError("Profile String Error - AFS Drivemounts - Share Name",FALSE);
1285                                                 ret=FALSE;
1286                                                 break;
1287                                         }
1288                                         AddToList(sDrive,sPath,sShare,sAuto);
1289                                         break;
1290                                 }
1291                                 drivelen-=(strlen(pDrivekey)+1);
1292                                 pDrivekey+=(strlen(pDrivekey)+1);
1293                         }
1294                 }
1295
1296         }
1297         return ret;
1298 }
1299
1300 void CWinAfsLoadDlg::OnChange() 
1301 {
1302         // TODO: Add your control notification handler code here
1303
1304         POSITION pos = m_cMountlist.GetFirstSelectedItemPosition();
1305         if (pos == NULL) return;
1306         int nItem = m_cMountlist.GetNextSelectedItem(pos);
1307         UINT state=m_cMountlist.GetCheck(nItem);
1308         if (state)
1309         {
1310                 MessageBox("You cannot change Item from the list while connected!","AFS - Warning",MB_OK|MB_ICONWARNING);
1311                 return;
1312         }
1313         CChange dlg(TRUE,this);
1314         dlg.m_sDrive=m_cMountlist.GetItemText(nItem,COLDRIVE);
1315         dlg.m_sPath=m_cMountlist.GetItemText(nItem,COLPATH);
1316         dlg.m_sDescription=m_cMountlist.GetItemText(nItem,COLSHARE);
1317         dlg.m_bAuto=(strcmp(m_cMountlist.GetItemText(nItem,COLAUTO),"*")==0);
1318         if (dlg.DoModal()==IDCANCEL) return;
1319         m_cMountlist.SetItemText(nItem,COLDRIVE,dlg.m_sDrive);
1320         m_cMountlist.SetItemText(nItem,COLPATH,dlg.m_sPath);
1321         m_cMountlist.SetItemText(nItem,COLSHARE,dlg.m_sDescription);
1322         m_cMountlist.SetItemText(nItem,COLAUTO,(dlg.m_bAuto)?"*":" ");
1323         UpdateData(FALSE);
1324         ProfileData(TRUE);
1325 }
1326
1327 VOID CWinAfsLoadDlg::AddToList(const char *sDrive,const char *sPath,const char *sShare,const char *sAuto)
1328 {
1329         LV_ITEM         lvitem;
1330         memset(&lvitem,0,sizeof(lvitem));
1331         int iSubItem,iActualItem;
1332         int iItem;
1333         if (stricmp(sShare,"home")==0) 
1334                 iItem=1;
1335         else if (stricmp(sShare,"all")==0)
1336                 iItem=0;
1337         else {
1338                 iItem=m_cMountlist.GetItemCount();
1339                 if (iItem<1) iItem=2;
1340         }
1341
1342         for (iSubItem = 0; iSubItem < NUMCOL; iSubItem++)
1343         {
1344                 lvitem.mask = LVIF_TEXT ;//| (iSubItem == 0? LVIF_IMAGE : 0);
1345                 lvitem.iItem = (iSubItem == 0)? iItem : iActualItem;
1346                 lvitem.iSubItem = iSubItem;
1347                 lvitem.iImage = 0;
1348                 switch(iSubItem)
1349                 {
1350                 case COLDRIVE:
1351                         lvitem.pszText=(char *)sDrive;
1352                         break;
1353                 case COLPATH:
1354                         lvitem.pszText=(char *)sPath;
1355                         break;
1356                 case COLSHARE:
1357                         lvitem.pszText=(char *)sShare;
1358                         break;
1359                 case COLAUTO:
1360                         lvitem.pszText=(char *)sAuto;
1361                         break;          
1362                 default:
1363                         break;
1364                 }
1365                 if (iSubItem == 0)
1366                         iActualItem = m_cMountlist.InsertItem(&lvitem); // insert new item
1367                 else
1368                         m_cMountlist.SetItem(&lvitem); // modify existing item (the sub-item text)
1369         }
1370
1371 }
1372
1373 void CWinAfsLoadDlg::OnAdd() 
1374 {
1375         // TODO: Add your control notification handler code here
1376         CChange dlg(FALSE,this);
1377         if (dlg.DoModal()==IDCANCEL) return;
1378         //return m_sDescription, m_sPath, m_sDrive
1379         AddToList(dlg.m_sDrive,dlg.m_sPath,dlg.m_sDescription,(dlg.m_bAuto)?"*":" ");
1380         UpdateData(FALSE);
1381         ProfileData(TRUE);                                                                      //update INI list if changed
1382 }
1383
1384
1385 void CWinAfsLoadDlg::OnRemove() 
1386 {
1387         // TODO: Add your control notification handler code here
1388         
1389         POSITION pos = m_cMountlist.GetFirstSelectedItemPosition();
1390         if (pos == NULL) return;
1391         while (pos)
1392         {
1393                 int nItem = m_cMountlist.GetNextSelectedItem(pos);
1394                 UINT state=m_cMountlist.GetCheck(nItem);
1395                 if (state)
1396                 {
1397                         HandleError("You cannot remove Item from the list while connected!");
1398                         continue;
1399                 }
1400 #if 0
1401                 if (stricmp(m_cMountlist.GetItemText(nItem,COLSHARE),"all")==0)
1402                 {
1403                         HandleError("You cannot remove 'All' Item from the list!");
1404                         continue;
1405                 }
1406 #endif
1407                 m_cMountlist.DeleteItem(nItem);
1408         }
1409         ProfileData(TRUE);
1410 }
1411
1412 // FOLLOWING ROUITNE IS required so OnItemchangedDrivemountlist can tell the difference
1413 // between a user changing an item to mount/dismount or the program is just updating the display
1414 // unfortunately any changes go thourgh OnItemchangedDrivemountlist
1415 void CWinAfsLoadDlg::OnClickDrivemountlist(NMHDR* pNMHDR, LRESULT* pResult) 
1416 {
1417         // TODO: Add your control notification handler code here
1418         
1419         *pResult = 0;
1420         NM_LISTVIEW* pListview = (NM_LISTVIEW*)pNMHDR;
1421         CString msg;
1422         *pResult=0;
1423         m_iActiveItem=pListview->iItem; //this is the only place where items changed are done by user click
1424 }
1425
1426 void CWinAfsLoadDlg::UpdateMountDisplay() 
1427 {
1428         TCHAR szDrive[] = TEXT("*:");
1429         TCHAR szMapping[ MAX_PATH ] = TEXT("");
1430         LPTSTR pszSubmount = szMapping;
1431     DWORD dwSize = MAX_PATH;
1432         TCHAR pDrive[DRIVESIZE+1];
1433         TCHAR pShare[SHARENAMESIZE+1];
1434         ASSERT(strlen(m_cAfs.MountName())!=0);
1435         BOOL update=FALSE;
1436         for (int iItem=m_cMountlist.GetItemCount()-1;iItem>=0;iItem--)
1437         {
1438                 m_cMountlist.GetItemText(iItem,COLDRIVE,pDrive,DRIVESIZE);
1439                 m_cMountlist.GetItemText(iItem,COLSHARE,pShare,SHARENAMESIZE);
1440                 if ((WNetGetConnection(pDrive, szMapping, &dwSize) == NO_ERROR) 
1441                         && (strstr(szMapping,m_cAfs.MountName())!=NULL))
1442                 {
1443                         if ((stricmp((strrchr(szMapping,'\\')+1),pShare)==0) 
1444                                 && (!m_cMountlist.GetCheck(iItem)))
1445                         {
1446                                 m_cMountlist.SetCheck(iItem,TRUE);
1447                                 AddMenu(m_cMountlist.GetItemText(iItem,COLDRIVE),m_cMountlist.GetItemText(iItem,COLSHARE));
1448                                 update=TRUE;
1449                         }
1450                 }
1451                 else {
1452                         if (m_cMountlist.GetCheck(iItem))
1453                         {
1454                                 m_cMountlist.SetCheck(iItem,FALSE);
1455                                 RemoveMenu(m_cMountlist.GetItemText(iItem,COLDRIVE));
1456                                 update=TRUE;
1457                         }
1458                 }
1459         }
1460         if (update)
1461                 m_cMountlist.Invalidate();
1462 }
1463
1464 void CWinAfsLoadDlg::OnItemchangedDrivemountlist(NMHDR* pNMHDR, LRESULT* pResult) 
1465 {
1466         NM_LISTVIEW* pListview = (NM_LISTVIEW*)pNMHDR;
1467         CString msg;
1468         *pResult=0;
1469         if ((pListview->uNewState & (ITEMCHECKED | ITEMNOTCHECKED))!=(pListview->uOldState & 0x3000))
1470         {
1471                 if (m_iActiveItem<0) return;    //no processing needed if not initiated by a mouse click
1472                 m_iActiveItem=-1;
1473                 switch (pListview->uNewState & (ITEMCHECKED | ITEMNOTCHECKED))
1474                 {
1475                 case ITEMCHECKED:       //mount a drive
1476                         if (!m_bServiceIsActive)
1477                         {// can't allow mounting if connection not active
1478                                 HandleError("You must connect first");
1479                                 m_cMountlist.SetCheck(pListview->iItem,FALSE);
1480                                 return;
1481                         }
1482                         LOG("Connect %s %s",m_cMountlist.GetItemText(pListview->iItem,COLDRIVE),m_cMountlist.GetItemText(pListview->iItem,COLSHARE));
1483                         {
1484                         CProgress progress(this,4);
1485                         if (!m_cAfs.Mount(msg
1486                                 ,m_cMountlist.GetItemText(pListview->iItem,COLDRIVE)
1487                                 ,m_cMountlist.GetItemText(pListview->iItem,COLSHARE)))
1488                         {
1489                                 m_cMountlist.SetCheck(pListview->iItem,FALSE);
1490                                 UpdateData(FALSE);
1491                                 HandleError(msg);
1492                                 return;
1493                         }
1494                         AddMenu(m_cMountlist.GetItemText(pListview->iItem,COLDRIVE),m_cMountlist.GetItemText(pListview->iItem,COLSHARE));
1495                         }
1496                         break;
1497                 case ITEMNOTCHECKED:    //dismount a drive
1498                         {
1499                         BOOL force=FALSE;
1500                         LOG("Disconnect %s",m_cMountlist.GetItemText(pListview->iItem,COLDRIVE));
1501                         do
1502                         {
1503                                 if (!m_cAfs.Dismount(msg,m_cMountlist.GetItemText(pListview->iItem,COLDRIVE),force))
1504                                 {// there was an error, allow the user to force closing the drive anyway
1505                                         CRetry dlg(TRUE);
1506                                         dlg.m_sMsg=msg;
1507                                         switch (dlg.DoModal())
1508                                         {
1509                                         case IDOK:
1510                                                 continue;
1511                                         case IDC_FORCE:
1512                                                 force=TRUE;
1513                                                 continue;
1514                                         default:
1515                                                 m_cMountlist.SetCheck(pListview->iItem,TRUE);
1516                                                 return;
1517                                         }
1518                                 }
1519                                 RemoveMenu(m_cMountlist.GetItemText(pListview->iItem,COLDRIVE));
1520                                 break;
1521                         } while (TRUE);
1522                         }
1523                         break;
1524                 default:
1525                         break;
1526                 }
1527                 return;
1528         }
1529         POSITION pos = m_cMountlist.GetFirstSelectedItemPosition();
1530         if (pos == NULL)
1531         {
1532                 m_cRemove.ModifyStyle(0,WS_DISABLED,0);
1533                 m_cChange.ModifyStyle(0,WS_DISABLED,0);
1534         } else {
1535                 m_cRemove.ModifyStyle(WS_DISABLED,0,0);
1536                 m_cMountlist.GetNextSelectedItem(pos);
1537                 if (pos==NULL)
1538                         m_cChange.ModifyStyle(WS_DISABLED,0,0);
1539                 else
1540                         m_cChange.ModifyStyle(0,WS_DISABLED,0);
1541         }
1542         m_cChange.Invalidate(TRUE);
1543         m_cRemove.Invalidate(TRUE);
1544         m_iActiveItem=-1;
1545 }
1546
1547 void CWinAfsLoadDlg::BuildDriveList(BOOL newone)
1548 {//if force then build a newone
1549         
1550         DWORD mapDrive=GetLogicalDrives();
1551         TCHAR szDrive[] = TEXT("*:  ");
1552         int iItem;
1553         if (newone)
1554         {
1555                 m_Drivelist.RemoveAll();
1556                 TCHAR szMapping[ MAX_PATH ] = TEXT("");
1557                 LPTSTR pszSubmount = szMapping;
1558             DWORD dwSize = MAX_PATH;
1559                 TCHAR stDrive[]=TEXT("*:");
1560                 for (iItem = 2;iItem <= 25; ++iItem)
1561                 {
1562                         szDrive[0]=stDrive[0]=iItem+'A';
1563                         if (((mapDrive & 1<<iItem)==0)  // if drive is not in use or it is a network assigned drive
1564                                                                                         //              then place it on the available drive list
1565                                 || (WNetGetConnection (stDrive, szMapping, &dwSize) == NO_ERROR))
1566                         {
1567                                 m_Drivelist.AddTail(CString(szDrive));
1568                         }
1569                 }
1570                 return;
1571         }
1572         //update drive list seting * for thoes drives already in use
1573         for (iItem=m_Drivelist.GetCount()-1;iItem>=0;iItem--)
1574         {
1575                 strcpy(szDrive,m_Drivelist.GetAt(m_Drivelist.FindIndex(iItem)));
1576                 szDrive[3]= ((1<<(szDrive[0]-'A')) & mapDrive)?'*' :' ';
1577                 m_Drivelist.SetAt(m_Drivelist.FindIndex(iItem),CString(szDrive));
1578         }
1579 }
1580
1581 void CWinAfsLoadDlg::ExtractDrive(CString &zdrive,const char *request)
1582 {// extract the cloest drive to the requested letter
1583         POSITION pos = m_Drivelist.Find(CString(request));
1584         if (pos)
1585         {
1586                 zdrive=m_Drivelist.GetAt(pos);
1587                 m_Drivelist.RemoveAt(pos);
1588                 return;
1589         }
1590         int count=m_Drivelist.GetCount()-4;
1591         if (count<0) count=0;
1592         pos=m_Drivelist.FindIndex(count);
1593         zdrive=m_Drivelist.GetAt(pos);
1594         m_Drivelist.RemoveAt(pos);
1595 }
1596
1597 HCURSOR CWinAfsLoadDlg::OnQueryDragIcon()
1598 {
1599         return (HCURSOR) m_hIcon;
1600 }
1601
1602
1603 // Main menu close statement
1604 BOOL CWinAfsLoadDlg::OnQueryEndSession( )
1605 {
1606         ShowWindow(SW_SHOW);
1607         CString msg;
1608         if (!DismountAll(msg,1))// disconnect any connected AFS mounts, unless there are files open!
1609                 return FALSE;
1610         TerminateBackground();
1611         if (m_nDirTimer)                                //Destroy Window is not being called 
1612                 KillTimer(m_nDirTimer);
1613         if (m_nAutTimer)
1614                 KillTimer(m_nAutTimer);
1615         m_nAutTimer=m_nDirTimer=0;
1616         return !m_bServiceIsActive;
1617 }
1618
1619 void CWinAfsLoadDlg::OnTimer(UINT nIDEvent) 
1620 {
1621         // TODO: Add your message handler code here and/or call default
1622         char pBuffer[64];
1623         int len;
1624         char *p=NULL;
1625         CString msg;
1626         switch (nIDEvent)
1627         {
1628         case WM_DIRTIMER:
1629                 switch (m_seqIndex)
1630                 {
1631                 case 22:
1632                 case 25://1.0
1633                         if ((m_seqCount+=TIMEINTERVAL)<1000) 
1634                                 break;
1635                 case 23: //0.75
1636                         if ((m_seqCount+=TIMEINTERVAL)<500)
1637                                 break;
1638                 case 20:
1639                 case 21:
1640                 case 24:
1641                 case 26://0.5
1642                         if ((m_seqCount+=TIMEINTERVAL)<500)
1643                                 break;
1644                 default://0.2
1645                         m_seqCount=0;
1646                         if (++m_seqIndex>MAXWORLDINDEX) m_seqIndex=0;
1647                         m_bmpWorld.UpdateMask(this,m_WorldRect);//build new mask and force repaint of world area 
1648                         break;
1649                 }
1650                 if ((!m_bServiceIsActive) || (m_bRestartAFSD)) break;
1651                 if ((m_dirCount+=TIMEINTERVAL)<CHECKDIR) break;
1652                 m_dirCount=0;
1653                 len=::GetWindowText(m_cAfs.GetLoadWindowHandle(),pBuffer,64);
1654                 if ((len==0) || ((p=strstr(pBuffer,"Finish"))!=NULL))
1655                 {// if p!=NULL then application is finished but not totally shutdown
1656                         if (p)
1657                         {
1658                                 ::SendMessage(m_cAfs.GetLoadWindowHandle(),WM_CLOSE,0,0);
1659                                 LOG("WM_CLOSE4");
1660                         }
1661                         CString msg;
1662                         DismountAll(msg,3);             //unfortunately all drive references are invalid also!
1663                         m_bServiceIsActive=FALSE;
1664                         UpdateConnect();
1665                         break;
1666                 }
1667                 if (!m_cCheckAdvanceDisplay.GetCheck()) break;
1668                 if ((WS_VISIBLE & GetStyle()) )
1669                         UpdateMountDisplay();
1670                 break;
1671         case WM_AUTTIMER:
1672                 if ((!m_bServiceIsActive) || m_bRestartAFSD) break;
1673                 switch (m_cAfs.TestTokenTime(msg))
1674                 {
1675                 case 0:
1676                         if (m_nShown==0) break;
1677                         m_cAuthWarn.ShowWindow(SW_HIDE);
1678                         m_cAuthWarn.Invalidate(TRUE);
1679                         m_nShown=0;
1680                         break;
1681                 case -1:
1682                         if (m_nShown==-1) break;
1683                         HandleError(msg);
1684                         ShowWindow(SW_SHOWDEFAULT);
1685                         m_nShown=-1;
1686                         break;
1687                 case 1:
1688                         if (m_nShown==1) break;
1689                         m_bkBrush.DeleteObject();
1690                         m_bkBrush.CreateSolidBrush(RGB(255,255,0));
1691                         m_cAuthWarn.SetWindowText(msg);
1692                         m_cAuthWarn.Invalidate(TRUE);
1693                         m_cAuthWarn.ShowWindow(SW_SHOW);
1694                         ShowWindow(SW_SHOWDEFAULT);
1695                         m_nShown=1;
1696                         LOG(msg);
1697                         break;
1698                 case 2:
1699                         if (m_nShown==2) break;
1700                         m_bkBrush.DeleteObject();
1701                         m_bkBrush.CreateSolidBrush(RGB(255,0,0));
1702                         m_cAuthWarn.ShowWindow(SW_SHOW);
1703                         m_cAuthWarn.SetWindowText(msg);
1704                         m_cAuthWarn.Invalidate(TRUE);
1705                         ShowWindow(SW_SHOWDEFAULT);
1706                         LOG(msg);
1707                         m_nShown=2;
1708                         break;
1709                 default:
1710                         break;
1711                 }
1712
1713                 break;
1714         default:
1715                 break;
1716         }
1717         CDialog::OnTimer(nIDEvent);
1718 }
1719
1720 void CWinAfsLoadDlg::OnAuthenicate() 
1721 {
1722         // TODO: Add your control notification handler code here
1723         CString msg;
1724         CWait wait;
1725         UpdateData(TRUE);
1726         m_nShown=0;
1727         m_cAuthWarn.ShowWindow(SW_HIDE);
1728         LOG("Re-Authenication");
1729         if (m_sUsername=="")
1730         {
1731                 HandleError("You must enter a user name!");
1732                 m_cUsername.SetFocus();
1733                 return;
1734         }
1735         if (m_sPassword=="")
1736         {
1737                 HandleError("You must enter a password!");
1738                 m_cPassword.SetFocus();
1739                 return;
1740         }
1741         if (!m_cAfs.Authencate(msg,m_sUsername,m_sPassword))
1742         {
1743                 HandleError(msg);
1744                 return;
1745         }
1746         m_cAuthenicate.SetWindowText("ReAuthenicate");
1747         m_cAuthenicate.Invalidate();
1748         if (!m_cSaveUsername.GetCheck())
1749         {
1750                 m_sPassword.Empty();
1751                 UpdateData(FALSE);
1752         }
1753
1754 }
1755
1756
1757 void CWinAfsLoadDlg::OnDestroy() 
1758 {
1759
1760 //    ASSERT( m_hBmpOld );
1761 //    VERIFY( m_dcMem.SelectObject( CBitmap::FromHandle(m_hBmpOld) ) );
1762     // Need to DeleteObject() the bitmap that was loaded
1763     m_bmpWorld.DeleteObject();
1764
1765     // m_dcMem destructor will handle rest of cleanup    
1766
1767         if (m_nDirTimer)                                //it is better to kill the timer here than PostNcDestroy
1768                 KillTimer(m_nDirTimer);
1769         if (m_nAutTimer)
1770                 KillTimer(m_nAutTimer);
1771         m_nAutTimer=m_nDirTimer=0;
1772         CDialog::OnDestroy();
1773         
1774         // TODO: Add your message handler code here
1775         
1776 }
1777
1778 // Here is how we change the Background color for the yellow warning
1779 HBRUSH CWinAfsLoadDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
1780 {
1781         HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
1782         
1783         // TODO: Change any attributes of the DC here
1784         if (pWnd->GetDlgCtrlID() == IDC_AUTHWARN)
1785         {
1786                 pDC->SetBkMode(TRANSPARENT);    // we have to make text background transparent 
1787                 return (HBRUSH)m_bkBrush;               // Return a different brush (YELLOW)
1788         }
1789         
1790         return hbr;
1791 }
1792
1793 void CWinAfsLoadDlg::OnShow() 
1794 {
1795         // TODO: Add your command handler code here
1796         CMenu* pSysMenu = GetSystemMenu(FALSE);
1797
1798         if (pSysMenu != NULL)
1799         {
1800                 if (0xFFFFFFFF!=pSysMenu->GetMenuState(IDM_CAPTUREWINDOW, MF_BYCOMMAND)) 
1801                         return;
1802                 CSettings dlg(this);
1803                 dlg.DoModal();
1804                 OnShowAddMenus();
1805         }
1806 }
1807
1808 void CWinAfsLoadDlg::OnShowAddMenus() 
1809 {
1810         CMenu* pSysMenu = GetSystemMenu(FALSE);
1811         if (pSysMenu == NULL) return;
1812         CString strMenu;
1813         pSysMenu->AppendMenu(MF_SEPARATOR);
1814         strMenu.LoadString(IDM_CAPTUREWINDOW);
1815         pSysMenu->AppendMenu(MF_STRING, IDM_CAPTUREWINDOW, strMenu);
1816         strMenu.LoadString(IDM_CAPTUREFILE);
1817         pSysMenu->AppendMenu(MF_STRING, IDM_CAPTUREFILE, strMenu);
1818         strMenu.LoadString(IDM_VIEWAFS);
1819         pSysMenu->AppendMenu(MF_STRING, IDM_VIEWAFS, strMenu);
1820 }
1821
1822 // Signaled when AFSD sends a socket message
1823 LRESULT CWinAfsLoadDlg::OnPowerBroadcast(WPARAM wParam, LPARAM lParam)
1824 {
1825         CString msg;
1826         CString sDrive;
1827         CString sKey;
1828         BOOL  result=TRUE;
1829         switch(wParam)
1830         {
1831         case PBT_APMSUSPEND:
1832                 LOG("PBT_APMSUSPEND");
1833                 break;
1834         case PBT_APMQUERYSUSPEND:
1835                 // if lParam & 1 ==1 then you can prompt user for info
1836                 LOG("PBT_APMQUERYSUSPEND");
1837 #if WIN95TEST
1838                 if (IsWin95())
1839                 {// Windows 95
1840                         CString *emsg=new CString;
1841                         emsg->Format("Warning: Attempt to Suspend was Denied\nPower Suspend on Windows 95 is not compatable with Ufiler. \nYou may be required to reboot before using Ufilier again!");
1842                         PostMessage(WM_ERRORMSG,AFS_EXITCODE_GENERAL_FAILURE,(LPARAM)emsg);
1843
1844                         return BROADCAST_QUERY_DENY;    //deny suspension
1845                 }
1846 #endif
1847                 if (m_bRestartAFSD)
1848                         break;
1849                 if (m_bServiceIsActive)
1850                 {
1851
1852                         if (
1853                                 (!IsWin95())    // WIN95 will suspend anyway
1854                                 && (!m_cAfs.CheckNet(msg)) 
1855                                 
1856                                 )
1857
1858                         {
1859                                 if (lParam &1) 
1860                                 {
1861                                         CString *emsg=new CString;
1862                                         emsg->Format("Attempt to Suspend Denied\n%s",msg);
1863                                         PostMessage(WM_ERRORMSG,AFS_EXITCODE_GENERAL_FAILURE,(LPARAM)emsg);
1864                                 }
1865                                 LOG("AFS Client Console stopped, powerdown denied.");
1866                                 return BROADCAST_QUERY_DENY;    //files open suspend denied
1867                         }
1868                         CString *emsg=new CString;
1869                         // Allow power suspension even though termination incomplete (no files open anyway)
1870                         if (!TerminateBackground(FALSE,emsg))
1871                         {
1872                                 if (lParam &1) 
1873                                 {
1874                                         m_cConnect.ModifyStyle(0,WS_DISABLED,0);
1875                                         m_cConnect.Invalidate();
1876                                         m_cCancel.SetWindowText("Exit");
1877                                         m_cCancel.Invalidate();
1878                                         m_trayIcon.SetConnectState(2);
1879                                         m_bServiceIsActive=FALSE;
1880                                         PostMessage(WM_ERRORMSG,AFS_EXITCODE_GENERAL_FAILURE,(LPARAM)emsg);
1881                                         result=FALSE;
1882                                 }
1883                         } else
1884                                 delete emsg;
1885                         m_bServiceIsActive=FALSE;
1886                 }
1887                 // terminate socket connection (even if terminatebackground failed
1888                 REQUESTUISUSPENDEVENT(ONPARMDISCONNECT);
1889                 {
1890                 WPARAM wp;
1891                 CString msg;
1892                 CWINAFSLOADAPP->WaitForEvent(SOCKETIO+2000,&wp,&msg);   //wait 2 second longer than any socket IO
1893                 switch (wp)
1894                 {
1895                 case AFS_EXITCODE_NORMAL:
1896                         break;
1897                 default:
1898                         // have to post message to myself so I can return Querry deny immediately
1899                         {
1900                         CString *emsg=new CString(msg);
1901                         m_cConnect.ModifyStyle(0,WS_DISABLED,0);
1902                         m_cConnect.Invalidate();
1903                         m_cCancel.SetWindowText("Exit");
1904                         m_cCancel.Invalidate();
1905                         PostMessage(WM_ERRORMSG,AFS_EXITCODE_GENERAL_FAILURE,(LPARAM)emsg);
1906                         m_trayIcon.SetConnectState(2);
1907                         result=FALSE;
1908                         }
1909                 }
1910                 }
1911                 m_bRestartAFSD=result;
1912                 break;
1913         case PBT_APMRESUMESUSPEND:
1914                 LOG("PBT_APMRESUMESUSPEND");
1915                 REQUESTUIPOSTEVENT(WM_UICONNECT,WM_CONNECTRETURN,0);
1916                 break;
1917         case PBT_APMRESUMECRITICAL:
1918                 LOG("PBT_APMRESUMECRITICAL");
1919                 REQUESTUIPOSTEVENT(WM_UICONNECT,WM_CONNECTRETURN,0);
1920                 break;
1921         default:
1922                 break;
1923         }
1924         UpdateConnect();
1925         return true;
1926 }
1927
1928
1929 // lParam will contain CString, they must be deleted when done!
1930 LRESULT CWinAfsLoadDlg::OnErrorMessage(WPARAM wParam, LPARAM lParam)
1931 {
1932         CString *msg=(CString *)lParam;
1933         MessageBox(*msg,"AFS Control Panel Warning");
1934         delete msg;
1935         return TRUE;
1936 }
1937
1938 // actual message comes from AfsLoad (CWinApp)
1939 LRESULT CWinAfsLoadDlg::OnAfsEvent(WPARAM wParam, LPARAM lParam)
1940 {
1941         ASSERT(lParam);
1942         CString * msg=(CString *)lParam;
1943         CString emsg;
1944         emsg.Format("OnAfsEvent %x [%s]",wParam,(const char *)(*msg));
1945         LOG((const char *)emsg);
1946         switch (wParam)
1947         {
1948                 case AFS_EXITCODE_NORMAL:
1949                         break;
1950                 default:
1951                         MessageBox((const char*)(*msg),"AFS Client Console Failure");
1952                         break;
1953         }
1954         if (msg)
1955                 delete msg;
1956         return 0;
1957 }
1958
1959
1960 void CWinAfsLoadDlg::ErrorDisplayState()
1961 {
1962         m_cConnect.ModifyStyle(0,WS_DISABLED,0);
1963         m_cConnect.Invalidate();
1964         m_cCancel.SetWindowText("Exit");
1965         m_cCancel.Invalidate();
1966         m_cAuthenicate.ModifyStyle(0,WS_DISABLED,0);
1967         m_cAuthenicate.Invalidate();
1968         UpdateConnect();
1969 }
1970
1971 static CProgress *m_progress=NULL;
1972
1973 // all calls must have set lParam null or contain a message to release
1974 // actual message comes from AfsLoad (CWinApp)
1975 LRESULT CWinAfsLoadDlg::OnNotifyReturn(WPARAM wParam, LPARAM lParam)
1976 {// fields messages from a NotifyFromUI, e.g. ONCONNECT ONPING
1977 // lParam contains the message that must be released
1978         CString msg;
1979         int iItem;
1980         CString sDrive;
1981         CString sKey;
1982         switch(wParam)
1983         {
1984         case WM_CONNECTRETURN:
1985                 if (lParam)
1986                 {// we had a failure
1987                         HandleError(*(CString *)lParam);
1988                         delete (CString *)lParam;
1989                         m_bRestartAFSD=FALSE;
1990                         ErrorDisplayState();
1991                         break;
1992                 }
1993                 if (!m_bRestartAFSD)
1994                         break;
1995                 m_progress = new CProgress(this,7);
1996                 if (m_progress)
1997                 {
1998                         m_progress->SetTitle("Power Restart","Enable AFS Client Console","Authenication");
1999                         m_progress->Next();
2000                 }
2001                 if (IsWin95())
2002                 {
2003                         LOG("Wait %d seconds to Bring up AFSD",m_PowerResumeDelay);
2004                         return TRUE;            // do a return instead of break so Delete won't be called
2005                 }
2006         case WM_RESUMEDELAY:
2007         case WM_PINGRETURN:     //we will return here after CONNECT(ONPING) finds the server connected
2008                 LOG("Done with delay, load AFSD");
2009                 if (m_progress)
2010                         m_progress->Next();
2011                 {
2012                 m_bRestartAFSD=FALSE;
2013                 if (lParam)
2014                 {// we had a failure
2015                         HandleError(*(CString *)lParam);
2016                         delete (CString *)lParam;
2017                         ErrorDisplayState();
2018                         break;
2019                 }
2020                 if (m_progress)
2021                         m_progress->Next();
2022                 if (!m_cAfs.Create(msg,m_sComputername,m_procInfo)) 
2023                 {
2024                         HandleError(msg);
2025                         m_procInfo.hThread=0;
2026                         ErrorDisplayState();
2027                         break;
2028                 } else
2029                         LOG("AFS Client Powerup started successfully.");
2030                 for (iItem=0;iItem<m_cMountlist.GetItemCount();iItem++)
2031                 {
2032                                 sKey = m_cMountlist.GetItemText(iItem,COLSHARE);
2033                         if (stricmp(sKey,"all")!=0) continue;
2034                         CString sAuto(m_cMountlist.GetItemText(iItem,COLAUTO));
2035                         if (sAuto!="*")
2036                                 continue;
2037                         sDrive=m_cMountlist.GetItemText(iItem,COLDRIVE);
2038                         LOG("Connect %s %s",sDrive,sKey);
2039                         m_cAfs.Dismount(msg,sDrive,TRUE);
2040                         if (!m_cAfs.Mount(msg,sDrive,sKey))
2041                         {
2042                                 CString msg2;
2043                                 m_cAfs.Shutdown(msg2);
2044                                 m_procInfo.hThread=0;
2045                                 msg2.Format("Connect can't continue: %s",msg);
2046                                 HandleError(msg2);
2047                                 ErrorDisplayState();
2048                                 return true;
2049                         }
2050                         AddMenu(sDrive,sKey);
2051                         break;
2052                 }
2053                 if (m_progress)
2054                         m_progress->Next();
2055                 if (!m_cAfs.Authencate(msg,m_sUsername,m_sPassword))
2056                 {
2057                         CString msg2;
2058                         DismountAll(msg,3);             //unfortunately all drive references are invalid also!
2059                         m_cAfs.Shutdown(msg2);
2060                         m_procInfo.hThread=0;
2061                         HandleError(msg);
2062                         ErrorDisplayState();
2063                         if (m_progress)
2064                                 delete m_progress;
2065                         return true;
2066                 }
2067                 m_bServiceIsActive=TRUE;
2068                 }
2069                 break;
2070         default:
2071                 if (lParam)
2072                         delete (CString *)lParam;
2073                 break;
2074         }
2075         UpdateConnect();
2076         if (m_progress)
2077                 delete m_progress;
2078         return true;
2079 }
2080
2081
2082 BOOL CWinAfsLoadDlg::OnHelpInfo(HELPINFO* pHelpInfo) 
2083 {
2084         // TODO: Add your message handler code here and/or call default
2085         ::WinHelp(m_hWnd,CWINAFSLOADAPP->m_pszHelpFilePath,HELP_CONTEXT,IDH_MAIN);
2086         return TRUE;
2087 }
2088
2089 void CWinAfsLoadDlg::OnHelpmain() 
2090 {
2091         // TODO: Add your control notification handler code here
2092         ::WinHelp(m_hWnd,CWINAFSLOADAPP->m_pszHelpFilePath,HELP_CONTEXT,IDH_MAIN);
2093         
2094 }
2095
2096 void CWinAfsLoadDlg::OnSettings() 
2097 {
2098         // TODO: Add your control notification handler code here
2099         CRegkey regkey("AFS\\Window");
2100         CCommandSettings dlg;
2101         dlg.m_ConnectOnStart=   CWINAFSLOADAPP->m_bConnect;
2102         dlg.m_LogToWindow=CWINAFSLOADAPP->m_bLogWindow;
2103         dlg.m_LogToFile=CWINAFSLOADAPP->m_bLog;
2104         dlg.m_UserName=m_sUsername;
2105         UINT tvar;
2106         DWORD size=sizeof(tvar);
2107         regkey.GetBinary("LoginTime",(LPBYTE)&tvar,size);
2108         dlg.m_uMaxLoginTime=tvar;
2109         dlg.m_uMaxPowerRestartDelay=m_PowerResumeDelay;
2110         if (dlg.DoModal()==IDOK)
2111         {
2112                 if (dlg.m_LogToWindow ^ CWINAFSLOADAPP->m_bLogWindow) 
2113                         CWINAFSLOADAPP->ShowLog(dlg.m_LogToWindow);
2114                 if (dlg.m_LogToFile ^ CWINAFSLOADAPP->m_bLog)
2115                         CWINAFSLOADAPP->ShowPrint(dlg.m_LogToFile);
2116                 CWINAFSLOADAPP->m_bLogWindow=dlg.m_LogToWindow;
2117                 CWINAFSLOADAPP->m_bLog=dlg.m_LogToFile;
2118                 CWINAFSLOADAPP->m_bConnect=dlg.m_ConnectOnStart;
2119                 CWINAFSLOADAPP->RegOptions(FALSE);
2120                 tvar=dlg.m_uMaxLoginTime;
2121                 regkey.PutBinary("LoginTime",(LPBYTE)&tvar,size);
2122                 m_PowerResumeDelay=dlg.m_uMaxPowerRestartDelay;
2123                 regkey.PutBinary("PowerResumeDelay",(LPBYTE)&m_PowerResumeDelay,size);
2124         }
2125 }
2126