/*++ Copyright (c) 1995 Microsoft Corporation Module Name: log.c Abstract: Routines for logging actions performed during setup. Author: Ted Miller (tedm) 4-Apr-1995 Revision History: --*/ #include "setupp.h" #pragma hdrstop #include // to define HRESULT for richedit.h #include // // Log item terminator. // PCSTR LogItemTerminator = "\r\n***\r\n\r\n"; // // Severity descriptions. Initialized in InitializeSetupActionLog. // PCSTR SeverityDescriptions[LogSevMaximum]; // // Handle to the setup action log file. // HANDLE ActionLogFile; // // Default filename for the action log file. // PCWSTR DefaultFileName = L"setuplog.txt"; // // Filename of the action log file. Filled in at init time. // PCWSTR ActionLogFileName; // // Mutex to prevent multiple instances of setup from writing to the log file // simultaneously. // PCWSTR LogFileMutexName = L"SetupActionLogMutex"; // // Constant strings used for logging in various places. // PCWSTR szWaitForSingleObject = L"WaitForSingleObject"; PCWSTR szFALSE = L"FALSE"; PCWSTR szSetGroupOfValues = L"SetGroupOfValues"; PCWSTR szSetArrayToMultiSzValue = L"SetArrayToMultiSzValue"; PCWSTR szCreateProcess = L"CreateProcess"; PCWSTR szRegOpenKeyEx = L"RegOpenKeyEx"; PCWSTR szRegQueryValueEx = L"RegQueryValueEx"; PCWSTR szRegSetValueEx = L"RegSetValueEx"; PCWSTR szDeleteFile = L"DeleteFile"; PCWSTR szRemoveDirectory = L"RemoveDirectory"; // // This structure is passed as the parameter to DialogBoxParam to provide // initialization data. // typedef struct _LOGVIEW_DIALOG_DATA { PCWSTR LogFileName; // actual file used PCWSTR WindowHeading; // actual title of main window } LOGVIEW_DIALOG_DATA, *PLOGVIEW_DIALOG_DATA; BOOL InitializeSetupActionLog( BOOL WipeLogFile ) /*++ Routine Description: Initialize the setup action log. This file is a textual description of actions performed during setup. The log file is called setuplog.txt and it exists in the windows dir. Arguments: WipeLogFile - if TRUE, any existing log file is deleted before logging begins. Return Value: Boolean value indicating whether initialization was sucessful. --*/ { WCHAR Logfilename[MAX_PATH]; UINT i; PWSTR p; // // Form the pathname of the logfile. // GetWindowsDirectory(Logfilename,MAX_PATH); ConcatenatePaths(Logfilename,DefaultFileName,MAX_PATH,NULL); ActionLogFileName = DuplicateString(Logfilename); // // If we're wiping the logfile clean, attempt to delete // what's there. // if(WipeLogFile) { SetFileAttributes(Logfilename,FILE_ATTRIBUTE_NORMAL); DeleteFile(Logfilename); } // // Open/create the file. // ActionLogFile = CreateFile( Logfilename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if(ActionLogFile == INVALID_HANDLE_VALUE) { ActionLogFile = NULL; } // // Initialize the log severity descriptions. // for(i=0; iWindowHeading); hWndRichEdit = GetDlgItem (hDialog, IDT_RICHEDIT1); if (!ReadLogFile (((LOGVIEW_DIALOG_DATA *)lParam)->LogFileName, hWndRichEdit)) { MessageBoxFromMessage (hDialog, MSG_UNABLE_TO_SHOW_LOG, NULL, IDS_ERROR, MB_OK|MB_ICONSTOP); EndDialog (hDialog, FALSE); } CenterWindowRelativeToParent(hDialog); PostMessage(hDialog,WM_APP,0,0); break; case WM_APP: hWndRichEdit = GetDlgItem (hDialog, IDT_RICHEDIT1); SendMessage(hWndRichEdit,EM_SETSEL,0,0); SendMessage(hWndRichEdit,EM_SCROLLCARET,0,0); break; case WM_COMMAND: switch (wParam) { case IDOK: EndDialog (hDialog, TRUE); default: return FALSE; } break; default: return FALSE; } return TRUE; } BOOL ViewSetupActionLog ( IN HWND hOwnerWindow, IN PCWSTR OptionalFileName OPTIONAL, IN PCWSTR OptionalHeading OPTIONAL ) /*++ Routine Description: Formats the setup action log and displays it in a window. The log file is called setuplog.txt and it exists in the windows dir. Arguments: hOwnerWindow - handle to window that owns the dialog box OptionalFileName - full path of the file to be displayed. OptionalHeading - text to be shown at the top of the window. Return Value: Boolean value indicating whether the routine was sucessful. --*/ { LOGVIEW_DIALOG_DATA Global; // initialization data for dialog box WCHAR TmpFileName[MAX_PATH]; // used to create the log file name PCWSTR TmpHeading; // used to create the heading HANDLE hRichedDLL; // DLL used for rich edit INT Status; // what we're going to return // // Form the pathname of the logfile. // if (!ARGUMENT_PRESENT(OptionalFileName)) { GetWindowsDirectory (TmpFileName,MAX_PATH); ConcatenatePaths (TmpFileName,DefaultFileName,MAX_PATH,NULL); Global.LogFileName = DuplicateString (TmpFileName); } else { if (wcslen(OptionalFileName) > MAX_PATH) { Status = 0; goto err0; } Global.LogFileName = DuplicateString (OptionalFileName); } if (!Global.LogFileName) { Status = FALSE; goto err0; } // // Form the heading for the dialog box. // if (!ARGUMENT_PRESENT(OptionalHeading)) { TmpHeading = MyLoadString (IDS_LOG_DEFAULT_HEADING); } else { TmpHeading = DuplicateString (OptionalHeading); } if (!TmpHeading) { Status = FALSE; goto err1; } Global.WindowHeading = FormatStringMessage (IDS_LOG_WINDOW_HEADING, TmpHeading, Global.LogFileName); if (!Global.WindowHeading) { Status = FALSE; goto err2; } // // Create the dialog box. // if (!(hRichedDLL = LoadLibrary (L"RICHED20.DLL"))) { Status = FALSE; goto err3; } Status = DialogBoxParam (MyModuleHandle, MAKEINTRESOURCE(IDD_VIEWLOG), hOwnerWindow, DialogProc, (LPARAM) &Global); // // Clean up and return. // FreeLibrary (hRichedDLL); err3: MyFree (Global.WindowHeading); err2: MyFree (TmpHeading); err1: MyFree (Global.LogFileName); err0: return Status; }