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 ___________________________________________________________________
17 #include "afscfg.h" // Main header for this application
19 #include "salvage_results_dlg.h"
21 #include <afs\afs_bosAdmin.h>
26 * DEFINITIONS _________________________________________________________________
29 static const int UPDATE_INTERVAL = 5000; // milleseconds
30 static const int LOG_BUF_SIZE = 25000; // bytes
31 static const int EDIT_CONTROL_MAX_CHARS = 64000; // Max chars an edit control can hold
32 static const char *SALVAGE_LOG_FILE_NAME = "SalvageLog.txt";
34 static rwWindowData arwDialog[] = {
35 { IDC_LOG, raSizeX | raSizeY, MAKELONG(350, 150), 0 },
36 { IDC_CLOSE, raMoveX | raMoveY, 0, 0 },
37 { 9, raMoveX | raMoveY, 0, 0 },
38 { idENDLIST, 0, 0, 0 }
43 * Variables _________________________________________________________________
46 static HWND hDlg = 0; // HWND for this page's dialog
48 static afs_status_t nStatus;
51 static BOOL bSalvageComplete;
55 * PROTOTYPES _________________________________________________________________
58 static void OnInitDialog(HWND hwndDlg);
59 static void OnClose();
60 static void SetMessages(int nStatusMsgID, int nLogMsgID);
61 static DWORD WINAPI ShowResults(LPVOID param);
62 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName);
63 static char *AddCarriageReturnsToLog(char *pszInBuf, char *&pszOutBuf);
64 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf);
65 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize);
67 BOOL CALLBACK SalvageResultsDlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp);
71 * EXPORTED FUNCTIONS _________________________________________________________
74 BOOL ShowSalvageResults(HWND hParent)
76 int nResult = ModalDialog(IDD_SALVAGE_RESULTS, hParent, (DLGPROC)SalvageResultsDlgProc);
78 return (nResult == IDOK);
83 * Dialog Proc _________________________________________________________________
86 BOOL CALLBACK SalvageResultsDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
88 if (AfsAppLib_HandleHelp(IDD_SALVAGE_RESULTS, hwndDlg, msg, wp, lp))
93 OnInitDialog(hwndDlg);
103 if (bSalvageComplete)
110 ResizeWindow(hwndDlg, arwDialog, rwaFixupGuts);
119 * STATIC FUNCTIONS _________________________________________________________________
124 * Event Handler Functions __________________________________________________________
127 static void OnInitDialog(HWND hwndDlg)
131 bSalvageComplete = FALSE;
133 ResizeWindow(hDlg, arwDialog, rwaFixupGuts);
135 hLogo = GetDlgItem(hDlg, IDC_LOGO);
137 AfsAppLib_StartAnimation(hLogo, 8);
139 SetMessages(IDS_SALVAGING, IDS_CURRENT_SALVAGE_LOG);
141 nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
143 ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED);
147 // Remove the start menu - we do this so the user can't close
148 // the dialog while salvage is being performed.
150 dw = GetWindowLong(hDlg, GWL_STYLE);
152 SetWindowLong(hDlg, GWL_STYLE, dw);
154 // Create a thread to keep the view of the log up to date
156 HANDLE hThread = CreateThread(0, 0, ShowResults, 0, 0, &dwThreadID);
157 CloseHandle(hThread);
160 static void OnClose()
162 bos_ServerClose(hServer, &nStatus);
164 EndDialog(hDlg, IDOK);
169 * Utility Functions _________________________________________________________________
172 static void SetMessages(int nStatusMsgID, int nLogMsgID)
174 TCHAR szMsgBuf[cchRESOURCE];
176 SetDlgItemText(hDlg, IDC_SALVAGE_STATUS, GetResString(nStatusMsgID, szMsgBuf));
177 SetDlgItemText(hDlg, IDC_LOG_TITLE, GetResString(nLogMsgID, szMsgBuf));
180 static char *AddCarriageReturnsToLog(char *pszInBuf, char *& pszOutBuf)
184 char *pInBuf = pszInBuf;
186 // How man new lines are there?
195 // Allocate enough memory for the log buffer plus CRs plus a NULL
196 if (!AllocMemory(pszOutBuf, strlen(pszInBuf) + nNumNLs + 1))
199 // Copy over the whole buffer, adding \r's as we go. The edit control
200 // seems to need \r before \n, so we set it up that way.
202 char *pOutBuf = pszOutBuf;
205 if (*pInBuf == '\n') {
209 *pOutBuf++ = *pInBuf;
219 static char *GetMaxPartOfLogWeCanShow(char *pszLogBuf)
223 // Find out how much of the log buffer is in use
224 int nLen = strlen(pszLogBuf);
226 if (nLen < EDIT_CONTROL_MAX_CHARS)
229 // Buffer is bigger than maximum, so find the last full line
230 // under the limit and return it.
231 char *psz = pszLogBuf + nLen - EDIT_CONTROL_MAX_CHARS;
233 // Make sure we return the beginning of a line
234 while (*psz && (*psz != '\n'))
243 static BOOL AllocMemory(char *&pszLogBuf, int nBufSize)
248 pszLogBuf = new char[nBufSize];
251 g_LogFile.Write("Failed to allocate memory (%d bytes) for the salvage log buffer.\r\n", nBufSize);
258 static void SaveLogToDisk(char *pszLogBuf, char *pszFileName)
260 // If no log file was specified by the user, then do nothing
264 FILE *fp = fopen(pszFileName, "w");
266 ShowError(hDlg, 0, IDS_ERROR_SAVING_SALVAGE_LOG_TO_DISK);
270 fprintf(fp, "%s", pszLogBuf);
275 static DWORD WINAPI ShowResults(LPVOID param)
277 ULONG nBufSize = LOG_BUF_SIZE;
279 char *pszLogBufWithCRs = 0;
280 DWORD dwWait = WAIT_TIMEOUT;
282 ULONG nLogSize = LOG_BUF_SIZE;
284 if (!AllocMemory(pszLogBuf, nBufSize))
287 while (dwWait != WAIT_OBJECT_0) {
288 // Wait for either the salvage thread to terminate or our update
290 dwWait = WaitForSingleObject(g_CfgData.hSalvageThread, UPDATE_INTERVAL);
292 // In either case, update the log display for the user
294 // Get the salvage log as it currently exists
296 nResult = bos_LogGet(hServer, "SalvageLog", &nLogSize, pszLogBuf, &nStatus);
298 if (nStatus == ADMMOREDATA) {
299 // If salvage isn't done, then get a bigger buffer than we need to
300 // prevent future ADMMOREDATA errors.
302 if (dwWait != WAIT_OBJECT_0) {
303 nBufSize += LOG_BUF_SIZE;
306 if (AllocMemory(pszLogBuf, nBufSize))
314 // NULL-terminate the log
315 pszLogBuf[nLogSize] = 0;
317 // The edit control that we use to show the log to the user needs \r\n at the end
318 // of each line, but the salvage log only has \n. We must replace the \n with
319 // \r\n before showing the log.
320 if (!AddCarriageReturnsToLog(pszLogBuf, pszLogBufWithCRs)) {
325 // The edit control has a limit to the number of characters it can hold. If the log
326 // is bigger than that limit, then we will show the maximum portion of the end of the
327 // log that we can fit in the edit control.
328 char *pszLogToShow = GetMaxPartOfLogWeCanShow(pszLogBufWithCRs);
330 // Put it into the edit control so the user can see it
331 SetDlgItemText(hDlg, IDC_LOG, A2S(pszLogToShow));
334 AfsAppLib_StopAnimation(hLogo);
337 SetMessages(IDS_SALVAGE_COMPLETE, IDS_FINAL_SALVAGE_LOG);
338 SaveLogToDisk(pszLogBufWithCRs, GetSalvageLogFileNameA());
339 MsgBox(hDlg, IDS_SALVAGE_COMPLETE, GetAppTitleID(), MB_OK);
341 SetMessages(IDS_SALVAGING, IDS_CANT_GET_SALVAGE_LOG);
342 ShowError(hDlg, nStatus, IDS_CANT_GET_SALVAGE_LOG);
345 CloseHandle(g_CfgData.hSalvageThread);
350 if (pszLogBufWithCRs)
351 delete pszLogBufWithCRs;
353 SetEnable(hDlg, IDC_CLOSE);
355 bSalvageComplete = TRUE;