/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // /////////////////////////////////////////////////////////////////////////////// namespace ManifestReader { using System; using System.IO; using System.Collections; using System.Xml; using System.Diagnostics; public class INFParser : ManifestParser { public override Hashtable Parse(string appName, string file, Hashtable elementTranslator) { Hashtable outTable = new Hashtable(); StreamReader ios = new StreamReader(file); #region Parse INF File ArrayList sections = new ArrayList(); INFSection curSection = null; INFVersionSection versionSection = null; INFStringSection strSection = null; string curLine = ios.ReadLine(); while(curLine != null) { // get rid of the whitespace on both sides curLine = curLine.Trim(); if (curLine.Equals("")) { curLine = ios.ReadLine(); continue; } // we don't like lines that start with control characters if (curLine[0] < 32) { curLine = ios.ReadLine(); continue; } if (curLine.StartsWith("#pragma")) { // I can't believe this is in an INF file! curLine = ios.ReadLine(); continue; } if (curLine.StartsWith("----")) { curLine = ios.ReadLine(); continue; } //Console.WriteLine(curLine); if (INFSection.IsComment(curLine)) { //Console.WriteLine("***Ignoring comment"); curLine = ios.ReadLine(); continue; } if (INFSection.IsSection(curLine)) { //Console.WriteLine("***Found Section"); if (curSection != null) { sections.Add(curSection); } if (INFSection.IsStringSection(curLine)) { //Console.WriteLine("***It's a Strings section"); curSection = new INFStringSection(curLine); strSection = (INFStringSection)curSection; } else { if (INFSection.IsVersionSection(curLine)) { //Console.WriteLine("***It's a version section"); curSection = new INFVersionSection(curLine); versionSection = (INFVersionSection)curSection; } else { curSection = new INFSection(curLine); } } } else { // I can only assume that the real INF parser just ignores // everything that's not in a section, given what I've seen // at the top of INF files so far if (curSection != null) { //Console.WriteLine("***Adding Line to Section " + curSection.Name); curSection.AddLine(curLine); } } curLine = ios.ReadLine(); } if (curSection != null) { sections.Add(curSection); } #endregion #region Replace Strings //Debug.Assert(versionSection != null); // make sure we have a string table somewhere if (strSection != null) { // now grab the INFStringSection and pass it to each INFSection // so they can update their strings to be correct for(int i = 0; i < sections.Count; i++) { ((INFSection)sections[i]).UpdateStrings(strSection); } } #endregion #region Record Registry Changes // now that we've replaced the strings, we can safely // discover all the Registry section lines for(int i = 0; i < sections.Count; i++) { ((INFSection)sections[i]).DiscoverRegistryLines(); } // walk the sections again and accumulate all the AddReg and DelReg sections Hashtable addRegSections = new Hashtable(); Hashtable delRegSections = new Hashtable(); for (int i = 0; i < sections.Count; i++) { ((INFSection)sections[i]).GetAddRegSections(addRegSections); ((INFSection)sections[i]).GetDelRegSections(delRegSections); } for(int i = 0; i < sections.Count; i++) { string secName = ((INFSection)sections[i]).Name; if (addRegSections.ContainsKey(secName) || delRegSections.ContainsKey(secName)) { // now walk its lines and enter the registry values ArrayList lines = ((INFSection)sections[i]).Lines; for(int j = 0; j < lines.Count; j++) { string line = (string)lines[j]; if (line.Equals("")) continue; string versionGUID = null; if (versionSection != null) { versionGUID = versionSection.Guid; } string regKey = INFSection.GetRegKey(line, versionGUID); if (regKey != null) { //Console.WriteLine("Got RegKey " + regKey); string regValue = INFSection.GetRegValue(line); // remove all but the innermost double-quote strings from this value int removeCount = 0; for(int k = 0; k < regValue.Length; k++) { if (regValue[k] == '"') { removeCount++; } } if (removeCount > 0) { regValue = regValue.TrimStart(new char[] {'"'}); regValue = regValue.TrimEnd(new char[] {'"'}); regValue = "\"" + regValue + "\""; } //Console.WriteLine("Got RegValue " + regValue); ManifestParser.addEntry(regKey, regValue, appName); } } } } #endregion return outTable; } } }