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 ___________________________________________________________________
14 #include "afscfg.h" // Main header for this application
16 #include "salvage_results_dlg.h"
18 #include "afs_bosAdmin.h"
23 * DEFINITIONS _________________________________________________________________
26 static const int UPDATE_INTERVAL = 5000; // milleseconds
27 static const int LOG_BUF_SIZE = 25000; // bytes
28 static const int EDIT_CONTROL_MAX_CHARS = 64000; // Max chars an edit control can hold
29 static const char *SALVAGE_LOG_FILE_NAME = "SalvageLog.txt";
31 static rwWindowData arwDialog[] = {
32 { IDC_LOG, raSizeX | raSizeY, MAKELONG(350, 150) },
33 { IDC_CLOSE, raMoveX | raMoveY },
34 { 9, raMoveX | raMoveY },
40 * Variables _________________________________________________________________
43 static HWND hDlg = 0; // HWND for this page's dialog
45 static afs_status_t nStatus;
48 static BOOL bSalvageComplete;
52 * PROTOTYPES _________________________________________________________________
55 static void OnInitDialog(HWND hwndDlg);
56 static void OnClose();
57 static void SetMessages(int nStatusMsgID, int nLogMsgID);
58 static DWORD WINAPI ShowResults(LPVOID param);
59 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName);
60 static char *AddCarriageReturnsToLog(char *pszInBuf, char *&pszOutBuf);
61 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf);
62 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize);
64 BOOL CALLBACK SalvageResultsDlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp);
68 * EXPORTED FUNCTIONS _________________________________________________________
71 BOOL ShowSalvageResults(HWND hParent)
73 int nResult = ModalDialog(IDD_SALVAGE_RESULTS, hParent, (DLGPROC)SalvageResultsDlgProc);
75 return (nResult == IDOK);
80 * Dialog Proc _________________________________________________________________
83 BOOL CALLBACK SalvageResultsDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
85 if (AfsAppLib_HandleHelp(IDD_SALVAGE_RESULTS, hwndDlg, msg, wp, lp))
90 OnInitDialog(hwndDlg);
100 if (bSalvageComplete)
107 ResizeWindow(hwndDlg, arwDialog, rwaFixupGuts);
116 * STATIC FUNCTIONS _________________________________________________________________
121 * Event Handler Functions __________________________________________________________
124 static void OnInitDialog(HWND hwndDlg)
128 bSalvageComplete = FALSE;
130 ResizeWindow(hDlg, arwDialog, rwaFixupGuts);
132 hLogo = GetDlgItem(hDlg, IDC_LOGO);
134 AfsAppLib_StartAnimation(hLogo, 8);
136 SetMessages(IDS_SALVAGING, IDS_CURRENT_SALVAGE_LOG);
138 nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
140 ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED);
144 // Remove the start menu - we do this so the user can't close
145 // the dialog while salvage is being performed.
147 dw = GetWindowLong(hDlg, GWL_STYLE);
149 SetWindowLong(hDlg, GWL_STYLE, dw);
151 // Create a thread to keep the view of the log up to date
153 HANDLE hThread = CreateThread(0, 0, ShowResults, 0, 0, &dwThreadID);
154 CloseHandle(hThread);
157 static void OnClose()
159 bos_ServerClose(hServer, &nStatus);
161 EndDialog(hDlg, IDOK);
166 * Utility Functions _________________________________________________________________
169 static void SetMessages(int nStatusMsgID, int nLogMsgID)
171 TCHAR szMsgBuf[cchRESOURCE];
173 SetDlgItemText(hDlg, IDC_SALVAGE_STATUS, GetResString(nStatusMsgID, szMsgBuf));
174 SetDlgItemText(hDlg, IDC_LOG_TITLE, GetResString(nLogMsgID, szMsgBuf));
177 static char *AddCarriageReturnsToLog(char *pszInBuf, char *& pszOutBuf)
181 char *pInBuf = pszInBuf;
183 // How man new lines are there?
192 // Allocate enough memory for the log buffer plus CRs plus a NULL
193 if (!AllocMemory(pszOutBuf, strlen(pszInBuf) + nNumNLs + 1))
196 // Copy over the whole buffer, adding \r's as we go. The edit control
197 // seems to need \r before \n, so we set it up that way.
199 char *pOutBuf = pszOutBuf;
202 if (*pInBuf == '\n') {
206 *pOutBuf++ = *pInBuf;
216 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf)
220 // Find out how much of the log buffer is in use
221 int nLen = strlen(pszLogBuf);
223 if (nLen < EDIT_CONTROL_MAX_CHARS)
226 // Buffer is bigger than maximum, so find the last full line
227 // under the limit and return it.
228 char *psz = pszLogBuf + nLen - EDIT_CONTROL_MAX_CHARS;
230 // Make sure we return the beginning of a line
231 while (*psz && (*psz != '\n'))
240 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize)
245 pszLogBuf = new char[nBufSize];
248 g_LogFile.Write("Failed to allocate memory (%d bytes) for the salvage log buffer.\r\n", nBufSize);
255 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName)
257 // If no log file was specified by the user, then do nothing
261 FILE *fp = fopen(pszFileName, "w");
263 ShowError(hDlg, 0, IDS_ERROR_SAVING_SALVAGE_LOG_TO_DISK);
267 fprintf(fp, "%s", pszLogBuf);
272 static DWORD WINAPI ShowResults(LPVOID param)
274 ULONG nBufSize = LOG_BUF_SIZE;
276 char *pszLogBufWithCRs = 0;
277 DWORD dwWait = WAIT_TIMEOUT;
279 ULONG nLogSize = LOG_BUF_SIZE;
281 if (!AllocMemory(pszLogBuf, nBufSize))
284 while (dwWait != WAIT_OBJECT_0) {
285 // Wait for either the salvage thread to terminate or our update
287 dwWait = WaitForSingleObject(g_CfgData.hSalvageThread, UPDATE_INTERVAL);
289 // In either case, update the log display for the user
291 // Get the salvage log as it currently exists
292 getlog: nResult = bos_LogGet(hServer, "SalvageLog", &nLogSize, pszLogBuf, &nStatus);
294 if (nStatus == ADMMOREDATA) {
295 // If salvage isn't done, then get a bigger buffer than we need to
296 // prevent future ADMMOREDATA errors.
298 if (dwWait != WAIT_OBJECT_0) {
299 nBufSize += LOG_BUF_SIZE;
302 if (AllocMemory(pszLogBuf, nBufSize))
310 // NULL-terminate the log
311 pszLogBuf[nLogSize] = 0;
313 // The edit control that we use to show the log to the user needs \r\n at the end
314 // of each line, but the salvage log only has \n. We must replace the \n with
315 // \r\n before showing the log.
316 if (!AddCarriageReturnsToLog(pszLogBuf, pszLogBufWithCRs)) {
321 // The edit control has a limit to the number of characters it can hold. If the log
322 // is bigger than that limit, then we will show the maximum portion of the end of the
323 // log that we can fit in the edit control.
324 char *pszLogToShow = GetMaxPartOfLogWeCanShow(pszLogBufWithCRs);
326 // Put it into the edit control so the user can see it
327 SetDlgItemText(hDlg, IDC_LOG, A2S(pszLogToShow));
330 AfsAppLib_StopAnimation(hLogo);
333 SetMessages(IDS_SALVAGE_COMPLETE, IDS_FINAL_SALVAGE_LOG);
334 SaveLogToDisk(pszLogBufWithCRs, GetSalvageLogFileNameA());
335 MsgBox(hDlg, IDS_SALVAGE_COMPLETE, GetAppTitleID(), MB_OK);
337 SetMessages(IDS_SALVAGING, IDS_CANT_GET_SALVAGE_LOG);
338 ShowError(hDlg, nStatus, IDS_CANT_GET_SALVAGE_LOG);
341 CloseHandle(g_CfgData.hSalvageThread);
346 if (pszLogBufWithCRs)
347 delete pszLogBufWithCRs;
349 SetEnable(hDlg, IDC_CLOSE);
351 bSalvageComplete = TRUE;