private void ExecuteInstallScriptCopyFoldersNode(VdfAstNode node) { for (Int32 i = 0; i < node.Count; i++) { if (worker != null && worker.CancellationPending) break; VdfAstNode folderNode = node[i]; String sourcePath = null; String destinationPath = null; for (Int32 j = 0; j < folderNode.Count; j++) { if (String.Compare(folderNode[j].Value, "SrcFolder 1", StringComparison.OrdinalIgnoreCase) == 0) sourcePath = folderNode[j][0].Value; else if (String.Compare(folderNode[j].Value, "DstFolder 1", StringComparison.OrdinalIgnoreCase) == 0) destinationPath = folderNode[j][0].Value; } if (!String.IsNullOrEmpty(sourcePath) && !String.IsNullOrEmpty(destinationPath)) SgiUtils.CopyDirectory(sourcePath, destinationPath, false, false, worker); } }
public void Add(VdfAstNode node) { nodes.Add(node); }
private void ExecuteInstallScriptRunProcessNode(VdfAstNode node) { for (Int32 i = 0; i < node.Count; i++) { if (worker != null && worker.CancellationPending) break; VdfAstNode registryValueNode = node[i]; String registryKey = @"HKEY_LOCAL_MACHINE\Software\Valve\Steam\Apps\" + application.Id.ToString(CultureInfo.InvariantCulture); Dictionary<Int32, String> processImages = null; Dictionary<Int32, String> commandLines = null; Boolean isNoCleanUp = true; Boolean isIgnoreExitCode = false; for (Int32 j = 0; j < registryValueNode.Count; j++) { if (String.Compare(registryValueNode[j].Value, "HasRunKey", StringComparison.OrdinalIgnoreCase) == 0) registryKey = registryValueNode[j][0].Value; else if (registryValueNode[j].Value.IndexOf("process", StringComparison.OrdinalIgnoreCase) == 0) { Int32 integerValue; String[] processString = registryValueNode[j].Value.Split(new Char[] { }, StringSplitOptions.RemoveEmptyEntries); if (processString.Length == 2 && Int32.TryParse(processString[1], out integerValue)) { if (processImages == null) processImages = new Dictionary<Int32, String>(1); processImages.Add(integerValue, registryValueNode[j][0].Value); } } else if (registryValueNode[j].Value.IndexOf("command", StringComparison.OrdinalIgnoreCase) == 0) { Int32 integerValue; String[] commandString = registryValueNode[j].Value.Split(new Char[] { }, StringSplitOptions.RemoveEmptyEntries); if (commandString.Length == 2 && Int32.TryParse(commandString[1], out integerValue)) { if (commandLines == null) commandLines = new Dictionary<Int32, String>(1); commandLines.Add(integerValue, registryValueNode[j][0].Value); } } else if (String.Compare(registryValueNode[j].Value, "NoCleanUp", StringComparison.OrdinalIgnoreCase) == 0) isNoCleanUp = registryValueNode[j][0].GetValueAsBoolean(); else if (String.Compare(registryValueNode[j].Value, "IgnoreExitCode", StringComparison.OrdinalIgnoreCase) == 0) isIgnoreExitCode = registryValueNode[j][0].GetValueAsBoolean(); } if (!String.IsNullOrEmpty(registryKey) && processImages != null) { RegistryKey key = SgiUtils.RegistryCreateKey(registryKey, RegistryView.Registry32); if (key != null) { Object keyValue = key.GetValue(registryValueNode.Value); if (keyValue == null || (keyValue != null && (keyValue is Int32) && (Int32)keyValue != 1)) { foreach (Int32 processNumber in processImages.Keys) { Process process = null; String commandLine; if (commandLines.TryGetValue(processNumber, out commandLine)) process = Process.Start(processImages[processNumber], commandLine); else process = Process.Start(processImages[processNumber]); if (process != null) { // Wait for the associated process to exit or cancelation of worker thread while (!process.WaitForExit(200) && (worker == null || !worker.CancellationPending)) { }; if (worker != null && worker.CancellationPending) // TODO: maybe worth to ask user what to do with process process.Kill(); else { if (!isIgnoreExitCode && process.ExitCode != 0) { MessageBoxOptions mbOptions = 0; if (CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft) mbOptions = MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign; MessageBox.Show(String.Format(CultureInfo.CurrentUICulture, Resources.ExecuteInstallScriptRunProcessNodeErrorMessage, processImages[processNumber], process.ExitCode, Environment.NewLine, valveDataFile.FullName), Resources.WarningMessage, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, mbOptions); } else key.SetValue(registryValueNode.Value, 1, RegistryValueKind.DWord); if (!isNoCleanUp) // TODO: dunno what to do with this { } } process.Close(); } } } } } } }
private void ExecuteInstallScriptRegistryNode(VdfAstNode node) { for (Int32 i = 0; i < node.Count; i++) { VdfAstNode registryKeyNode = node[i]; RegistryKey registryKey = SgiUtils.RegistryCreateKey(registryKeyNode.Value, RegistryView.Registry32); if (registryKey != null) { for (Int32 j = 0; j < registryKeyNode.Count; j++) { VdfAstNode registryValueKindNode = registryKeyNode[j]; String valueKind = registryValueKindNode.Value; if (!String.IsNullOrEmpty(valueKind)) { for (Int32 k = 0; k < registryValueKindNode.Count; k++) { VdfAstNode registryValueNode = registryValueKindNode[k]; if (registryValueNode[0].Count > 0) // registryKeyValueNode.Value is language name { if (String.Compare(gameLanguage, registryValueNode.Value, StringComparison.OrdinalIgnoreCase) == 0) registryValueNode = registryValueNode[0]; else registryValueNode = null; } if (registryValueNode != null) { Object value; RegistryValueKind registryValueKind; if (String.Compare(valueKind, "string", StringComparison.OrdinalIgnoreCase) == 0) { value = registryValueNode[0].Value; registryValueKind = RegistryValueKind.String; } else if (String.Compare(registryValueKindNode.Value, "dword", StringComparison.OrdinalIgnoreCase) == 0) { Int32 integerValue; // dword may mean dword or binary, so we should parse value (not sure about this) if (Int32.TryParse(registryValueNode[0].Value, out integerValue)) { value = integerValue; registryValueKind = RegistryValueKind.DWord; } else { value = Encoding.UTF8.GetBytes(registryValueNode[0].Value); registryValueKind = RegistryValueKind.Binary; } } else { value = null; registryValueKind = RegistryValueKind.Unknown; } if (value != null && registryValueKind != RegistryValueKind.Unknown) registryKey.SetValue(registryValueNode.Value, value, registryValueKind); } } } } } } }
private void ExecuteInstallScript(VdfAstNode installScriptNode) { for (Int32 i = 0; i < installScriptNode.Count; i++) { if (worker != null && worker.CancellationPending) break; VdfAstNode node = installScriptNode[i]; if (String.Compare(node.Value, "Registry", StringComparison.OrdinalIgnoreCase) == 0) ExecuteInstallScriptRegistryNode(node); else if (String.Compare(node.Value, "Run Process", StringComparison.OrdinalIgnoreCase) == 0) ExecuteInstallScriptRunProcessNode(node); else if (String.Compare(node.Value, "Copy Folders", StringComparison.OrdinalIgnoreCase) == 0) ExecuteInstallScriptCopyFoldersNode(node); } }
/// <summary> /// Creates abstract syntax tree from abstract syntax tree. /// </summary> private void CreateAST() { if (worker == null || !worker.CancellationPending) { Stack<VdfAstNode> astStack = new Stack<VdfAstNode>(); VdfAstNode keyNode = new VdfAstNode(VdfSTNodeType.VdfScript, valveDataFile.FullName); Boolean isNextNodeHaveKey = false; ast = keyNode; astStack.Push(keyNode); // non recursive algorithm of creating abstract syntax tree. foreach (VdfCstNode cstNode in cst) { if (cstNode.NodeType == VdfSTNodeType.Value) { VdfAstNode node = new VdfAstNode(cstNode.NodeType, GetNodeValue(cstNode)); keyNode.Add(node); if (!isNextNodeHaveKey) { astStack.Push(keyNode); keyNode = node; isNextNodeHaveKey = true; } else { keyNode = astStack.Pop(); isNextNodeHaveKey = false; } } else if (cstNode.NodeType == VdfSTNodeType.NewLine) { isNextNodeHaveKey = false; } else if (cstNode.NodeType == VdfSTNodeType.BlockStart) { isNextNodeHaveKey = false; } else if (cstNode.NodeType == VdfSTNodeType.BlockEnd) { keyNode = astStack.Pop(); isNextNodeHaveKey = false; } } } }
private VdfAstNode ast; // abstract syntax tree public ValveDataFile(SteamApplication app, String fileName, DirectoryInfo installDirectory, String language, BackgroundWorker worker) { this.application = app; this.valveDataFile = new FileInfo(fileName); this.installDir = installDirectory; this.gameLanguage = language; this.worker = worker; cst = new List<VdfCstNode>(); ast = null; }