macos-use-platform-copy-of-afssettings-20060802
[openafs.git] / src / WINNT / win9xpanel / WinAfsLoad.cpp
1 // WinAfsLoad.cpp : Defines the class behaviors for the application.
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 "cregkey.h"
15 #include "api95.h"
16 #include "termwarn.h"
17 #include "myframe.h"
18 #include "afsmsg95.h"
19 #include "Tlhelp32.h"
20
21 #ifdef _DEBUG
22 #define new DEBUG_NEW
23 #undef THIS_FILE
24 static char THIS_FILE[] = __FILE__;
25 #endif
26
27 /////////////////////////////////////////////////////////////////////////////
28 // CWinAfsLoadApp
29
30 BEGIN_MESSAGE_MAP(CWinAfsLoadApp, CWinApp)
31         //{{AFX_MSG_MAP(CWinAfsLoadApp)
32         //}}AFX_MSG_MAP
33         ON_COMMAND(ID_HELP, CWinApp::OnHelp)
34         ON_THREAD_MESSAGE(WM_UIONPARM,OnNotifyReturn)
35         ON_THREAD_MESSAGE(WSA_EVENT, OnAfsEvent)
36 END_MESSAGE_MAP()
37
38 /////////////////////////////////////////////////////////////////////////////
39 // CWinAfsLoadApp construction
40
41 CWinAfsLoadApp::CWinAfsLoadApp()
42 {
43         // TODO: add construction code here,
44         // Place all significant initialization in InitInstance
45 }
46
47 /////////////////////////////////////////////////////////////////////////////
48 // The one and only CWinAfsLoadApp object
49
50 CWinAfsLoadApp theApp;
51
52 /////////////////////////////////////////////////////////////////////////////
53 // CWinAfsLoadApp initialization
54
55 HWND CWinAfsLoadApp::m_hAfsLoadFinish=0;
56 HWND CWinAfsLoadApp::m_hAfsLoad=0;
57 CString CWinAfsLoadApp::m_sDosAppName;
58 /*
59                 DWORD dwProcessID;
60                 ::GetWindowThreadProcessId (hWnd, &dwProcessID);
61 */
62 BOOL CALLBACK CWinAfsLoadApp::EnumWindowsProc(HWND hWnd, LPARAM lParam)
63 {
64         CWnd *wnd=CWnd::FromHandle(hWnd);
65         CString msg;
66         CString sFinish;
67         wnd->GetWindowText(msg);
68         if ( (!m_sDosAppName.IsEmpty()) 
69                 && (m_sDosAppName!=""))
70         {
71                 if (msg==m_sDosAppName)
72                         m_hAfsLoad=hWnd;
73                 sFinish.Format("Finished - %s",m_sDosAppName);
74                 if (msg==sFinish)
75                         m_hAfsLoadFinish=hWnd;
76         }
77         if (msg==DOSTITLE)
78                 m_hAfsLoad=hWnd;
79         if ((msg==DOSTITLEFINISH)||(msg==APPTITLEFINISH))
80                 m_hAfsLoadFinish=hWnd;
81         return ((m_hAfsLoad==0) && (m_hAfsLoadFinish==0));
82 }
83
84 int CWinAfsLoadApp::ExitInstance() 
85 {
86         // TODO: Add your specialized code here and/or call the base class
87         if (m_pCMyUIThread)
88         {
89                 SetNotifyEventSuspend();
90                 m_pCMyUIThread->PostThreadMessage(WM_UIONPARM,ONPARMCLOSE,0);
91                 WaitForSingleObject(CMyUIThread::m_hEventThreadKilled, INFINITE);
92                 CloseHandle(CMyUIThread::m_hEventThreadKilled);
93                 m_pCMyUIThread=NULL;
94         }
95         return CWinApp::ExitInstance();
96 }
97
98 BOOL CWinAfsLoadApp::InitInstance()
99 {
100         HWND hwnd=FindWindow(NULL,"AFS Activity Log");
101         CString msg;
102         msg.LoadString(IDD_ACTIVITYLOG);
103         if (hwnd)
104         {
105                 ::PostMessage(hwnd,WM_SYSCOMMAND,IDM_VISIBLE,0);
106                 return FALSE;
107         }
108         EnumWindows (CWinAfsLoadApp::EnumWindowsProc, (LPARAM) 0);      //lets grab other open windows and close them down
109         if (!AfxSocketInit())
110         {
111                 AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
112                 return FALSE;
113         }
114
115         // Standard initialization
116         // If you are not using these features and wish to reduce the size
117         //  of your final executable, you should remove from the following
118         //  the specific initialization routines you do not need.
119
120 #ifdef _AFXDLL
121         Enable3dControls();                     // Call this when using MFC in a shared DLL
122 #else
123         Enable3dControlsStatic();       // Call this when linking to MFC statically
124 #endif
125
126         PCHAR pPath=getenv("AFSCONF");
127         m_sTargetDir.Empty();
128         if (!pPath)
129                 AfxMessageBox("AFS Error - Improper installation, Enviornemnt variable AFSCONF missing",MB_ICONWARNING | MB_OK);
130         else 
131                 m_sTargetDir.Format("%s\\",pPath);
132
133 //      CString t(m_sTargetDir);
134 //      t+="afs-light.hlp";
135
136         m_pszHelpFilePath=_tcsdup(_T("afswin9x.hlp"));
137 // initialize variables
138         CRegkey regkey("AFS\\Window");
139         if (regkey.Getkey()!=0)
140         {
141                 DWORD len=64;
142                 regkey.GetString("Title",m_sDosAppName,len);
143         }
144         RegOptions(TRUE);
145
146         if ((m_pCMyUIThread=(CMyUIThread *)AfxBeginThread(RUNTIME_CLASS(CMyUIThread)),THREAD_PRIORITY_IDLE)==NULL)
147         {// need to create a very low priority else it will interfere with other windows
148                 AfxMessageBox("Error creating background thread for progress bar! /nApplicaton still operational.");
149                 m_pCMyUIThread=NULL;
150         } else
151                 m_pCMyUIThread->m_hEventThreadKilled    //used to test when thread is done
152                         = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset
153         // scan for command line options
154         // show userid: password: connect
155         CharLower(m_lpCmdLine);
156         m_bShowAfs=(strstr(m_lpCmdLine,"show")!=NULL);
157         m_bConnect=(strstr(m_lpCmdLine,"connect")!=NULL);
158         if (m_bLogWindow)
159                 ShowLog(TRUE);
160         if (m_bLog)
161                 ShowPrint(TRUE);
162         char *str=NULL;
163         CString cUserName;
164         strlwr(m_lpCmdLine);    //convert to lower case
165         if ((str=strstr(m_lpCmdLine,"userid:"))!=NULL)  // 
166         {
167                 cUserName=(strstr(str,":"));
168         }
169         CString cPassWord;
170         if ((str=strstr(m_lpCmdLine,"password:"))!=NULL)
171         {
172                 cPassWord=(strstr(str,":"));
173         }
174         m_bNoID=(strstr(m_lpCmdLine,"noid")!=NULL);
175
176         if (m_hAfsLoadFinish)   // SOME REASON THE WINDOW WAS NOT SHUT DOWN, SO LETES KILL IT
177         {
178                 ::SendMessage(m_hAfsLoadFinish,WM_CLOSE,0,0);
179                 LOG("WM_CLOSE");
180         }
181         if (m_hAfsLoad) // Something wrong, BACKGROUND is running without dialog
182         {
183                 CTermWarn *pModeless = new CTermWarn(NULL);
184                 pModeless->Create();
185                 pModeless->SetActiveWindow();
186                 ShutdownAfs();
187                 CTime startTime = CTime::GetCurrentTime();
188                 CTimeSpan elapsedTime;
189                 do 
190                 {
191                         Sleep(500);
192                         m_hAfsLoad=0;
193                         EnumWindows (EnumWindowsProc, (LPARAM) 0);      //lets prevent multiple instances!
194                         elapsedTime= CTime::GetCurrentTime() - startTime;
195                         if (elapsedTime.GetTotalSeconds()>10) 
196                         {
197                                 if (pModeless)
198                                         pModeless->OnCancel();
199                                 ::ShowWindow(m_hAfsLoad,SW_SHOWNORMAL);
200                                 ::AfxMessageBox("AFS Error - Warning AFS Client Console still running.\n Locate the console and use Control C to manually terminate it!");
201                                 return FALSE;
202                         }
203                 } while (m_hAfsLoad);
204                 if (m_hAfsLoadFinish)   // SOME REASON THE WINDOW WAS NOT SHUT DOWN, SO LETES KILL IT
205                 {
206                         ::SendMessage(m_hAfsLoadFinish,WM_CLOSE,0,0);
207                         LOG("WM_CLOSE");
208                 }
209                 if (pModeless)
210                         pModeless->OnCancel();
211         }
212         CWinAfsLoadDlg dlg(cUserName,cPassWord);
213         m_pMainWnd = &dlg;
214         int nResponse = dlg.DoModal();
215         if (nResponse == IDOK)
216         {
217                 // TODO: Place code here to handle when the dialog is
218                 //  dismissed with OK
219         }
220         else if (nResponse == IDCANCEL)
221         {
222                 // TODO: Place code here to handle when the dialog is
223                 //  dismissed with Cancel
224         }
225
226         // Since the dialog has been closed, return FALSE so that we exit the
227         //  application, rather than start the application's message pump.
228         return TRUE;
229 }
230
231 BOOL CWinAfsLoadApp::RegOptions(BOOL fetch)
232 {
233         CRegkey regkey("AFS\\Window");
234         if (regkey.Getkey()==0) return FALSE;
235         DWORD w=0;
236         DWORD len=sizeof(w);
237         if (fetch)
238         {
239                 regkey.GetBinary("CommandSettings",(LPBYTE)(&w),len);
240                 m_bLogWindow=((w & 2)!=0);
241                 m_bLog=((w & 4)!=0);
242                 m_bConnect=((w & 1)!=0);
243         } else
244         {
245                 w=((m_bLogWindow)?2:0) | ((m_bLog)?4:0) | ((m_bConnect)?1:0);
246                 regkey.PutBinary("CommandSettings",(LPBYTE)(&w),sizeof(DWORD));
247         }
248         return TRUE;
249 }
250
251 void CWinAfsLoadApp::Log(const char *s)
252 {
253         TRACE("%s\n",s);
254         if ((!m_bLogWindow) && (!m_bLog)) return;
255         if (s)
256         {
257                 SYSTEMTIME timeDest;
258                 GetSystemTime(&timeDest);
259                 CString *mt=new CString;        //release is handled by CMyUIThread
260                 mt->Format("(%02d:%02d:%2d-%03d)%s\r\n",
261                         timeDest.wHour,
262                         timeDest.wMinute,
263                         timeDest.wSecond,
264                         timeDest.wMilliseconds,s);
265                 m_pCMyUIThread->PostThreadMessage(WM_LOG,0,(LPARAM)mt);
266         }
267         else
268                 m_pCMyUIThread->PostThreadMessage(WM_LOG,0,0);
269 }
270
271 void CWinAfsLoadApp::Log(const char *f,const DWORD d)
272 {
273         CString msg;
274         msg.Format(f,d);
275         Log(msg);
276 }
277
278 void CWinAfsLoadApp::Log(const char *f,const DWORD d,const DWORD d2)
279 {
280         CString msg;
281         msg.Format(f,d,d2);
282         Log(msg);
283 }
284
285 void CWinAfsLoadApp::Log(const char *f,const char*s)
286 {
287         CString msg;
288         msg.Format(f,s);
289         Log(msg);
290 }
291
292 void CWinAfsLoadApp::Log(const char *f,const char*s,const char*s2)
293 {
294         CString msg;
295         msg.Format(f,s,s2);
296         Log(msg);
297 }
298
299 void CWinAfsLoadApp::Log(const char *f,const char*s,const char*s2,const char*s3)
300 {
301         CString msg;
302         msg.Format(f,s,s2,s3);
303         Log(msg);
304 }
305
306 void CWinAfsLoadApp::ShowLog(BOOL yes)
307 {
308         m_pCMyUIThread->PostThreadMessage(WM_LOG,LOGSHOWWINDOW,yes);
309 }
310
311 void CWinAfsLoadApp::ShowPrint(BOOL yes)
312 {
313         CString *mp=new CString();
314         mp->Format("%s\\afscli.log",getenv("AFSCONF"));
315         m_pCMyUIThread->PostThreadMessage(WM_LOG,LOGSHOWPRINT,(yes)?(LPARAM)mp:NULL);
316 }
317
318 void CWinAfsLoadApp::Progress(VOID *ptr, UINT mode)
319 {
320         // you cannot obtain the handle to the window int these routines so you have enough time to create the window
321         // It is ok to postmessage to a window in a different thread!
322         if (m_pCMyUIThread==NULL) return;
323         switch (mode)
324         {
325         case ProgFSetTitle:
326                 ::PostMessage(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd()
327                         ,WM_PROGRESSPARM,ProgFSetTitle,(LPARAM)ptr);
328                 break;
329         case ProgFHide:
330                 ::PostMessage(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd()
331                         ,WM_PROGRESSPARM,ProgFHide,0);
332                 break;
333         case ProgFNext:
334                 ::PostMessage(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd(),WM_PROGRESSPARM,ProgFNext,0);
335                 BringWindowToTop(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd());
336                 break;
337         default:
338                 ::PostMessage(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd(),WM_PROGRESSPARM,ProgFOpt,mode);
339                 BringWindowToTop(((CDialog *)m_pCMyUIThread->GetMainWnd())->GetSafeHwnd());
340                 ((CDialog *)m_pCMyUIThread->GetMainWnd())->CenterWindow((CWnd *)ptr);
341         case 0:
342                 break;
343         }
344 }
345
346 void CWinAfsLoadApp::RequestUISuspendEvent(UINT mode)
347 {
348         SetNotifyEventSuspend();
349         m_pCMyUIThread->PostThreadMessage(WM_UIONPARM,mode,0);
350 }
351
352 void CWinAfsLoadApp::RequestUIPostEvent(UINT mode,WPARAM wp,LPARAM lp)
353 {
354         SetNotifyEventPostMessage();
355         m_pCMyUIThread->PostThreadMessage(mode,wp,lp);
356 }
357
358
359 /*
360 There is no queue for messages (only one event) therefore messages passed to us
361 are not queued and stored in m_sMsg & m_wParam;
362 */
363
364 void CWinAfsLoadApp::SetNotifyEventSuspend()
365 {
366         ResetEvent(CMyUIThread::m_hEventThreadKilled);
367         m_uNotifyMessage=1;
368 }
369
370 void CWinAfsLoadApp::WaitForEvent(UINT logintime,WPARAM *wp,CString *msg)
371 {
372         switch (WaitForSingleObject(CMyUIThread::m_hEventThreadKilled, logintime))
373         {
374         case WAIT_OBJECT_0:
375                 LOG("OnAfsEvent - Receive Good Status ");
376                 *msg=m_sMsg;
377                 break;
378         default:
379                 *wp=AFS_EXITCODE_GENERAL_FAILURE;
380                 *msg="AFS Client timed out, failure to respond\r\nCheck Network Connection.";
381                 LOG("OnAfsEvent %s",(const char *)*msg);
382                 return;
383         }
384         *wp=m_wParam;
385 }
386
387 /*
388 Tthis funciton is called from UIThread (different thread) 
389         and should not contain and Windows stuff assocaited with CWinAFSLoad.
390 It is used to display messages from a backgound process or during PowerSuspend denial
391 NOTICE: PostThreadMessage leaves deletion of message up to caller
392         WaitEvent does not have to delete message because Wait is not queued like PostMessage
393 */
394 void CWinAfsLoadApp::WSANotifyFromUI(WPARAM wp,const char *msg)
395 {       
396         TRACE("CWinAfsLoadApp::Notify wp=%d,msg=[%s]\n",wp,msg);
397         switch (m_uNotifyMessage)
398         {
399         case 2:
400                 {// for post message use allocated memory to hold results and pass back to main thread
401                 CString *mp=new CString;                //memory is released by destination routine!
402                 *mp=msg;
403                 PostThreadMessage(WSA_EVENT,wp,(LPARAM)mp);     //this goes to WSA_EVENT
404                 }
405                 break;
406         case 1:
407                 // For setting the Event completion, pass information back to calling thread
408                 m_wParam=wp;
409                 m_sMsg=msg;     
410                 SetEvent(CMyUIThread::m_hEventThreadKilled);
411                 m_uNotifyMessage=0;
412                 break;
413         default:
414                 break;
415         }
416 }
417
418 void CWinAfsLoadApp::NotifyFromUI(WPARAM wp,const char *msg)
419 {// called from UIThread to notify return status
420         CString *mp=NULL;
421         if (msg)
422         {
423                 mp=new CString;         //memory is released by destination routine!
424                 *mp=msg;
425                 TRACE("CWinAfsLoadApp::Notify wp=%d,msg=[%s]\n",wp,msg);
426         } else
427                 TRACE("CWinAfsLoadApp::Notify wp=%d,msg=NULL\n",wp);
428         if (wp)
429                 PostThreadMessage(WM_UIONPARM,wp,(LPARAM)mp);
430 }
431
432 LRESULT CWinAfsLoadApp::OnNotifyReturn(WPARAM wParam, LPARAM lParam)
433 {
434         if (m_pMainWnd)
435                 return ((CWinAfsLoadDlg *)m_pMainWnd)->OnNotifyReturn(wParam,lParam);
436         return TRUE;
437 }
438
439 LRESULT CWinAfsLoadApp::OnAfsEvent(WPARAM wParam, LPARAM lParam)
440 {
441         if (m_pMainWnd)
442                 return ((CWinAfsLoadDlg *)m_pMainWnd)->OnAfsEvent(wParam,lParam);
443         return TRUE;
444 }
445