2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * INCLUDES ___________________________________________________________________
18 #include <afsconfig.h>
19 #include <afs/param.h>
23 #include "afscfg.h" // Main header for this application
25 #include "salvage_results_dlg.h"
27 #include <afs\afs_bosAdmin.h>
32 * DEFINITIONS _________________________________________________________________
35 static const int UPDATE_INTERVAL = 5000; // milleseconds
36 static const int LOG_BUF_SIZE = 25000; // bytes
37 static const int EDIT_CONTROL_MAX_CHARS = 64000; // Max chars an edit control can hold
38 static const char *SALVAGE_LOG_FILE_NAME = "SalvageLog.txt";
40 static rwWindowData arwDialog[] = {
41 { IDC_LOG, raSizeX | raSizeY, MAKELONG(350, 150), 0 },
42 { IDC_CLOSE, raMoveX | raMoveY, 0, 0 },
43 { 9, raMoveX | raMoveY, 0, 0 },
44 { idENDLIST, 0, 0, 0 }
49 * Variables _________________________________________________________________
52 static HWND hDlg = 0; // HWND for this page's dialog
54 static afs_status_t nStatus;
57 static BOOL bSalvageComplete;
61 * PROTOTYPES _________________________________________________________________
64 static void OnInitDialog(HWND hwndDlg);
65 static void OnClose();
66 static void SetMessages(int nStatusMsgID, int nLogMsgID);
67 static DWORD WINAPI ShowResults(LPVOID param);
68 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName);
69 static char *AddCarriageReturnsToLog(char *pszInBuf, char *&pszOutBuf);
70 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf);
71 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize);
73 BOOL CALLBACK SalvageResultsDlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp);
77 * EXPORTED FUNCTIONS _________________________________________________________
80 BOOL ShowSalvageResults(HWND hParent)
82 int nResult = ModalDialog(IDD_SALVAGE_RESULTS, hParent, (DLGPROC)SalvageResultsDlgProc);
84 return (nResult == IDOK);
89 * Dialog Proc _________________________________________________________________
92 BOOL CALLBACK SalvageResultsDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
94 if (AfsAppLib_HandleHelp(IDD_SALVAGE_RESULTS, hwndDlg, msg, wp, lp))
99 OnInitDialog(hwndDlg);
103 switch (LOWORD(wp)) {
109 if (bSalvageComplete)
116 ResizeWindow(hwndDlg, arwDialog, rwaFixupGuts);
125 * STATIC FUNCTIONS _________________________________________________________________
130 * Event Handler Functions __________________________________________________________
133 static void OnInitDialog(HWND hwndDlg)
137 bSalvageComplete = FALSE;
139 ResizeWindow(hDlg, arwDialog, rwaFixupGuts);
141 hLogo = GetDlgItem(hDlg, IDC_LOGO);
143 AfsAppLib_StartAnimation(hLogo, 8);
145 SetMessages(IDS_SALVAGING, IDS_CURRENT_SALVAGE_LOG);
147 nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
149 ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED);
153 // Remove the start menu - we do this so the user can't close
154 // the dialog while salvage is being performed.
156 dw = GetWindowLong(hDlg, GWL_STYLE);
158 SetWindowLong(hDlg, GWL_STYLE, dw);
160 // Create a thread to keep the view of the log up to date
162 HANDLE hThread = CreateThread(0, 0, ShowResults, 0, 0, &dwThreadID);
163 CloseHandle(hThread);
166 static void OnClose()
168 bos_ServerClose(hServer, &nStatus);
170 EndDialog(hDlg, IDOK);
175 * Utility Functions _________________________________________________________________
178 static void SetMessages(int nStatusMsgID, int nLogMsgID)
180 TCHAR szMsgBuf[cchRESOURCE];
182 SetDlgItemText(hDlg, IDC_SALVAGE_STATUS, GetResString(nStatusMsgID, szMsgBuf));
183 SetDlgItemText(hDlg, IDC_LOG_TITLE, GetResString(nLogMsgID, szMsgBuf));
186 static char *AddCarriageReturnsToLog(char *pszInBuf, char *& pszOutBuf)
190 char *pInBuf = pszInBuf;
192 // How man new lines are there?
201 // Allocate enough memory for the log buffer plus CRs plus a NULL
202 if (!AllocMemory(pszOutBuf, strlen(pszInBuf) + nNumNLs + 1))
205 // Copy over the whole buffer, adding \r's as we go. The edit control
206 // seems to need \r before \n, so we set it up that way.
208 char *pOutBuf = pszOutBuf;
211 if (*pInBuf == '\n') {
215 *pOutBuf++ = *pInBuf;
225 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf)
229 // Find out how much of the log buffer is in use
230 int nLen = strlen(pszLogBuf);
232 if (nLen < EDIT_CONTROL_MAX_CHARS)
235 // Buffer is bigger than maximum, so find the last full line
236 // under the limit and return it.
237 char *psz = pszLogBuf + nLen - EDIT_CONTROL_MAX_CHARS;
239 // Make sure we return the beginning of a line
240 while (*psz && (*psz != '\n'))
249 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize)
254 pszLogBuf = new char[nBufSize];
257 g_LogFile.Write("Failed to allocate memory (%d bytes) for the salvage log buffer.\r\n", nBufSize);
264 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName)
266 // If no log file was specified by the user, then do nothing
270 FILE *fp = fopen(pszFileName, "w");
272 ShowError(hDlg, 0, IDS_ERROR_SAVING_SALVAGE_LOG_TO_DISK);
276 fprintf(fp, "%s", pszLogBuf);
281 static DWORD WINAPI ShowResults(LPVOID param)
283 ULONG nBufSize = LOG_BUF_SIZE;
285 char *pszLogBufWithCRs = 0;
286 DWORD dwWait = WAIT_TIMEOUT;
288 ULONG nLogSize = LOG_BUF_SIZE;
290 if (!AllocMemory(pszLogBuf, nBufSize))
293 while (dwWait != WAIT_OBJECT_0) {
294 // Wait for either the salvage thread to terminate or our update
296 dwWait = WaitForSingleObject(g_CfgData.hSalvageThread, UPDATE_INTERVAL);
298 // In either case, update the log display for the user
300 // Get the salvage log as it currently exists
302 nResult = bos_LogGet(hServer, "SalvageLog", &nLogSize, pszLogBuf, &nStatus);
304 if (nStatus == ADMMOREDATA) {
305 // If salvage isn't done, then get a bigger buffer than we need to
306 // prevent future ADMMOREDATA errors.
308 if (dwWait != WAIT_OBJECT_0) {
309 nBufSize += LOG_BUF_SIZE;
312 if (AllocMemory(pszLogBuf, nBufSize))
320 // NULL-terminate the log
321 pszLogBuf[nLogSize] = 0;
323 // The edit control that we use to show the log to the user needs \r\n at the end
324 // of each line, but the salvage log only has \n. We must replace the \n with
325 // \r\n before showing the log.
326 if (!AddCarriageReturnsToLog(pszLogBuf, pszLogBufWithCRs)) {
331 // The edit control has a limit to the number of characters it can hold. If the log
332 // is bigger than that limit, then we will show the maximum portion of the end of the
333 // log that we can fit in the edit control.
334 char *pszLogToShow = GetMaxPartOfLogWeCanShow(pszLogBufWithCRs);
336 // Put it into the edit control so the user can see it
337 SetDlgItemText(hDlg, IDC_LOG, A2S(pszLogToShow));
340 AfsAppLib_StopAnimation(hLogo);
343 SetMessages(IDS_SALVAGE_COMPLETE, IDS_FINAL_SALVAGE_LOG);
344 SaveLogToDisk(pszLogBufWithCRs, GetSalvageLogFileNameA());
345 MsgBox(hDlg, IDS_SALVAGE_COMPLETE, GetAppTitleID(), MB_OK);
347 SetMessages(IDS_SALVAGING, IDS_CANT_GET_SALVAGE_LOG);
348 ShowError(hDlg, nStatus, IDS_CANT_GET_SALVAGE_LOG);
351 CloseHandle(g_CfgData.hSalvageThread);
356 if (pszLogBufWithCRs)
357 delete pszLogBufWithCRs;
359 SetEnable(hDlg, IDC_CLOSE);
361 bSalvageComplete = TRUE;