singrdk/base/Windows/AppReader/INFParser.cs

205 lines
5.3 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}
}