private bool DetectIoctlCodes(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Detect Ioctl Codes ====="); detectionInfo.unsupportedIoctlCodes = new List<string>(); detectionInfo.ResetDetectResult(); if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb30)) { try { detectionInfo.F_CopyOffload = detector.CheckIOCTL_CopyOffload(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.F_CopyOffload = new DetectResult[] { DetectResult.DetectFail, DetectResult.DetectFail }; detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_OFFLOAD_READ.ToString(), string.Format("Detect FSCTL_OFFLOAD failed: {0}", ex.Message)); detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_OFFLOAD_WRITE.ToString(), string.Format("Detect FSCTL_OFFLOAD failed: {0}", ex.Message)); } //Add the unsupported IoctlCodes to the list if (detectionInfo.F_CopyOffload[0] != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_OFFLOAD_READ.ToString()); if (detectionInfo.F_CopyOffload[1] != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_OFFLOAD_WRITE.ToString()); try { detectionInfo.F_FileLevelTrim = detector.CheckIOCTL_FileLevelTrim(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.F_FileLevelTrim = DetectResult.DetectFail; detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_FILE_LEVEL_TRIM.ToString(), string.Format("Detect FSCTL_FILE_LEVEL_TRIM failed: {0}", ex.Message)); } //Add the unsupported IoctlCodes to the list if (detectionInfo.F_FileLevelTrim != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_FILE_LEVEL_TRIM.ToString()); try { detectionInfo.F_ValidateNegotiateInfo = detector.CheckIOCTL_ValidateNegotiateInfo("IPC$", ref detectionInfo); } catch (Exception ex) { detectionInfo.F_ValidateNegotiateInfo = DetectResult.DetectFail; if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb311)) { detectionInfo.detectExceptions.Add( CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO.ToString(), "FSCTL_VALIDATE_NEGOTIATE_INFO is not applicable when the Connection.Dialect is 3.1.1."); } else { detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO.ToString(), string.Format("Detect FSCTL_VALIDATE_NEGOTIATE_INFO failed: {0}", ex.Message)); } } //Add the unsupported IoctlCodes to the list if (detectionInfo.F_ValidateNegotiateInfo != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO.ToString()); } if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb21)) { try { detectionInfo.F_ResilientHandle = detector.CheckIOCTL_ResilientHandle(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.F_ResilientHandle = DetectResult.DetectFail; detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY.ToString(), string.Format("Detect FSCTL_LMR_REQUEST_RESILIENCY failed: {0}", ex.Message)); } //Add the unsupported IoctlCodes to the list if (detectionInfo.F_ResilientHandle != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY.ToString()); bool supported = false; string failedReason = null; // Try all shares to detect if integrity info is supported. foreach (var share in detectionInfo.shareInfo) { if (!share.ShareName.Contains("$")) { try { detectionInfo.F_IntegrityInfo = detector.CheckIOCTL_IntegrityInfo(share.ShareName, ref detectionInfo); } catch (Exception ex) { // Do not need to record all failedReasons. // So just pick one, the last failedReason. failedReason = ex.Message; } if (detectionInfo.F_IntegrityInfo[0] == DetectResult.Supported) { supported = true; detectionInfo.shareSupportingIntegrityInfo = share.ShareName; // Clean up last detect exception record when detected previous shares if (detectionInfo.detectExceptions.ContainsKey(CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION.ToString())) detectionInfo.detectExceptions.Remove(CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION.ToString()); if (detectionInfo.detectExceptions.ContainsKey(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION.ToString())) detectionInfo.detectExceptions.Remove(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION.ToString()); break; } } } if (!supported && failedReason != null && !detectionInfo.detectExceptions.ContainsKey(CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION.ToString())) { detectionInfo.F_IntegrityInfo = new DetectResult[] { DetectResult.DetectFail, DetectResult.DetectFail }; detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION.ToString(), string.Format("Detect FSCTL_INTEGRITY_INFORMATION failed: {0}", failedReason)); detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION.ToString(), string.Format("Detect FSCTL_INTEGRITY_INFORMATION failed: {0}", failedReason)); } //Add the unsupported IoctlCodes to the list if (detectionInfo.F_IntegrityInfo[0] != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION.ToString()); if (detectionInfo.F_IntegrityInfo[1] != DetectResult.Supported) detectionInfo.unsupportedIoctlCodes.Add(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION.ToString()); } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); return true; }
private bool CheckUsernamePassword(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Check the Credential ====="); try { detector.CheckUsernamePassword(detectionInfo); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Error, string.Format("The User cannot log on:{0} \r\nPlease check the credential", ex.Message)); } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); return true; }
private void DetectCreateContexts(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Detect Create Contexts ====="); detectionInfo.unsupportedCreateContexts = new List<string>(); if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb30)) { try { detectionInfo.F_AppInstanceId = detector.CheckCreateContexts_AppInstanceId(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID.ToString(), string.Format("Detect SMB2_CREATE_APP_INSTANCE_ID failed: {0}", ex.Message)); } // Add the unsupported CreateContexts to the list if (detectionInfo.F_AppInstanceId != DetectResult.Supported) { detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID.ToString()); } try { detectionInfo.F_Leasing_V2 = detector.CheckCreateContexts_LeaseV2(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2.ToString(), string.Format("Detect SMB2_CREATE_REQUEST_LEASE_V2 failed: {0}", ex.Message)); } // Add the unsupported CreateContexts to the list if (detectionInfo.F_Leasing_V2 != DetectResult.Supported) { detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2.ToString()); } string failedReason = null; try { detectionInfo.F_HandleV2_BatchOplock = detector.CheckCreateContexts_HandleV2BatchOplock(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { failedReason = ex.Message; } try { detectionInfo.F_HandleV2_LeaseV1 = detector.CheckCreateContexts_HandleV2LeaseV1(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { failedReason = ex.Message; } try { detectionInfo.F_HandleV2_LeaseV2 = detector.CheckCreateContexts_HandleV2LeaseV2(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { failedReason = ex.Message; } if (detectionInfo.F_HandleV2_BatchOplock != DetectResult.Supported && detectionInfo.F_HandleV2_LeaseV1 != DetectResult.Supported && detectionInfo.F_HandleV2_LeaseV2 != DetectResult.Supported) { detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2.ToString()); detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2.ToString()); if (failedReason != null) { detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2.ToString(), string.Format("Detect Durable Handle V2 failed: {0}", failedReason)); detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2.ToString(), string.Format("Detect Durable Handle V2 failed: {0}", failedReason)); } } } if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb21)) { try { detectionInfo.F_Leasing_V1 = detector.CheckCreateContexts_LeaseV1(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE.ToString(), string.Format("Detect SMB2_CREATE_REQUEST_LEASE failed: {0}", ex.Message)); } // Add the unsupported CreateContexts to the list if (detectionInfo.F_Leasing_V1 != DetectResult.Supported) { detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE.ToString()); } string failedReason = null; try { detectionInfo.F_HandleV1_BatchOplock = detector.CheckCreateContexts_HandleV1BatchOplock( detectionInfo.BasicShareName, detectionInfo.smb2Info.MaxSupportedDialectRevision, ref detectionInfo); } catch (Exception ex) { failedReason = ex.Message; } try { detectionInfo.F_HandleV1_LeaseV1 = detector.CheckCreateContexts_HandleV1LeaseV1(detectionInfo.BasicShareName, ref detectionInfo); } catch (Exception ex) { failedReason = ex.Message; } // Add the unsupported CreateContexts to the list if (detectionInfo.F_HandleV1_BatchOplock != DetectResult.Supported && detectionInfo.F_HandleV1_LeaseV1 != DetectResult.Supported) { detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST.ToString()); detectionInfo.unsupportedCreateContexts.Add(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT.ToString()); if (failedReason != null) { detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST.ToString(), string.Format("Detect Durable Handle V1 failed: {0}", failedReason)); detectionInfo.detectExceptions.Add( CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT.ToString(), string.Format("Detect Durable Handle V1 failed: {0}", failedReason)); } } } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); }
private bool PingSUT(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Ping Target SUT ====="); try { detectionInfo.networkInfo = detector.PingTargetSUT(); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLog(LogLevel.Error, ex.Message); } if (detectionInfo.networkInfo.SUTIpList.Count == 0) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); return false; } logWriter.AddLog(LogLevel.Warning, "Success", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); return true; }
/// <summary> /// Run property autodetection. /// </summary> /// <returns>Return true if the function is succeeded.</returns> public bool RunDetection() { logWriter.AddLog(LogLevel.Information, "===== Start detecting ====="); FSDetector detector = new FSDetector (logWriter, detectionInfo.targetSUT, new AccountCredential(detectionInfo.domainName, detectionInfo.userName, detectionInfo.password), detectionInfo.securityPackageType); // Terminate the whole detection if any exception happens in the following processes if (!PingSUT(detector)) return false; if (!DetectLocalNetworkInfo(detector)) return false; if (!DetectSMB2Info(detector)) return false; if (!CheckUsernamePassword(detector)) return false; // Do not interrupt auto-detection // Even if detecting platform and useraccount failed DetectPlatformAndUserAccount(detector); if (!DetectShareInfo(detector)) return false; if (!DetermineBasicShare()) return false; DetermineSymboliclink(); detectionInfo.detectExceptions = new Dictionary<string, string>(); // Detect IoctlCodes and Create Contexts // If any exceptions, just ignore DetectIoctlCodes(detector); DetectCreateContexts(detector); logWriter.AddLog(LogLevel.Information, "===== End detecting ====="); return true; }
private bool DetectShareInfo(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Fetch Share Info ====="); try { detectionInfo.shareInfo = detector.FetchShareInfo(detectionInfo); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Information, string.Format("FetchShareInfo failed, reason: {0}", ex.Message)); logWriter.AddLog(LogLevel.Error, string.Format("Detect share info failed. Cannot do further detection.", ex.Message)); } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); if (detectionInfo.shareInfo != null) { logWriter.AddLog(LogLevel.Information, "Target SUT Share Info:"); foreach (var item in detectionInfo.shareInfo) { logWriter.AddLog(LogLevel.Information, string.Format("Share Name: {0}", item.ShareName)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Type: {0}", item.ShareType)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Flags: {0}", item.ShareFlags)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Capabilities: {0}", item.ShareCapabilities)); } logWriter.AddLineToLog(LogLevel.Information); } return true; }
private bool DetectSMB2Info(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Fetch Smb2 Info ====="); try { detectionInfo.smb2Info = detector.FetchSmb2Info(detectionInfo); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Error, string.Format("Detect SUT SMB2 info failed: {0} \r\n", ex.Message)); } if (detectionInfo.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb2Unknown || detectionInfo.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb2Wildcard) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Error, string.Format("The DialectRevision in Negotiate response should not be {0}", detectionInfo.smb2Info.MaxSupportedDialectRevision)); } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Information, "Target SUT SMB2 Info:"); logWriter.AddLog(LogLevel.Information, string.Format("MaxSupportedDialectRevision: {0}", detectionInfo.smb2Info.MaxSupportedDialectRevision)); logWriter.AddLog(LogLevel.Information, string.Format("SupportedCapabilities: {0}", detectionInfo.smb2Info.SupportedCapabilities)); logWriter.AddLineToLog(LogLevel.Information); return true; }
private void DetectPlatformAndUserAccount(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Detect SUT Platform and Useraccounts ====="); detector.FetchPlatformAndUseraccounts(ref detectionInfo); logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); }
private bool DetectLocalNetworkInfo(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Fetch Network Info ====="); try { detectionInfo.networkInfo = detector.FetchLocalNetworkInfo(detectionInfo); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Error, string.Format("Detect network info failed: {0} \r\nPlease check Target SUT", ex.Message)); } if (detectionInfo.networkInfo == null) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); return false; } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Information, "Target SUT Network Info:"); logWriter.AddLog(LogLevel.Information, "Available IP Address:"); foreach (var item in detectionInfo.networkInfo.SUTIpList) { logWriter.AddLog(LogLevel.Information, "\t" + item.ToString()); } logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Information, "Local Test Driver Network Info:"); logWriter.AddLog(LogLevel.Information, "Available IP Address:"); foreach (var item in detectionInfo.networkInfo.LocalIpList) { logWriter.AddLog(LogLevel.Information, "\t" + item.ToString()); } logWriter.AddLineToLog(LogLevel.Information); return true; }
private bool DetectSQOS(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Detect SQOS ====="); if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb311)) { try { detectionInfo.SqosSupport = detector.CheckSqosSupport(ref detectionInfo); } catch (Exception e) { logWriter.AddLog(LogLevel.Information, string.Format("Detect SQOS failed: {0}", e.Message)); detectionInfo.SqosSupport = DetectResult.DetectFail; detectionInfo.detectExceptions.Add(CtlCode_Values.FSCTL_STORAGE_QOS_CONTROL.ToString(), string.Format("Detect SQOS failed: {0}", e.Message)); } } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); return true; }
private bool DetectShareInfo(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Fetch Share Info ====="); try { detectionInfo.shareInfo = detector.FetchShareInfo(detectionInfo); } catch (Exception ex) { logWriter.AddLog(LogLevel.Warning, "Failed", false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Information); logWriter.AddLog(LogLevel.Information, string.Format("FetchShareInfo failed, reason: {0}", ex.Message)); logWriter.AddLog(LogLevel.Error, string.Format("Detect share info failed. Cannot do further detection.", ex.Message)); } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); if (detectionInfo.shareInfo != null) { logWriter.AddLog(LogLevel.Information, "Target SUT Share Info:"); foreach (var item in detectionInfo.shareInfo) { logWriter.AddLog(LogLevel.Information, string.Format("Share Name: {0}", item.ShareName)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Type: {0}", item.ShareType)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Flags: {0}", item.ShareFlags)); logWriter.AddLog(LogLevel.Information, string.Format("\tShare Capabilities: {0}", item.ShareCapabilities)); if (item.ShareType != ShareType_Values.SHARE_TYPE_DISK || item.ShareName.Contains("$")) continue; // Identify the shares for Oplock model if (item.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK)) { if (item.ShareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT)) { detectionInfo.shareListWithForceLevel2AndSOFS.Add(item.ShareName); } else { detectionInfo.shareListWithForceLevel2WithoutSOFS.Add(item.ShareName); } } else { if (item.ShareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT)) { detectionInfo.shareListWithoutForceLevel2WithSOFS.Add(item.ShareName); } else { detectionInfo.shareListWithoutForceLevel2OrSOFS.Add(item.ShareName); } } } logWriter.AddLineToLog(LogLevel.Information); } return true; }
private bool DetectRSVD(FSDetector detector) { logWriter.AddLog(LogLevel.Information, "===== Detect RSVD ====="); if (detectionInfo.CheckHigherDialect(detectionInfo.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb30)) { try { detectionInfo.RsvdSupport = detector.CheckRsvdSupport(ref detectionInfo); } catch (Exception e) { logWriter.AddLog(LogLevel.Information, string.Format("Detect RSVD failed: {0}", e.Message)); detectionInfo.RsvdSupport = DetectResult.DetectFail; detectionInfo.detectExceptions.Add(@"SVHDX_OPEN_DEVICE_CONTEXT_V1\V2", string.Format("Detect RSVD failed: {0}", e.Message)); } } logWriter.AddLog(LogLevel.Warning, "Finished", false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Information); return true; }