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